diff --git a/.gitignore b/.gitignore index 5114a0304c..cf62f18a03 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ bfgminer bfgminer.exe +bfgminer-rpc +bfgminer-rpc.exe +bitforce-firmware-flash cgminer cgminer.exe minerd @@ -25,11 +28,42 @@ config.log config.status config.guess config.sub +70-bfgminer.rules mingw32-config.cache *~ +*.orig +*.rej +*.swp +*.kate-swp ext_deps config.h.in config.h + +ccan*/libccan.a +lib/arg-nonnull.h +lib/c++defs.h +lib/libgnu.a +lib/signal.h +lib/string.h +lib/stdint.h +lib/warn-on-use.h +iospeeds_local.h +version.h +version.h.new + +mkinstalldirs + +.pc +bfgminer-bitforce.conf + +vgcore.* +core* +*.log +*.json +*.patch +*.zip +*.tbz2 +*.bz2 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..f64eea5462 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,12 @@ +[submodule "libblkmaker"] + path = libblkmaker + url = git://github.com/bitcoin/libblkmaker.git +[submodule "ccan"] + path = ccan-upstream + url = git://git.ozlabs.org/~ccan/ccan +[submodule "libbase58"] + path = libbase58 + url = git://github.com/luke-jr/libbase58.git +[submodule "knc-asic"] + path = knc-asic + url = git://github.com/KnCMiner/knc-asic diff --git a/.travis.deps b/.travis.deps new file mode 100644 index 0000000000..10a137c660 --- /dev/null +++ b/.travis.deps @@ -0,0 +1,35 @@ +test "x$1" = "xI-am-okay-with-destroying-my-system" || exit 1 +set -ex + +# Upgrading GCC triggers locale rebuild, so just do the one in use +sudo rm /var/lib/locales/supported.d/* +echo $LANG UTF-8 | sudo tee /var/lib/locales/supported.d/en + +echo -e 'deb http://ftp.us.debian.org/debian/ wheezy main\ndeb http://security.debian.org/ wheezy/updates main' | sudo tee '/etc/apt/sources.list' +sudo rm -r /etc/apt/sources.list.d +curl https://ftp-master.debian.org/keys/archive-key-7.0.asc | sudo apt-key add - +sudo apt-get update -qq +if [ -z "$CROSS_BINPKGS" ]; then + DEV_DEPS='libcurl4-gnutls-dev libjansson-dev uthash-dev' +fi +sudo apt-get install -y build-essential autoconf automake libtool $DEV_DEPS $EXTRA_DEPS + +if [ -n "$UBUNTU_DEPS" ]; then + cat <<\EOF | sudo tee '/etc/apt/sources.list' +deb http://gb.archive.ubuntu.com/ubuntu/ trusty main restricted universe +deb http://gb.archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe +deb http://gb.archive.ubuntu.com/ubuntu/ trusty-backports main restricted universe +deb http://security.ubuntu.com/ubuntu trusty-security main restricted universe +EOF + sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 3B4FE6ACC0B21F32 + sudo apt-get update -qq + sudo apt-get install -y $UBUNTU_DEPS +fi + +if [ -n "$CROSS_BINPKGS" ]; then + wget "https://github.com/luke-jr/cross-binpkgs/archive/${CROSS_BINPKGS}.zip" + unzip "${CROSS_BINPKGS}.zip" + for f in "cross-binpkgs-${CROSS_BINPKGS/+/-}"/*/*; do + sudo tar -C "/usr/${CROSS_BINPKGS/+*/}/" -xjvpf "$f" + done +fi diff --git a/.travis.script b/.travis.script new file mode 100644 index 0000000000..3310055f4f --- /dev/null +++ b/.travis.script @@ -0,0 +1,22 @@ +test "x$1" = "xI-am-okay-with-destroying-my-system" || exit 1 +set -ex + +if [ -n "$CROSS_BINPKGS" ]; then + CROSS_BINPKGS="${CROSS_BINPKGS/+*/}" + myCC="${CROSS_BINPKGS}-gcc" + CC_ARGS="-I/usr/${CROSS_BINPKGS}/usr/include" + export LDFLAGS="-L/usr/${CROSS_BINPKGS}/usr/lib -L/usr/${CROSS_BINPKGS}/usr/bin" + export PKG_CONFIG_PATH="/usr/${CROSS_BINPKGS}/usr/lib/pkgconfig/" + export PKG_CONFIG_SYSROOT_DIR="/usr/${CROSS_BINPKGS}" +fi + +export CC="$(which "$myCC") $CC_ARGS" +$CC --version + +./autogen.sh +./configure $GLOBAL_CONFIGURE_ARGS $CONFIGURE_ARGS +make CFLAGS="$GLOBAL_CFLAGS $BUILD_CFLAGS" $MAKEOPTS +if [ -z "$CROSS_BINPKGS" ]; then + make check + sudo make install +fi diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..1e1e0991f8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,144 @@ +os: linux +language: c +compiler: gcc +env: + global: + - MAKEOPTS=-j3 + - GLOBAL_CFLAGS='-O2 -Wall' + - GLOBAL_CONFIGURE_ARGS='--prefix=/usr' +matrix: + fast_finish: true + include: + - compiler: ": Full GCC" + # Upgrade GCC to avoid false warnings; build the full project with -Werror + env: myCC='gcc' UBUNTU_DEPS='gcc libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' BUILD_CFLAGS='-Werror' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-system-libbase58 --enable-tool' + - compiler: ": Full LLVM" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' BUILD_CFLAGS='-Werror' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-system-libbase58 --enable-tool' + - compiler: ": pkgconf" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev pkgconf' EXTRA_DEPS='libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' BUILD_CFLAGS='-Werror' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-system-libbase58 --enable-tool' + - compiler: ": MinGW64 ncurses" + env: UBUNTU_DEPS='gcc-mingw-w64-x86-64' EXTRA_DEPS='pkg-config yasm' CROSS_BINPKGS='x86_64-w64-mingw32+ncurses' BUILD_CFLAGS='-Werror' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-system-libbase58 --host=x86_64-w64-mingw32 --disable-knc --disable-bfsb --disable-jingtian --disable-metabank --disable-minergate --disable-titan --disable-kncasic --disable-minion' + - compiler: ": MinGW64 pdcurses" + env: UBUNTU_DEPS='gcc-mingw-w64-x86-64' EXTRA_DEPS='pkg-config yasm' CROSS_BINPKGS='x86_64-w64-mingw32' BUILD_CFLAGS='-Werror' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-system-libbase58 --host=x86_64-w64-mingw32 --disable-knc --disable-bfsb --disable-jingtian --disable-metabank --disable-minergate --disable-titan --disable-kncasic --disable-minion' + - compiler: ": Standard" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-keccak --enable-scrypt' + - compiler: ": Std SHA2" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='' + - compiler: ": Std Keccak" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-keccak' + - compiler: ": Std scrypt" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-scrypt' + - compiler: ": No hidapi" + env: myCC='clang' UBUNTU_DEPS='linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt' + - compiler: ": No VFIO" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-vfio' + - compiler: ": No UIO" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-uio' + - compiler: ": No VFIO/UIO" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-uio --without-vfio' + - compiler: ": Non-wide ncurses" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncurses5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --with-curses=ncurses5' + - compiler: ": No curses" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-curses' + - compiler: ": No libudev" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-libudev' + - compiler: ": No libusb" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-libusb' + - compiler: ": No libevent" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libmicrohttpd-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-libevent' + - compiler: ": No libmicrohttpd" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libi2c-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-libmicrohttpd' + - compiler: ": No libi2c-dev" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev yasm libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --disable-knc --disable-titan --disable-kncasic' + - compiler: ": No yasm" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev libsensors4-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt' + - compiler: ": No libsensors" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev libi2c-dev yasm' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-sensors' + - compiler: ": No opt deps" + env: myCC='clang' EXTRA_DEPS='pkg-config' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-uio --without-vfio --without-sensors --without-libmicrohttpd --without-libevent --without-libusb --without-curses --without-libudev --disable-knc --disable-titan --disable-kncasic' + - compiler: ": Only ncurses" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--enable-other-drivers --enable-keccak --enable-scrypt --without-uio --without-vfio --without-sensors --without-libmicrohttpd --without-libevent --without-libusb --without-libudev --disable-knc --disable-titan --disable-kncasic' + - compiler: ": Only CPU" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev yasm' CONFIGURE_ARGS='--disable-other-drivers --enable-cpumining --enable-keccak --enable-scrypt' + - compiler: ": Only OpenCL" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev libsensors4-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-opencl --enable-keccak --enable-scrypt' + - compiler: ": OpenCL w/o ADL" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev libsensors4-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-opencl --enable-keccak --enable-scrypt --disable-adl' + - compiler: ": OpenCL w/o sensors" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-opencl --enable-keccak --enable-scrypt' + - compiler: ": OpenCL w/o ADL or sensors" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-opencl --enable-keccak --enable-scrypt --disable-adl' + - compiler: ": Only alchemist" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-scrypt --enable-alchemist' + - compiler: ": Only bitforce" + env: myCC='clang' UBUNTU_DEPS='linux-libc-dev' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitforce' + - compiler: ": Only bitmain" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitmain' + - compiler: ": Only icarus" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-icarus' + - compiler: ": Only dualminer" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-icarus --enable-dualminer --enable-scrypt' + - compiler: ": Only zeusminer" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-icarus --enable-zeusminer --enable-scrypt' + - compiler: ": Only gridseed" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-gridseed --enable-scrypt' + - compiler: ": Only avalon" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-avalon' + - compiler: ": Only avalonmm" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-avalonmm' + - compiler: ": Only knc" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev libi2c-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-knc' + - compiler: ": Only kncasic" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev libi2c-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-scrypt --enable-kncasic' + - compiler: ": Only modminer" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-modminer' + - compiler: ": Only cointerra" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev libusb-1.0-0-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-cointerra' + - compiler: ": Only klondike" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev libusb-1.0-0-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-klondike' + - compiler: ": Only titan" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev libi2c-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-scrypt --enable-titan' + - compiler: ": Only x6500" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev libusb-1.0-0-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-x6500' + - compiler: ": Only ztex" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev libusb-1.0-0-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-ztex' + - compiler: ": Only bifury" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bifury' + - compiler: ": Only bitfury" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitfury' + - compiler: ": Only bfsb" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitfury --enable-bfsb' + - compiler: ": Only bigpic" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitfury --enable-bigpic' + - compiler: ": Only bfx" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev libusb-1.0-0-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitfury --enable-bfx' + - compiler: ": Only drillbit" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitfury --enable-drillbit' + - compiler: ": Only twinfury" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitfury --enable-twinfury' + - compiler: ": Only littlefury" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitfury --enable-littlefury' + - compiler: ": Only nanofury" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitfury --enable-nanofury' + - compiler: ": Only hashbuster" + env: myCC='clang' UBUNTU_DEPS='libhidapi-dev' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitfury --enable-hashbuster' + - compiler: ": Only hashbusterusb" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev libusb-1.0-0-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitfury --enable-hashbusterusb' + - compiler: ": Only hashfast" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-hashfast' + - compiler: ": Only jingtian" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-jingtian' + - compiler: ": Only metabank" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-bitfury --enable-metabank' + - compiler: ": Only minergate" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-minergate' + - compiler: ": Only minion" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-minion' + - compiler: ": Only rockminer" + env: myCC='clang' EXTRA_DEPS='pkg-config libncursesw5-dev' CONFIGURE_ARGS='--disable-other-drivers --enable-rockminer' + exclude: + - compiler: gcc +install: + - bash .travis.deps I-am-okay-with-destroying-my-system +script: + - bash .travis.script I-am-okay-with-destroying-my-system diff --git a/70-bfgminer.rules.in b/70-bfgminer.rules.in new file mode 100644 index 0000000000..def58d4745 --- /dev/null +++ b/70-bfgminer.rules.in @@ -0,0 +1,65 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="add", SUBSYSTEMS=="usb", GOTO="bfgminer_start" +GOTO="bfgminer_end" +LABEL="bfgminer_start" + +@USE_BIFURY_TRUE@ENV{ID_MODEL}=="*bi•fury*", GOTO="bfgminer_add" +@USE_BIGPIC_TRUE@ENV{ID_MODEL}=="*Bitfury*BF1*", GOTO="bfgminer_add" +@USE_BITFORCE_TRUE@ENV{ID_MODEL}=="*BitFORCE*SHA256*", GOTO="bfgminer_add" +@USE_COINTERRA_TRUE@ENV{ID_MODEL}=="*GoldStrike*", GOTO="bfgminer_add" +@USE_DRILLBIT_TRUE@ENV{manufacturer}=="*Drillbit*", GOTO="bfgminer_add" +@USE_ICARUS_TRUE@ENV{ID_MODEL}=="*Antminer*", GOTO="bfgminer_add" +@USE_ICARUS_TRUE@ENV{ID_MODEL}=="*Cairnsmore1*", GOTO="bfgminer_add" +@USE_ICARUS_TRUE@ENV{ID_MODEL}=="*Compac*Bitcoin*", GOTO="bfgminer_add" +@USE_ICARUS_TRUE@ENV{ID_MODEL}=="*Block*Erupter*", GOTO="bfgminer_add" +@USE_HASHBUSTER_TRUE@ENV{ID_MODEL}=="*HashBuster*", GOTO="bfgminer_add" +@USE_HASHBUSTERUSB_TRUE@ENV{ID_MODEL}=="*HashBuster*", GOTO="bfgminer_add" +@USE_HASHFAST_TRUE@ENV{idVendor}=="297c", ENV{manufacturer}=="*HashFast*", GOTO="bfgminer_add" +@USE_HASHFAST_TRUE@ENV{ID_MODEL}=="*GoldenNonce*", GOTO="bfgminer_add" +@USE_KLONDIKE_TRUE@ENV{idVendor}=="04d8", ENV{idProduct}=="f60a", ENV{manufacturer}=="*Klondike*", GOTO="bfgminer_add" +@USE_KLONDIKE_TRUE@ENV{idVendor}=="fa05", ENV{idProduct}=="0001", ENV{manufacturer}=="*HashBuster*", GOTO="bfgminer_add" +@USE_LITTLEFURY_TRUE@ENV{ID_MODEL}=="*LittleFury*", GOTO="bfgminer_add" +@USE_MODMINER_TRUE@ENV{ID_MODEL}=="*ModMiner*", GOTO="bfgminer_add" +@USE_NANOFURY_TRUE@ENV{idVendor}=="04d8", ENV{idProduct}=="00de", ENV{ID_MODEL}=="*NanoFury*", GOTO="bfgminer_add" +@USE_ROCKMINER_TRUE@ENV{ID_MODEL}=="*R-BOX miner*", GOTO="bfgminer_add" +@USE_ROCKMINER_TRUE@ENV{ID_MODEL}=="*RX-BOX miner*", GOTO="bfgminer_add" +@USE_TWINFURY_TRUE@ENV{ID_MODEL}=="*Twinfury*", GOTO="bfgminer_add" +@USE_X6500_TRUE@ENV{idVendor}=="0403", ENV{idProduct}=="6001", ENV{ID_MODEL}=="*X6500 FPGA Miner*", GOTO="bfgminer_add" +@USE_ZTEX_TRUE@ENV{ID_MODEL}=="*btcminer for ZTEX*", GOTO="bfgminer_add" + +# The below are broad udev rules that may match devices other than the miners expected. +# You can uncomment them with the --enable-broad-udevrules configure option. + +# Avalon1 +@BROAD_UDEVRULES_TRUE@@USE_AVALON_TRUE@ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", GOTO="bfgminer_add" +# AvalonMM +@BROAD_UDEVRULES_TRUE@@USE_AVALONMM_TRUE@ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", GOTO="bfgminer_add" +# DualMiner +@BROAD_UDEVRULES_TRUE@@USE_DUALMINER_TRUE@ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", GOTO="bfgminer_add" +# GridSeed +@BROAD_UDEVRULES_TRUE@@USE_GRIDSEED_TRUE@ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", GOTO="bfgminer_add" +# Icarus +@BROAD_UDEVRULES_TRUE@@USE_ICARUS_TRUE@ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", GOTO="bfgminer_add" +# Cairnsmore1 +@BROAD_UDEVRULES_TRUE@@USE_ICARUS_TRUE@ATTRS{idVendor}=="067b", ATTRS{idProduct}=="0230", GOTO="bfgminer_add" +@BROAD_UDEVRULES_TRUE@@USE_ICARUS_TRUE@ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8350", GOTO="bfgminer_add" +# Block Erupter and Antminer U* +@BROAD_UDEVRULES_TRUE@@USE_ICARUS_TRUE@ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", GOTO="bfgminer_add" +# ZeusMiner +@BROAD_UDEVRULES_TRUE@@USE_ZEUSMINER_TRUE@ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", GOTO="bfgminer_add" +# Possibly unprogrammed ZTEX +@BROAD_UDEVRULES_TRUE@@USE_ZTEX_TRUE@ATTRS{idVendor}=="221a", ATTRS{idProduct}=="0100", GOTO="bfgminer_add" +# BFx2 +@BROAD_UDEVRULES_TRUE@@USE_BFX_TRUE@ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", GOTO="bfgminer_add" +# RockMiner +@BROAD_UDEVRULES_TRUE@@USE_ROCKMINER_TRUE@ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", GOTO="bfgminer_add" + +GOTO="bfgminer_end" + +LABEL="bfgminer_add" + +@USE_UDEVRULES_GROUP_TRUE@GROUP="@UDEVRULES_GROUP@" +ENV{ID_MM_DEVICE_IGNORE}="1" + +LABEL="bfgminer_end" diff --git a/ADL/adl_defines.h b/ADL/adl_defines.h new file mode 100644 index 0000000000..e4f5e550e6 --- /dev/null +++ b/ADL/adl_defines.h @@ -0,0 +1,782 @@ +/* The statements-of-fact provided herein are intended to be compatible with + * AMD ADL's library. AMD is the creator and copyright holder of the ADL + * library this interface describes, and therefore also defined this interface + * originally. + * These free interfaces were created by Luke Dashjr + * As interfaces/APIs cannot be copyrighted, there is no license needed in the + * USA and probably many other jurisdictions. + * If your jurisdiction rules otherwise, the header is offered by Luke Dashjr + * under the MIT license, but you are responsible for determining who your + * jurisdiction considers to be the copyright holder in such a case. + * + * THE INFORMATION IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE INFORMATION OR THE USE OR OTHER DEALINGS IN THE + * INFORMATION. + */ + +#ifndef ADL_DEFINES_H_ +#define ADL_DEFINES_H_ + +enum { + ADL_FALSE = 0, + ADL_TRUE = 1, +}; + +#define ADL_MAX_CHAR 4096 +#define ADL_MAX_PATH 256 +#define ADL_MAX_ADAPTERS 150 +#define ADL_MAX_DISPLAYS 150 +#define ADL_MAX_DEVICENAME 32 +#define ADL_ADAPTER_INDEX_ALL -1 +#define ADL_MAIN_API_OPTION_NONE 0 + +enum { + ADL_DDC_OPTION_SWITCHDDC2 = 1, + ADL_DDC_OPTION_RESTORECOMMAND = 2, +}; + +enum { + ADL_DL_I2C_ACTIONREAD = 1, + ADL_DL_I2C_ACTIONWRITE = 2, + ADL_DL_I2C_ACTIONREAD_REPEATEDSTART = 3, +}; + +enum { + ADL_OK_WAIT = 4, + ADL_OK_RESTART = 3, + ADL_OK_MODE_CHANGE = 2, + ADL_OK_WARNING = 1, + ADL_OK = 0, + ADL_ERR = -1, + ADL_ERR_NOT_INIT = -2, + ADL_ERR_INVALID_PARAM = -3, + ADL_ERR_INVALID_PARAM_SIZE = -4, + ADL_ERR_INVALID_ADL_IDX = -5, + ADL_ERR_INVALID_CONTROLLER_IDX = -6, + ADL_ERR_INVALID_DIPLAY_IDX = -7, + ADL_ERR_NOT_SUPPORTED = -8, + ADL_ERR_NULL_POINTER = -9, + ADL_ERR_DISABLED_ADAPTER = -10, + ADL_ERR_INVALID_CALLBACK = -11, + ADL_ERR_RESOURCE_CONFLICT = -12, +}; + +enum { + ADL_DT_MONITOR = 0, + ADL_DT_TELEVISION = 1, + ADL_DT_LCD_PANEL = 2, + ADL_DT_DIGITAL_FLAT_PANEL = 3, + ADL_DT_COMPONENT_VIDEO = 4, + ADL_DT_PROJECTOR = 5, +}; + +enum { + ADL_DOT_UNKNOWN = 0, + ADL_DOT_COMPOSITE = 1, + ADL_DOT_SVIDEO = 2, + ADL_DOT_ANALOG = 3, + ADL_DOT_DIGITAL = 4, +}; + +enum { + ADL_DISPLAY_COLOR_BRIGHTNESS = (1 << 0), + ADL_DISPLAY_COLOR_CONTRAST = (1 << 1), + ADL_DISPLAY_COLOR_SATURATION = (1 << 2), + ADL_DISPLAY_COLOR_HUE = (1 << 3), + ADL_DISPLAY_COLOR_TEMPERATURE = (1 << 4), + ADL_DISPLAY_COLOR_TEMPERATURE_SOURCE_EDID = (1 << 5), + ADL_DISPLAY_COLOR_TEMPERATURE_SOURCE_USER = (1 << 6), +}; + +enum { + ADL_DISPLAY_ADJUST_OVERSCAN = (1 << 0), + ADL_DISPLAY_ADJUST_VERT_POS = (1 << 1), + ADL_DISPLAY_ADJUST_HOR_POS = (1 << 2), + ADL_DISPLAY_ADJUST_VERT_SIZE = (1 << 3), + ADL_DISPLAY_ADJUST_HOR_SIZE = (1 << 4), + ADL_DISPLAY_ADJUST_SIZEPOS = (ADL_DISPLAY_ADJUST_VERT_POS | ADL_DISPLAY_ADJUST_HOR_POS | ADL_DISPLAY_ADJUST_VERT_SIZE | ADL_DISPLAY_ADJUST_HOR_SIZE), + ADL_DISPLAY_CUSTOMMODES = (1 << 5), + ADL_DISPLAY_ADJUST_UNDERSCAN = (1 << 6), +}; + +enum { + ADL_DESKTOPCONFIG_UNKNOWN = 0, + ADL_DESKTOPCONFIG_SINGLE = (1 << 0), + ADL_DESKTOPCONFIG_CLONE = (1 << 2), + ADL_DESKTOPCONFIG_BIGDESK_H = (1 << 4), + ADL_DESKTOPCONFIG_BIGDESK_V = (1 << 5), + ADL_DESKTOPCONFIG_BIGDESK_HR = (1 << 6), + ADL_DESKTOPCONFIG_BIGDESK_VR = (1 << 7), + ADL_DESKTOPCONFIG_RANDR12 = (1 << 8), +}; + +#define ADL_MAX_DISPLAY_NAME 256 + +enum { + ADL_DISPLAYDDCINFOEX_FLAG_PROJECTORDEVICE = (1 << 0), + ADL_DISPLAYDDCINFOEX_FLAG_EDIDEXTENSION = (1 << 1), + ADL_DISPLAYDDCINFOEX_FLAG_DIGITALDEVICE = (1 << 2), + ADL_DISPLAYDDCINFOEX_FLAG_HDMIAUDIODEVICE = (1 << 3), + ADL_DISPLAYDDCINFOEX_FLAG_SUPPORTS_AI = (1 << 4), + ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC601 = (1 << 5), + ADL_DISPLAYDDCINFOEX_FLAG_SUPPORT_xvYCC709 = (1 << 6), +}; + +enum { + ADL_DISPLAY_CONTYPE_UNKNOWN = 0, + ADL_DISPLAY_CONTYPE_VGA = 1, + ADL_DISPLAY_CONTYPE_DVI_D = 2, + ADL_DISPLAY_CONTYPE_DVI_I = 3, + ADL_DISPLAY_CONTYPE_ATICVDONGLE_NTSC = 4, + ADL_DISPLAY_CONTYPE_ATICVDONGLE_JPN = 5, + ADL_DISPLAY_CONTYPE_ATICVDONGLE_NONI2C_JPN = 6, + ADL_DISPLAY_CONTYPE_ATICVDONGLE_NONI2C_NTSC = 7, + ADL_DISPLAY_CONTYPE_HDMI_TYPE_A = 10, + ADL_DISPLAY_CONTYPE_HDMI_TYPE_B = 11, + ADL_DISPLAY_CONTYPE_SVIDEO = 12, + ADL_DISPLAY_CONTYPE_COMPOSITE = 13, + ADL_DISPLAY_CONTYPE_RCA_3COMPONENT = 14, + ADL_DISPLAY_CONTYPE_DISPLAYPORT = 15, +}; + +enum { + ADL_TV_STANDARDS = (1 << 0), + ADL_TV_SCART = (1 << 1), +}; + +enum { + ADL_STANDARD_NTSC_M = (1 << 0), + ADL_STANDARD_NTSC_JPN = (1 << 1), + ADL_STANDARD_NTSC_N = (1 << 2), + ADL_STANDARD_PAL_B = (1 << 3), + ADL_STANDARD_PAL_COMB_N = (1 << 4), + ADL_STANDARD_PAL_D = (1 << 5), + ADL_STANDARD_PAL_G = (1 << 6), + ADL_STANDARD_PAL_H = (1 << 7), + ADL_STANDARD_PAL_I = (1 << 8), + ADL_STANDARD_PAL_K = (1 << 9), + ADL_STANDARD_PAL_K1 = (1 << 10), + ADL_STANDARD_PAL_L = (1 << 11), + ADL_STANDARD_PAL_M = (1 << 12), + ADL_STANDARD_PAL_N = (1 << 13), + ADL_STANDARD_PAL_SECAM_D = (1 << 14), + ADL_STANDARD_PAL_SECAM_K = (1 << 15), + ADL_STANDARD_PAL_SECAM_K1 = (1 << 16), + ADL_STANDARD_PAL_SECAM_L = (1 << 17), +}; + +enum { + ADL_CUSTOMIZEDMODEFLAG_MODESUPPORTED = (1 << 0), + ADL_CUSTOMIZEDMODEFLAG_NOTDELETETABLE = (1 << 1), + ADL_CUSTOMIZEDMODEFLAG_INSERTBYDRIVER = (1 << 2), + ADL_CUSTOMIZEDMODEFLAG_INTERLACED = (1 << 3), + ADL_CUSTOMIZEDMODEFLAG_BASEMODE = (1 << 4), +}; + +enum { + ADL_DISPLAY_CV_DONGLE_D1 = (1 << 0), + ADL_DISPLAY_CV_DONGLE_D2 = (1 << 1), + ADL_DISPLAY_CV_DONGLE_D3 = (1 << 2), + ADL_DISPLAY_CV_DONGLE_D4 = (1 << 3), + ADL_DISPLAY_CV_DONGLE_D5 = (1 << 4), +}; + +enum { + ADL_DISPLAY_CV_DONGLE_480I = (1 << 0), + ADL_DISPLAY_CV_DONGLE_480P = (1 << 1), + ADL_DISPLAY_CV_DONGLE_540P = (1 << 2), + ADL_DISPLAY_CV_DONGLE_720P = (1 << 3), + ADL_DISPLAY_CV_DONGLE_1080I = (1 << 4), + ADL_DISPLAY_CV_DONGLE_1080P = (1 << 5), + ADL_DISPLAY_CV_DONGLE_16_9 = (1 << 6), + ADL_DISPLAY_CV_DONGLE_720P50 = (1 << 7), + ADL_DISPLAY_CV_DONGLE_1080I25 = (1 << 8), + ADL_DISPLAY_CV_DONGLE_576I25 = (1 << 9), + ADL_DISPLAY_CV_DONGLE_576P50 = (1 << 10), + ADL_DISPLAY_CV_DONGLE_1080P24 = (1 << 11), + ADL_DISPLAY_CV_DONGLE_1080P25 = (1 << 12), + ADL_DISPLAY_CV_DONGLE_1080P30 = (1 << 13), + ADL_DISPLAY_CV_DONGLE_1080P50 = (1 << 14), +}; + +enum { + ADL_DISPLAY_FORMAT_FORCE_720P = (1 << 0), + ADL_DISPLAY_FORMAT_FORCE_1080I = (1 << 1), + ADL_DISPLAY_FORMAT_FORCE_1080P = (1 << 2), + ADL_DISPLAY_FORMAT_FORCE_720P50 = (1 << 3), + ADL_DISPLAY_FORMAT_FORCE_1080I25 = (1 << 4), + ADL_DISPLAY_FORMAT_FORCE_576I25 = (1 << 5), + ADL_DISPLAY_FORMAT_FORCE_576P50 = (1 << 6), + ADL_DISPLAY_FORMAT_FORCE_1080P24 = (1 << 7), + ADL_DISPLAY_FORMAT_FORCE_1080P25 = (1 << 8), + ADL_DISPLAY_FORMAT_FORCE_1080P30 = (1 << 9), + ADL_DISPLAY_FORMAT_FORCE_1080P50 = (1 << 10), +}; + +enum { + ADL_DISPLAY_FORMAT_CVDONGLEOVERIDE = (1 << 0), + ADL_DISPLAY_FORMAT_CVMODEUNDERSCAN = (1 << 1), + ADL_DISPLAY_FORMAT_FORCECONNECT_SUPPORTED = (1 << 2), + ADL_DISPLAY_FORMAT_RESTRICT_FORMAT_SELECTION = (1 << 3), + ADL_DISPLAY_FORMAT_SETASPECRATIO = (1 << 4), + ADL_DISPLAY_FORMAT_FORCEMODES = (1 << 5), + ADL_DISPLAY_FORMAT_LCDRTCCOEFF = (1 << 6), +}; + +enum { + ADL_PM_PARAM_DONT_CHANGE = 0, +}; + +enum { + ADL_BUSTYPE_PCI = 0, + ADL_BUSTYPE_AGP = 1, + ADL_BUSTYPE_PCIE = 2, + ADL_BUSTYPE_PCIE_GEN2 = 3, +}; + +enum { + ADL_STEREO_OFF = 0, + ADL_STEREO_ACTIVE = (1 << 1), + ADL_STEREO_SUPPORTED = (1 << 2), + ADL_STEREO_BLUE_LINE = (1 << 3), + ADL_STEREO_PASSIVE = (1 << 6), + ADL_STEREO_PASSIVE_HORIZ = (1 << 7), + ADL_STEREO_PASSIVE_VERT = (1 << 8), + ADL_STEREO_AUTO_HORIZONTAL = (1 << 30), + ADL_STEREO_AUTO_VERTICAL = (1 << 31), +}; + +enum { + ADL_WORKSTATION_LOADBALANCING_SUPPORTED = 1, + ADL_WORKSTATION_LOADBALANCING_AVAILABLE = 2, +}; + +enum { + ADL_WORKSTATION_LOADBALANCING_DISABLED = 0, + ADL_WORKSTATION_LOADBALANCING_ENABLED = 1, +}; + +enum { + ADL_CONTEXT_SPEED_UNFORCED = 0, + ADL_CONTEXT_SPEED_FORCEHIGH = 1, + ADL_CONTEXT_SPEED_FORCELOW = 2, +}; + +enum { + ADL_ADAPTER_SPEEDCAPS_SUPPORTED = (1 << 0), +}; + +enum { + ADL_GLSYNC_PORT_UNKNOWN = 0, + ADL_GLSYNC_PORT_BNC = 1, + ADL_GLSYNC_PORT_RJ45PORT1 = 2, + ADL_GLSYNC_PORT_RJ45PORT2 = 3, +}; + +enum { + ADL_GLSYNC_CONFIGMASK_NONE = 0, + ADL_GLSYNC_CONFIGMASK_SIGNALSOURCE = (1 << 0), + ADL_GLSYNC_CONFIGMASK_SYNCFIELD = (1 << 1), + ADL_GLSYNC_CONFIGMASK_SAMPLERATE = (1 << 2), + ADL_GLSYNC_CONFIGMASK_SYNCDELAY = (1 << 3), + ADL_GLSYNC_CONFIGMASK_TRIGGEREDGE = (1 << 4), + ADL_GLSYNC_CONFIGMASK_SCANRATECOEFF = (1 << 5), + ADL_GLSYNC_CONFIGMASK_FRAMELOCKCNTL = (1 << 6), +}; + +enum { + ADL_GLSYNC_FRAMELOCKCNTL_NONE = 0, + ADL_GLSYNC_FRAMELOCKCNTL_ENABLE = (1 << 0), + ADL_GLSYNC_FRAMELOCKCNTL_DISABLE = (1 << 1), + ADL_GLSYNC_FRAMELOCKCNTL_SWAP_COUNTER_RESET = (1 << 2), + ADL_GLSYNC_FRAMELOCKCNTL_SWAP_COUNTER_ACK = (1 << 3), + ADL_GLSYNC_FRAMELOCKCNTL_STATE_ENABLE = (1 << 0), +}; + +enum { + ADL_GLSYNC_COUNTER_SWAP = (1 << 0), +}; + +enum { + ADL_GLSYNC_SIGNALSOURCE_UNDEFINED = 0x0100, + ADL_GLSYNC_SIGNALSOURCE_FREERUN = 0x0101, + ADL_GLSYNC_SIGNALSOURCE_BNCPORT = 0x0102, + ADL_GLSYNC_SIGNALSOURCE_RJ45PORT1 = 0x0103, + ADL_GLSYNC_SIGNALSOURCE_RJ45PORT2 = 0x0104, +}; + +enum { + ADL_GLSYNC_SIGNALTYPE_UNDEFINED = 0, + ADL_GLSYNC_SIGNALTYPE_480I = 1, + ADL_GLSYNC_SIGNALTYPE_576I = 2, + ADL_GLSYNC_SIGNALTYPE_480P = 3, + ADL_GLSYNC_SIGNALTYPE_576P = 4, + ADL_GLSYNC_SIGNALTYPE_720P = 5, + ADL_GLSYNC_SIGNALTYPE_1080P = 6, + ADL_GLSYNC_SIGNALTYPE_1080I = 7, + ADL_GLSYNC_SIGNALTYPE_SDI = 8, + ADL_GLSYNC_SIGNALTYPE_TTL = 9, + ADL_GLSYNC_SIGNALTYPE_ANALOG = 10, +}; + +enum { + ADL_GLSYNC_SYNCFIELD_UNDEFINED = 0, + ADL_GLSYNC_SYNCFIELD_BOTH = 1, + ADL_GLSYNC_SYNCFIELD_1 = 2, +}; + +enum { + ADL_GLSYNC_TRIGGEREDGE_UNDEFINED = 0, + ADL_GLSYNC_TRIGGEREDGE_RISING = 1, + ADL_GLSYNC_TRIGGEREDGE_FALLING = 2, + ADL_GLSYNC_TRIGGEREDGE_BOTH = 3, +}; + +enum { + ADL_GLSYNC_SCANRATECOEFF_UNDEFINED = 0, + ADL_GLSYNC_SCANRATECOEFF_x5 = 1, + ADL_GLSYNC_SCANRATECOEFF_x4 = 2, + ADL_GLSYNC_SCANRATECOEFF_x3 = 3, + ADL_GLSYNC_SCANRATECOEFF_x5_DIV_2 = 4, + ADL_GLSYNC_SCANRATECOEFF_x2 = 5, + ADL_GLSYNC_SCANRATECOEFF_x3_DIV_2 = 6, + ADL_GLSYNC_SCANRATECOEFF_x5_DIV_4 = 7, + ADL_GLSYNC_SCANRATECOEFF_x1 = 8, + ADL_GLSYNC_SCANRATECOEFF_x4_DIV_5 = 9, + ADL_GLSYNC_SCANRATECOEFF_x2_DIV_3 = 10, + ADL_GLSYNC_SCANRATECOEFF_x1_DIV_2 = 11, + ADL_GLSYNC_SCANRATECOEFF_x2_DIV_5 = 12, + ADL_GLSYNC_SCANRATECOEFF_x1_DIV_3 = 13, + ADL_GLSYNC_SCANRATECOEFF_x1_DIV_4 = 14, + ADL_GLSYNC_SCANRATECOEFF_x1_DIV_5 = 15, +}; + +enum { + ADL_GLSYNC_PORTSTATE_UNDEFINED = 0, + ADL_GLSYNC_PORTSTATE_NOCABLE = 1, + ADL_GLSYNC_PORTSTATE_IDLE = 2, + ADL_GLSYNC_PORTSTATE_INPUT = 3, + ADL_GLSYNC_PORTSTATE_OUTPUT = 4, +}; + +enum { + ADL_GLSYNC_LEDTYPE_BNC = 0, + ADL_GLSYNC_LEDTYPE_RJ45_LEFT = 0, + ADL_GLSYNC_LEDTYPE_RJ45_RIGHT = 1, +}; + +enum { + ADL_GLSYNC_LEDCOLOR_UNDEFINED = 0, + ADL_GLSYNC_LEDCOLOR_NOLIGHT = 1, + ADL_GLSYNC_LEDCOLOR_YELLOW = 2, + ADL_GLSYNC_LEDCOLOR_RED = 3, + ADL_GLSYNC_LEDCOLOR_GREEN = 4, + ADL_GLSYNC_LEDCOLOR_FLASH_GREEN = 5, +}; + +enum { + ADL_GLSYNC_PORTCNTL_NONE = 0, + ADL_GLSYNC_PORTCNTL_OUTPUT = 1, +}; + +enum { + ADL_GLSYNC_MODECNTL_NONE = 0, + ADL_GLSYNC_MODECNTL_GENLOCK = 1, + ADL_GLSYNC_MODECNTL_TIMINGSERVER = 2, +}; + +enum { + ADL_GLSYNC_MODECNTL_STATUS_NONE = 0, + ADL_GLSYNC_MODECNTL_STATUS_GENLOCK = (1 << 0), + ADL_GLSYNC_MODECNTL_STATUS_SETMODE_REQUIRED = (1 << 1), + ADL_GLSYNC_MODECNTL_STATUS_GENLOCK_ALLOWED = (1 << 2), +}; + +#define ADL_MAX_GLSYNC_PORTS 8 +#define ADL_MAX_GLSYNC_PORT_LEDS 8 + +enum { + ADL_XFIREX_STATE_NOINTERCONNECT = (1 << 0), + ADL_XFIREX_STATE_DOWNGRADEPIPES = (1 << 1), + ADL_XFIREX_STATE_DOWNGRADEMEM = (1 << 2), + ADL_XFIREX_STATE_REVERSERECOMMENDED = (1 << 3), + ADL_XFIREX_STATE_3DACTIVE = (1 << 4), + ADL_XFIREX_STATE_MASTERONSLAVE = (1 << 5), + ADL_XFIREX_STATE_NODISPLAYCONNECT = (1 << 6), + ADL_XFIREX_STATE_NOPRIMARYVIEW = (1 << 7), + ADL_XFIREX_STATE_DOWNGRADEVISMEM = (1 << 8), + ADL_XFIREX_STATE_LESSTHAN8LANE_MASTER = (1 << 9), + ADL_XFIREX_STATE_LESSTHAN8LANE_SLAVE = (1 << 10), + ADL_XFIREX_STATE_PEERTOPEERFAILED = (1 << 11), + ADL_XFIREX_STATE_MEMISDOWNGRADED = (1 << 16), + ADL_XFIREX_STATE_PIPESDOWNGRADED = (1 << 17), + ADL_XFIREX_STATE_XFIREXACTIVE = (1 << 18), + ADL_XFIREX_STATE_VISMEMISDOWNGRADED = (1 << 19), + ADL_XFIREX_STATE_INVALIDINTERCONNECTION = (1 << 20), + ADL_XFIREX_STATE_NONP2PMODE = (1 << 21), + ADL_XFIREX_STATE_DOWNGRADEMEMBANKS = (1 << 22), + ADL_XFIREX_STATE_MEMBANKSDOWNGRADED = (1 << 23), + ADL_XFIREX_STATE_DUALDISPLAYSALLOWED = (1 << 24), + ADL_XFIREX_STATE_P2P_APERTURE_MAPPING = (1 << 25), + ADL_XFIREX_STATE_P2PFLUSH_REQUIRED = ADL_XFIREX_STATE_P2P_APERTURE_MAPPING, + ADL_XFIREX_STATE_XSP_CONNECTED = (1 << 26), + ADL_XFIREX_STATE_ENABLE_CF_REBOOT_REQUIRED = (1 << 27), + ADL_XFIREX_STATE_DISABLE_CF_REBOOT_REQUIRED = (1 << 28), + ADL_XFIREX_STATE_DRV_HANDLE_DOWNGRADE_KEY = (1 << 29), + ADL_XFIREX_STATE_CF_RECONFIG_REQUIRED = (1 << 30), + ADL_XFIREX_STATE_ERRORGETTINGSTATUS = (1 << 31), +}; + +enum { + ADL_DISPLAY_PIXELFORMAT_UNKNOWN = 0, + ADL_DISPLAY_PIXELFORMAT_RGB = (1 << 0), + ADL_DISPLAY_PIXELFORMAT_YCRCB444 = (1 << 1), + ADL_DISPLAY_PIXELFORMAT_YCRCB422 = (1 << 2), + ADL_DISPLAY_PIXELFORMAT_RGB_LIMITED_RANGE = (1 << 3), + ADL_DISPLAY_PIXELFORMAT_RGB_FULL_RANGE = ADL_DISPLAY_PIXELFORMAT_RGB +}; + +enum { + ADL_DL_DISPLAYCONFIG_CONTYPE_UNKNOWN = 0, + ADL_DL_DISPLAYCONFIG_CONTYPE_CV_NONI2C_JP = 1, + ADL_DL_DISPLAYCONFIG_CONTYPE_CV_JPN = 2, + ADL_DL_DISPLAYCONFIG_CONTYPE_CV_NA = 3, + ADL_DL_DISPLAYCONFIG_CONTYPE_CV_NONI2C_NA = 4, + ADL_DL_DISPLAYCONFIG_CONTYPE_VGA = 5, + ADL_DL_DISPLAYCONFIG_CONTYPE_DVI_D = 6, + ADL_DL_DISPLAYCONFIG_CONTYPE_DVI_I = 7, + ADL_DL_DISPLAYCONFIG_CONTYPE_HDMI_TYPE_A = 8, + ADL_DL_DISPLAYCONFIG_CONTYPE_HDMI_TYPE_B = 9, + ADL_DL_DISPLAYCONFIG_CONTYPE_DISPLAYPORT = 10, +}; + +enum { + ADL_DISPLAY_DISPLAYINFO_DISPLAYCONNECTED = (1 << 0), + ADL_DISPLAY_DISPLAYINFO_DISPLAYMAPPED = (1 << 1), + ADL_DISPLAY_DISPLAYINFO_NONLOCAL = (1 << 2), + ADL_DISPLAY_DISPLAYINFO_FORCIBLESUPPORTED = (1 << 3), + ADL_DISPLAY_DISPLAYINFO_GENLOCKSUPPORTED = (1 << 4), + ADL_DISPLAY_DISPLAYINFO_MULTIVPU_SUPPORTED = (1 << 5), + ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_SINGLE = (1 << 8), + ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_CLONE = (1 << 9), + ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2VSTRETCH = (1 << 10), + ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_2HSTRETCH = (1 << 11), + ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_EXTENDED = (1 << 12), + ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCH1GPU = (1 << 16), + ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_NSTRETCHNGPU = (1 << 17), + ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED2 = (1 << 18), + ADL_DISPLAY_DISPLAYINFO_MANNER_SUPPORTED_RESERVED3 = (1 << 19), +}; + +enum { + ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NOTACTIVE = (1 << 0), + ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_SINGLE = (1 << 1), + ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_CLONE = (1 << 2), + ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NSTRETCH1GPU = (1 << 3), + ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_NSTRETCHNGPU = (1 << 4), + ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_2VSTRETCH = (1 << 5), + ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_2HSTRETCH = (1 << 6), + ADL_ADAPTER_DISPLAYCAP_MANNER_SUPPORTED_EXTENDED = (1 << 7), + ADL_ADAPTER_DISPLAYCAP_PREFERDISPLAY_SUPPORTED = (1 << 8), + ADL_ADAPTER_DISPLAYCAP_BEZEL_SUPPORTED = (1 << 9), +}; + +enum { + ADL_DISPLAY_DISPLAYMAP_MANNER_RESERVED = (1 << 0), + ADL_DISPLAY_DISPLAYMAP_MANNER_NOTACTIVE = (1 << 1), + ADL_DISPLAY_DISPLAYMAP_MANNER_SINGLE = (1 << 2), + ADL_DISPLAY_DISPLAYMAP_MANNER_CLONE = (1 << 3), + ADL_DISPLAY_DISPLAYMAP_MANNER_RESERVED1 = (1 << 4), + ADL_DISPLAY_DISPLAYMAP_MANNER_HSTRETCH = (1 << 5), + ADL_DISPLAY_DISPLAYMAP_MANNER_VSTRETCH = (1 << 6), + ADL_DISPLAY_DISPLAYMAP_MANNER_VLD = (1 << 7), +}; + +enum { + ADL_DISPLAY_DISPLAYMAP_OPTION_GPUINFO = 1, +}; + +enum { + ADL_DISPLAY_DISPLAYTARGET_PREFERRED = 1, +}; + +enum { + ADL_DISPLAY_POSSIBLEMAPRESULT_VALID = 1, + ADL_DISPLAY_POSSIBLEMAPRESULT_BEZELSUPPORTED = 2, +}; + +enum { + ADL_DISPLAY_MODE_COLOURFORMAT_565 = (1 << 0), + ADL_DISPLAY_MODE_COLOURFORMAT_8888 = (1 << 1), + ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_000 = (1 << 2), + ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_090 = (1 << 3), + ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_180 = (1 << 4), + ADL_DISPLAY_MODE_ORIENTATION_SUPPORTED_270 = (1 << 5), + ADL_DISPLAY_MODE_REFRESHRATE_ROUNDED = (1 << 6), + ADL_DISPLAY_MODE_REFRESHRATE_ONLY = (1 << 7), +}; + +enum { + ADL_DISPLAY_MODE_PROGRESSIVE_FLAG = 0, + ADL_DISPLAY_MODE_INTERLACED_FLAG = 2, +}; + +#define ADL_OSMODEINFOXPOS_DEFAULT -640 +#define ADL_OSMODEINFOYPOS_DEFAULT 0 +#define ADL_OSMODEINFOXRES_DEFAULT 640 +#define ADL_OSMODEINFOYRES_DEFAULT 480 +#define ADL_OSMODEINFOXRES_DEFAULT800 800 +#define ADL_OSMODEINFOYRES_DEFAULT600 600 +#define ADL_OSMODEINFOREFRESHRATE_DEFAULT 60 +#define ADL_OSMODEINFOCOLOURDEPTH_DEFAULT 8 +#define ADL_OSMODEINFOCOLOURDEPTH_DEFAULT16 16 +#define ADL_OSMODEINFOCOLOURDEPTH_DEFAULT24 24 +#define ADL_OSMODEINFOCOLOURDEPTH_DEFAULT32 32 +#define ADL_OSMODEINFOORIENTATION_DEFAULT 0 +#define ADL_OSMODEINFOORIENTATION_DEFAULT_WIN7 DISPLAYCONFIG_ROTATION_FORCE_UINT32 +#define ADL_OSMODEFLAG_DEFAULT 0 + +enum ADLPurposeCode { + ADL_PURPOSECODE_NORMAL = 0, + ADL_PURPOSECODE_HIDE_MODE_SWITCH, + ADL_PURPOSECODE_MODE_SWITCH, + ADL_PURPOSECODE_ATTATCH_DEVICE, + ADL_PURPOSECODE_DETACH_DEVICE, + ADL_PURPOSECODE_SETPRIMARY_DEVICE, + ADL_PURPOSECODE_GDI_ROTATION, + ADL_PURPOSECODE_ATI_ROTATION, +}; + +enum ADLAngle { + ADL_ANGLE_LANDSCAPE = 0, + ADL_ANGLE_ROTATERIGHT = 90, + ADL_ANGLE_ROTATE180 = 180, + ADL_ANGLE_ROTATELEFT = 270, +}; + +enum ADLOrientationDataType { + ADL_ORIENTATIONTYPE_OSDATATYPE, + ADL_ORIENTATIONTYPE_NONOSDATATYPE +}; + +enum ADLPanningMode { + ADL_PANNINGMODE_NO_PANNING = 0, + ADL_PANNINGMODE_AT_LEAST_ONE_NO_PANNING = 1, + ADL_PANNINGMODE_ALLOW_PANNING = 2, +}; + +enum ADLLARGEDESKTOPTYPE { + ADL_LARGEDESKTOPTYPE_NORMALDESKTOP = 0, + ADL_LARGEDESKTOPTYPE_PSEUDOLARGEDESKTOP = 1, + ADL_LARGEDESKTOPTYPE_VERYLARGEDESKTOP = 2, +}; + +#define ADL_I2C_MAJOR_API_REV 1 +#define ADL_I2C_MINOR_DEFAULT_API_REV 0 +#define ADL_I2C_MINOR_OEM_API_REV 1 + +enum { + ADL_DL_I2C_LINE_OEM = 1, + ADL_DL_I2C_LINE_OD_CONTROL = 2, + ADL_DL_I2C_LINE_OEM2 = 3, +}; + +#define ADL_DL_I2C_MAXDATASIZE 0x00000040 +#define ADL_DL_I2C_MAXWRITEDATASIZE 0x0000000C +#define ADL_DL_I2C_MAXADDRESSLENGTH 0x00000006 +#define ADL_DL_I2C_MAXOFFSETLENGTH 0x00000004 + +enum { + ADL_DL_DISPLAYPROPERTY_TYPE_UNKNOWN = 0, + ADL_DL_DISPLAYPROPERTY_TYPE_EXPANSIONMODE = 1, + ADL_DL_DISPLAYPROPERTY_TYPE_USEUNDERSCANSCALING = 2, +}; + +enum { + ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_CENTER = 0, + ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_FULLSCREEN = 1, + ADL_DL_DISPLAYPROPERTY_EXPANSIONMODE_ASPECTRATIO = 2, +}; + +enum { + ADL_DL_DISPLAY_DITHER_UNKNOWN = 0, + ADL_DL_DISPLAY_DITHER_DISABLED = 1, + ADL_DL_DISPLAY_DITHER_ENABLED = 2, +}; + +#define ADL_MAX_EDIDDATA_SIZE 256 +#define ADL_MAX_EDID_EXTENSION_BLOCKS 3 + +enum { + ADL_DL_CONTROLLER_OVERLAY_ALPHA = 0, + ADL_DL_CONTROLLER_OVERLAY_ALPHAPERPIX = 1, +}; + +enum { + ADL_DL_DISPLAY_DATA_PACKET__INFO_PACKET_RESET = 0, + ADL_DL_DISPLAY_DATA_PACKET__INFO_PACKET_SET = 1, +}; + +enum { + ADL_DL_DISPLAY_DATA_PACKET__TYPE__AVI = (1 << 0), + ADL_DL_DISPLAY_DATA_PACKET__TYPE__RESERVED = (1 << 1), + ADL_DL_DISPLAY_DATA_PACKET__TYPE__VENDORINFO = (1 << 2), +}; + +enum { + ADL_GAMUT_MATRIX_SD = 1, + ADL_GAMUT_MATRIX_HD = 2, +}; + +enum { + ADL_DL_CLOCKINFO_FLAG_FULLSCREEN3DONLY = (1 << 0), + ADL_DL_CLOCKINFO_FLAG_ALWAYSFULLSCREEN3D = (1 << 1), + ADL_DL_CLOCKINFO_FLAG_VPURECOVERYREDUCED = (1 << 2), + ADL_DL_CLOCKINFO_FLAG_THERMALPROTECTION = (1 << 3), +}; + +enum { + ADL_DL_POWERXPRESS_GPU_INTEGRATED = 1, + ADL_DL_POWERXPRESS_GPU_DISCRETE = 2, +}; + +enum { + ADL_DL_POWERXPRESS_SWITCH_RESULT_STARTED = 1, + ADL_DL_POWERXPRESS_SWITCH_RESULT_DECLINED = 2, + ADL_DL_POWERXPRESS_SWITCH_RESULT_ALREADY = 3, +}; + +#define ADL_DL_POWERXPRESS_VERSION_MAJOR 2 +#define ADL_DL_POWERXPRESS_VERSION_MINOR 0 +#define ADL_DL_POWERXPRESS_VERSION (((ADL_DL_POWERXPRESS_VERSION_MAJOR) << 16) | ADL_DL_POWERXPRESS_VERSION_MINOR) + +enum { + ADL_DL_THERMAL_DOMAIN_OTHER = 0, + ADL_DL_THERMAL_DOMAIN_GPU = 1, +}; + +enum { + ADL_DL_THERMAL_FLAG_INTERRUPT = 1, + ADL_DL_THERMAL_FLAG_FANCONTROL = 2, +}; + +enum { + ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ = (1 << 0), + ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE = (1 << 1), + ADL_DL_FANCTRL_SUPPORTS_RPM_READ = (1 << 2), + ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE = (1 << 3), +}; + +enum { + ADL_DL_FANCTRL_SPEED_TYPE_PERCENT = 1, + ADL_DL_FANCTRL_SPEED_TYPE_RPM = 2, +}; + +enum { + ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED = 1, +}; + +#define ADL_DL_MAX_MVPU_ADAPTERS 4 + +enum { + MVPU_ADAPTER_0 = (1 << 0), + MVPU_ADAPTER_1 = (1 << 1), + MVPU_ADAPTER_2 = (1 << 2), + MVPU_ADAPTER_3 = (1 << 3), +}; + +#define ADL_DL_MAX_REGISTRY_PATH 256 + +enum { + ADL_DL_MVPU_STATUS_OFF = 0, + ADL_DL_MVPU_STATUS_ON = 1, +}; + +enum { + ADL_ASIC_UNDEFINED = 0, + ADL_ASIC_DISCRETE = (1 << 0), + ADL_ASIC_INTEGRATED = (1 << 1), + ADL_ASIC_FIREGL = (1 << 2), + ADL_ASIC_FIREMV = (1 << 3), + ADL_ASIC_XGP = (1 << 4), + ADL_ASIC_FUSION = (1 << 5), +}; + +enum { + ADL_DL_TIMINGFLAG_DOUBLE_SCAN = (1 << 0), + ADL_DL_TIMINGFLAG_INTERLACED = (1 << 1), + ADL_DL_TIMINGFLAG_H_SYNC_POLARITY = (1 << 2), + ADL_DL_TIMINGFLAG_V_SYNC_POLARITY = (1 << 3), +}; + +enum { + ADL_DL_MODETIMING_STANDARD_CVT = (1 << 0), + ADL_DL_MODETIMING_STANDARD_GTF = (1 << 1), + ADL_DL_MODETIMING_STANDARD_DMT = (1 << 2), + ADL_DL_MODETIMING_STANDARD_CUSTOM = (1 << 3), + ADL_DL_MODETIMING_STANDARD_DRIVER_DEFAULT = (1 << 4), +}; + +enum { + ADL_XSERVERINFO_XINERAMAACTIVE = (1 << 0), + ADL_XSERVERINFO_RANDR12SUPPORTED = (1 << 1), +}; + +enum { + ADL_CONTROLLERVECTOR_0 = 1, + ADL_CONTROLLERVECTOR_1 = 2, +}; + +enum { + ADL_DISPLAY_SLSGRID_ORIENTATION_000 = (1 << 0), + ADL_DISPLAY_SLSGRID_ORIENTATION_090 = (1 << 1), + ADL_DISPLAY_SLSGRID_ORIENTATION_180 = (1 << 2), + ADL_DISPLAY_SLSGRID_ORIENTATION_270 = (1 << 3), +}; + +enum { + ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_LANDSCAPE = (1 << 0), + ADL_DISPLAY_SLSGRID_CAP_OPTION_RELATIVETO_CURRENTANGLE = (1 << 1), + ADL_DISPLAY_SLSGRID_PORTAIT_MODE = (1 << 2), +}; + +enum { + ADL_DISPLAY_SLSMAPCONFIG_GET_OPTION_RELATIVETO_LANDSCAPE = 1, + ADL_DISPLAY_SLSMAPCONFIG_GET_OPTION_RELATIVETO_CURRENTANGLE = 2, +}; + +enum { + ADL_DISPLAY_SLSMAPCONFIG_CREATE_OPTION_RELATIVETO_LANDSCAPE = 1, + ADL_DISPLAY_SLSMAPCONFIG_CREATE_OPTION_RELATIVETO_CURRENTANGLE = 2, +}; + +enum { + ADL_DISPLAY_SLSMAPCONFIG_REARRANGE_OPTION_RELATIVETO_LANDSCAPE = 1, + ADL_DISPLAY_SLSMAPCONFIG_REARRANGE_OPTION_RELATIVETO_CURRENTANGLE = 2, +}; + +enum { + ADL_DISPLAY_SLSGRID_RELATIVETO_LANDSCAPE = 0x10, + ADL_DISPLAY_SLSGRID_RELATIVETO_CURRENTANGLE = 0x20, +}; + +enum { + ADL_DISPLAY_SLSMAP_BEZELMODE = (1 << 4), + ADL_DISPLAY_SLSMAP_DISPLAYARRANGED = (1 << 1), + ADL_DISPLAY_SLSMAP_CURRENTCONFIG = (1 << 2), +}; + +enum { + ADL_DISPLAY_SLSMAPINDEXLIST_OPTION_ACTIVE = 1, +}; + +enum { + ADL_DISPLAY_BEZELOFFSET_STEPBYSTEPSET = (1 << 2), + ADL_DISPLAY_BEZELOFFSET_COMMIT = (1 << 3), +}; + +#endif /* ADL_DEFINES_H_ */ diff --git a/ADL/adl_sdk.h b/ADL/adl_sdk.h new file mode 100644 index 0000000000..9151dc6f71 --- /dev/null +++ b/ADL/adl_sdk.h @@ -0,0 +1,32 @@ +/* The statements-of-fact provided herein are intended to be compatible with + * AMD ADL's library. AMD is the creator and copyright holder of the ADL + * library this interface describes, and therefore also defined this interface + * originally. + * These free interfaces were created by Luke Dashjr + * As interfaces/APIs cannot be copyrighted, there is no license needed in the + * USA and probably many other jurisdictions. + * If your jurisdiction rules otherwise, the header is offered by Luke Dashjr + * under the MIT license, but you are responsible for determining who your + * jurisdiction considers to be the copyright holder in such a case. + * + * THE INFORMATION IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE INFORMATION OR THE USE OR OTHER DEALINGS IN THE + * INFORMATION. + */ + +#ifndef ADL_SDK_H_ +#define ADL_SDK_H_ + +#include "adl_structures.h" + +typedef void*( +#ifdef __stdcall + __stdcall +#endif +*ADL_MAIN_MALLOC_CALLBACK)(int); + +#endif /* ADL_SDK_H_ */ diff --git a/ADL/adl_structures.h b/ADL/adl_structures.h new file mode 100644 index 0000000000..b9a6c2baed --- /dev/null +++ b/ADL/adl_structures.h @@ -0,0 +1,572 @@ +/* The statements-of-fact provided herein are intended to be compatible with + * AMD ADL's library. AMD is the creator and copyright holder of the ADL + * library this interface describes, and therefore also defined this interface + * originally. + * These free interfaces were created by Luke Dashjr + * As interfaces/APIs cannot be copyrighted, there is no license needed in the + * USA and probably many other jurisdictions. + * If your jurisdiction rules otherwise, the header is offered by Luke Dashjr + * under the MIT license, but you are responsible for determining who your + * jurisdiction considers to be the copyright holder in such a case. + * + * THE INFORMATION IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE INFORMATION OR THE USE OR OTHER DEALINGS IN THE + * INFORMATION. + */ + +#ifndef ADL_STRUCTURES_H_ +#define ADL_STRUCTURES_H_ + +#include "adl_defines.h" + +typedef struct AdapterInfo { + int iSize; + int iAdapterIndex; + char strUDID[ADL_MAX_PATH]; + int iBusNumber; + int iDeviceNumber; + int iFunctionNumber; + int iVendorID; + char strAdapterName[ADL_MAX_PATH]; + char strDisplayName[ADL_MAX_PATH]; + int iPresent; + +#ifdef WIN32 + int iExist; + char strDriverPath[ADL_MAX_PATH]; + char strDriverPathExt[ADL_MAX_PATH]; + char strPNPString[ADL_MAX_PATH]; + int iOSDisplayIndex; +#elif !defined(__APPLE__) /* Linux */ + int iXScreenNum; + int iDrvIndex; + char strXScreenConfigName[ADL_MAX_PATH]; +#endif /* Linux */ +} AdapterInfo, *LPAdapterInfo; + +#if !(defined(WIN32) || defined(__APPLE__)) +typedef struct XScreenInfo { + int iXScreenNum; + char strXScreenConfigName[ADL_MAX_PATH]; +} XScreenInfo, *LPXScreenInfo; +#endif /* Linux */ + +typedef struct ADLMemoryInfo { + long long iMemorySize; + char strMemoryType[ADL_MAX_PATH]; + long long iMemoryBandwidth; +} ADLMemoryInfo, *LPADLMemoryInfo; + +typedef struct ADLDDCInfo { + int ulSize; + int ulSupportsDDC; + int ulManufacturerID; + int ulProductID; + char cDisplayName[ADL_MAX_DISPLAY_NAME]; + int ulMaxHResolution; + int ulMaxVResolution; + int ulMaxRefresh; + int ulPTMCx; + int ulPTMCy; + int ulPTMRefreshRate; + int ulDDCInfoFlag; +} ADLDDCInfo, *LPADLDDCInfo; + +typedef struct ADLGamma { + float fRed; + float fGreen; + float fBlue; +} ADLGamma, *LPADLGamma; + +typedef struct ADLCustomMode { + int iFlags; + int iModeWidth; + int iModeHeight; + int iBaseModeWidth; + int iBaseModeHeight; + int iRefreshRate; +} ADLCustomMode, *LPADLCustomMode; + +typedef struct ADLGetClocksOUT { + long ulHighCoreClock; + long ulHighMemoryClock; + long ulHighVddc; + long ulCoreMin; + long ulCoreMax; + long ulMemoryMin; + long ulMemoryMax; + long ulActivityPercent; + long ulCurrentCoreClock; + long ulCurrentMemoryClock; + long ulReserved; +} ADLGetClocksOUT; + +typedef struct ADLDisplayConfig { + long ulSize; + long ulConnectorType; + long ulDeviceData; + long ulOverridedDeviceData; + long ulReserved; +} ADLDisplayConfig; + +typedef struct ADLDisplayID { + int iDisplayLogicalIndex; + int iDisplayPhysicalIndex; + int iDisplayLogicalAdapterIndex; + int iDisplayPhysicalAdapterIndex; +} ADLDisplayID, *LPADLDisplayID; + +typedef struct ADLDisplayInfo { + ADLDisplayID displayID; + int iDisplayControllerIndex; + char strDisplayName[ADL_MAX_PATH]; + char strDisplayManufacturerName[ADL_MAX_PATH]; + int iDisplayType; + int iDisplayOutputType; + int iDisplayConnector; + int iDisplayInfoMask; + int iDisplayInfoValue; +} ADLDisplayInfo, *LPADLDisplayInfo; + +typedef struct ADLDisplayMode { + int iPelsHeight; + int iPelsWidth; + int iBitsPerPel; + int iDisplayFrequency; +} ADLDisplayMode; + +typedef struct ADLDetailedTiming { + int iSize; + short sTimingFlags; + short sHTotal; + short sHDisplay; + short sHSyncStart; + short sHSyncWidth; + short sVTotal; + short sVDisplay; + short sVSyncStart; + short sVSyncWidth; + short sPixelClock; + short sHOverscanRight; + short sHOverscanLeft; + short sVOverscanBottom; + short sVOverscanTop; + short sOverscan8B; + short sOverscanGR; +} ADLDetailedTiming; + +typedef struct ADLDisplayModeInfo { + int iTimingStandard; + int iPossibleStandard; + int iRefreshRate; + int iPelsWidth; + int iPelsHeight; + ADLDetailedTiming sDetailedTiming; +} ADLDisplayModeInfo; + +typedef struct ADLDisplayProperty { + int iSize; + int iPropertyType; + int iExpansionMode; + int iSupport; + int iCurrent; + int iDefault; +} ADLDisplayProperty; + +typedef struct ADLClockInfo { + int iCoreClock; + int iMemoryClock; +} ADLClockInfo, *LPADLClockInfo; + +typedef struct ADLI2C { + int iSize; + int iLine; + int iAddress; + int iOffset; + int iAction; + int iSpeed; + int iDataSize; + char *pcData; +} ADLI2C; + +typedef struct ADLDisplayEDIDData { + int iSize; + int iFlag; + int iEDIDSize; + int iBlockIndex; + char cEDIDData[ADL_MAX_EDIDDATA_SIZE]; + int iReserved[4]; +} ADLDisplayEDIDData; + +typedef struct ADLControllerOverlayInput { + int iSize; + int iOverlayAdjust; + int iValue; + int iReserved; +} ADLControllerOverlayInput; + +typedef struct ADLAdjustmentinfo { + int iDefault; + int iMin; + int iMax; + int iStep; +} ADLAdjustmentinfo; + +typedef struct ADLControllerOverlayInfo { + int iSize; + ADLAdjustmentinfo sOverlayInfo; + int iReserved[3]; +} ADLControllerOverlayInfo; + +typedef struct ADLGLSyncModuleID { + int iModuleID; + int iGlSyncGPUPort; + int iFWBootSectorVersion; + int iFWUserSectorVersion; +} ADLGLSyncModuleID , *LPADLGLSyncModuleID; + +typedef struct ADLGLSyncPortCaps { + int iPortType; + int iNumOfLEDs; +} ADLGLSyncPortCaps, *LPADLGLSyncPortCaps; + +typedef struct ADLGLSyncGenlockConfig { + int iValidMask; + int iSyncDelay; + int iFramelockCntlVector; + int iSignalSource; + int iSampleRate; + int iSyncField; + int iTriggerEdge; + int iScanRateCoeff; +} ADLGLSyncGenlockConfig, *LPADLGLSyncGenlockConfig; + +typedef struct ADLGlSyncPortInfo { + int iPortType; + int iNumOfLEDs; + int iPortState; + int iFrequency; + int iSignalType; + int iSignalSource; +} ADLGlSyncPortInfo, *LPADLGlSyncPortInfo; + +typedef struct ADLGlSyncPortControl { + int iPortType; + int iControlVector; + int iSignalSource; +} ADLGlSyncPortControl; + +typedef struct ADLGlSyncMode { + int iControlVector; + int iStatusVector; + int iGLSyncConnectorIndex; +} ADLGlSyncMode, *LPADLGlSyncMode; + +typedef struct ADLGlSyncMode2 { + int iControlVector; + int iStatusVector; + int iGLSyncConnectorIndex; + int iDisplayIndex; +} ADLGlSyncMode2, *LPADLGlSyncMode2; + +typedef struct ADLInfoPacket { + char hb0; + char hb1; + char hb2; + char sb[28]; +} ADLInfoPacket; + +typedef struct ADLAVIInfoPacket { + char bPB3_ITC; + char bPB5; +} ADLAVIInfoPacket; + +typedef struct ADLODClockSetting { + int iDefaultClock; + int iCurrentClock; + int iMaxClock; + int iMinClock; + int iRequestedClock; + int iStepClock; +} ADLODClockSetting; + +typedef struct ADLAdapterODClockInfo { + int iSize; + int iFlags; + ADLODClockSetting sMemoryClock; + ADLODClockSetting sEngineClock; +} ADLAdapterODClockInfo; + +typedef struct ADLAdapterODClockConfig { + int iSize; + int iFlags; + int iMemoryClock; + int iEngineClock; +} ADLAdapterODClockConfig; + +typedef struct ADLPMActivity { + int iSize; + int iEngineClock; + int iMemoryClock; + int iVddc; + int iActivityPercent; + int iCurrentPerformanceLevel; + int iCurrentBusSpeed; + int iCurrentBusLanes; + int iMaximumBusLanes; + int iReserved; +} ADLPMActivity; + +typedef struct ADLThermalControllerInfo { + int iSize; + int iThermalDomain; + int iDomainIndex; + int iFlags; +} ADLThermalControllerInfo; + +typedef struct ADLTemperature { + int iSize; + int iTemperature; +} ADLTemperature; + +typedef struct ADLFanSpeedInfo { + int iSize; + int iFlags; + int iMinPercent; + int iMaxPercent; + int iMinRPM; + int iMaxRPM; +} ADLFanSpeedInfo; + +typedef struct ADLFanSpeedValue { + int iSize; + int iSpeedType; + int iFanSpeed; + int iFlags; +} ADLFanSpeedValue; + +typedef struct ADLODParameterRange { + int iMin; + int iMax; + int iStep; +} ADLODParameterRange; + +typedef struct ADLODParameters { + int iSize; + int iNumberOfPerformanceLevels; + int iActivityReportingSupported; + int iDiscretePerformanceLevels; + int iReserved; + ADLODParameterRange sEngineClock; + ADLODParameterRange sMemoryClock; + ADLODParameterRange sVddc; +} ADLODParameters; + +typedef struct ADLODPerformanceLevel { + int iEngineClock; + int iMemoryClock; + int iVddc; +} ADLODPerformanceLevel; + +typedef struct ADLODPerformanceLevels { + int iSize; + int iReserved; + ADLODPerformanceLevel aLevels[1]; +} ADLODPerformanceLevels; + +typedef struct ADLCrossfireComb { + int iNumLinkAdapter; + int iAdaptLink[3]; +} ADLCrossfireComb; + +typedef struct ADLCrossfireInfo { + int iErrorCode; + int iState; + int iSupported; +} ADLCrossfireInfo; + +typedef struct ADLBiosInfo { + char strPartNumber[ADL_MAX_PATH]; + char strVersion[ADL_MAX_PATH]; + char strDate[ADL_MAX_PATH]; +} ADLBiosInfo, *LPADLBiosInfo; + +typedef struct ADLAdapterLocation { + int iBus; + int iDevice; + int iFunction; +} ADLAdapterLocation; + +typedef struct ADLMVPUCaps { + int iSize; + int iAdapterCount; + int iPossibleMVPUMasters; + int iPossibleMVPUSlaves; + char cAdapterPath[ADL_DL_MAX_MVPU_ADAPTERS][ADL_DL_MAX_REGISTRY_PATH]; +} ADLMVPUCaps; + +typedef struct ADLMVPUStatus { + int iSize; + int iActiveAdapterCount; + int iStatus; + ADLAdapterLocation aAdapterLocation[ADL_DL_MAX_MVPU_ADAPTERS]; +} ADLMVPUStatus; + +typedef struct ADLActivatableSource { + int iAdapterIndex; + int iNumActivatableSources; + int iActivatableSourceMask; + int iActivatableSourceValue; +} ADLActivatableSource, *LPADLActivatableSource; + +typedef struct ADLMode { + int iAdapterIndex; + ADLDisplayID displayID; + int iXPos; + int iYPos; + int iXRes; + int iYRes; + int iColourDepth; + float fRefreshRate; + int iOrientation; + int iModeFlag; + int iModeMask; + int iModeValue; +} ADLMode, *LPADLMode; + +typedef struct ADLDisplayTarget { + ADLDisplayID displayID; + int iDisplayMapIndex; + int iDisplayTargetMask; + int iDisplayTargetValue; +} ADLDisplayTarget, *LPADLDisplayTarget; + +typedef struct tagADLBezelTransientMode { + int iAdapterIndex; + int iSLSMapIndex; + int iSLSModeIndex; + ADLMode displayMode; + int iNumBezelOffset; + int iFirstBezelOffsetArrayIndex; + int iSLSBezelTransientModeMask; + int iSLSBezelTransientModeValue; +} ADLBezelTransientMode, *LPADLBezelTransientMode; + +typedef struct ADLAdapterDisplayCap { + int iAdapterIndex; + int iAdapterDisplayCapMask; + int iAdapterDisplayCapValue; +} ADLAdapterDisplayCap, *LPADLAdapterDisplayCap; + +typedef struct ADLDisplayMap { + int iDisplayMapIndex; + ADLMode displayMode; + int iNumDisplayTarget; + int iFirstDisplayTargetArrayIndex; + int iDisplayMapMask; + int iDisplayMapValue; +} ADLDisplayMap, *LPADLDisplayMap; + +typedef struct ADLPossibleMap { + int iIndex; + int iAdapterIndex; + int iNumDisplayMap; + ADLDisplayMap* displayMap; + int iNumDisplayTarget; + ADLDisplayTarget* displayTarget; +} ADLPossibleMap, *LPADLPossibleMap; + +typedef struct ADLPossibleMapping { + int iDisplayIndex; + int iDisplayControllerIndex; + int iDisplayMannerSupported; +} ADLPossibleMapping, *LPADLPossibleMapping; + +typedef struct ADLPossibleMapResult { + int iIndex; + int iPossibleMapResultMask; + int iPossibleMapResultValue; +} ADLPossibleMapResult, *LPADLPossibleMapResult; + +typedef struct ADLSLSGrid { + int iAdapterIndex; + int iSLSGridIndex; + int iSLSGridRow; + int iSLSGridColumn; + int iSLSGridMask; + int iSLSGridValue; +} ADLSLSGrid, *LPADLSLSGrid; + +typedef struct ADLSLSMap { + int iAdapterIndex; + int iSLSMapIndex; + ADLSLSGrid grid; + int iSurfaceMapIndex; + int iOrientation; + int iNumSLSTarget; + int iFirstSLSTargetArrayIndex; + int iNumNativeMode; + int iFirstNativeModeArrayIndex; + int iNumBezelMode; + int iFirstBezelModeArrayIndex; + int iNumBezelOffset; + int iFirstBezelOffsetArrayIndex; + int iSLSMapMask; + int iSLSMapValue; +} ADLSLSMap, *LPADLSLSMap; + +typedef struct ADLSLSOffset { + int iAdapterIndex; + int iSLSMapIndex; + ADLDisplayID displayID; + int iBezelModeIndex; + int iBezelOffsetX; + int iBezelOffsetY; + int iDisplayWidth; + int iDisplayHeight; + int iBezelOffsetMask; + int iBezelffsetValue; +} ADLSLSOffset, *LPADLSLSOffset; + +typedef struct ADLSLSMode { + int iAdapterIndex; + int iSLSMapIndex; + int iSLSModeIndex; + ADLMode displayMode; + int iSLSNativeModeMask; + int iSLSNativeModeValue; +} ADLSLSMode, *LPADLSLSMode; + +typedef struct ADLPossibleSLSMap { + int iSLSMapIndex; + int iNumSLSMap; + ADLSLSMap* lpSLSMap; + int iNumSLSTarget; + ADLDisplayTarget* lpDisplayTarget; +} ADLPossibleSLSMap, *LPADLPossibleSLSMap; + +typedef struct ADLSLSTarget { + int iAdapterIndex; + int iSLSMapIndex; + ADLDisplayTarget displayTarget; + int iSLSGridPositionX; + int iSLSGridPositionY; + ADLMode viewSize; + int iSLSTargetMask; + int iSLSTargetValue; +} ADLSLSTarget, *LPADLSLSTarget; + +typedef struct ADLBezelOffsetSteppingSize { + int iAdapterIndex; + int iSLSMapIndex; + int iBezelOffsetSteppingSizeX; + int iBezelOffsetSteppingSizeY; + int iBezelOffsetSteppingSizeMask; + int iBezelOffsetSteppingSizeValue; +} ADLBezelOffsetSteppingSize, *LPADLBezelOffsetSteppingSize; + +#endif /* ADL_STRUCTURES_H_ */ diff --git a/ADL_SDK/.gitignore b/ADL_SDK/.gitignore deleted file mode 100644 index 05c579eed4..0000000000 --- a/ADL_SDK/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -adl_defines.h -adl_sdk.h -adl_structures.h diff --git a/ADL_SDK/readme.txt b/ADL_SDK/readme.txt deleted file mode 100644 index 9411e4b9c3..0000000000 --- a/ADL_SDK/readme.txt +++ /dev/null @@ -1,3 +0,0 @@ -Please insert AMD ADL files adl_defines.h adl_sdk.h adl_structures.h here. -They can be found here: -http://developer.amd.com/sdks/ADLSDK/Pages/default.aspx diff --git a/API-README b/API-README deleted file mode 100644 index 601ac1c9d8..0000000000 --- a/API-README +++ /dev/null @@ -1,526 +0,0 @@ - -This README contains details about the BFGMiner RPC API - - -If you start BFGMiner with the "--api-listen" option, it will listen on a -simple TCP/IP socket for single string API requests from the same machine -running BFGMiner and reply with a string and then close the socket each time -If you add the "--api-network" option, it will accept API requests from any -network attached computer. - -You can only access the comands that reply with data in this mode. -By default, you cannot access any privileged command that affects the miner - -you will receive an access denied status message see --api-allow below. - -You can specify IP addresses/prefixes that are only allowed to access the API -with the "--api-allow" option e.g. --api-allow W:192.168.0.1,10.0.0/24 -will allow 192.168.0.1 or any address matching 10.0.0.*, but nothing else -IP addresses are automatically padded with extra '.0's as needed -Without a /prefix is the same as specifying /32 -0/0 means all IP addresses. -The 'W:' on the front gives that address/subnet privileged access to commands -that modify BFGMiner (thus all API commands) -Without it those commands return an access denied status. -See --api-groups below to define other groups like W: -Privileged access is checked in the order the IP addresses were supplied to -"--api-allow" -The first match determines the privilege level. -Using the "--api-allow" option overides the "--api-network" option if they -are both specified -With "--api-allow", 127.0.0.1 is not by default given access unless specified - -More groups (like the privileged group W:) can be defined using the ---api-groups command -Valid groups are only the letters A-Z (except R & W are predefined) and are -not case sensitive -The R: group is the same as not privileged access -The W: group is (as stated) privileged access (thus all API commands) -To give an IP address/subnet access to a group you use the group letter -in front of the IP address instead of W: e.g. P:192.168.0/32 -An IP address/subnet can only be a member of one group -A sample API group would be: - --api-groups P:switchpool:enablepool:addpool:disablepool:removepool:* -This would create a group 'P' that can do all current pool commands and all -non-priviliged commands - the '*' means all non-priviledged commands -Without the '*' the group would only have access to the pool commands -Defining multiple groups example: - --api-groups Q:quit:restart:*,S:save -This would define 2 groups: - Q: that can 'quit' and 'restart' as well as all non-priviledged commands - S: that can only 'save' and no other commands - -The RPC API request can be either simple text or JSON. - -If the request is JSON (starts with '{'), it will reply with a JSON formatted -response, otherwise it replies with text formatted as described further below. - -The JSON request format required is '{"command":"CMD","parameter":"PARAM"}' -(though of course parameter is not required for all requests) -where "CMD" is from the "Request" column below and "PARAM" would be e.g. -the CPU/GPU number if required. - -An example request in both formats to set GPU 0 fan to 80%: - gpufan|0,80 - {"command":"gpufan","parameter":"0,80"} - -The format of each reply (unless stated otherwise) is a STATUS section -followed by an optional detail section - -From API version 1.7 onwards, reply strings in JSON and Text have the -necessary escaping as required to avoid ambiguity - they didn't before 1.7 -For JSON the 2 characters '"' and '\' are escaped with a '\' before them -For Text the 4 characters '|' ',' '=' and '\' are escaped the same way - -Only user entered information will contain characters that require being -escaped, such as Pool URL, User and Password or the Config save filename, -when they are returned in messages or as their values by the API - -For API version 1.4 and later: - -The STATUS section is: - - STATUS=X,When=NNN,Code=N,Msg=string,Description=string| - - STATUS=X Where X is one of: - W - Warning - I - Informational - S - Success - E - Error - F - Fatal (code bug) - - When=NNN - Standard long time of request in seconds - - Code=N - Each unique reply has a unigue Code (See api.c - #define MSG_NNNNNN) - - Msg=string - Message matching the Code value N - - Description=string - This defaults to the BFGMiner version but is the value of --api-description - if it was specified at runtime. - -For API version 1.10 and later: - -The list of requests - a (*) means it requires privileged access - and replies are: - - Request Reply Section Details - ------- ------------- ------- - version VERSION CGMiner=BFGMiner version - API=API version - - config CONFIG Some miner configuration information: - GPU Count=N, <- the number of GPUs - PGA Count=N, <- the number of PGAs - CPU Count=N, <- the number of CPUs - Pool Count=N, <- the number of Pools - ADL=X, <- Y or N if ADL is compiled in the code - ADL in use=X, <- Y or N if any GPU has ADL - Strategy=Name, <- the current pool strategy - Log Interval=N, <- log interval (--log N) - Device Code=GPU ICA | <- spaced list of compiled devices - - summary SUMMARY The status summary of the miner - e.g. Elapsed=NNN,Found Blocks=N,Getworks=N,...| - - pools POOLS The status of each pool - e.g. Pool=0,URL=http://pool.com:6311,Status=Alive,...| - - devs DEVS Each available GPU, PGA and CPU with their status - e.g. GPU=0,Accepted=NN,MHS av=NNN,...,Intensity=D| - Last Share Time=NNN, <- standand long time in seconds - (or 0 if none) of last accepted share - Last Share Pool=N, <- pool number (or -1 if none) - Will not report PGAs if PGA mining is disabled - Will not report CPUs if CPU mining is disabled - - devdetail DEVS Each available device with their fixed details - e.g. GPU=0,Driver=opencl,Kernel=diablo,Model=...| - - gpu|N GPU The details of a single GPU number N in the same - format and details as for DEVS - - pga|N PGA The details of a single PGA number N in the same - format and details as for DEVS - This is only available if PGA mining is enabled - Use 'pgacount' or 'config' first to see if there are any - - cpu|N CPU The details of a single CPU number N in the same - format and details as for DEVS - This is only available if CPU mining is enabled - Use 'cpucount' or 'config' first to see if there are any - - gpucount GPUS Count=N| <- the number of GPUs - - pgacount PGAS Count=N| <- the number of PGAs - Always returns 0 if PGA mining is disabled - - cpucount CPUS Count=N| <- the number of CPUs - Always returns 0 if CPU mining is disabled - - switchpool|N (*) - none There is no reply section just the STATUS section - stating the results of switching pool N to the - highest priority (the pool is also enabled) - The Msg includes the pool URL - - enablepool|N (*) - none There is no reply section just the STATUS section - stating the results of enabling pool N - The Msg includes the pool URL - - addpool|URL,USR,PASS (*) - none There is no reply section just the STATUS section - stating the results of attempting to add pool N - The Msg includes the pool URL - Use '\\' to get a '\' and '\,' to include a comma - inside URL, USR or PASS - - poolpriority|N,... (*) - none There is no reply section just the STATUS section - stating the results of changing pool priorities - See usage below - - disablepool|N (*) - none There is no reply section just the STATUS section - stating the results of disabling pool N - The Msg includes the pool URL - - removepool|N (*) - none There is no reply section just the STATUS section - stating the results of removing pool N - The Msg includes the pool URL - N.B. all details for the pool will be lost - - gpuenable|N (*) - none There is no reply section just the STATUS section - stating the results of the enable request - - gpudisable|N (*) - none There is no reply section just the STATUS section - stating the results of the disable request - - gpurestart|N (*) - none There is no reply section just the STATUS section - stating the results of the restart request - - gpuintensity|N,I (*) - none There is no reply section just the STATUS section - stating the results of setting GPU N intensity to I - - gpumem|N,V (*) - none There is no reply section just the STATUS section - stating the results of setting GPU N memoryclock to V MHz - - gpuengine|N,V (*) - none There is no reply section just the STATUS section - stating the results of setting GPU N clock to V MHz - - gpufan|N,V (*) - none There is no reply section just the STATUS section - stating the results of setting GPU N fan speed to V% - - gpuvddc|N,V (*) - none There is no reply section just the STATUS section - stating the results of setting GPU N vddc to V - - save|filename (*) - none There is no reply section just the STATUS section - stating success or failure saving the BFGMiner config - to filename - The filename is optional and will use the cgminer - default if not specified - - quit (*) none There is no status section but just a single "BYE" - reply before BFGMiner quits - - notify NOTIFY The last status and history count of each devices problem - e.g. NOTIFY=0,Name=GPU,ID=0,Last Well=1332432290,...| - - privileged (*) - none There is no reply section just the STATUS section - stating an error if you do not have privileged access - to the API and success if you do have privilege - The command doesn't change anything in BFGMiner - - pgaenable|N (*) - none There is no reply section just the STATUS section - stating the results of the enable request - You cannot enable a PGA if it's status is not WELL - This is only available if PGA mining is enabled - - pgadisable|N (*) - none There is no reply section just the STATUS section - stating the results of the disable request - This is only available if PGA mining is enabled - - devdetails DEVDETAILS Each device with a list of their static details - This lists all devices including those not supported - by the 'devs' command - e.g. DEVDETAILS=0,Name=GPU,ID=0,Driver=opencl,...| - - restart (*) none There is no status section but just a single "RESTART" - reply before cgminer restarts - - stats STATS Each device or pool that has 1 or more getworks - with a list of stats regarding getwork times - The values returned by stats may change in future - versions thus would not normally be displayed - Device drivers are also able to add stats to the - end of the details returned - - check|cmd COMMAND Exists=Y/N, <- 'cmd' exists in this version - Access=Y/N| <- you have access to use 'cmd' - -When you enable, disable or restart a GPU or PGA, you will also get Thread messages -in the BFGMiner status window - -The 'poolpriority' command can be used to reset the priority order of pools. -Each pool should be listed by id number in order of preference (first = most -preferred). Any pools not listed will be prioritized after the ones that are, -in an undefined order. If the priority change affects the miner's preference -for mining, it may switch immediately. - -When you switch to a different pool to the current one (including by priority -change), you will get a 'Switching to URL' message in the BFGMiner status -windows - -Obviously, the JSON format is simply just the names as given before the '=' -with the values after the '=' - -If you enable BFGMiner debug (-D or --debug) you will also get messages showing -details of the requests received and the replies - -There are included 4 program examples for accessing the API: - -api-example.php - a php script to access the API - usAge: php api-example.php command - by default it sends a 'summary' request to the miner at 127.0.0.1:4028 - If you specify a command it will send that request instead - You must modify the line "$socket = getsock('127.0.0.1', 4028);" at the - beginning of "function request($cmd)" to change where it looks for BFGMiner - -API.java/API.class - a java program to access the API (with source code) - usAge is: java API command address port - Any missing or blank parameters are replaced as if you entered: - java API summary 127.0.0.1 4028 - -api-example.c - a 'C' program to access the API (with source code) - usAge: api-example [command [ip/host [port]]] - again, as above, missing or blank parameters are replaced as if you entered: - api-example summary 127.0.0.1 4028 - -miner.php - an example web page to access the API - This includes buttons and inputs to attempt access to the privileged commands - Read the top of the file (miner.php) for details of how to tune the display - and also to use the option to display a multi-rig summary - ----------- - -Feature Changelog for external applications using the API: - - -API V1.14 - -Modified API commands: - 'stats' - more icarus timing stats added - 'notify' - include new device comms error counter - -The internal code for handling data was rewritten (~25% of the code) -Completely backward compatible - ----------- - -API V1.13 (cgminer v2.4.4) - -Added API commands: - 'check' - -Support was added to cgminer for API access groups with the --api-groups option -It's 100% backward compatible with previous --api-access commands - ----------- - -API V1.12 (cgminer v2.4.3) - -Modified API commands: - 'stats' - more pool stats added - -Support for the ModMinerQuad FPGA was added - ----------- - -API V1.11 (cgminer v2.4.2) - -Modified API commands: - 'save' no longer requires a filename (use default if not specified) - -'save' incorrectly returned status E (error) on success before. -It now correctly returns S (success) - ----------- - -API V1.10 (cgminer v2.4.1) - -Added API commands: - 'stats' - -N.B. the 'stats' command can change at any time so any specific content -present should not be relied upon. -The data content is mainly used for debugging purposes or hidden options -in cgminer and can change as development work requires - -Modified API commands: - 'pools' added "Last Share Time" - ----------- - -API V1.9 (cgminer v2.4.0) - -Added API commands: - 'restart' - -Modified API commands: - 'notify' corrected invalid JSON - ----------- - -API V1.8 (cgminer v2.3.5) - -Added API commands: - 'devdetails' - -Support for the ZTex FPGA was added - ----------- - -API V1.7 (cgminer v2.3.4) - -Added API commands: - 'removepool' - -Modified API commands: - 'pools' added "User" - -From API version 1.7 onwards, reply strings in JSON and Text have the -necessary escaping as required to avoid ambiguity -For JSON the 2 characters '"' and '\' are escaped with a '\' before them -For Text the 4 characters '|' ',' '=' and '\' are escaped the same way - ----------- - -API V1.6 (cgminer v2.3.2) - -Added API commands: - 'pga' - 'pgaenable' - 'pgadisable' - 'pgacount' - -Modified API commands: - 'devs' now includes Icarus and Bitforce FPGA devices - 'notify' added "*" to the front of the name of all numeric error fields - 'config' correct "Log Interval" to use numeric (not text) type for JSON - -Support for Icarus and Bitforce FPGAs was added - ----------- - -API V1.5 was not released - ----------- - -API V1.4 (Kano's interim release of cgminer v2.3.1) - -Added API commands: - 'notify' - -Modified API commands: - 'config' added "Device Code" and "OS" - -Added "When" to the STATUS reply section of all commands - ----------- - -API V1.3 (cgminer v2.3.1-2) - -Added API commands: - 'addpool' - -Modified API commands: - 'devs'/'gpu' added "Total MH" for each device - 'summary' added "Total MH" - ----------- - -API V1.2 (cgminer v2.3.0) - -Added API commands: - 'enablepool' - 'disablepool' - 'privileged' - -Modified API commands: - 'config' added "Log Interval" - -Starting with API V1.2, any attempt to access a command that requires -privileged security, from an IP address that does not have privileged -security, will return an "Access denied" Error Status - ----------- - -API V1.1 (cgminer v2.2.4) - -There were no changes to the API commands in cgminer v2.2.4, -however support was added to cgminer for IP address restrictions -with the --api-allow option - ----------- - -API V1.1 (cgminer v2.2.2) - -Prior to V1.1, devs/gpu incorrectly reported GPU0 Intensity for all GPUs - -Modified API commands: - 'devs'/'gpu' added "Last Share Pool" and "Last Share Time" for each device - ----------- - -API V1.0 (cgminer v2.2.0) - -Remove default CPU support - -Added API commands: - 'config' - 'gpucount' - 'cpucount' - 'switchpool' - 'gpuintensity' - 'gpumem' - 'gpuengine' - 'gpufan' - 'gpuvddc' - 'save' - ----------- - -API V0.7 (cgminer v2.1.0) - -Initial release of the API in the main cgminer git - -Commands: - 'version' - 'devs' - 'pools' - 'summary' - 'gpuenable' - 'gpudisable' - 'gpurestart' - 'gpu' - 'cpu' - 'gpucount' - 'cpucount' - 'quit' - diff --git a/API.class b/API.class deleted file mode 100755 index 026ab141c6..0000000000 Binary files a/API.class and /dev/null differ diff --git a/API.java b/API.java deleted file mode 100644 index 36c1578a58..0000000000 --- a/API.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * - * Usage: java API command ip port - * - * If any are missing or blank they use the defaults: - * - * command = 'summary' - * ip = '127.0.0.1' - * port = '4028' - * - */ - -import java.net.*; -import java.io.*; - -class API -{ - static private final int MAXRECEIVESIZE = 65535; - - static private Socket socket = null; - - private void closeAll() throws Exception - { - if (socket != null) - { - socket.close(); - socket = null; - } - } - - public void display(String result) throws Exception - { - String value; - String name; - String[] sections = result.split("\\|", 0); - - for (int i = 0; i < sections.length; i++) - { - if (sections[i].trim().length() > 0) - { - String[] data = sections[i].split(",", 0); - - for (int j = 0; j < data.length; j++) - { - String[] nameval = data[j].split("=", 2); - - if (j == 0) - { - if (nameval.length > 1 - && Character.isDigit(nameval[1].charAt(0))) - name = nameval[0] + nameval[1]; - else - name = nameval[0]; - - System.out.println("[" + name + "] =>"); - System.out.println("("); - } - - if (nameval.length > 1) - { - name = nameval[0]; - value = nameval[1]; - } - else - { - name = "" + j; - value = nameval[0]; - } - - System.out.println(" ["+name+"] => "+value); - } - System.out.println(")"); - } - } - } - - public void process(String cmd, InetAddress ip, int port) throws Exception - { - char buf[] = new char[MAXRECEIVESIZE]; - int len = 0; - -System.out.println("Attempting to send '"+cmd+"' to "+ip.getHostAddress()+":"+port); - - try - { - socket = new Socket(ip, port); - PrintStream ps = new PrintStream(socket.getOutputStream()); - ps.print(cmd.toLowerCase().toCharArray()); - ps.flush(); - - InputStreamReader isr = new InputStreamReader(socket.getInputStream()); - len = isr.read(buf, 0, MAXRECEIVESIZE); - - closeAll(); - } - catch (IOException ioe) - { - System.err.println(ioe.toString()); - closeAll(); - return; - } - - String result = new String(buf, 0, len); - - System.out.println("Answer='"+result+"'"); - - display(result); - } - - public API(String command, String _ip, String _port) throws Exception - { - InetAddress ip; - int port; - - try - { - ip = InetAddress.getByName(_ip); - } - catch (UnknownHostException uhe) - { - System.err.println("Unknown host " + _ip + ": " + uhe); - return; - } - - try - { - port = Integer.parseInt(_port); - } - catch (NumberFormatException nfe) - { - System.err.println("Invalid port " + _port + ": " + nfe); - return; - } - - process(command, ip, port); - } - - public static void main(String[] params) throws Exception - { - String command = "summary"; - String ip = "127.0.0.1"; - String port = "4028"; - - if (params.length > 0 && params[0].trim().length() > 0) - command = params[0].trim(); - - if (params.length > 1 && params[1].trim().length() > 0) - ip = params[1].trim(); - - if (params.length > 2 && params[2].trim().length() > 0) - port = params[2].trim(); - - new API(command, ip, port); - } -} diff --git a/AUTHORS b/AUTHORS index 7ef9c87f97..5efe4c58ee 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,94 @@ -Original CPU mining software: Jeff Garzik -GPU mining and refactor: Con Kolivas 15qSxP1SQcUX3o4nhkfdbgyoWEFMomJ4rZ -FPGA mining and refactor: Luke Dashjr 1QATWksNFGeUJCWBrN4g6hGM178Lovm7Wh -API+: Andrew Smith 1Jjk2LmktEQKnv8r2cZ9MvLiZwZ9gxabKm +CURRENT MAINTAINERS: + +Luke Dashjr 1QATWksNFGeUJCWBrN4g6hGM178Lovm7Wh +John Stefanopoulos + +Debian packaging: Dmitry Smirnov + +--- + +PAST MAINTAINERS: + +Anatoly Legkodymov +Andreas Auer +Andrew Smith 1Jjk2LmktEQKnv8r2cZ9MvLiZwZ9gxabKm +Con Kolivas 15qSxP1SQcUX3o4nhkfdbgyoWEFMomJ4rZ +Jeff Garzik +Nate Woolls 1JnZoFeCVYJgaKbKwDUxSkTZWWpBmwWTgV +Nelisky +Pelle Nilsson +Vitalii Demianets +Xiangfu + +--- + +CONTRIBUTORS: + +Abracadabra +anajavi +Andrew McDonald +Ang Iongchun +ArtForz +BFL_Jonathon +Bitfury +blinkier +bluemurder +capa66 +Christian Berendt +Colin Percival +Daniel Mack +Denis Ahrens +Dmitriy Korniychuk +Dmitry Sorokin +Dualminer Team +fleger +Glenn Francis Murray +gluk +Graeme Humphries +GridSeed Team +HashBuster team +Huang Le <4tarhl@gmail.com> +Isidoro Ghezzi +James Hilliard +James Morris +Jason Hughes +Jason Snell +Jean-Luc Cooke +Jonathan Lynch +Josh Lehan +Kiyoaki Matsugae +Lauri Kasanen +Lingchao Xu +Luke Mitchell +Mark Crichton +Martin Danielsen +Michael Kedzierski +Mr O +mtrlt +Neil Kettle +Nico Oelgart +Olivier Gay +Paul Sheppard +Paul Wouters +Pavel Semjanov +Peter Stuge +Phateus +Philip Kaufmann +pontus +pooler +Raulo +Red_Wolf_2 +Ricardo Iván Vieitez Parra +Ronny Van Keer +Rusty Russell +Серёга +slax0r +Teemu Suikki +Thorsten Gilling +Tim Bartletts +Tydus +Ufasoft +Vladimir Strinski +Zefir Kurtisi +ZeusMiner Team +Znort 987 diff --git a/CL/cl.h b/CL/cl.h index 7d634451fc..dca23d5d3c 100644 --- a/CL/cl.h +++ b/CL/cl.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011 The Khronos Group Inc. + * Copyright (c) 2008-2010 The Khronos Group Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the @@ -21,6 +21,8 @@ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. ******************************************************************************/ +/* $Revision: 11707 $ on $Date: 2010-06-13 23:30:16 -0700 (Sun, 13 Jun 2010) $ */ + #ifndef __OPENCL_CL_H #define __OPENCL_CL_H @@ -47,15 +49,14 @@ typedef cl_ulong cl_bitfield; typedef cl_bitfield cl_device_type; typedef cl_uint cl_platform_info; typedef cl_uint cl_device_info; +typedef cl_bitfield cl_device_address_info; typedef cl_bitfield cl_device_fp_config; typedef cl_uint cl_device_mem_cache_type; typedef cl_uint cl_device_local_mem_type; typedef cl_bitfield cl_device_exec_capabilities; typedef cl_bitfield cl_command_queue_properties; -typedef intptr_t cl_device_partition_property; -typedef cl_bitfield cl_device_affinity_domain; -typedef intptr_t cl_context_properties; +typedef intptr_t cl_context_properties; typedef cl_uint cl_context_info; typedef cl_uint cl_command_queue_info; typedef cl_uint cl_channel_order; @@ -63,50 +64,25 @@ typedef cl_uint cl_channel_type; typedef cl_bitfield cl_mem_flags; typedef cl_uint cl_mem_object_type; typedef cl_uint cl_mem_info; -typedef cl_bitfield cl_mem_migration_flags; typedef cl_uint cl_image_info; -typedef cl_uint cl_buffer_create_type; typedef cl_uint cl_addressing_mode; typedef cl_uint cl_filter_mode; typedef cl_uint cl_sampler_info; typedef cl_bitfield cl_map_flags; typedef cl_uint cl_program_info; typedef cl_uint cl_program_build_info; -typedef cl_uint cl_program_binary_type; typedef cl_int cl_build_status; typedef cl_uint cl_kernel_info; -typedef cl_uint cl_kernel_arg_info; -typedef cl_uint cl_kernel_arg_address_qualifier; -typedef cl_uint cl_kernel_arg_access_qualifier; -typedef cl_bitfield cl_kernel_arg_type_qualifier; typedef cl_uint cl_kernel_work_group_info; typedef cl_uint cl_event_info; typedef cl_uint cl_command_type; typedef cl_uint cl_profiling_info; - typedef struct _cl_image_format { cl_channel_order image_channel_order; cl_channel_type image_channel_data_type; } cl_image_format; -typedef struct _cl_image_desc { - cl_mem_object_type image_type; - size_t image_width; - size_t image_height; - size_t image_depth; - size_t image_array_size; - size_t image_row_pitch; - size_t image_slice_pitch; - cl_uint num_mip_levels; - cl_uint num_samples; - cl_mem buffer; -} cl_image_desc; - -typedef struct _cl_buffer_region { - size_t origin; - size_t size; -} cl_buffer_region; /******************************************************************************/ @@ -125,13 +101,6 @@ typedef struct _cl_buffer_region { #define CL_IMAGE_FORMAT_NOT_SUPPORTED -10 #define CL_BUILD_PROGRAM_FAILURE -11 #define CL_MAP_FAILURE -12 -#define CL_MISALIGNED_SUB_BUFFER_OFFSET -13 -#define CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST -14 -#define CL_COMPILE_PROGRAM_FAILURE -15 -#define CL_LINKER_NOT_AVAILABLE -16 -#define CL_LINK_PROGRAM_FAILURE -17 -#define CL_DEVICE_PARTITION_FAILED -18 -#define CL_KERNEL_ARG_INFO_NOT_AVAILABLE -19 #define CL_INVALID_VALUE -30 #define CL_INVALID_DEVICE_TYPE -31 @@ -167,22 +136,13 @@ typedef struct _cl_buffer_region { #define CL_INVALID_BUFFER_SIZE -61 #define CL_INVALID_MIP_LEVEL -62 #define CL_INVALID_GLOBAL_WORK_SIZE -63 -#define CL_INVALID_PROPERTY -64 -#define CL_INVALID_IMAGE_DESCRIPTOR -65 -#define CL_INVALID_COMPILER_OPTIONS -66 -#define CL_INVALID_LINKER_OPTIONS -67 -#define CL_INVALID_DEVICE_PARTITION_COUNT -68 /* OpenCL Version */ #define CL_VERSION_1_0 1 -#define CL_VERSION_1_1 1 -#define CL_VERSION_1_2 1 /* cl_bool */ #define CL_FALSE 0 #define CL_TRUE 1 -#define CL_BLOCKING CL_TRUE -#define CL_NON_BLOCKING CL_FALSE /* cl_platform_info */ #define CL_PLATFORM_PROFILE 0x0900 @@ -196,7 +156,6 @@ typedef struct _cl_buffer_region { #define CL_DEVICE_TYPE_CPU (1 << 1) #define CL_DEVICE_TYPE_GPU (1 << 2) #define CL_DEVICE_TYPE_ACCELERATOR (1 << 3) -#define CL_DEVICE_TYPE_CUSTOM (1 << 4) #define CL_DEVICE_TYPE_ALL 0xFFFFFFFF /* cl_device_info */ @@ -250,30 +209,8 @@ typedef struct _cl_buffer_region { #define CL_DEVICE_VERSION 0x102F #define CL_DEVICE_EXTENSIONS 0x1030 #define CL_DEVICE_PLATFORM 0x1031 -#define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032 +/* 0x1032 reserved for CL_DEVICE_DOUBLE_FP_CONFIG */ /* 0x1033 reserved for CL_DEVICE_HALF_FP_CONFIG */ -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF 0x1034 -#define CL_DEVICE_HOST_UNIFIED_MEMORY 0x1035 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR 0x1036 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT 0x1037 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_INT 0x1038 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG 0x1039 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT 0x103A -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE 0x103B -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF 0x103C -#define CL_DEVICE_OPENCL_C_VERSION 0x103D -#define CL_DEVICE_LINKER_AVAILABLE 0x103E -#define CL_DEVICE_BUILT_IN_KERNELS 0x103F -#define CL_DEVICE_IMAGE_MAX_BUFFER_SIZE 0x1040 -#define CL_DEVICE_IMAGE_MAX_ARRAY_SIZE 0x1041 -#define CL_DEVICE_PARENT_DEVICE 0x1042 -#define CL_DEVICE_PARTITION_MAX_SUB_DEVICES 0x1043 -#define CL_DEVICE_PARTITION_PROPERTIES 0x1044 -#define CL_DEVICE_PARTITION_AFFINITY_DOMAIN 0x1045 -#define CL_DEVICE_PARTITION_TYPE 0x1046 -#define CL_DEVICE_REFERENCE_COUNT 0x1047 -#define CL_DEVICE_PREFERRED_INTEROP_USER_SYNC 0x1048 -#define CL_DEVICE_PRINTF_BUFFER_SIZE 0x1049 /* cl_device_fp_config - bitfield */ #define CL_FP_DENORM (1 << 0) @@ -282,8 +219,6 @@ typedef struct _cl_buffer_region { #define CL_FP_ROUND_TO_ZERO (1 << 3) #define CL_FP_ROUND_TO_INF (1 << 4) #define CL_FP_FMA (1 << 5) -#define CL_FP_SOFT_FLOAT (1 << 6) -#define CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT (1 << 7) /* cl_device_mem_cache_type */ #define CL_NONE 0x0 @@ -306,25 +241,9 @@ typedef struct _cl_buffer_region { #define CL_CONTEXT_REFERENCE_COUNT 0x1080 #define CL_CONTEXT_DEVICES 0x1081 #define CL_CONTEXT_PROPERTIES 0x1082 -#define CL_CONTEXT_NUM_DEVICES 0x1083 -/* cl_context_properties */ +/* cl_context_info + cl_context_properties */ #define CL_CONTEXT_PLATFORM 0x1084 -#define CL_CONTEXT_INTEROP_USER_SYNC 0x1085 - -/* cl_device_partition_property */ -#define CL_DEVICE_PARTITION_EQUALLY 0x1086 -#define CL_DEVICE_PARTITION_BY_COUNTS 0x1087 -#define CL_DEVICE_PARTITION_BY_COUNTS_LIST_END 0x0 -#define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN 0x1088 - -/* cl_device_affinity_domain */ -#define CL_DEVICE_AFFINITY_DOMAIN_NUMA (1 << 0) -#define CL_DEVICE_AFFINITY_DOMAIN_L4_CACHE (1 << 1) -#define CL_DEVICE_AFFINITY_DOMAIN_L3_CACHE (1 << 2) -#define CL_DEVICE_AFFINITY_DOMAIN_L2_CACHE (1 << 3) -#define CL_DEVICE_AFFINITY_DOMAIN_L1_CACHE (1 << 4) -#define CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE (1 << 5) /* cl_command_queue_info */ #define CL_QUEUE_CONTEXT 0x1090 @@ -339,14 +258,6 @@ typedef struct _cl_buffer_region { #define CL_MEM_USE_HOST_PTR (1 << 3) #define CL_MEM_ALLOC_HOST_PTR (1 << 4) #define CL_MEM_COPY_HOST_PTR (1 << 5) -// reserved (1 << 6) -#define CL_MEM_HOST_WRITE_ONLY (1 << 7) -#define CL_MEM_HOST_READ_ONLY (1 << 8) -#define CL_MEM_HOST_NO_ACCESS (1 << 9) - -/* cl_mem_migration_flags - bitfield */ -#define CL_MIGRATE_MEM_OBJECT_HOST (1 << 0) -#define CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED (1 << 1) /* cl_channel_order */ #define CL_R 0x10B0 @@ -359,9 +270,6 @@ typedef struct _cl_buffer_region { #define CL_ARGB 0x10B7 #define CL_INTENSITY 0x10B8 #define CL_LUMINANCE 0x10B9 -#define CL_Rx 0x10BA -#define CL_RGx 0x10BB -#define CL_RGBx 0x10BC /* cl_channel_type */ #define CL_SNORM_INT8 0x10D0 @@ -384,10 +292,6 @@ typedef struct _cl_buffer_region { #define CL_MEM_OBJECT_BUFFER 0x10F0 #define CL_MEM_OBJECT_IMAGE2D 0x10F1 #define CL_MEM_OBJECT_IMAGE3D 0x10F2 -#define CL_MEM_OBJECT_IMAGE2D_ARRAY 0x10F3 -#define CL_MEM_OBJECT_IMAGE1D 0x10F4 -#define CL_MEM_OBJECT_IMAGE1D_ARRAY 0x10F5 -#define CL_MEM_OBJECT_IMAGE1D_BUFFER 0x10F6 /* cl_mem_info */ #define CL_MEM_TYPE 0x1100 @@ -397,8 +301,6 @@ typedef struct _cl_buffer_region { #define CL_MEM_MAP_COUNT 0x1104 #define CL_MEM_REFERENCE_COUNT 0x1105 #define CL_MEM_CONTEXT 0x1106 -#define CL_MEM_ASSOCIATED_MEMOBJECT 0x1107 -#define CL_MEM_OFFSET 0x1108 /* cl_image_info */ #define CL_IMAGE_FORMAT 0x1110 @@ -408,17 +310,12 @@ typedef struct _cl_buffer_region { #define CL_IMAGE_WIDTH 0x1114 #define CL_IMAGE_HEIGHT 0x1115 #define CL_IMAGE_DEPTH 0x1116 -#define CL_IMAGE_ARRAY_SIZE 0x1117 -#define CL_IMAGE_BUFFER 0x1118 -#define CL_IMAGE_NUM_MIP_LEVELS 0x1119 -#define CL_IMAGE_NUM_SAMPLES 0x111A /* cl_addressing_mode */ #define CL_ADDRESS_NONE 0x1130 #define CL_ADDRESS_CLAMP_TO_EDGE 0x1131 #define CL_ADDRESS_CLAMP 0x1132 #define CL_ADDRESS_REPEAT 0x1133 -#define CL_ADDRESS_MIRRORED_REPEAT 0x1134 /* cl_filter_mode */ #define CL_FILTER_NEAREST 0x1140 @@ -434,7 +331,6 @@ typedef struct _cl_buffer_region { /* cl_map_flags - bitfield */ #define CL_MAP_READ (1 << 0) #define CL_MAP_WRITE (1 << 1) -#define CL_MAP_WRITE_INVALIDATE_REGION (1 << 2) /* cl_program_info */ #define CL_PROGRAM_REFERENCE_COUNT 0x1160 @@ -444,20 +340,11 @@ typedef struct _cl_buffer_region { #define CL_PROGRAM_SOURCE 0x1164 #define CL_PROGRAM_BINARY_SIZES 0x1165 #define CL_PROGRAM_BINARIES 0x1166 -#define CL_PROGRAM_NUM_KERNELS 0x1167 -#define CL_PROGRAM_KERNEL_NAMES 0x1168 /* cl_program_build_info */ #define CL_PROGRAM_BUILD_STATUS 0x1181 #define CL_PROGRAM_BUILD_OPTIONS 0x1182 #define CL_PROGRAM_BUILD_LOG 0x1183 -#define CL_PROGRAM_BINARY_TYPE 0x1184 - -/* cl_program_binary_type */ -#define CL_PROGRAM_BINARY_TYPE_NONE 0x0 -#define CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT 0x1 -#define CL_PROGRAM_BINARY_TYPE_LIBRARY 0x2 -#define CL_PROGRAM_BINARY_TYPE_EXECUTABLE 0x4 /* cl_build_status */ #define CL_BUILD_SUCCESS 0 @@ -471,47 +358,17 @@ typedef struct _cl_buffer_region { #define CL_KERNEL_REFERENCE_COUNT 0x1192 #define CL_KERNEL_CONTEXT 0x1193 #define CL_KERNEL_PROGRAM 0x1194 -#define CL_KERNEL_ATTRIBUTES 0x1195 - -/* cl_kernel_arg_info */ -#define CL_KERNEL_ARG_ADDRESS_QUALIFIER 0x1196 -#define CL_KERNEL_ARG_ACCESS_QUALIFIER 0x1197 -#define CL_KERNEL_ARG_TYPE_NAME 0x1198 -#define CL_KERNEL_ARG_TYPE_QUALIFIER 0x1199 -#define CL_KERNEL_ARG_NAME 0x119A - -/* cl_kernel_arg_address_qualifier */ -#define CL_KERNEL_ARG_ADDRESS_GLOBAL 0x119B -#define CL_KERNEL_ARG_ADDRESS_LOCAL 0x119C -#define CL_KERNEL_ARG_ADDRESS_CONSTANT 0x119D -#define CL_KERNEL_ARG_ADDRESS_PRIVATE 0x119E - -/* cl_kernel_arg_access_qualifier */ -#define CL_KERNEL_ARG_ACCESS_READ_ONLY 0x11A0 -#define CL_KERNEL_ARG_ACCESS_WRITE_ONLY 0x11A1 -#define CL_KERNEL_ARG_ACCESS_READ_WRITE 0x11A2 -#define CL_KERNEL_ARG_ACCESS_NONE 0x11A3 - -/* cl_kernel_arg_type_qualifer */ -#define CL_KERNEL_ARG_TYPE_NONE 0 -#define CL_KERNEL_ARG_TYPE_CONST (1 << 0) -#define CL_KERNEL_ARG_TYPE_RESTRICT (1 << 1) -#define CL_KERNEL_ARG_TYPE_VOLATILE (1 << 2) /* cl_kernel_work_group_info */ #define CL_KERNEL_WORK_GROUP_SIZE 0x11B0 #define CL_KERNEL_COMPILE_WORK_GROUP_SIZE 0x11B1 #define CL_KERNEL_LOCAL_MEM_SIZE 0x11B2 -#define CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 0x11B3 -#define CL_KERNEL_PRIVATE_MEM_SIZE 0x11B4 -#define CL_KERNEL_GLOBAL_WORK_SIZE 0x11B5 /* cl_event_info */ #define CL_EVENT_COMMAND_QUEUE 0x11D0 #define CL_EVENT_COMMAND_TYPE 0x11D1 #define CL_EVENT_REFERENCE_COUNT 0x11D2 #define CL_EVENT_COMMAND_EXECUTION_STATUS 0x11D3 -#define CL_EVENT_CONTEXT 0x11D4 /* cl_command_type */ #define CL_COMMAND_NDRANGE_KERNEL 0x11F0 @@ -531,24 +388,13 @@ typedef struct _cl_buffer_region { #define CL_COMMAND_MARKER 0x11FE #define CL_COMMAND_ACQUIRE_GL_OBJECTS 0x11FF #define CL_COMMAND_RELEASE_GL_OBJECTS 0x1200 -#define CL_COMMAND_READ_BUFFER_RECT 0x1201 -#define CL_COMMAND_WRITE_BUFFER_RECT 0x1202 -#define CL_COMMAND_COPY_BUFFER_RECT 0x1203 -#define CL_COMMAND_USER 0x1204 -#define CL_COMMAND_BARRIER 0x1205 -#define CL_COMMAND_MIGRATE_MEM_OBJECTS 0x1206 -#define CL_COMMAND_FILL_BUFFER 0x1207 -#define CL_COMMAND_FILL_IMAGE 0x1208 /* command execution status */ #define CL_COMPLETE 0x0 #define CL_RUNNING 0x1 #define CL_SUBMITTED 0x2 #define CL_QUEUED 0x3 - -/* cl_buffer_create_type */ -#define CL_BUFFER_CREATE_TYPE_REGION 0x1220 - + /* cl_profiling_info */ #define CL_PROFILING_COMMAND_QUEUED 0x1280 #define CL_PROFILING_COMMAND_SUBMIT 0x1281 @@ -586,35 +432,22 @@ clGetDeviceInfo(cl_device_id /* device */, size_t /* param_value_size */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clCreateSubDevices(cl_device_id /* in_device */, - const cl_device_partition_property * /* properties */, - cl_uint /* num_devices */, - cl_device_id * /* out_devices */, - cl_uint * /* num_devices_ret */) CL_API_SUFFIX__VERSION_1_2; -extern CL_API_ENTRY cl_int CL_API_CALL -clRetainDevice(cl_device_id /* device */) CL_API_SUFFIX__VERSION_1_2; - -extern CL_API_ENTRY cl_int CL_API_CALL -clReleaseDevice(cl_device_id /* device */) CL_API_SUFFIX__VERSION_1_2; - /* Context APIs */ extern CL_API_ENTRY cl_context CL_API_CALL clCreateContext(const cl_context_properties * /* properties */, - cl_uint /* num_devices */, - const cl_device_id * /* devices */, + cl_uint /* num_devices */, + const cl_device_id * /* devices */, void (CL_CALLBACK * /* pfn_notify */)(const char *, const void *, size_t, void *), - void * /* user_data */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + void * /* user_data */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_context CL_API_CALL clCreateContextFromType(const cl_context_properties * /* properties */, - cl_device_type /* device_type */, + cl_device_type /* device_type */, void (CL_CALLBACK * /* pfn_notify*/ )(const char *, const void *, size_t, void *), - void * /* user_data */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + void * /* user_data */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL clRetainContext(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; @@ -649,7 +482,13 @@ clGetCommandQueueInfo(cl_command_queue /* command_queue */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; -/* Memory Object APIs */ +extern CL_API_ENTRY cl_int CL_API_CALL +clSetCommandQueueProperty(cl_command_queue /* command_queue */, + cl_command_queue_properties /* properties */, + cl_bool /* enable */, + cl_command_queue_properties * /* old_properties */) CL_API_SUFFIX__VERSION_1_0; + +/* Memory Object APIs */ extern CL_API_ENTRY cl_mem CL_API_CALL clCreateBuffer(cl_context /* context */, cl_mem_flags /* flags */, @@ -658,19 +497,26 @@ clCreateBuffer(cl_context /* context */, cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateSubBuffer(cl_mem /* buffer */, - cl_mem_flags /* flags */, - cl_buffer_create_type /* buffer_create_type */, - const void * /* buffer_create_info */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1; - +clCreateImage2D(cl_context /* context */, + cl_mem_flags /* flags */, + const cl_image_format * /* image_format */, + size_t /* image_width */, + size_t /* image_height */, + size_t /* image_row_pitch */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateImage(cl_context /* context */, - cl_mem_flags /* flags */, - const cl_image_format * /* image_format */, - const cl_image_desc * /* image_desc */, - void * /* host_ptr */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_2; +clCreateImage3D(cl_context /* context */, + cl_mem_flags /* flags */, + const cl_image_format * /* image_format */, + size_t /* image_width */, + size_t /* image_height */, + size_t /* image_depth */, + size_t /* image_row_pitch */, + size_t /* image_slice_pitch */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL clRetainMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; @@ -700,12 +546,7 @@ clGetImageInfo(cl_mem /* image */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; -extern CL_API_ENTRY cl_int CL_API_CALL -clSetMemObjectDestructorCallback( cl_mem /* memobj */, - void (CL_CALLBACK * /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/), - void * /*user_data */ ) CL_API_SUFFIX__VERSION_1_1; - -/* Sampler APIs */ +/* Sampler APIs */ extern CL_API_ENTRY cl_sampler CL_API_CALL clCreateSampler(cl_context /* context */, cl_bool /* normalized_coords */, @@ -743,13 +584,6 @@ clCreateProgramWithBinary(cl_context /* context */, cl_int * /* binary_status */, cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; -extern CL_API_ENTRY cl_program CL_API_CALL -clCreateProgramWithBuiltInKernels(cl_context /* context */, - cl_uint /* num_devices */, - const cl_device_id * /* device_list */, - const char * /* kernel_names */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_2; - extern CL_API_ENTRY cl_int CL_API_CALL clRetainProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; @@ -765,30 +599,7 @@ clBuildProgram(cl_program /* program */, void * /* user_data */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL -clCompileProgram(cl_program /* program */, - cl_uint /* num_devices */, - const cl_device_id * /* device_list */, - const char * /* options */, - cl_uint /* num_input_headers */, - const cl_program * /* input_headers */, - const char ** /* header_include_names */, - void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */), - void * /* user_data */) CL_API_SUFFIX__VERSION_1_2; - -extern CL_API_ENTRY cl_program CL_API_CALL -clLinkProgram(cl_context /* context */, - cl_uint /* num_devices */, - const cl_device_id * /* device_list */, - const char * /* options */, - cl_uint /* num_input_programs */, - const cl_program * /* input_programs */, - void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */), - void * /* user_data */, - cl_int * /* errcode_ret */ ) CL_API_SUFFIX__VERSION_1_2; - - -extern CL_API_ENTRY cl_int CL_API_CALL -clUnloadPlatformCompiler(cl_platform_id /* platform */) CL_API_SUFFIX__VERSION_1_2; +clUnloadCompiler(void) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL clGetProgramInfo(cl_program /* program */, @@ -836,14 +647,6 @@ clGetKernelInfo(cl_kernel /* kernel */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; -extern CL_API_ENTRY cl_int CL_API_CALL -clGetKernelArgInfo(cl_kernel /* kernel */, - cl_uint /* arg_indx */, - cl_kernel_arg_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_2; - extern CL_API_ENTRY cl_int CL_API_CALL clGetKernelWorkGroupInfo(cl_kernel /* kernel */, cl_device_id /* device */, @@ -852,7 +655,7 @@ clGetKernelWorkGroupInfo(cl_kernel /* kernel */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; -/* Event Object APIs */ +/* Event Object APIs */ extern CL_API_ENTRY cl_int CL_API_CALL clWaitForEvents(cl_uint /* num_events */, const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; @@ -864,27 +667,13 @@ clGetEventInfo(cl_event /* event */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; -extern CL_API_ENTRY cl_event CL_API_CALL -clCreateUserEvent(cl_context /* context */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1; - extern CL_API_ENTRY cl_int CL_API_CALL clRetainEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL clReleaseEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; -extern CL_API_ENTRY cl_int CL_API_CALL -clSetUserEventStatus(cl_event /* event */, - cl_int /* execution_status */) CL_API_SUFFIX__VERSION_1_1; - -extern CL_API_ENTRY cl_int CL_API_CALL -clSetEventCallback( cl_event /* event */, - cl_int /* command_exec_callback_type */, - void (CL_CALLBACK * /* pfn_notify */)(cl_event, cl_int, void *), - void * /* user_data */) CL_API_SUFFIX__VERSION_1_1; - -/* Profiling APIs */ +/* Profiling APIs */ extern CL_API_ENTRY cl_int CL_API_CALL clGetEventProfilingInfo(cl_event /* event */, cl_profiling_info /* param_name */, @@ -905,92 +694,34 @@ clEnqueueReadBuffer(cl_command_queue /* command_queue */, cl_mem /* buffer */, cl_bool /* blocking_read */, size_t /* offset */, - size_t /* size */, + size_t /* cb */, void * /* ptr */, cl_uint /* num_events_in_wait_list */, const cl_event * /* event_wait_list */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueReadBufferRect(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_read */, - const size_t * /* buffer_offset */, - const size_t * /* host_offset */, - const size_t * /* region */, - size_t /* buffer_row_pitch */, - size_t /* buffer_slice_pitch */, - size_t /* host_row_pitch */, - size_t /* host_slice_pitch */, - void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; - extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueWriteBuffer(cl_command_queue /* command_queue */, cl_mem /* buffer */, cl_bool /* blocking_write */, size_t /* offset */, - size_t /* size */, + size_t /* cb */, const void * /* ptr */, cl_uint /* num_events_in_wait_list */, const cl_event * /* event_wait_list */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueWriteBufferRect(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_write */, - const size_t * /* buffer_offset */, - const size_t * /* host_offset */, - const size_t * /* region */, - size_t /* buffer_row_pitch */, - size_t /* buffer_slice_pitch */, - size_t /* host_row_pitch */, - size_t /* host_slice_pitch */, - const void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueFillBuffer(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - const void * /* pattern */, - size_t /* pattern_size */, - size_t /* offset */, - size_t /* size */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_2; - extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueCopyBuffer(cl_command_queue /* command_queue */, cl_mem /* src_buffer */, cl_mem /* dst_buffer */, size_t /* src_offset */, size_t /* dst_offset */, - size_t /* size */, + size_t /* cb */, cl_uint /* num_events_in_wait_list */, const cl_event * /* event_wait_list */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueCopyBufferRect(cl_command_queue /* command_queue */, - cl_mem /* src_buffer */, - cl_mem /* dst_buffer */, - const size_t * /* src_origin */, - const size_t * /* dst_origin */, - const size_t * /* region */, - size_t /* src_row_pitch */, - size_t /* src_slice_pitch */, - size_t /* dst_row_pitch */, - size_t /* dst_slice_pitch */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; - extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueReadImage(cl_command_queue /* command_queue */, cl_mem /* image */, @@ -1017,16 +748,6 @@ clEnqueueWriteImage(cl_command_queue /* command_queue */, const cl_event * /* event_wait_list */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueFillImage(cl_command_queue /* command_queue */, - cl_mem /* image */, - const void * /* fill_color */, - const size_t * /* origin[3] */, - const size_t * /* region[3] */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_2; - extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueCopyImage(cl_command_queue /* command_queue */, cl_mem /* src_image */, @@ -1066,7 +787,7 @@ clEnqueueMapBuffer(cl_command_queue /* command_queue */, cl_bool /* blocking_map */, cl_map_flags /* map_flags */, size_t /* offset */, - size_t /* size */, + size_t /* cb */, cl_uint /* num_events_in_wait_list */, const cl_event * /* event_wait_list */, cl_event * /* event */, @@ -1094,15 +815,6 @@ clEnqueueUnmapMemObject(cl_command_queue /* command_queue */, const cl_event * /* event_wait_list */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueMigrateMemObjects(cl_command_queue /* command_queue */, - cl_uint /* num_mem_objects */, - const cl_mem * /* mem_objects */, - cl_mem_migration_flags /* flags */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_2; - extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueNDRangeKernel(cl_command_queue /* command_queue */, cl_kernel /* kernel */, @@ -1123,7 +835,7 @@ clEnqueueTask(cl_command_queue /* command_queue */, extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueNativeKernel(cl_command_queue /* command_queue */, - void (CL_CALLBACK * /*user_func*/)(void *), + void (*user_func)(void *), void * /* args */, size_t /* cb_args */, cl_uint /* num_mem_objects */, @@ -1134,26 +846,16 @@ clEnqueueNativeKernel(cl_command_queue /* command_queue */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueMarkerWithWaitList(cl_command_queue /* command_queue */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_2; +clEnqueueMarker(cl_command_queue /* command_queue */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueBarrierWithWaitList(cl_command_queue /* command_queue */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_2; +clEnqueueWaitForEvents(cl_command_queue /* command_queue */, + cl_uint /* num_events */, + const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL -clSetPrintfCallback(cl_context /* context */, - void (CL_CALLBACK * /* pfn_notify */)(cl_context /* program */, - cl_uint /*printf_data_len */, - char * /* printf_data_ptr */, - void * /* user_data */), - void * /* user_data */) CL_API_SUFFIX__VERSION_1_2; - - +clEnqueueBarrier(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; /* Extension function access * @@ -1162,72 +864,7 @@ clSetPrintfCallback(cl_context /* context */, * check to make sure the address is not NULL, before using or * calling the returned function address. */ -extern CL_API_ENTRY void * CL_API_CALL -clGetExtensionFunctionAddressForPlatform(cl_platform_id /* platform */, - const char * /* func_name */) CL_API_SUFFIX__VERSION_1_2; - - -#ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS -#warning CL_USE_DEPRECATED_OPENCL_1_0_APIS is defined. These APIs are unsupported and untested in OpenCL 1.1! - /* - * WARNING: - * This API introduces mutable state into the OpenCL implementation. It has been REMOVED - * to better facilitate thread safety. The 1.0 API is not thread safe. It is not tested by the - * OpenCL 1.1 conformance test, and consequently may not work or may not work dependably. - * It is likely to be non-performant. Use of this API is not advised. Use at your own risk. - * - * Software developers previously relying on this API are instructed to set the command queue - * properties when creating the queue, instead. - */ - extern CL_API_ENTRY cl_int CL_API_CALL - clSetCommandQueueProperty(cl_command_queue /* command_queue */, - cl_command_queue_properties /* properties */, - cl_bool /* enable */, - cl_command_queue_properties * /* old_properties */) CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED; -#endif /* CL_USE_DEPRECATED_OPENCL_1_0_APIS */ - - -#ifdef CL_USE_DEPRECATED_OPENCL_1_1_APIS - extern CL_API_ENTRY cl_mem CL_API_CALL - clCreateImage2D(cl_context /* context */, - cl_mem_flags /* flags */, - const cl_image_format * /* image_format */, - size_t /* image_width */, - size_t /* image_height */, - size_t /* image_row_pitch */, - void * /* host_ptr */, - cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; - - extern CL_API_ENTRY cl_mem CL_API_CALL - clCreateImage3D(cl_context /* context */, - cl_mem_flags /* flags */, - const cl_image_format * /* image_format */, - size_t /* image_width */, - size_t /* image_height */, - size_t /* image_depth */, - size_t /* image_row_pitch */, - size_t /* image_slice_pitch */, - void * /* host_ptr */, - cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; - - extern CL_API_ENTRY cl_int CL_API_CALL - clEnqueueMarker(cl_command_queue /* command_queue */, - cl_event * /* event */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; - - extern CL_API_ENTRY cl_int CL_API_CALL - clEnqueueWaitForEvents(cl_command_queue /* command_queue */, - cl_uint /* num_events */, - const cl_event * /* event_list */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; - - extern CL_API_ENTRY cl_int CL_API_CALL - clEnqueueBarrier(cl_command_queue /* command_queue */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; - - extern CL_API_ENTRY cl_int CL_API_CALL - clUnloadCompiler(void) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; - - extern CL_API_ENTRY void * CL_API_CALL - clGetExtensionFunctionAddress(const char * /* func_name */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; -#endif /* CL_USE_DEPRECATED_OPENCL_1_2_APIS */ +extern CL_API_ENTRY void * CL_API_CALL clGetExtensionFunctionAddress(const char * /* func_name */) CL_API_SUFFIX__VERSION_1_0; #endif /* OMIT_OPENCL_API */ diff --git a/CL/cl_platform.h b/CL/cl_platform.h index c823430934..4a52407540 100644 --- a/CL/cl_platform.h +++ b/CL/cl_platform.h @@ -21,7 +21,7 @@ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. **********************************************************************************/ -/* $Revision: 11803 $ on $Date: 2010-06-25 10:02:12 -0700 (Fri, 25 Jun 2010) $ */ +/* $Revision: 14830 $ on $Date: 2011-05-26 08:34:31 -0700 (Thu, 26 May 2011) $ */ #ifndef __CL_PLATFORM_H #define __CL_PLATFORM_H @@ -36,32 +36,21 @@ extern "C" { #endif #if defined(_WIN32) - #define CL_API_ENTRY - #define CL_API_CALL __stdcall - #define CL_CALLBACK __stdcall +#define CL_API_ENTRY +#define CL_API_CALL __stdcall #else - #define CL_API_ENTRY - #define CL_API_CALL - #define CL_CALLBACK +#define CL_API_ENTRY +#define CL_API_CALL #endif #ifdef __APPLE__ - #define CL_EXTENSION_WEAK_LINK __attribute__((weak_import)) - #define CL_API_SUFFIX__VERSION_1_0 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER - #define CL_EXT_SUFFIX__VERSION_1_0 CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER - #define CL_API_SUFFIX__VERSION_1_1 CL_EXTENSION_WEAK_LINK - #define CL_EXT_SUFFIX__VERSION_1_1 CL_EXTENSION_WEAK_LINK - #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#define CL_API_SUFFIX__VERSION_1_0 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#define CL_API_SUFFIX__VERSION_1_1 +#define CL_EXTENSION_WEAK_LINK __attribute__((weak_import)) #else - #define CL_EXTENSION_WEAK_LINK - #define CL_API_SUFFIX__VERSION_1_0 - #define CL_EXT_SUFFIX__VERSION_1_0 - #define CL_API_SUFFIX__VERSION_1_1 - #define CL_EXT_SUFFIX__VERSION_1_1 - #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED - #define CL_API_SUFFIX__VERSION_1_2 - #define CL_EXT_SUFFIX__VERSION_1_2 - #define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED +#define CL_API_SUFFIX__VERSION_1_0 +#define CL_API_SUFFIX__VERSION_1_1 +#define CL_EXTENSION_WEAK_LINK #endif #if (defined (_WIN32) && defined(_MSC_VER)) @@ -119,40 +108,14 @@ typedef double cl_double; #define CL_DBL_MIN 2.225073858507201383090e-308 #define CL_DBL_EPSILON 2.220446049250313080847e-16 -#define CL_M_E 2.718281828459045090796 -#define CL_M_LOG2E 1.442695040888963387005 -#define CL_M_LOG10E 0.434294481903251816668 -#define CL_M_LN2 0.693147180559945286227 -#define CL_M_LN10 2.302585092994045901094 -#define CL_M_PI 3.141592653589793115998 -#define CL_M_PI_2 1.570796326794896557999 -#define CL_M_PI_4 0.785398163397448278999 -#define CL_M_1_PI 0.318309886183790691216 -#define CL_M_2_PI 0.636619772367581382433 -#define CL_M_2_SQRTPI 1.128379167095512558561 -#define CL_M_SQRT2 1.414213562373095145475 -#define CL_M_SQRT1_2 0.707106781186547572737 - -#define CL_M_E_F 2.71828174591064f -#define CL_M_LOG2E_F 1.44269502162933f -#define CL_M_LOG10E_F 0.43429449200630f -#define CL_M_LN2_F 0.69314718246460f -#define CL_M_LN10_F 2.30258512496948f -#define CL_M_PI_F 3.14159274101257f -#define CL_M_PI_2_F 1.57079637050629f -#define CL_M_PI_4_F 0.78539818525314f -#define CL_M_1_PI_F 0.31830987334251f -#define CL_M_2_PI_F 0.63661974668503f -#define CL_M_2_SQRTPI_F 1.12837922573090f -#define CL_M_SQRT2_F 1.41421353816986f -#define CL_M_SQRT1_2_F 0.70710676908493f - #define CL_NAN (CL_INFINITY - CL_INFINITY) #define CL_HUGE_VALF ((cl_float) 1e50) #define CL_HUGE_VAL ((cl_double) 1e500) #define CL_MAXFLOAT CL_FLT_MAX #define CL_INFINITY CL_HUGE_VALF +#define CL_CALLBACK __stdcall + #else #include @@ -210,35 +173,7 @@ typedef double cl_double __attribute__((aligned(8))); #define CL_DBL_MIN 0x1.0p-1022 #define CL_DBL_EPSILON 0x1.0p-52 -#define CL_M_E 2.718281828459045090796 -#define CL_M_LOG2E 1.442695040888963387005 -#define CL_M_LOG10E 0.434294481903251816668 -#define CL_M_LN2 0.693147180559945286227 -#define CL_M_LN10 2.302585092994045901094 -#define CL_M_PI 3.141592653589793115998 -#define CL_M_PI_2 1.570796326794896557999 -#define CL_M_PI_4 0.785398163397448278999 -#define CL_M_1_PI 0.318309886183790691216 -#define CL_M_2_PI 0.636619772367581382433 -#define CL_M_2_SQRTPI 1.128379167095512558561 -#define CL_M_SQRT2 1.414213562373095145475 -#define CL_M_SQRT1_2 0.707106781186547572737 - -#define CL_M_E_F 2.71828174591064f -#define CL_M_LOG2E_F 1.44269502162933f -#define CL_M_LOG10E_F 0.43429449200630f -#define CL_M_LN2_F 0.69314718246460f -#define CL_M_LN10_F 2.30258512496948f -#define CL_M_PI_F 3.14159274101257f -#define CL_M_PI_2_F 1.57079637050629f -#define CL_M_PI_4_F 0.78539818525314f -#define CL_M_1_PI_F 0.31830987334251f -#define CL_M_2_PI_F 0.63661974668503f -#define CL_M_2_SQRTPI_F 1.12837922573090f -#define CL_M_SQRT2_F 1.41421353816986f -#define CL_M_SQRT1_2_F 0.70710676908493f - -#if defined( __GNUC__ ) +#if (defined( __GNUC__ ) || defined( __IBMC__ )) #define CL_HUGE_VALF __builtin_huge_valf() #define CL_HUGE_VAL __builtin_huge_val() #define CL_NAN __builtin_nanf( "" ) @@ -251,6 +186,8 @@ typedef double cl_double __attribute__((aligned(8))); #define CL_MAXFLOAT CL_FLT_MAX #define CL_INFINITY CL_HUGE_VALF +#define CL_CALLBACK + #endif #include @@ -399,7 +336,7 @@ typedef unsigned int cl_GLenum; #endif /* Define alignment keys */ -#if defined( __GNUC__ ) +#if (defined( __GNUC__ ) || defined( __IBMC__ )) #define CL_ALIGNED(_x) __attribute__ ((aligned(_x))) #elif defined( _WIN32) && (_MSC_VER) /* Alignment keys neutered on windows because MSVC can't swallow function arguments with alignment requirements */ @@ -413,7 +350,7 @@ typedef unsigned int cl_GLenum; #endif /* Indicate whether .xyzw, .s0123 and .hi.lo are supported */ -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) /* .xyzw and .s0123...{f|F} are supported */ #define CL_HAS_NAMED_VECTOR_FIELDS 1 /* .hi and .lo are supported */ @@ -426,7 +363,7 @@ typedef unsigned int cl_GLenum; typedef union { cl_char CL_ALIGNED(2) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_char x, y; }; __extension__ struct{ cl_char s0, s1; }; __extension__ struct{ cl_char lo, hi; }; @@ -439,7 +376,7 @@ typedef union typedef union { cl_char CL_ALIGNED(4) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_char x, y, z, w; }; __extension__ struct{ cl_char s0, s1, s2, s3; }; __extension__ struct{ cl_char2 lo, hi; }; @@ -452,13 +389,10 @@ typedef union #endif }cl_char4; -/* cl_char3 is identical in size, alignment and behavior to cl_char4. See section 6.1.5. */ -typedef cl_char4 cl_char3; - typedef union { cl_char CL_ALIGNED(8) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_char x, y, z, w; }; __extension__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7; }; __extension__ struct{ cl_char4 lo, hi; }; @@ -477,7 +411,7 @@ typedef union typedef union { cl_char CL_ALIGNED(16) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_char x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; __extension__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; __extension__ struct{ cl_char8 lo, hi; }; @@ -501,7 +435,7 @@ typedef union typedef union { cl_uchar CL_ALIGNED(2) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_uchar x, y; }; __extension__ struct{ cl_uchar s0, s1; }; __extension__ struct{ cl_uchar lo, hi; }; @@ -514,7 +448,7 @@ typedef union typedef union { cl_uchar CL_ALIGNED(4) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_uchar x, y, z, w; }; __extension__ struct{ cl_uchar s0, s1, s2, s3; }; __extension__ struct{ cl_uchar2 lo, hi; }; @@ -527,13 +461,10 @@ typedef union #endif }cl_uchar4; -/* cl_uchar3 is identical in size, alignment and behavior to cl_uchar4. See section 6.1.5. */ -typedef cl_uchar4 cl_uchar3; - typedef union { cl_uchar CL_ALIGNED(8) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_uchar x, y, z, w; }; __extension__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7; }; __extension__ struct{ cl_uchar4 lo, hi; }; @@ -552,7 +483,7 @@ typedef union typedef union { cl_uchar CL_ALIGNED(16) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_uchar x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; __extension__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; __extension__ struct{ cl_uchar8 lo, hi; }; @@ -576,7 +507,7 @@ typedef union typedef union { cl_short CL_ALIGNED(4) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_short x, y; }; __extension__ struct{ cl_short s0, s1; }; __extension__ struct{ cl_short lo, hi; }; @@ -589,7 +520,7 @@ typedef union typedef union { cl_short CL_ALIGNED(8) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_short x, y, z, w; }; __extension__ struct{ cl_short s0, s1, s2, s3; }; __extension__ struct{ cl_short2 lo, hi; }; @@ -602,13 +533,10 @@ typedef union #endif }cl_short4; -/* cl_short3 is identical in size, alignment and behavior to cl_short4. See section 6.1.5. */ -typedef cl_short4 cl_short3; - typedef union { cl_short CL_ALIGNED(16) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_short x, y, z, w; }; __extension__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7; }; __extension__ struct{ cl_short4 lo, hi; }; @@ -627,7 +555,7 @@ typedef union typedef union { cl_short CL_ALIGNED(32) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_short x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; __extension__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; __extension__ struct{ cl_short8 lo, hi; }; @@ -651,7 +579,7 @@ typedef union typedef union { cl_ushort CL_ALIGNED(4) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_ushort x, y; }; __extension__ struct{ cl_ushort s0, s1; }; __extension__ struct{ cl_ushort lo, hi; }; @@ -664,7 +592,7 @@ typedef union typedef union { cl_ushort CL_ALIGNED(8) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_ushort x, y, z, w; }; __extension__ struct{ cl_ushort s0, s1, s2, s3; }; __extension__ struct{ cl_ushort2 lo, hi; }; @@ -677,13 +605,10 @@ typedef union #endif }cl_ushort4; -/* cl_ushort3 is identical in size, alignment and behavior to cl_ushort4. See section 6.1.5. */ -typedef cl_ushort4 cl_ushort3; - typedef union { cl_ushort CL_ALIGNED(16) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_ushort x, y, z, w; }; __extension__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7; }; __extension__ struct{ cl_ushort4 lo, hi; }; @@ -702,7 +627,7 @@ typedef union typedef union { cl_ushort CL_ALIGNED(32) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_ushort x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; __extension__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; __extension__ struct{ cl_ushort8 lo, hi; }; @@ -725,7 +650,7 @@ typedef union typedef union { cl_int CL_ALIGNED(8) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_int x, y; }; __extension__ struct{ cl_int s0, s1; }; __extension__ struct{ cl_int lo, hi; }; @@ -738,7 +663,7 @@ typedef union typedef union { cl_int CL_ALIGNED(16) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_int x, y, z, w; }; __extension__ struct{ cl_int s0, s1, s2, s3; }; __extension__ struct{ cl_int2 lo, hi; }; @@ -751,13 +676,10 @@ typedef union #endif }cl_int4; -/* cl_int3 is identical in size, alignment and behavior to cl_int4. See section 6.1.5. */ -typedef cl_int4 cl_int3; - typedef union { cl_int CL_ALIGNED(32) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_int x, y, z, w; }; __extension__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7; }; __extension__ struct{ cl_int4 lo, hi; }; @@ -776,7 +698,7 @@ typedef union typedef union { cl_int CL_ALIGNED(64) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_int x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; __extension__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; __extension__ struct{ cl_int8 lo, hi; }; @@ -800,7 +722,7 @@ typedef union typedef union { cl_uint CL_ALIGNED(8) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_uint x, y; }; __extension__ struct{ cl_uint s0, s1; }; __extension__ struct{ cl_uint lo, hi; }; @@ -813,7 +735,7 @@ typedef union typedef union { cl_uint CL_ALIGNED(16) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_uint x, y, z, w; }; __extension__ struct{ cl_uint s0, s1, s2, s3; }; __extension__ struct{ cl_uint2 lo, hi; }; @@ -826,13 +748,10 @@ typedef union #endif }cl_uint4; -/* cl_uint3 is identical in size, alignment and behavior to cl_uint4. See section 6.1.5. */ -typedef cl_uint4 cl_uint3; - typedef union { cl_uint CL_ALIGNED(32) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_uint x, y, z, w; }; __extension__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7; }; __extension__ struct{ cl_uint4 lo, hi; }; @@ -851,7 +770,7 @@ typedef union typedef union { cl_uint CL_ALIGNED(64) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_uint x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; __extension__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; __extension__ struct{ cl_uint8 lo, hi; }; @@ -874,7 +793,7 @@ typedef union typedef union { cl_long CL_ALIGNED(16) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_long x, y; }; __extension__ struct{ cl_long s0, s1; }; __extension__ struct{ cl_long lo, hi; }; @@ -887,7 +806,7 @@ typedef union typedef union { cl_long CL_ALIGNED(32) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_long x, y, z, w; }; __extension__ struct{ cl_long s0, s1, s2, s3; }; __extension__ struct{ cl_long2 lo, hi; }; @@ -900,13 +819,10 @@ typedef union #endif }cl_long4; -/* cl_long3 is identical in size, alignment and behavior to cl_long4. See section 6.1.5. */ -typedef cl_long4 cl_long3; - typedef union { cl_long CL_ALIGNED(64) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_long x, y, z, w; }; __extension__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7; }; __extension__ struct{ cl_long4 lo, hi; }; @@ -925,7 +841,7 @@ typedef union typedef union { cl_long CL_ALIGNED(128) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_long x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; __extension__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; __extension__ struct{ cl_long8 lo, hi; }; @@ -949,7 +865,7 @@ typedef union typedef union { cl_ulong CL_ALIGNED(16) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_ulong x, y; }; __extension__ struct{ cl_ulong s0, s1; }; __extension__ struct{ cl_ulong lo, hi; }; @@ -962,7 +878,7 @@ typedef union typedef union { cl_ulong CL_ALIGNED(32) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_ulong x, y, z, w; }; __extension__ struct{ cl_ulong s0, s1, s2, s3; }; __extension__ struct{ cl_ulong2 lo, hi; }; @@ -975,13 +891,10 @@ typedef union #endif }cl_ulong4; -/* cl_ulong3 is identical in size, alignment and behavior to cl_ulong4. See section 6.1.5. */ -typedef cl_ulong4 cl_ulong3; - typedef union { cl_ulong CL_ALIGNED(64) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_ulong x, y, z, w; }; __extension__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7; }; __extension__ struct{ cl_ulong4 lo, hi; }; @@ -1000,7 +913,7 @@ typedef union typedef union { cl_ulong CL_ALIGNED(128) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_ulong x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; __extension__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; __extension__ struct{ cl_ulong8 lo, hi; }; @@ -1025,7 +938,7 @@ typedef union typedef union { cl_float CL_ALIGNED(8) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_float x, y; }; __extension__ struct{ cl_float s0, s1; }; __extension__ struct{ cl_float lo, hi; }; @@ -1038,7 +951,7 @@ typedef union typedef union { cl_float CL_ALIGNED(16) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_float x, y, z, w; }; __extension__ struct{ cl_float s0, s1, s2, s3; }; __extension__ struct{ cl_float2 lo, hi; }; @@ -1051,13 +964,10 @@ typedef union #endif }cl_float4; -/* cl_float3 is identical in size, alignment and behavior to cl_float4. See section 6.1.5. */ -typedef cl_float4 cl_float3; - typedef union { cl_float CL_ALIGNED(32) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_float x, y, z, w; }; __extension__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7; }; __extension__ struct{ cl_float4 lo, hi; }; @@ -1076,7 +986,7 @@ typedef union typedef union { cl_float CL_ALIGNED(64) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_float x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; __extension__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; __extension__ struct{ cl_float8 lo, hi; }; @@ -1100,7 +1010,7 @@ typedef union typedef union { cl_double CL_ALIGNED(16) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_double x, y; }; __extension__ struct{ cl_double s0, s1; }; __extension__ struct{ cl_double lo, hi; }; @@ -1113,7 +1023,7 @@ typedef union typedef union { cl_double CL_ALIGNED(32) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_double x, y, z, w; }; __extension__ struct{ cl_double s0, s1, s2, s3; }; __extension__ struct{ cl_double2 lo, hi; }; @@ -1126,13 +1036,10 @@ typedef union #endif }cl_double4; -/* cl_double3 is identical in size, alignment and behavior to cl_double4. See section 6.1.5. */ -typedef cl_double4 cl_double3; - typedef union { cl_double CL_ALIGNED(64) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_double x, y, z, w; }; __extension__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7; }; __extension__ struct{ cl_double4 lo, hi; }; @@ -1151,7 +1058,7 @@ typedef union typedef union { cl_double CL_ALIGNED(128) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) +#if (defined( __GNUC__) || defined( __IBMC__ )) && ! defined( __STRICT_ANSI__ ) __extension__ struct{ cl_double x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; __extension__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; __extension__ struct{ cl_double8 lo, hi; }; @@ -1170,29 +1077,6 @@ typedef union #endif }cl_double16; -/* Macro to facilitate debugging - * Usage: - * Place CL_PROGRAM_STRING_DEBUG_INFO on the line before the first line of your source. - * The first line ends with: CL_PROGRAM_STRING_BEGIN \" - * Each line thereafter of OpenCL C source must end with: \n\ - * The last line ends in "; - * - * Example: - * - * const char *my_program = CL_PROGRAM_STRING_BEGIN "\ - * kernel void foo( int a, float * b ) \n\ - * { \n\ - * // my comment \n\ - * *b[ get_global_id(0)] = a; \n\ - * } \n\ - * "; - * - * This should correctly set up the line, (column) and file information for your source - * string so you can do source level debugging. - */ -#define __CL_STRINGIFY( _x ) # _x -#define _CL_STRINGIFY( _x ) __CL_STRINGIFY( _x ) -#define CL_PROGRAM_STRING_DEBUG_INFO "#line " _CL_STRINGIFY(__LINE__) " \"" __FILE__ "\" \n\n" #ifdef __cplusplus } diff --git a/ChangeLog b/ChangeLog index baf77a88a1..472fdf2c07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,3 +2,5 @@ See git repository ('git log') for full changelog. Git repo can be found at: https://github.com/luke-jr/bfgminer + +The NEWS file contains most of the changelog diff --git a/FPGA-README b/FPGA-README deleted file mode 100644 index 7b9f004d11..0000000000 --- a/FPGA-README +++ /dev/null @@ -1,68 +0,0 @@ - -This README contains extended details about FPGA mining with cgminer - -Bitforce - ---bfl-range Use nonce range on bitforce devices if supported - -This option is only for bitforce devices. Earlier devices such as the single -did not have any way of doing small amounts of work which meant that a lot of -work could be lost across block changes. Some of the "minirigs" have support -for doing this, so less work is lost across a longpoll. However, it comes at -a cost of 1% in overall hashrate so this feature is disabled by default. It -is only recommended you enable this if you are mining with a minirig on -p2pool. - - -Icarus - -There is a hidden option in cgminer when Icarus support is compiled in: - ---icarus-timing Set how the Icarus timing is calculated - one setting/value for all or comma separated - default[=N] Use the default Icarus hash time (2.6316ns) - short Calculate the hash time and stop adjusting it at ~315 difficulty 1 shares (~1hr) - long Re-calculate the hash time continuously - value[=N] Specify the hash time in nanoseconds (e.g. 2.6316) and abort time (e.g. 2.6316=80) - -Icarus timing is required for devices that do not exactly match a default Icarus Rev3 in -processing speed -If you have an Icarus Rev3 you should not normally need to use --icarus-timing since the -default values will maximise the MH/s and display it correctly - -Icarus timing is used to determine the number of hashes that have been checked when it aborts -a nonce range (including on a LongPoll) -It is also used to determine the elapsed time when it should abort a nonce range to avoid -letting the Icarus go idle, but also to safely maximise that time - -'short' or 'long' mode should only be used on a computer that has enough CPU available to run -cgminer without any CPU delays (an active desktop or swapping computer would not be stable enough) -Any CPU delays while calculating the hash time will affect the result -'short' mode only requires the computer to be stable until it has completed ~315 difficulty 1 shares -'long' mode requires it to always be stable to ensure accuracy, however, over time it continually -corrects itself - -When in 'short' or 'long' mode, it will report the hash time value each time it is re-calculated -In 'short' or 'long' mode, the scan abort time starts at 5 seconds and uses the default 2.6316ns -scan hash time, for the first 5 nonce's or one minute (whichever is longer) - -In 'default' or 'value' mode the 'constants' are calculated once at the start, based on the default -value or the value specified -The optional additional =N specifies to set the default abort at N 1/10ths of a second, not the -calculated value, which is 112 for 2.6316ns - -To determine the hash time value for a non Icarus Rev3 device or an Icarus Rev3 with a different -bitstream to the default one, use 'long' mode and give it at least a few hundred shares, or use -'short' mode and take note of the final hash time value (Hs) calculated -You can also use the RPC API 'stats' command to see the current hash time (Hs) at any time - -The Icarus code currently only works with a dual FPGA device that supports the same commands as -Icarus Rev3 requires and also is less than ~840MH/s and greater than 2MH/s -If a dual FPGA device does hash faster than ~840MH/s it should work correctly if you supply the -correct hash time nanoseconds value - -The timing code itself will affect the Icarus performance since it increases the delay after -work is completed or aborted until it starts again -The increase is, however, extremely small and the actual increase is reported with the -RPC API 'stats' command (a very slow CPU will make it more noticeable) -Using the 'short' mode will remove this delay after 'short' mode completes -The delay doesn't affect the calculation of the correct hash time diff --git a/HACKING b/HACKING new file mode 100644 index 0000000000..e8e68b9abf --- /dev/null +++ b/HACKING @@ -0,0 +1,125 @@ +Driver API +========== + +NOTE: This API is subject to change. It is recommended that you submit your +driver, even if obscure, to the mainline BFGMiner codebase so that it will be +updated when the API changes. + +BFGMiner defines 3 different units that drivers can use: +- "Device" is a logical unit used for mining. It is represented by its first + processor's `struct cgpu_info`. Example: ButterFly Labs MiniRig SC. +- "Processor" is a logical work processing unit. It is represented by a `struct + cgpu_info` and one or more `struct thr_info`. Example: a single board within + ButterFly Labs MiniRig SC. +- "Thread" is a sequence of instructions and stack that manages hashing on one + or more Processors within a single Device. It is represented by a `struct + thr_info`. + +It should be noted that while every Processor has a `struct thr_info`, this may +not represent the same Thread which is managing hashing on the Processor. +Instead, this `struct thr_info` is only used to store status information needed +for the Processor, and is maintained by the managing Thread in addition to its +own `struct thr_info`. New drivers are encouraged to use an asynchronous model +to manage as many Processors as possible within a single Thread. + +struct device_drv basics +------------------------ + +Every driver defines a `struct device_drv`. The `dname` field contains a +short name of the driver. This should consist only of lowercase alphabetic +characters, and be the same name used in the source file: driver-foobar.c +defines `dname` "foobar". The `name` field contains a three-letter abbreviation +for the device, used in the representation of devices. For example, `dname` +"FOO" would result in devices represented as "FOO 0", "FOO 1", etc and +processors represented as "FOO 0a", "FOO 0b", etc. + +Drivers must define a function `drv_detect`, which is run at startup to detect +devices. For each device (note: NOT each processor), it should allocate a +`struct cgpu_info`, set some basic parameters on it, and call the `add_cgpu` +function with it as an argument. Various values you can initialize are: + .drv This MUST be set to your driver's `struct device_drv`! + .deven Should be set to DEV_ENABLED + .procs Number of Processors for this device + .threads Number of threads your device needs - should be either a + multiple of .procs (threads will be allocated to each + Processor), or one (a single thread will be allocated only to + the Device, to manage all Processors) + .name Null-terminated name of the device itself +`drv_detect` should return the total number of devices created. It should leave +the device in an unused state, as the user may opt to delete it outright. + +Threads +------- + +The first interaction BFGMiner will have with a device is by calling the +driver's `thread_prepare` function for each Thread. This occurs while BFGMiner +is still in a single-threaded state, before any Threads have actually started +running independently. It should do only the minimal initialization necessary +to proceed, and return true iff successful. + +Once all the Threads are setup, BFGMiner starts them off by calling the +`thread_init` function. This should do all initialization that can occur in +parallel with other Threads. + +The driver should specify a `minerloop` to use. For the purposes of this +document, it is assumed you will be using `minerloop_async`. Please note that +the default is currently `minerloop_scanhash`, and much of the documentation +here will NOT work with this `minerloop`. + +Processors +---------- + +Processors work with `struct work` objects, which each represent a block header +to find a solution for. Before your driver sees a `struct work`, it will be +passed to the function `prepare_work` with pointers to the Processor `struct +thr_info` and the `struct work` as arguments. Most drivers do not need to do +anything at this stage, so feel free to omit the `prepare_work` function. + +For each job, the `job_prepare` function is called in advance, with three +arguments: Processor `struct thr_info *`, `struct work *`, and a `uint64_t` +limiting how many nonces to check (starting from `work->blk.nonce`). Unless you +implement a `can_limit_work` function, you will always receive a full nonce +range from 0 to 0xffffffff. `job_prepare` increments `work->blk.nonce` to the +last nonce the processor will be attempting and returns true when successful. +Please note this will be called while the previous job is still executing. + +When it is time to actually start the new job, the `job_start` function will be +called. This is given the Processor `struct thr_info *` as its only argument, +and should start the job most recently prepared with `job_prepare`. Note that +it is possible for `job_prepare` to be called for a job that never starts +(another `job_prepare` may be executed to override the previous one instead). +`job_start` must call `mt_job_transition` as soon as the actual switchover to +the new job takes place, and must call `job_start_complete` when successful; +in case of a failure, it should call `job_start_abort` instead. `job_start` +must set `thr->tv_morework` to the time the device expects to need its next +work item. It is generally advisable to set this a bit early to ensure any +delays do not make it late. `job_start` is expected to always succeed and does +not have a return value. + +Immediately before `job_start` is called to change from one job to the next, +`job_get_results` will be called to fetch any volatile results from the +previous job. It is provided the Processor's `struct thr_info *` and the +currently executing job's `struct work *`. It should ONLY fetch the raw data +for the results, and not spend any time processing or submitting it. If +`job_get_results` is defined for your driver, it must (directly or indirectly) +ensure `job_results_fetched` is called when complete (including the case of +failure). After the new job has been started, your driver's +`job_process_results` function will be called to complete the submission of +these results with the same arguments, plus a bool to tell you whether the +processor is being stopped. If it is, your driver must call `mt_disable_start` +when it has successfully stopped hashing. + +Drivers may define a `poll` function. If this is defined, `thr->tv_poll` must +always be set to a valid time to next execute it, for each Processor. + +Whenever a solution is found (at any point), the function `submit_nonce` should +be called, passing the Processor `struct thr_info *`, `struct work *`, and +nonce as arguments. If the solution is invalid (any of the final 32 bits of the +hash are nonzero), it will be recorded as a hardware error and your driver's +`hw_error` function (if one is defined) will be called. + +As often as results are processed, your driver should call the `hashes_done` +function with a number of arguments: Processor `struct thr_info *`, count of +hashes completed (including calls to `submit_nonce`), a `struct timeval *` +that tells how long it took to find these hashes (usually time since the last +call to `hashes_done`, and a `uint32_t *` which should usually be NULL. diff --git a/Makefile.am b/Makefile.am index abc179badc..0709cebc76 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,93 +1,436 @@ +# Copyright 2012-2014 Luke Dashjr +# Copyright 2012 zefir +# Copyright 2011-2013 Con Kolivas +# Copyright 2013 James Z.M. Gao +# Copyright 2013-2014 Nate Woolls +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) +# any later version. See COPYING for more details. ACLOCAL_AMFLAGS = -I m4 -if WANT_JANSSON -JANSSON_INCLUDES= -I$(top_srcdir)/compat/jansson -else -JANSSON_INCLUDES= -endif +EXTRA_DIST = \ + m4/gnulib-cache.m4 \ + linux-usb-bfgminer \ + windows-build.txt + +dist_doc_DATA = \ + AUTHORS COPYING HACKING NEWS README \ + example.conf \ + README.RPC -EXTRA_DIST = example.conf m4/gnulib-cache.m4 linux-usb-bfgminer \ - ADL_SDK/readme.txt api-example.php miner.php \ - API.class API.java api-example.c windows-build.txt \ - bitstreams/* API-README FPGA-README +rpcexamplesdir = $(docdir)/rpc-examples +dist_rpcexamples_DATA = \ + api-example.php miner.php \ + api-example.c \ + api-example.py -SUBDIRS = lib compat ccan +SUBDIRS = lib ccan.bfg -INCLUDES = $(PTHREAD_FLAGS) -fno-strict-aliasing $(JANSSON_INCLUDES) $(USB_FLAGS) +# Without a redirected rule, code depending on different lib/*.h files may try to build dependencies of that in parallel, which can fail +lib/%: lib_directory + @test -e $@ +lib_directory: + $(MAKE) -C lib +ccan.bfg/libccan.a: + $(MAKE) -C ccan.bfg $* + +INCLUDES = -fno-strict-aliasing bin_PROGRAMS = bfgminer -bin_SCRIPTS = *.cl +sbin_SCRIPTS = + +if HAVE_WINDOWS +else +bin_SCRIPTS = start-bfgminer.sh +endif + +# first, our own stuff +bfgminer_LDADD = lib/libgnu.a ccan.bfg/libccan.a +bfgminer_LDFLAGS = +bfgminer_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib -I$(top_srcdir)/ccan-upstream -bfgminer_LDFLAGS = $(PTHREAD_FLAGS) -bfgminer_LDADD = $(DLOPEN_FLAGS) @LIBCURL_LIBS@ @JANSSON_LIBS@ @PTHREAD_LIBS@ \ +# second, potentially embedded libs +bfgminer_LDADD += $(libbase58_LIBS) $(libblkmaker_LIBS) +bfgminer_CPPFLAGS += $(libbase58_CFLAGS) $(libblkmaker_CFLAGS) + +# finally, everything else +bfgminer_LDFLAGS += $(PTHREAD_FLAGS) +bfgminer_LDADD += $(DLOPEN_FLAGS) @LIBCURL_LIBS@ @JANSSON_LIBS@ @PTHREAD_LIBS@ \ @NCURSES_LIBS@ @PDCURSES_LIBS@ @WS2_LIBS@ \ - @UDEV_LIBS@ @USB_LIBS@ \ - @MATH_LIBS@ lib/libgnu.a ccan/libccan.a -bfgminer_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib + @UDEV_LIBS@ @LIBUSB_LIBS@ @MM_LIBS@ @RT_LIBS@ \ + $(MATH_LIBS) +bfgminer_CPPFLAGS += @LIBUSB_CFLAGS@ @LIBCURL_CFLAGS@ + +bfgminer_CPPFLAGS += -DCGMINER_PREFIX='"$(pkgdatadir)"' + +bfgminer_CPPFLAGS += @JANSSON_CFLAGS@ +bfgminer_CPPFLAGS += $(PTHREAD_FLAGS) +bfgminer_CPPFLAGS += $(NCURSES_CPPFLAGS) + +bfgminer_CPPFLAGS += $(AUTOSCAN_CPPFLAGS) +bfgminer_LDADD += $(AUTOSCAN_LIBS) # common sources bfgminer_SOURCES := miner.c -bfgminer_SOURCES += elist.h miner.h compat.h bench_block.h \ - util.c uthash.h logging.h \ +bfgminer_SOURCES += miner.h compat.h \ + deviceapi.c deviceapi.h \ + util.c util.h logging.h \ sha2.c sha2.h api.c +EXTRA_bfgminer_DEPENDENCIES = + +TESTS = test-bfgminer.sh +EXTRA_DIST += test-bfgminer.sh +SH_LOG_COMPILER = /bin/sh +AM_TESTS_ENVIRONMENT = PATH='$(srcdir)':"$$PATH"; export PATH; +TESTS_ENVIRONMENT = $(AM_TESTS_ENVIRONMENT) +TEST_EXTENSIONS = .sh + +.PHONY: update-version +update-version: + ( cd $(top_srcdir) && $(top_srcdir)/gen-version.sh ) >version.h.new + cmp $(top_srcdir)/version.h version.h.new && rm version.h.new || mv version.h.new $(top_srcdir)/version.h +version.h: update-version +bfgminer_SOURCES += version.c version.h +BUILT_SOURCES = version.h + +SUBDIRS += $(libbase58_SUBDIRS) $(libblkmaker_SUBDIRS) +EXTRA_bfgminer_DEPENDENCIES += $(libbase58_EXTRADEPS) $(libblkmaker_EXTRADEPS) +@BUNDLED_LIB_RULES@ bfgminer_SOURCES += logging.c -# GPU sources, TODO: make them selectable -# the GPU portion extracted from original main.c -bfgminer_SOURCES += driver-opencl.h driver-opencl.c +if HAVE_WINDOWS +bfgminer_SOURCES += winhacks.h +endif + +if USE_UDEVRULES +dist_udevrules_DATA = 70-bfgminer.rules +endif -# the original GPU related sources, unchanged +if NEED_BFG_DRIVER_PROXY +bfgminer_SOURCES += driver-proxy.c driver-proxy.h +endif + +if USE_LIBMICROHTTPD +bfgminer_SOURCES += httpsrv.c httpsrv.h driver-getwork.c +bfgminer_LDADD += $(libmicrohttpd_LIBS) +bfgminer_LDFLAGS += $(libmicrohttpd_LDFLAGS) +bfgminer_CPPFLAGS += $(libmicrohttpd_CFLAGS) +endif + +if USE_LIBEVENT +bfgminer_SOURCES += driver-stratum.c +bfgminer_LDADD += $(libevent_LIBS) +bfgminer_LDFLAGS += $(libevent_LDFLAGS) +bfgminer_CPPFLAGS += $(libevent_CFLAGS) +endif + + +if USE_OPENCL +bfgminer_SOURCES += driver-opencl.h driver-opencl.c bfgminer_SOURCES += ocl.c ocl.h findnonce.c findnonce.h bfgminer_SOURCES += adl.c adl.h adl_functions.h -bfgminer_SOURCES += *.cl -if HAS_CPUMINE -# original CPU related sources, unchanged +kernelsdir = $(pkgdatadir)/opencl +dist_kernels_DATA = + +dist_doc_DATA += README.GPU + +if HAVE_SENSORS +bfgminer_LDADD += $(sensors_LIBS) +endif + +endif + + +if USE_KECCAK +bfgminer_SOURCES += malgo/keccak.c + +if USE_OPENCL +dist_kernels_DATA += $(top_srcdir)/opencl/keccak.cl +endif +endif + +if USE_SHA256D +bfgminer_SOURCES += malgo/sha256d.c + +if USE_OPENCL +dist_kernels_DATA += \ + $(top_srcdir)/opencl/diablo.cl \ + $(top_srcdir)/opencl/diakgcn.cl \ + $(top_srcdir)/opencl/phatk.cl \ + $(top_srcdir)/opencl/poclbm.cl +endif + +if USE_CPUMINING bfgminer_SOURCES += \ - sha256_generic.c sha256_4way.c sha256_via.c \ + sha256_generic.c sha256_via.c \ sha256_cryptopp.c sha256_sse2_amd64.c \ - sha256_sse4_amd64.c sha256_sse2_i386.c \ + sha256_sse4_amd64.c \ sha256_altivec_4way.c -# the CPU portion extracted from original main.c -bfgminer_SOURCES += driver-cpu.h driver-cpu.c +if HAVE_SSE2 +bfgminer_LDADD += libsse2cpuminer.a +noinst_LIBRARIES = libsse2cpuminer.a +libsse2cpuminer_a_SOURCES = sha256_4way.c +libsse2cpuminer_a_CFLAGS = $(bfgminer_CPPFLAGS) $(SSE2_CFLAGS) +endif if HAS_YASM + AM_CFLAGS = -DHAS_YASM if HAVE_x86_64 SUBDIRS += x86_64 +x86_64/libx8664.a: + $(MAKE) -C x86_64 $* bfgminer_LDADD += x86_64/libx8664.a else # HAVE_x86_64 SUBDIRS += x86_32 +x86_32/libx8632.a: + $(MAKE) -C x86_32 $* bfgminer_LDADD += x86_32/libx8632.a + +if HAVE_SSE2 +libsse2cpuminer_a_SOURCES += sha256_sse2_i386.c +endif + endif # HAVE_x86_64 endif # HAS_YASM -endif # HAS_CPUMINE +endif # USE_CPUMINING +endif # USE_SHA256D -if NEED_FPGAUTILS -bfgminer_SOURCES += fpgautils.c fpgautils.h +if USE_SCRYPT +bfgminer_SOURCES += malgo/scrypt.c malgo/scrypt.h +dist_doc_DATA += README.scrypt + +if USE_OPENCL +dist_kernels_DATA += \ + $(top_srcdir)/opencl/psw.cl \ + $(top_srcdir)/opencl/scrypt.cl \ + $(top_srcdir)/opencl/zuikkis.cl +endif endif -if HAS_BITFORCE +if USE_CPUMINING +dist_doc_DATA += README.CPU +bfgminer_SOURCES += driver-cpu.h driver-cpu.c +endif # USE_CPUMINING + +if NEED_BFG_LOWL_VCOM +bfgminer_SOURCES += lowl-vcom.c lowl-vcom.h +if HAVE_WINDOWS +else +bfgminer_SOURCES += iospeeds.h iospeeds_posix.h +endif +endif + +if HAVE_LIBUSB +bfgminer_SOURCES += lowl-usb.c lowl-usb.h +endif + +if NEED_BFG_BINLOADER +bfgminer_SOURCES += binloader.c binloader.h +endif + +if NEED_BFG_LOWLEVEL +bfgminer_SOURCES += lowlevel.c lowlevel.h +endif + +if NEED_DYNCLOCK +bfgminer_SOURCES += dynclock.c dynclock.h +endif + +if NEED_BFG_WORK2D +bfgminer_SOURCES += work2d.c work2d.h +endif + +if HAS_FPGA +dist_doc_DATA += README.FPGA +endif + +if HAS_ASIC +dist_doc_DATA += README.ASIC +endif + +if USE_ALCHEMIST +bfgminer_SOURCES += driver-alchemist.c +endif + +if USE_BITFORCE bfgminer_SOURCES += driver-bitforce.c endif -if HAS_ICARUS -bfgminer_SOURCES += driver-icarus.c +if USE_BITMAIN +bfgminer_SOURCES += driver-bitmain.c driver-bitmain.h +endif + +if USE_BIGPIC +bfgminer_SOURCES += driver-bigpic.c driver-bigpic.h endif -if HAS_MODMINER +if USE_DRILLBIT +bfgminer_SOURCES += driver-drillbit.c +endif + +if USE_TWINFURY +bfgminer_SOURCES += driver-twinfury.c driver-twinfury.h +endif + +if USE_ICARUS +bfgminer_SOURCES += driver-icarus.c driver-icarus.h +bfgminer_SOURCES += driver-cairnsmore.c +bfgminer_SOURCES += driver-erupter.c +bfgminer_SOURCES += driver-antminer.c +endif + +if USE_GC3355 +bfgminer_SOURCES += gc3355.c gc3355.h +endif + +if USE_GRIDSEED +bfgminer_SOURCES += driver-gridseed.c +endif + +if USE_DUALMINER +bfgminer_SOURCES += driver-dualminer.c +endif + +if USE_ZEUSMINER +bfgminer_SOURCES += driver-zeusminer.c +endif + +if USE_AVALON +bfgminer_SOURCES += driver-avalon.c driver-avalon.h +endif + +if USE_AVALONMM +bfgminer_SOURCES += driver-avalonmm.c +endif + +if USE_KNC +bfgminer_SOURCES += driver-knc.c +endif + +if USE_KNCASIC +bfgminer_SOURCES += driver-kncasic.c +endif + +if USE_KLONDIKE +bfgminer_SOURCES += driver-klondike.c driver-klondike.h driver-hashbusteravalon.c +endif + +if USE_MODMINER bfgminer_SOURCES += driver-modminer.c -bitstreamsdir = $(bindir)/bitstreams -dist_bitstreams_DATA = bitstreams/* endif -if HAS_ZTEX +if USE_TITAN +bfgminer_SOURCES += driver-titan.c titan-asic.c titan-asic.h +endif + +if NEED_KNC_ASIC +bfgminer_SOURCES += knc-asic/knc-asic.c knc-asic/knc-spimux.c knc-asic/knc-transport-spimux.c knc-asic/include/knc-asic.h knc-asic/include/knc-transport.h +endif + +if USE_X6500 +bfgminer_SOURCES += driver-x6500.c jtag.c jtag.h +endif + +if USE_ZTEX bfgminer_SOURCES += driver-ztex.c libztex.c libztex.h -bitstreamsdir = $(bindir)/bitstreams -dist_bitstreams_DATA = bitstreams/* endif + +if USE_BIFURY +bfgminer_SOURCES += driver-bifury.c +endif + +if USE_BITFURY +bfgminer_SOURCES += driver-bitfury.c driver-bitfury.h libbitfury.c libbitfury.h + +if USE_BFSB +bfgminer_SOURCES += driver-bfsb.c +endif + +if USE_BFX +bfgminer_SOURCES += driver-bfx.c +endif + +if USE_METABANK +bfgminer_SOURCES += driver-metabank.c tm_i2c.h tm_i2c.c +endif + +if USE_LITTLEFURY +bfgminer_SOURCES += driver-littlefury.c +endif + +if USE_NANOFURY +bfgminer_SOURCES += driver-nanofury.c mcp2210.c mcp2210.h +endif + +if USE_HASHBUSTER +bfgminer_SOURCES += driver-hashbuster.c +endif + +if USE_HASHBUSTERUSB +bfgminer_SOURCES += driver-hashbusterusb.c +endif + +endif + +if USE_COINTERRA +bfgminer_SOURCES += driver-cointerra.c driver-cointerra.h +endif + +if USE_HASHFAST +bfgminer_SOURCES += driver-hashfast.c +endif + +if USE_JINGTIAN +bfgminer_SOURCES += driver-aan.c driver-aan.h +bfgminer_SOURCES += driver-jingtian.c +endif + +if USE_MINERGATE +bfgminer_SOURCES += driver-minergate.c +endif + +if USE_MINION +bfgminer_SOURCES += driver-minion.c +endif + +if USE_ROCKMINER +bfgminer_SOURCES += driver-rockminer.c +endif + +if NEED_BFG_LOWL_FTDI +bfgminer_SOURCES += lowl-ftdi.c lowl-ftdi.h +endif + +if NEED_BFG_LOWL_HID +bfgminer_SOURCES += lowl-hid.c lowl-hid.h +bfgminer_CPPFLAGS += $(hidapi_CFLAGS) +endif + +if NEED_BFG_LOWL_MSWIN +bfgminer_SOURCES += lowl-mswin.c lowl-mswin.h +endif + +if NEED_BFG_LOWL_PCI +bfgminer_SOURCES += lowl-pci.c lowl-pci.h + +if USE_VFIO +sbin_SCRIPTS += setup-vfio +endif +endif + +if NEED_BFG_LOWL_SPI +bfgminer_SOURCES += lowl-spi.h lowl-spi.c +endif + +bin_PROGRAMS += bfgminer-rpc +bfgminer_rpc_SOURCES = api-example.c +bfgminer_rpc_LDADD = @WS2_LIBS@ diff --git a/NEWS b/NEWS index 3c0c70327e..6b2910e84f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6128 @@ +BFGMiner Version 5.5.0 - January 3, 2018 + +- Update official Win32/64 build compiler and libraries: +- - Win64 compiler (GCC) from 5.3.0 to 7.2.0 (Win32 remains at 4.7.4) +- - c-ares from 1.10.0-r1 to 1.11.0 +- - libjansson from 2.7 to 2.10 +- - libcurl from 7.47.1 to 7.57.0 +- - libevent from 2.1.5-r4 to 2.1.8 +- - libusb from 1.0.20 to 1.0.21 +- - libmicrohttpd from 0.9.48 to 0.9.58 +- - zlib from 1.2.8-r1 to 1.2.11-r1 +- Update copyrights +- AUTHORS: Update +- README.ASIC: Update Alcheminer +- alchemist: Reset using DTR as well +- alchemist: Experimental USB->UART Dongle Support on RPi +- make-release: Add crypt32.dll to OS-provided library list +- README: Expand on --set-device documentation +- Update libblkmaker to 0.6.0 +- openwrt: Update for LEDE 17.01 +- ccan: Update to latest version (which fixes musl libc support) +- Bugfix: probe_device_thread: Fix threadname buffer size +- Bugfix: appdata_file_call: Fix buffer size and loop +- Bugfix: SSM: Clear desired_default_share_pdiff when initialising +desired_share_pdiff before authentication +- cpu: Avoid relocations for x86_64 assembly that interfere with building +BFGMiner as a PIE +- Bugfix: SSM: We already hold the pool lock when we need to call stale_work, +so avoid trying to lock it a second time inside the function +- Bugfix: Hold the control lock when updating the generate-to script +- Bugfix: Hold the pool lock when updating lp_id +- Bugfix: icarus: Explicitly specify type wide enough for bitshift in +icarus_proc_for_nonce +- configure: BFG_FIND_INCLUDE_PATH: Handle more unusual syntax correctly +- Bugfix: SSM: Handle network problems safely, and use thread-safe libevent + + +BFGMiner Version 5.4.2 - March 26, 2016 + +- Update official Win32/64 build compiler and libraries: +- - Win64 compiler (GCC) from 4.7.4 to 5.3.0 (Win32 remains at 4.7.4) +- - libcurl from 7.39.0 to 7.47.1 +- - libevent from 2.0.21 to 2.1.5-r4 +- - libusb from 1.0.18 (Win32) and 1.0.19 (Win64) to 1.0.20 +- - libmicrohttpd from 0.9.38_pre33603 to 0.9.48 +- Update libblkmaker to 0.5.3 +- Bugfix: Sanitise lock situation for work2d +- Bugfix: SSM: Never issue the same work2d twice in a row +- Bugfix: SSM: Never send mining.notify for stale work2d +- SSM: Refactor work2d check and job pruning from _stratumsrv_update_notify +into stratumsrv_update_notify_str +- Updates for OpenWrt 15.05 +- Bugfix: Correct work2d handling for GBT servers + + +BFGMiner Version 5.4.1 - November 21, 2015 + +- bitmain: Use more portable PRIu64 rather than %llu (which fails on Windows) +- icarus: Use more portable PRIu64 rather than %llu (which fails on Windows) +- Bugfix: openwrt: Fix bitmain option +- Bugfix: antminer: Avoid strstr(NULL, ...) when device has no [available] +product string +- Update libblkmaker to 0.5.2 +- openwrt: Add option to enable bitmain driver +- openwrt: Update libusb device list + + +BFGMiner Version 5.4.0 - October 23, 2015 + +- AUTHORS: Move jstefanop to current maintainers +- Disable alchemist by default, add Travis build, and document configure option +in README +- alchemist: New scrypt ASIC driver +- hashfast: Support setting clock speed from TUI Manage +- avalon: Support setting clock speed from TUI Manage +- antminer: Support setting clock speed from TUI Manage (hidden for non-BM1382/4 +devices) +- jingtian: Allow changing clock speed from TUI +- Debuglog for retrodiff being disabled +- Disable retrodiff when it was not explicitly enabled, and the pool doesn't +seem to like it +- Bugfix: Only adjust work_difficulty on retrodiff submissions, so we can still +detect them on rejection +- (Re-)enable retrodiff by default for stratum pools, since some servers +implement mining.set_difficulty wrong in this way +- New pool option "retrodiff" +- If a share passes difficulty check for the updated pool target, record that +target for correct accounting of diff_stale. +- DevAPI: Remove unused temporary variable from driver iteration +- README.ASIC: Expand Antminer S5 section to S1-S5 for completeness, since in +theory they should work +- bitmain: Make reg_data optional for S4 and S5, calculating it from clock +- Document Bitmain Antminer S5 support +- bitmain: Remove poll_prio_threshold and just ensure we poll at a regular +interval to avoid nonce buffer overruns +- bitmain: Remove dead per-device constants +- bitmain: Only have one set of actual maximums +- bitmain: Migrate BITMAIN_MAX_NONCE_NUM to runtime packet_max_nonce +- bitmain: Migrate BITMAIN_MAX_WORK_QUEUE_NUM/bitmain_work_poll_prio to runtime +poll_prio_threshold +- bitmain: Migrate BITMAIN_MAX_WORK_NUM to runtime packet_max_work +- bitmain: Dummy model parameter +- bitmain: Remove baud/flush, as the fake VCOM kernel driver ignores (and +complains about) both +- bitmain: Poll after queuing work, once enough is queued +- bitmain: Sleep a little between polling +- bitmain: Flush queues for work restarts +- bitmain: Queue multiple works at a time +- bitmain: Remove more dead code +- bitmain: Prune old work eventually +- Bugfix: bitmain: Properly count work-search failures as HW errors +- bitmain: Refactor to work with minerloop_queue (leaks work memory) +- bitmain: Avoid busy-looping on network devices +- bitmain: Support for talking to a device over the network +- bitmain: Use the hottest reading for device temperature +- Bugfix: bitmain: Actually use baud setting +- bitmain: Remove more dead code +- bitmain: Handle stale results normally +- bitmain: Simplify num2bit +- bitmain: Initial set-device based configuration +- bitmain: Use lowl-vcom abstractions +- Update copyrights +- Bugfix: bitmain: Type-safe printf-format usage +- Travis: Test bitmain-only build +- Build bitmain driver +- bitmain: Hardcode configuration for now +- bitmain: Rework nonce_diff handling +- bitmain: Update headers +- bitmain: Deal with unused variable warnings sanely +- bitmain: Explicitly de-const device_path for freeing +- Bugfix: bitmain: Correct type of cgpu->temp reference +- Bugfix: bitmain: Use uint8_t consistently for binary data +- Bugfix: bitmain: Clear opt_bitmain_dev string properly +- bitmain: Remove non-existent bitmain_detect parameter +- bitmain: Cleanup unnecessary code +- bitmain: Use uthash to find queued work +- bitmain: Implement inc_dev_status within record_temp_fan +- bitmain: Remove non-applicable limits +- bitmain: Remove obsolete get_statline_before function +- bitmain: Move g_miner_version to bitmain_info struct +- bitmain: Remove direct USB code +- bitmain: Update driver registration +- bitmain: Update symbol names +- bitmain: Remove dead code +- bitmain: Replace custom hexdump with normal bin2hex +- bitmain: Get network difficulty from first work task +- bitmain: No-op htole8 +- bitmain: Simulate cgminer work_block somewhat +- bitmain: Update bin2hex usage for malloc-free version +- bitmain: Copy low-level code from Bitmain cgminer usbutils +- Copy working driver-bitmain.c from Bitmain's cgminer at commit +4ecf89341657ea7efecdf588586ca3f068ab17ab +- Add api_add_percent to miner.h +- Bugfix: DevAPI: Update includes from uthash to utlist and support older +versions of uthash +- Bugfix: RPC: Need to include utlist.h for config file list +- Bugfix: antminer: Avoid NULL dereference for non-BM1382/4 devices +- README.ASIC: Update documentation for BM1382/4 clock calculation support +- antminer: Support for setting BM1382/4 clock by frequency MHz +- Bugfix: Keep JSON from getaccountaddress around long enough for debug messages +- Bugfix: Run gen-version.sh from source directory +- Fix to enable building into directory out of source tree +- Bugfix: Clean up JSON from getaccountaddress +- Bugfix: Do not use hash tables for driver lists, since they require unique +keys +- Pool option #cksuggest to use CKPool-compatible mining.suggest_difficulty +- RPC: Add "Rotate Period" to config +- RPC: Extend setconfig to change strategy +- Allow setting strategy by name +- bitforce: Enable changing voltage from the Manage TUI +- avalonmm: Use proc_set_device_tui_wrapper instead of avalonmm_tui_wrapper +- DevAPI: Add generic proc_set_device_tui_wrapper +- bitforce: Add "voltage" setting to send V?X commands +- Bugfix: compac: Set dname so assignments match +- README.RPC: Add missing setconfig|stratum-port documentation +- README.RPC: Add missing setconfig|http-port documentation +- Bugfix: lowl-vcom: Check for tcgetattr/tcsetattr/tcflush failure +- configure: List compac driver in output +- Travis: Workaround Travis bug +- configure: Use AC_PROG_SED to find sed + + +BFGMiner Version 5.3.0 - September 5, 2015 + +- README.ASIC: Compac docs +- antminer: Explicit support for GekkoScience's Compac BM1384 Bitcoin Miner +- icarus: Use all null padding when probing work division (BM1384 reacts +strangely - using part as start nonce?) +- antminer: Match Product strings including "Antminer" +- Bugfix: icarus: Never set timeout to 0, since it disables the timeout +altogether + + +BFGMiner Version 5.2.0 - June 5, 2015 + +- Upgraded Windows hidapi library from 0.8.0_pre20130121 to 0.8.0_rc1_p20140719 +- Update bundled libbase58 to 0.1.4 +- README.ASIC: Document usage with AntMiner U3 +- icarus: Include ns/hash estimates for each nonce result, in debug logging +- icarus: Cleanup dev vs proc repr in logging +- Bugfix: update_block_display: Ensure we have console lock, and avoid rare +relock when resizing windows inside curses_print_status +- gitmodules: Change libblkmaker URI to use GitHub since Gitorious is defunct +- Bugfix: DevAPI: Avoid infinite hang in set_device help +- bitforce: Wait until pre-initialisation jobs all flush completely before +starting to avoid sanity check issues +- bitforce: Wait to clear job queue (at init) until we have actually opened the +device +- bitforce: Remove unnecessary delay +- Bugfix: vcom: Avoid overflowing cc_t before division to deciseconds +- Bugfix: bitforce: Ensure hashes_done is called for every completed job +- antminer: Adapt default configuration to work with U3 as well as U1/U2 +- antminer: Add U3 voltage setting (x??? format only for now) +- antminer: getstatus needs to read a result for every chip, but we don't use +the output anyway, so just skip it +- icarus: Modify work division detection packet to be compatible with Antminer +U3 +- icarus: Replace decisecond-precision read_count with read_timeout_ms +(millisecond precision) to handle faster devices like the Antminer U3 that +complete works in under 1ds +- lowl-vcom: vcom_set_timeout_ms function (increases precision to ms on Windows +only) +- util: timer_remaining_us function +- configure: Improve path finding macro to work with more possible CPP output +- configure: Macroify header path search +- Reduce HTTP request failure log level to DEBUG since it often occurs probing +stratum pools +- Bugfix: DevAPI: Guarantee set_device functions never get passed a NULL pointer +for newvalue +- Always update block display after pool display in case of username wrapping +around +- icarus: Pass device representation to icarus_{gets,write} so logging can use +it rather than fd numbers +- Bugfix: icarus: Check for impossibly fast hw errors (and don't report Eh/s +when they occur) +- Bugfix: icarus: Avoid a race with watchdog applying settings by setting +device_data before add_cgpu +- RPC: Clean up api_add_* somewhat +- Bugfix: util: Fix is_power_of_two +- Port antminer driver to use set_device_funcs + + +BFGMiner Version 5.1.0 - February 19, 2015 + +- Fix broken driver options in configure script +- Bugfix: extract_domain: Correctly handle query/fragment in URI without path +- kncasic: Do flush! +- kncasic: avoid duplicate nonces to be reported +- kncasic: Fix logging levels +- kncasic: Neptune-compatible API interface for enabling/disabling dies +- kncasic: Use one bfgminer processor per die (not per core) +- Update libblkmaker to 0.5.1 +- Titan: Lower log level when reconfiguring dies +- Titan: does not need SHA256d algo +- Titan: lower log level for flush messages +- Titan: adjust log levels in knc_titan_get_info +- get_master_rolling_hashrate -> get_proc_rolling_hashrate +- Update webconfig code to latest BFGMiner +- allow url based config files +- kncasic: Fix "double free" error +- kncasic: We need to free queued work to avoid memory leaks +- Bugfix: minion: Don't try to add 0-chip devices +- configure: Avoid BASHisms for better portability + + +BFGMiner Version 5.0.0 - November 29, 2014 + +- opencl: Fail gracefully if clGetProgramInfo/CL_PROGRAM_NUM_DEVICES returns +zero +- opencl: Remember results of global offset testing +- opencl: Only save kernel binary when we built from source +- opencl: Only try to patch BFI_INT when compiling a kernel from source +- opencl: Major refactor, splitting up opencl_load_kernel into many new +functions +- titan: Initialise variables to satisfy compilers +- Bugfix: opencl: Correctly handle non-goffset kernels +- Fixing column spacing of non-curses device output +- Bugfix: opencl: free memory if clState creation fails +- Titan: Do not do actual configuration job in API thread context. Instead, send +commands to the worker thread to do the actual job. +- Titan: bugfix: dies are not configured if die#0 is OFF +- Titan: unused function argument +- Titan: unused variables +- Update knc-asic: Titan FPGA image with spi->i2c commands removed and fixed +some lock-up scenarios +- Titan code rework: Use one bfgminer processor per die (instead of core) +- minion: Reinitialise chips if they don't seem to be progressing +- minion: Read temperature sensor +- minion: TUI clock speed control +- minion: Include "Frequency" in RPC status +- minion: Add "clock" setting +- minion: Set configuration parameters we care about +- minion: Reset chip at initialization +- minion: Configure PLL to 900 MHz at startup +- minion: Report hashes done as accurately as we can +- minion: Core enable/disable control +- minion: Implement queue flushing +- minion: Implement basic mining +- lowl-spi: linux_spi_txrx2 to include device protocol dumping +- minion: Detection code for the Prospero X1 +- Actually add version.c file +- Only rebuild a minimal version.c file when git commit changes +- Bugfix: Use HASH_ADD_KEYPTR for const char *, not HASH_ADD_STR +- Bugfix: Re-lock stgd_lock when we don't have a malgo-specific pool to use +- scrypt: Disable OpenCL by default +- opencl: Remove support for "OCL1" kernel define (indicated OpenCL 1.1+) +- opencl: Autodetect whether global offset actually works +- opencl: Add no-goffset support to scrypt kernels +- opencl: Determine kernel support for goffset by code analysis +- opencl: Add "goffset" setting to override detection of support for global work +offsets +- util: seek_data_cb: Check validity of offset +- Allow libcurl to rewind the upload buffer +- cpu: Set the priority of miner threads to idle on Windows +- cpu: Use _SC_NPROCESSORS_CONF instead of _SC_NPROCESSORS_ONLN +- cpu: Do not set thread affinity on single-processor systems +- Adding additional boolean keywords enable and disable +- AUTHORS: Move Pelle and Vitalii to "Current Maintainers" since they actively +maintain the Titan driver +- AUTHORS: Add Ronny Van Keer (Keccak C implementation) +- Titan: supply its own rolling hashrate implementation +- A driver can supply its own rolling hashrate function (in case generic +rolling hashrate implementation does not work) +- Bugfix: configure: kncasic does not actually need i2c-tools +- Keccak: Simplify keccak_hash_data +- keccak: Adapt opencl intensity interpretation to have approximately the same +desktop interactivity affect as SHA256d +- Keccak: Include support in various builds +- Travis: Update with Keccak +- opencl/keccak: Add non-goffset support +- opencl/keccak: Unroll all the hash rounds properly +- opencl: Add Keccak support via "fullheader" kernel interface +- keccak: Adapt for BFGMiner +- Keccak: Import algorithm code as-is +- opencl: Add a simple "fullheader" kernel interface +- Update stratum mining.capabilities method to use a single Object for all +parameters +- Bugfix: Correct USE_SHA256D macro name to ensure SHA256d is always preferred +as default algorithm +- cpu: Generic scanhash that can support any PoW algorithm +- RPC: Include Hash Method in minecoin for new algorithms +- opencl: Teach findnonce to behave based on kernel interface rather than mining +algorithm +- opencl: Get min_nonce_diff from struct mining_algorithm +- Move malgo-specific code to dedicated source files +- opencl: Simplify kernel-specific data handling +- Update knc-asic: Fix issue with detect_die crashing due to errors in response +- titan: Init last_nonce on die reconfiguration to avoid lots of "unknown work" +messages +- Bugfix: titan: Extra garbage was sent on SPI with new commands +- titan: Remove temporary log messages for manual report checks +- titan: Wrong variable used in new per-die iteration +- titan: Do manual core checks in parallel with normal ones +- titan: Fix: Only one die was checked after flush in last commit +- titan: Manually check all cores for reports after flush +- opencl: Remove redundant checks for USE_OPENCL +- cpu: Remove redundant checks for USE_CPUMINING +- opencl: Only attempt to BFI_INT patch SHA256d kernels +- Significantly rewrite configure script to handle driver dependencies cleaner +- Make SHA256d mining optional +- Bugfix: cointerra: Can handle nonces down to pdiff 1 +- kncasic: Initialise first_cgpu to silence false warning +- Bugfix: Clarify goffset decision code, and refuse to compile kernels in +situations where they won't work +- Bugfix: opencl: Output buffer must be readable by kernel since it is used with +a count/position iterator +- Bugfix: opencl: Skip NULL kernel interface entry +- DevAPI: hashes_done: Simplify and improve precision of max_nonce calculation +- opencl: Avoid duplicating kernel_interfaces mapping in select_kernel +- opencl: Avoid duplicating kernel_interfaces mapping in +opencl_scanhash_get_kernel +- cpu: Drivers should not be doing fulltest on their own, so remove it +- cpu: Pass full work struct to scanhash functions +- kncasic: Split up each ASIC channel to its own device +- kncasic: Use consistent naming for KNC_MAX_DIES_PER_CORE +- kncasic: Refactoring: coreid is not used, remove it +- kncasic: Refactoring: put all device architecture defines in one place (knc-asic.h) +- kncasic: Add lock to protect concurrent accesses to knc_state +- kncasic: Fix auto +- Build system fixes for kncasic driver +- configure: Deduplicate Linux i2c-dev.h checks for KnCMiner drivers +- Travis: Update for kncasic driver +- kncasic: Only show the relevant die for RPC stats +- kncasic: Use proc_repr for logging +- kncasic: Split up logical processors +- kncasic: Silence warning about unhandled enumeration values +- Bugfix: kncasic: Proper format specifications +- kncasic: Remove unused code +- kncasic: Minimal changes to get it compiling +- kncasic: Import gen 2 driver from cgminer commit +bc153552be8591250cb3214bf5202501d4a39922 +- titan: Move thread_reportin() call to poll function +- titan: reportin every process_report to avoid falsely tripping the watchdog +- titan: Remove unused variables +- Bump knc-asic submodule +- titan: Increase FPGA to ASIC SPI frequency to 6 MHz +- titan: Use new get_work_status prototype and print FPGA CRC error counters to +log +- Titan flush optimization fix: Don't send get_info commands when FPGA is +speaking to ASIC +- titan: All dies use same nonce working range +- Titan flush optimization bugfix: FPGA status was checked once per poll instead +of once per ASIC +- Titan flush optimization: Bugfix: Flush time measurement only worked with one +ASIC +- Titan flush optimization: Point knc-asic submodule to include new FPGA image +- Titan flush optimization: Remove temporary debug messages +- Titan flush optimization: Keep works in local queue until slot number is +reused +- Titan flush optimization: Point knc-asic submodule to needed revision +- Titan flush optimization: Measure new flush time +- Titan flush optimization: Send works to all dies after flush +- Titan flush optimization: First rough implementation +- Titan: Less clobber on the screen: group some "failure" messages +- Bugfix: Prefer not using work created just to ensure a specific algorithm is +queued, so strategies work as much as possible +- Stratum: Enable mining.set_goal to change parameters on the current goal +- cpu: Fail gracefully if unsupported mining algo gets into scanhash +- opencl: Fail gracefully if unsupported mining algo gets into +opencl_scanhash_get_kernel +- SSM: Send goal malgo to goal-enabled clients +- Allow pools with #change_goal_malgo attribute to change the mining algorithm +used by their assigned goal +- Gracefully fail when no pool can be found to generate specific-algo work +- Remove opt_scrypt +- dualminer: Replace opt_scrypt with a per-device "scrypt" option +- dualminer: Make dual_mode a per-device option as it should be +- opencl: Nearly complete migration to per-work mining algorithms +- pool_actively_desired: If we are the highest priority, workable pool for a +given algorithm, we are needed +- Ignore opt_queue for unused mining algorithms +- Set name and aliases on mining algorithms +- When hotplug is enabled and a mining algorithm is configured for the first +time, schedule a rescan of hardware to pick up anything now applicable that may +not have been before +- Try to keep enough work queued for each mining algorithm in use +- Move select_loadbalance and select_failover logic into their own functions +- Keep track of how much work is staged per-algorithm +- Keep track of how many goals reference each mining algorithm +- Abstract goal_set_malgo function +- Build a mining_algorithms list +- get_work: Restore previous getwork rollntime behaviour +- get_work: Only return work items compatible with processor (degrades getwork +rollntime support) +- opencl: Support for per-work mining algorithms +- Build without POW_SCRYPT at all +- opencl: Defer loading kernel until it is needed +- opencl: Split initCl into opencl_create_clState and opencl_load_kernel +- SSM: Implement mining.capabilities including proxying mining.set_goal +- Replace mining.goal.subscribe with mining.capabilities +- Stratum: Avoid resetting the goal if the old and new name match +- Allow specifying goal options as eg, --pool-goal name:malgo=scrypt +- cpu: Support for per-work mining algorithms +- Replace cgpu.min_nonce_diff with drv.drv_min_nonce_diff(cgpu, malgo) +- proxy: Avoid assumptions about mining algorithm at initialisation +- Core only: Partially move most of opt_scrypt to mining_goal +- opencl: Reintroduce independent intensity setting internally +- Move MAX_*_INTENSITY stuff to driver-opencl.h +- proxy: Minimise minimum difficulty for proxy clients +- Enable --generate-to option (was --coinbase-addr) to work with non-default +goals +- Save pool goals in written config files +- README: Update documentation for multiple blockchain support +- RPC: Add "Difficulty Accepted" to "coin" command +- RPC: Add "Mining Goal" to "pools" command +- RPC: Accept an additional argument for "addpool" to indicate mining goal by +name +- Stratum: Support for mining.set_goal("goal name") - currently just resetting +the user-configured goal +- Teach longpoll logic about multiple mining goals +- RPC: Include non-default goals in reply to "coin" command +- Ignore generation address/script on pools using non-default mining goals +- Only include block display lines for active goals +- Move income to block display line, and show extra block display lines for each +additional mining goal +- New --pool-goal option to set a distinct named goal per-pool +- Parameterise most references to global mining_goal_info +- Move block_time to be per block_info +- Show "?" for income if block height is unknown +- Move block height tracking onto block_info +- Calculate current_fullhash only when needed (for RPC 'coins') +- Replace current_block_id with blkchain->currentblk[->block_id] +- Move current_hash to goal->current_goal_detail +- Clean up struct block_info names +- Use full prevblock hash as block key (also gets rid of dead code) +- Move global variables related to the blockchain or mining goals on to global +structs + + +BFGMiner Version 4.10.1 - November 29, 2014 + +- Upgraded Windows libcurl from 7.38.0 to 7.39.0 +- Bugfix: bytes_free: Set buf to NULL so the bytes_t is reusable +- Bugfix: minergate: Avoid malloc(0) if stats file has too few values +- Bugfix: modminer: Avoid leaking devname when detecting claimed devices +- Bugfix: free memory allocated for config file loading/writing +- Bugfix: nanofury: Avoid NULL pointer dereference on init failure +- Bugfix: varint_decode: Correctly decode multibyte numbers +- cpu: Fix processor count detection with HW_NCPU +- cpu: SCHED_IDLE and SCHED_BATCH can only be used with sched_priority 0 +- cpu: fix sched_setaffinity parameter : sizeof(cpu_set_t) +- Bugfix: opencl: Correctly accept negative intensities and set dynamic +intensity without changing current value +- Since longpoll connections are never reused, explicitly forbid reuse so +libcurl cleans them up immediately +- Bugfix: Correct already-in-use getcbaddr message +- Demote some Bitfury debug log messages to only with device protocol dumping +- Update bundled libbase58 to 0.1.3 +- README.ASIC: Minor cleanups to Zeusminer section +- README.ASIC: Explain Zeusminer options +- Makefile: Specify .cl files explicitly, and only include scrypt ones when +configured with scrypt support +- Bugfix: DevAPI: hashes_done: Explicitly cast to uint64_t for big calculations +(LLVM was allowing overflow) +- Bugfix: titan: First core in each die got too big nonce area to work on +- Travis: Build MinGW64 with ncurses +- Bugfix: Declare manual_enable_pool in miner.h, for api.c use +- Bugfix: bitfury: Use long long and llabs to avoid under/over flows misbehaving +- Bugfix: Highlight all active pools, in pool listing +- Set quota to 1 when enabling a failover-only pool, and disable failover-only +when setting quota +- Bugfix: pool_actively_desired: Detect failover-only conditions for loadbalance +and balance strategies +- Bugfix: Only display pools as Failover state when it is effectively so +- Make sure KEY_EVENT from wincon is ignored (it conflicts with ncurses) +- README.ASIC: Add details for BFx2 USB +- Titan: Submit stale shares while doing flushes +- README.ASIC: Remove CFLAGS hack not needed for KnCMiner Titan build +- Bugfix: Need unicode_micro in non-Unicode curses builds +- Remove unused variables from curses-less builds +- Bugfix: Cannot duplicate userpass option or we end up with it processed double + + +BFGMiner Version 4.10.0 - October 21, 2014 + +- Upgraded Windows libjansson from 2.6 to 2.7 +- i2c-tools are not required by Titan +- minergate: Fix hashmeter +- minergate: Support minergate-side ntime rolling for SP30 only +- minergate: Autodetect SP30 on /tmp/connection_pipe_sp30 +- minergate: Make stats file configurable +- minergate: SP30 only wants max 10 queue requests at a time +- minergate: Use work_completed flag for SP30 +- minergate: Only SP10 has a second winner_nonce +- minergate: Simplify multi-winner_nonce handling +- Bugfix: minergate: Correct endian for 2nd winner_nonce +- minergate: Vary max jobs queued +- minergate: Vary number of requests/responses per packet +- minergate: Support --set MGT:protover=N +- Titan: fix compiler warning "maybe-uninitialized" +- Titan: Increase die inactivity timeout to 20 secs +- Titan: Slightly improve some debug messages +- Titan: Use multi-part batched SPI transfers for flushes (saves 2 secs on each +flush) +- Titan: Fix buffer overflow +- Titan: Increase queue prefill value up to 20 +- Titan: Flag for fast broadcast flushes. Not enabled: DC/DCs trip off easily! +- Titan: Monitor die health, reconfigure it if no shares in 10 seconds +- Titan: Make log level of some messages lower, to not clobber the screen +- Titan: Work assignment and flushing is per-die, not per-ASIC +- Titan: Set flush flag after re-configuring the die +- Titan: Refactoring: intermediate variables for first_proc and repr +- Titan: Flush cores one-by-one right before reconfiguring them +- Titan: Define for the broadcast core address +- Titan: Re-configuring dies through API command "procset" +- Titan: Use correct version of knc_titan_setup_core +- Titan: configure_one_die func for configuring single die +- Titan: fill all non-found ASIC structs with the same (invalid) data +- Titan: Core init parameters (nonce range) independent of number of found dies + + +BFGMiner Version 4.9.0 - October 5, 2014 + +- Upgraded Windows libraries: +- - libcurl from 7.37.0 to 7.38.0 +- - libusb from 1.0.18 to 1.0.19 (Win64 only) +- - mingw64-runtime from 3.1.0 to 3.2.0 (Win64 only) +- - uthash from 1.9.7 to 1.9.9 +- Travis: Update for titan driver +- configure: Accept --enable-titan=CONTROLLER to select controller +- make-release: Remove unnecessary knc-asic/{*.rbf,*system,waas} from release +source +- extra_work_queue so devices can influence their effect on the central work +queue somewhat (titan needs less than 1-per-proc) +- Avoid adding include paths for titan driver +- Bugfix: titan: Add missing printf formatting for core busy status +- avalon: Drop custom hexdump logging +- Build titan driver independently from knc (Jupiter) driver +- titan: Do not fill up next slot immediately after urgent setwork +- titan: Pre-fill work queue so that all ASICs have fresh jobs after a flush +- Build instructions for KnC Titan +- Doesn't compile without explicitly included inttypes.h on some machines +- knc-asic: Updated to e5c986d3c44fde8c5b069508ef6979f2f2be92d6 +- Fix Makefile.am to build bfgminer for titan +- titan: Subdivide full nonce range only between cores in one ASIC (because +works are now distributed per-ASIC too) +- titan: DC/DCs does not like broadcast flushes (urgent setwork). Do not do it! +- titan: Preparation to setting threads-per-core externally, by user +- titan: Re-flush cores in case of slot number collision +- titan: Per-ASIC flush, per-ASIC work management +- titan: Start cores after flush individually, not by broadcast. +- titan: Default frequency is 275 MHz +- titan: Difficulty is offset by one in ASIC cores. +- titan: Fix first_proc pointer +- titan: Use 2 threads per core +- titan: Use setup_core from knc-asic library +- titan: Poll all enabled ASICs amd dies, not only one +- titan: Properly set work_accepted flag +- titan: Hint detection function about expected device type +- titan: Fix setup_core command +- titan: Use knc-asic library for transport layer +- Add knc-asic as submodule +- titan: Change spi device to spidev1.0 +- titan: Add define to .h file +- titan: Increase workqueue size up to number of slots per core +- titan: Send data to hashmeter +- titan: Disregard stale reports after flush +- titan: Check for next asic/die switch when processing info results +- Bugfix: titan: Fix segfault +- titan: Set actual hardware nonce_diff for works in prepare_work +- titan: Do clean flush ("purge") on init +- titan: Store last_nonce right +- titan: First attempt to process nonce responses +- titan: Change 'scanhash' minerloop to 'queue' +- titan: Init all cores for their own nonce ranges +- titan: For RPi we use spidev0.1 +- titan: Setup_core command implemented +- titan: New commands set_work & get_report +- titan: Move asic-specific functionality to the separate file (titan-asic.c) +- titan: First ugly detect of Titan chip over SPI +- knc-titan: Begin work on Titan (scrypt miner) driver +- libbase58: Use git URI for submodule to avoid failure on systems without HTTPS +support +- Travis: Cross-compile a Win64 build +- RPC: Initialise json_config to silence false warning +- Make sure MOUSE_MOVED from wincon is ignored (it conflicts with curses) +- Travis: Perform full builds with libbase58's base58 tool (which is used for +tests) +- Travis: Test many configuration variations +- Travis: Build with libsensors and VFIO +- Travis: Upgrading GCC triggers locale rebuild, so just do the one in use +- Travis: No need to upgrade GCC for LLVM build +- Travis build configuration +- Run BFGMiner's unit tests for 'make check', and have --unittest exit with +failure if any problems occur +- libbase58: Update to pick up on LLVM fixes +- Bugfix: configure: Affect gridseed driver with --disable-other-drivers +- Bugfix: configure: minergate driver needs lowlevel for claiming sockets +- Bugfix: configure: --disable-other-drivers should not affect non-driver +options +- Bugfix: configure: --with[out]-vfio needs $withval, not $enableval +- Bugfix: rockminer: Correct types for short read error message +- Bugfix: icarus: fix the STATS RPC API call crashes with a multi-proc device +- Bugfix: cointerra: Check lowlevel device is USB before trying to probe it (as +USB) +- bitforce: Reinstate device work inprogress count sanity check for 28nm devices +- littlefury: Read uC temperature sensor +- littlefury: Keep track of enabled chips and power state explicitly in case of +trouble +- Bugfix: async minerloop fix for devices disabled at start +- twinfury: Implement device protocol dump more low-level + + +BFGMiner Version 4.8.0 - September 10, 2014 + +- Improve precision of total_secs used in (at least) RPC summary Elapsed +- Bump embedded libblkmaker to 0.5.0 +- Bump embedded libbase58 to 0.1.1 +- Remove now-unused bfg_cond_timedwait which cannot be made portable +- Spawn a new thread for cmd-idle rather than relying on problematic pthread +timedwait +- README: --coinbase-check-* options +- Bugfix: Accept actual percentages for --coinbase-check-percent +- Optimise coinbase check logic by using actual script bytes everywhere possible +- Pool option #skipcbcheck to disable new coinbase checks +- pool_check_coinbase: Avoid redisabling an already misbehaving pool +- Bugfix: Keep connection active for rejecting and misbehaving pools so we can +detect when they recover +- Share pool coinbase check reaction code +- Initial version of coinbase checking function for GBT and stratum +- cointerra: Ensure devlog messages cannot overflow +- Bugfix: cointerra: Defer setting USB timeout until after initialisation +- cointerra: Set configuration and claim interface +- Bugfix: cointerra: Check ep is open before trying to talk to it (crash at init +failure) +- cointerra: Support for --set cta:load=N +- cointerra: Store load setting on struct cointerra_info +- cointerra: Operate within a single thread +- cointerra: Update to minerloop_queue +- cointerra: Split work packet into cointerra_queue_append function +- cointerra: Prepare for splitting work packet into cointerra_queue_append +function +- cointerra: Use more fresh code for work packet +- cointerra: Use fresh code for work packet +- Bugfix: cointerra: Use bfg_cond_timedwait to avoid spinning +- cointerra: Claim and release lowlevel device +- cointerra: Propagate per-core temperatures to each processor +- cointerra: Reduce redundant stats information +- cointerra: Correctly divide up individual processors +- cointerra: Update to latest BFGMiner +- work_ntime_range helper function +- work_{get,set}_ntime inline functions +- Store a reference timeval with ntime_roll_limits +- util: min macro +- cointerra: Cleanup debugging +- cointerra: Divide up processors +- cointerra: Wait for info packet on probe +- cointerra: Dirty BFGMiner port +- lowl-usb: Cleanup dead code +- notifier_wait, notifier_wait_us, and notifier_reset functions +- Export the flush_queue function for use by drivers. +- Provide a function to discard queued work based on age. +- Export share_diff function and add flip12 macro +- Provide a copy_work_noffset function for copying a work struct but changing +its ntime. +- Add api_add_int16 to API functions. +- cointerra: Remove nodev checks for now +- cointerra: Replace reset semaphore with a simple notifier +- Build cointerra driver +- cointerra: Import driver from cgminer as-is +- Silently ignore shares rejected if they were above target and only got +submitted "just in case" +- Abstract put_in_parens function +- Abstract extract_reject_reason function +- Remove dead code +- Bugfix: bfg_cond_timedwait providing semantics expected for --cmd-idle +implementation +- Per-processor TUI: Align columns for more-than-one proc letter +- m4/bundled_lib: Workaround bug in autoconf <2.64 +- If full version is too long, try truncating it at '-' +- Bugfix: Fix CPU miner benchmarking within benchmark-intense mode +- benchmark: Detect duplicate shares within 5 minutes +- benchmark-intense: benchmark_update_interval constant in code +- benchmark-intense: Detect stale results +- benchmark-intense: Update work every second +- benchmark-intense: Simulate 250 KB generation transaction +- benchmark-intense: Generate individual work items from 2D work (tests host CPU +rate of work production) +- Introduce --benchmark-intense option +- Import libbase58 for base58 encoding/decoding +- Cleanup libblkmaker bundling code to mostly live in autoconf macros +- Always check if we should switch pools when enabling one, and always enable +pools we want to switch to + + +BFGMiner Version 4.7.1 - September 10, 2014 + +- Bugfix: Reorder LDADD and such for priority +- Bugfix: bitforce: Initialise variable to NULL +- Bugfix: SSM: Use client_next member consistently when working with +stratumsrv_connlist +- Bugfix: SSM: Check that a username is provided to mining.authorize +- Bugfix: SSM: When n2pad<0, release lock before returning +- Bugfix: SSM: Make buffers long enough to avoid overflows +- Bugfix: Need signed types for ntime min/max offsets +- Bugfix: rockminer: Fix processor disabling +- rockminer: Limit even unsafe frequencies to 640 MHz, since above that +overflows frequency bits and triggers fan control +- tq_pop: Remove abstime argument since nothing used it and it wouldn't work +anyway (uses CLOCK_REALTIME while we use CLOCK_MONOTONIC[_RAW] when possible) +- Bugfix: Check last solo generation tx against new template rather than most +recent +- README: Explicitly mention automatic solo mining configuration, and stress the +importance of --coinbase-sig +- Bugfix: Recheck current_pool after calling pool_died +- Bugfix: Stable pool recovery: Only care if the pool is enabled +- README.ASIC: Add a section for Gridseed +- Bugfix: benchmark: Free json_null() after use +- Bugfix: minergate: Claim socket before we initialise a cgpu for it +- Bugfix: avalonmm: Claim device before we initialise a cgpu for it +- Bugfix: switch_pools: Broadcast lp_cond outside of control_lock to avoid +deadlocking +- Protect enabled_pools by a mutex in disable_pool function +- Combine reject_pool into disable_pool function, and don't allow it to override +a manual disable +- Call disable_pool() at the begin of remove_pool() and combine them when +appears together in the code +- Bugfix: Always call enable_pool and disable_pool to ensure consistent handling +of the situations +- Remove dead CPU mining code to silence warnings + + +BFGMiner Version 4.7.0 - August 17, 2014 + +- openwrt/multibuild: Avoid copying bitforce-firmware-flash, which is no longer +included +- AUTHORS: Simpler design, alphabetise lists +- Remove obsolete SuSE packaging +- Bugfix: test_hash: Fix Htarg calculation for exact binary divisions of diff 1 +- Fix target calculation from diff < 1.0 in test_hash() +- avalonmm: Try to autodetect a sane default voltage and clock from MM version +- avalonmm: Only poll one module at a time, so they don't try to talk over each +other +- avalonmm: Set baud rate for detection +- Stratum: Ignore response from mining.extranonce.subscribe +- Stratum: Implement mining.set_extranonce, and advertise support for it to +pools with a #xnsub flag +- Stratum: Keep nonce1 and n2size in a "staging" state until mining.notify is +received +- Stratum: Avoid putting new targets on pool stratum_work until mining.notify is +received for it +- minergate: Flush during init +- minergate: Flush ready-to-queue list +- minergate: Avoid preparing new jobs to queue while we are pending a flush, +since the flush would occur after queuing the new jobs +- minergate: Check for reused job ids +- minergate: Avoid counting flushed jobs toward hashes done +- minergate: Report all temperatures individually to RPC +- minergate: Load temperatures from stats file +- minergate: Implement hashmeter +- minergate: Scale nonce difficulty up to pdiff 32 +- minergate: Implement mining +- minergate: Support for detecting a SP10 +- Bugfix: configure: avalonmm needs work2d +- Bugfix: bitforce: Remove sanity check triggered by race conditions on 65nm +devices +- Bugfix: bitforce: Avoid double-free of voltage data + + +BFGMiner Version 4.6.0 - August 2, 2014 + +- avalonmm: Even if no fans report speed, display set % +- Bugfix: avalonmm: Fix fan speed setting +- Bugfix: avalonmm: Actually read the result needed to get the correct module id +- README.ASIC: Document AvalonMM driver usage with Avalon 2/3 rigs +- Bugfix: Makefile.am: Remove reference to non-existent driver-avalonmm.h +- avalonmm: Safely handle an improper job id that is within the last 2 sent +- avalonmm: Include asserted fan speed in RPC +- avalonmm: Include asserted fan speed in ManageTUI +- avalonmm: Silence warning about detect ack at runtime +- avalonmm: Make fan speed an option (both RPC and TUI) +- avalonmm: Allow changing clock speed and voltage from Manage TUI +- Bugfix: avalonmm: Show proper units for fans & voltage +- avalonmm: Support for disabling the entire chain +- Implement broad_udevrules for avalonmm +- avalonmm: Show extranonce1, module id, temperatures, fans, clock, and voltage +in Manage TUI +- avalonmm: Include Module Id and ExtraNonce1 in RPC devdetails +- avalonmm: Add Temperature0/1 and Fan Percent 0/1 to RPC +- avalonmm: Add Frequency and Voltage to RPC +- avalonmm: Add voltage setting (defaults to 0.6625 V) +- avalonmm: Add clock setting and try to autodetect it if not provided +- avalonmm: Implement hashmeter +- avalonmm: Adjust device target up to pdiff 32 when possible +- avalonmm: Update job when current pool changes +- Bugfix: avalonmm: MM flips the xnonce2, so we need to do the same +- avalonmm: Implement mining logic +- lowl-spi: Move bit order reverse to bitflip8 function in util +- avalonmm: Treat multiple chained modules as slaves rather than processors +- avalonmm: Probing for devices using Avalon Miner Manager (Avalon2/3 rigs) +- littlefury: Move crc16 logic to util +- Use BUILT_SOURCES to ensure version.h is always built first +- configure option --with-udevrules-group to allow customising the group name +used +- Bugfix: zero_stats: Only call cgpu function if it exists +- Remove FPGA-only bitforce-firmware-flash tool (now located at +https://github.com/luke-jr/bitforce-fpga-firmware-flash ) + + +BFGMiner Version 4.5.0 - July 26, 2014 + +- Bugfix: zeusminer: Fix crash in TUI with newly introduced feature +- Bugfix: gridseed: Fix crash in TUI with newly introduced feature +- gridseed: Add the ability to set clock speed via the TUI +- bitforce: Support for Monarch devices on Windows using new "mswin" lowlevel +interface to scan for KMDF driver +- Bugfix: gridseed: Implement a proper scanhash routine for GridSeeds +- zeusminer: Add the ability to set clock speed via the TUI +- Bugfix: gridseed: Only set PLL frequency once (not once per processor) +- Bugfix: zeusminer: Retry detection on failure - ZM fails detection 1 / ~30 +times +- Bugfix: zeusminer: Enabling the ZeusMiner driver should flag needing lowl-vcom +- aan: Silence false warnings +- Include broad udev rules when configured with --enable-broad-udevrules option +- Bugfix: util: Lower the threshold for considering pool Scrypt diff broken +- Bugfix: gc3355: Do not send work_id (or anything) in the last 4 bytes of work +- gridseed: Refactor code to clean up and organize +- gridseed: Document GridSeed specifics with comments and URLs +- Copyright cleanups and updates +- Bugfix: zeusminer: using icarus timing can lead to false positive Idle +detection +- zeusminer: Return the Chip # via the RPC API call procdetails +- zeusminer: Display the Chip # in the UI when viewing per-proc details +- Bugfix: miner: Check work->blk.nonce to see if work should be abandoned +- rockminer: Allow setting clock 300-2560 as long as prefixed by "unsafe:" +- util: Work around broken Scrypt pools automatically using realistic pdiff +assumptions +- scanhash: Document scanhash related methods with comments +- Bugfix: gridseed: Report communication errors using dev_error() +- gc3355: Return bytes read to distinguish 0 bytes from error +- Bugfix: gridseed: Add delay between Scrypt reset and sending work +- gridseed: Bugfix: fix the constant used for estimated hash rates +- klondike: zero_stats support +- bitforce: zero_stats support (Temperature, Voltage, and Avg Wait) +- avalon: zero_stats support (temp_max, no_matching_work, match_work_count%d) +- Add driver interface for zero_stats function +- Bugfix: bitforce: Short-circuit bitforce_read(0) to avoid lowlif issues +- Bugfix: bitforce: Ensure data for the current command is always read (and only +once), with lowl-pci +- Bugfix: setup-vfio: Add device ids to vfio-pci even if they didn't have a +driver previously +- Bugfix: lowl-pci: Use volatile qualifier for PCI mmaps +- Bugfix: bitforce: Use lowlevel interface device was probed with, for actual +mining +- setup-vfio: New shell script to automatically configure VFIO +- README.ASIC: Monarch: Need to do new_id for every affected device, and only +after unbinding them +- README.ASIC: Monarch: Use shell variables for commands +- gridseed: Bugfix: Revert earlier changes to scanhash based on feedback +- hashfast: Support for changing clock at runtime +- hashfast: Store a copy of what we believe to be the chip configuration data +- hashfast: Store firmware revision +- util: pk_uNle macro for changing a number inside a packed structure +- README.ASIC: KnCMiner: Talk about additional i2c-tools dependency +- README.ASIC: KnCMiner: Remove mention of now-obsolete Bertmod +- README.ASIC: KnCMiner: Grammatical corrections +- Bugfix: RPC: Avoid processor-specific details in devdetails +- gridseed: Bugfix: log invalid detect responses as debug info, not an error +- zeusminer: Support setting clock via RPC API procset call +- README: Add Controla and Minera controller software links & info +- gridseed: Bugfix: Fix hash-rate calculation when no nonces are being found +- dualminer: Bugfix: assign the proper value for work_division +- gridseed: Refactor to clarify GridSeed terminology +- gridseed: Add support for displaying per-chip statistics +- gridseed: Convert to use newer set_device_funcs interface +- Bugfix: gridseed: Don't leak cgpu_info when devices are already claimed +- icarus: Processor detail support +- DevAPI: Allow using device_proc_by_id with const struct cgpu_info +- icarus: Ensure fpga_count is finalised before add_cgpu is called +- icarus: Move work_division autodetection code into new +icarus_probe_work_division function +- icarus: Remove ability to change fpga_count at runtime +- Bugfix: gen-version.sh: Replace bashism ("here string") +- gridseed: Support devices with more than 255 physical processors +- Use `git describe` to generate version.h to avoid user confusion over builds +from git +- zeusminer: Support devices with more than 255 physical processors +- hashfast: Include chip/core address in RPC procdetails +- gridseed: Reduce traffic sending work to GridSeed devices +- gridseed: Bugfix: previous refactor (unpublished) changed logic +- gc3355: Refactor to remove SHA2 code specific to the 5-Chip GridSeed Orb +- lowl-vcom: Bugfix: do not attempt to open the USB devices when enumerating + + +BFGMiner Version 4.4.0 - July 7, 2014 + +- Update official Windows build compiler from GCC 4.7.3 to 4.7.4 +- lowl-vcom: Added support for auto scanning (-S auto) on Mac OS X +- rockminer: implement --device-protocol-dump for debugging +- README: Update for commandline options +- README: Update configure options +- Bugfix: bfg_gpio_setpin_output: Clear alt-function bits via INP_GPIO macro +- jingtian: Explicitly configure SPI device while opening +- jingtian: Toggle ASIC reset GPIO at startup +- aan: Set defaults as soon as a proc is initialised +- aan: Allow specifying clock as xHEXX for a raw PLL register config +- aan: Include current frequency in RPC status +- aan: Implement --set jtn:clock=MHz +- aan: Logic to calculate PLL configurations for a given frequency +- jingtian: Use SPI enable GPIO to disconnect SPI during chipselect changes +- aan: Set PLL to 850 MHz +- aan: Simplify register buffer +- jingtian: Decode extra temperature bytes in read_reg +- aan: Add a read_reg hook +- aan: Enable configuring nonce diff with (eg) --set jtn:diff=32 +- aan: Properly handle nonce_diff +- aan: Implement mining +- DevAPI: Some designs set the main thr tv_poll from secondary thrs, so check it +after the loop +- aan: aan_spi_parse_rx implies spi_clear_buf +- jingtian: Do detection asynchronously across all possible chipselects so they +complete in parallel +- aan: Refactor aan_spi_cmd a bit +- jingtian: Implement device protocol dump +- jingtian: Detection-only code for new driver +- lowl-spi: GPIO access functions +- lowl-spi: Move knc_spi_txrx to linux_spi_txrx +- SGW: Support for proxy-share difficulty preferences +- SSM: Propagate proxy-share difficulty changes to established connections +- SSM: Track stratum connections for each proxy user +- SSM: Track authorised users for each connection +- SSM: Initialise proxyshare difficulty from --set pxy:diff=N +- proxy: Accept --set pxy:diff=N to set preferred proxyshare difficulty +- proxy: Provide a place to store desired proxyshare difficulty on a +per-username basis, and copy it to SSM connections when authorising them +- SSM: Track proxy share difficulties +- Expose target_diff function and add pdiff_to_bdiff macro +- util: double_find_precision function to identify ideal precision for a fp +number +- work2d: Expose WORK2D_MAX_DIVISIONS in header +- add_local_gbt: Avoid adding servers already configured +- Bugfix: Avoid writing automatically configured local GBT servers to the config +file unless they have been manually enabled +- add_local_gbt: Use rpcconnect when configured +- rockminer: Bugfix: must specify a baud rate (maximum of 115200) to get a read +response +- Bugfix: Use atexit() to ensure a final \n is always printed at exit to work +cleanly with new logging design +- Restore compatibility with old versions of libblkmaker +- Bugfix: probe for ZeusMiner before probing for DualMiner +- Wait until coinbase-addr is needed again, before updating it following a block +change (always using getaccountaddress) +- Don't automatically use #getcbaddr for local bitcoind if the user provided +their own +- Bugfix: refresh_bitcoind_address: Check for NULL json (which is not JSON +"null") +- Bugfix: add_pool: If no current pool set, initialise it (otherwise pool +testing may start a longpoll thread which tries to access currentpool +uninitialised) +- devpath_to_devid: *nix: Reject anything that doesn't begin with a / + + +BFGMiner Version 4.3.0 - June 30, 2014 + +- Bugfix: zeusminer: Include config.h +- openwrt: Disable libusb via --without-libusb +- Avoid waiting for local bitcoind test if we have other pools defined already +- lowl-pci: Silence warning on big endian +- bitfury: Portability fixes, including big endian compatibility +- Bugfix: bifury: strtoll already implies native endian, no need to flip it +again +- bitforce: Additional sanity checks, including ensuring our final queued count +matches that seen by the device +- bitforce: Go back to ignoring race-triggered sanity check warnings for ZqX +- bitforce: Refactor FLB and queue flush sanity checks +- bitforce: Use binary FLB protocol for Monarch +- bitforce: Add bitforce_read function to deal with binary responses +- bitforce: Support for queue id based jobs +- Make work->device_id unsigned +- bitforce: Support device explicit "Scan Interval" to override hardcoded sleep +times +- bitforce: Allow queued_max to exceed BITFORCE_MAX_QUEUED_MAX iff the firmware +provides an explicit Queue Depth +- bitforce: Fix bitforce_chips_to_plan_for to work beyond 32 chips +- configure: Clean up zeusminer logic +- icarus: Use estimated hashes for hw errors (more accurate hashrate for devices +where hw error values vary significantly from hashes performed) +- zeusminer: Bugfix: calculate work_division based on chips and cores +- Replace swabn with bswap_32mult (matching swap32yes parameters and +performance) +- Bugfix: zeusminer: Correctly encode job header regardless of native endian +- zeusminer: support added for ZeusMiner scrypt ASICs +- icarus: refactoring: commenting ICARUS_INFO members +- icarus: Accept any power of two as a valid work_division +- icarus: option added for Icarus-based drivers to ignore the golden nonce +during probe +- util: is_power_of_two function +- Bugfix: Display proper statline R and HW error percents for values < 1 +- openwrt: Provide scrypt option +- Benchmark: Debuglog headers generated +- Bugfix: cpu: Fix scrypt CPU miner +- Bugfix: scrypt: Fix scrypt hash postprocessing for big endian +- Bugfix: scrypt: Correct endian handling in PBKDF2_SHA256_80_128 +- scrypt: Add unit test for scrypt_1024_1_1_256_sp +- scrypt: Add unit tests for PBKDF2_SHA256_80_128 and salsa20_8 +- Bugfix: Copy ALL the data with swap32to +- Automatically add pool configured from bitcoin.conf for failover only +- Add failover_only pool flag, to avoid using it regardless of strategy +- Accept --default-config option to search and load default configuration files, +even if user is specifying their own +- Use appdata_file_call to find BFGMiner config file(s) +- util: appdata_file_call and appdata_file_find_first functions +- ccan: Update to latest version (which includes floatval option support) +- Bugfix: Adapt quit function to new logging design +- Workaround GCC 4.6 initialisation bugs with BYTES_INIT +- Bugfix: Use int rather than ssize_t to type-match %d expectation +- Minor refactor of text-only mode: avoid wasting bottom line of console, and +save status lines as they are replaced by log items +- Bugfix: Wake up wait_lpcurrent if its conditions for returning may have +changed +- Defer determining --quit-summary default until it is needed, so hotplugged +devices affect it +- Bugfix: In benchmark mode, only remove the new pools after putting them in the +array, since the removal will try to remove it from the array +- Bugfix: Initialise struct pool in add_pool rather than halfway through startup +- URI parameter #getcbaddr to request coinbase address from bitcoind or +compatible servers +- pool_set_uri function +- util: bytes_eq and bytes_assimilate +- Replace struct _cbscript_t with bytes_t for simplicity +- Bugfix: Parse userpass option with strchr rather than strtok to avoid +usernameless passwords getting into the username field and being displayed +- Bugfix: Free old coinbase script before setting a new one +- util: upper_power_of_two_u32 function +- Avoid unnecessarily finding drivers in a loop +- lowl-pci: Never probe via -S *:all +- configure: Succeed even if the libblkmaker submodule is missing (only +--with-system-libblkmaker) +- rockminer: Reset task timeout when queuing work +- rockminer: When we detect a task failure, check if we ought to grab a new work +rather than resend +- rockminer: Add a time limit before resending work even outside of midtask +state +- Bugfix: rockminer: Keep count of requested jobs properly +- make-release: Include ccan LICENSE symlinks as symlinks even in ZIP +- make-release: Ensure ccan licenses get included in source +- Bugfix: make-release: Correctly avoid unused parts of ccan +- make-release: Do builds with the official source release, to test that it +works +- Bugfix: DevAPI: Make for_each_logical_proc work correctly +- Avoid double hashing of shares +- Create work_hash function to abstractly produce work->hash from work->data +regardless of algorithm used + + +BFGMiner Version 4.2.0 - June 11, 2014 + +- Upgraded Windows libmicrohttpd from 0.9.35 to 0.9.38_pre33603 +- SGW: Workaround BE Cube bugs with new libmicrohttpd by forcing HTTP 1.0 +response +- rockminer: Increase hw error count for problems +- rockminer: Autodetect with "R-BOX miner" or "RX-BOX miner" product strings +- rockminer: Support for seeing and setting clock frequency in Manage TUI +- rockminer: Include clock frequency in RPC processor status +- rockminer: Support for setting clock frequency +- rockminer: Workaround lost tasks by resending them +- rockminer: Support for temperature sensors +- rockminer: Debug messages +- Bugfix: rockminer: Initialise rockminer_chip_data +- Bugfix: rockminer: Ensure work actually exists before testing against it +- rockminer: Mine at 270 MHz +- rockminer: Implement mining (at 200 MHz) +- DevAPI: Move device_proc_by_id out of bifury driver, since it is generically +useful +- rockminer: Detection code for new driver +- bfg_socket wrapper to ensure sockets are close-on-exec +- set_cloexec_socket: Explicitly cast SOCKET to HANDLE + + +BFGMiner Version 4.1.0 - June 6, 2014 + +- Bugfix: Ensure variables are declared even without ADL support +- RPC: Include a list of config files loaded in "config" reply +- Bugfix: Save a linked list of config files loaded so output makes sense +(previously only the most recent config file was named, and errors were reported +inconsistently) +- README.RPC: Document Coinbase-Sig in config reply +- Bugfix: Safely handle pool status line when no pools are alive +- bitforce: Refactor bitforce_vcom_gets slightly to be more sane +- Bugfix: initiate_stratum: Ensure extranonce2 size is not negative (which could +lead to exploits later as too little memory gets allocated) +- Stratum: extract_sockaddr: Truncate overlong addresses rather than stack +overflow +- Stratum: tlsca parameter to require CA validation of TLS certificate +- Bugfix: Avoid setting tv_idle before testing pool (it will be set if the test +fails) +- restart_stratum: Make use of return_via +- return_via helper function family to assign a variable and goto +- Bugfix: restart_stratum: Release pool_test_lock on failure +- bfsb: Disable all banks before enabling the one we want, to avoid having two +enabled at the same time (eg, when switching from bank 3 to bank 2) +- Interpret present "tls" parameter to require TLS +- uri_get_param_bool2 returning a tristate +- Tests for uri_find_param +- Split uri_find_param out of uri_get_param_bool +- gridseed: Allow specifying an arbitrary number of chips with --set gsd:chips=X +- gridseed: added support for the 80-chip (two blades of 40 chips) G-Blade +Scrypt-only miner +- Bugfix: gridseed: use a signed integer so that returning -1 has defined +behavior +- RPC: Return integer difficulties without decimal places +- Bugfix: Zero pool "Works" +- Bugfix: Set any listening sockets to close-on-exec/non-inheritable to avoid +issues rebinding them on restart +- RPC: Explicitly shutdown communication on client sockets to avoid them being +held open by forked processes +- RPC: Clean up mcast socket with tidyup_socket +- RPC: Move socket tidyup code to its own function +- Bugfix: RPC: Use pthread_exit rather than returning from the RPC thread, to +ensure tidyup gets called +- Bugfix: bitforce: During initialisation, clear each XLink slave exactly once +only + + +BFGMiner Version 4.0.0 - May 26, 2014 + +- Update openwrt Makefile for xz source +- Update libblkmaker to 0.4.0 +- Workaround Homebrew-induced segfault during device scan +- Allow hotplug with scrypt +- Bugfix: test_domain_funcs: printf precisions must be int, not size_t +- littlefury: Cleanup to make avoiding memory leak easier +- Bugfix: Avoid using an enum type to hold a bitfield +- ruby extension is "rb" not "py" +- README.RPC: Document api-example.rb +- Add Ruby Api Example +- hashfast: Check devices with Product matching "GoldenNonce" so we have a +vendor-neutral way to detect them +- Reduce set_device-not-implemented message to debug log level, since it can +occur for init-only settings +- Use a mutex to block pool_active on a common check per pool at any given time +- Use cURL return code to check if cURL sockets hit CURLE_AGAIN +- Abstract pool_recently_got_work into a dedicated function +- AUTHORS: Dmitry Smirnov contributes BFGMiner packaging to Debian +- README: Talk about more GUIs and mining OSs +- icarus: Minor optimisation (swap byte order in 32-bit always-aligned groups, +and skip pointless memory copy) +- icarus: Initialise ob_bin to avoid leaking other memory to device +- Bugfix: bitfury: Set stat_elapsed_secs early, just in case we jump with goto +- Bugfix: Report actual kernel name in RPC, rather than kernel interface name +- README.scrypt: Document psw kernel +- opencl: Another optimised scrypt kernel ("psw") +- README.scrypt: Document zuikkis kernel +- opencl: Optimised scrypt kernel ("zuikkis") +- Bugfix: Silence harmless warnings +- Bugfix: vcom_set_timeout: Return whether successful +- bitforce: Set name for ASIC devices +- Bugfix: Avoid unnecessary rescans due to wrong devtype +- bitforce: Support 28nm ChannelNN format for ZCX +- Bugfix: bitforce: Don't confuse channels with X-Link +- Bugfix: bitforce: Set VCOM timeout to 1 second for ZGX request, since it +sometimes lacks a newline +- lowl-vcom: vcom_set_timeout function +- bitfury: Eventually (after 30 seconds) give up trying to detect chip +generation and just assume gen1 +- bitfury: Use other nonces for gen1 detection so one bad core can't break it +- Bugfix: bitfury: Account for necessary nonce fudging during chipgen detection +- gridseed: Switch from the Queued miner loop to the Scanhash miner loop +Improves performance on Raspberry Pi Fixes inaccurate hashrate estimates Fixes +bug overwriting work inadvertently +- If the current pool lacks its own block change detection, keep the pool used +for that connected +- pool_active_lp_pool function to complement select_longpoll_pool +- Track which pools have active longpoll connections +- Avoid retrying longpoll requests for removed pools (and possibly change block +change notification source for existing ones) if longpoll connection gets +dropped +- util: Pass full json_rpc_call_state to upload_data_cb +- Remove now-unused variable +- nanofury: Update enable/disable/reinit to cleanly handle multichip devices +- bifury: Default max_queued to chips * 5 + 6 so it is back up to the original +16 for bi*fury (which seems to need it sometimes) +- bifury: Default max_queued to chips * 5 for extra breathing room (avoids +occasional issues with Hex*Fury) +- README.ASIC: Document workarounds for OSM/Hex*Fury firmware bugs +- bifury: Measure hashes done by nonces found since we cannot tell what +generation chip is in use +- bifury: Default max_queued to chips * 4 +- bifury: chips init setting to workaround buggy hardware which reports wrong +chip count +- bifury: free_after_job setting to workaround buggy hardware which ignores +maxroll +- bfg_strtobool helper function +- bifury: Enable runtime modification of max_queued +- bifury: Migrate to set_device_funcs interface +- Stratum: Accept a "notls" parameter on pool URIs to disable opportunistic TLS +- uri_get_param_bool helper function for pool parameters +- nanofury: Only ramp up osc6_bits on multichip devices +- Bugfix: nanofury: Move the bitfury pointer back to the last element before +starting the ramp up loop +- Bugfix: Use pdiff 1/0x10000 for scrypt benchmarking +- benchmark: Use sane bits (of a very high difficulty to avoid triggering +anti-reorg protections) +- Ignore work difficulty minisculely harder (ie, rounding error) than what +device supports +- Benchmark: Add 2D work support +- SSM: Use a lower share difficulty in scrypt mode +- Rework test_nonce to share common logic for scrypt and SHA256d +- work2d: Accept nonce difficulty with submissions +- configure: Make work2d building abstract from libevent +- work2d: Standardised way to pad extranonce beyond what work2d manages +- Abstract code from stratumsrv_mining_submit into new work2d_submit_nonce +function +- Avoid handling hex encoding in work2d +- Move/rename _ssm_gen_dummy_work to work2d_gen_dummy_work +- SSM: Refactor _ssm_gen_dummy_work to work with struct stratum_work instead of +struct stratumsrv_job +- Move "nonce1" session id from struct pool to struct stratum_work +- Add pool and work_restart_id to struct stratum_work so they can be used +independently of struct pool +- Move n2size from struct pool to struct stratum_work +- autogen.sh: Automate cleaning INSTALL out of libblkmaker so git updates +properly +- Update libblkmaker to 0.4.0 +- Replace drv_rolllimit with struct ntime_roll_limits +- util: Unpack and pack utility functions ([u]pk_u{8,16,32}{le,be}) +- GBT: Do not allow drivers to roll ntime +- GBT: Use libblkmaker 2D work to service SSM and potentially other 2D work +drivers +- Hide blktemplate_t behind bfg_tmpl_ref to abstract reference counter +- Add pool_has_usable_swork function +- SSM: Split stratum work division into 2D work manager ("work2d") +- bitforce: Avoid crashing when broken devices report more jobs flushed than +they had to flush +- nanofury: Gradually ramp up osc6_bits for NF6 design +- util: memrchr is not portable (GNU extension), so implement our own my_memrchr +- bitfury: Report correct hashrate for gen2 chips +- bitfury: Detect gen2 chips +- Stratum: If difficulty calculates out to 0.999 to 1, round it up to 1 to avoid +something SHA2 hardware cannot handle +- Stratum: If the pool target has changed since the job a work came from, check +any shares against the new target too in case it expects retroactive difficulty +adjustments +- Stratum: Interpret integer difficulty values as pdiff (or Ldiff, for scrypt) +to avoid losing shares on non-compliant servers +- Rework difficulty-to-target functions to error on the safe side, and +consistently work in pdiff or bdiff +- Simplify stratum to convert difficulty to target immediately +- Stratum: Attempt connection with unauthenticated TLS, with failover to raw TCP +- Stratum: Return to curl_easy_{send,recv} +- get_registered_domain: Return full IP for raw IP addresses, so they can at +least redirect to the same IP +- Reject redirection across different registered domain names (can be disabled +by appending #redirect to pool URI) +- util: match_domains function +- util: Add isCalpha, get_registered_domain, and extract_domain functions +- README: Update for gridseed 5-chip orb +- configure: Clean up gridseed logic to only build by default when scrypt is +enabled +- gridseed: Fix warnings +- gridseed: Added support for Scrypt hashing with 5-chip GridSeed devices +- dualminer: Only one debug message needed for all init options +- dualminer: Move opt_dual_mode to dualminer file +- gc3355: move scrypt_only_reset_cmd out of scrypt_only_reset +- dualminer: No need to reconfigure frequency every work +- dualminer: refactor gc3355 code for readability, maintainability and use with +other devices +- dualminer: Abstract dualminer_init_hashrate out of dualminer_init_firstrun +- dualminer: Initialise opt_pll_freq along with opt_sha2_units +- dualminer: Move opt_sha2_units initialisation to new dualminer_set_defaults +function +- dualminer: Remove unnecessary opt_sha2_number +- dualminer: Simplify teardown +- dualminer: No need to parse strings for SHA2 unit counts +- gc3355: Support for appending jobs with task id +- gc3355: increase delays to 20ms +- gc3355: use NULL for end-of-command terminator +- dualminer: comment what various things are for and/or do +- dualminer: Split gc3355_scrypt_prepare_work and gc3355_sha2_prepare_work out +of dualminer_job_prepare +- dualminer: Use cgsleep_ms rather than usleep +- gc3355: Remove unused opt_hubfans variable +- dualminer: rename various things to be clearer +- Use a common enum bfg_gpio_value for both lowl-vcom (cts, dtr, rts) and +mcp2210 +- README.RPC: Document quit/restart reply format change +- RPC: Provide a full status section for quit/restart commands +- RPC: Add "Miner" to version response to include software name along with +version +- Bugfix: Dereference udev monitor events when done with them +- opencl: Workaround false warning regarding Mesa version number parsing +- knc: use_dcdc setting that Nov batch users can use to disable DCDC usage +- configure: Include for _Static_assert check +- opencl: If kernel does not specify an interface in scrypt mode, assume it's +the scrypt interface +- opencl: Replace dated versioning with hash of source code +- opencl: Search all the same kernel paths when setting kernel +- opencl: Accept arbitrary kernel filenames, provided they specify a kernel +interface somewhere in the source file +- Bugfix: Explicitly pass precision and width as int type +- Make pool stability message use nicer English +- Failover pool switching back delay is now configurable. +- Expand extranonce2 size to 64-bit +- README.ASIC: KnCMiner: Suggest --disable-other-drivers and remove +no-optimisation CFLAGS +- configure: libusb is implied by lowl-usb, so no need to list it as an option +separately +- Silence warnings when built without various drivers +- DevAPI: Remove long deprecated serial_detect function family +- Bugfix: Turn spidevc into lowl-spi to fix building the knc driver without the +bitfury driver +- Avoid triggering unnecessary device rescans (such as with pre-lowlevel +drivers) +- Replace --no-client-reconnect with --no-pool-redirect which also disables +X-Stratum header redirects +- Partial: A new --no-client-reconnect command that disables the +'client.reconnect' function. +- ftdi: Rename files to lowl-ftdi.{c,h} to fit with naming convention +- bfx: New driver for BFx2 Bitfury USB stick miners +- ftdi: ft232h_mpsse_readwrite_all function to do both reading and writing +concurrently in MPSSE mode +- ftdi: ft232h_mpsse_set_axbus function +- ftdi: Support for ft232h MPSSE mode (currently only works with +ft232r_write_all) +- ftdi: Split most of ft232r_open into a ftdi_common_open function +- ftdi: Support for --device-protocol-dump +- ftdi: Scan for ft232h-based devices +- ftdi: Avoid neutering lowlevel_device_info when opening it +- ftdi: Accept const data in write functions +- ftdi: Use actual USB packet size for FTDI status removal +- ftdi: Make ftdi lowlevel code independent of x6500 driver +- dualminer: Workaround false compiler warning in gc3355_config_cpm +- Bugfix: --disable-other-drivers should not force libusb to be unused +- Bugfix: README: Alphabetise and categorise build configuration options (and +add missing ones) +- TUI: Use _wlogprint for pool proto to avoid compiler warning +- Bugfix: TUI: Fall back to RPC URI if sockaddr_url hasn't been extracted (such +as benchmark mode) +- Hide work update messages unless explicitly enabled with hidden +--verbose-work-updates flag +- TUI: Redesign pool info line to include share difficulties in multipool modes +and last explicity work update timestamp +- nanofury: Abstract both power gpios into a nanofury_power_enable function +- nanofury: Add NANOFURY_GP_PIN_PWR_EN0 (inverted PWR_EN) - support for power +management (hardware) optimizations +- Bugfix: nanofury: Set cgpu_data for all processors (eg, to avoid crashing in +nanofury_set_ledmode for non-first procs) +- Bugfix: nanofury: Use correct SPI port for baud setting +- proxy: "Report in" clients when their info is looked up by username +- opencl: Replace (and deprecate) --no-opencl-binaries option, with --set +opencl:binary=no +- opencl: Reenable OpenCL kernel binaries for Mesa OpenCL >= 10.1 +- gc3355: Replace frequency-setting hex blobs with logic +- README: Update for DualMiner +- make-release: Switch to xz for source releases +- Stratum: If a pool explicitly tells us it doesn't support get_transactions, no +need to wait for a timeout +- api - buffer size off by 1 for joined commands +- miner.php - define a default rigport (that can be changed) and don't require a +port number in the rigs array +- miner.php allow links for rig buttons in tables and allow using the 4th IP +octet if no rig name - default disabled for both +- Remove wrong goto +- Remove the unqueued work reference when we discard work from get queued as' +well. +- Wake the global work scheduler when we remove a work item from the unqueued +work pointer. +- Discard work that is stale in the get_queued() function, returning NULL +instead. +- Bugfix: dualminer: Declare support for both SHA256d and scrypt algorithms +- gc3355: Use lowl-vcom set_serial_dtr function +- lowl-vcom: Implement set_serial_dtr +- gc3355: Use lowl-vcom cts/rts functions +- lowl-vcom: Implement set_serial_rts for Windows +- lowl-vcom: set_serial_rts should return the new rts value, if anything +- Rename icarus-common.h to driver-icarus.h +- icarus: probe_timeout setting to control how long we wait before giving up on +probes +- icarus: Defer initial open until init +- Remove debugging garbage that snuck in +- configure: New --disable-other-drivers options for users who want to build +just select drivers +- Simplify _now_gettimeofday on Windows, working around weird WINE crash +- cpu: Fix and simplify benchmarking on Windows (removes hidden --bench-algo +option) +- Remove old bench_block.h, no longer needed +- Bugfix: cpu: Adapt benchmarking code to new benchmark work generator +- Report precise share difficulties below 1 +- Bugfix: lowlevel: Pretend drivers not matching the active algorithm don't +exist +- Bugfix: dualminer: Set min_nonce_diff before getting work +- Bugfix: gc3355: Use correct byte counts for hex2bin +- configure: Fix up dualminer logic +- dualminer: Support for mining both Scrypt and SHA2 using DualMiner GC3355 +thumb sticks +- miner: scan for low level devices even if --scrypt is specified by the user +(to detect Scrypt ASICs) +- icarus: output protocol information if the user specifies +--device-protocol-dump +- icarus: Support for driver-specified job command lengths +- icarus: Support for custom driver job start function +- icarus: Support for custom driver initialisation function +- icarus: Call icarus_job_prepare via driver job_prepare key so it can be +overridden +- icarus: generic support for devices that return little-endian nonces +- icarus: allow custom probes +- icarus: expose do_icarus_close +- RPC: Remove separate CPU and GPU counters from devs Msg +- RPC: Optimise find_index_by_cgpu +- Bugfix: RPC: Restore PGA index counting +- Accept decimal values for --shares, and clarify weighed nature of the value +- benchmark: Remove all real pools, and prevent adding them +- benchmark: Fake submission of "shares" +- benchmark: Roll data before nonce only +- Bugfix: configure: Report bitforce:pci instead of bitforce:uio +- bitforce: Workaround broken/old compilers by setting device_fd outside of +initialisation +- AUTHORS: Update email for Kano +- RPC: Add "MHS rolling" key to status mirroring "MHS %ds" +- minorfix: remove extra semicolon +- Drillbit: Revert needless commit 270c1d01f, thanks @luke-jr +- Drillbit: Add upper and lower bounds to "Eight boards have a multiple of 8 +ASICs" check +- Drillbit: Clarify use of device_data pointer to store capabilities/protocol +version temporarily +- Drillbit: Keep reading work for as long as the device returns results. +- Drillbit: Be strict about not accepting any boards with newer protocol +versions. Protocol version bumps are non-backwards-compatible. +- Drillbit: Add support for "protocol version 4", non-device-specific +configuration packet format +- README.RPC: Add link to Node.js RPC wrapper +- opencl: Get temperature and fan speed updates with get_stats interface rather +than abusing statline override interface +- Bugfix: Remove devtype variable from driver API +- opencl: Deprecate --auto-{fan,gpu} and --gpu-dyninterval options +- opencl: Infer autoengine mode when the clock setting receives a range +- opencl: Infer autofan mode when the fan setting receives a range +- Bugfix: opencl: Defer initial intensity assignment until init, so opt_scrypt +has a chance to be set +- opencl: Strip leading and trailing spaces from names +- trimmed_strdup helper function +- icarus: Replace hard-coded "Icarus" mentions +- opencl: Deprecate all dedicated commandline options for parameters accessible +via set_device +- opencl: Make current intensity, xintensity, and oclthreads available via RPC +- opencl: Redo Manage TUI detail line to use xintensity when more reasonable +- opencl: Support for setting oclthreads as intensity=xNNN (for NNN xintensity); +also allow setting d for an initial dynamic intensity +- opencl: Store oclthreads and only convert to/from intensity numbers when +dealing with external interfaces +- RPC: Deprecate all cpu* and gpu* commands, and remove CPU/GPU counts from +'devs' response +- RPC: pgarestart command to match {cpu,gpu}restart +- RPC: Unify common code under get_pga_cgpu function +- README.RPC: Deprecate gpu{intensity,mem,engine,fan,vddc} now that they can be +accessed via {pga,proc}set +- RPC: Consider CPU and OpenCL devices as "PGAs" to begin migration to a simpler +interface +- RPC: Turn gpu{intensity,mem,engine,fan,vddc} into wrappers around set_device +- opencl: Support configuration using set_device interface +- Bugfix: miner_thread: Don't call cgpu_set_defaults if it has already been +called +- Common add_set_device_option for automatically generated --set-device options +- Bugfix: opencl: Safely handle work->device_data across work copies and cleans +- set_device: Accept underscores for temp_{cutoff,target} +- opencl: Allow specifying a comma separated list for --gpu-threads +- opencl: _SET_INT_LIST2 to set variables not necessarily within +opencl_device_data +- hashfast: Enable setting device-wide clock at probe time using USB_INIT +- Bugfix: hashfast: Use signed type for manipulating raw temperature data, in +case it is below 0 C +- hashbusteravalon: Add udev rule +- klondike: Split up work and submissions among logical processors +- klondike: Make reply_wait_time a settable variable (configured lower for +hashbusteravalon) +- klondike: Explicitly enable slaves as well as the master +- hashbusteravalon: Klondike-based metadriver +- klondike: Pre-initialise klninfo separately from probe +- klondike: Allow setting max_work_count and max_work_time via set_device +- klondike: Variablise max_work_count and old_work_ms +- Move all OpenCL-specific data behind device_data pointers, and relocate +OpenCL-specific code out of miner.c +- opencl: Macro-ise code for list options +- Reduce failure applying set-device rules to debug loglevel +- Add --set as alias for --set-device +- Bugfix: miner.c: Correct ccan include +- Bugfix: Correct ccan-upstream directory include +- Load default config before commandline options, so the latter override the +former (but prioritise defaultconfig pools last) +- configure: Check for sys/termios.h used by ccan/opt +- make-release: Only include specific components of ccan +- Use git submodule for ccan (moving opt_*_floatval into miner.c) +- Probe erupter before icarus, since they are far more common now +- Accept --no-config option to inhibit loading default config file, even without +specifying another config +- Bugfix: RPC: Ensure isjoin always gets initialised +- bitforce: Remove two really-unused variables +- nanofury: Silence false warning from some compilers about uninitialised +variable use +- hashfast: Promote problematic write() replies to warning level +- hashfast: Log errno on write failures +- Extend maximum processor count to 17,576 (3 letters) +- DevAPI: Make processor lettering code more extensible +- Remove shorthand option for undocumented --bench-algo +- Remove long-deprecated and non-functional --enable-cpu option +- Deprecate shorthand options for uncommonly-used --algo, --cpu-threads, +--expiry, --gpu-threads, --intensity, --kernel-path, --kernel, --scan-time, +--vectors, and --worksize +- API-README correct new text format documentation +- API allow multiple commands/replies in one request +- Due to work restarts causing ~all processors to request work at once, it is +always ideal to stage at least mining_threads extra works +- scrypt: raise the maximum GPU intensity for scrypt mining to 31 - benefits +shown for AMD R9 290 models +- Bugfix: bitforce: ZNX/ZWX expect size minus 1 +- Bugfix: bitforce: Start building send_queue command at the real end +- Bugfix: bitforce: Defer opening until after devdata is initialised (since it +is now used to track open-ness) +- Document uio/vfio configure options as --without-* since they are enabled by +default when available +- Include list of lowlevels built in configure and --help output +- lowl-pci: Autodetect build-time support for UIO and/or VFIO during configure +- README.ASIC: Document how to use Monarch in a PCI-Express arrangement on Linux +- lowl-pci/vfio: Support pread/pwrite access to bars +- lowl-pci: Support for vfio +- Abstract UIO-specific code from bitforce driver into lowl-pci +- bitforce: Initialise lasttag based on response register +- bitforce: Tie in UIO with lowl-pci +- lowl-pci: New lowlevel driver for raw PCI devices +- util: bfg_slurp_file function to quickly read a file +- bitforce: Support for PCI interface via UIO +- bitforce: Hide vcom interfaces behind new struct bitforce_lowl_interface +- bitforce: Let the lowlevel interface deal only with the actual device +cgpu_info +- bitforce: Abstract most of VCOM layer away from driver code +- bitforce: Avoid checking fd by adding is_open flag +- bitforce: Replace BF{open,close} with more abstract bitforce_vcom_{open,close} +- bitforce: Abstract fd access mostly down to BFgets/BFwrite +- bitforce: Support for 28nm WX single-stage bulkqueue command +- bitforce: Use enum for style (FPGA vs SC) +- bitforce: Remove never-used and buggy "work queue" mode +- Round temperature to an integer in thermal cutoff warning +- Bugfix: icarus: Initialise read_count and other timing-related variables +- Change default log interval to 20 seconds +- hashfast: Bump default thermal cutoff temperature to 100 C +- Bugfix: DevAPI: Ensure temp-cutoff and temp-target are always supported +settings +- Bugfix: Initialise cutoff and target temperatures in allocate_cgpu if not +initialised by the driver +- Include temperature in thermal cutoff warning +- Avoid automatic rescans when hotplug is disabled +- nanofury: New "ledmode" RPC setting, to control LED behaviour +- nanofury: Support for changing baud rate +- nanofury: Detect number of chips, so multiple can be used +- bitfury: When detecting chips, oscillate slower and tolerate clocks outside of +a predefined range +- Default --quit-summary to devs if there are more than 24 processors +- Control printing of quit device summary with --quit-summary option +- bitfury: Migrate all drivers to set_device_funcs interface +- drv_set_defaults: Take devpath and serial params so matching by those can work +- avalon: Replace avalon-options with set_device_funcs +- klondike: Replace klondike-options with set_device_funcs +- Replace temp-cutoff and temp-target parameters with set-device options +- README.FPGA: Update documentation for Icarus driver +- icarus: Replace icarus-timing with set_device_funcs (including wrapper for +single icarus-timing case) +- icarus: Replace icarus-options with set_device_funcs (including wrapper for +single icarus-options case) +- drv_set_defaults2 function to work with set_device_funcs +- icarus: Clarify user_set flags with an enum +- icarus: Clarify reopen modes with an enum +- Accept parameter to set_device "help" as a request for help on a specific +setting +- set_device_funcs support for returning messages on success +- RPC: Support for alternate message strings +- bitfurce: Use new set_device_funcs interface +- Refactor set_device interface to use option arrays +- configure: Turn _Static_assert into a noop if the compiler lacks support +- Store when the last getwork was retrieved and display it in the API summary. +- bitforce: Consistently use fd -1 when device is not open +- hashfast: Support for voltage in RPC stats +- hashfast: Support for voltage displayed in ManageTUI +- hashfast: Support for temperature +- Trigger automatic rescans if an expected probe fails (assuming the device just +needs more time to initialise) +- Schedule rescan after a 1 second delay, should it be requested twice +- hotplug: Wait 100ms before rescanning, so plugging in a hub can be handled at +once and drivers have time to finish initialisation +- Linux hotplug: Ignore EAGAIN and EINTR from epoll_wait so debugging works +- Common hotplug_trigger function to use regardless of platform-specific +implementation +- Autoscan for new devices on Linux using libudev +- Autoscan for new devices on Windows when DBT_DEVNODES_CHANGED message is +broadcast +- Replace suffix_string with a wrapper around format_unit3 +- Skip lowlevel-based scans in scrypt mode +- README.GPU: Document new opencl autodetect behaviour +- opencl: Enable by default in scrypt mode + + +BFGMiner Version 3.10.1 - May 26, 2014 + +- Upgraded Windows libraries: +- - libcurl from 7.34.0 to 7.37.0 (and SSL support enabled) +- - libjansson from 2.4 to 2.6 +- - libmicrohttpd from 0.9.30 to 0.9.35 (now Win64 also) +- - libusb from libusbx 1.0.17 to 1.0.18 +- DevAPI: for_each_{managed,logical}_proc helper macros +- Update libblkmaker to 0.3.3 +- make-release: Copy submodules from local system +- make-release: Automatically determine DLL dependencies to include +- Bugfix: littlefury: Avoid memory leak for already-claimed devices +- Bugfix: drillbit: Avoid 9-byte memory leak for already-claimed devices +- Bugfix: lowl-ftdi: ft232r_close: Free device handle +- Bugfix: bitfury: Avoid memory leaks when detect fails +- Bugfix: klondike: Correct case of dname +- Bugfix: hashfast: Set LIFE_INIT2 so a dead engine doesn't hold up the stats +line +- Bugfix: bitforce: Restore device name loading for FPGA Singles +- Bugfix: Add config.h include to files missing it +- Bugfix: swap32to?e: Ensure conditionals always have the same type +- Bugfix: Protect prev_cancelstate variables under console lock +- opencl: Silence warning about duplicate const qualifier +- hashbuster: Avoid signed char problems in return status check +- Bugfix: bfg_claim_any: Use a mutex to avoid races around device claims +- SSM: Silence JSON parse error message for HTTP POST and TLS attempts +- bifury: Defer precision loss until after checking osc6_bits value +- opencl: bfg_clBuildProgram function to share common error handling (logging) +code +- opencl: Avoid printing empty build logs +- Bugfix: opencl: Free allocated memory when done with it +- Bugfix: Stratum: Use an error buffer on struct pool rather than the stack, so +it remains valid for the lifetime of the connection +- Bugfix: Reset tv_idle on pools after test failure +- Bugfix: Ignore last work time if pool is known to be down +- pick_unit: Avoid infinite loop when passed inf float +- Bugfix: bitfury: Correct comment about how much of the nonce range chips +process +- Bugfix: Initialise getq (and stgd_lock) earlier so it is ready in case startup +interactive pool-add tries to stage work +- bitfury: Wait for two low frequency measurements before acting on a freq drop +(in case of a single misread) +- Bugfix: SSM: decref parsed JSON when done with it +- knc: Replace numeric constants with KNC_CORES_PER_DIE, KNC_DIE_PER_CHIP, and +KNC_CORES_PER_CHIP defines +- Bugfix: knc: Actually skip over extra processors rather than infinite loop +- Bugfix: Use rlim_t type for old_soft_limit so comparison with RLIM_INFINITY is +correct on all platforms +- Update alloca logic to work on more platforms +- start-bfgminer.sh: Shell script to (re)start bfgminer in a background screen +session +- Bugfix: Handle disabled CPU support properly in various places +- Bugfix: README.ASIC: KnCMiner: Use supported Angstrom feeds only +- Bugfix: pool_active: Skip testing explicitly when we have a recent answer +- RPC: Use struct timeval for mcast bind timer +- Bugfix: Restore 2-minutes-past-last-work wait before terminating unused +stratum connections +- Partial: Bugfix: Turn spidevc into lowl-spi to fix building the knc driver +without the bitfury driver +- SSM: Silence JSON parse error message for HTTP attempts +- Bugfix: Use UTF-8 for micro prefix internally (and in logging) +- Consistently allocate space used for formatting numbers +- util: utf8_len and utf8_strlen functions to quickly measure a character or +string +- Bugfix: README: Add missing driver build configuration options +- Bugfix: renumber_cgpu: No need to copy dev_repr over itself (and trying to is +undefined) +- Move OpenCL kernel FAQ to README.GPU and clarify it a bit +- Bugfix: Log work updates for all active pools in multipool mode +- test_work_current: Cleanup +- Bugfix: Differentiate pool_actively_desired from pool_actively_in_use for +cnx_needed +- Abstract pool_actively_in_use to handle multipool checking for multiple uses +- Bugfix: antminer: Fix typo +- Bugfix: renumber_cgpu: Rebuild repr strings to match new information +- Bugfix: Skip final pool_active check in balancing modes (where pools switch +around often) +- Bugfix: Adjust quota GCD only after completely adding the pool, otherwise it +will be ignored by the adjustment +- Bugfix: opencl: Can only BFI_INT patch if using OpenCL binaries +- SGW: Support for scrypt +- README: Document VCOM low_latency flag and latency_timer sysfs attribute, +which can help run more VCOM-based devices on low-end USB hosts +- Add USB faqs. +- Bugfix: Stratum: Wait a bit for a response before assuming the pool is hiding +block contents +- README: FAQ about Raspberry Pi issues +- Check for when errno is set on windows as well as the windows variant for +errors. +- Partial: Handle interruptions to various select calls in util.c +- Bugfix: configure: Only fail due to not having libusb, if the user really +needs or wants libusb +- Bugfix: Update help display to replace (U)tility with (I)ncome +- Bugfix: Deduplicate % symbols in help display +- Bugfix: Correct documentation for --shares option +- cpu/scrypt: Fix last_nonce to be host endian also +- Bugfix: cpu: Correct results found by scrypt algorithm +- Bugfix: lowl-vcom: _get_osfhandle failure returns INVALID_HANDLE_VALUE, not +NULL +- Bugfix: lowl-vcom: Invalid fd checks should be for -1, not 0 +- Bugfix: SSM: Actually acquire and release extranonce1s +- Bugfix: C reserves identifiers beginning with an underscore and uppercase +letter or another underscore +- Skip trying to submit shares in benchmark mode +- Rework benchmark mode +- Bugfix: configure: Only pull in lowl-usb for lowl-vcom if libusb is available +- Bugfix: hashfast: Ensure size of hex data passed to applog is of type int +- README.ASIC: Update "SGW" virtual device identifier to current "PXY" +- Bugfix: klondike: Reenable hw error reporting on nonces found for unknown work +- Bugfix: Expand deprecated work->subid field to int width, needed by klondike +driver for tracking work +- Bugfix: erupter: Sapphire detected as Emerald and Emerald not detected +- configure: Remove duplicate sys/file.h check +- Bugfix: httpsrv: Add missing includes for stdarg, stddef, stdio, and stdlib +- hashbusterusb: Initialise send packets fully to avoid leaking uninitialised +data to devices +- Bugfix: Correct typo in --help ("AlgoritHms") +- Bugfix: twinfury: Avoid crashing when next_work is not populated here +- Bugfix: hashbusterusb: Close device after failures +- Bugfix: hashbuster: Close device after failures +- README: List --quota in options +- README.ASIC: Update documentation for Avalon +- Bugfix: Leave thr->*work alone when disabling non-minerloop_async devices +- udev rules: Set flag so ModemManager ignores devices +- bifury: Thermal overheat causes restart losing the clock, so resend it while +temperature is over 80 C +- bitforce: Explicitly assign indexes for bitforce_proto enum +- Bugfix: RPC: MSG_PGASETOK does not have a string param +- littlefury: Close device if there are any communication problems +- littlefury: Abstract out littlefury_set_power +- Bugfix: hashfast: Add missing serial_claim +- Bugfix: drillbit: Add missing serial_claim +- Bugfix: bifury: Add missing serial_claim +- Bugfix: littlefury: Add missing serial_claim +- Bugfix: Allocate all new devices completely, before trying to activate any +(since the first processor may control the secondary ones) +- Since scrypt miners tend to work at actual share difficulty, use that for +diff1 counting +- Bugfix: diff1 measurements should be increased by nonce difficulty, not share +difficulty +- drillbit: strtol into a long int so negative responses properly get an error +- Rename *nonces variables to *_diff1 to reflect their nature better +- Refactor diff1 records to properly weigh non-diff1 work +- AUTHORS: Add Nico Oelgart +- Fixed multiple XSS injection vectors +- drillbit: Expand allowed external clock range to 0-65535 + + +BFGMiner Version 3.10.0 - January 15, 2014 + +- Downgrade official Windows build compiler to GCC 4.7.3. +- Update official Win64 build mingw64-runtime from 3.0.0 to 3.1.0 +- Bugfix: Stratum: Accept JSON Number type for port number +- Bugfix: proxy: Set start timer when creating new virtual devices +- antminer: Add support for the Identify function - flashes LED 10 times +- drillbit: Expand allowed external clock range to 0-255 +- drillbit: Forbid setting external clock usage if not supported by device +- Check for DBC_TEMP capability before trying to read temperature +- Bugfix: drillbit: Reduce work message to correct size +- README: Update documentation for new udev rules and "video" group +- Bugfix: opencl/adl: Set iSpeedType for get-fanspeed requests, and ensure we +don't change do something weird with the fan when initially setting user-defined +speed flag. +- Bugfix: drillbit: Initialise rv variable +- Bugfix: Simplify adding "http://" prefix to avoid strncat overflow (length +excludes null byte) +- hashfast: Debuglog work flushing +- hashfast: Implement OP_NONCE search flag +- hashfast: Log seq numbers for nonces found +- hashfast: Count hashes done by nonces found, rather than no-pending-work +(which could be triggered by flushes) +- hashfast: Just keep a queue of the 32 most recent work items per core +- hashfast: Convert to minerloop_queue driver model +- hashfast: Gracefully complain if we are given an unknown chip or core address +- udev rule for hashfast devices +- hashfast: New driver using UMS protocol +- CRC-8-CCITT implementation +- AUTHORS: Add Lingchao Xu and move nwoolls up to antminer driver (and mention +TwinFury driver for Andreas) +- knc: Workaround false compiler warning about "uninitialised" vars +- Bugfix: drillbit: Access fd after potentially reopening +- Remove Christmas colouring +- drillbit: Add udev rule +- drillbit: Correct configure logic to check for generic bitfury code (needed to +decode nonces) +- drillbit: Implement some basic problem recovery +- drillbit: Support identify command +- drillbit: Read/write access to clock and voltage configuration from RPC and +ManageTUI +- drillbit: Store board configuration +- drillbit: Read temperature sensor +- drillbit: Check nonces against prev work +- drillbit: Implement mining +- drillbit: Only detection code +- antminer: Initial support for the Bitmain AntMiner U1 ASIC Includes support +for identifying the U1 separately from Icarus and Block Erupter Also includes +overclocking via --set-device antminer:clock=xHEX +- Extend horizontal lines to full screen width +- Log devid for USB string request failures +- Bugfix: segmentation fault if the terminal window is too narrow for the Help +and Quit items +- Accept "address" spelled out in --coinbase-addr option +- Bugfix: document the need to package zlib1.dll in the Windows build +instructions +- Bugfix: Stratum: Re-read pool sock var after suspend+restart +- Silence false uninitialised var use warning and calculate dev_runtime only +once +- Bugfix: HID API not properly detected on Mac OS X +- Adjust device list size as necessary when accessing options +- Avoid erasing the screen when statusy is not changing +- Abstract common set_statusy code out of change_logwinsize and check_winsizes +- TUI: Support pgup/pgdown for scrolling device list by page +- Bugfix: icarus: quirk_reopen is an int +- Bugfix: Do not allocate spi_port on the Stack, even to initialize - +EXC_BAD_ACCESS on OS X +- get_statline3: Simplify statistics gathering +- Bugfix: twinfury: Use serial number formatted over USB, so it works with +--scan +- twinfury: Only debuglog temperature debugging data when --device-protocol-dump +is enabled +- Bugfix: twinfury: Populate temperature info on both processors +- Option --weighed-stats to display A and R values weighed by difficulty +- README.GPU: Document always-disabled-by-default for OpenCL driver +- AUTHORS: Add Nate Woolls +- Extend menu to full width of window +- Abstract out spaces-to-eol to bfg_wspctoeol function +- Elaborate on spi_port+stack problem in comments +- Bugfix: Do not allocate spi_port on the Stack - EXC_BAD_ACCESS on OS X +- Bugfix: don't attempt to probe Bluetooth devices when scanning hardware +- x6500: Allow overriding the maximum frequency used by the dynclock logic Can +now use e.g. --set-device x6500:maxclock=210 Prevents spending time on +frequencies that only produce HW errors +- HACKING: Clearly document that dname must be lowercase and alphabetic +- bifury: Tolerate corruption in submit message, remapping shares to the first +processor if chip id is unrecognised +- bifury: Tolerate corruption in hwerror message +- bifury: Tolerate corruption in job message, and only count hashes done when +completing a known job +- Use a lowercase driver name to fix --scan pattern matching Otherwise the +following doesn't work: -S noauto -S twinfury:auto + + +BFGMiner Version 3.9.0 - December 25, 2013 + +- Update official Win32 build compiler and library: +- - Upgrade GCC from 4.8.1 to 4.8.2 +- - Upgrade libcurl from 7.28.1 to 7.34.0 +- Update official Win64 build compiler and library: +- - Upgrade GCC from 4.7.3 to 4.8.2 +- - Upgrade mingw64-runtime from 2.0.8 to 3.0.0 +- Green-on-red title colours for Christmas release +- write_config: Include http-port and stratum-port options +- Interpret F1 as a request for Help +- Bugfix: SSM: Free old _ssm_notify before replacing it +- Bugfix: SSM: Clean _ssm_cur_job_work as needed to avoid memory leaks +- Support matching --scan with lowlevel devid +- cgpu_match: Unit test for USB device path matching +- Bugfix: cgpu_match: Handle digits in dname (x6500) +- cgpu_match: More unit tests (dname with digit) +- cgpu_match: More unit tests (dname and case insensitivity) +- Display "NO DEVICES FOUND" line in place of device list, when there are none +- bitfury: Use drv_set_defaults to enable setting baud before probe +- bitfury: Split out SPI port configuration option ("baud") to its own function +- drv_set_defaults wrapper function around cgpu_set_defaults for use with +options that may need to be set during probe +- bitfury: Set poll interval to start iteration before responses are processed +- modminer: Check identification begins with "ModMiner" to avoid false detection +- Bugfix: hashbusterusb: Correct return value of hashbusterusb_vrm_unlock +- Support for installing a udev rules file for Linux +- twinfury: Remove unused variable to silence warning +- cgpu_request_control should be a noop when called from the main thread +- Bugfix: Handle errors creating a vcom devid more gracefully +- Bugfix: _wlog: Allocate enough space for complete copy of log line +- bfsb: Remove unused clock_gettime +- Bugfix: bfsb: Remove useless slot_on which was never properly initialised +- Bugfix: When QueryDosDevice fails, skip trying to parse its (undefined) +results +- hashbusterusb: Voltage should be in volts (not millivolts) for RPC +- hashbusterusb: Provide access to VRM stuff from RPC +- hashbusterusb: Use cgpu_request_control interface to safely access device from +outside main thread +- hashbusterusb: Include Voltage in RPC stats +- Bugfix: hashbusterusb: Ensure unlock code is always allocated, even if null +- hashbusterusb: Abstract code into hashbusterusb_vrm_lock +- hashbusterusb: Abstract code into hashbusterusb_vrm_unlock +- hashbusterusb: Abstract code into hashbusterusb_set_voltage +- Bugfix: hashbusterusb: Check for voltage change error correctly +- Abstract mutex_request code from X6500 driver into generic device API +interface +- hashbusterusb: Use standard identification behaviour +- hashbusterusb: Abstract hashbusterusb_set_colour function +- hashbusterusb: Get voltage with temperature +- hashbusterusb: Clean up unused variable warnings +- hashbusterusb: Use bitfury_wlogprint_status for osc6_bits displaying in Manage +TUI +- Bugfix: hashbusterusb: Remove ignored prompt for VRM lock +- hashbusterusb: Use Manage/osc6_bits code from main bitfury driver +- hashbusterusb: Provide access to VRM and identification in Manage TUI +- hashbusterusb: Shutdown PSU +- nanofury: Support identify function by turning off LED for 5 seconds +- nanofury: nanofury_state structure +- bitfury: Set poll interval to start iteration before responses are processed +- Twinfury: moved voltage reading to the thread init function +- Twinfury supply voltage initial reading: error log improved +- Twinfury: Reading supply voltage on startup +- Voltage scaling for twinfury implemented + + +BFGMiner Version 3.8.1 - December 9, 2013 + +- bfgminer-rpc: Catch error when server host fails to resolve to an IP +- RPC: Remove unnecessary delay from RPC server startup +- Call WSAStartup for our own needs independently of libcurl etc +- hashbusterusb: Give more meaningful errors before serial number is known +- hashbusterusb: Populate device_path with USB devid +- Rename hashbuster2 to hashbusterusb (only a-z allowed in driver names) +- Include libusb in options list, since it is no longer tied to specific drivers +- Make hashbuster serial number output match formatting on physical board +- Fix for hashbuster first init after power up +- Workaround Microsoft's non-standard swprintf +- vcom: Fabricate vcom devinfo for any existing paths specified to --scan, in +case enumeration fails +- Bugfix: hashbuster2: Check for errors setting up libusb handle +- Bugfix: Draw statuswin in line order to ensure overflow is cutoff properly +- Fixed one byte stack overflow in mcast recvfrom. +- Bugfix: Let libc do any translation for %lc before adding wide characters to +curses +- Specifically handle mining.get_transactions failures so they get logged at the +lower debug loglevel +- Bugfix: lowlevel: Use LL_DELETE2 when cleaning up secondary list + + +BFGMiner Version 3.8.0 - December 1, 2013 + +- Bugfix: lowl-usb.h: Add missing includes for stdbool/stdint +- hashbuster2: Retry writing request if no response received in 100ms +- lowl-usb: usb_ep_set_timeouts_ms function that behaves similar to termios +VTIME (timeout before begin of read/write) +- hashbuster2: Use new lowl_usb_endpoint for i/o +- lowl-usb: Add tools for more reliable read/write using bulk transfers +- Add bytes_extend_buf, bytes_preappend, bytes_postappend for reading direct to +a bytes_t +- New / updated instructions for building bfgminer on Windows +- configure: Adjust header-path discovery to work sanely with spaces and +backslashes in paths +- Bugfix: configure: More fixing BSD sed syntax for curses header search +- bitfury: Reinitialise chips if their frequency drops over 50% +- bfg_strerror: Trim C whitespace off the right of FormatMessage output, since +Windows can add \r\n +- Demote commonish errors to debug loglevel +- klondike: Add support for Avalon2-based designs +- klondike: Remove unnecessary limit of 999 on clock speed displayed in Manage +Device +- Bugfix: hashbuster2: Claim USB device internally +- Bugfix: hashbuster2: Do not try to use lowl-hid.h +- Bugfix: hashbuster2: Close device and free memory allocated, when no chips are +found +- Bugfix: hashbuster2: Remove libusb init and debug level setting +- Bugfix: hashbuster2: Avoid add_cgpu when no chips found +- Bugfix: klondike: Claim USB device internally +- Bugfix: devpath_to_devid: Check stat for error before allocating memory +- Bugfix: lowlevel: Free hash table data when done with it +- Bugfix: bifury: Free memory used by version reply +- bfgtls: Implement destructor to free memory when threads exit +- hashbuster2: Remove unnecessary libusb_detach_kernel_driver +- hashbuster2: Read unique serial number from device +- hashbuster2: Use hashbuster2_io for probe +- hashbuster2: Clean up warnings about unused variables +- README: Document --enable-opencl configure option +- README: Update for HashBuster Micro +- hashbuster2: Integrate into BFGMiner as a separate driver +- hashbuster2: Import driver for new protocol +- Bugfix: nanofury: Check if mcp2210_device exists before trying to power it off +- Bugfix: lowl-vcom: Check for error getting root hub path +- openwrt: Update package description +- configure: Add --without-libusb option to explicitly disable using it +- Bugfix: Pass newlines as ASCII (fixes lack of them in non-unicode builds) + + +BFGMiner Version 3.7.0 - November 27, 2013 + +- FTDI scan: Use intptr_t to avoid warning about different size type cast +- Bugfix: proxy: Add missing unistd.h include +- Bugfix: bifury: Precision specifications should be int, not size_t +- Bugfix: klondike: Include config.h first +- Bugfix: binloader: Include config.h first +- README.ASIC: Include support URI for bi*fury driver and firmware +- Added MultiMiner as an example of a GUI application that wraps bfgminer using +the RPC interface +- Silence non-issue warnings +- bifury: Add support for hwerror message +- inc_hw_errors2: Support reporting hw errors without a known nonce +- bifury: Initialise cutofftemp to 75 C +- bifury: Turn chips off and on when disabled and enabled +- bifury: Split out bifury_send_clock +- Bugfix: bifury: Avoid double-free and double-close on version parse errors +during probe +- bifury: Add support for clock command +- bifury: Update for "job" protocol change +- bifury: Update to current git +- bifury: Workaround bugs in older firmware by flooding device with work until +it proves it has needwork +- bifury: Attempt to submit shares even if maxroll limit is ignored +- Clone cgminer's submit_noffset_nonce interface +- Bugfix: bifury: Check that there is a line before comparing it to "version " +- bifury: Prune jobs older than 16 queued, to eventually clean up discarded work +(from flushes) +- Replace ucs2tochar* with ucs2_to_utf8* to handle Unicode +- README.ASIC: Document Bi*Fury firmware upgrade +- bifury: Free work when we know it's complete +- bifury: Implement hashrate reporting using "job" messages +- bifury: Tolerate other data before version reply +- bifury: Abstract line parsing into bifury_readln function +- Bugfix: bifury: Use a char array, rather than pointer to char array, for +bifury_init_cmds +- bifury: Unify SEND devprotodump logging code +- fpgautils: Skip SetCommConfig on Windows if baud is not to be set +- Check for U+2022 and replace it with "*" is unprintable +- Use replacement character for non-printable Unicode +- Use UTF-8 for Unicode +- Implement a utf8_decode function to produce wchar_t needed by curses +- bifury: New driver +- Bugfix: twinfury: Handle flash request for both chips, and avoid using proc +uninitialised +- Bugfix: twinfury: Fix various technicalities +- Bugfix: twinfury: Remove incorrect tcflush +- Twinfury communication protocol changed to be more robust. A preamble is sent +before the actual command. +- LED flashing changed: - setting a flag and flash the LED during the poll +cycle - mutex removed +- Renamed bf2 driver -> twinfury driver bin2hex utility used to convert the +serial number +- BF2 driver comment edited +- BF2 - Twin Bitfury USB miner driver added +- Deprecate --ndevs|-n (redundant with -d? and GPU-only) +- Never abort startup just because we have no devices (there may be cases this +is pointless, but at least it's consistent) +- cgpu_match: Accept ranges for letter processor specification +- cgpu_match: Accept ranges for numeric elements +- test_cgpu_match: Test with more than one device/processor +- configure: Condense configuration options summary a bit +- configure: Put configuration options summary back after everything completes +- Workaround bug in MinGW-w64: Check for strtok_r to be defined at compile-time, +and don't override it unless we really want to override +- Bugfix: configure: Use new need_lowl_vcom instead of need_fpgautils +- configure: Explicitly check for sleep +- Bugfix: Set LIBUSB_LIBS for non-pkgconf non-header-subdir libusb installations +- Move unused winsock2.h includes to the end of config.h +- Use lround instead of llround, since it has better compatibility with older +MingW and Cygwin versions +- lowl-hid: Save and use hid_enumerate results from library test +- Silence Windows build warnings +- mcp2210: Remove cruft leftover from HID code (moved out) +- lowl-vcom: sysfs scan: Simplify maybe_strdup into _sysfs_do_read +- lowl-vcom: sysfs scan: Don't bother getting product string until we confirm it +is in fact a tty device +- input_pool: Accept a null password +- Bugfix: Move const data into the scope it needs to be in +- Bugfix: Restore case insensitivity to --scan driver names +- Accept "@" separator for serial/path in --scan to match --device and +--set-device better +- README: Uppercase the sequence letter when talking about multiple pools +- README: Mention "make install" and clarify saving settings +- Bugfix: avalon: Don't "probe" with -S +- bitforce: Add lowl_* to bitforce_queue so it can be specified by name as a +driver +- Bugfix: devpath_to_devid: Be strict about COM port specifications on Windows +- Bugfix: avalon: Don't "probe" with -S all +- Bugfix: Only count devices in -d? +- RPC: {dev,proc}details: Add 'Processors', 'Manufacturer', 'Product', +'Serial', 'Target Temperature', 'Cutoff Temperature' +- debian: Need to explicitly add opencl support to build. +- Correctly document klondike as being enabled by default +- Simplify logic for README.ASIC and README.FPGA install +- Split fpgautils into lowl-vcom and binloader, and fix internal build +dependencies +- Add README.CPU to "make install" distribution when built with CPU mining +support +- line 2913 added urlencode +- Bugfix: RPC: Release apisock on error in tidyup +- klondike - dont try to flush if not initialised +- Rename --scan-serial to --scan +- Bugfix: Handle invalid driver names cleanly +- Workaround libcurl bug to properly support HTTP proxies for stratum +- Bugfix: Write klondike options for klondike-options (not icarus options) +- README.OpenWrt: Change example repository to "latest", and document +alternatives +- mcp2210: Add support for --device-protocol-dump +- Bugfix: Initialise dynamic osc6_bits variables +- README: Fixed a few typos here and there and improved wording (Thanks +miningpenguin!) +- README: Moved CPU sections to README.CPU and elaborated more on it +- README*: Grammatical cleanups +- README.ASIC: More KnCMiner +- README.ASIC: Add section about KnCMiner +- Bugfix: opencl: Dynamic mode should disable threads for this device, not just +N after the first +- Bugfix: Make curses_input return NULL on a blank line, as most callers expect +- Duplicate (hidden) --userpass option before --pool-priority so it can be used +in config files +- Only probe VCOM devices on bare "all" scan-serial request +- Provide backports of uthash LL_{PREPEND,FOREACH{,_SAFE}}2 (only added in +1.9.7, not yet in major distros) +- Upgrade required uthash version to 1.9.4 for LL_CONCAT +- README: Update documentation for scan-serial +- README: Bitstreams no longer included with BFGMiner source +- README: Remove incomplete and unnecessary list of ASIC/FPGA devices +- write_config: Add scan-serial and set-device +- write_config: Update to make JSON Array of named parameters +- Remove support for comma-separated values in --device, and update +documentation +- lowlevel: Collapse multiple lowlevel drivers on the same devid to a secondary +linked list, and only spawn one thread to probe all lowlevels on a given devid +- Bugfix: vcom_devinfo_scan: Clean up hashtable when done +- README: Update cgminer driver FAQ with Windows-specific answer, now that we +have a workaround for *nix +- cpu/opencl: Always disable by default; removes deprecated -G option entirely +- vcom_lowl_probe_wrapper: Attempt to reattach detached USB devices +- Bugfix: erupter: Prioritise Emerald after Sapphire +- Bugfix: Allow "drv:auto" to override general "noauto" +- Bugfix: _probe_device_match: Fix inverted logic +- Bugfix: Don't try to call lowl_probe for drivers that don't support that +interface +- lowl-hid: Use usb devids for libusb-based hidapi devices +- Replace bfg_claim_hid with lowlevel_claim +- lowlevel: Generic claim interface for lowlevel info +- cgpu_match: Compare dev_t under paths +- Rework -d? output to display more useful information now that device ordering +is non-deterministic +- cgpu_match: Add support for matching by serial number or path +- Unit tests for cgpu_match +- Rework --device option to accept a pattern and JSON Array in config; removes +support for processor ranges +- Remove --remove-disabled option, as it conflicts with hotplug, per-processor +stuff, etc already +- Bugfix: Reimplement "noauto" flag +- Bugfix: Restore "-S foo" without driver name functionality +- Bugfix: scan-serial: Compare dev_t as well +- littlefury: Convert to lowl_probe +- hashbuster: Convert to lowl_probe +- avalon: Convert to lowl_probe +- cairnsmore/erupter/icarus: Convert to lowl_probe +- bigpic: Convert to lowl_probe +- ztex: Convert to lowl_probe +- x6500: Convert to lowl_probe +- nanofury: Convert to lowl_probe +- modminer: Convert to lowl_probe +- klondike: Convert to lowl_probe +- bitforce: Convert to lowl_probe +- fpgautils: Wrapper to easily adapt an old detectone to new lowl_probe +- lowlevel: Add match variants of detect functions +- DevAPI: add_cgpu: Use mutex to ensure thread safety +- Make detectone_meta_info thread-local +- New threaded device probe framework + + +BFGMiner Version 3.6.0 - November 12, 2013 + +- RPC: Bump to 2.2 for Works in POOLS +- Bugfix: klondike: Don't try to free off the stack +- configure: Update klondike checks for libusb +- klondike: Autodetect by VID/PID/Manufacturer, rather than too-short "K16" +Product search +- Remove accidentally added ASIC-README +- klondike: Remove noop identify function +- klondike: Replace deprecated statline with temperature and ManageTUI stuff +- --shares should be scaled to diff1 not absolute number of shares +- More README updates. +- Minor README updates. +- sha2 allow external access to some macros and the K array +- klondike: Fixed a math issue when reporting fan speed on the status line. +- Add a get and queue helper work function. +- Reset the work_restart bool after the scanwork loop in case the driver flushes +work synchronously. +- Get rid of the stage thread since all work can be asynchronously added now via +hash_push anyway. +- Fix for opt_worktime on big endian machines. +- Do get_work in fill_queue without holding other locks. +- Make hash_pop signal the work scheduler each time it waits on the conditional +that it should look for more work. +- Remove discarded work from quota used. +- Display works completed in summary and API data. +- Store how many work items are worked on per pool. +- Add the ability to add uint8 and uint16 entities to api data. +- klondike - initialise stat_lock +- klondike - better to unlock locks than to lock them twice :) +- Remove roundl check and define +- 'llround' is more suitable here than 'roundl' +- klondike - change options to clock and temptarget only +- klondike - fix another uninit dev warning +- klondike - downgrade 'late update' but add an idle detect - and correct error +levels +- klondike - fix isc uninit warning +- klondike - drop the device for hotplug if it's unresponsive +- klondike - single 'shutdown' and ensure it happens +- klondike remove SCNu8 - unsupported on windows +- klondike - fix uninitialised dev bug +- Don't attempt to disable curses or print a summary during an app restart to +prevent deadlocks. +- klondike - error condition handling +- Modify Makefile to only include opencl related code when configured in. +- Convert opencl to need to be explicitly enabled during build with +--enable-opencl +- Implement a cglock_destroy function. +- Implement a rwlock_destroy function. +- Implement a mutex_destroy function. +- Simplify queued hashtable by storing unqueued work separately in a single +pointer. +- Add cgminer compatibility macro for ms_tdiff +- klondike rewrite work control +- allow __work_complete() access +- miner.h allow devices to tv_stamp work +- klondike - can only calculate the nonce difference on or after the 2nd nonce +- klondike - correct/reverse min/max stats +- klondike: Remove unnecessary devlock +- klondike - use a link list queue rather than a circular buffer - and add +timing stats +- Klondike - increase circular read buffer size +- Klondike - extra zero value and range checking in temp conversion +- klondike - display MHz also +- klondike correct cvtKlnToC() temperature calculation +- klondike - correct 1st reply debug based on define +- klondike - debug dump structured replies +- klondike - avoid division by zero if maxcount is unexpectedly zero +- klondike store and report errorcount and noise +- klondike - fix chipstats api stats buffer overrun with 16 chips +- klondike add new nonecount only once +- klondike - report mh/s based on nonces found + put old estimate into API stats +- klondike use a memcpy +- klondike fix bracket tabs indenting +- klondike: Update code to current git +- Klondike update code to current git +- Add Klondike to README +- Add Klondike to README.ASIC +- Klondike to main directory +- Klondike consistent code spacing +- Klondike update driver code to current git +- klondike: update firmware for 16 chips, add dist files +- klondike: beta final 0.3.0 release +- klondike: updated firmware, IOC method +- klondike: prevent nonces when not state W +- klondike: added driver config option support +- klondike: fixes for 300 MHz, fix K1 parts list +- klondike: update driver, docs +- klondike: update firmware & utils +- klondike: updated cgminer driver for 3.3.1 +- klondike: update firmware and driver, create new cgminer fork +- update klondike driver +- klondike: add cgminer driver file as-is + + +BFGMiner Version 3.5.2 - November 12, 2013 + +- README.scrypt: Update to reflect current status of code (unmaintained); remove +Con's litecoin donation address (leaving his bitcoin one) since it is unknown if +he still accepts donations with litecoin +- Bugfix: minerloop_async: Check the correct _mt_disable_called flag +- bitforce: Allow ZCX response to override Manufacturer string +- Bugfix: RPC: Restore null termination on responses +- Bugfix: configure: We need DLOPEN_FLAGS for lowlevel hid too +- Add additional debug information to help track work through BFGMiner +- README: Update hidapi dependency for HashBuster +- Bugfix: bigpic: Convert device serial and nonces to host endian +- Bugfix: modminer: Ensure devices that fail probe are closed properly +- Bugfix: bitforce: Ensure devices that fail probe are closed properly +- Bugfix: littlefury: Ensure devices that fail probe are closed properly +- Bugfix: bigpic: Ensure devices that fail probe are closed properly +- nanofury: Attempt to be more resilient to problems + + +BFGMiner Version 3.5.1 - November 7, 2013 + +- Bugfix: make-release: Add README.GPU document +- Demote USB string fetch failure to LOG_DEBUG since it is rather common +- Bugfix: RPC: devscan shouldn't be available to read-only access +- Bugfix: bigpic: Ignore the bitfury chip's counter as best we can +- Bugfix: bigpic: Accept other delimiters in Bitfury BF1 product string in +autodetection +- Bugfix: Fix VCOM/fpgautils build check +- Bugfix: Only include VCOM code when VCOM/fpgautils support is being built +- Bugfix: Reimplement scan-serial "all" keyword +- Bugfix: bitforce detect: Close device after ZGX failure +- Bugfix: Define lowl_usb even if libusb support is omitted, since VCOM and HID +drivers check against it for warnings + + +BFGMiner Version 3.5.0 - November 6, 2013 + +- bigpic: Probe sooner than most drivers, but still after icarus/erupter +- cpu/opencl: Fix probe priorities to be last +- Bugfix: RPC: Correct per-device Work Utility to be per-minute instead of +per-second +- Bugfix: Fix Windows VCOM enumeration to work with new lowlevel code +- Bugfix: nanofury: Use maybe_strdup in case strings may be missing +- Bugfix: bitfury: Fix processor disable/enable for all bitfury-based devices +- hashbuster: Get temperature when available +- Bugfix: hashbuster: Use maybe_strdup where there might not be a string +- hid: Treat null-length strings as missing entirely +- hashbuster: Enable dynamic osc6_bits +- hashbuster: New driver +- Split a hid lowlevel out of mcp2210 +- ztex: Convert to use lowlevel usb enumerator +- A quick flag to allow drivers to convey the desire to rescan devices (from +lowlevel up) +- Lowlevel USB enumerator for libusb +- dname for lowlevel drivers +- Bugfix: lowlevel: Avoid null pointer dereference on devices that are missing +USB strings +- lowlevel: Add a userpointer to lowl_found_devinfo_func_t and use it for +serial_autodetect +- Rework VCOM autodetection to go through lowlevel interface, avoiding repeat +USB string fetching +- lowlevel: Keep track of the claimed devid and debuglog every found device +- ft232r: devinfo_scan: Don't skip claimed USB devices +- ft232r: Be more tolerant of USB open failure or missing strings +- RPC: Build most of CONFIG "Device Code" by iterating over registered driver +list +- drv_detect_all: Use priority-sorted list of registered drivers +- Build hash tables to find drivers by dname or name +- Build a linked list of registered drivers +- BFG_REGISTER_DRIVER macro to commonly pre-define device_drv structures +- Move have_libusb checks out of drv_detect_all +- Replace opt_nogpu with simple function that adds opencl:noauto to scan-serial +list +- opencl: Remove ancient gpu_threads variable, not really needed anymore +- Bugfix: Stop waiting for pool testing as soon as one is active +- bitfury: Clean up by making private functions static, and naming public ones +with [lib]bitfury_ prefix +- bitfury: Remove old (unused) driver code +- bitfury_gpio: Convert to using current bitfury driver code +- Bugfix: littlefury: Upgrade to use current bitfury driver (old one didn't work +with littlefury anymore anyway) +- Bugfix: test_work_current: Make hexstr buffer large enough for blkhashstr +later on (issuing old work msg) +- README: Document --enable-knc configure option +- README: Document --disable-nanofury configure option +- Windows autodetect: clear detectone meta info +- Check for Windows DDK headers, and where they are (and build without them if +unavailable) +- Windows SetupAPI-based detection for USB VCOM devices (tested with CP210x and +CDC) +- ucs2tochar{,_dup} functions to convert USB string descriptors to char* format +- bfg_strerror: Support for Windows system errors +- Introduce applogfail* macros +- Bugfix: scrypt: Add missing include stdbool.h +- Bugfix: Explicitly cast uses of be32toh to uint32_t +- Bugfix: Add missing includes of config.h, stdbool.h, and stdint.h +- lowlevel: Convey device manufacturer up to nanofury cgpus +- nanofury: Store device HID path for RPC +- lowlevel: Promote path to a normal element for devices to simplify things a +bit +- nanofury: Claim mcp2210/hid devices +- mcp2210: Implement claim on HID paths +- fpgautils: Use string identifiers for internal hardware claims +- ztex: Keep interface claimed as a lock +- Bugfix: mcp2210: Check for NULL hid device strings before trying to convert +them to ASCII +- FTDI autodetect: Enable populating USB product and serial number +- Bugfix: FTDI autodetect: Add missing parameter values and remove unused buffer +- Bugfix: bigpic: Don't active poll event without a poll function + + +BFGMiner Version 3.4.0 - October 26, 2013 + +- Bugfix: knc: Use separate DEV_RECOVER_DRV deven when doing automatic core +disable/re-enable, so user-initiated disables are left alone +- Document existing enum dev_enable usage +- Bugfix: knc: Only try to re-enable cores after we've actually asserted them as +disabled, otherwise we won't actually assert the enable either +- knc: Automatically disable and re-enable problematic cores +- AUTHORS: Add Dmitry Sorokin +- bitfury: Disable dynamic osc6_bits when manually setting a specific value +- bitfury_do_io: Make use of timer_elapsed +- bitfury: Only use dynamic osc6_bits with boards that support it explicitly +(BFSB and Metabank for now) +- bitfury: More debugging info for dynamic osc6_bits +- Bugfix: bitfury: Fix tv_stat to persist +- bitfury: Remove useless debugging +- bitfury: Simplify dynamic osc6_bits logic such that the range is defined in +one place +- bitfury: Remove unused skip_stat +- Bugfix: bitfury: Stick to tracking best_done per-chip, and never call +zero_stats (which is for users, not drivers) +- Bugfix: bitfury: Use proc_repr rather than incorrectly calculated chip_id +- Bugfix: bitfury: struct bitfury_device is already chip-specific +- bitfury: dynamic osc_6 bits +- bitfury: Improve frequency calculation - fixes occasional miscalculations as +well as makes it safer with multiple devices +- bitfury: Added frequency calculation +- tm_i2c: Corrected copyright +- Allow --set-device opt=val without a device specification to attempt setting +it on every device +- Bugfix: knc: Maintain queue_full for all cores, so they continue to queue work +even if the first is disabled +- bitfury: Allow setting osc6_bits up to 60 +- Bugfix: Set status to LIFE_DEAD2 when killing threads at shut off, to avoid +calling driver code +- Skip "testing stability" message at startup +- Try switching pools if for some reason we end up with only idle pools and have +ended up current_pool set to an idle one. +- Check a pool is stable for >5 mins before switching back to it. +- ManageTUI: Slash key performs processor selection by search +- nanofury: Populate dev_product and dev_serial +- mcp2210: Implement mcp2210_close +- Bugfix: mcp2210: hid_write needs a report id, especially on Windows +- mcp2210: Workaround some Windows snprintf not handling wide strings correctly +by simply copying character-per-character (only works for ASCII data) +- Bugfix: chroot: Check that chdir succeeds +- AUTHORS: Add pontus +- knc: Expose Voltage and DCDC Current to TUI Manage device +- knc: Expose Voltage and DCDC Current to RPC status +- knc: Store volt/current on knccore +- knc: Read voltage/current from DCDCs +- Bugfix: knc: Fix temperature readout of half-celcius +- Bugfix: Only define have_libusb if building with libusb support +- littlefury: Remove unused code +- bitfury: RPC procset: Ignore extra data (like newline) after numbers +- Add --set-device option to allow setting default procset commands +- README: Document hidapi dependency for NanoFury sticks +- AUTHORS: Include Vladimir Strinski for NanoFury code +- mcp2210: Set GPIO output mode atomically with their output values +- nanofury: Power off device when shutting down +- make-release: Include libhidapi-0.dll +- mcp2210: Port to Windows +- configure: Find hidapi.h for mcp2210 using pkg-config +- bitfury: Provide read/write access to osc6_bits from the Manage TUI +- nanofury: Reduce oscillator bits to 50 to stay within USB specs +- bitfury: If multiple integers differ after 4 tries, just go with the first so +we can start mining +- nanofury: Implement actual mining code +- nanofury: Turn off device after checkport +- nanofury: New driver; detect device +- mcp2210: Implement protocol required for NanoFury USB sticks +- mcp2210: Skeleton low-level driver for MCP2210 USB to SPI Master bridge +- ft232r: Use lowlevel interface for ft232r_open +- Abstract ft232r scan+probe interface into new generic lowlevel driver +interface +- configure: Error if knc driver is requested, but linux/i2c-dev.h is missing or +not from i2c-tools +- knc: Attempt to express core enable/disable to controller +- knc: Put knc_device on every processor device_data +- Refactor device disable/enable logic so that drv.thread_{disable,enable} +actually get called +- Bugfix: knc: Check that device actually has work queued, before trying to find +the most recent one +- knc: Read temperature sensors +- DevAPI: minerloop_queue: Run watchdog in device thread +- knc: Pass queue flush to device when its most recent job produces stale shares +- knc: Issue flush command at init +- Bugfix: knc: Perform le32toh on unknown-work nonces +- knc: Use independent device_id for works to enforce 15-bit size +- Bugfix: spi_emit_nop: Correct counter logic +- knc: Implement mining +- knc: Use FPGA i2c to identify present ASICs +- knc: Basic detection of boards on expected i2c buses +- DevAPI: generic_detect: Just use an enum for flags +- Use list of drivers/algos/options generated by configure in --help info +- miner.php correct sort gen field names largest to smallest +- api ... the code related to device elapsed +- api add device elapsed since hotplug devices Elapsed is less than cgminer Elapsed +- RPC: Include more info in per-device/processor status +- API add 'MHS %ds' to 'summary' +- Icarus remove unneeded opt_debug tests due to applog being a macro +- We should only yield once in cg_wunlock +- Provide a function to downgrade a cglock from a write lock to an intermediate +variant. +- Reset quotas on load balance for all pools at the same time to avoid running +out during selection and unintentionally dropping to fallback. +- Break out of select pool from a common point for appropriate debug messages +and to avoid further tests. +- Find the greatest common denominator in quotas and use the smallest number of +consecutive work items per pool in quota load balance mode to smooth hashrate +across pools with large quotas. Give excess quota to priority pool 0 instead of +pool 0. +- Add subdir-objects to automake options. +- Use the --failover-only flag to have special meaning in combination with +load-balance mode to distribute any unused quota back to pool 0 to maintain +ratios amongst other pools. +- Display quota and allow it to be modified via the pool menu. +- More README about quotas. +- Document quotas and new load-balance strategy. +- Add API commands and modify output to support pool quota displaying and +changing. +- Change message in status when using a balanced pool strategy to notify if +there's a stratum pool as well. +- Add quota support to configuration files. +- Rotate pools on all failures to set a pool in select_pool. +- Use quotas for load-balance pool strategy. +- Provide a mechanism for setting a pool quota to be used by load-balance. +- Change --socks-proxy option to default to SOCKS5 +- Cope with trailing slashes in stratum urls. +- Make extract_sockaddr set variables passed to it rather than pool struct +members. +- miner.php sort the mcast rigs so they are always in the same relative order +- miner.php allow sending the muticast message multiple times +- miner.php mcast ignore duplicate replies +- miner.php coding warning +- miner.php disable 'gen' by default +- miner.php allow formula generation of new fields +- miner.php add doctype +- miner.php remove incorrect echo +- miner.php optional error if not enough mcast rigs are found +- take_queued_work_bymidstate should use a write lock. +- API mcast add a description option with miner.php +- Skip dissecting opt->names in parse_config if it doesn't exist. +- ICA optional limit timing with short=N or long=N +- logging - applogsiz() for large messages +- Provide a funcion that looks up queued work by midstate and then removes it +from the device hash database. +- Wait until all pools are done testing before giving up, regardless of how long +they take to fail +- AUTHORS: Add Ricardo Iván Vieitez Parra and Paul Wouters +- Bugfix: Check that setgid succeeds +- When using --chroot, chdir to the new root +- Bugfix: Add missing drivers to --help list +- Bugfix: Zero stats: cgpu->diff_stale +- fpgautils: serial_close: Explicitly release advisory lock before closing, in +case fd has been inherited by a process forked by system() +- Use serial_close to pair with every serial_open +- Workaround bug in Plibc by resetting locale to "C" at startup +- Bugfix: bitfury: Check for necessity of linux/i2c.h so build succeeds with +i2c-tools's userspace linux/i2c-dev.h +- bitforce: Workaround bugs in current firmware for the Chili +- Bugfix: DevAPI: Reduce race-collision delay to 1ms so thread_shutdown actually +gets called before threads are killed forcefully +- Bugfix: configure: Use AC_SYS_LARGEFILE to ensure nonce/share log files can +safely grow bigger than 2 GB +- Bugfix: Correct argument type for --submit-threads option +- littlefury: Workaround Xcode bug initialising fields in anonymous unions +- Bugfix: write_config: Make intensity list writing more readable, and avoid +extraneous argument in dynamic intensity case +- DevAPI: Trigger mt_disable_start after init, if a device is disabled before +minerloop starts +- icarus: Skip sending new work if entering DEV_RECOVER* modes +- icarus: When disabling, close device fd and stop sending new work +- RPC: Use get_api_extra_device_status for full-device status, for devices with +only a single processor + + +BFGMiner Version 3.3.0 - October 11, 2013 + +- openwrt: Optional libevent support +- RPC: Add missing drivers to Device Code +- bigpic_process_results: Cleanup +- RPC: Use procs count for device summaries, rather than iterating over linked +list (which may span multiple devices) +- Bugfix: Use bfg_waddstr for cg_[mv]wprintw so special characters get +interpreted properly +- Bugfix: bitfury: Clear force_reinit flag after reinit +- Bugfix: Use base unit for zero, and only if all values are zero +- RPC: Always build pga* and proc* methods +- Bugfix: icarus: Check for valid fd before all usage +- Bugfix: Stratum initiate: Clear json var after freeing it, to avoid a +potential double-free if retry fails before new JSON is parsed +- Bugfix: Correct --log-file error message +- Cleanly fall back to other micro- prefix symbols if locale doesn't support the +preferred one(s) +- Bugfix: bfg_waddstr: Missing break after selecting degrees symbol +- Silence warning about (never really) uninitalised variable use in notifystatus +- RPC: Complete split between devs/pga* and proc* methods +- RPC: Internal restructuring to support device-wide view +- RPC: Remove devdetail method, and rework newer devdetails to use its code +- configure: Advise running ldconfig when detected and probably necessary +- configure: Simplify final information summary +- Bugfix: configure: Disable httpsrv/libevent if not available +- README: Mention free GPU mining dependencies +- Write config: Avoid writing default temperature settings +- bitforce: Set default cutoff temperature to 85C for SC-class devices +- When shutting down, don't wait for mining threads any longer after the 1 +second sleep +- bitfury: Silence warning about (never possible) uninitialised variable use +- bigpic: Handle write failures +- json_rpc_call_completed: Silence incorrect type cast warning +- icarus: Silence warning about (never really) uninitalised variable use in +icarus_scanhash +- fpgautils: Check for fgets error +- Silence warning about (never really) uninitalised variable use in +multi_format_unit +- ft232r: Silence warning about (never really) uninitalised variable use +- Silence unused result warnings for notifier_{read,wake} +- Log a warning if --cmd-* returns a non-zero exit code +- configure: Update bigpic driver dependency on bitfury code +- metabank: Initialise --temp-cutoff to 50C +- README.ASIC: Document special care needed for some bitfury-based miners +- Bugfix: bitfury: Correct results from RPC pgaset +- bitfury: Move Slot and fasync RPC info to details instead of status +- bitfury: Include chip fasync in RPC status +- bfsb: Split up processors among a separate device per board +- Bugfix: bitfury: Copy rxbufs to stack in case we need to do SPI communication +in the meantime +- bfsb: Merge bfsb_detect_chips into bfsb_autodetect (unchanged) +- bfsb/metabank: Allow pgaset to change osc6_bits and SPI baud rate +- bitfury: Fix code indentation +- bitfury: bitfury_init_oldbuf: Optimise during runtime +- metabank: Remove unused variables +- bitfury: Send a work with lots of nonces to help cold-started bitfurys fill a +static buffer +- Bugfix: configure: Show --enable-bfsb/metabank in help, since they are +disabled by default +- metabank: Reduce i2c banking to only when necessary +- bfsb: Only build spi_bfsb_select_bank if bfsb driver is being compiled +- bitfury: Reorganize polling to hit chips sequentially, so SPI traffic can be +minimised +- bitfury: spi_emit_data: Return address read data will be located at after txrx +- bitfury: After 8 bad nonces in a sample period, reinit immediately rather than +waiting for the remaining up-to-0x38 +- bitfury: Reinitialise chips if their active nonce stops changing +- bitfury: Recalibrate immediately when we know we need it +- bitfury: Reset chips if more than 8 hw errors are found in a 0x40 result +sample period +- bitfury: If previous nonce mismatch persists, try recalibrating oldbuf +- bfsb: Shutdown chip when disabling +- bfsb: Expose Clock Bits and Slot to RPC +- configure: Simplify dynclock necessity detection +- configure: Tie libudev usage to fpgautils +- configure: Simplify fpgautils necessity detection +- DevAPI: add_cgpu_slave for more elegant multi-device threads +- Use procs count for device summaries, rather than iterating over linked list +(which may span multiple devices) +- metabank: Split up processors among a separate device per board +- metabank: Merge metabank_detect_chips into metabank_autodetect (unchanged) +- Removed temperature output from metabank_api_extra_device_status(). +- Modified code to store temperature at cgpu->temp for metabank devices. +- bitfury: Added get_api_extra_device_status for 'devs' request in metabank +driver: Slot, Clock Bits, Temperature, Voltage. +- minerloop_async: Run watchdog code within actual device thread +- bitfury: Remove unused libbitfury_readHashData +- Bugfix: DevAPI: Don't call job_process_results when there was no previous job +- bigpic: Convert to async minerloop +- bitfury: Port to Windows +- bigpic: Use bitfury_fudge_nonce +- Use common bitfury_decnonce for all bitfury-based devices +- Rename bf1 driver to bigpic, as the same device has other brands too +- bf1: Clean up log messages +- bf1: Reduce loglevel of debug messages +- Bugfix: bf1: Add missing header to Makefile.am, and fix .dname/.name +- Bugfix: bf1: Fix warnings +- BF1 driver modified to work under Windows -> packing of structs isn't working +with Windows +- Corrected hash rate estimation for BF1. Only 756 out of 1024 nonces are +scanned. +- Cleaning up the bf1 driver code +- BF1 driver working +- Bitfury BF1 source files added +- bfsb: modified to use LukeJr:'s new code +- configure: Reorder output +- configure: Allow to build *fury drivers only +- bitfury: Turn commented debug stuff into #ifdef BITFURY_SENDHASHDATA_DEBUG +- bitfury: Implement queue_full to ensure all processors have a work ready +before scanwork +- bfsb: set api speed to 625khz +- initial support for bitfurystrikesback boards +- bitfury: LINE_LEN instead of 2048 +- bitfury: 4Mhz SPI by default +- bitfury: double SPI polling +- bitfury: +Strange Counter -printf Counter +- bitfury: tuning of parameters; fixed cycles calculation +- bitfury: Move clock increase from common code to metabank driver init +- bitfury: Add driver-bitfury.h for shared function declarations +- bitfury: Do debug logging of read data before rotation +- bitfury: Decode nonce array sooner to make debugging easier +- bitfury: Check that the previous nonce still matches, to detect response +corruption +- bitfury: Workaround corruption by looking for matches rather than changes +- bitfury: Rewrite using async minerloop (currently only setup on metabank +driver) +- bitfury: Fix memory issues +- littlefury: Turn off chips when exiting +- littlefury: Adapt to 16-bit payload size (protocol change) +- Bugfix: littlefury: Fix bitfury_do_packet +- bitfury: Report bad nonces properly +- bitfury: Unify common nonce fudging code +- Bugfix: bitfury: Chips only scan 0xbd000000 nonces per work +- bitfury: Fix logging to use applog +- bitfury: Split driver into bitfury_gpio (bare GPIO) and metabank (i2c banked +GPIO) +- littlefury: Use bitfury driver scanwork +- bitfury: Eliminate more static variables +- bitfury: Treat each chip as its own processor +- bitfury: Resolve devices[chip] only once per chip +- bitfury: Move second_run logic back to libbitfury +- bitfury: Loop over chips once during scanwork +- bitfury: Abstract hashes_done2 which keeps track of time deltas per thr on its +own +- littlefury: Need to set tv_morework +- bitfury: Abstract out payload_to_atrvec +- littlefury: Log read return value when unexpected +- bitfury: Eliminate non-const global variables +- littlefury: Safeguard on job switching +- Bugfix: littlefury: Keep reading until error, EOF, or buffer filled +- littlefury: Log devproto of incomplete reads +- Enable littlefury detection +- Bugfix: configure: Enable bitfury by default properly +- bitfury: Require explicit -S bitfury:auto to probe GPIO-based SPI +- bitfury: Move i2c slot handling to metabank-specific driver code +- littlefury: Initial driver for BitCentury's USB miner +- bitfury: Split actual chip detection into simple function +- Bugfix: bitfury: Fix driver "name" to be correct length +- bitfury: Abstract SPI interface +- Bugfix: bitfury: Fix more warnings +- Bugfix: bitfury: Fix warnings +- bitfury: Intercept and use applog for perror calls +- Bugfix: bitfury: Handle SPI init failure cleanly +- bitfury: major intermediate update +- bitfury: added chip series detection; multiple chip mining +- Bitfury ASIC initial support +- DynClk: Improve commented documentation +- Replace Utility with (expected) Income calculated by actual shares submitted +in 100% PPS value +- format_unit3: BTC formatting with 2 decimal place digits +- format_unit3: Support for nano- and pico- sizes +- format_unit3: Use an enum for float-precision parameter +- format_unit2: Support milli- and micro- unit prefixes +- opencl: Disable by default if other devices are found; to enable, use -S +opencl:auto +- write_config: Save request-diff option +- Stratum: Clear unused extranonce2 space +- Don't even show 'Attempting to restart' for devices that don't support it +- Workaround bug in PDCurses wresize +- Bugfix: Include config.h in sha2.c first +- make-release: Include libevent-2-0-5.dll in Windows packages +- README: Document dependency on libevent +- README: Document new --chroot-dir and --setuid options +- Bugfix: Use correct configure define for chroot +- Remove --disable-chroot build option: always compile --chroot-dir if supported +- Bugfix: Use correct configure define for pwd.h +- Improvements on code +- Update miner.c +- Added basic chroot support, added option to configure.ac. +- Updated miner.c +- Added basic chroot support +- Replace u-hashrate with nonce-based hashrate adjusted for rejects/stales +- SSM: Windows port +- SSM: Allow configuring stratum port via --stratum-port option and RPC +setconfig +- SSM: Implement mining.hashes_done extension +- Proxy: Catch invalid usernames and error +- SSM: Report hashes done based on share submissions +- SSM: Include current time in job ids to avoid false hardware errors due to job +id reuse +- SSM: If no notify is currently set, try to set it before refusing a subscribe +- SSM: Prune old jobs after expiry +- SSM: Use pool data read lock when subdividing notify +- SSM: Gracefully fail when upstream stratum notify cannot be subdivided +- SSM: Gracefully fail when upstream pool is not stratum (by closing subscribed +clients, and refusing to subscribe new ones) +- SSM: Properly fail cleanly when maximum clients are connected +- SSM: Clean up stratumsrv_job when pruning it +- SSM: Avoid responding to notifications, and give an error for unknown methods +- SSM: Propagate work updates to clients +- Mostly functional stratum proxy driver +- Stratum: Split actual work generation away from the current pool data +- Bugfix: Stratum: Dereference pool swork coinbase buffer inside data lock +- SGW: Split proxy code out from driver-getwork into driver-proxy +- Bugfix: miner.php: Check $dototal[$name] is set before comparing its value +- Bugfix: RPC: Use bad_nonces in Hardware% instead of generic hw_errors +- Bugfix: RPC: Handle LIFE_DEAD2 case +- Make failure to open sharelog or noncelog abort startup +- Nonce logging option --noncelog to simply store every nonce and its info +- Abstract --sharelog option parsing + + +BFGMiner Version 3.2.1 - September 19, 2013 + +- Only show long-poll message in pool summary if it's not using stratum. +- README.ASIC: Clarify syntax of --scan-serial usage for USB Erupters +- Bugfix: RPC: Defer allocation of apisock until after we check for --api-listen +- make-release: Only try to include libmicrohttpd if bfgminer.exe depends on it +- Bugfix: make-release: Include libplibc-1.dll if available +- SGW: For Windows builds, include winsock2.h instead of POSIX networking +headers +- configure: Display getwork proxy server support in summary +- Bugfix: SGW: Pass actual cgpu_info to prune_worklog_thread instead of silently +casting one from getwork_client +- Bugfix: Get total_staged with lock for TS stat, before getting console lock +- Bugfix: bitforce: Correct fanmode RPC help +- bitforce: Hide fan control when disabled in firmware +- Bugfix: bitforce: Correct fanspeed TUI setting +- Bugfix: logging: Allow up to 4 KB for log lines +- Bugfix: icarus: Ensure last2_work exists before trying to check nonces fit it +- README.OpenWrt: Include serialusb drivers +- README: Include OpenWrt serialusb driver package names +- Bugfix: Initialise notifier (as invalid) for no-thread devices (SGW) +- Bugfix: Free temporary kernel path copy when writing config file +- Bugfix: Put kernel path on the (main) stack after initialisation from +commandline/config, to avoid appending an argv or jansson string +- Bugfix: Always allow startup with curses enabled (since the user can use +Manage devices to add new ones, and display Ctrl-C for text-only quit help +- Bugfix: Ignore/reject libmicrohttpd before 0.9.5, which introduced symbols we +need +- README: Elaborate on format of BW +- Bugfix: Try to initialise libusb later, so any mutexes applog might need are +initialised +- Bugfix: Implicitly initialise timer_set_now when it is first called +- util: Eliminate unsafe const-removing casts +- configure: Cleanup CFLAGS/LDFLAGS display +- Show RT_LIBS in ./configure output. + + +BFGMiner Version 3.2.0 - August 29, 2013 +- cpu: sse2_64: Rename sha256_init to sha256_init_sse2 to avoid conflict with +new sha2.c +- httpsrv: Some older versions of libmicrohttpd need stdint.h included first +- make-release: Include libmicrohttpd-10.dll if it exists +- Fixes column alignment in decimal fields. Workaround for printf rounding up +when formatting decimals into limited width. +- New hidden --unittest option. No longer runs unit tests at startup by default, +for faster startup. Added unit test for width printing of decimal numbers. +- Bugfix: configure: More fixing BSD sed syntax for curses header search +- Bugfix: configure: More fixing BSD sed syntax for libusb header search +- README: Update solo mining docs +- erupter: Continue searching a job until the end, even if an earlier result is +found +- icarus: Do hwerror-triggered reopen before sending the next job the first +time, to avoid having to resend it later +- icarus: Avoid sending a new job if the nonce found was for one before the +current job anyway +- icarus: Double-buffer work to solve nonces found before work change takes +effect +- icarus: Abstract nonce processing +- Bugfix: icarus: Avoid trying to submit 0 on comms error +- icarus: Skip unnecessary nonce memcpy +- icarus: Make state->last_work a pointer and store it on the heap +- miner.php fix missing global +- Bugfix: erupter: After identify, skip starting work if next scanhash is +already decided to be a "first run" (eg, device errors) +- Bugfix: erupter: Fix identify following hw error +- Bugfix: icarus: Don't try to send work if device open failed +- Debug log when zeroing stats +- Upgrade libblkmaker to 0.3.2 +- Bugfix: GBT: Advertise coinbasevalue capability +- Bugfix: Always compile add_serial now that it's somewhat generic +- icarus: Avoid sending a new job if the nonce found was for one before the +current job anyway +- icarus: Double-buffer work to solve nonces found before work change takes +effect +- icarus: Abstract nonce processing +- Bugfix: icarus: Avoid trying to submit 0 on comms error +- icarus: Skip unnecessary nonce memcpy +- icarus: Make state->last_work a pointer and store it on the heap +- README.RPC: Remove usbstats mention +- README: Add FAQ regarding cgminer messing up drivers +- README.RPC: Fix miner name +- README.RPC: Correct to mention other supported devices for pgaidentify +- api.c fix mcast debug message bug +- README.RPC: break all lines at most 80 characters +- Update the API Multicast documentation +- miner.php implement API Multicast handling to automatically find your local +net miners +- Bugfix: RPC: Fix log format types in io_flush +- Set RT_LIBS correctly from autoconf detection +- Explicitly check for clock_nanosleep and only use it when available +- Further integrate cgsleep API into BFGMiner's timer system, so clock_nanosleep +is only used on platforms with CLOCK_MONOTONIC +- Convert cgtimer_t to struct timeval +- Bugfix: Fix BSD sed syntax for curses header search +- Bugfix: configure: Really fix BSD sed syntax for libusb header search +- README.RPC: Mention multicast detection +- README: Include --mcast-* options in usage +- Use ccan's standard char* set/show functions for --api-mcast-{addr,code} +- Bugfix: RPC: Use the same mcast code in reply, and log it correctly +- API mcast only reply to remote IP's that are allowed access +- Initial API Multicast response v0.1 to find cgminer APIs +- Check for cnx_needed on each loop through wait_lp_current. +- Return positive for cnx_needed when no_work is true. +- Add no_work bool to set when we are in an underrun situation +- Reorder support names alphabetically. +- We don't want to continue into the hash_pop function if the getq is frozen. +- Carve out the unused portions of sha2 implementation. +- Import Aaron D. Gifford's fast sha256 implementation. +- Use cloned work when finding avalon results since another thread can discard +the work item while it's in use. +- Provide a variant of find_work_bymidstate that returns a clone of the found +work. +- Use timespecs on windows as cgtimer_t to capitalise on the higher resolution +clock changes. +- Abstract out the conversion of system time to an lldiv_t in decimicroseconds. +- Use our own gettimeofday implementation on windows for it to be consistent +across ming builds and higher resolution. +- Provide cgtimer_sub helper functions. +- Provide cgtimer_to_ms helper functions. +- Rename cgsleep_prepare_r as cgtimer_time to get time in cgtimer_t format and +call cgsleep_prepare_r as a macro for cgtimer_time +- TimeBeginPeriod and TimeEndPeriod do not add significant overhead when run the +entire time for cgminer so avoid trying to maintain balanced numbers of them for +specific time calls to simplify code. +- Replace all references to the old n*sleep functions with the equivalent +cgsleep_*s replacements. +- timeGetTime uses huge resources on windows so revert to using timevals for its +implementation of cgtimer_t +- Quotient/remainder error in ms division. +- Provide cgtimer_to_timeval helper functions. +- Provide a timeval_to_cgtime helper function to reuse values. +- Simplify cgsleep code for windows by using a typedef for cgtimer_t that +resolves to clock resolution, using that internally. +- On windows use the higher accuracy timegettime function to really get 1ms +clock and timer accuracy. +- Fix missed endtimeperiod in overrun timer on windows. +- Make cgsleep_us_r take an int64_t for us. +- Make the cgsleep functions build on windows. +- Set high resolution timing on windows within the cgsleep functions. +- Provide reentrant versions of cgsleep functions to allow start time to be set +separately from the beginning of the actual sleep, allowing scheduling delays to +be counted in the sleep. +- Make the nmsleep and nusleep functions use the new cgsleep functions internally +till functions are migrated to the new cgsleep API. +- Add a ms_to_timespec helper function, and create a cgsleep_ms function that +uses absolute timers with clock_nanosleep to avoid overruns. +- Add rt lib linkage to enable use of clock_nanosleep functions with older +glibc. +- Add a timeraddspec helper function. +- Provide a us_to_timespec helper function. +- Provide a us_to_timeval helper function. +- Add helper functions to convert timespec to timeval and vice versa. +- Bugfix: SGW: Discard work from log only by expiry, so post-startup hardware +errors are truly only hardware errors +- bitforce: Make voltages available to RPC +- bitforce: Save voltages as array of longs internally +- Bugfix: Clear device bad nonces when zeroing stats +- cpu & opencl: Defer RUNONCE to actual autodetection, so they can be added once +after startup +- Bugfix: Avoid crash activating [M]anage devices with no currently defined +devices +- TUI: Support for adding new devices using the plus key from [M]anage devices +- Bugfix: Use add_serial function for scan_serial, so that "all" keyword works +correctly +- SGW: Add support for new X-Hashes-Done header to allow devices to more +accurately report their work +- SGW: Add X-Mining-Identifier header to inform devices what they are +represented by in BFGMiner +- SGW: Use JSON for 401 response; add Server HTTP header +- AUTHORS: Add contributor Josh Lehan +- Changed comparison constants to allow for floating-point rounding +- Install README.ASIC for Block Erupter related drivers as well as Avalon +- make-release: Windows users don't need README.Debian +- README.OpenWrt: Import from BFGMiner downloads +- Silence Windows warning about send data signedness +- Fix block info +- API/miner.php add some % fields +- Don't yield on grabbing the read lock variant of cglocks. +- util.c expand quit to show file/func/line +- We should be using a cg_wlock initially in generating stratum work before +downgrading the lock. +- Add the ability to downgrade a write variant of the cglocks. +- Yield after releasing a lock in case we are on a device with limited CPU +resources. +- Fix --scrypt being required before scrypt intensities on command line or not +working at all via config files. +- Limit intensity range according to whether scrypt is in use or not. +- Do not allow benchmark mode to be used with scrypt. +- miner.php format Best Share +- README.ASIC block erupter USB brief +- Check for negative wait time in socket_full. +- Adjust socket wait timeout in recv_line according to how long we've already +waited to avoid a 60 second wait dropping to 1 second due to a blocked socket. +- force type checking on curses +- logging - size check sprintf +- Only use length-counted variants of format_unit and percentf +- Implement snprintf-like versions of format_unit and percentf +- miner - size check all sprintf +- size check get_datestamp/get_timestamp and remove unused cgpu->init +- make all statline overflow safe +- Convert the decay_time function into one that truly creates an exponentially +decaying average over opt_log_interval. +- GPU fan rpm display 9999 when it overflows +- Change mode on python file. +- Only update hashmeter if we have done hashes or haven't updated longer than +the log interval, fixing a us/ms error. +- README.ASIC: Document usage with Block Erupter Blades +- README: Add mention of libmicrohttpd to dependencies +- SGW: Include hash1 in work +- SGW: Include application/json Content-Type header +- Fix build without libmicrohttpd +- Allow startup to proceed with no devices, as long as RPC or HTTP are listening +- SGW: Refuse to issue new work to disabled devices +- SGW: Respond with stale rejection if share is known to be immediately stale +- Expose HTTP getwork username in Manage TUI and devdetails RPC +- Add --cmd-idle notification command for REST/WAIT conditions +- bfgminer-rpc: Accept unlimited size replies +- api-example.py: Accept unlimited size replies +- RPC: Rewrite io_data to cleanly handle unlimited sized responses +- Configure options to build --without-libmicrohttpd support +- RPC: setconfig can now change http-port (enabling or disabling the http +service included) +- Embedded HTTP server to handle getwork-based mining devices +- inc_hw_errors2 function can handle a bad nonce without a known work +- Split up scan_serial function to enable internally adding ad-hoc cgpu +- Helper functions bfg_json_obj_string and share __json_array_string +- bytes_t: Add bytes_shift and bytes_nullterminate +- Fix configure help for --without-sensors +- README: Document --with-system-libblkmaker +- Bugfix: Use BSD-friendly sed syntax for libusb header search +- Bugfix: Handle bitstreams properly +- Bugfix: Skip search for addwstr since it breaks --with-curses=preference +- Bugfix: configure: Find correct curses include path without *-config +- README.FPGA: Further clarify ZTEX setup +- Display a friendly error directing to README.FPGA when bitstream cannot be +loaded +- Remove bitstreams from BFGMiner distribution entirely, and include pointers +where to find them in README.FPGA +- ztex: Use load_bitstream_bytes for .bin files +- fpgautils: load_bitstream_bytes support for Intel HEX format (.ihx) files +- Add missing 16-bit byteswap macros +- fpgautils: load_bitstream_bytes function to load a bitstream into a bytes_t +- bytes_t functions: bytes_init, bytes_append, bytes_reset +- Look for bitstreams in /usr/share/bitstreams +- Disable Unicode support by default (use --unicode to enable) +- make-release: Skip stripping debug info from Windows EXEs, for now +- Bugfix: Ensure work variable is assigned before checking its thr_id +- Bugfix: notifier_init (Windows): setsockopt needs an int for SO_REUSEADDR +- Bugfix: Avoid turning totals red just because a processor is idle +- Enable notifications for sick/dead with --cmd-sick and --cmd-dead options that +execute commands when the event occurs +- RPC: Add cpu enable/disable/restart +- windows-build: Update to use libpdcursesw.dll +- Ensure socket error messages are used for socket errors on Windows +- fpgautils: Attempt to use Linux advisory locks on serial devices +- Bugfix: README: --temp-cutoff sets the maximum temperature before cutoff, not +temperature that triggers cutoff +- Bugfix: Avoid incrementing dev_thermal_cutoff_count when just updating +timestamp on status +- Detect curses support for wide characters during configure +- configure: Check for more variants of curses library names +- Bugfix: ztex: Avoid trying to format non-libusb error with libusb error name +- Bugfix: Avoid trying to assign const use_unicode variable with --no-unicode +option +- Remove long-unused opt_time variable +- RPC: Avoid exposing Coinbase-Sig when it isn't supported +- Bugfix: Fix build with libblkmaker < 0.2 +- Attempt stratum mining.suggest_target before mining.subscribe, if +--request-diff is used +- Retry stratum if initiation fails for any reason after we have sent something +(assuming there is more older variants we can try) +- Bugfix: Restore delay for authorization on stratum mining.get_transactions +- Bugfix: Fix TUI-only build +- bitforce: Extend pgaset _cmd to variable-length commands +- Bugfix: Use red for total processor count +- bitforce: Undocumented _cmd1 pgaset for experimenting with firmware +- Bugfix: curses: use_default_colors() when possible +- Bugfix: Calculate scrolling range with new cursor lines +- Bugfix: Ensure use_unicode and have_unicode_degrees constants are defined for +curses-less builds +- Bugfix: Replace block_timeval with (time_t) block_time +- README: Update for --no-unicode option + + +BFGMiner Version 3.1.4 - August 2, 2013 +- Windows: Rebuild pdcurses with UTF-8 and wide character support +- Bugfix: Avoid using wide curses symbols/macros when USE_UNICODE is not defined +- Unicode: Use line drawing in TUI Help +- Use bfg_waddstr even with Unicode disabled, since it's needed for red +highlight +- Colour bad conditions in red +- Unicode: Cross-tee intersecting lines +- Unicode: Use WACS_VLINE for vertical lines +- Unicode: If degrees symbol is available, add it to temperatures +- Unicode: bfg_waddstr wrapper to handle non-ASCII characters, currently used +only by logging and statlines +- Unicode: Use WACS_HLINE for horizontal lines +- Add framework for using Unicode in TUI (can be disabled with --no-unicode) +- Avoid using potentially locale-dependent ctype functions in locale-independent +contexts +- Refactor temperature in TUI statlines to share code nicer +- Bugfix: avalon: Fix applog formatting +- Bugfix: Align totals columns in per-processor view +- Bugfix: Fix curses-less build +- configure: Workaround buggy autoconf versions +- Bugfix: erupter: Include headers in order necessary for Windows +- Bugfix: Reimplement get_intrange using strtol instead of sscanf (which is +broken on Windows) +- Bugfix: get_intrange: Check for extra garbage at the end, only after we know +we have an end-position +- Bugfix: Fix Enter key in TUI on Windows +- erupter: Split identify-handling logic into handle_identify function +- Bugfix: erupter: Ensure identify is handled during no-once or firstrun +- erupter: After identify, check if a work restart is needed immediately +- erupter: Implement identify function by pausing hashing for 3 seconds +- Bugfix: icarus: Remember firstrun state in case it gets changed for the next +run +- icarus: Move actual dynclock updates to icarus_job_start +- icarus: Split out icarus_job_prepare, and rename icarus_job_start +- Bugfix: ZeroStats: Reset column widths to 1 +- miner.php: Include max temperature in device totals line +- Bugfix: Stratum Fix debug logging of initial mining.subscribe command +- Bugfix: Call pool_set_opaque from work_decode, so block content hiding/ +providing messages work for getwork/GBT +- Split block contents hiding/providing notices out from stratum code +- Add test suite for get_intrange +- Bugfix: Check for error conditions in get_intrange to not have weird --device +behaviour when bad values are provided +- Bugfix: erupter: Take advantage of detectone_meta_info to handle Emerald +autodetection +- TUI Help describing the various status fields (contributed by midnightmagic) +- Bugfix: ManageTUI: Allow 'I' key to be used by devices not supporting identify +- Bugfix: Prefer Sapphire over Emerald for -S erupter:* +- Bugfix: Clear total_bad_nonces when zeroing statistics +- Bugfix: modminer: Since we are not searching iManuf string for needles, only +look for "ModMiner" +- Bugfix: sysfs autodetect: Recurse into tty/ subdirectory (necessary for +CDC/ACM ttys) +- sysfs autodetect: Split tty* directory search into new _sysfs_find_tty +function +- modminer: Reduce default clock to 190 MHz +- README: Update driver info to include Erupter driver +- README: FAQ about scrypt and difficulty +- Include count of working devices/processors in totals statline +- Format totals statline the same way as individual device/processor statlines +- Rearrange TUI a bit, including menu at the top (+1 log line) and hashrate +total closer to device summaries +- Bugfix: setup_stratum_curl: Need to release stratum lock on connection failure +too +- Bugfix: Avoid unnecessary locks inside curses_print_status, which is called +with the console lock held +- Bugfix: setup_stratum_curl: Hold stratum lock until connection completes, to +avoid potential races +- Bugfix: stratum_works: If stratum is already active, it works (avoid trying to +initialise it again) +- Replace hashrate_to_bufstr/ti_hashrate_bufstr with format_unit/ +multi_format_unit_array +- New multi_format_unit_array to fill multiple buffers instead of building a +delimited string +- multi_format_unit: Skip recounting length of fixed-length strings +- Shrink status line to fit in 80 columns +- Add network bandwidth rate to TUI +- New multi_format_unit variadic macro to handle formatting multiple numbers at +once +- format_unit: Option to choose 3-digit integer display vs 5-character floating- +point display +- Optimization: format_unit: Handle number first, to avoid having to restore +suffix later +- Generalise hashrate_pick_unit/hashrate_to_bufstr into pick_unit/format_unit +- Extend hashrate_pick_unit/hashrate_to_bufstr to handle sub-kilo units +- Split total_bytes_xfer to total_bytes_rcvd and total_bytes_sent +- Bugfix: _decode_udev_enc_dup: Allocate enough space for full string +- Bugfix: Never use waddstr for logwin, since it would bypass special newline +handling +- Bugfix: bitforce: Set kname on chip processors +- bitforce: Include voltages in Manage device TUI +- Defer newlines going to curses logwin, to avoid a useless blank line at the +bottom of the window +- Ensure printing to logwin always goes through _wlog +- Remove blank line above log window +- bitforce: Identify parallel queue protocol distinctly from mere bulk queue +- ManageTUI: Include kernel name, when available +- Stratum: Roll ntime as we generate work +- Stratum: Make swork.ntime native-endian +- Stratum: Treat ntime as uint32_t (as it should be), still always big endian +- Debuglog ManageTUI actions/responses +- ManageTUI: Add generic Identify support +- Bugfix: Move serial_detect* and open_bitstream to DevAPI code so CPU/OpenCL +can build properly without fpgautils +- Short-circuit logging sooner in quiet mode +- Write to both stderr and console within same console lock "session" +- Bugfix: Also hold the console lock when writing to stderr +- Use common console locking function for stdout in logging.c +- Move console lock and unlock functions (which also handle thread cancelstate) +to miner.h +- Bugfix: bitforce: Only try to clear queues of SC devices, since FPGA MR boards +interpret ZQX/ZOX differently +- Timer-based gettimeofday substitute for systems with poor time-of-day clocks +(Windows) +- Use clock_gettime(CLOCK_MONOTONIC) for timers when available +- Use QueryPerformanceCounter for timers on Windows +- Generic refactoring for timer_set_now +- Replace all remaining uses of gettimeofday for timers, with timer_set_now (aka +cgtime) +- Don't mix timers with timestamps (visual only) +- Always use struct timeval for timers, and don't mix timers with timestamps +(functional only) +- get_datestamp: Change timeval parameter to time_t, and implement +get_now_datestamp for common "current time" use case +- Use get_datestamp for (non-microsecond) log timestamps +- Bugfix: ztex: Allocate final processor names on the heap, so they survive when +the stack for ztex_prepare is gone +- Bugfix: ztex: Copy serial number to device "name" before cloning it for other +processors +- Bugfix: x6500: Use cgpu->temp directly since there is only one sensor per +processor +- Bugfix: Actually show the highest temperature, not just calculate it +- x6500: Allow changing clock speed from TUI Manage device +- x6500: Port pgaset clock from modminer driver at +66d2a3ab072fcdbc3c7ed41a97f265afa917bbee +- modminer: Allow changing clock speed from TUI Manage device +- bitforce: Flush job and result queues at startup to avoid unnecessary warnings +- x6500: Reduce default clock to 190 MHz +- Bugfix: fpgautils: Close libusb handle after copying USB strings +- use BSD sed syntax to generate iospeed_local.h + + +BFGMiner Version 3.1.3 - July 11, 2013 +- Bugfix: Reset staged_full flag when discarding (stale) popped work, or +increasing the queue minimum +- Bugfix: Only trigger staged work underrun if a mining thread was actually +waiting for it (and do so sooner, before it has the work made) +- bytes_cpy: avoid malloc and memcpy when size is zero +- fix infinite loop in bytes_cpy when size is zero +- Bugfix: Generate iospeeds_local.h based on termios.h defines, and only try to +use POSIX standard if that fails + + +BFGMiner Version 3.1.2 - July 8, 2013 +- When not compiling with optimizations, initialize unused nonce2 space to avoid +warnings from memory checking tools +- TUI Manage devices: Support PgUp/PgDn keys to skip over processors within the +same device +- Bugfix: bitforce: Prefer 2nd temperature if higher than 1st +- When displaying device summary statlines, use the highest temperature reported +by any processor +- Stratum: Fix nonce2 sizes greater than 4 and (on big-endian) smaller than 4 +- bitforce: Manage TUI: Display both temperatures (if two), and enable changing +fan speed +- opencl: Add fan speed to Manage device TUI now that it's been removed from +statline +- DevAPI: Remove old statline APIs entirely, and add new override_statline_temp +(used by modminer/x6500 for upload %) +- README: Update statlines +- TUI: Replace DevAPI statline_before with a predefined temperature column to +free up statline space +- Refactor and simplify bin2hex to speed up and avoid unnecessary heap use +- stratum: Refactor work generation to do hex2bin conversions once, rather than +every single header generated +- Implement bytes_t for generic binary data storage (including smart realloc- +based resize) +- Bugfix: fpgautils: Only try to change baud rate when requested +- x6500: Provide manuf/product/serial to cgpu interface +- ztex: Provide manuf/product/serial to cgpu interface +- erupter: Use baud 115200 by default +- List valid baud rates once in iospeeds.h and standardize conversions +- TUI: Display device manufacturer/product/serial in Manage device screen, when +available +- DevAPI: Store manufacturer/product/serial for each device +- fpgautils: detectone_meta_info to provide metainformation (manufacturer, +product, serial) on devices to detectone functions +- Bugfix: fpgautils: Close product string file from sysfs (autodetect) +- erupter: New icarus-based driver to handle autodetection of Block Erupter +devices +- Add --log-file option which redirects stderr to a file, but valid anywhere in +the commandline or config file +- Detect staged work underruns and increase queue to avoid them +- Rewrite hex2bin to perform much faster (reduces minirig CPU usage by more than +half!) +- README: Add condensed list of dependencies +- Enable "maintainer mode" by default +- Bugfix: opencl: TUI manage: "Change settings" must not be compiled in with +no-ADL builds +- Bugfix: Detect whether the linker accepts -zorigin before attempting to use it +- opencl: ADL: ADL_Adapter_ID_Get fails with newer drivers, so tolerate its +failure best we can +- opencl: Don't try to use BFI_INT patching with APP-SDK newer than 1084 +(Catalyst 13.1), since it doesn't work +- fpgautils: Elaborate that bitstream open failures are probably due to missing +bitstream package +- fpgautils: s/firmware/bitstream/ +- Bugfix: Cleanup handling of complete device/driver failure +- Deprecate -C (enable CPU) and -G (disable GPU) options, now that -S +drv:[no]auto can be used for the same purposes +- Bugfix: Since at least one of unix (or __APPLE__) or WIN32 is required by +util.h, make sure unix is defined if WIN32 is not +- Bugfix: Set ELF rpath for bundled libblkmaker to use $ORIGIN so it can be run +from other directories +- Bugfix: Cleanup needs to happen before printing the final quit message, or it +gets lost in TUI mode +- Bugfix: fpgautils: Initialize my_dev_t instances with null bytes, to ensure +random unused data cannot influence hash keys +- opencl: ManageTUI: Clear log cleanly for changing settings +- Remove "GPU management" TUI entirely +- opencl: Use new "Manage device" interface to do everything "GPU management" +used to be used for +- DevAPI: Add interface for drivers to define custom "Manage device" options +- DevAPI: New function called to display additional processor information for +"Manage devices" +- TUI: Add enable/disable commands to device management +- TUI: Implement beginnings of generic device management interface +- Bugfix: avalon: Fix LIFE_INIT2 setting +- Add LIFE_INIT2 status (safe to call functions, but not mining yet) for devices +that want to report initialization status in their statline +- Bugfix: modminer: Only program once for --force-dev-init +- Bugfix: x6500: Only program once for --force-dev-init +- fpgautils: Workaround and document Xcode clang bug +- Bugfix: avalon: Correctly claim serial port +- Bugfix: -S all: Mac OS X needs to probe /dev/cu.*, not just /dev/cu.usb* +- cpu & opencl: Refuse to detect more than once +- cpu & opencl: Respect scan-serial auto/noauto instructions +- ft232r & libztex: Skip probe of claimed devices +- fpgautils: Check for devices being claimed before calling detectone from autodetectors +- x6500 & ztex: Claim USB devices +- fpgautils: Implement bfg_claim_usb for claiming devices by USB bus number and +address +- fpgautils: Replace serial_claim with bfg_claim_serial using a more cleanly +extensible interface and implementation +- fpgautils: serial_claim: Include a bus enum in hash key +- Add serial port claiming logic to avalon, bitforce, and modminer drivers +- RPC: "devscan" command to probe for new devices +- New (internal) scan_serial function to probe for new devices at runtime +- Split out per-cgpu temperature configuration code to load_temp_config_cgpu +- DevAPI: Modify add_cgpu to use temporary devices_new array, so detection can +be done without touching live variables +- Move more cgpu initialization to allocate_cgpu +- Move devtype default assignment to allocate_cgpu +- Move cgpu startup routine to new start_cgpu function +- Move cgpu_info allocation to new allocate_cgpu function +- Move *.drv_detect calls to a new drv_detect_all function +- DevAPI: add_cgpu: There is no need to hold mutexes while creating devices +- Bugfix: cpu: Update device "kernel name" with auto-selected algorithm +- usbtest: Improve portability to at least 2.7 and 3.2 +- usbtest: Avoid messing up the display by escaping weird bytes via repr() +- usbtest: Skip last 2 optional parameters, since we use the defaults and they +are not in older versions of pyserial +- Bugfix: bitforce: ZOX limits results to 16 results per call, so repeat ZOX +until there are fewer +- Bugfix: Initialization for bfgtls needs to be done in each thread +- Bugfix: stratum: Be patient with stratum lines that come in slower than we can +process them +- Use bfg_strerror in locations previously just logging raw error numbers +- Bugfix: stratum: Log WSAGetLastError() for error number on recv failures on +Windows +- Use bfg_strerror where it is already needed (for thread-safety) +- New thread-safe bfg_strerror function to portably stringify error codes +- Bugfix: bitforce_queue: Initialize buf2 so errors don't cause the work queue +to flush +- TUI: Display percentage invalid of found nonces with hw errors +- Bugfix: modminer & x6500: Increment *->diff1 for all bad nonces +- percentf2 that takes t as precalculated total +- Keep track of bad nonces independently from generic hw errors +- inc_hw_errors: Resolve cgpu outside of mutex +- Use inc_hw_errors function at every site which increases hw_errors + + +BFGMiner Version 3.1.1 - June 22, 2013 +- stratum: Deliver exact socket-error within the debug error message +- Don't install docs for (compile-time) disabled functionality +- Bugfix: Handle make dependencies on subdirectory files properly +- Bugfix: Use EXTRA_*_DEPENDENCIES for Cygwin workaround, to fix program make +dependencies +- Support new overclocking speeds for avalon: 325, 350 and 375 +- Bugfix: logging: Since we are inlining snprintf, stdio.h is needed +- Bugfix: serial_autodetect_ftdi: Debuglog FTDI COM port mappings returned, fix +type of FT_HANDLE +- Bugfix: Allow starting non-libusb devices if libusb_init fails +- Bugfix: Add missing newline to libusb_init failure message +- Bugfix: opencl: Remove unnecessary casts from rot() macro, which created type +issues +- Bugfix: Remove unused variables +- Suspend stratum connections when we know they've failed and don't try to recv +data from them once the socket no longer exists. +- applog/quit fix GPU errors created +- logging remove extra added +- remove varargs from logging/quit/in general as much as possible +- compile unix code on Mac OS X fixes not finding the config file in $HOME +- Create a pool_localgen bool function for testing when a pool can generate work +locally. +- Use mining start time for device MH/U calculations +- Bugfix: Save start time for stats to correct "Elapsed" key on "stats" RPC +request +- modminer: tidy up free in device detect function +- bitforce: RPC pgaset fanmode 9 for auto fan control +- Bugfix: usbtest: Correct obvious typos +- Initial import of usbtest.py script +- Include microseconds in log output with new --log-microseconds option +- bitforce: Workaround chip ids not necessarily being in order by choosing +processor count based on expected chip ids rather than parallelization +- serial_autodetect_ftdi: Debuglog FTDI COM port mappings returned +- Bugfix: On stratum disconnect, clear stratum_active and stratum_notify +atomically along with sock +- Windows: Use backtrace.dll to print usable backtraces to stderr on crash +- Bugfix: bitforce: parallelized: Properly handle parallelized protocol with +only 1 chip +- Bugfix: bitforce: XLINK: Increment boardno when moving on to the next board +- bitforce: XLINK: Update to use actual length,xlinkid header order +- Bugfix: bitforce: XLINK: Avoid trying to send 0 bytes after each write +- Bugfix: opencl: Build fpgautils even if OpenCL is the only driver, now that it +uses it for kernel-finding +- Bugfix: Do not try to call get_stats or get_statline* if device is still +initializing +- Bugfix: opencl: Add missing include for fpgautils.h (needed for +open_bitstream) + + +BFGMiner Version 3.1.0 - June 13, 2013 +- Bugfix: openwrt: Expect fixed bitstream path for input +- Improve Makefile organization and fix "make install" +- icarus: Upgrade work division autodetection probe to be faster and also detect +8 core +- Calculate rejection percentage based on weighed shares, not absolute counts +- Count weighed discarded (stale) shares per cgpu +- Bugfix: Cleanly count discarded (stale) shares without overlapping +devices/sshare locks within clear_stratum_shares +- configure: Enable Avalon support by default now that it behaves reasonably +- avalon: Since detection is not really implemented, only probe devices when the +driver is specified to -S by name (eg, "avalon:/dev/ttyUSB0") +- Bugfix: bitforce_queue: Never try to reinitialize a slave processor +- Bugfix: bitforce_queue: Use work_list_del everywhere we remove from work_list +to ensure work gets freed properly when done +- Reduce HW error logging to debug level, so it doesn't clutter the TUI log by +default +- DevAPI: When a device has more than 26 processors, represent them as aa-zz +- bitforce: bitforce: Fix TUI display of slave processors on parallelized boards +- bitforce: Only display temperature in TUI for the first chip on parallelized +boards +- Bugfix: bitforce: Set temperature for all processors on the board +- Bugfix: bitforce_queue: Initialize proc->device_data to board data for +parallelized chip processors +- Bugfix: bitforce_queue: Defer nonce count check until after thiswork has been +identified (or handled as NULL) +- avalon: avalon_clear_readbuf can simply wait for a single read timeout on +Windows to avoid select +- avalon: Simplify avalon_get_result by using avalon_gets +- avalon: Go back to good old serial timeouts for gets, since select() is for +sockets (only, on Windows) +- Updated api.c to return the hashrate with 3 decimal places +- Change hashrate display to never display 3 fractional digits, because it looks +a bit ugly +- bitforce: Credit hashrate to the correct chip on parallelized devices +- Re-set work thr_id on share submissions, to ensure the result gets credited to +the correct device in case of shared job queues (as in BitForce long boards) +- bitforce: Turn parallelization into separate logical processors for more +details on each, including working with XLink +- bitforce_queue: Implement job sanity checks using new "ZqX" for devices using +parallelization +- bitforce_queue: Minimal support for parallelization +- Add --device-protocol-dump option to debuglog low-level bitforce protocol +details +- When shutting down, set work restart flag (and trigger notifier) to help +mining threads escape to their main minerloop (and check for shutdown) +- Document and check for uthash version 1.9.2+ +- Bugfix: Don't report failure for graceful mining thread shutdown +- Name devices in mining thread failures +- Warn about killing mining threads +- Bugfix: Wake up mining threads when asking them to shutdown +- Disable pthread cancel within curses locking +- Shorten the avalon statline to fit in the curses interface and show the lowest +speed fan cooling the asic devices. +- Change switch_compact function name to switch_logsize to be used for other +changes. +- Only adjust cursor positions with curses locked. +- devs display - fix GPU duplicate bug +- basic copyright statement in API.java +- Change the --device parameter parsing and configuration to accept ranges and +comma separated values. +- Modify scrypt kernel message. +- Check for pool_disabled in wait_lp_current +- Check for pool enabled in cnx_needed. +- Add README.ASIC to debian packaging and make-release +- Document avalon options in ASIC-README +- Create README.ASIC with basic summary of supported ASIC devices. +- Do avalon driver detection last as it will try to claim any similar device and +they are not reliably detected. +- Set the fanspeed to the nominal chosen for GPUs. +- Clamp initial GPU fanspeed to within user specified range. +- Avalon fan factor is already multiplied into the info values. +- Get rid of zeros which corrupt display. +- Logic fail on minimum fanspeed reporting. +- Provide a workaround for fan0 sensor not being used on avalon and pad fan RPM +with zeros. +- Add ambient temp and lowest fan RPM information to avalon statline. +- Display max temperature and fanspeed data for avalon. +- Set devices to disabled after they exit the hashing loops to prevent the +watchdog thread from trying to act on them. +- Scanhash functions perform driver shutdown so don't repeat it. +- Change the opencl shutdown sequence. +- Send the shutdown message to threads and do the thread shutdown functions +before more forcefully sending pthread_cancel to threads. +- Icarus report data direction with comms errors +- Execute driver shutdown sequence during kill_work. +- Provide an nusleep equivalent function to nmsleep. +- Set avalon_info to device data void struct. +- Make submit_nonce return a bool for whether it's a valid share or not. +- Do a non-blocking read of anything in the avalon buffer after opening the +device. +- Assign the avalon info data to the device_data in cgpu_info. +- Rename cgpu_data to use new device_data +- miner.h remove unused device_file and add device_data +- Must unlock curses as well in logwin_update. +- icarus report usb write error information +- Make mining threads report out during work submission. +- submit_work_async is no longer used directly by driver code. +- Create a logwin_update function which mandatorily updates the logwin and use +it when input is expected to prevent display refresh delays. +- All stratum calls to recv_line are serialised from the one place so there is +no need to use locking around recv(). +- Only allow the mining thread to be cancelled when it is not within driver +code, making for cleaner shutdown and allowing us to pthread_join the miner +threads on kill_work(). +- Implement pthread_testcancel replacement for BIONIC +- Attribute whatever stats we can get on untracked stratum shares based on +current pool diff. +- Downgrade OpenCL headers to 1.0, which work fine for our purposes and are more +compatible +- icarus: If work_division autodetect fails, just use the old default of 2 +- avalonhost-raminst script to help with installing to RAM on Avalon-host +routers +- Attempt to probe /dev/cu.usb* for fallback "-S all" +- openwrt: Download uthash dependency +- Bugfix: openwrt: Always build with libsensors support disabled +- configure: Check for uthash headers +- Bugfix: ztex: Only destroy libztex device after the last handle to it has been +released +- ztex: Remove libztex slave device interface, simply passing fpgaNum to +selectFpga +- Bugfix: cpu: Fix yasm and sse2 detection +- cpu: Check for SSE2 support independently from yasm +- Bugfix: cpu: Make sure to link libsse2cpuminer.a before x86_32/libx8632.a +- Bugfix: cpu: Only build libsse2cpuminer iff yasm is available and targetting +x86_32 +- Bugfix: Free work only after deleting it from list +- Remove embedded uthash.h and utlist.h from Makefile +- windows-build.txt: Update for system uthash +- Remove embedded uthash (and add dependency on system uthash) +- Replace elist.h with utlist.h +- Bugfix: Fix build with CPU mining and *without* yasm +- cpu: Be explicit about size of sha256_init address +- cpu: Add --algo fastauto (new default) to detect a usable algorithm without +taking over a minute +- cpu: Default to --algo auto +- cpu: Support all platform-applicable assembly algorithms, even if used CFLAGS +don't support them +- Ubuntu: Updated changelog, added scrypt support. +- cpu: Set fixed symbol names for stuff shared with assembly +- cpu: Create Mach-O asm binaries on Darwin-based systems +- Bugfix: cpu: Use COFF yasm binfmt on Cygwin +- Bugfix: cpu: Get correct nonce from data, where the CPU sub-drivers leave it +- Remove redundant "Reject ratio" in exit-time summary +- Apply "R+S(%)" formatting to long-form statistics +- Group stale shares in with rejects (but still distinctly counted) and make the +percentage be (reject+stale)/total +- Include rejected shares as a percentage +- Move Utility and Best Share to status line +- Remove LW from status line, since it is basically useless +- ztex: Clean up a lot of ugly casting +- Bugfix: Correctly avoid SIGPIPE on Mac +- Make set_work_target a function to set a specified char as target for use +elsewhere. +- Minor typo. +- Support more shares to be returned for scrypt mining. +- Set all stratum sockets to nonblocking to avoid trying to use MSG_DONTWAIT on +windows. +- Only use MSG_NOSIGNAL for !win32 since it doesn't exist on windows. +- Use MSG_NOSIGNAL on stratum send() +- Set TCP_NODELAY for !linux for raw sockets. +- Use TCP_NODELAY with raw sockets if !opt_delaynet +- Recheck select succeeds on EWOULDBLOCK for stratum. +- Don't use TCP_NODELAY if opt_delaynet is enabled with stratum. +- Fix warnings in avalon driver. +- correct applog typing +- Simplify the many lines passed as API data in the avalon driver now that the +API does not need persistent storage for the name. +- Duplicate the name string always in api_add_data_full to not need persistent +storage for names passed to it. +- Add extra matching work count data in API for Avalon with 4 modules. +- Clean up summary slightly better on exit. +- opencl: Disable using binary kernels on Apple by default +- Use sock_blocks in api.c +- Fix build and distdir. +- compile on win32 +- Update README.scrypt with improved hashrates for 7970. +- Use copy_time helper throughout miner.c +- Provide wrappers for commonly used timer routines with API stats. +- Use flip32 function instead of open coding it in gen_stratum_work. +- Move util.c exports to util.h +- Replace gettimeofday usage with cgtime +- Adopt gettimeofday wrapper from cgminer (cgtime) that is always called with tz +set to NULL and increases the resolution on windows. +- Add high resolution to nmsleep wrapper on windows. +- Bugfix: Export stats_lock for deviceapi +- Set default ocl work size for scrypt to 256. +- fliter out the wrong result from adjust fan code +- Set last device valid work on adding device. +- Make scrypt submission use the submit_nonce code, with nonces matching +endianness. +- Increment hardware error count from the one site. +- compile avalon driver on win32 and win64 +- build out of source dir +- Rename scrypt regenhash function for consistency. +- Add Mac FAQ. +- Further driver FAQs. +- Check for work restart after disable in the hash queued work loop since it may +be a long time before we re-enable a device. +- Unconditionally test for many wrong results on avalon and reset to avoid +passing a corrupt avalon result to temperature code. +- Only reset an avalon device with no results when there are no results +consecutively. +- More FAQs. +- Avoid applog in recalloc_sock. +- Avoid applog under cg_wlock. +- Put spacing around locking code for clarity. +- Avoid applog under pool_lock. +- Avoid more recursive locks. +- Avoid applog while ch_lock is held. +- Avoid recursive locks in fill_queue. +- Variable is already initialised in global scope. +- More GPU FAQs. +- More README faqs. +- Yet more README faqs. +- Add more FAQs to README. +- Wrap result wrong tests in avalon scanhash in unlikely() and only consider a +hash count of zero wrong if a restart wasn't issued. +- avalon: if result_wrong >= get_work_count jump out the read loop +- Fix warning on 32bit. +- fix the fan control on max temp2/3 +- for some reason network down. one simple bfgminer command: "bfgminer -o +127.0.0.1:8888 -O fa:ke --avalon-options 115200:32:10:50:256" can idle the +avalon for safe power and protect chip +- if hash_count == 0; reinit avalon, fix the 0MHS bug use the max value of temp1 +and temp2 for fan control +- Reinstate the matching_work_count per subdevice on avalon based on the work +subid. +- Rationalise and simplify the share diff and block solve detection to a common +site. +- subid field for devices that do not yet support the distinct device/processor +interface +- Make the avalon array size a macro. +- Use replacement of work items in the avalon buffer as needed instead of +flushing them. +- Reinstate wrong work count to reset avalon regardless and display number of +wrong results. +- select() on serial usb in avalon does not work properly with zero timeout. +- Use no timeout on further reads in avalon_gets +- Do sequential reads in avalon_get_reset to cope with partial reads. +- Show read discrepancy in avalon_get_reset. +- Reuse avalon_get_work_count variable. +- Check for AVA_GETS_RESTART when deciding if avalon has messed up. +- Make the detection of all wrong results on avalon much more conservative to +avoid false positives on work restarts. +- Show error codes on select and read fail in avalon. +- If we get a restart message in avalon_gets still check if there's a receive +message to parse first without a timeout before returning AVA_GETS_RESTART. +- avalon_gets is always called from the one call site so inline it. +- The read_count is unused by the avalon get result code and no longer required +for avalon reset so simplify code removing it. +- Use a separate avalon_get_reset function for resetting avalon instead of using +avalon_get_result. +- The current hash count returned by avalon scanhash is just an obfuscated +utility counter so make it explicit. +- Check for a restart before a timeout in message parsing code in avalon. +- We should check for a restart message before checking for a timeout in avalon +scanhash. +- Store the subid for the work item in avalon. +- Fix record_temp_fan function in avalon driver. +- Remove inappropriate memset of struct avalon result which was corrupting fan +values. +- Only do_avalon_close once on multiple errors. +- Reset the result_wrong count on block change in avalon scanhash to prevent +false positives for all nonces failed. +- Small timeouts on select() instead of instant timeout increase reliability of +socket reads and writes. +- Rotate the avalon work array and free work on AVA_SEND_BUFFER_EMPTY as well. +- Only get extra work in fill_queue if we don't have any unqueued work in the +list. +- Don't get any work if our queue is already full in avalon_fill. +- Free avalon->works in the event we call avalon_prepare on failure to +initialise. +- Fix warnings. +- Create an array of 4 lots of work for avalon and cycle through them. +- Remove unused per unit matching work count for avalon. +- Rename the confusing avalon_info pointer. +- Simplify avalon scanhash code using the new find_queued_work_bymidstate +function. +- Members of cgpu_info for avalon are not meant to be in the union. +- Use correct struct device_drv for avalon_drv. +- Check enough work is queued before queueing more in avalon_fill. +- Actually put the work in the avalon queue. +- Rename avalon_api to avalon_drv. +- First draft of port of avalon driver to new cgminer queued infrastructure. +- Minor README updates. +- README.GPU: Properly warn about overclocking damage +- Add example 7970 tuning for scrypt in readme. +- Update driver recommendations. +- Add extensive GPU FAQs for the flood of new Scrypt miners. +- Bugfix: Expect bitstreams and kernels to be in the srcdir, not build dir +- cpu: Prefer sse4_64 algorithm if supported +- cpu: sse2_32: Force bare symbols for cross-asm/C symbols +- Compile CPU mining for win32 and win64 +- configure: Check for pthread in -lwinpthread +- Use has_pth flag instead of trying to mess with pthread internals +- configure: Explicitly check for nanosleep +- configure: Include "no" response in BFG_PTHREAD_FLAG_CHECK +- miner.h missing extern +- Update links and recommended SDKs. +- Bugfix: README.GPU: Fix some typos +- Update README to match changes to display. +- Remove increasingly irrelevant discarded work from status lines. +- Remove increasingly irrelevant GW value from status. +- README.GPU: Correct terminology +- Update README about intensity. +- Bugfix: Restore always autodetecting stratum as non-scrypt +- icarus: Replace default of 2 work_division/fpga_count with autodetection of 1, +2, or 4 +- Update scrypt readme with newer information and to match changes in code. +- Set default GPU threads to 1 for scrypt. +- Connect backup stratum pools if the primary pool cannot deliver work. +- Use a new algorithm for choosing a thread concurrency when none or no shader +value is specified for scrypt. +- Do not round up the bufsize to the maximum allocable with scrypt. +- Remove the rounding-up of the scrypt padbuffer which was not effectual and +counter-productive on devices with lots of ram, limiting thread concurrencies +and intensities. +- Make pool adding while running asynchronous, using the pool test thread +functionality. +- Only curl easy cleanup a stratum curl if it exists. +- Add intermediate variants of cglocks that can be up or downgraded to read or +write locks and use them for stratum work generation. +- Move the stratum data to be protected under a new cg_lock data_lock. +- Convert the ch_lock to cg_lock. +- Convert the control_lock to a cg_lock. +- Remove unused qd_lock. +- Implement cg_lock write biased rwlocks. +- Don't start testing any pools with the watchpool thread if any of the test +threads are still active. +- Set sockd to false should curl setup fail on stratum. +- Reopen the socket whenever we're retrying stratum. +- Set pool died on failed testing to allow idle flag and time to be set. +- Remove unused pthread_t typedefs from struct pool. +- Perform pool_resus on all pools that are found alive with the test pool +threads. +- Use pool_unworkable in select_balanced as well. +- Differentiate pool_unusable from pool_unworkable. +- Keep a connection open on higher priority stratum pools to fail back to them. +- Set the wrong bool in pool_active +- Only bypass unusable pools if they're not the selected ones. +- Find the first usable pool in preference to the current pool in select_pool +for work. +- Add a pool_unusable function which checks if a pool is stratum but not active +to use within switch_pools. +- API no longer ignore send() status +- API make the main socket non-static +- Start the stratum thread only if we successfully init and authorise it, +otherwise unset the init flag. +- Make the initialisation of the stratum thread more robust allowing the +watchpool thread safe access to it after the stratum thread is started. +- Shorten the time before keepalive probes are sent out and how frequently +they're sent with stratum curls. +- Display select return value on select fail in stratum thread. +- Clear the socket of anything in the receive buffer if we're going to retry +connecting. +- Perform pool resus on pools that were not set as the initial pool at startup. +- Allow pools to be resuscitated on first startup by the watchpool thread. +- Check all pools simultaneously at startup switching to the first alive one to +speed up startup. +- Close any sockets opened if we fail to initiate stratum but have opened the +socket. +- API use control_lock when switching pools +- Clear last pool work on switching pools if the current pool supports local +work generation or we are in failover only mode. +- make rw locks: mining_thr_lock and devices_lock +- work queues - remove new but unnecessary functions +- functions for handling work queues +- find_work() to find work in devices work queue +- Add a get_queued function for devices to use to retrieve work items from the +queued hashtable. +- Add the choice of hash loop to the device driver, defaulting to hash_sole_work +if none is specified. +- Add a driver specific flush_work for queued devices that may have work items +already queued to abort working on them on the device and discard them. +- Flush queued work on a restart from the hash database and discard the work +structs. +- Create a central point for removal of work items completed by queued device +drivers. +- Create a fill_queue function that creates hashtables of as many work items as +is required by the device driver till it flags the queue full. +- Create the hash queued work variant for use with devices that are fast enough +to require a queue. +- Make sure to do full avalon_init if the device_fd is invalid. +- Document extra zero byte in avalon_reset. +- Microoptimise likely paths in avalon_gets. +- Make sure to set timeout to 100ms instead of 1ms in avalon read loop for +select. +- Make sure to get time of first response in avalon read loop. +- Use select for a reliable timeout in avalon read and don't read 1 byte at a +time, optimising read loop. +- We should break on the loop on a work restart in avalon, and only consider all +errors if we actually have gotten some results. +- Avalon init on comms error as well. +- Reinit avalon device in case of FPGA controller mess up. +- Increase reliability of avalon startup by only opening and resetting the +device once, looking for the id sequence offset by one byte as well, and still +ignoring if it's wrong, assuming it is an avalon. +- Nest avalon_decode functions to avoid doing unnecessary lookups once we have +found the nonce. +- Use htole32 wrapper for nonce encoding in avalon. +- Remove unused rev8 function from avalon driver. +- Remove const qualifier from driver structs +- rename device_api -> device_drv and all related api -> drv +- rename get_proc_by_id() to get_devices() +- Wrap access to devices array under a mutex +- Provide wrappers for grabbing of thr value under the mining_thr_lock. +- mutex all access to mining_thr +- Split thr_info array into control_thr and mining_thr pointers so more mining +threads can be added later +- Update the hashmeter at most 5 times per second. +- Speed up watchdog interval and therefore display updates to 2 seconds. +- Add README.GPU to EXTRA_DIST. +- Split out the GPU specific information from the README into a README.GPU file. +- Update docs and reorder README to show executive summary near top. +- Add more FAQs about crossfire. +- Convert error getting device IDs in ocl code to info log level only since +multiple platforms may be installed and the error is harmless there. +- Unnecessary extra array in ocl code. +- Cope with the highest opencl platform not having usable devices. +- Update kernel file names signifying changes. +- Use constants from the array of __constants throughout the diablo kernel. +- Create a __constant array for use within diablo kernel. +- Use global constant arrays for all other constants used in scrypt kernel. +- Use global __constants for sha functions in scrypt kernel. +- Use constants for endian swap macros. +- Revise scrypt kernel copyright notice. +- Separate out additions in scrypt kernel. +- Reuse some Vals[] variables that can be assigned to constants earlier in the +poclbm kernel, making for fewer ops. +- Put all constants used in poclbm kernel into __const memory array to speed up +concurrent reads on the wavefront. +- opencl: Support for reading temperature from free software radeon drivers via +libsensors + + +BFGMiner Version 3.0.3 - June 13, 2013 + +- make-release: Include all submodules, recursively +- Remove API.java example (no copyright license) +- Minimally fix "make install" to ignore bitstream sources +- Add submodule for ZtexBTCMiner (aka ztex_ufm1_*) +- Add submodule for X6000_ztex_comm4 (aka x6500-overclocker-0402) +- ztex: Use standard file header/comment formatting, and update license to GPLv3 +- bitforce: Allow a longer timeout (1250ms) for ZCX (Device Information) +commands +- Bugfix: pdcurses doesn't like changing logwin size without clearing it also, +so do that in display options +- -S all: Start QueryDosDevices probe with 256-byte buffer +- Use common code to ensure the prefix of -S *:all remains in all +implementations of it (/dev glob was removing prefixes) +- bitforce_queue: Ensure comma following nonce count is there, to error cleanly +- bitforce: Report queue send failures, and count as hw errors +- Bugfix: bitforce_queue: Don't try to send ready-to-queue work to device, when +there is no ready-to-queue work +- Bugfix: bitforce: Clear want_to_send_queue flag when flushing queue, since we +can't send an empty queue +- bitforce: Include new total queued count in flush debugging +- Bugfix: bitforce_queue: Implement a minimum wait time of 10ms +- README: Document serial device format for Mac OS X +- Bugfix: cairnsmore1: Enable building with libudev autodetection even if only +icarus drivers are enabled +- Bugfix: sysfs autodetect: Continue searching even after finding one tty (fixes +multiple ttys per device, such as some Cairnsmore1s) +- Bugfix: ztex: Avoid destroying libztex device in case other processors are +still in use (fixes crash when 1.15y becomes unavailable) +- Update windows-build.txt +- ccan: Add missing copyright comment headers +- Remove obsolete mknsis.sh +- Add missing copyright sections to files that may need them +- Standard copyright format (including year) for adl_functions.h +- Bugfix: When disabling device, ensure its prev_work (if any) gets freed +properly +- Check stratum socket exists and is writable before even considering whether +the sessionid is the same or not +- Bugfix: Check that the stratum_share struct for a failed submission is still +in the submission hashtable before trying to delete it +- README: Add missing documentation for CPU algorithms cryptopp_asm32, sse2_32, +and altivec_4way +- Bugfix: icarus: Check work restart before timeout +- Bugfix: icarus: Debuglog the correct read timeout (and omit from work restart +since there's no trivial way to get it) +- README: Update links +- Bugfix: cpu: Fix warning on Win64 +- Bugfix: avalon: Strict formatting +- Bugfix: Cleanup trivial warnings +- Bugfix: bitforce: Seek to end of nonce counter to find nonces, in case there +are more than 9 +- Bugfix: Build hexdump.c into the project normally like everything else +- Bugfix: Really fix device entries in saved config file +- Update the write config to properly record device entries and remove disabled +option. +- avalon: Really fix applog formatting +- va_copy is meant to be matched by a va_end in log_generic. +- Further fix distdir for hexdump.c +- Fulltest is true if value is <= target. +- Fix warning with no curses built in. +- Bugfix: configure: Check NEED_FPGAUTILS correctly +- configure: Better grammar for --enable-cpumining help +- Bugfix: Check for SSE 4.1 support before building sse4_64 asm CPU miner (uses +MOVNTDQA instruction) +- Bugfix: elist: Use uintptr_t for member offset +- Bugfix: opencl/adl: Fix format string +- Bugfix: opencl: Correct usage of formatted prints +- Increase fd limits as much as possible at startup +- Bugfix: bitforce: bulk queue: Cleanly retry for high temperature recovery +- Fixed deps for raring, which has newer libudev1. +- bitforce: debuglog actual result data +- Bugfix: Missing 'else' can result in null pointer dereference in race +- Minor grammo in avalon driver. +- Make avalon temperature reading LOG_INFO level. +- Fix the problem of seting up termio of ttyUSB0 for icarus. the CSIZE is the +mask of CS2/4/8 +- bufsize is an unsigned integer, make it so for debug. +- Bugfix: bitforce: Include get_api_stats in BQUEUE mode +- Bugfix: Always compile support for commandline --temp-target and +--temp-cutoff, and write them in the config for all devices +- Bugfix: Ensure cURL timers get set correctly in submission thread +- Bugfix: modminer: Remove unused parameter to sprintf +- Bugfix: modminer: Use correct format for bytes left in bitstream upload +message +- Bugfix: Access strategy name string directly instead of accidentally +- Add printf-format syntax checks to more functions that should use it +- AUTHORS: Add more contributors +- Support configure flag --with-system-libblkmaker to allow building without the +bundled copy +- Bugfix: Use HTTP/1.1 compatible product token for User-Agent header + + +BFGMiner Version 3.0.2 - April 28, 2013 + +- Receive failures in recv_line should unconditionally fail. +- Use sock_blocks function for stratum send and receive. +- Avoid applog under stratum_lock in __stratum_send. +- Create an OS specific sock_blocks function. +- There should be no error response code with return value 0 in recv_line. +- Check for errors on stratum recv for any recv return value less than 1 and +only parse the response if it's positive. +- Avoid applog under stratum_lock in recv_line. + + +BFGMiner Version 3.0.1 - April 24, 2013 + +- Bugfix: configure: Move actual roundl macro back to miner.h after math.h +should be included +- Bugfix: configure: Use dummy pointer to correctly detect roundl when conftest +main is missing argc parameter +- Bugfix: configure: Use variable argument to roundl to prevent compilers from +optimizing it out entirely +- Remove bitstreams from Windows binary distributions (README directs users to +download source and copy them) +- make-release: Remove autom4te.cache from distributed source +- Bugfix: Omit --no-opencl-binaries option from build if OpenCL is not being +compiled +- Bugfix: Check that all pools have URIs set before starting +- Bugfix: bitforce: Make noncebuf large enough for max qresults +1 (for OK line) +- opencl: Ability to avoid using binary kernels with new --no-opencl-binaries +option +- README: Include jansson PKG_CONFIG_PATH in example for Mac +- Include trailing \0 with coinbase sigs if there's room +- Differentiate socket closed from socket error in recv_line. +- Add new best share info to verbose logging. +- Add notice for when network diff is changed. +- convert sleep(const) to nmsleep() +- Rename longpoll threads according to what pool they're associated with +- miner.php report 'Last Valid Work' as time before request +- API V1.25 - add 'Last Valid Work' time for each device +- add 'count' to customsummarypage 'calc' +- Bugfix: ztex: Initialize fw_buf pointer to NULL so a free before allocation is +safe +- Cleanup when stratum curl fails to initialise. +- LTC text typo +- Recreate cURL for new stratum connections, and clear stratum_notify on +suspending them +- clear_stratum_shares: Rename diff_stale variable to diff_cleared +- MMQ it's a bitstream +- Update a pool's last work time when the work is popped as well as staged. +- Extend stratum connections another minute (total 2 minutes) after the last +work item was staged, and maintain last_work_time for non-stratum pools. +- Fix --benchmark generating valid work for cgminer. +- Bugfix: Correct pdbuilder result directory +- Omit add_serial_all code when serial support is not wanted +- Use configure to detect presence of roundl to avoid redefining an actual +function (possibly inline) +- Bugfix: roundl: Add needed parenthesis to perform ?: before + +- Bugfix: ft232r: Defer allocating structure until after USB endpoint is +successfully opened, so it won't leak in case of failure +- Bugfix: ztex: Free bitstream in memory when done with it +- Bugfix: Safely handle all-space cURL debug messages, should they ever happen +- Silence warnings about poor format usage for quit() +- Apply noreturn and printf-format attributes to quit() function definition +- Bugfix: set_serial_rts get flags to manipulate them correctly +- Bugfix: Missing return for /dev globbing +- Bugfix: Free unused work when retrying failed lp request +- Display processor name with thread disabled/re-enabled messages +- Move best share to top summary line, and add network difficulty to block line +- opencl: Default to phatk kernel for Mesa platform +- opencl: Default to single thread with Mesa OpenCL +- opencl: Check for Mesa OpenCL and avoid using binary kernels with it +- bitforce: Never increase bulkqueue poll wait time during queue underruns +- bitforce: Start off polling bulk queue every 100ms +- bitforce: Log device queue size after getting bulk results +- bitforce: Ensure bulkqueue polling occurs at least once a second +- opencl: Include OpenCL platform in kernel binary filenames +- bitforce: Use bulk queue mode for all SC devices +- Bugfix: bitforce: When reinitializing, free all known works to avoid +decrementing reset queued counter +- bitforce: Handle timeout during ZOX as cleanly as possible +- Bugfix: bitforce: Make reinitialization more complete and safe +- Bugfix: bitforce: Close opened fd if reinit fails +- Bugfix: bitforce: Retry ZGX until device is NOT busy +- bitforce: Log when zero queued results are received + + +BFGMiner Version 3.0.0 - April 5, 2013 + +- Update libblkmaker to 0.3.0 +- debian: Include new api-example.py in docs +- added example for Python using the RPC API +- added SPEC file for SUSE distributions +- Bugfix: bitforce: Free initialization data to avoid trivial one-time memory +leak +- Support for local submission of found blocks (GBT only) +- bitforce: RPC pgaset fanmode 0-5 for manual fan control +- bitforce: More debugging information +- Bugfix: modminer: Since RPC always includes the temperature, we don't need to +add it specially +- bitforce: Expose dual temperature sensors to RPC +- bitforce: Support for up to 2 temperature sensors per processor +- Bugfix: bitforce: BFP_QUEUE: Attempt to recover from extra queue results, or +the next job finishing early +- bitforce: Always send a new job ASAP after flushing the queue +- bitforce: Implement "Queue Job Pack" (ZWX) and use it for XLINK devices to +avoid USB latency issues +- bitforce: Ignore INPROCESS added to ZOX response +- Implement minerloop_queue for devices that process work items too fast to keep +track of which one they're currently working on +- bitforce: Split ZOX command into its own function +- Bugfix: DevAPI: Free work when preparing it fails +- DevAPI: Abstract get_and_prepare_work for minerloops +- DevAPI: Move select() logic from minerloop_async to do_notifier_select +- Clarify stratum mining.set_difficulty debug log message +- No longer call configure from autogen.sh +- Bugfix: bitforce: Ensure result_busy_polled gets set for queue mode to avoid +unnecessary 10ms wait times +- Bugfix: bitforce: Use common code for end of job_get_results, so queue results +don't short-circuit timing code +- Bugfix: bitforce: Ensure "OK" doesn't remain in queued results buffer +- Bugfix: bitforce: next_line needs to increment beyond the newline character +- Update README for x970 memdiff values. +- Do not scan other gpu platforms if one is specified. +- Update README for sync objects on windows. +- Add information for setting gpu max alloc and sync parameters for windows with +scrypt. +- Whitelist AMD APP SDK 2.8 for diablo kernel. +- Show pool number in switch message +- Clear just the socket buffer when we don't care what is left in a stratum +socket. +- Clear the stratum socket whenever we are closing it since the buffer is going +to be reused. +- Do not continue work from a stratum pool where the connection has been +interrupted. +- Close any existing stratum socket if we are attempting to restart stratum so +the pool knows the connection has gone. +- Show mechanism of stratum interruption if select times out. +- Make stratum connection interrupted message higher priority to be visible at +normal logging levels. +- API add 'Network Difficulty' to 'coin' +- avalon: if all result are wrong in one batch read. reinit the avalon +- avalon: record the last result temperature info +- delay when close avalon; only record matched result +- avalon: fix no_matching_work only count when debug +- avalon: minor change +- avalon: add idle code +- avalon: fliter the temp_max >= 100, print the result for debug. +- avalon: export more data to API stats +- avalon: add default chip frequency +- avalon: fix the work_i3 init +- avalon: add reinit_device +- avalon: the temp_history_count base on timeout +- avalon: fix mistake on adjest_fan +- avalon.c: fix the copyright +- bfgminer-rpc: add -o option: no format, only the result +- avalon: update fan pwm +- avalon: update the FAN_PWM MAX/MIN +- avalon: minor change +- avalon: overclock code +- avalon: fix the display +- avalon: minor change +- avalon: fix the fan/temp control +- avalon: fix the temp_avg +- avalon: fix temp +- avalon: add fan/temp control +- avalon: add FAN speed factor +- avalon: add TODO on fan/temp control. cleanup detect +- avalon: add the gate_miner bits +- avalon: only send one byte on reset +- avalon: add support on send 2 bulk taskes at begin +- avalon: fix the hash_count return +- avalon: fix the LOG_WARNING +- avalon: add comment on hash_count +- avalon: WORKAROUND on hashrate +- avalon: update max miner_num +- avalon: add more info on api +- avalon: add nonce_elf and more info on match miner_num +- avalon: change reset to 300ms +- avalon: move bulk buffer to it's info structrue +- avalon: more work on hashrate and read_count +- avalon: add baud 38400 support +- avalon: fix nonce_range EB +- avalon: fix the hashrate wrong +- more info on avalon API +- avalon: fix the nonce_range EL +- avalon: fix the read count +- avalon: more work on nonce_range +- avalon: read() times and send delay fixed +- avalon: add the send delay option +- avalon: print out fan/temp info +- avalon: add the result info (fan/temp etc) +- avalon: more check on hardware error +- avalon: more work on get_work_count +- avalon: now we have dynamic get_work_count +- avalon: more work on parameters +- avalon: add timeout parameter +- avalon: baud as parameter now +- avalon: send work pitch should be : (15*(8+2)*4/19200)s +- avalon: more work on match work +- avalon: fix free_work +- avalon: continue on reset work. wait for buffer empty +- avalon: add options, if write() error. sleep(1) before reset() +- avalon: more cleanup +- avalon: finish read when Buffer empty +- avalon: fix the nonce EB issue +- avalon: MORE work +- avalon: fix the EB/LB issue +- avalon: some cleanup +- avalon: fix the first configure task +- more work on the avalon buffer +- avalon: fix the BIG_ENDIAN issue +- avalon: Fix the buffer statu +- change defines to avalon parameters +- fix the cts return +- avalon: change the data to uint8_t, add some test temp code +- avalon: fix task init +- avalon: more data format work +- change to avalon data format +- debug: add a debug hexdump.c +- avalon: add some code on match work +- avalon: try to correct the pool_status and dev_status +- avalon: more work on multi-works +- avalon: more work on read +- avalon: more work on get results +- more RTS code on avalon.c/h +- more RTS code +- avalon: some cleanup +- avalon: more work on new work queue structrue +- fpgautils.c: use lancelot as target +- avalon: since we submit task as bulk data. modify again +- add scanhash_queue +- renmae avalon.h to driver-avalon.h +- fpgautils.c: add get_serial_cts +- understand the avalon protocol more +- avalon: new software structrue but target as lancelot +- add avalon.h +- avalon: fix warning +- avalon: add TODO comments +- more AVALON defines +- avalon: more work +- add driver-avalon.c +- add avalon support to automake +- Default to work queue mode on BitForce SC devices +- bitforce: Implement support for non-contiguous XLINK slave addressing +- gnulib: stdint: fix build with Android's Bionic fox x86 +- gnulib: stdint: Improve support for Android. +- gnulib: stdint: Add support for Android. +- Check for ?e##toh macros independently from hto?e## +- If pthread_cancel is missing/emulated, set asynchronous thread cancel type on +stage, watchdog, watchpool, and longpoll threads since the emulation cannot +support deferred cancellation +- If pthread_cancel is missing (Bionic/Android), emulate it using pthread_kill +and pthread_exit +- configure: Intelligently detect what flags/libs get us working pthread, and +define HAVE_PTHREAD_CANCEL if pthread_cancel is available +- Bugfix: Initialize mutex_request to invalid so devices that don't use it +(bitforce) don't try to +- RPC: pools: Add "Message" to show last client.show_message received over +stratum +- Stratum: Support client.show_message method +- Don't retry without resume support, if the first attempt just timed out +- Bugfix: minerloop_async: Intelligently handle work updates and device disables +during transitions +- Bugfix: minerloop_async: Free old (unused) prepared work when replacing it +with an upgraded one +- Bugfix: Free pool sessionid before replacing it +- Bugfix: Stratum: Address dereference-after-free and memory leak introduced in +resume support +- Stratum: If old protocol fails as well, try to resume again next time around +- Bugfix: Stratum: Only failover to old mining.subscribe protocol if the +previous attempt was the new one (fixes a flood of retries) +- Try to extract the sessionid associated with mining.notify on 3rd level array +and submit it along with the userid to support mining resume, failing gracefully +and restarting if the pool rejects it. +- Cope with misread sessionid on stratum for now. +- Use the sessionid as passed on stratum connect to attempt to resume a +connection once and then clear it if it fails, to use a new connection. +- Move to storing the nonce1 in the work struct instead of the sessionid for the +now defunct first draft mining.resume protocol. +- Only continue submitting shares with mining.resume support on stratum when the +session id matches. +- Provide support for mining.resume with stratum, currently re-authorising after +successful resumption pending finalising of the protocol process. +- Provide basic framework for restarting stratum depending on whether resume +support exists or not. +- Abstract out the setting up of the stratum curl socket. +- Remove redundant setting of strings to NULL since the whole work struct is +zeroed. +- Only clear stratum shares mandatorily on stratum dropouts when the pool does +not support resume. +- Stratum: Keep trying to submit shares, even across reconnects +- Use new select loop primitives in submission thread +- Bugfix: Missing pool_no parameter to applog for no-stratum-sessionid debug +message +- Do as much outside of mutex locking of sshare_lock as possible. +- Remove last reference to struct work used outside the sshare_lock in +submit_work_thread +- Unlock the sshare_lock in submit_work_thread when all references to work and +sshare are complete. +- Bugfix: Copy and free sessionid on work objects +- Add timestamps to stratum_share structs as they're generated and copy the +stratum sessionid if it exists to stratum work generated. +- Store session id for stratum if the pool supports it for future mining.resume +support. +- Keep the unique id of each work item across copy_work to prevent multiple work +items having the same id. +- x6500: Never consider processors idle if they're enabled +- x6500: Make mutex management cleaner by blocking device select loop during +idle get_stats +- Bugfix: minerloop_async: Always refer to real thread for select loop +- Bugfix: Initialize work_restart_notifier[1] to INVSOCK instead of -1 to be +portable +- ztex: Use restart_wait to react quicker to work updates +- Handy TIMEVAL_USECS macro +- Restore blocking restart_wait function with nearly identical semantics as old +one +- Bugfix: bitforce: Rework sleep delay adjustment logic to properly deal with +more accurate timing readings (added in device API update) +- Hidden --force-rollntime option for getwork pools (use like --pool-priority, +after each pool definition) +- Include processor id in get_work logging +- Support for BIP23 BPE request target extension via new --request-diff option +- Hidden option to reduce "work update" messages to debug level: +--quiet-work-updates +- Change "work restart" to "work update" in messages to reflect reality more +accurately (no work is lost), and normalize case of "longpoll" +- HACK: Since get_work still blocks, reportin all processors dependent on this +thread +- Move FD_SETSIZE definition to configure so it affects everywhere it needs to +- Move absolute_uri function to util.c +- Remove now-unused blocking-wait code (restart_cond, restart_wait, and +stale_wait) +- Bugfix: bitforce: Zero hashes complete if we get an invalid response +- HACK: Since get_work still blocks, reportout all processors dependent on this +thread +- bitforce: Support for work queue protocol on BitForce SC devices +- Use new double-stage format for SC devices +- modminer+x6500: Expose frequencies to API in terms of MHz to be consistent +with ztex driver and cgminer +- bitforce: Replace (bool)cgpu->nonce_range with (enum)bitforce_data->proto +- bitforce: XLINK support for multiple processors +- bitforce: Prepare log messages for XLINK by separating into proc and dev +messages +- bitforce: Always use fd/mutex pointers on actual device, to prepare for XLINK +support +- bitforce: Get fd/mutex pointers only once per function +- bitforce: Abstract commands to bitforce_cmd1 (single-stage) and bitforce_cmd2 +(double-stage) functions +- bitforce: Debuglog device information during detection +- Bugfix: Missing includes needed on Windows +- Bugfix: Use waddstr instead of wprintw to display completed device summary +line, so literal %s don't get interpreted as formatting options +- Bugfix: bitforce: Avoid polling continuously between work restart and job +completion +- bitforce: Use poll device API when job_get_results needs to wait +- bitforce: Use poll device API when job_start needs to wait +- stale_work_future function to determine in advance if a work/share will be +stale at some future time +- bitforce: Minimally refactor to adapt to new minerloop_async +- minerloop_async: Break out of select on work_restart_notifier +- Replace UNIX-only work_restart_fd pipe with portable work_restart_notifier +- Bugfix: Clean out unused variables from minerloop_async +- Move new device API code to new deviceapi.c source file +- Make minerloop_async more async, using some callbacks to handle event +completions +- Split part of minerloop_async into do_get_results, and a bit other +reorganization +- Abstract select_timeout function to convert a realtime timeval to a timeout +pointer for select() +- Split part of minerloop_async into do_process_results, and don't allow +api->job_get_results to return hashes +- Split part of minerloop_async into do_job_prepare and do_job_start +- Initialize thr->tv_poll to -1 (disabled) +- Update the hashmeter one last time before disabling a device +- minerloop_async: Break out of select for wakeup notifications +- Replace mining thread queues (which were only used for wakeup pings) with +notifiers (which can be used with select and co) +- Unify all mining thread wakeup to mt_enable (simplifying code) +- Bugfix: get_statline: Correct device summary status, only showing DEAD or OFF +if it affects all processors +- Working processor disable/enable with new async minerloop (currently gets +stuck if all processors disabled) +- Bugfix: get_statline: Only care about the processor status if +--show-processors is set +- Bugfix: watchdog: Use processor thr_info even if it isn't a real thread +- Only support thread-per-device or N-threads-per-processor; simplify +work_restart check +- x6500: Remove mutex, since driver is single-threaded now +- Bugfix: Update utility every get_statline call, and include every processor +involved +- HACKING: New text file to document the internal workings of (currently) the +device API +- Bugfix: mining_threads is now a total of thr_info objects, not necessarily +actual running threads +- x6500: Working (but incomplete) asynchronous/single-threaded driver +- Incomplete (but workable) asynchronous minerloop +- Core support for managing multiple processors from a single thread +- Allow device drivers to implement their own minerloop +- Move cgpu_info and thr_info initialization to main, and ensure all get +initialized before starting any threads +- Refactor and simplify miner_thread (no major behavioural changes) +- Move difficulties to end of share result message, so they can be made to line +up nicely +- Bugfix: Consolidate share result message code (including fixing displayed +hash portion for stratum) +- miner.php: Include ProcID in Device column as a letter +- Show summaries per-device unless --show-processors is used (also available on +Display TUI menu) +- Order next_proc linked list in processor id order +- Consolidate processor summary line generation for TUI and text-only modes +- RPC: Update to include ProcID so multiprocessor devices can be understood +correctly +- RPC: Common function for adding device-identifying fields +- modminer: Make single-processor statline look like other temperature-only +statlines +- modminer: Split each FPGA into its own logical processor (in the same device +still) +- modminer: Get mutex pointer only once per function +- ztex: Combine master+slave devices into a single multiprocessor device +- Preformat dev_repr (device representation) and proc_repr (processor +representation) once for use everywhere +- x6500: Split each FPGA into its own logical processor (in the same device +still) +- x6500: Get mutex pointer only once per function +- Minimal support for defining devices with multiple logical processors +- Rename all README files to standard README.* style + + +BFGMiner Version 2.10.6 - April 5, 2013 + +- Bugfix: Restore missing variable +- Bugfix: openwrt: Never include _ in platform name +- Bugfix: Fixed typo in bfgminer-rpc usage +- pool_active: Ensure temporary curl is always cleaned up +- Try to find jansson via pkg-config first, and fall back to checking system +defaults if that fails +- Attempt to find libjansson via pkg-config if AC_CHECK_LIB fails +- Update scrypt readme re drivers and sdk. +- Bugfix: README: Move --device out of GPU only options +- Update .gitignore +- Added bfgminer-rpc binary to .gitignore +- Bugfix: Actually change to the newly selected pool when statum is inactive and +it decides to change +- Bugfix: modminer: Properly fail on dynclock error +- Bugfix: opencl: Clean pc_data->work before freeing pc_data +- Bugfix: Correct order of libblkmaker libraries so static builds work +- Bugfix: Need to ensure __BIG_ENDIAN__ is defined before including uthash.h +- Bugfix: Stratum: When destroying cURL easy handle, be sure to clear pool +stratum_curl pointer +- Bugfix: bitforce: Fix warning +- Bugfix: Stratum: Properly handle non-integer "id" for client.get_version +requests +- json_dumps_ANY utility function to portably implement json_dumps(..., ... | +JSON_ENCODE_ANY) +- Bugfix: bitforce: Free old name when updating it on reinitialization +- Stratum: Include pool number in send/recv protocol logging +- Include pool number in stratum thread name +- API always report failed send() replies +- API.java allow partial reads +- Bugfix: Stratum: Use curl_easy_cleanup to close connection, so cURL +understands what is going on +- Bugfix: hash_pop: If a work should be rolled, use a clone of it rather than +consume a rollable work +- openwrt: Move Makefile into a bfgminer subdirectory to avoid symlinking issues +- openwrt: Use --with-curses=ncurses to avoid ncursesw dependency +- configure: Support --with-curses=FOO to look for curses implementation in +libFOO +- Set pool socket to INVSOCK after closing connection, just in case +- Clean up compiler warnings +- Bugfix: Check that pool is active one last time before selecting it +- Bugfix: Trim whitespace (like newlines) off the end of debug info from +libcurl +- Bugfix: submit_nonce: Backup the original work->blk.nonce since the miner +code uses it to track work consumption +- Bugfix: Scheduler needs to unpause disabled devices, even if it isn't waking +them up +- Bugfix: Use SOCKETTYPE for notifiers, to avoid potential overflow on Win64 +- Bugfix: Some versions of MingW define localtime_r, but don't handle the +timeval.tv_sec case that we use; so undef any preexisting one and use our own +- Bugfix: reinit_gpu: Remember the selected device to correctly change +properties of +- Bugfix: cpu: reinit_device hasn't worked since 93b284d, so just remove it +entirely instead of letting it screw with thread 0 +- Document necessity to run ldconfig and possibly configure ld.so +- Bugfix: Complete startup after just one pool is found active, no need to wait +for the rest +- Bugfix: Update links +- miner.php: Replace PGA dev number with concatenated device ID +- Bugfix: miner.php: Display devices with aligned columns instead of assuming +they come out of the RPC aligned +- Bugfix: miner.php: Silence PHP "local timezone" warning +- Bugfix: api-example: Try to use BSD sockets on any non-Windows platform +- Bugfix: stratum: Delay mining.get_transactions request until after auth has +succeeded, so its failure doesn't abort the connection (also avoids any delay +from a large result) +- --no-getwork option to disable getwork protocol support +- Clarify dependencies with Debian/Ubuntu package names + + +BFGMiner Version 2.10.5 - February 8, 2013 + +- Bugfix: Actually increment template_nonce when we use it +- Change file modes. +- Fix logic fail on partial writes with stratum send that was leading to corrupt +message submissions. + + +BFGMiner Version 2.10.4 - February 7, 2013 + +- New platform ports: OpenWrt and Win64 +- Update official Windows build compiler and libraries: +- - Upgrade GCC from 4.6.3 to 4.7.2 +- - Upgrade libusbx from 1.0.10 to 1.0.14 +- - Upgrade jansson from 2.3.1 to 2.4 +- - Upgrade libcurl from 7.26.0 to 7.28.1 +- - Upgrade pthreads-win32 from 2.8.0 to 2.9.1 +- Bugfix: Release libudev handle when ID_MODEL doesn't match what we're looking +for +- openwrt: Script to build for multiple platforms easily +- openwrt: Bitstreams should be "all" arch +- Working OpenWrt Buildroot Makefile +- Do not enable the pool disable on reject feature unless explicitly enabled +with --disable-rejecting. +- Check for calloc failure for completeness in gen_stratum_work. +- Cache the coinbase length to speed up stratum work generation. +- Cache the header length when generating stratum work to avoid calculating it +on every work generation, and to only need one alloc+sprintf, speeding up work +generation. +- Use heap ram for coinbase in gen_stratum_work, zeroing it before use. +- Provide a wrapper for aligning lengths of size_t to 4 byte boundaries. +- Bugfix: ztex: While 1.15y can finish highspeed FPGA config immediately, at +least 1.15x needs some delay +- Use CURLOPT_OPENSOCKETFUNCTION to intercept the socket being created for +stratum, in order to workaround CURLINFO_LASTSOCKET breakage on Win64 +- make-release: Update for Win64 and bfgminer-rpc.exe +- Use localtime_r instead of localtime, including a Windows implementation that +handles Win64's broken struct timeval.tv_sec +- Use standard execv arg type on Win64 +- Bugfix: Correct various size mismatches +- Ensure winsock2.h is always included before windows.h +- Bugfix: Add necessary Winsock library to bfgminer-rpc linking +- Bugfix: Remove dependencies of compat.h on miner.h for Windows (moves +timersub/timeradd to compat.h where it belongs) +- modminer: Raise default/maximum clocks to 210 and 250 respectively +- modminer: Use better-performing X6500 overclocker bitstream +- Disable libusb linkage/usage when neither X6500 nor ZTEX support is desired +- Add support for "--scan-serial all" via simply globbing /dev +- fpgautils: serial_autodetect implementation using sysfs +- fpgautils: Unified serial_autodetect function to find a serial device +regardless of the underlying method +- fpgautils: Look for bitstreams in ../share/bfgminer/ too +- Bugfix: Ensure curses library is always linked in NCURSES_LIBS, to avoid +unnecessary dependencies for (non-curses) tools +- Bugfix: GBT: work->data is always little-endian, but libblkmaker wants the +nonce in native-endian +- Bugfix: cpu: Corrections necessary to get 'c' and 'cryptopp' algorithms +working on big endian +- Bugfix: Sanity check for bits exponent in real_block_target +- Bugfix: cpu: Increment nonce after checking (rather than before), to avoid +skipping the first nonce of each scanhash call +- cpu: via: Only swap back the nonce, rather than all data +- cpu: Minor optimization by checking H==0 before calling fulltest +- Bugfix: Skip yasm check when building for non-x86 platforms +- Allow --scantime alias to --scan-time +- Build bfgminer-rpc program from api-example.c +- Bugfix: Remove miner.h include from api-example.c since it isn't needed and +pulls in libblkmaker +- Make wrapping consistent at 79-80 characters per line +- Bugfix: Correct numerous misspellings, typos, etc +- Bugfix: Prefer using a non-frozen mining thread for watchdog +- Bugfix: x6500: Expose x6500_fpga_data even if JTAG reset/detect fail, since +it is still used to store temperature info if the other FPGA initializes +- Adding ZTEX Windows guide from Jason Snell + + +BFGMiner Version 2.10.3 - January 22, 2013 + +- Revert "x6500: Whenever we get a hardware error, purge buffers just in case +of read/write desync" +- Bugfix: libblkmaker: Check that zero-padding on base58check input matches +output (needed to properly reject addresses with too many or too few prefix/pad +'1's) +- Bugfix: Free bin2hex output in __update_block_title +- Bugfix: Allocate space for the terminating null byte on new current_hash +- Display tail end of prevblock hash rather than start+32bits +- Try to extract block height from coinbase scriptSig, when mining stratum +- Display next block height when using GBT +- Use suffixes for target-difficulty also, in share accept/reject loglines +- Bugfix: Implement common target_diff function, fixing scrypt-specific bugs in +and simplifying common code shared by set_blockdiff, calc_diff, and share_diff +- Set DISPLAY to :0 by default (on non-Windows) +- Bugfix: Reset pool bytes received when zeroing stats +- miner.php trim trailing zeros on some of the STATS numbers +- Semi-Cherrypick: API stats - include pool network bytes + in miner.php +- Best Share readme +- API zero - zero statistics - all or bestshare - with optional on screen +summary +- api.c pgaenable not re-enabling the device - plus related debug +- diffexactone pool diff1 used for share value calculation is ffffffff... not +100000000... :P +- miner.php user/pass fix 'usr' is readonly +- miner.php optional user/pass login restrictions +- zero (most) API stats +- Remember best share per pool and return in API pools +- ztex: precheck the secondary solutions to avoid hw errors the ztex bitstreams +gives back the latest checked nonce and its hash7 value and two possible +solutions. +- Bugfix: configure: if blocks require at least one command, so fill with true +- Bugfix: Only log stratum resume if it was actually "idle" before +- Zero the best share string memory when zeroing stats. +- Change the pool stratum socket buffer to new cgminer implementation, to +allocate it in a grow-only fashon and reduce virtual memory fragmentation at +the expense of CPU time. +- Differentiate socket full from sock full. +- Allow stratum to startup without notify but check it is valid before creating +stratum work. +- Do not try to generate stratum work unless the notify command has succeeded. +- Document Mac OS X configure usage with Homebrew pkg-config path +- Clean up post-configure display of compile environment +- Bugfix: If native ncurses detection fails, print "none?" result before moving +on to try AC_SEARCH_LIBS scan +- Fix more printf-format non-compatibilities +- Update windows-build.txt + + +BFGMiner Version 2.10.2 - December 27, 2012 + +- Update documentation to include block difficulty +- Reset all stats when requested +- Reset total diff1 shares when zeroing stats as well to show correct work +utility. +- Update documentation. +- Parse anything in the stratum socket if it's full without waiting. Empty the +socket even if a connection is not needed in case there are share returns. +- Provide a mechanism to zero all the statistics from the menu. +- Display the current pool diff in the status line. +- Display block diff in status line. +- Generalise the code for solving a block to enable block solve detection with +scrypt mining. +- Generate the output hash for scrypt as well and use the one function to set +share_diff. +- Use one size for scratchbuf as a macro in scrypt.c +- Remove the unused sha224 functions. +- Check staged_rollable under staged lock, when cloning available work. +- scrypt_diff uses a uint64_t as well. +- Correct target for stratum support with scrypt mining. +- Bugfix: Ensure nonces are put in data as little-endian in test_nonce* +- Add low-level debugging info for data_buffer (some only enabled with +-DDEBUG_DATABUF) +- Make all_data_cb fwrite-compliant by returning nmembs, and check for unlikely +overflows +- Bugfix: Need to do extract_sockaddr before trying to initiate stratum +(erroneous http URI usage, except at startup) +- Bugfix: Update last GBT work in pool_active before staging it, since otherwise +it could possibly be consumed before we copy it +- Bugfix: Address Windows-specific formatting issues (including lack of support +for %ll*) +- Bugfix: ztex: Correct formatting for reset failure error +- ztex: Fix formatting in a debug message +- cairnsmore: Don't bother timing dynclock detection, since there's no standard +way to log it accurately +- Correct formatting in FPGA drivers +- opencl/adl: Fix formatting to fit strict rules +- Explicitly cast all_data.buf to char* for debug printing +- Follow strict time_t handling rules +- Use GNU format-checking attribute when available for applog + + +BFGMiner Version 2.10.1 - December 21, 2012 + +- libztex: fixed a typo +- libztex: check returnvalue of libusb_claim_interface() and release the +interface in case of early exit +- Bugfix: submissions: Skip FD_ISSET when fd==-1 (let the next select setup deal +with cleaning them out) +- Bugfix: Remove sws from write_sws list when discarding it due to pre-send +stratum disconnection +- Bugfix: Shutdown stratum socket when initiate fails, so it doesn't linger +- Bugfix: Clear stratum receive buffer when initializing, in case there was +extra unprocessed data in it from a previous connection +- Stop all work from the current pool if it's a stratum pool once it is +disconnected since it will be invalid upon reconnecting. +- Discard all staged work from stratum pools as well as the shares upon +disconnection since all the work becomes invalid. +- Use correct cbreak after 15 second delay when no pool is found alive. +- modminer: Set default clock frequency to user request so it sticks better +- modminer: Make valid frequency range consistent: 2-230 +- Allow stratum to work with scrypt. +- MMQ add api pgaset for clock +- API V1.23 - new pgaset command, to be used soon +- Protect the best_share/best_diff values under control lock. +- Bugfix: modminer: Return failure to change frequency when device reports it +- opencl: Look in the right place for OpenCL library on Mac OS X +- Bugfix: AC_C_BIGENDIAN is reported to have problems, and invasive even if +buried in a conditional, so don't use it +- Bugfix: Check for bswap_* first, to avoid redefinition based on other variants +- Bugfix: autoheader isn't smart enough to figure out variable defines, so use +AH_TEMPLATE for each possible header +- Check a stratum pool hasn't gone dead while being a backup pool and missed +having its idle flag cleared. +- Fix null pointer issue when one chip on an X6500 is not initialized yet when +reading temperature. +- Hot-patch broken libcurl pkgconfig CFLAGS found in libcurl's Windows binaries +- Update OpenCL 1.2 headers from http://www.khronos.org/registry/cl/api/1.2/ +- Reorganize detection of platform byteswap macros and endian to be more robust +using autoconf +- Move new bandwidth-based Efficiency to status line +- Replace work-based efficiency with new bandwidth-based efficiency +- Bugfix: Pull out GBT request collapsing since it is no longer needed with new +get_work main loop +- Bugfix: Free unused work when waiting on external GBT request +- README: Explicitly mention automake dependency +- README: Update AMD APP SDK URIs +- Bugfix: Free shares discarded before beginning submission +- Bugfix: Discard stratum shares waiting for a writable socket, if the pool +disconnects in the meantime +- Bugfix: Always let watchpool thread handle dead pool recovery (including for +stratum-only pools) +- Bugfix: Avoid lingering stratum_auth when connection is lost +- API-README explain custom page extensions in miner.php +- miner.php add a sample group pool report +- miner.php allow where,group,having on cumstom pages +- Bugfix: Hook CURLOPT_DEBUGFUNCTION to count actual bytes sent/received by +libcurl +- Bugfix: Reset pool transparency_time when connecting to stratum +- Bugfix: Immediately discard shares found on disconnected stratum pools, since +there is no way to submit them +- Bugfix: Decrement total_submitting when stale shares are discarded before any +submission attempts +- Bugfix: Only try to compare stratum job_id for work that has a job_id (ie, +ones that came from stratum) +- Bugfix: Recheck has_stratum even if the pool hasn't changed, in case pool has +switched to another protocol in the process; also only delay 5 seconds before +retry if pool is the same +- Bugfix: Try GBT if no pool protocol is known (can occur in the process of +stratum failover to GBT) +- Bugfix: Correctly track discarded stratum shares, and log them as "disconnect" +in sharelog +- Check for EWOULDBLOCK when supported in send and recv as well. +- Use the raw send() command instead of curl_easy_send since curl raw socket +usage introduces random bugs on windows. +- Use raw recv() command in place of curl_easy_recv since the curl +implementation introduces random bugs on windows builds when the recv fails. +- miner.php when displaying a single rig, add prev/next rig buttons if they +exist, next to refresh +- miner.php allow custom page joins for STATS +- miner.php - include windows easyphp link +- driver-ztex: use the correct size for the swap array +- API stats - display pool byte transfer stats +- Pool store data transfer stats +- Benchmark incorrect work size +- ChangeLog refer to NEWS +- driver-ztex: search the complete noncerange based on the actual speed +- API-README update +- api use a dynamic io buffer, truncated before it reaches the current ~64k +limit + + +BFGMiner Version 2.10.0 - December 11, 2012 + +- Bugfix: Free work before replacing it with clone +- Bugfix: Since we are using pipes for select notifier on *nix, we need to use +read/write there +- Bugfix: Winsock needs send/recv for sockets, not write/read +- Bugfix: opencl: Initialize pc_data to avoid clean_work checking uninitialized +pointers +- Bugfix: Correct parenthesis in bind() call in Windows notifier_init +- Include Windows error messages in notifier_init errors +- Include prctl header for thread renaming to work. +- Set tv_idle time if a pool is not active when input from the menu. +- minor unlikely zero pointer test +- BeaverCreek doesn't like BFI INT patching. +- Only stratum pools that are idle need to be kicked via cnx_needed. +- Do not do any setup if opt_api_listen is disabled in api.c. +- libztex: in case the selectFpga() failed set the selected fpga to unknown +- Only set the lagging flag for select_pool() on failed getwork if we're not in +opt_fail_only mode. +- driver-ztex: support for broken fpga on a multifpga board +- libztex: use a function for the twice called firmware reset code +- libztex: removed an unused struct member (ztex->valid) +- Set the pool lagging flag on startup to avoid it being shown initially, and +only unset it once the maximum number of staged work items has been reached. +- libztex: Include compat.h for substitute libusb_error_name (on older libusb +versions missing it) +- Suppress warning about "succeeded" not being used in finish_req_in_progress +for now +- Bugfix: Always give the get_work thread a curl, regardless of other +outstanding curls in use +- Bugfix: Failover after even a single job-request failure (or else it takes +too long on timeouts) +- Bugfix: Need to remove and re-add curl easy handles from multi to start a new +request +- Access total_submitting under mutex lock to avoid any potential races, and +increment it as soon as we queue the submission up +- Just leave the submit_work thread running persistently +- Bugfix: Restore work->pool after prepare_rpc_req since clean_work now clears +it +- Bugfix: Now that stage_work is trying to manipulate staged_work in the same +thread, clone_available needs to stage it outside of its own lock +- Make main() the getwork scheduler once everything is set up, so that all app +exits use the kill_work and quit paths. +- Set successful connect to true on auth stratum to allow summary on exit from +single stratum pool. +- Hash_pop should signal further waiters on its own pthread conditional in case +there are multiple waiters. +- Check the job_id has not changed on stratum work when deciding if the work is +stale as might occur across disconnections. +- Perform pool_resus on getwork pool that generates work in getwork_thread. +- Set pool lagging message for getwork pool that falls to zero staged in getwork +thread. +- Stage extra work when the primary pool is a getwork pool without rolltime. +- Do not try to clean up twice if kill message is given. +- Only recalculate total_staged in getwork thread if required. +- Include the correct config header in libztex and include it before other +includes. +- Implement a completely new getwork scheduler. Stage all work from the one +thread, making it possible to serialise all requests minimising the number of +getworks requested or local work generated. Use a pthread conditional to wake up +the thread whenever work is removed to generate enough work to stay above the +watermark set by opt_queue. Remove all remnants of the old queueing mechanism, +deleting the now defunct queued count. +- Bugfix: Clean up share hashing and target checks, fixing share difficulty +calculation for above-target would-be-shares +- Use templates from pool_active and longpolls without fetching more +unnecessarily +- Try to avoid requesting GBT jobs when there is already a request in progress +that will likely provide sufficient work +- Reuse most recent GBT job if in get_work_thread if it isn't stale +- libztex: fixed some warnings and removed some whitespaces +- Remove all references to the now unused workio_cmd structure. +- Remove the old workio command queue thread, replacing it with a kill +conditional to exit the program. +- Remove getwork command from workio_cmd queues and do them directly from +queue_request. +- Begin tearing down the old workio command queues by removing submit commands +from there and submit them asynchronously via their own threads. +- driver-ztex: changed two pairs of malloc()/memset() to calloc() +- libztex: Read bitstream file in 2kb blocks with simpler and faster code +- Added the binary versions of ztex_ufm1_15d4.ihx and ztex_ufm1_15y1.ihx +- libztex: Add firmware download support for ZTEX 1.15d and 1.15x +- libztex: Factor out local version of libusb_get_string_descriptor_ascii() +- libztex: Don't return error when a bitstream was already configured +- libztex: Read bitstream file in 64kb blocks with simpler and faster code +- libztex: Verify that the mining firmware is not a dummy firmware +- libztex: Match mining firmware ZTEX descriptor against the dummy firmware +- libztex: Start download sequence only after reading in the new firmware +- libztex: Download mining firmware to all devices with dummy firmware +- Update windows build instructions. +- Set pool probed to true on successful authorisation with stratum to avoid it +being pinged later. +- Style changes. +- Allow pool active to be called on stratum or disabled pools in the watchpool +thread if the pool has not been probed. +- lock (most of) the threaded statistics updates +- README stats don't add up +- Rearrange summary lines and include count of active submissions in progress +- Defer submissions instead of blocking in pop_curl_entry +- Run a single share submission thread asynchronously submitting all shares in +parallel +- Handle share submissions asynchronously, one at a time (still threaded) +- Split up json_rpc_call so it can be used asynchronously in libcurl-multi +- Split submit_upstream_work into _request and _completed stages, pulling out +json_rpc_call +- Bugfix: Adjust USB_* variables to new LIBUSB_* names +- Bugfix: Avoid double-free due to realloc_strcat moving memory around +- Bugfix: Stratum connections might be needed for share submissions up to a +minute after the last time they are used to generate work +- Bugfix: Clean work before trying to generate new stratum work on top of it +- Bugfix: modminer: Get rid of useless usbutils include +- Make need connection return true if a pool is idle. +- New --skip-security-checks option to allow miners to skip checks when it +saves bandwidth +- Skip stratum transaction download when there are no transactions +- API add Best Share to summary +- API lock access to some summary statistics (and copy them) +- Enable backup stratum connections for getwork when the primary pool doesn't +have longpoll aka solo mining. +- Check for correct absence of opt_fail_only in cnx_needed. +- Remove unused variable. +- The specification for stratum has been elaborated to say that a changed diff +applies only to new work so do not retarget when submitting shares. +- Suspend stratum connections to backup pools when there is no requirement to +potentially grab work from them. +- Rename rename_thr to RenameThread to match cgminer +- modminer: Adopt symbolic command names from kanoi +- Make gen_stratum_work more robust by using a dynamically allocated array for +the header in case bogus data is sent by the pool to avoid overflowing a static +array. +- scrypt_diff now returns a uint64_t +- Support monitoring and reporting much higher diffs for scrypt mining, +truncating irrelevant zeroes from displayed hash. +- Pass ostate values around in scrypt to be able to extract full hashes if +needed later on. +- Revert "Handle crash exceptions by trying to restart cgminer unless the +--no-restart option is used." +- Provide helper function realloc_strcat to extend arbitrary length arrays +based on string length. +- Use base_work for comparison just for cleanness in __copy_work +- Remove all static work structs, using the make and free functions. +- Add pool no. to stale share detected message. +- Add info about which pool share became stale while resubmitting. +- Reduce extra slots in the max backlog for ztex to minimise memory waste. +- Get rid of unused last_work in opencl thread data. +- Do away with the flaky free_work api in the driver code which would often lose +the work data in opencl and simply flush it before exiting the opencl scanhash. +- Minor work handling restructure, including moving some stratum data from +fixed-size buffers to their own heap allocations. +- opencl: Use new dev_error function for REASON_DEV_NOSTART +- Provide rudimentary support for the balancing failover strategies with stratum +and GBT by switching pools silently on getwork requests. +- Convert remaining modminer and bfl uses of usleep to nmsleep. +- Convert libztex to nmsleep where possible. +- Convert unreliable usleep calls to nmsleep calls in ztex driver. +- Tidy up device error counts +- Only increase gpu engine speed by a larger step if the temperature is below +hysteresis instead of increasing it to max speed. +- Convert pool not responding and pool alive message on backup pools to verbose +level only since they mean a single failed getwork. +- Use stratum block change from backup pools as an alternative to longpoll for +pools that don't support LP. +- Round some more static string arrays to 4 byte boundaries. +- There is no need for the static arrays to be larger than required, so long as +they're 4 byte aligned to appease ARM. +- Hash1 is only used by the CPU mining code and never changes so remove it from +the work struct and bypass needing to process the value for all other mining. + + +BFGMiner Version 2.9.5 - December 11, 2012 + +- Bugfix: Copy share hash to work->hash before doing 4-byte flip required by +fulltest +- driver-ztex: libztex_setFreq() must be called before ztex_releaseFpga() +- libztex: Make log messages say bitstream when refering to bitstreams +- Increase FD_SETSIZE to 4096 on Windows +- Bugfix: Use AC_PROG_CPP in libusb include subdirectory detection for improved +portability +- Bugfix: Free input memory after prioritising pools in TUI +- Bugfix: Free filename entry for writing config file when done with it +- Bugfix: Free stratum nonce1 before replacing it with new value on reconnect + + +BFGMiner Version 2.9.4 - December 4, 2012 + +- Update libblkmaker to 0.2.1 +- Count template number, and append it to the coinbase of templates without any +cbtxn +- Bugfix: bitforce: Always increment global hw error counter when incrementing +device hwe +- Bugfix: Correct order of printf-style arguments in cbappend fail +- Bugfix: Capitalize "MHz" correctly +- ztex: Correctly release mutex and reset FPGA if configuration fails +- ztex: Harmonize low-speed FPGA configuration code with high-speed code +- libztex: Silence warning: comparison between signed and unsigned +- Count longpoll decodes as queued work since the count otherwise remains +static. +- Bugfix: Assign header-based rolltime before decoding work, so GBT expires +overrides it properly +- Look for libusb_init in -lusb, since FreeBSD has it there +- Bugfix: Use pkgconfig for libusb when available, and try to guess the include +path if not +- Bugfix: FPGA-README: Correct idVendor in example MMQ udev rule +- fixes target calc for mips openwrt +- Bugfix: clear_work: Whether the template is in fact being freed or not, the +work reference to it needs to be +- libztex: Work around ZTEX USB firmware bug exposed by the FreeBSD libusb +- README: Document solo mining usage +- README: Update dependencies +- Bugfix: We should never roll stale work +- Ubuntu: Removing erroneous libssl dep again. GITHUB#94 +- Bugfix: Clear out stratum share work before freeing it +- Provide rudimentary support for literal ipv6 addresses when parsing stratum +URLs. +- Do not attempt to remove the stratum share hash after unsuccessful submission +since it may already be removed by clear_stratum_shares. + + +BFGMiner Version 2.9.3 - November 16, 2012 + +- Bugfix: Properly process new stratum jobs through test_work_current, even if +old shares are still accepted, and copy submit_old flag correctly +- Ensure pdiff 1 is always caught regardless of bdiff precision, and ceil all +other cases to ensure we never lose valid shares +- Check against a double for current pool diff. +- Support for fractional diffs and the classic just-below-1 share all FFs diff +target. +- Check share target diff for best_share to be calculated when solo mining. +- Store the full stratum url information in rpc_url for correct configuration +file saving. +- Put in a hack to prevent dud work from sneaking into test_work_current being +seen as a new block. +- Reset the work->longpoll flag where it will affect stratum work items as +well. +- Bugfix: Stratum does not guarantee notify messages every minute, so extend +timeout to 2 full minutes +- Bugfix: Always honour libblkmaker time limits +- Always (debug)log when stratum template is updated by the pool +- Bugfix: When a stratum connection is interrupted, ensure all work/shares for +it are considered stale +- Bugfix: clear_sock should return on socket errors +- Bugfix: Force calculation of work_difficulty since set_work_target fails to +consider the pdiff1000. +- Get rid of unused warning for !scrypt. +- Use select on stratum send to make sure the socket is writeable. +- Cope with dval being zero in suffix_string and display a single decimal place +when significant digits is not specified but the value is greater than 1000. +- Pad out the suffix string function with zeroes on the right. +- Failure to calloc in bin2hex is a fatal failure always so just check for that +failure within the function and abort, simplifying the rest of the code. +- Provide locking around the change of the stratum curl structures to avoid +possible races. +- Bump opencl kernel version numbers. +- Remove atomic ops from opencl kernels given rarity of more than once nonce on +the same wavefront and the potential increased ramspeed requirements to use the +atomics. +- Clear the pool idle flag in stratum when it comes back to life. +- Display correct share hash and share difficulty with scrypt mining. +- Show work target diff for scrypt mining. +- Watch for buffer overflows on receiving data into the socket buffer. +- Dramatically simplify the dynamic intensity calculation by oversampling many +runs through the opencl kernel till we're likely well within the timer +resolution on windows. +- Align static arrays to 4 byte boundaries to appease ARM builds for stratum. +- Update documentation. +- Left align values that are suffix_string generated. +- Share_diff should not be converting the work data to hex. +- Update readme describing difficulty displayed on log lines. +- Off by one error. +- Prevent overflows of the port char array in extract_sockaddr. +- Disable stratum detection with scrypt. +- Display the actual share diff next to the pool required diff, using a suffix +creation function to prevent values of >1000 being shown in their entirety. +- Fix 4 * 0 being 0 that would break dynamic intensity mode. +- Supplement other 64-bit endian swap macros +- Bugfix: Fix htobe64 on big endian platforms that don't define it +- Fix lack of htobe64 on mingw32. +- Reinstate the history on dynamic intensity mode to damp fluctuations in +intensity but use an upper limit on how much the value can increase at any time +to cope with rare overflows. +- Update to cgminer's newer dynamic intensity algorithm +- Support for the stratum mining protocol. +- Simplify target generation code. +- Add support for client.get_version for stratum. +- Use a 64 bit unsigned integer on the diff target to generate the hex target. +- Update reconnect message to show whole address including port. +- Look for null values and parse correct separate array entries for url and port +with client reconnect commands for stratum. +- The command for stratum is client.reconnect, not mining.reconnect. +- Only copy the stratum url to the rpc url if an rpc url does not exist. +- Implement rudimentary mining.reconnect support for stratum. +- Ignore the value of stratum_active on calling initiate_stratum and assume +we're always trying to reinitiate it, and set the active flag to false in that +function. +- stratum auth can be unset if we fail to authorise on subsequent calls to +auth_stratum which undoes the requirement of setting it in one place so set it +in pool_active. +- Format Stratum submission-start debug the same way as other submissions +- Bugfix: Set work_restart_id in gen_stratum_work for when work is reused to +avoid thinking it's all stale. +- Only auto-switch to Stratum internally, but save HTTP URI in case pool stops +using Stratum; also always shows original pool URI on RPC +- SHUT_RDWR is now always defined for us, so no need to check ifdef on LP hang +- Implement --no-stratum option to disable autodetection +- Show Stratum pools as "Strtm" protocol in "Pool management" TUI +- Bugfix: BFGMiner doesn't use rpc_proxytype +- Remove free that could segfault. +- Use the stratum url as the rpc url advertised if we switch to it. +- Count an invalid nonce count as a hardware error on opencl. +- Count each stratum work item as local work. +- Cope with one stratum pool being the only active pool when it dies by sleeping +for 5 seconds before retrying to get work from it instead of getting work +indefinitely. +- Detect stratum outage based on either select timing out or receiving an empty +buffer and properly re-establish connection by disabling the stratum_active +flag, coping with empty buffers in parse_stratum. +- Fix various modminer warnings on mingw. +- Fix sign warning on windows build for bitforce. +- Cast socketfail to integer since SOCKET is an unsigned int on windows. +- Use the stratum thread to detect when a stratum pool has died based on no +message for 2 minutes. +- Only set the stratum auth flag once and once the stratum thread is started, +use that to set/unset the stratum active flag. +- Only hand off to stratum from getwork if we succeed in initiating the +protocol. +- Target should only be 32 bytes copied. +- Use a static array for work submission data instead of stack memory. +- Clear the buffer data before sprinting to it. +- Clear work stratum strings before setting them and add them to debug output. +- Drop stratum connect failed message to verbose level only since it's a regular +probing message. +- TCP Keepalive in curl is only in very recent versions and not required with +regular messages on stratum anyway. +- Move stratum sockets to curl infrastructure with locking around send+recv to +begin support for proxies and ssl. +- Make detect stratum fail if a proxy has been set up. +- Stratum does not currently have any proxy support so do not try to switch to +stratum if a proxy has been specified. +- Windows doesn't work with MSG_PEEK on recv so move to a continuously updating +buffer for incoming messages. +- Alloca is unreliable on windows so use static arrays in util.c stratum code. +- Begin support for mingw stratum build. +- Add space to reject reason. +- Parse the reject reason where possible from stratum share submission. +- Pass json error value to share result function to be able to parse reject +reason in stratum. +- Don't try to parse unneeded parameters in response to mining.subscribe. +- Remove the sshare hash entry if we failed to send it. +- Change notify message to info level to avoid spamming repeatedly when a pool +is down. +- Check the stratum pool difference has not changed compared to the work diff +when testing whether a share meets the target or not and retarget if necessary. +- Bit error in target calculation for stratum. +- Offset the current block detection to the prev block hash. +- We should be testing for id_val, not id in parse stratum response. +- Make target on stratum scale to any size by clearing sequential bits according +to diff. +- Correct target calculation in gen_stratum_work. +- If a share result has an error code but still has an id, it is likely a +reject, not an error. +- Initiate stratum the first time in pool_active only, allowing us to switch to +it on getting a failed getwork and detecting the presence of stratum on the url +at that time. +- Use 5 second timeout on sock full for now as a temporary workaround. +- If no stratum url is set by the end of the detect stratum routine, copy the +sockaddr url. +- Make all buffers slightly larger to prevent overflow. +- Make the stratum recv buffer larger than the recvsize. +- Userpass needs to be copied to user and pass earlier to allow stratum +authorisation to work with it. +- Store a sockaddr url of the stripped url used in determining sockaddr to not +confuse it with the stratum url and fix build warnings. +- Decrease the queued count with stratum work once it's staged as well. +- Allow the stratum retry to initiate and auth stratum in pool_alive to make +sure the stratum thread is started. +- Avoid duplicating pool->rpc_url and setting pool->stratum_url twice to itself. +- Detect if a getwork based pool has the X-Stratum header on startup, and if so, +switch to the stratum based pool. +- Comment update. +- Minor message change. +- Create a work item from a "clean" request from stratum allowing the new block +to be detected and the appropriate block change message to be given. +- Use statically allocated stratum strings in struct work to cope with the +inability to safely deallocate dynamically allocated ram. +- Use the current pool when deciding whether to reuse work from a stratum source +rather than the work's previous pool. +- Copy the stratum url to the rpc url to avoid none being set. +- Provide locking around stratum send operations to avoid races. +- Submit shares from stratum through the abstracted submit share function +detecting what message they belong to and showing the data from the associated +work, and then deleting it from the hash. +- Use a more robust mechanism to obtain a \n terminated string over a socket. +- Abstract out share submit as a function to be useable by stratum. +- Rename parse_stratum to parse_method as it is only for stratum messages that +contain methods. +- Display stratum as mechanism in status line when current pool is running it. +- Count each stratum notify as a getwork equivalent. +- Correct nonce submitted with share. +- Extranonce2 should be added before coinbase2. +- We should be hashing the binary coinbase, not the hex one. +- Fix endianness of nonce submitted for stratum. +- Check that stratum is already active in initiate_stratum to avoid +de-authorising ourselves by subscribing again. +- Begin implementing a hash database of submissions and attempt sending results. +- Copy parameters from stratum work required for share submission. +- Set lagging flag on first adding a pool to prevent pool slow warning at +startup. +- Fix work->target being a 32 byte binary in gen_stratum_work. +- Store and display stripped url in its own variable. +- Create machinery to divert work requests to stratum. +- Generate the work target in gen_stratum_work, setting default diff to 1 in +case it is not yet set. +- Generate work data, midstate and hash1 in gen_stratum_work. +- Generate header created from stratum structures in gen_stratum_work. +- Generate merkle root hash in gen_stratum_work. +- Generate the coinbase for generation of stratum based work. +- The number of transactions is variable so make merkle a variable length +dynamically allocated array and track how many there are for stratum. +- Rename nonce2 to n2size reflecting that it's a size variable and not the +actual nonce. +- Provide rudimentary support for stratum clean work command in the stratum +thread. +- Cope with pools being removed in the stratum thread. +- Use the pool sock value directly in the stratum thread in case it changes +after reconnecting. +- Create a stratum thread per pool that has stratum that monitors the socket and +serves received data. +- Check return value of stratum_parse. +- Complete authorisation in stratum. +- Implement stratum parsing of notify parameters and storing them in the pool +stratum work structure. +- Create helper functions for duplicating json strings to avoid keeping json +references in use. +- Append \n in the sock_send function instead of adding it when constructing +json in stratum. +- Don't keep any json references around with stratum structures. +- Create parse_stratum function that hands off stratum parameters to other +functions to manage pool stratum work struct variables. Implement mining +difficulty setting. +- Create helper functions for checking when a socket is ready to read on and +receive a single line at a time. Begin stratum authorisation process. +- Provide a helper function for reading a single \n terminated string from a +socket. +- Create a stratum work structure to store current work variables. +- Test specifically for stratum being active in pool_active. +- Detect stratum in common place when adding urls, and use a bool to tell us +when it's active. +- Remove unused add_pool_details5 +- Fix warnings. +- Extract and store various parameters on stratum init confirming successful +mining notify. +- Use existing socket macros and close the socket on failure in init stratum. +- Initiate stratum and grab first json result. +- Get detailed addressinfo from the parsed URL for future raw socket usage when +possible. IPV4 only for now. +- Prepare for getaddrinfo call. +- Add data structures to pool struct for socket communications. +- Put all socket definitions in util.h to allow reusing by added socket +functions to be used in util.c. + + +BFGMiner Version 2.8.3 - October 18, 2012 + +- Update to libblkmaker 0.1.3 +- Use explicit host to BE functions in scrypt code instead of hard coding +byteswap everywhere. +- Ease the checking on allocation of padbuffer8 in the hope it works partially +anyway on an apparently failed call. +- Round target difficulties down to be in keeping with the rounding of detected +share difficulties. +- String alignment to 4 byte boundaries and optimisations for bin<->hex +conversions. +- Fix GPU memory allocation size for scrypt +- Fix access violation with scrypt mining +- Bugfix: Only free rpc_req after using it, not before +- Bugfix: Increment work->pool->staged inside of mutex to avoid work being +freed (and staged decremented) before we dereference it +- Revert "No need for extra variable in hash_push.": The extra variable is +needed to avoid a rare dereference-after-free error. +- In opencl_free_work, make sure to still flush results in dynamic mode. +- Workaround: Debug log only after dec_queued, to make a free/use race more +rare +- Bugfix: Remove redundant \n in debug messages +- Bugfix: Free rpc_req in pool_active and longpolls +- README: Explicitly provide Ubuntu package name for libjansson-dev +- Bugfix: Include flash_led bool in cgpu_info for Icarus-but-not-BitForce +builds, since Cairnsmore uses it +- Only check work block id against pool's if the pool has a known block id +- Avoid clearing pool->block_id unless we really are changing pools + + +BFGMiner Version 2.8.2 - October 8, 2012 + +- Update to libblkmaker 0.1.2 +- Bugfix: --temp-target no longer has a simple default (fixes build without +OpenCL support) +- Bugfix: icarus: Silence false epoll error +- Bugfix: icarus: Set firstrun for errors starting next job, so the current +one finishes properly +- Bugfix: icarus: Restore generic failure management for write errors +- Use strtod not strtol for bitforce temp backup. +- Cope with broken drivers returning nonsense values for bitforce temperatures. +- Minor warning fixes. +- Fix unused warnings on ming build. +- Fix sign warning in ocl.c +- fds need to be zeroed before set in modminer. +- Put scrypt warning on separate line to avoid 0 being shown on windows as +bufsize. +- Prevent corrupt values returned from the opencl code from trying to read +beyond the end of the buffer by masking the value to a max of 15. +- Icarus USB write failure is also a comms error +- api.c DEBUG message has no paramter +- Icarus catch more USB errors and close/reopen the port +- API-README update cgminer verison number +- hashmeter fix stats kh/s on 32bit windows +- cairnsmore: Increase maximum clock frequency to 210 Mhz +- icarus: Hashrate estimates really don't need the attention of a warning, +demote them to debug +- cairnsmore: Automatically "downgrade" default FPGA-per-device to 1 for +dynclock devices +- Bugfix: cairnsmore: Get autodetection of dynclock to work consistently +- cairnsmore: Adjust dynclock usage to react in proper time +- dynclock: Document function usage +- cairnsmore: Fix race on dynclock detection +- icarus: Detect attempts to send commands via work and neuter them +- cairnsmore: Glasswalker has a minimum multiplier of 20 :( +- cairnsmore: Detect frequency changing support despite hashing of commands +- modminer: Allow clocks down to 2 Mhz just in case +- Allow device drivers and users to properly change target temperatures for +non-GPUs +- Check that ncurses*-config installs actually work before deciding to use +them +- Bugfix: Fix multiple bugs in autogen.sh +- - Don't use readlink -f unneccesarily (it's not portable) +- - Always run autoreconf within the real source directory +- - Run configure from PWD, *not* the real source directory +- Bugfix: Include nonce in data buffer for debugging +- Bugfix: swap32* wants count of 32-bit blocks, not bytes +- Initial Cygwin port +- Revert "Remove needless roundl define.", since it is needed for Cygwin and +OpenWRT +- Bugfix: Deal with various compiler warnings +- modminer: Implement --temp-hysteresis logic +- Support for maximum frequency being below the default, eg when the maximum +is temporarily reduced to deal with temperature +- Bugfix: modminer: Reduce dynclock max frequency as needed to keep +temperature below cutoff +- Bugfix: Restore disabled label, needed to skip over hashrate calculations +(which mess up otherwise) +- Bugfix: bitforce: Count actual throttling as hardware errors +- icarus: Allow failure in case of reopen failure, now that the miner core +will retry on its own +- If a device dies, attempt to reinitialize it occasionally +- Bugfix: The REST flag is now preferred over WAIT, since the former might +trigger the latter +- Bugfix: modminer: Update temperature readings when disabled (fixes thermal +cutoff recovery) +- Bugfix: Move thermal cutoff to general watchdog code (fixes bitforce +recovery) +- Rename enable_device to register_device, since it only works for setting it +up at startup +- Move targettemp from ADL to cgpu_info, so all devices can readily use it +- Bugfix: "REST" flag had too much padding +- Bugfix: adl: Only warn and disable GPU due to thermal cutoff, if it's +actually enabled +- Bugfix: bitforce: Only warn and disable bitforce due to thermal cutoff, if +it's actually enabled + + +BFGMiner Version 2.8.1 - September 27, 2012 + +- Avoid strndup for Windows compatibility +- Bugfix: cairnsmore: Add missing compat.h include (for sleep) +- cairnsmore: Implement "identify" for supported firmware +- Adjust identify_device API to return a bool whether supported or not, for +runtime capability detection +- Bugfix: cairnsmore: Fix invalid share detection on LE +- Bugfix: icarus: Fix logging message to not assume "Icarus" always, and use +device driver name +- Bugfix: cairnsmore: Correct frequency scaling detection logic +- cairnsmore: When changing frequency, adjust Hs expectations accordingly +- cairnsmore: Detect availability of frequency scaling, and only enable it +when supported +- cairnsmore: Implement dynamic clocking support for Glasswalker's bitstream +- Update libblkmaker to 0.1.1 +- Advertise BFGMiner in blocks found by default (without --coinbase-sig) +- RPC: Add "Coinbase-Sig" to config/setconfig +- New --coinbase-sig option to add arbitrary data to blocks you generate (GBT +only) +- opencl: Defer nonce validity checking to submit_nonce +- scrypt: Implement test_nonce2 and submit_nonce hw error check +- Bugfix: modminer: Convert nonce to native endian +- Interpret any attempts to submit a H-not-zero nonce as a hardware error +- make-release: Strip DLLs and EXE in Windows binary +- dynclock: Use consistent messages for frequency changes +- modminer: Port to dynclock +- dynclock: Split dynamic clocking algorithm out of Ztex driver +- Bugfix: When changing GPU memclock, adjust internal variable so it is +correctly saved to config file +- Bugfix: Re-probe longpoll header for each pool alive check, including +retries when a preferred protocol fails +- Bugfix: modminer: Bitstream binary filenames are *.bit +- modminer: Start frequency off at 200 Mhz +- Reorder libztex header include order to fix missing struct definition. +- Display share difficulty on log with a shortened hash display on submission. +- API stats add some pool getwork difficulty stats +- Ignore any pings pushed to the worker threads if the thread is still paused to +prevent it being enabled and disabled repeatedly. +- Test for sequential getwork failures on a pool that might actually be up but +failing to deliver work as we may end up hammering it repeatedly by mistake. +- reduce windows compile warnings +- util.c - bug - proxy - no data end condition +- API don't change 'Diff1 Shares' - backward compatability FTW +- miner.php highlighting correctly handling difficulty +- API - Add last share difficulty for devices and pool +- Store and report Accepted,Rejected,Stale difficulty in the summary and API +- WorkTime - display prevblock for scrypt +- api.c remove compile warnings +- Calculate work difficulty for each getwork and display with WorkTime debug +- FPGA - allow long or short device names in detect code + style police +- WorkTime - multiple nonce per work and identify the work source +- Optional WorkTime details with each Accepted/Rejected work item +- Icarus - ignore hardware errors in timing mode +- miner.php oops - mistype +- API pgaidentify - unsupported message should be a warning +- API/BFL identify a device - currently only BFL to flash the led +- BFL add throttle count to internal stats + API +- BFL: missing device id in log message +- Bugfix: ztex: Clear device_ztex before freeing it +- Bugfix: ztex: statline existence depends on whether the libztex structure +exists, not whether the cgpu is enabled +- Bugfix: README: Make usermod commands consistent, including important -a +option +- Bugfix: Address a couple of rare TQ leaks, and improve logging a bit +- Bugfix: Properly quote configure options + + +BFGMiner Version 2.8.0 - September 15, 2012 + +- Be specific about jansson version requirement +- Replace "Alive" in pool status with protocol in use (GBT or GWork) +- Remove copy of old jansson from source repository +- Honour block template expiry (BIP 23 Basic Pool Extensions "expires") +- Add --no-gbt option so getblocktemplate can be disabled if it causes +problems +- BIP 22 long polling +- Properly detect pool protocol +- Bugfix: Sort out work template refcounting by properly using work_free and +new workcpy +- Support for rolling extranonce in templates +- Initial libblkmaker integration, using a git submodule +- cairnsmore: There's no set hashrate like Icarus, so always use short timing +mode by default +- Bugfix: Include unistd.h needed for ssize_t type +- fpgautils: Don't try to scan serial at all anymore, if a device is claimed +- fpgautils: serial_claim function to politely ask other drivers not to try to +use device +- RPC: Update to work with Cairnsmore +- cairnsmore: Windows autodetect using FTDI library +- cairnsmore: Beginnings of new driver, with automatic upgrade from Icarus +detection +- icarus: Support disabling reopen quirk via --icarus-options +- proxy: Replace mess of encoding proxy into pool URI with a --pool-proxy +option, and use cURL's builtin proxy URI support +- save individual pool proxy settings to config +- API-README update for pools proxy info +- CURL support for individual proxy per pool and all proxy types +- Bugfix: Update current_block_id for fixed set_curblock +- miner.php by default don't display IP/Port numbers in error messages +- api.c all STATUS messages automatically escaped +- API add display of and setting queue,scantime,expiry +- README - FPGA device FAQ +- API add device diff1 work +- count device diff1 shares +- API-README update +- api.c Correct diff1 field name +- Bugfix: Sanitize block hash handling (including fixing on big endian) +- Bugfix: Print the (full) correct block hash when warning about work issued +against old blocks +- Bugfix: When comparing current block, only pay attention to the prevblock +header +- Allow mixing user+pass and userpass, so long as user+pass are balanced +before userpass options +- ztex: Include device serial number and FPGA number in cgpu name field +- ztex: Abstract common cgpu_info creation code +- ztex: Do thread initialization in thread_init rather than thread_prepare +- Bugfix: Tolerate working on old blocks when there is only one pool enabled +- Bugfix: ztex: Detect through fpgautils so -S noauto correctly inhibits +autodetection +- ztex: Workaround duplicate share submissions by doubling "backlog" size +- ztex: Use consistent device ids for logging +- Bugfix: ztex: Increment global hw_errors too +- Bugfix: free adhoc string elist element when removing it from list +- Bugfix: icarus: Initialize lret variable after work restart reentry +- Bugfix: ztex: Free lastnonce heap memory if backlog allocation fails +- icarus: Initialize epoll event structure in a way Valgrind is happier with +- Bugfix: Use strtok_r for parse_config since some options use strtok +themselves +- Import strtok_r from gnulib for Windows portability +- Bugfix: ztex: Don't try to destroy a mutex that was never created (single +FPGA Ztex devices) +- ztex: Clean up redundant dereferencing in ztex_shutdown +- API-README more debug parameter information +- API allow full debug settings control +- Sort the blocks database in reverse order, allowing us to remove the first +block without iterating over them. Output the block number to debug. +- Adjust opencl intensity when adjusting thread count to prevent it getting +pegged at a value below the minimum threads possible. +- miner.h max_hashes -> int64_t +- Keep the local block number in the blocks structs stored and sort them by +number to guarantee we delete the oldest when ageing the block struct entries. +- Use correct sdk version detection for SDK 2.7 +- Bugfix: Align Ztex statline properly by removing redundant frequency +- make-release: Convert text files to DOS format for Windows ZIP + + +BFGMiner Version 2.7.5 - August 27, 2012 + +- Revert "Do a complete cgminer restart if the ATI Display Library fails, as +it does on windows after running for some time, when fanspeed reporting +fails." +- Stop special-casing worksize default to 256 for Cypress, since it incurs a 5 +MH/s hit with stock config +- New "--scan-serial all" feature to probe all enumerated serial ports +- modminer: Revamp dynamic clocking algorithm per request from cablepair +- Test for lagging once more in queue_request to enable work to leak to backup +pools. +- There is no need to try to switch pools in select_pool since the current pool +is actually not affected by the choice of pool to get work from. +- Only clear the pool lagging flag if we're staging work faster than we're using +it. +- needed flag is currently always false in queue_request. Remove it for now. +- thr is always NULL going into queue_request now. +- Fix for non-ADL OpenCL device formatting issue + + +BFGMiner Version 2.7.4 - August 23, 2012 + +- Perform select_pool even when not lagging to allow it to switch back if needed +to the primary. +- Simplify macros in output kernels avoiding apparent loops and local variables. +- Carry the needed bool over the work command queue. +- Move the decision to queue further work upstream before threads are spawned +based on fine grained per-pool stats and increment the queued count immediately. +- Track queued and staged per pool once again for future use. +- OpenCL 1.0 does not have native atomic_add and extremely slow support with +atom_add so detect opencl1.0 and use a non-atomic workaround. +- Pools: add RollTime info to API 'stats' and 'Stats' button in miner.php + + +BFGMiner Version 2.7.3 - August 23, 2012 + +- Minimise the number of getwork threads we generate. +- Pick worksize 256 with Cypress if none is specified. +- Give warning with sdk2.7 and phatk as well. +- Whitelist sdk2.7 for diablo kernel as well. +- Only keep the last 6 blocks in the uthash database to keep memory usage +constant. Storing more is unhelpful anyway. +- Increase kernel versions signifying changed APIs. +- BFL flash - more FPGA-README +- Check we haven't staged work while waiting for a curl entry before proceeding. +- Use atomic ops to never miss a nonce on opencl kernels, including nonce==0, +also allowing us to make the output buffer smaller. +- Remove compile errors/warnings and document compile/usage in FPGA-README +- Ignore the submit_fail flag when deciding whether to recruit more curls or not +since we have upper bounds on how many curls can be recruited, this test is +redundant and can lead to problems. +- API-README update cgminer version number +- API-README fix groups P: example mistake +- API-README add COIN and other edits +- miner.php allow 'coin' is custom pages + + +BFGMiner Version 2.7.1 - August 22, 2012 + +- Update windows build instructions courtesy of sharky. +- Increase max curls to number of mining threads + queue * 2, accounting for up +and downstream comms. +- Queue enough requests to get started. +- There is no point trying to clone_work in get_work() any more since we clone +on every get_work_thread where possible. +- There is no point subtracting 1 from maxq in get_work_thread. +- miner.php allow page title to be defined in myminer.php +- Only set lagging flag once there are no staged work items. +- select_pool does not switch back to the primary once lagging is disabled. +- Increment total work counter under mutex lock. +- Increment the queued count after the curl is popped in case there's a delay +waiting on curls and we think we've queued work when in fact we're waiting on +curls. +- Do the dynamic timing in opencl code over a single pass through scanhash to +make sure we're only getting opencl times contributing to the measured +intervals. +- Increase curl reaping time to 5 minutes since comms between curl requests can +be 2 mins apart with lots of rolltime. +- No need for extra variable in hash_push. +- Remove short options -r and -R to allow them to be reused and remove readme +entries for deprecated options. +- Deprecate the opt_fail_pause parameter, leaving a null placeholder for +existing configurations. +- Free work before retrying in get_work_thread. +- Don't pause after failed getwork, set lagging flag and reassess. +- We should not be pausing in trying to resubmit shares. +- Get rid of the extending fail pause on failed connects since we discard work +after a period. +- get_work always returns true so turn it into a void function. +- get_work never returns false so get rid of fail pause loop. +- Get rid of pause and retry from get_upstream_work so we only do it from one +place. +- Remove all cases where --retries aborts BFGMiner, making it for submission +retries only, where it makes sense. + + +BFGMiner Version 2.7.0 - August 21, 2012 + +- Implement a new pool strategy, BALANCE, which monitors work performed per pool +as a rolling average every 10 minutes to try and distribute work evenly over all +the pools. Do this by monitoring diff1 solutions to allow different difficulty +target pools to be treated equally, along with solo mining. Update the +documentation to describe this strategy and more accurately describe the +load-balance one. +- fpga serial I/O extra debug (disabled by default) +- Getwork fail was not being detected. Remove a vast amount of unused variables +and functions used in the old queue request mechanism and redefine the getfail +testing. +- Consider us lagging only once our queue is almost full and no staged work. +- Simplify the enough work algorithm dramatically. +- Only queue from backup pools once we have nothing staged. +- Don't keep queueing work indefinitely if we're in opt failover mode. +- Make sure we don't opt out of queueing more work if all the queued work is +from one pool. +- Set lagging flag if we're on the last of our staged items. +- Reinstate clone on grabbing work. +- Grab clones from hashlist wherever possible first. +- Cull all the early queue requests since we request every time work is popped +now. +- Keep track of staged rollable work item counts to speed up clone_available. +- Make expiry on should_roll to 2/3 time instead of share duration since some +hardware will have very fast share times. +- Check that we'll get 1 shares' worth of work time by rolling before saying we +should roll the work. +- Simplify all those total_secs usages by initialising it to 1 second. +- Overlap queued decrementing with staged incrementing. +- Artificially set the pool lagging flag on pool switch in failover only mode as +well. +- Artificially set the pool lagging flag on work restart to avoid messages about +slow pools after every longpoll. +- Factor in opt_queue value into enough work queued or staged. +- Roll work whenever we can on getwork. +- Queue requests for getwork regardless and test whether we should send for a +getwork from the getwork thread itself. +- Get rid of age_work(). +- Don't try to get bitforce temperature if we're polling for a result to +minimise the chance of interleaved responses. +- Fix harmless unused warnings in scrypt.h. +- Check we are not lagging as well as there is enough work in getwork. + + +BFGMiner Version 2.6.5 - August 20, 2012 + +- API new command 'coin' with mining information +- Add message to share if it's a resubmit. +- Add virtual adl mapping for when none is specified on the command line to +not crash without a map specified. +- Fix ADL gpu-map not working when there are more ADL devices than openCL. +Patch supplied and tested by Nite69. +- bitforce: Initial import of Linux-only bitforce-firmware-flash utility +- Revert stale-on-arrival failsafe, since it ends up needing exceptions for +everything +- Bugfix: opencl: Declare opencl_dynamic_cleanup in header +- Even if we want to submit stale shares, give up if we have more submissions +waiting on threads (even before failing) +- Even if we want to submit stale shares, give up if they've failed and we +have more submissions waiting on threads +- opencl: Use timeBeginPeriod on Windows to ensure gettimeofday has sufficient +precision for dynamic intensity +- Bugfix: opencl: Move ADL fanspeed warning messages to a new thread to get +around summary-update deadlocking +- README: Note that user groups don't get updated until re-login +- Initialise cnt in libztex.c +- Don't try to start devices that don't support scrypt when scrypt mining. +- Repeating on timeout in ztex could make the code never return. +- Offset libusb reads/writes by length written as well in ztex. +- Cope with timeouts and partial reads in ztex code. +- If there are more devices than nDevs, don't iterate over them as they may +overwrite devices mapped below that with the mapping option. +- Fix README faq on bfl auto-detect. +- Set memory clock based on memdiff if present from with engine changes, +allowing it to parallel manual changes from the menu as well. +- api.c typo +- API allow display/change failover-only setting +- API-README corrections +- miner.php documentation (in API-README) v0.1 +- Bugfix: opencl: Show blank device-info statline area if GPU doesn't have +ADL, to fix column alignment +- README: Document usage of 0 to indicate "leave at default" for comma- +delimited GPU options +- Correct API-README versions to match when BFGMiner included them +- API-README update changelog +- Minimise locking and unlocking when getting counts by reusing shared mutex +lock functions. +- Avoid getting more work if by the time the getwork thread is spawned we find +ourselves with enough work. +- The bitforce buffer is cleared and hw error count incremented on return from a +failed send_work already so no need to do it within the send_work function. +- Don't make mandatory work and its clones last forever. +- modminer: Log debug info for nonces found + + +BFGMiner Version 2.6.4 - August 11, 2012 + +- Bugfix: Define my_cancellable_getch in miner.h +- Escape " and \ when writing json config file +- miner.php allow a custom page section to select all fields with '*' - e.g. to +create a STATS section on a custom page +- miner.php optional single rig totals (on by default) +- Bugfix: Initialize submitting mutex +- Bugfix: bitforce: Allocate enough space for FTDI description pointers +- Queue one request for each staged request removed, keeping the staged +request count optimal at all times. +- Bugfix: Avoid cancelling threads while locks are held +- Set recognizable names on threads for debugging +- Bugfix: Don't keep making new get_work threads if all pools are dead +- Enable configuring submission thread limit with --submit-threads option +- Bugfix: Limit active submission threads to 0x40 so we don't overflow +- Bugfix: Properly handle switching to pools that aren't on the latest block, +and warn if a pool actively switches to an old block +- Log more details of reasons in stale_work debug messages +- Failsafe against stale-on-arrival work: disable the pool +- Bugfix: Debug message should show "Work stale due to work restart" when it's +not a share +- windows-build: Remove APP SDK section since it is no longer needed +- modminer: HACK: Let last_work handle the end of the work, and start the next +one immediately +- Bugfix: modminer: Remove erroneous "else" statement, to fix hashrate +reporting +- README: Document user group required for FPGAs on Gentoo and Ubuntu +- BFGMiner-specific README adjustments +- Bugfix: opencl: Ignore error getting device ids from platforms unless they +are explicitly chosen +- New --debuglog option to include debug info in stderr logfile even if not in +the console +- Bumped down debhelper compatibility reqs so that this will build on Lucid. +- Updated to match packaging changes. +- Switched to native packages so we don't have to muck around creating fake +upstream tarballs, and can easily generate minor versions for upload to +Launchpad. +- Removed accidentally included debugging line. +- Minor version bump again because of launchpad. Will sort this out for next +release. +- Updated to patch bitforce module issue on Debian/Ubuntu. +- Added local quilt config dir to ignore. +- modminer: Check nonce against previous work, in case of race +- Bugfix: Enable --kernel-path option if ModMiner or Ztex is enabled (even if +no OpenCL) +- Bugfix: Escape backslashes and double-quotes in strings that rightfully may +have them, when writing JSON config file +- Clean object (.o) and dependency (.d) files out of source tree +- Bugfix: bitforce: Don't count hashes that never happened due to throttling +- Bugfix: Deal with serial_open timeout maximum (25.5s) +- - fpgautils: Linux only supports uint8_t decisecond values for timeouts, so +use uint8_t for timeout value; this gets smart compilers to throw warnings +when overflowed in some cases +- - bitforce: Reduce serial timeout to 25 seconds (was 30) and increase job +long timeout to 25 seconds (was 15) to handle throttling gracefully +- modminer: Add debug info to API extra device stats +- modminer: Raise clock speed when there's only good nonces for a while +- modminer: Only print clock speed adjustments when they actually change +- modminer: Increase tolerance for bad nonces to 2% +- modminer: Reset bad-nonce ratio measurement when the clock speed changes +- Bugfix: bitforce: Include the correct device id in "garbled response" warning +- ADL: Add attribution and disclaimer to interfaces +- Cleaned out refs to AMD SDKs. +- Updated README about debian packaging, changelog with minor version bump to +work around Launchpad reqs. +- Updated changelog with Ubuntu release specific version, needed to build for +multiple releases. Also stripped out ADL SDK stuff in the build rules. +- Initial work to adjust debian packaging from cgminer. Should build correctly +now with pbuilder/pdebuild, and include docs. +- Adapt miner code to free ADL structures +- Import free ADL interfaces +- Include scrypt.h in Makefile. +- Fix windows bitforce build. +- Convert the serial autodetect functions to use int instead of char to +enumerate devices. +- Uglify windows autodetect code for BFL. +- There is no point zeroing temperature in BFL if we fail to get a response, and +we should register it as a HW error, suggesting throttling. +- Update SCRYPT README with information about HW errors. +- Use the scrypt CPU code to confirm results from OCL code, and mark failures as +HW errors, making it easier to tune scrypt parameters. +- We may as well leave one curl still available per pool instead of reaping the +last one. +- Display reaped debug message outside mutex lock to avoid recursive locking. +- api.c update API start message and include port number +- miner.php ignore arg when readonly +- miner.php allow pool inputs: delete, addpool, poolpriority +- bitforce: Reopen on communication error +- Bugfix: Calculate hw err percent for the affected FPGA only +- make-release: Adapt to new autogen by using NOCONFIGURE var + + +BFGMiner Version 2.6.3 - August 6, 2012 + +- modminer: Relax no-nonces downclocking condition to be more reasonable +- README: Update scrypt configure option +- README: Update configure options +- Bugfix: Display --disable-modminer in configure --help now that it is +enabled by default +- Add specific information when ADL detects error -10 saying the device is not +enabled. +- modminer: Shorten upload warning message to fit better +- modminer: Sending a "ping" first, to workaround bug in new firmware betas +- modminer: Include Hardware Errors and Valid Nonces in extra device status +- Bugfix: modminer: Calculate bad-nonce percentage based only on the same +FPGA's hardware errors, accurately +- modminer: Show bitstream upload progress in statline, and only report to log +every 10% +- modminer: Be more verbose about why the clock is getting reduced +- Document how Icarus golden nonce is handled by other FPGAs +- Rewrite should_run for sched, to properly handle one-shot schedules spanning +midnight +- Bugfix: Check list_empty in pop_curl_entry after condition wait +- Bugfix: Only add new pools to array after completing basic structure +initialization +- If __BFGMINER_SEGFAULT_ERRQUIT is set in the environment, segfault on +non-zero quit()s +- Check against NULL pointers getting into curlring +- modminer: Finish a process results run with a nonce poll, rather than sleep +- modminer: Workaround Windows driver failures +- Count likely throttling episodes on bitforce devices as hardware errors. +- Bugfix: bitforce: Increase serial read timeout to 30 seconds during actual +mining, to tolerate more throttling +- Style cleanups. +- Make pool_disabled the first in the enums == 0, fixing the pool enabled count +which compares if value is not enabled before enabling it. +- Correct writing of scrypt parameters to config file based on command line +parameters only. +- Add scrypt support while writing conf +- Use different variables for command line specified lookup gap and thread +concurrency to differentiate user defined versus auto chosen values. +- Queue a request on pool switch in case we have no work from the new pool yet. +- API remove unused warning in non-GPU compile +- api.c in linux allow to open a closed socket in TIME_WAIT +- Display failover only mode in pool menu and allow it to be toggled live. +- Reinstate check for system queueing lag when the current pool's queue is maxed +out, there is no staged work, and the work is needed now. +- Fix harmless warnings. +- Check the current staged and global queued as well before queueing requests. +Discard stales before ageing work in the watchdog thread. Queue requests after +discarding and ageing work in watchdog thread. Display accurate global queued in +curses output. Reuse variable in age_work(). +- The queueing mechanism has become a complex state machine that is no longer +predictable. Rewrite it from scratch watching only current queues in flight and +staged work available on a pool by pool basis. +- Update debian package configs to v2.6.2 +- Queue an extra request whenever staged work drops below mining thread count in +hash_pop. +- Bugfix: Initialize logwin to 1 line high temporarily, to avert PDCurses crash +- Enable FPGA support by default, as long as their dependencies are met +- Bugfix: modminer: Search for *ModMiner* in udev ID_MODEL +- make-release: build with --enable-scrypt +- miner.php support custom report section joins +- ICA default fpga_count to work_division if specified +- FPGA-README document new hidden --icarus-options +- ICA support 57600 baud rate, up to 8 FPGA and partial working FPGA boards +- Scrypt mining does not support block testing yet so don't try to print it. +- Clear the bitforce buffer whenever we get an unexpected result as it has +likely throttled and we are getting cached responses out of order, and use the +temperature monitoring as a kind of watchdog to flush unexpected results. +- It is not critical getting the temperature response in bitforce so don't +mandatorily wait on the mutex lock. +- Check there is a cutoff temp actually set in bitforce before using it as a cut +off value otherwise it may think it's set to zero degrees. +- We dropped the temporary stopping of curl recruiting on submit_fail by +mistake, reinstate it. +- Make threads report in either side of the scanhash function in case we miss +reporting in when restarting work. +- Add debugging output when work is found stale as to why. +- Print the 3 parameters that are passed to applog for a debug line in +bitforce.c +- Clear bitforce buffer on init as previously. +- Add some headroom to the number of curls available per pool to allow for +longpoll and sendwork curls. +- Show the correct base units on GPU summary. +- Bugfix: bitforce: 1 decisecond timeout is unreasonably short, give it a +second +- Bugfix: Don't try to log abandon time, since we aren't keeping track +reasonably +- Import uthash 1.9.6 +- Bugfix: bitforce: Pause after send_work failures +- Fix comm error handling to not consider work restarts an error condition +- comm error bug fix +- Bugfix: No endian.h on Windows +- Remove unused mkinstalldirs +- Display scrypt as being built in as well. +- Fix build warning about KL_SCRYPT when built without scrypt support. +- News update. +- More scrypt intensity information. +- Minor readme updates. +- Update README with more build instructions. +- Remove the low hash count determinant of hardware being sick. A low hash rate +can be for poor network connectivity or scrypt mining, neither of which are due +to sick hardware. +- Style +- API-README poolpriority changes +- api.c verify poolpriority parameters before changing pools +- api.c poolpriority changes +- Implement shared swap32(yes|tole|tobe) function to handle endian flipping +32-bit chunks in blocks +- Use correct macros for endian handling code + + +BFGMiner Version 2.6.1 - July 29, 2012 + +- Autoselect --scrypt iff all pools send scrypt work +- Adapt SCRYPT-README to BFGMiner (directing Bitcoin donations the correct +direction to reach Con) +- Remove mentions of Litecoin specifically +- Bugfix: Fix build without OpenCL but with scrypt +- make-release: Add SCRYPT-README +- Bump version 2.6.0, adding SCRYPT README to makefile. +- Smarter autogen.sh script. +- Sleeping on intensity decrease is broken, remove it. +- Sleep only the extra amount of time we overran the dynamic interval in dynamic +mode. +- Add scrypt documentation in the form of a separate readme. +- Fix build error without scrypt enabled. +- Limit thread concurrency for scrypt to 5xshaders if shaders is specified. +- Simplify repeated use of gpus[gpu]. in ocl.c +- Find the nearest power of 2 maximum alloc size for the scrypt buffer that can +successfully be allocated and is large enough to accomodate the thread +concurrency chosen, thus mapping it to an intensity. +- Don't make opt_scrypt mandatory blocking with opencl code. +- Update kernel versions reflecting changes in the API. +- Make the thread concurrency and lookup gap options hidden on the command line +and autotune parameters with a newly parsed --shaders option. +- Fix target testing with scrypt kernel as it would have been missing shares +below target. +- Always create the largest possible padbuffer for scrypt kernels even if not +needed for thread_concurrency, giving us some headroom for intensity levels. +- Use the detected maximum allocable memory on a GPU to determine the optimal +scrypt settings when lookup_gap and thread_concurrency parameters are not given. +- Check the maximum allocable memory size per opencl device. +- Add debugging output if buffer allocation fails for scrypt and round up +bufsize to a multiple of 256. +- Nonce testing for btc got screwed up, leading to no accepted shares. Fix it. +- Display size of scrypt buffer used in debug. +- Allow intensities up to 20 if scrypt is compiled in. +- Add name to scrypt kernel copyright. +- Allow lookup gap and thread concurrency to be passed per device and store +details in kernel binary filename. +- Ignore negative intensities for scrypt. +- Change the scale of intensity for scrypt kernel and fix a build warning. +- Correct target value passed to scrypt kernel. +- Use 256 output slots for kernels to allow 1 for each worksize. +- Test the target in the actual scrypt kernel itself saving further +calculations. +- Reinstate GPU only opencl device detection. +- Decrease lookup gap to 1. Does not seem to help in any way being 2. +- Fix build. +- Make pad0 and pad1 local variable in scrypt kernel. +- Constify input variable in scrypt kernel. +- Send correct values to scrypt kernel to get it finally working. +- Create command queue before compiling program in opencl. +- Fix external scrypt algo missing. +- Limit scrypt to 1 vector. +- Handle KL_SCRYPT in config write. +- Get rid of stuff. +- Don't enqueuewrite buffer at all for pad8 and pass work details around for +scrypt in dev_blk. +- Set the correct data for cldata and prepare for pad8 fixes. +- Get rid of spaces in arrays in scrypt kernel. +- Start with smaller amount of hashes in cpu mining to enable scrypt to return +today sometime. +- Free the scratchbuf memory allocated in scrypt and don't check if CPUs are +sick since they can't be. Prepare for khash hash rates in display. +- Add cpumining capability for scrypt. +- Set scrypt settings and buffer size in ocl.c code to be future modifiable. +- Cope with when we cannot set intensity low enough to meet dynamic interval by +inducing a forced sleep. +- Make dynamic and scrypt opencl calls blocking. +- Fix nonce submission code for scrypt. +- Make sure goffset is set for scrypt and drop padbuffer8 to something +manageable for now. +- Set up buffer8 for scrypt. +- Build fix for opt scrypt. +- Don't check postcalc nonce with sha256 in scrypt. +- Don't test nonce with sha and various fixes for scrypt. +- Make scrypt buffers and midstate compatible. +- Use specific output array entries in scrypt kernel. +- Provide initial support for the scrypt kernel to compile with and mine scrypt +with the --scrypt option. +- Enable completely compiling scrypt out. +- Begin import of scrypt opencl kernel from reaper. + + BFGMiner Version 2.5.3 - July 29, 2012 - Bugfix: Add zlib1.dll to Win32 release archive @@ -43,13 +6168,9 @@ found notice - miner.php add a socket RCV timeout for if cgminer is hung and the API thread is still running - BFL force all code to timeout to avoid hanging -- Detach pthread from within the api thread in case it is terminated due to not -being instantiated before pthread_cancel is called from main, leading to a -segfault. - Initialise mdplatform. - Find the gpu platform with the most devices and use that if no platform option is passed. -- Allow more platforms to be probed if first does not return GPUs. - Bugfix: It is not a hardware error if nonces returned from modminer don't meet the pool target - bitforce & icarus: Log detection failures at debug log level, so we don't @@ -69,7 +6190,6 @@ better - Simplify code to a single vprintf path for curses-less printing - Move opt_quiet check to my_log_curses, so it works for curses-less builds - Use log_generic for vapplog to cut down on code duplication -- Add space to log output now that there is more screen real estate available. - Bugfix: Copy argv[0] given to dirname() - Find the gpu platform with the most devices and use that if no platform option is passed. @@ -122,8 +6242,6 @@ error API - Revert "Merge branch 'ave_time' of https://github.com/pshep/cgminer.git" - Add average return time to api stats - Missed one nonce-range disabling. -- Remove bitforce_thread_init The delay thing does nothing useful... when long -poll comes around, all threads restart at the same time anyway. - Change timeouts to time-vals for accuracy. - More BFL tweaks. Add delay between closing and reopening port. Remove buffer clear in re-init Add kernel type (mini-rig or single) @@ -161,6 +6279,8 @@ mt_disable function. - Use standard cfsetispeed/cfsetospeed to set baud rate on *nix - miner.php split() flagged deprecated in PHP 5.3.0 - Bugfix: Use nmsleep instead of restart_wait, so we always wait the full time +- Make long timeout 10seconds on bitforce for when usleep or nanosleep just +can't be accurate... BFGMiner Version 2.5.0 - July 7, 2012 @@ -333,7 +6453,6 @@ cards when ADL failed. - modminer: Don't delay 2nd+ FPGAs during work restart - Disable OpenCL code when not available. - Fix openwrt crashing on regeneratehash() by making check_solve a noop. -- FPGA - allow device detect override without an open failure - Fix sign warning. - Bugfix: icarus: properly store/restore info and work end times across longpoll restarts @@ -722,7 +6841,6 @@ kernels. - Add vector type hint to diablo kernel. - Add worksize and vector attribute hints to the poclbm kernel. - Spaces for non-aligned variables in poclbm. -- More tidying of poclbm. - Swap Vals and W variables where they can overlap in poclbm. - More tidying of poclbm. - Tidy up first half of poclbm. diff --git a/README b/README index ea94c6ac3c..4a08446bc0 100644 --- a/README +++ b/README @@ -1,7 +1,9 @@ +BFGMiner: +St. Barbara's Faithfully Glorified Mining Initiative Naturally Exceeding Rivals +or Basically a Freaking Good Miner -This is a multi-threaded multi-pool GPU, FPGA and CPU miner with ATI GPU -monitoring, (over)clocking and fanspeed support for bitcoin and derivative -coins. Do not use on multiple block chains at the same time! +This is a multi-threaded, multi-blockchain, multi-pool ASIC, FPGA, GPU and CPU +miner with dynamic clocking, monitoring, and fanspeed support for bitcoin. This code is provided entirely free of charge by the programmer in his spare time so donations would be greatly appreciated. Please consider donating to the @@ -28,271 +30,396 @@ irc://irc.freenode.net/eligius License: GPLv3. See COPYING for details. -READ EXECUTIVE SUMMARY BELOW FOR FIRST TIME USERS! +SEE ALSO README.ASIC, README.FPGA, README.GPU, README.RPC, AND README.scrypt FOR +MORE INFORMATION ON EACH. + +--- + +EXECUTIVE SUMMARY ON USAGE: + +Single pool: + +bfgminer -o http://pool:port -u username -p password + +Multiple pools: + +bfgminer -o http://pool1:port -u pool1username -p pool1password -o http://pool2:port -u pool2usernmae -p pool2password + +Multiple blockchains: + +bfgminer -o http://pool1:port -u pool1username -p pool1password --pool-goal default -o http://pool2:port -u pool2usernmae -p pool2password --pool-goal freicoin + +Single pool with a standard http proxy: + +bfgminer -o http://pool:port -x http://proxy:port -u username -p password + +Single pool with a socks5 proxy: + +bfgminer -o http://pool:port -x socks5://proxy:port -u username -p password + +The list of proxy types are: + http: standard http 1.1 proxy + socks4: socks4 proxy + socks5: socks5 proxy + socks4a: socks4a proxy + socks5h: socks5 proxy using a hostname + +Proxy support requires cURL version 7.21.7 or newer. + +If you specify the --socks-proxy option to BFGMiner, it will only be applied to +all pools that don't specify their own proxy setting like above + + +After saving configuration from the menu ([S],[W]) you do not need to give +BFGMiner any arguments, it will load your configuration instead. + +Any configuration file may also contain a single + "include" : "filename" +to recursively include another configuration file. +Writing the configuration will save all settings from all files to the output +configuration file. + + +--- +BUILDING BFGMINER + +Everything you probably want, condensed: + build-essential autoconf automake libtool pkg-config libcurl4-gnutls-dev + libjansson-dev uthash-dev libncursesw5-dev libudev-dev libusb-1.0-0-dev + libevent-dev libmicrohttpd-dev libhidapi-dev Dependencies: - curl dev library http://curl.haxx.se/libcurl/ - (libcurl4-openssl-dev) - curses dev library - (libncurses5-dev or libpdcurses on WIN32) - pkg-config http://www.freedesktop.org/wiki/Software/pkg-config - jansson http://www.digip.org/jansson/ - (jansson is included in-tree and not necessary) - yasm 1.0.1+ http://yasm.tortall.net/ - (yasm is optional, gives assembly routines for CPU mining) - AMD APP SDK http://developer.amd.com/sdks/AMDAPPSDK - (This sdk is mandatory for GPU mining) - AMD ADL SDK http://developer.amd.com/sdks/ADLSDK - (This sdk is mandatory for ATI GPU monitoring & clocking) - libudev headers - (This is only required for FPGA auto-detection and is linux only) - libusb headers - (This is only required for ZTEX support) - -BFGMiner specific configuration options: - --enable-cpumining Build with cpu mining support(default disabled) - --disable-opencl Override detection and disable building with opencl - --disable-adl Override detection and disable building with adl - --enable-bitforce Compile support for BitForce FPGAs(default disabled) - --enable-icarus Compile support for Icarus Board(default disabled) - --enable-modminer Compile support for ModMiner FPGAs(default disabled) - --enable-ztex Compile support for Ztex Board(default disabled) + autoconf http://www.gnu.org/software/autoconf/ + automake http://www.gnu.org/software/automake/ + libtool http://www.gnu.org/software/libtool/ + pkg-config http://www.freedesktop.org/wiki/Software/pkg-config + ...or pkgconf https://github.com/pkgconf/pkgconf -Basic *nix build instructions: - To build with GPU mining support: - Install AMD APP sdk, ideal version (see FAQ!) - no official place to - install it so just keep track of where it is if you're not installing - the include files and library files into the system directory. - (Do NOT install the ati amd sdk if you are on nvidia.) - To build with GPU monitoring & clocking support: - Extract the AMD ADL SDK, latest version - there is also no official - place for these files. Copy all the *.h files in the "include" - directory into BFGMiner's ADL_SDK directory. - -The easiest way to install the ATI AMD SPP sdk on linux is to actually put it -into a system location. Then building will be simpler. Download the correct -version for either 32 bit or 64 bit from here: - http://developer.amd.com/sdks/AMDAPPSDK/downloads/Pages/default.aspx - -This will give you a file with a name like AMD-APP-SDK-v2.4-lnx64.tgz - -Then: - -sudo su -cd /opt -tar xf /path/to/AMD-APP-SDK-v2.4-lnx64.tgz -cd / -tar xf /opt/AMD-APP-SDK-v2.4-lnx64/icd-registration.tgz -ln -s /opt/AMD-APP-SDK-v2.4-lnx64/include/CL /usr/include -ln -s /opt/AMD-APP-SDK-v2.4-lnx64/lib/x86_64/* /usr/lib/ -ldconfig - -If you are on 32 bit, x86_64 in the 2nd last line should be x86 - - To actually build: - - ./autogen.sh # only needed if building from git repo - CFLAGS="-O2 -Wall -march=native" ./configure - or if you haven't installed the ati files in system locations: - CFLAGS="-O2 -Wall -march=native -I" LDFLAGS="-L ./configure - make + libcurl4-gnutls-dev http://curl.haxx.se/libcurl/ + + libjansson-dev 2.0+ http://www.digip.org/jansson/ + + uthash-dev 1.9.4+ http://troydhanson.github.io/uthash/ + +Optional Dependencies: + Text-User-Interface (TUI): curses dev library; any one of: + libncurses5-dev http://www.gnu.org/software/ncurses/ (Linux and Mac) + libncursesw5-dev ^ same + libpdcurses http://pdcurses.sourceforge.net/ (Linux/Mac/Windows) + + Multiple ASIC/FPGA autodetection: any one of: + sysfs (built-in to most Linux kernels, just mount on /sys) + libudev-dev http://www.freedesktop.org/software/systemd/libudev/ + + HashBuster Nano & NanoFury USB devices: + libhidapi-dev https://github.com/signal11/hidapi + + getwork server for Block Erupter Blades: + libmicrohttpd-dev 0.9.5+ http://www.gnu.org/software/libmicrohttpd/ - If it finds the opencl files it will inform you with - "OpenCL: FOUND. GPU mining support enabled." - -Basic WIN32 build instructions (LIKELY OUTDATED INFO. requires mingw32): - ./autogen.sh # only needed if building from git repo - rm -f mingw32-config.cache - MINGW32_CFLAGS="-O2 -Wall -msse2" mingw32-configure - make - ./mknsis.sh + Stratum proxy: + libevent 2.0.3+ http://libevent.org/ + + KnCMiner SHA2 miners: + libi2c-dev https://i2c.wiki.kernel.org/index.php/I2C_Tools + + HashBuster Micro, Klondike, X6500 and ZTEX FPGA boards: + libusb-1.0-0-dev http://www.libusb.org/ + + Video card GPU mining (free): + llvm 3.3+ http://llvm.org/ + clang 3.3+ http://clang.llvm.org/ + libclc http://libclc.llvm.org/ + Mesa 9.2.0+ http://www.mesa3d.org/ + libsensors4-dev https://github.com/groeck/lm-sensors + ATi/AMD video card GPU mining (non-free): + AMD APP SDK http://developer.amd.com/tools/heterogeneous-computing/amd-accelerated-parallel-processing-app-sdk/ + + CPU mining optimized assembly algorithms: + yasm 1.0.1+ http://yasm.tortall.net/ + + +BFGMiner driver configuration options: + --disable-other-drivers Build without drivers by default unless explicitly + enabled + --enable-broad-udevrules + Include udev rules for ambiguous devices which may + not be miners + --enable-alchemist Compile support for AlcheMist (default disabled) + --disable-avalon Compile support for Avalon (default enabled) + --disable-avalonmm Compile support for Avalon2/3 (default enabled) + --enable-bfsb Compile support for BFSB (default disabled) + --disable-bfx Compile support for BFx2 (default enabled) + --disable-bifury Compile support for Bi*Fury (default enabled) + --disable-bigpic Compile support for Big Picture Mining USB (default + enabled) + --disable-bitforce Compile support for BitForce (default enabled) + --disable-bitfury Compile support for Bitfury (default enabled) + --enable-bitmain Compile support for Bitmain Antminer S* series + (default disabled) + --disable-cointerra Compile support for CoinTerra (default enabled) + --enable-cpumining Compile support for CPU mining (default disabled) + --disable-drillbit Compile support for DrillBit (default enabled) + --disable-dualminer Compile support for DualMiner (default enabled) + --disable-gridseed Compile support for GridSeed (default enabled) + --disable-hashbuster Compile support for HashBuster Nano (default + enabled) + --disable-hashbusterusb Compile support for HashBuster Micro (default + enabled) + --disable-hashfast Compile support for HashFast (default enabled) + --disable-icarus Compile support for Icarus (default enabled) + --enable-jingtian Compile support for JingTian (default disabled) + --disable-klondike Compile support for Klondike (default enabled) + --enable-knc Compile support for KnC (default disabled) + --enable-kncasic Compile support for KnC gen 2 (default disabled) + --disable-littlefury Compile support for LittleFury (default enabled) + --enable-metabank Compile support for Metabank (default disabled) + --enable-minergate Compile support for Spondoolies minergate interface + (default disabled) + --enable-minion Compile support for Minion (default disabled) + --disable-modminer Compile support for ModMiner (default enabled) + --disable-nanofury Compile support for NanoFury (default enabled) + --enable-opencl Compile support for OpenCL (default disabled) + --disable-adl Build without ADL monitoring (default enabled) + --disable-rockminer Compile support for RockMiner (default enabled) + --enable-titan Compile support for KnC Titan (default disabled) + --disable-twinfury Compile support for Twinfury (default enabled) + --disable-x6500 Compile support for X6500 (default enabled) + --disable-zeusminer Compile support for ZeusMiner (default enabled) + --disable-ztex Compile support for ZTEX (default enabled) + +BFGMiner algorithm configuration option: + --enable-keccak Compile support for Keccak (default disabled) + --disable-sha256d Compile support for SHA256d (default enabled) + --enable-scrypt Compile support for scrypt (default disabled) + +BFGMiner dependency configuration options: + --without-curses Compile support for curses TUI (default enabled) + --without-libevent Compile support for libevent stratum server (default + enabled) + --without-libmicrohttpd Compile support for libmicrohttpd getwork server + (default enabled) + --without-libudev Autodetect FPGAs using libudev (default enabled) + --without-libusb Compile using libusb (default enabled) + --without-sensors Build with libsensors monitoring (default enabled) + --without-system-libbase58 + Use bundled libbase58 rather than system one + --with-system-libblkmaker + Use system libblkmaker rather than bundled one + (default disabled) + --with-udevrulesdir=DIR Install udev rules into this directory + --with-udevrules-group=groupname + Configure mining devices to be owned by a specific + group (default `video') + --without-uio Compile support for PCI devices via Linux UIO + interface (default enabled) + --without-vfio Compile support for PCI devices via Linux VFIO + interface (default enabled) + +Basic *nix build instructions: + +./autogen.sh # only needed if building from git repo +./configure # list configuration options here +make + +No installation is necessary. You may run BFGMiner from the build directory +directly. + +On Mac OS X, you can use Homebrew to install the dependency libraries. When you +are ready to build BFGMiner, you may need to point the configure script at one +or more pkg-config paths. For example: + ./configure PKG_CONFIG_PATH=/usr/local/opt/curl/lib/pkgconfig:/usr/local/opt/jansson/lib/pkgconfig + Native WIN32 build instructions: see windows-build.txt +If you build BFGMiner from source, it is recommended that you run it from the +build directory. On *nix, you will usually need to prepend your command with a +path like this (if you are in the bfgminer directory already): ./bfgminer +To install system wide run 'sudo make install' or 'make install' as root. You +can then run from any terminal. + --- Usage instructions: Run "bfgminer --help" to see options: -Usage: . [-atDdGCgIKklmpPQqrRsTouvwOchnV] +Usage: bfgminer [-DdElmpPQqUsTouOchnV] + Options for both config file and command line: --api-allow Allow API access (if enabled) only to the given list of [W:]IP[/Prefix] address[/subnets] This overrides --api-network and you must specify 127.0.0.1 if it is required W: in front of the IP address gives that address privileged access to all api commands --api-description Description placed in the API status header (default: BFGMiner version) --api-groups API one letter groups G:cmd:cmd[,P:cmd:*...] - See API-README for usage + See README.RPC for usage --api-listen Listen for API requests (default: disabled) By default any command that does not just display data returns access denied See --api-allow to overcome this +--api-mcast Enable API Multicast listener, default: disabled +--api-mcast-addr API Multicast listen address (default: "224.0.0.75") +--api-mcast-code Code expected in the API Multicast message, don't use '-' (default: "FTW") +--api-mcast-des Description appended to the API Multicast reply, default: '' +--api-mcast-port API Multicast listen port (default: 4028) --api-network Allow API (if enabled) to listen on/for any address (default: only 127.0.0.1) --api-port Port number of miner API (default: 4028) +--balance Change multipool strategy from failover to even share balance --benchmark Run BFGMiner in benchmark mode - produces no shares +--benchmark-intense Run BFGMiner in intensive benchmark mode - produces no shares +--chroot-dir Chroot to a directory right after startup +--cmd-idle Execute a command when a device is allowed to be idle (rest or wait) +--cmd-sick Execute a command when a device is declared sick +--cmd-dead Execute a command when a device is declared dead +--coinbase-check-addr A list of address to check against in coinbase payout list received from the previous-defined pool, separated by ',' +--coinbase-check-total The least total payout amount expected in coinbase received from the previous-defined pool +--coinbase-check-percent The least benefit percentage expected for the sum of addr(s) listed in --cbaddr argument for previous-defined pool +--coinbase-sig Set coinbase signature when possible +--compact Use compact display without per device statistics --debug|-D Enable debug output ---expiry|-E Upper bound on how many seconds after getting work we consider a share from it stale (default: 120) +--debuglog Enable debug logging +--device-protocol-dump Verbose dump of device protocol-level activities +--device|-d Enable only devices matching pattern (default: all) +--disable-rejecting Automatically disable pools that continually reject shares +--http-port Port number to listen on for HTTP getwork miners (-1 means disabled) (default: -1) +--expiry Upper bound on how many seconds after getting work we consider a share from it stale (w/o longpoll active) (default: 120) +--expiry-lp Upper bound on how many seconds after getting work we consider a share from it stale (with longpoll active) (default: 3600) --failover-only Don't leak work to backup pools when primary pool is lagging ---kernel-path|-K Specify a path to where bitstream and kernel files are (default: "/usr/local/bin") ---load-balance Change multipool strategy from failover to even load balance ---log|-l Interval in seconds between log output (default: 5) +--failover-switch-delay Delay in seconds before switching back to a failed pool (default: 300) +--generate-to Set an address to generate to for solo mining +--force-dev-init Always initialize devices when possible (such as bitstream uploads to some FPGAs) +--kernel-path Specify a path to where bitstream and kernel files are +--load-balance Change multipool strategy from failover to quota based balance +--log|-l Interval in seconds between log output (default: 20) +--log-file|-L Append log file for output messages +--log-microseconds Include microseconds in log output --monitor|-m Use custom pipe cmd for output messages ---net-delay Impose small delays in networking to not overload slow routers +--net-delay Impose small delays in networking to avoid overloading slow routers +--no-gbt Disable getblocktemplate support +--no-getwork Disable getwork support +--no-hotplug Disable hotplug detection +--no-local-bitcoin Disable adding pools for local bitcoin RPC servers --no-longpoll Disable X-Long-Polling support ---no-pool-disable Do not automatically disable pools that continually reject shares +--no-pool-redirect Ignore pool requests to redirect to another server +--no-restart Do not attempt to restart devices that hang +--no-stratum Disable Stratum detection --no-submit-stale Don't submit shares if they are detected as stale +--no-unicode Don't use Unicode characters in TUI +--noncelog Create log of all nonces found --pass|-p Password for bitcoin JSON-RPC server --per-device-stats Force verbose mode and output per-device statistics +--pool-goal Named goal for the previous-defined pool +--pool-priority Priority for just the previous-defined pool +--pool-proxy|-x Proxy URI to use for connecting to just the previous-defined pool --protocol-dump|-P Verbose dump of protocol-level activities --queue|-Q Minimum number of work items to have queued (0 - 10) (default: 1) --quiet|-q Disable logging output, display status and errors +--quit-summary Summary printed when you quit: none/devs/procs/detailed +--quota|-U quota;URL combination for server with load-balance strategy quotas --real-quiet Disable all output ---remove-disabled Remove disabled devices entirely, as if they didn't exist ---retries|-r Number of times to retry before giving up, if JSON-RPC call fails (-1 means never) (default: -1) ---retry-pause|-R Number of seconds to pause, between retries (default: 5) +--request-diff Request a specific difficulty from pools (default: 1.0) +--retries Number of times to retry failed submissions before giving up (-1 means never) (default: -1) --rotate Change multipool strategy from failover to regularly rotate at N minutes (default: 0) --round-robin Change multipool strategy from failover to round robin on failure ---scan-time|-s Upper bound on time spent scanning current work, in seconds (default: 60) +--scan|-S Configure how to scan for mining devices +--scan-time Upper bound on time spent scanning current work, in seconds (default: 60) --sched-start Set a time of day in HH:MM to start mining (a once off without a stop time) --sched-stop Set a time of day in HH:MM to stop mining (will quit without a start time) +--scrypt Use the scrypt algorithm for mining (non-bitcoin) +--set-device|--set Set default parameters on devices; eg, NFY:osc6_bits=50, bfl:voltage=, compac:clock= +--setuid Username of an unprivileged user to run as --sharelog Append share log to file ---shares Quit after mining N shares (default: unlimited) ---socks-proxy Set socks4 proxy (host:port) +--shares Quit after mining 2^32 * N hashes worth of shares (default: unlimited) +--show-processors Show per processor statistics in summary +--skip-security-checks Skip security checks sometimes to save bandwidth; only check 1/th of the time (default: never skip) +--socks-proxy Set socks proxy (host:port) for all pools without a proxy specified +--stratum-port Port number to listen on for stratum miners (-1 means disabled) (default: -1) +--submit-threads Minimum number of concurrent share submissions (default: 64) --syslog Use system log for output messages (default: standard error) ---temp-cutoff Temperature where a device will be automatically disabled, one value or comma separated list (default: 95) +--temp-hysteresis Set how much the temperature can fluctuate outside limits when automanaging speeds (default: 3) --text-only|-T Disable ncurses formatted screen output +--unicode Use Unicode characters in TUI --url|-o URL for bitcoin JSON-RPC server --user|-u Username for bitcoin JSON-RPC server --verbose Log verbose output to stderr as well as status output +--weighed-stats Display statistics weighed to difficulty 1 --userpass|-O Username:Password pair for bitcoin JSON-RPC server +--worktime Display extra work time debug information Options for command line only: --config|-c Load a JSON-format configuration file See example.conf for an example configuration. +--no-default-config Inhibit loading default config file +--default-config Always load the default config file --help|-h Print this message --version|-V Display version and exit GPU only options: ---auto-fan Automatically adjust all GPU fan speeds to maintain a target temperature ---auto-gpu Automatically adjust all GPU engine clock speeds to maintain a target temperature ---device|-d Select device to use, (Use repeat -d for multiple devices, default: all) ---disable-gpu|-G Disable GPU mining even if suitable devices exist ---gpu-threads|-g Number of threads per GPU (1 - 10) (default: 2) ---gpu-dyninterval Set the refresh interval in ms for GPUs using dynamic intensity (default: 7) ---gpu-engine GPU engine (over)clock range in Mhz - one value, range and/or comma separated list (e.g. 850-900,900,750-850) ---gpu-fan GPU fan percentage range - one value, range and/or comma separated list (e.g. 25-85,85,65) --gpu-map Map OpenCL to ADL device order manually, paired CSV (e.g. 1:0,2:1 maps OpenCL 1 to ADL 0, 2 to 1) ---gpu-memclock Set the GPU memory (over)clock in Mhz - one value for all or separate by commas for per card. ---gpu-memdiff Set a fixed difference in clock speed between the GPU and memory in auto-gpu mode --gpu-platform Select OpenCL platform ID to use for GPU mining ---gpu-powertune Set the GPU powertune percentage - one value for all or separate by commas for per card. --gpu-reorder Attempt to reorder GPU devices according to PCI Bus ID ---gpu-vddc Set the GPU voltage in Volts - one value for all or separate by commas for per card. ---intensity|-I Intensity of GPU scanning (d or -10 -> 10, default: d to maintain desktop interactivity) ---kernel|-k Override kernel to use (diablo, poclbm, phatk or diakgcn) - one value or comma separated ---ndevs|-n Enumerate number of detected GPUs and exit --no-adl Disable the ATI display library used for monitoring and setting GPU parameters ---no-restart Do not attempt to restart GPUs that hang ---temp-hysteresis Set how much the temperature can fluctuate outside limits when automanaging speeds (default: 3) ---temp-overheat Overheat temperature when automatically managing fan and GPU speeds (default: 85) ---temp-target Target temperature when automatically managing fan and GPU speeds (default: 75) ---vectors|-v Override detected optimal vector (1, 2 or 4) - one value or comma separated list ---worksize|-w Override detected optimal worksize - one value or comma separated list +GPU mining is disabled by default for SHA256d if you have any dedicated mining +devices, but can be enabled explicitly specifying the -S opencl:auto option. -FPGA mining boards(BitForce, Icarus, ModMiner, Ztex) only options: +See README.GPU for more information regarding GPU mining. +See README.scrypt for more information regarding (non-bitcoin) scrypt mining. ---scan-serial|-S Serial port to probe for FPGA mining device -This option is only for BitForce, Icarus, and/or ModMiner FPGAs +To use ASICs or FPGAs, you will need to be sure the user BFGMiner is running as +has appropriate permissions. This varies by operating system. +On Linux, with BFGMiner's udev rules: sudo usermod -a -G video +Note that on GNU/Linux systems, you will usually need to login again before +group changes take effect. -By default, BFGMiner will scan for autodetected FPGAs unless at least one --S is specified for that driver. If you specify -S and still want BFGMiner -to scan, you must also use "-S auto". If you want to prevent BFGMiner from -scanning without specifying a device, you can use "-S noauto". Note that -presently, autodetection only works on Linux, and might only detect one -device depending on the version of udev being used. +By default, BFGMiner will scan for autodetected devices. If you want to prevent +BFGMiner from doing this, you can use "-S noauto". If you want to probe all +serial ports, you can use "-S all"; note that this may write data to non-mining +devices which may then behave in unexpected ways! -On linux is usually of the format /dev/ttyUSBn -On windows is usually of the format \\.\COMn -(where n = the correct device number for the FPGA device) +On Linux, is usually of the format /dev/ttyUSBn +On Mac OS X, is usually of the format /dev/cu.usb* +On Windows, is usually of the format \\.\COMn +(where n = the correct device number for the device) -The official supplied binaries are compiled with support for all FPGAs. +The official supplied binaries are compiled with support for all ASICs/FPGAs. To force the code to only attempt detection with a specific driver, -prepend the argument with the driver name followed by a colon. -For example, "icarus:/dev/ttyUSB0" or "bitforce:\\.\COM5" +prepend the argument with the driver name followed by an "at" symbol. +For example, "icarus@/dev/ttyUSB0" or "bitforce@\\.\COM5" +or using the short name: "ica@/dev/ttyUSB0" or "bfl@\\.\COM5" -For other FPGA details see the FPGA-README - - -CPU only options (not included in binaries): - ---algo|-a Specify sha256 implementation for CPU mining: - auto Benchmark at startup and pick fastest algorithm - c Linux kernel sha256, implemented in C - 4way tcatm's 4-way SSE2 implementation - via VIA padlock implementation - cryptopp Crypto++ C/C++ implementation - sse2_64 SSE2 64 bit implementation for x86_64 machines - sse4_64 SSE4.1 64 bit implementation for x86_64 machines (default: sse2_64) ---cpu-threads|-t Number of miner CPU threads (default: 4) ---enable-cpu|-C Enable CPU mining with other mining (default: no CPU mining if other devices exist) +Some FPGAs do not have non-volatile storage for their bitstreams and must be +programmed every power cycle, including first use. To use these devices, you +must download the proper bitstream from the vendor's website and copy it to the +"bitstreams" directory into your BFGMiner application directory. +See README.ASIC and README.FPGA for more information regarding these. +See README.CPU for information regarding CPU mining. --- -EXECUTIVE SUMMARY ON USAGE: - -After saving configuration from the menu, you do not need to give BFGMiner any -arguments and it will load your configuration. - -Any configuration file may also contain a single - "include" : "filename" -to recursively include another configuration file. -Writing the configuration will save all settings from all files in the output. - - -Single pool, regular desktop: - -bfgminer -o http://pool:port -u username -p password - -Single pool, dedicated miner: - -bfgminer -o http://pool:port -u username -p password -I 9 - -Single pool, first card regular desktop, 3 other dedicated cards: - -bfgminer -o http://pool:port -u username -p password -I d,9,9,9 - -Multiple pool, dedicated miner: - -bfgminer -o http://pool1:port -u pool1username -p pool1password -o http://pool2:port -u pool2usernmae -p pool2password -I 9 - -Add overclocking settings, GPU and fan control for all cards: - -bfgminer -o http://pool:port -u username -p password -I 9 --auto-fan --auto-gpu --gpu-engine 750-950 --gpu-memclock 300 - -Add overclocking settings, GPU and fan control with different engine settings for 4 cards: - -bfgminer -o http://pool:port -u username -p password -I 9 --auto-fan --auto-gpu --gpu-engine 750-950,945,700-930,960 --gpu-memclock 300 - -READ WARNINGS AND DOCUMENTATION BELOW ABOUT OVERCLOCKING +WHILE RUNNING: -On Linux you virtually always need to export your display settings before -starting to get all the cards recognised and/or temperature+clocking working: +The following options are available while running with a single keypress: -export DISPLAY=:0 +[M]anage devices [P]ool management [S]ettings [D]isplay options [H]elp [Q]uit ---- +M gives you something like: -WHILE RUNNING: +Select processor to manage using up/down arrow keys + BFL 0a: 78.0C | 3.64/ 3.70/ 2.91Gh/s | A:46 R:0+0(none) HW: 2/none + BitFORCE SHA256 SC from Butterfly Labs +Serial: FTWN6T67 -The following options are available while running with a single keypress: +[D]isable +Or press Enter when done -[P]ool management [G]PU management [S]ettings [D]isplay options [Q]uit P gives you: Current pool management strategy: Failover +[F]ailover only disabled [A]dd pool [R]emove pool [D]isable pool [E]nable pool [C]hange management strategy [S]witch pool [I]nformation @@ -304,85 +431,101 @@ S gives you: [S]cantime: 60 [E]xpiry: 120 [R]etries: -1 -[P]ause: 5 [W]rite config file +[B]FGMiner restart D gives you: -Toggle: [D]ebug [N]ormal [S]ilent [V]erbose [R]PC debug -[L]og interval [C]lear +[N]ormal [C]lear [S]ilent mode (disable all output) +[D]ebug:off +[P]er-device:off +[Q]uiet:off +[V]erbose:off +[R]PC debug:off +[W]orkTime details:off +co[M]pact: off +[L]og interval:5 Q quits the application. -G gives you something like: +The running log shows output similar to that below: -GPU 0: [124.2 / 191.3 Mh/s] [Q:212 A:77 R:33 HW:0 E:36% U:1.73/m] -Temp: 67.0 C -Fan Speed: 35% (2500 RPM) -Engine Clock: 960 MHz -Memory Clock: 480 Mhz -Vddc: 1.200 V -Activity: 93% -Powertune: 0% -Last initialised: [2011-09-06 12:03:56] -Thread 0: 62.4 Mh/s Enabled ALIVE -Thread 1: 60.2 Mh/s Enabled ALIVE - -[E]nable [D]isable [R]estart GPU [C]hange settings -Or press any other key to continue + [2013-02-13 00:26:30] Accepted 1758e8df BFL 0 pool 0 Diff 10/1 + [2013-02-13 00:26:32] Accepted 1d9a2199 MMQ 0a pool 0 Diff 8/1 + [2013-02-13 00:26:33] Accepted b1304924 ZTX 0 pool 0 Diff 1/1 + [2013-02-13 00:26:33] Accepted c3ad22f4 XBS 0b pool 0 Diff 1/1 +The 8 byte hex value are the 2nd set of 32 bits from the share submitted to the +pool. The 2 diff values are the actual difficulty target that share reached +followed by the difficulty target the pool is currently asking for. --- -Also many issues and FAQs are covered in the forum thread +Also many issues and FAQs are covered in the forum threads dedicated to this program, - http://forum.bitcoin.org/index.php?topic=28402.0 + https://bitcointalk.org/?topic=78192 + https://bitcointalk.org/?topic=168174 -The output line shows the following: -5s:1713.6 avg:1707.8 u:1710.2 Mh/s | A:729 R:8 HW:0 E:242% U:22.53/m +If you are mining on a single pool, the pool display shows: + Pool 0: ...s.m.eligius.st Diff:16 +Strtm LU:[03:26:16] User:1QATWksNFGeUJCWBrN4g6hGM178Lovm7Wh -Each column is as follows: -5s: A 5 second exponentially decaying average hash rate -avg: An all time average hash rate -u: An all time average hash rate based on actual accepted shares -A: The number of Accepted shares -R: The number of Rejected shares -HW: The number of HardWare errors -E: The Efficiency defined as number of shares returned / work item -U: The Utility defined as the number of shares / minute +This tells you which pool you're using, as well as its current share difficulty, +protocol, and last explicit work update. If BFGMiner has a working block +notification source, the protocol will be prefixed by a plus sign. If not, a +minus sign. - GPU 1: 73.5C 2551RPM | 427.3/443.0/442.1Mh/s | A:8 R:0 HW:0 U:4.39/m +If you are mining on multiple pools at once, the pool display instead shows: + Pools: 2 (0,1) Diff:4-16 + LU:[03:25:30] -Each column is as follows: -Temperature (if supported) -Fanspeed (if supported) -A 5 second exponentially decaying average hash rate -An all time average hash rate -An all time average hash rate based on actual accepted shares -The number of accepted shares -The number of rejected shares -The number of hardware erorrs -The utility defines as the number of shares / minute +You get the total number of working pools, the pool numbers for each of those, +the range of current share difficulties, whether block notification is working +(plus/minus), and the oldest explicit work update currently being used for new +work. + +The block display shows: +Block #217364: ...1b89f8d3 Diff:7.67M (54.93T) Started: [17:17:22] I:12.99mBTC/hr + +This shows a short stretch of the next block's height, the current block, +difficulty (including the network hashrate that difficulty represents), when the +search for the new block started, and finally expected Income, calculated by +actual shares submitted in 100% PPS value (assumes Bitcoin, does not account for +altcoin conversions!). The BFGMiner status line shows: - TQ: 1 ST: 1 SS: 0 DW: 0 NB: 1 GW: 301 LW: 8 GF: 1 RF: 1 + ST:1 F:0 NB:1 AS:0 BW:[ 75/241 B/s] E:2.42 BS:2.71k -TQ is Total Queued work items. ST is STaged work items (ready to use). -SS is Stale Shares discarded (detected and not submitted so don't count as rejects) -DW is Discarded Work items (work from block no longer valid to work on) +F is network Failure occasions (server down or slow to provide work) NB is New Blocks detected on the network -GW is GetWork requested (work items from pools) -LW is Locally generated Work items -GF is Getwork Fail Occasions (server slow to provide work) -RF is Remote Fail occasions (server slow to accept work) +AS is Active Submissions (shares in the process of submitting) +BW is BandWidth usage on the network (received/sent) +E is Efficiency defined as number of shares accepted (multiplied by their + difficulty) per 2 KB of bandwidth +BS is the all time Best Share difficulty you've found + +The totals line shows the following: + 6/32 75.0C | 171.3/170.8/171.2Gh/s | A:729 R:8+0(.01%) HW:0/.81% + +Each column is as follows: + The number of devices and processors currently mining + Hottest temperature reported by any processor + 20 second exponentially decaying average hash rate (configurable with --log + option) + An all time average hash rate + An all time average hash rate based on actual nonces found, adjusted for pool + reject and stale rate + The number of Accepted shares + The number of Rejected shares and stale shares discarded (never submitted), + and the percentage these are of total found. + The number of HardWare errors, and percentage invalid of nonces returned + +Each device shows: + BFL 2: 74.0C | 51.97/58.90/57.17Gh/s | A:847 R:15+0(.54%) HW:496/.91% + +Columns are the same as in the totals line. -NOTE: Running intensities above 9 with current hardware is likely to only -diminish return performance even if the hash rate might appear better. A good -starting baseline intensity to try on dedicated miners is 9. Higher values are -there to cope with future improvements in hardware. --- MULTIPOOL @@ -407,8 +550,108 @@ This strategy moves at user-defined intervals from one active pool to the next, skipping pools that are idle. LOAD BALANCE: -This strategy sends work in equal amounts to all the pools specified. If any -pool falls idle, the rest will take up the slack keeping the miner busy. +This strategy sends work to all the pools on a quota basis. By default, all +pools are allocated equal quotas unless specified with --quota. This +apportioning of work is based on work handed out, not shares returned so is +independent of difficulty targets or rejected shares. While a pool is disabled +or dead, its quota is dropped until it is re-enabled. Quotas are forward +looking, so if the quota is changed on the fly, it only affects future work. +If all pools are set to zero quota or all pools with quota are dead, it will +fall back to a failover mode. See quota below for more information. + +The failover-only flag has special meaning in combination with load-balance +mode and it will distribute quota back to priority pool 0 from any pools that +are unable to provide work for any reason so as to maintain quota ratios +between the rest of the pools. + +BALANCE: +This strategy monitors the amount of difficulty 1 shares solved for each pool +and uses it as a basis for trying to doing the same amount of work for each +pool. + + +--- +SOLO MINING + +BFGMiner supports solo mining with any GBT-compatible bitcoin node (such as +bitcoind). To use this mode, you need to specify the URL of your bitcoind node +using the usual pool options (--url, --userpass, etc), and the --generate-to +option to specify the Bitcoin address you wish to receive the block rewards +mined. When you run Bitcoin Core on the same computer as your miner, the pool +itself will be automatically configured for you (on the default goal). Please be +aware that solo mining via GBT is at this time only supported for Bitcoin. + +IMPORTANT: If you are solo mining with more than one instance of BFGMiner (or +any other software) per payout address, you must also specify data using the +--coinbase-sig option to ensure each miner is working on unique work. Note +that this data will be publicly seen if your miner finds a block using any +GBT-enabled pool, even when not solo mining (such as failover). + +If your bitcoin node does not support longpolling (for example, bitcoind 0.8.x), +you should consider setting up a failover pool to provide you with block +notifications. Note that solo mining does not use shares, so BFGMiner's adjusted +hashrate (third column) may suddenly drop to zero if a block you submit is +rejected; this does not indicate that it has stopped mining. + +Example solo mining usage: + +bfgminer -o http://localhost:8332 -u username -p password \ + --generate-to 1QATWksNFGeUJCWBrN4g6hGM178Lovm7Wh \ + --coinbase-sig "rig1: This is Joe's block!" + +If you want to solo mine on multiple GBT-compatible Bitcoin blockchains, you can +specify --generate-to multiple times with a goal name prefix followed by a +colon. Note that at this time, the coinbase sig is always shared across all +goals/pools. + +Example multi-blockchain solo mining usage: + +bfgminer -o http://localhost:8332 -u username -p password \ + --generate-to 1QATWksNFGeUJCWBrN4g6hGM178Lovm7Wh \ + -o http://localhost:7221 -u user2 -p password --pool-goal mychain \ + --generate-to mychain:1QATWksNFGeUJCWBrN4g6hGM178Lovm7Wh \ + --coinbase-sig "rig1: This is Joe's block!" + + +--- +QUOTAS + +The load-balance multipool strategy works off a quota based scheduler. The +quotas handed out by default are equal, but the user is allowed to specify any +arbitrary ratio of quotas. For example, if all the quota values add up to 100, +each quota value will be a percentage, but if 2 pools are specified and pool0 +is given a quota of 1 and pool1 is given a quota of 9, pool0 will get 10% of +the work and pool1 will get 90%. Quotas can be changed on the fly with RPC, +and do not act retrospectively. Setting a quota to zero will effectively +disable that pool unless all other pools are disabled or dead. In that +scenario, load-balance falls back to regular failover priority-based strategy. +While a pool is dead, it loses its quota and no attempt is made to catch up +when it comes back to life. + +To specify quotas on the command line, pools should be specified with a +semicolon separated --quota(or -U) entry instead of --url. Pools specified with +--url are given a nominal quota value of 1 and entries can be mixed. + +For example: +--url poolA:portA -u usernameA -p passA --quota "2;poolB:portB" -u usernameB -p passB +Will give poolA 1/3 of the work and poolB 2/3 of the work. + +Writing configuration files with quotas is likewise supported. To use the above +quotas in a configuration file they would be specified thus: + +"pools" : [ + { + "url" : "poolA:portA", + "user" : "usernameA", + "pass" : "passA" + }, + { + "quota" : "2;poolB:portB", + "user" : "usernameB", + "pass" : "passB" + } +] + --- LOGGING @@ -427,6 +670,27 @@ it will log to a file called logfile.txt and otherwise work the same. There is also the -m option on linux which will spawn a command of your choice and pipe the output directly to that command. +The WorkTime details 'debug' option adds details on the end of each line +displayed for Accepted or Rejected work done. An example would be: + + <-00000059.ed4834a3 M:X D:1.0 G:17:02:38:0.405 C:1.855 (2.995) W:3.440 (0.000) S:0.461 R:17:02:47 + +The first 2 hex codes are the previous block hash, the rest are reported in +seconds unless stated otherwise: +The previous hash is followed by the getwork mode used M:X where X is one of +P:Pool, T:Test Pool, L:LP or B:Benchmark, +then D:d.ddd is the difficulty required to get a share from the work, +then G:hh:mm:ss:n.nnn, which is when the getwork or LP was sent to the pool and +the n.nnn is how long it took to reply, +followed by 'O' on its own if it is an original getwork, or 'C:n.nnn' if it was +a clone with n.nnn stating how long after the work was recieved that it was +cloned, (m.mmm) is how long from when the original work was received until work +started, +W:n.nnn is how long the work took to process until it was ready to submit, +(m.mmm) is how long from ready to submit to actually doing the submit, this is +usually 0.000 unless there was a problem with submitting the work, +S:n.nnn is how long it took to submit the completed work and await the reply, +R:hh:mm:ss is the actual time the work submit reply was received If you start BFGMiner with the --sharelog option, you can get detailed information for each share found. The argument to the option may be "-" for @@ -450,380 +714,248 @@ For example (this is wrapped, but it's all on one line for real): f681634a4f1f63d01a0cd43fb338000000000080000000000000000000000000 0000000000000000000000000000000000000000000000000000000080020000 ---- -OVERCLOCKING WARNING AND INFORMATION - -AS WITH ALL OVERCLOCKING TOOLS YOU ARE ENTIRELY RESPONSIBLE FOR ANY HARM YOU -MAY CAUSE TO YOUR HARDWARE. OVERCLOCKING CAN INVALIDATE WARRANTIES, DAMAGE -HARDWARE AND EVEN CAUSE FIRES. THE AUTHOR ASSUMES NO RESPONSIBILITY FOR ANY -DAMAGE YOU MAY CAUSE OR UNPLANNED CHILDREN THAT MAY OCCUR AS A RESULT. - -The GPU monitoring, clocking and fanspeed control incorporated into BFGMiner -comes through use of the ATI Display Library. As such, it only supports ATI -GPUs. Even if ADL support is successfully built into BFGMiner, unless the card -and driver supports it, no GPU monitoring/settings will be available. - -BFGMiner supports initial setting of GPU engine clock speed, memory clock -speed, voltage, fanspeed, and the undocumented powertune feature of 69x0+ GPUs. -The setting passed to BFGMiner is used by all GPUs unless separate values are -specified. All settings can all be changed within the menu on the fly on a -per-GPU basis. - -For example: ---gpu-engine 950 --gpu-memclock 825 - -will try to set all GPU engine clocks to 950 and all memory clocks to 825, -while: ---gpu-engine 950,945,930,960 --gpu-memclock 300 - -will try to set the engine clock of card 0 to 950, 1 to 945, 2 to 930, 3 to -960 and all memory clocks to 300. - -AUTO MODES: -There are two "auto" modes in BFGMiner, --auto-fan and --auto-gpu. These can -be used independently of each other and are complementary. Both auto modes -are designed to safely change settings while trying to maintain a target -temperature. By default this is set to 75 degrees C but can be changed with: - ---temp-target -e.g. ---temp-target 80 -Sets all cards' target temperature to 80 degrees. - ---temp-target 75,85 -Sets card 0 target temperature to 75, and card 1 to 85 degrees. - -AUTO FAN: -e.g. ---auto-fan (implies 85% upper limit) ---gpu-fan 25-85,65 --auto-fan - -Fan control in auto fan works off the theory that the minimum possible fan -required to maintain an optimal temperature will use less power, make less -noise, and prolong the life of the fan. In auto-fan mode, the fan speed is -limited to 85% if the temperature is below "overheat" intentionally, as -higher fanspeeds on GPUs do not produce signficantly more cooling, yet -significanly shorten the lifespan of the fans. If temperature reaches the -overheat value, fanspeed will still be increased to 100%. The overheat value -is set to 85 degrees by default and can be changed with: - ---temp-overheat -e.g. ---temp-overheat 75,85 -Sets card 0 overheat threshold to 75 degrees and card 1 to 85. - -AUTO GPU: -e.g. ---auto-gpu --gpu-engine 750-950 ---auto-gpu --gpu-engine 750-950,945,700-930,960 - -GPU control in auto gpu tries to maintain as high a clock speed as possible -while not reaching overheat temperatures. As a lower clock speed limit, -the auto-gpu mode checks the GPU card's "normal" clock speed and will not go -below this unless you have manually set a lower speed in the range. Also, -unless a higher clock speed was specified at startup, it will not raise the -clockspeed. If the temperature climbs, fanspeed is adjusted and optimised -before GPU engine clockspeed is adjusted. If fan speed control is not available -or already optimal, then GPU clock speed is only decreased if it goes over -the target temperature by the hysteresis amount, which is set to 3 by default -and can be changed with: ---temp-hysteresis -If the temperature drops below the target temperature, and engine clock speed -is not at the highest level set at startup, BFGMiner will raise the clock speed. -If at any time you manually set an even higher clock speed successfully in -BFGMiner, it will record this value and use it as its new upper limit (and the -same for low clock speeds and lower limits). If the temperature goes over the -cutoff limit (95 degrees by default), BFGMiner will completely disable the GPU -from mining and it will not be re-enabled unless manually done so. The cutoff -temperature can be changed with: - ---temp-cutoff -e.g. ---temp-cutoff 95,105 -Sets card 0 cutoff temperature to 95 and card 1 to 105. - ---gpu-memdiff -125 -This setting will modify the memory speed whenever the GPU clock speed is -modified by --auto-gpu. In this example, it will set the memory speed to -be 125 Mhz lower than the GPU speed. This is useful for some cards like the -6970 which normally don't allow a bigger clock speed difference. - - -CHANGING SETTINGS: -When setting values, it is important to realise that even though the driver -may report the value was changed successfully, and the new card power profile -information contains the values you set it to, that the card itself may -refuse to use those settings. As the performance profile changes dynamically, -querying the "current" value on the card can be wrong as well. So when changing -values in BFGMiner, after a pause of 1 second, it will report to you the current -values where you should check that your change has taken. An example is that -6970 reference cards will accept low memory values but refuse to actually run -those lower memory values unless they're within 125 of the engine clock speed. -In that scenario, they usually set their real speed back to their default. - -BFGMiner reports the so-called "safe" range of whatever it is you are modifying -when you ask to modify it on the fly. However, you can change settings to values -outside this range. Despite this, the card can easily refuse to accept your -changes, or worse, to accept your changes and then silently ignore them. So -there is absolutely to know how far to/from where/to it can set things safely or -otherwise, and there is nothing stopping you from at least trying to set them -outside this range. Being very conscious of these possible failures is why -BFGMiner will report back the current values for you to examine how exactly the -card has responded. Even within the reported range of accepted values by the -card, it is very easy to crash just about any card, so it cannot use those -values to determine what range to set. You have to provide something meaningful -manually for BFGMiner to work with through experimentation. - -STARTUP / SHUTDOWN: -When BFGMiner starts up, it tries to read off the current profile information -for clock and fan speeds and stores these values. When quitting BFGMiner, it -will then try to restore the original values. Changing settings outside of -BFGMiner while it's running may be reset to the startup BFGMiner values when -BFGMiner shuts down because of this. - --- RPC API -For RPC API details see the API-README file - ---- - -GPU DEVICE ISSUES and use of --gpu-map - -GPUs mine with OpenCL software via the GPU device driver. This means you need -to have both an OpenCL SDK installed, and the GPU device driver RUNNING (i.e. -Xorg up and running configured for all devices that will mine on linux etc.) -Meanwhile, the hardware monitoring that BFGMiner offers for AMD devices relies -on the ATI Display Library (ADL) software to work. OpenCL DOES NOT TALK TO THE -ADL. There is no 100% reliable way to know that OpenCL devices are identical -to the ADL devices, as neither give off the same information. BFGMiner does its -best to correlate these devices based on the order that OpenCL and ADL numbers -them. It is possible that this will fail for the following reasons: - -1. The device order is listed differently by OpenCL and ADL (rare), even if the -number of devices is the same. -2. There are more OpenCL devices than ADL. OpenCL stupidly sees one GPU as two -devices if you have two monitors connected to the one GPU. -3. There are more ADL devices than OpenCL. ADL devices include any ATI GPUs, -including ones that can't mine, like some older R4xxx cards. - -To cope with this, the ADVANCED option for --gpu-map is provided with BFGMiner. -DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. The default will work the -vast majority of the time unless you know you have a problem already. - -To get useful information, start BFGMiner with just the -n option. You will get -output that looks like this: - -[2012-04-25 13:17:34] CL Platform 0 vendor: Advanced Micro Devices, Inc. -[2012-04-25 13:17:34] CL Platform 0 name: AMD Accelerated Parallel Processing -[2012-04-25 13:17:34] CL Platform 0 version: OpenCL 1.1 AMD-APP (844.4) -[2012-04-25 13:17:34] Platform 0 devices: 3 -[2012-04-25 13:17:34] 0 Tahiti -[2012-04-25 13:17:34] 1 Tahiti -[2012-04-25 13:17:34] 2 Cayman -[2012-04-25 13:17:34] GPU 0 AMD Radeon HD 7900 Series hardware monitoring enabled -[2012-04-25 13:17:34] GPU 1 AMD Radeon HD 7900 Series hardware monitoring enabled -[2012-04-25 13:17:34] GPU 2 AMD Radeon HD 6900 Series hardware monitoring enabled -[2012-04-25 13:17:34] 3 GPU devices max detected - -Note the number of devices here match, and the order is the same. If devices 1 -and 2 were different between Tahiti and Cayman, you could run BFGMiner with: ---gpu-map 2:1,1:2 -And it would swap the monitoring it received from ADL device 1 and put it to -opencl device 2 and vice versa. - -If you have 2 monitors connected to the first device it would look like this: - -[2012-04-25 13:17:34] Platform 0 devices: 4 -[2012-04-25 13:17:34] 0 Tahiti -[2012-04-25 13:17:34] 1 Tahiti -[2012-04-25 13:17:34] 2 Tahiti -[2012-04-25 13:17:34] 3 Cayman -[2012-04-25 13:17:34] GPU 0 AMD Radeon HD 7900 Series hardware monitoring enabled -[2012-04-25 13:17:34] GPU 1 AMD Radeon HD 7900 Series hardware monitoring enabled -[2012-04-25 13:17:34] GPU 2 AMD Radeon HD 6900 Series hardware monitoring enabled - -To work around this, you would use: --d 0 -d 2 -d 3 --gpu-map 2:1,3:2 - -If you have an older card as well as the rest it would look like this: - -[2012-04-25 13:17:34] Platform 0 devices: 3 -[2012-04-25 13:17:34] 0 Tahiti -[2012-04-25 13:17:34] 1 Tahiti -[2012-04-25 13:17:34] 2 Cayman -[2012-04-25 13:17:34] GPU 0 AMD Radeon HD 4500 Series hardware monitoring enabled -[2012-04-25 13:17:34] GPU 1 AMD Radeon HD 7900 Series hardware monitoring enabled -[2012-04-25 13:17:34] GPU 2 AMD Radeon HD 7900 Series hardware monitoring enabled -[2012-04-25 13:17:34] GPU 3 AMD Radeon HD 6900 Series hardware monitoring enabled - -To work around this you would use: ---gpu-map 0:1,1:2,2:3 - +For RPC API details see the README.RPC file --- FAQ +Q: Why can't BFGMiner find lib even after I installed it from source +code? +A: On UNIX-like operating systems, you often need to run one or more commands to +reload library caches, such as "ldconfig" or similar. A couple of systems (such +as Fedora) ship with /usr/local/lib missing from their library search path. In +this case, you can usually add it like this: + echo /usr/local/lib >/etc/ld.so.conf.d/local.conf +Please note that if your libraries installed into lib64 instead of lib, you +should use that in the ld.so config file above instead. + Q: BFGMiner segfaults when I change my shell window size. A: Older versions of libncurses have a bug to do with refreshing a window after a size change. Upgrading to a new version of curses will fix it. +Q: I have multiple USB stick devices but I can't get them all to work at once? +A: Very few USB hubs deliver the promised power required to run as many devices +as they fit if all of them draw power from USB. Devices may use up to 2.5 watts +of power (or 4.5 watts for USB 3 devices), and mining USB sticks usually need it +all. You can estimate how much power your USB hub can provide by multiplying its +power supply's output amps by volts (so, if it says 12V 2.5A, you have 12*2.5= +30 watts). + +Q: I've confirmed my USB miners are powered sufficiently, but BFGMiner still +is having problems running more than a few at once? +A: Some USB hosts cannot deal with polling as often as miners may need for quick +delivery of shares. On Linux, you can request putting VCOM devices in "high +latency" mode (or rather, disabling the default "low latency" mode) using the +setserial command: + setserial /dev/ttyUSB0 '^low_latency' +You can further tweak device latency by finding the latency_timer attribute in +sysfs. + +Q: I've plugged my devices into my USB hub but nothing shows up? +A: RPis and Windows have incomplete or non-standard USB3 support so they may +never work. It may be possible to get a USB3 hub to work by plugging it into a +USB2 hub. + Q: Can I mine on servers from different networks (eg smartcoin and bitcoin) at the same time? A: No, BFGMiner keeps a database of the block it's working on to ensure it does not work on stale blocks, and having different blocks from two networks would make it invalidate the work from each other. -Q: Can I change the intensity settings individually for each GPU? -A: Yes, pass a list separated by commas such as -I d,4,9,9 +Q: Can I configure BFGMiner to mine with different login credentials or pools +for each separate device? +A: No such feature has been implemented to support this. Q: Can I put multiple pools in the config file? A: Yes, check the example.conf file. Alternatively, set up everything either on -the command line or via the menu after startup and choose settings->write +the command line or via the menu after startup and choose [S]ettings->[W]rite config file and the file will be loaded one each startup. Q: The build fails with gcc is unable to build a binary. -A: Remove the "-march=native" component of your CFLAGS as your version of gcc +A: Remove the "-march=native" component of your CFLAGS as your version of GCC does not support it. -Q: The CPU usage is high. -A: The ATI drivers after 11.6 have a bug that makes them consume 100% of one -CPU core unnecessarily so downgrade to 11.6. Binding BFGMiner to one CPU core on -windows can minimise it to 100% (instead of more than one core). Driver version -11.11 on linux and 11.12 on windows appear to have fixed this issue. Note that -later drivers may have an apparent return of high CPU usage. Try -'export GPU_USE_SYNC_OBJECTS=1' on Linux before starting BFGMiner. - Q: Can you implement feature X? A: I can, but time is limited, and people who donate are more likely to get their feature requests implemented. -Q: My GPU hangs and I have to reboot it to get it going again? -A: The more aggressively the mining software uses your GPU, the less overclock -you will be able to run. You are more likely to hit your limits with BFGMiner -and you will find you may need to overclock your GPU less aggressively. The -software cannot be responsible and make your GPU hang directly. If you simply -cannot get it to ever stop hanging, try decreasing the intensity, and if even -that fails, try changing to the poclbm kernel with -k poclbm, though you will -sacrifice performance. BFGMiner is designed to try and safely restart GPUs as -much as possible, but NOT if that restart might actually crash the rest of the -GPUs mining, or even the machine. It tries to restart them with a separate -thread and if that separate thread dies, it gives up trying to restart any more -GPUs. - Q: Work keeps going to my backup pool even though my primary pool hasn't failed? A: BFGMiner checks for conditions where the primary pool is lagging and will pass some work to the backup servers under those conditions. The reason for -doing this is to try its absolute best to keep the GPUs working on something +doing this is to try its absolute best to keep the devices working on something useful and not risk idle periods. You can disable this behaviour with the option --failover-only. Q: Is this a virus? -A: BFGMiner is being packaged with other trojan scripts and some antivirus -software is falsely accusing bfgminer.exe as being the actual virus, rather -than whatever it is being packaged with. If you installed BFGMiner yourself, -then you do not have a virus on your computer. Complain to your antivirus -software company. +A: As BFGMiner is being packaged with other trojan scripts, some antivirus +software is falsely accusing bfgminer.exe as being the actual virus, rather than +whatever it is being packaged with. If you installed BFGMiner yourself from a +reputable source then you do not have a virus on your computer. Complain to your +antivirus software company. They seem to be flagging even source code from +BFGMiner as malicious now, even though text source files can't do anything by +themselves. Q: Can you modify the display to include more of one thing in the output and less of another, or can you change the quiet mode or can you add yet another output mode? -A: Everyone will always have their own view of what's important to monitor. +A: Everyone will always have their own view of what is important to monitor. The defaults are very sane and I have very little interest in changing this any further. -Q: Can you change the autofan/autogpu to change speeds in a different manner? -A: The defaults are sane and safe. I'm not interested in changing them -further. The starting fan speed is set to 50% in auto-fan mode as a safety -precaution. - -Q: Why is my efficiency above/below 100%? -A: Efficiency simply means how many shares you return for the amount of work -you request. It does not correlate with efficient use of your hardware, and is -a measure of a combination of hardware speed, block luck, pool design and other -factors +Q: Why is my efficiency above/below 1.00? +A: Efficiency simply means how many shares you return for the amount of +bandwidth used. It does not correlate with efficient use of your hardware, and +is a measure of a combination of hardware speed, block luck, pool design and +many other factors. Q: What are the best parameters to pass for X pool/hardware/device. A: Virtually always, the DEFAULT parameters give the best results. Most user -defined settings lead to worse performance. The ONLY thing most users should -need to set is the Intensity. +defined settings lead to worse performance. Q: What happened to CPU mining? -A: Being increasingly irrelevant for most users, and a maintenance issue, it is -no longer under active development and will not be supported unless someone -steps up to help maintain it. No binary builds supporting CPU mining will be -released but CPU mining can be built into BFGMiner when it is compiled. - -Q: I upgraded BFGMiner version and my hashrate suddenly dropped! -A: No, you upgraded your SDK version unwittingly between upgrades of BFGMiner -and that caused your hashrate to drop. See the next question. - -Q: I upgraded my ATI driver/SDK/BFGMiner and my hashrate suddenly dropped! -A: The hashrate performance in BFGMiner is tied to the version of the ATI SDK -that is installed only for the very first time BFGMiner is run. This generates -binaries that are used by the GPU every time after that. Any upgrades to the -SDK after that time will have no effect on the binaries. However, if you -install a fresh version of BFGMiner, and have since upgraded your SDK, new -binaries will be built. It is known that the 2.6 ATI SDK has a huge hashrate -penalty on generating new binaries. It is recommended to not use this SDK at -this time unless you are using an ATI 7xxx card that needs it. - -Q: Which ATI SDK is the best for BFGMiner? -A: At the moment, versions 2.4 and 2.5 work the best. If you are forced to use -the 2.6 SDK, the phatk kernel will perform poorly, while the diablo or my -custom modified poclbm kernel are optimised for it. - -Q: I have multiple SDKs installed, can I choose which one it uses? -A: Run bfgminer with the -n option and it will list all the platforms currently -installed. Then you can tell BFGMiner which platform to use with --gpu-platform. - -Q: GUI version? -A: No. The RPC interface makes it possible for someone else to write one -though. +A: See README.CPU for more information. + +Q: Is there a GUI version? +A: Yes, there are a number of GUI interfaces for BFGMiner: +Name Website Operating system(s) +---- ------- ------------------- +EasyMiner http://www.butterflylabs.com/drivers/ Android, Linux, Windows +MacMiner http://fabulouspanda.co.uk/macminer/ Mac +MultiMiner http://www.multiminerapp.com/ Linux, Mac, Windows (.NET) + +Q: Is there a "bare-metal" version? +A: Yes, there are a few dedicated mining operating systems built on BFGMiner: +Name Website Hardware +---- ------- -------- +Controla http://hashra.com/support Raspberry Pi +MinePeon http://mineforeman.com/minepeon/ BeagleBone Black, Raspberry Pi +Minera http://getminera.com/ Raspberry Pi +PiMP http://getpimp.org/ x86 Q: I'm having an issue. What debugging information should I provide? A: Start BFGMiner with your regular commands and add -D -T --verbose and provide -the full startup output and a summary of your hardware, operating system, ATI -driver version and ATI stream version. - -Q: BFGMiner reports no devices or only one device on startup on Linux although -I have multiple devices and drivers+SDK installed properly? -A: Try 'export DISPLAY=:0" before running BFGMiner. +the full startup output and a summary of your hardware, operating system, and if +applicable, ATI driver version and ATI stream version. + +Q: Why isn't BFGMiner performing well or working on my Raspberry Pi? +A: Raspberry Pis have hardware defect(s) which affect USB devices to varying +degrees. Some devices will never be able to work on them, some work fine, and +some require hacks to workaround the problem. One common workaround is to add +the dwc_otg.speed=1 parameter to /boot/cmdline.txt. Note that this will slow +down the USB bus to USB 1.1 speeds, which also affects network bandwidth since +the Raspberry Pi uses a USB network interface. You may wish to consider +upgrading to a BeagleBone or UDOO controller. + +Q: Can I mine with BFGMiner on a Mac? +A: BFGMiner will compile on OS X, but the performance of GPU mining is +compromised due to the OpenCL implementation on OS X, there is no temperature or +fanspeed monitoring and the cooling design of most Macs, despite having +powerful GPUs, will usually not cope with constant usage leading to a high risk +of thermal damage. It is highly recommended not to mine on a Mac unless it is +with an external USB device. Q: My network gets slower and slower and then dies for a minute? -A; Try the --net-delay option. +A; Try the --net-delay option if you are on a getwork or GBT server. -Q: How do I tune for p2pool? -A: p2pool has very rapid expiration of work and new blocks, it is suggested you +Q: How do I tune for P2Pool? +A: P2Pool has very rapid expiration of work and new blocks, it is suggested you decrease intensity by 1 from your optimal value, and decrease GPU threads to 1 -with -g 1. It is also recommended to use --failover-only since the work is -effectively like a different block chain. If mining with a minirig, it is worth -adding the --bfl-range option. - -Q: Are kernels from other mining software useable in BFGMiner? -A: No, the APIs are slightly different between the different software and they -will not work. +with --set-device OCL:threads=1. It is also recommended to use --failover-only +since the work is effectively like a different block chain. If mining with a +Mini Rig, it is worth adding the --bfl-range option. Q: I run PHP on windows to access the API with the example miner.php. Why does it fail when php is installed properly but I only get errors about Sockets not working in the logs? -A: http://us.php.net/manual/en/sockets.installation.php +A: Please check http://us.php.net/manual/en/sockets.installation.php Q: What is a PGA? -A: At the moment, BFGMiner supports 4 FPGAs: BitForce, Icarus, ModMiner, and Ztex. +A: At the moment, BFGMiner supports 5 FPGAs: BitForce, Icarus, ModMiner, X6500, +and ZTEX. They are Field-Programmable Gate Arrays that have been programmed to do Bitcoin mining. Since the acronym needs to be only 3 characters, the "Field-" part has -been skipped. - -Q: How do I get my BFL device to auto-recognise? -A: They are only automatically recognised on linux, and no option needs to be -passed to them. The only thing that needs to be done is to load the driver for -them, which on linux would require: -sudo modprobe ftdi_sio vendor=0x0403 product=0x6014 - +been skipped. "PGA" is also used for devices built with Application-Specific +Integrated Circuits (ASICs). + +Q: What is an ASIC? +A: They are Application Specific Integrated Circuit devices and provide the +highest performance per unit power due to being dedicated to only one purpose. + +Q: How do I get my BFL/Icarus/Lancelot/Cairnsmore device to auto-recognise? +A: On Linux, if the /dev/ttyUSB* devices don't automatically appear, the only +thing that needs to be done is to load the driver for them: + BitForce: sudo modprobe ftdi_sio vendor=0x0403 product=0x6014 + Erupter: sudo modprobe cp210x vendor=0x10c4 product=0xea60 + Icarus: sudo modprobe pl2303 vendor=0x067b product=0x0230 + Lancelot: sudo modprobe ftdi_sio vendor=0x0403 product=0x6001 + Cairnsmore: sudo modprobe ftdi_sio vendor=0x0403 product=0x8350 +On some systems you must manally install the driver required for the device. +OpenWrt drivers (install with opkg): + FTDI: kmod-usb-serial-ftdi + Erupter: kmod-usb-serial-cp210x + Icarus: kmod-usb-serial-pl2303 +Windows drivers: + FTDI: http://www.ftdichip.com/Drivers/VCP.htm + Erupter: http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx + Icarus: http://prolificusa.com/pl-2303hx-drivers/ + +Q: I ran cgminer, and now BFGMiner doesn't work! +A: cgminer has its own non-standard implementations of the drivers for most USB +devices, and requires you to replace the official drivers with WinUSB on Windows +(usually using Zadig). Before you can use BFGMiner, you will need to restore the +original driver. Uninstalling the device (and WinUSB driver) from Device Manager +and re-plugging it will usually trigger driver re-installation to the default +drivers. + +Q: On Linux I can see the /dev/ttyUSB* devices, but BFGMiner can't mine on them? +A: Make sure you have the required privileges to access the /dev/ttyUSB* +devices: + sudo ls -las /dev/ttyUSB* +will give output like: + 0 crw-rw---- 1 root video 188, 0 2012-09-11 13:49 /dev/ttyUSB0 +This means your account must have the group 'video' or root privileges. +To permanently give your account the 'video' group: + sudo usermod -G video -a `whoami` +Then logout and back in again. + +Q: Can I mine scrypt with FPGAs or ASICs? +A: BFGMiner supports scrypt mining with GridSeed GC3355 ASICs, using either +DualMiner USB sticks or the 5-chip orb. + +Q: Why does BFGMiner show a fractional difficulty when mining scrypt? +A: BFGMiner consistently uses pdiff measurement for difficulty everywhere, +rather than other measurements that may exist. For scrypt, pdiff 1 is very +difficult, and higher get exponentially harder. It is unlikely you will want to +use pdiff 1+ with scrypt any time soon. + +Q: What is stratum and how do I use it? +A: Stratum is a protocol designed to reduce resources for mining pools at the +cost of keeping the miner in the dark and blindly transferring his mining +authority to the pool. It is a return to the problems of the old centralized +"getwork" protocol, but capable of scaling to hardware of any speed like the +standard GBT protocol. If a pool uses stratum instead of GBT, BFGMiner will +automatically detect it and switch to the support as advertised if it can. +Stratum uses direct TCP connections to the pool and thus it will NOT currently +work through a http proxy but will work via a socks proxy if you need to use +one. If you input the stratum port directly into your configuration, or use the +special prefix "stratum+tcp://" instead of "http://", BFGMiner will ONLY try to +use stratum protocol mining. + +Q: Why don't the statistics add up: Accepted, Rejected, Stale, Hardware Errors, +Diff1 Work, etc. when mining greater than 1 difficulty shares? +A: As an example, if you look at 'Difficulty Accepted' in the RPC API, the number +of difficulty shares accepted does not usually exactly equal the amount of work +done to find them. If you are mining at 8 difficulty, then you would expect on +average to find one 8 difficulty share, per 8 single difficulty shares found. +However, the number is actually random and converges over time as it is an +average, not an exact value, thus you may find more or less than the expected +average. --- diff --git a/README.ASIC b/README.ASIC new file mode 100644 index 0000000000..c765a52401 --- /dev/null +++ b/README.ASIC @@ -0,0 +1,495 @@ +SUPPORTED DEVICES + +Currently supported ASIC devices include Avalon, Bitfountain's Block Erupter +series (both USB and blades), a large variety of Bitfury-based miners, +Bitmain's Antminer S5 and U1-3, Butterfly Labs' SC range of devices, HashBuster +boards, GekkoScience's Compac USB stick, Klondike modules, and KnCMiner's +Mercury, Jupiter and Saturn. + + +ANTMINER S1-S5 +-------------- + +BFGMiner must be compiled for and run on the embedded controller. When +configuring, use the --enable-bitmain option to build the 'bitmain' driver used +to interface with this hardware. None of the device attributes are autodetected +at this time, so you must also tell BFGMiner this at runtime with a series of +--set options. For example: + +-S bitmain:auto --set btm:model=S5 --set btm:layout=32:8 --set btm:timeout=3 +--set btm:clock=350 --set btm:reg_data=0d82 --set btm:voltage=x0725 + +Note that reg_data is optional for S4 and S5 and will be calculated from clock +if not provided. + +The meaning of each of these options are not documented individually at this +time, but can be determined from the stock cgminer's options. You want to look +at the "bitmain-options" from the command line, and the "bitmain-freq" and +"bitmain-voltage" in the /config/cgminer.conf file. +In this case, they were: + +NOTE: These are NOT valid BFGMiner options! + --bitmain-options 115200:32:8:7:200:0782:0725 + | | | | ^^^^ voltage + | | | ^^^^ reg_data + | | ^^^ clock + | ^ timeout + ^^^^ layout + "bitmain-freq" : "3:350:0d82", + | | ^^^^ reg_data + | ^^^ clock + ^ timeout + "bitmain-voltage" : "0725" + ^^^^ voltage + +Notice how there are duplicate settings for timeout, clock, reg_data, and +voltage. You can probably use either one, but the 350 MHz clock performs +better than the 200 MHz clock. You shouldn't mix and match the +timeout/clock/reg_data combinations, however! + +Additionally, since the controllers are underpowered for these devices, you may +need to experiment with a good queue setting to control how much work BFGMiner +tries to pre-prepare for it. A reasonable starting place is: + +--queue 8192 + + +ALCHEMIST +--------- +This driver requires the latest FPGA firmware flashed on the blades (stock +firmware has major bug and won't run properly with this driver). For +instructions, please visit: https://litecointalk.org/?topic=27370 +The driver has been designed to run each of the 8 blades inside an AlcheMist +256 as a separate miner. To detect all the blades you need to manually probe it +with the following serial ports: + +-S ALC:all -S ALC:/dev/ttyO1 -S ALC:/dev/ttyO2 -S ALC:/dev/ttyO3 +-S ALC:/dev/ttyO4 + +(the four ttyUSB ports are auto detected by all) + +The driver supports custom frequency settings in the range of 200-400 MHz in 16 +MHz increments (driver will default to 352 MHz if these conditions are not met). +Frequency is set with the following --set option: + +--set ALC:clock=336 + +You can also set the frequency per board by specifying the tty port: + +--set ALC@/dev/ttyO3:clock=352 + +Driver also supports running blades off a Raspberry Pi directly or with USB Dongles. For a single blade off a raspberry Pi make sure you have configured GPIO pin 25 correctly (see below) and scan via +-S ALC:/dev/ttyAMA0 + +echo 25 > /sys/class/gpio/export +echo out > /sys/class/gpio/gpio25/direction + +for multiple blades using USB Dongles connected to a pi make sure the reset pin on the alcheminer board is connected to the RTS/DTR pin on the dongle board, and option --set +ALC:mode=1 added to startup command line. + + +ANTMINER U3 +----------- + +The U3 does not support autodetection, so you will want to use --scan-serial to +manually probe it. For example, to scan all devices, you can use: + +-S antminer:all --set antminer:chip=BM1382 + +Additionally, for optimal performance you will need to set voltage, clock, and +timing. Voltage format for the U3 is not documented by the manufacturer, thus +must be provided as hexadecimal configuration codes. Timing is provided in the +number of nanoseconds each hash takes at the given configuration. A +known-working configuration is: + +--set antminer:voltage=x800 --set antminer:clock=237.5 +--set antminer:timing=0.022421 + +To set different frequency and voltage settings for multiple U3 miners on a +single BFGMiner process use: + +--set antminer@\\.\COM10:voltage=xNNNN + +or + +--set antminer@/dev/ttyUSB1:voltage=xNNNN + +Another option is to program the CP2102 chip so they have unique serial numbers; +this method would avoid problems with the device showing up on different tty/COM +locations after reboot/hotplug: + +/cp210x-program -w -F eeprom-content.AntU3-custom.hex --set-product-string='Antminer U3' --set-serial-number=myveryown0001 + +Then you can use --set antminer@myveryown0001:voltage=xNNNN + + +AVALON 1 +-------- + +Currently, Avalon boards are best supported by connecting them directly (or via +a hub) to a regular PC running BFGMiner. It is also possible to install the +OpenWrt packages of BFGMiner to the Avalon's embedded controller, but this is +not a simple task due to its lack of available flash space. + +To use the Avalon from a regular PC, you will need to specify two options: +First, add the -S option specifying the avalon driver specifically. For example, + +-S avalon:\\.\COM9 + +Next, use the --set-device option to provide the device configuration. +If you are translating options from --avalon-options (cgminer and older versions +of BFGMiner), note the values are baud:miner_count:asic_count:timeout:clock. + + baud=N The device is essentially hard coded to emulate 115200 baud, + so you shouldn't change this. + miner_count=N Most Avalons are 3 module devices, which come to 24 miners. + 4 module devices would use 32 here. + asic_count=N Virtually all have 10, so don't change this. + timeout=N This defines how long the device will work on a work item + before accepting new work to replace it. It should be changed + according to the frequency (last setting). It is possible to + set this a little lower if you are trying to tune for short + block mining (eg p2pool) but much lower and the device will + start creating duplicate shares. + clock=N This is the clock speed of the devices. Only specific values + work: 256, 270, 282 (default), 300, 325, 350 and 375. + +Sample settings for valid different frequencies (last 2 values): +34:375 +36:350 +39:325 +43:300 +45:282 +47:270 +50:256 + + +AVALON 2/3 +---------- + +Avalon 2/3 units communicate with a UART, usually attached to your host via a +generic USB UART adapter. Therefore, you will need to manually probe the correct +UART device with the -S option: + +-S avalonmm:\\.\COM22 + +Next, use the --set option to configure at least your desired clock frequency +and voltage. + +Avalon 2: --set avalonmm:clock=1500 --set avalonmm:voltage=1 +Avalon 3: --set avalonmm:clock=450 --set avalonmm:voltage=0.6625 + +You may also want to set the fan speed, which is specified as a percentage: + +--set avalonmm:fan=95 + + +BFSB, MEGABIGPOWER, AND METABANK BITFURY BOARDS +----------------------------------------------- + +Both BFSB and MegaBigPower (V2 only at this time) boards are supported with the +"bfsb" driver. Metabank boards are supported with the "metabank" driver. These +drivers are not enabled by default, since they must be run on a Raspberry Pi in +a specific hardware configuration with the boards. To enable them, you must +build with --enable-bfsb or --enable-metabank. Do not try to use these drivers +without the manufacturer-supported hardware configuration! Also note that these +drivers do not properly support thermal shutdown at this time, and without +sufficient cooling you may destroy your board or chips! + +To start BFGMiner, ensure your Raspberry Pi's SPI is enabled (you can run the +raspi-config utility for this). For Metabank boards, you must also load the I2C +drivers (do not try to modprobe both with a single command; it won't work): + modprobe i2c-bcm2708 + modprobe i2c-dev +Then you must run BFGMiner as root, with the proper driver selected. +For example: + sudo bfgminer -S bfsb:auto + + +BFx2 +---- + +You will need to install the WinUSB driver instead of the default FTDI serial +driver. The easiest way to do this is using Zadig: http://zadig.akeo.ie/ + +Note that since it's impossible to tell the BFx2 apart from various other +devices (including BFL/Cairnsmore1 miners and even many non-mining devices!), +you must run with the -S bfx:all option (or 'bfx:all' at the M+ menu). + +I do not know what this will do with other devices; it may start fires, +launch nuclear missiles (please don't run BFGMiner on computers with +missile controls), etc. + + +BI*FURY +------- + +Bi*Fury should just work; you may need to use -S bifury: + +On Windows, you will need to install the standard USB CDC driver for it. + http://store.bitcoin.org.pl/support + +If you want to upgrade the firmware, unplug your device. You will need to +temporarily short a circuit. With the USB connector pointing forward, and the +heatsink down, look to the forward-right; you will see two tiny lights, a set of +2 terminals, and a set of 3 terminals. The ones you need to short are the set of +2. With them shorted, plug the device back into your computer. It will then +pretend to be a mass storage disk drive. If you use Windows, you can play along +and just overwrite the firmware.bin file. If you use Linux, you must use mcopy: + mcopy -i /dev/disk/by-id/usb-NXP_LPC1XXX_IFLASH_ISP-0:0 firmware.bin \ + ::/firmware.bin +After this is complete, unplug the device again and un-short the 2 terminals. +This completes the upgrade and you can now plug it back in and start mining. + + +BIG PICTURE MINING BITFURY USB +------------------------------ + +These miners are sensitive to unexpected data. Usually you can re-plug them to +reset to a known-good initialisation state. To ensure they are properly detected +and used with BFGMiner, you must specify -S bigpic:all (or equivalent) options +prior to any other -S options (which might probe the device and confuse it). + + +BLOCK ERUPTER BLADE +------------------- + +Blades communicate over Ethernet using the old but simple getwork mining +protocol. If you build BFGMiner with libmicrohttpd, you can have it work with +one or more blades. First, start BFGMiner with the --http-port option. For +example: + bfgminer --http-port 8330 +Then configure your blade to connect to your BFGMiner instance on the same port, +with a unique username per blade. It will then show up as a PXY device and +should work more or less like any other miner. + + +BLOCK ERUPTER USB +----------------- + +These will autodetect if supported by the device; otherwise, you need to use +the '--scan-serial erupter:' option to tell BFGMiner what device to +probe; if you know you have no other serial devices, or only ones that can +tolerate garbage, you can use '--scan-serial erupter:all' to probe all serial +ports. They communicate with the Icarus protocol, which has some additional +options in README.FPGA + + +COMPAC +------ + +These USB sticks are based on Bitmain's BM1384 chip, and use the antminer +driver. You can set the clock frequency with + +--set compac:clock=200 + +You can also adjust the clock real-time while the stick is hashing using RPC's pgaset: + +bfgminer-rpc "pgaset|0,clock,x0982" + | ^^^^^ hex frequency + ^ device number + + +HEX*FURY +-------- + +Hex*Fury uses the bifury driver. Miners using earlier boards may need to +workaround bugs in the firmware: + bfgminer --set bifury:chips=6 --set bifury:free_after_job=no +This may cause poor behaviour or performance from other bifury-based devices. +If you encounter this, you can set the workarounds per-device by using their +serial number (which can be seen in the TUI device manager; in this example, +141407160211cdf): + bfgminer --set bifury@141407160211cdf:chips=15 ... + + +KLONDIKE +-------- + +--klondike-options Set klondike options clock:temptarget + + +KNCMINER (Jupiter) +-------- + +KnCMiner rigs use a BeagleBone Black (BBB) as the host; this is pluged into a +"cape" with a FPGA and connections for 4-6 ASIC modules (depending on the cape +version). Note that in addition to the usual dependencies, this driver also +requires i2c-tools (aka libi2c-dev on some systems). The BBB comes with the +Ångström Distribution by default. The following is a step by step install for +BFGMiner on this system; + +-----------------Start------------ +cat >/etc/opkg/feeds.conf <<\EOF +src/gz noarch http://feeds.angstrom-distribution.org/feeds/v2013.06/ipk/eglibc/all/ +src/gz base http://feeds.angstrom-distribution.org/feeds/v2013.06/ipk/eglibc/armv7ahf-vfp-neon/base/ +src/gz beaglebone http://feeds.angstrom-distribution.org/feeds/v2013.06/ipk/eglibc/armv7ahf-vfp-neon/machine/beaglebone/ +EOF + +opkg update +opkg install angstrom-feed-configs +rm /etc/opkg/feeds.conf +opkg update + +opkg install update-alternatives +opkg install automake autoconf make gcc cpp binutils git less pkgconfig-dev ncurses-dev libtool nano bash i2c-tools-dev +while ! opkg install libcurl-dev; do true; done + +curl http://www.digip.org/jansson/releases/jansson-2.0.1.tar.bz2 | tar -xjvp +cd jansson-2.0.1 +./configure --prefix=/usr CC=arm-angstrom-linux-gnueabi-gcc --disable-static NM=arm-angstrom-linux-gnueabi-nm +make install && ldconfig +cd .. + +git clone git://github.com/luke-jr/bfgminer +cd bfgminer +./autogen.sh +git clone git://github.com/troydhanson/uthash +./configure --host=arm-angstrom-linux-gnueabi --enable-knc --disable-other-drivers CFLAGS="-I$PWD/uthash/src" +make AR=arm-angstrom-linux-gnueabi-ar + +/etc/init.d/cgminer.sh stop +./bfgminer -S knc:auto -c /config/cgminer.conf + +---------------END------------- + +KNCMINER (Titan) +-------- + +Titan uses RaspberryPi as a controller. + +Build instructions: +-----------------Start------------ + +git clone git@github.com:KnCMiner/bfgminer.git +cd bfgminer +./autogen.sh +./configure --enable-scrypt --disable-sha256d --enable-titan --disable-other-drivers +make +sudo /etc/init.d/bfgminer.sh restart +screen -r + +---------------END------------- + +MONARCH +------- + +The Butterfly Labs Monarch devices can be used as either USB devices, or in a +PCI-Express slot. As USB devices, they are essentially plug-and-play. If you +wish to use them via PCI-Express, however, you must first load the proper +driver. BFGMiner can work with either Linux uio (2.6.23+, requires root access) +or Linux vfio (3.6+, requires IOMMU support). + +To enable uio on your cards, you may need to do: + sudo modprobe uio_pci_generic + echo 1cf9 0001 | sudo tee /sys/bus/pci/drivers/uio_pci_generic/new_id + +Enabling vfio is similar, but allows you to run BFGMiner without root +privileges. Since setting this up is more complicated, BFGMiner includes a +setup-vfio script (which must be run with root permissions). Simply run: + sudo setup-vfio --unsafe --user $(whoami) 1cf9 0001 +You will be asked about each Monarch found, and must answer 'yes' to each one. + +If you wish to manually setup VFIO, follow these steps: +First, load the kernel module: + sudo modprobe vfio-pci +Next, identify what the device ids are for your card(s): + lspci -D | grep 1cf9 # the first number of each line is the device id +From that, you can identify its IOMMU group, and list all devices sharing that +group: + readlink "/sys/bus/pci/devices/$DEVICE_ID/iommu_group" + ls "/sys/kernel/iommu_groups/$IOMMU_GROUP_ID/devices/" +All of the devices listed (other than the Monarch), if any, will need to be +disabled and unbound! To do that, use: + echo "$DEVICE_ID" | sudo tee "/sys/bus/pci/devices/$DEVICE_ID/driver/unbind" + echo "$DEVICE_CODE" | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id +Note that $DEVICE_ID should be something like "0000:01:00.0" and $DEVICE_CODE is +something like "1cf9 0001" (this example is the Monarch itself). +If you want to run BFGMiner as a normal user: + chown "$USERNAME" "/dev/vfio/$IOMMU_GROUP_ID" +Depending on your system, you may also need to do: + echo 1 | sudo tee /sys/module/vfio_iommu_type1/parameters/allow_unsafe_interrupts + + +ONESTRINGMINER +-------------- + +OneStringMiner boards use the bifury driver. Miners using earlier boards may +need to workaround bugs in the firmware: + bfgminer --set bifury:chips=15 --set bifury:free_after_job=no +If you have different devices using the bifury driver, see the section on +Hex*Fury for applying workarounds per-device. + + +GRIDSEED +-------- + +Gridseed units, at the present time, come in two versions: Blade - a 40 chip +unit and Orb - a 5 chip unit. Orb units can be used to mine both SHA256d and +scrypt based coins whereas the Blade is scrypt only, although BFGMiner only +supports scrypt mode at this time. + +BFGMiner allows a miner to connect both types of units to a single miner +instance and provides for granular control of the clock frequencies for each +device and each chip on each device. The basic use of this feature is to use the +--set option on from the command line: + +bfgminer --scrypt -S gridseed:all --set gridseed@:clock=825 + +for multiple devices, add multiple --set arguments. + +Additionally, these can be added to the bfgminer.conf file for persistence like +this: + +"set" : [ + "gridseed@:clock=825", + "gridseed@:clock=850", + "gridseed@:clock=875" +] + +To find the device serial number, start bfgminer and press to manage +devices, then or through the list of devices and take +note of the device serial number in the device information shown. + +... +Select processor to manage using up/down arrow keys + GSD 0a: | 74.4/ 72.9/ 10.2kh/s | A: 1 R:0+0(none) HW:0/none + STM32 Virtual COM Port from STMicroelectronics +Serial: 6D85278F5650 +Clock speed: 875 +... + +So for example, an entry would look like this: + gridseed@6D85278F5650:clock=875 + + +ZEUSMINER +--------- + +Zeusminers do not support autodetection, so you will need to use --scan to probe +for them: + +-S zeusminer:\\.\COM3 + +You should also configure the driver for your specific device: + + --set zeusminer:clock=N Clock frequency (default: 328) + --set zeusminer:chips=N Number of chips per device + Blizzard : 6 Cyclone : 96 + Hurricane X2: 48 (2*24) Hurricane X3: 64 (2*32) + Thunder X2: 96 (4*24) Thunder X3: 128 (4*32) +Note: if you set this option incorrectly, the device may underperform and/or + misreport hashrate. + +For example: + +bfgminer --scrypt -o stratum+tcp://pool:port -u user -p pass -S zeusminer:\\.\COM3 --set zeusminer:clock=328 --set zeusminer:chips=128 + +--- + +This code is provided entirely free of charge by the programmer in his spare +time so donations would be greatly appreciated. Please consider donating to the +address below. + +Luke-Jr +1QATWksNFGeUJCWBrN4g6hGM178Lovm7Wh diff --git a/README.CPU b/README.CPU new file mode 100644 index 0000000000..1f8c4e0ecc --- /dev/null +++ b/README.CPU @@ -0,0 +1,45 @@ +EXECUTIVE SUMMARY ON CPU USAGE: + +By default, BFGMiner will NOT mine on CPUs unless it is explicitly compiled with +support and told to do so. CPU mining for bitcoin is generally considered to be +obsolete as it requires considerably more power per hash computed than either +GPU, FPGA or ASIC based mining. If you still wish to mine using CPUs you will +need to build a custom binary with support enabled (refer to the build notes in +README for further information). + +The following CPU mining options are available: + +--algo Specify sha256 implementation for CPU mining: + fastauto* Quick benchmark at startup to pick a working algorithm + auto Benchmark at startup and pick fastest algorithm + c Linux kernel sha256, implemented in C + 4way tcatm's 4-way SSE2 implementation + via VIA padlock implementation + cryptopp Crypto++ C/C++ implementation + cryptopp_asm32 Crypto++ 32-bit assembler implementation + sse2_32 SSE2 32 bit implementation for i386 machines + sse2_64 SSE2 64 bit implementation for x86_64 machines + sse4_64 SSE4.1 64 bit implementation for x86_64 machines + altivec_4way Altivec implementation for PowerPC G4 and G5 machines +--cpu-threads Number of miner CPU threads (default: -1) + +CPU FAQ: + +Q: What happened to CPU mining? +A: Being increasingly irrelevant for most users, and a maintenance issue, it is +no longer under active development and will not be supported unless someone +steps up to help maintain it. No binary builds supporting CPU mining will be +released for Windows but CPU mining can be built into BFGMiner when it is +compiled. For builds which do support CPU mining, it is still disabled by +default, and must be enabled using the -S cpu:auto option. + +Q: So, should I even try CPU mining? +A: No, it honestly will waste more power and time than it is worth at this stage. +If you really wish to mine, you are better off getting a suitable ASIC instead. + +Q: But, if the computers aren't mine and I'm not paying for the power? +A: If you are trying to use computers that aren't yours, you really should +reconsider. Attempting to mine with a large number of devices will often impact +negatively on many pools and will likely pay almost nothing due to the small +number of successful shares submitted. Apart from that, you will probably get +into trouble with someone down the track for misusing the computers. diff --git a/README.FPGA b/README.FPGA new file mode 100644 index 0000000000..247f645905 --- /dev/null +++ b/README.FPGA @@ -0,0 +1,288 @@ + +This README contains extended details about FPGA mining with BFGMiner + + +ModMiner (MMQ) +-------------- + +ModMiner does not have any persistent storage for bitstreams, so BFGMiner must +upload it after power on. For this to work, you must first download the +necessary bitstream file to BFGMiner's "bitstreams" directory, and give it the +name "fpgaminer_x6500-overclocker-0402.bit". You can download this bitstream +from FPGA Mining LLC's website: + http://www.fpgamining.com/documentation/firmware + +- + +If the MMQ doesn't respond to BFGMiner at all, or the red LED isn't flashing +then you will need to reset the MMQ. + +The red LED should always be flashing when it is mining or ready to mine. + +To reset the MMQ, you are best to press the left "RESET" button on the +backplane, then unplug and replug the USB cable. + +If your MMQ doesn't have a button on the "RESET" pad, you need to join the two +left pads of the "RESET" pad with conductive wire to reset it. Cutting a small +(metal) paper-clip in half works well for this. + +Then unplug the USB cable, wait for 5 seconds, then plug it back in. + +After you press reset, the red LED near the USB port should blink continuously. + +If it still wont work, power off, wait for 5 seconds, then power on the MMQ +This of course means it will upload the bitstream again when you start BFGMiner. + +- + +Device 0 is on the power end of the board. + +- + +You must make sure you have an appropriate firmware in your MMQ +Read here for official details of changing the firmware: + http://wiki.btcfpga.com/index.php?title=Firmware + +The basics of changing the firmware are: + You need two short pieces of conductive wire if your MMQ doesn't have buttons + on the "RESET" and "ISP" pads on the backplane board. + Cutting a small (metal) paper-clip in half works well for this. + + Join the 2 left pads of the "RESET" pad with wire and the led will dim. + Without disconnecting the "RESET", join the 2 left pads of the "ISP" pad with + a wire and it will stay dim. + Release "RESET" then release "ISP" and is should still be dim. + Unplug the USB and when you plug it back in it will show up as a mass storage + device. + Linux: (as one single line): + mcopy -i /dev/disk/by-id/usb-NXP_LPC134X_IFLASH_ISP000000000-0:0 + modminer091012.bin ::/firmware.bin + Windows: delete the MSD device file firmware.bin and copy in the new one + rename the new file and put it under the same name 'firmware.bin' + Disconnect the USB correctly (so writes are flushed first) + Join and then disconnect "RESET" and then plug the USB back in and it's done. + +Best to update to one of the latest 2 listed below if you don't already +have one of them in your MMQ. + +The current latest different firmware are: + + Latest for support of normal or TLM bitstream: + http://btcfpga.com/files/firmware/modminer092612-TLM.bin + + Latest with only normal bitstream support (Temps/HW Fix): + http://btcfpga.com/files/firmware/modminer091012.bin + +The code is currently tested on the modminer091012.bin firmware. +This comment will be updated when others have been tested. + +- + +On many Linux distributions there is an app called modem-manager that may cause +problems when it is enabled, due to opening the MMQ device and writing to it. + +The problem will typically present itself by the flashing led on the backplane +going out (no longer flashing) and it takes a power cycle to re-enable the MMQ +firmware - which then can lead to the problem reoccurring. + +You can either disable/uninstall modem-manager if you don't need it or: +a (hack) solution to this is to blacklist the MMQ USB device in +/lib/udev/rules.d/77-mm-usb-device-blacklist.rules + +Adding 2 lines like this (just above APC) should help. +# MMQ +ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0003", ENV{ID_MM_DEVICE_IGNORE}="1" + +The change will be lost and need to be re-done, next time you update the +modem-manager software. + + +BitForce (BFL) +-------------- + +--bfl-range Use nonce range on BitForce devices if supported + +This option is only for BitForce devices. Earlier devices such as the single +did not have any way of doing small amounts of work which meant that a lot of +work could be lost across block changes. Some of the Mini Rigs have support +for doing this, so less work is lost across a longpoll. However, it comes at +a cost of 1% in overall hashrate so this feature is disabled by default. It +is only recommended you enable this if you are mining with a Mini Rig on +P2Pool. + +BitFORCE FPGA Single units can have their bitstream modified using the +bitforce-firmware-flash utility on Linux, which can be obtained from: + https://github.com/luke-jr/bitforce-fpga-firmware-flash +It is untested with other devices. Use at your own risk! Windows users may use +Butterfly Labs EasyMiner to change firmware. + +To compile: + make bitforce-firmware-flash +To flash your BFL, specify the BFL port and the flash file e.g.: + sudo ./bitforce-firmware-flash /dev/ttyUSB0 alphaminer_832.bfl +It takes a bit under 3 minutes to flash a BFL and shows a progress % counter +Once it completes, you may also need to wait about 15 seconds, then power the +BFL off and on again. + +If you get an error at the end of the BFL flash process stating: + "Error reading response from ZBX" +it may have worked successfully anyway. +Test mining on it to be sure if it worked or not. + +You need to give BFGMiner about 10 minutes mining with the BFL to be sure of +the Mh/s value reported with the changed firmware - and the Mh/s reported will +be less than the firmware speed since you lose work on every block change. + + +Icarus (ICA) +------------ + +There are a number of options for Icarus-compatible devices which can be used +with --set-devices (or the RPC pgaset method): + + baud=N The serial baud rate (default 115200) + work_division=N The fraction of work divided up for each processor: 1, 2, + 4, or 8. e.g. 2 means each does half the nonce range + (default 2) + fpga_count=N The actual number of processors working; this would + normally be the same as work_division. Range is from 1 up + to . It defaults to the value of + work_division, or 2 if you don't specify work_division. + reopen=MODE Controls how often the driver reopens the device to + workaround issues. Choices are 'never', on 'timeout' only + (default), or every 'cycle'. + timing=MODE Set how the timing is calculated: + default[=N] Use the default hash time + short[=N] Calculate the hash time and stop + adjusting it at ~315 difficulty 1 shares + (~1hr) + long=[N] Re-calculate the hash time continuously + value[=N] Specify the hash time in nanoseconds + (e.g. 2.6316) and abort time (e.g. + 2.6316=80). + +An example would be: --set-device ECM:baud=57600 --set-device +ECM:work_division=2 --set-device DCM:fpga_count=1 --set-device ECM:reopen=never +This would mean: use 57600 baud, the FPGA board divides the work in half however +only 1 FPGA actually runs on the board, and don't reopen the device (e.g. like +an early CM1 Icarus copy bitstream). + +Icarus timing is used to determine the number of hashes that have been checked +when it aborts a nonce range (including on a longpoll). +It is also used to determine the elapsed time when it should abort a nonce +range to avoid letting the Icarus go idle, but also to safely maximise that +time. + +'short' or 'long' mode should only be used on a computer that has enough CPU +available to run BFGMiner without any CPU delays. +Any CPU delays while calculating the hash time will affect the result +'short' mode only requires the computer to be stable until it has completed +~315 difficulty 1 shares, 'long' mode requires it to always be stable to ensure +accuracy, however, over time it continually corrects itself. +The optional additional =N for 'short' or 'long' specifies the limit to set the +timeout to in deciseconds; thus if the timing code calculation is higher while +running, it will instead use the limit. +This can be set to the appropriate value to ensure the device never goes idle +even if the calculation is negatively affected by system performance. + +When in 'short' or 'long' mode, it will report the hash time value each time it +is re-calculated. +In 'short' or 'long' mode, the scan abort time starts at 5 seconds and uses the +default 2.6316ns scan hash time, for the first 5 nonces or one minute +(whichever is longer). + +In 'default' or 'value' mode the 'constants' are calculated once at the start, +based on the default value or the value specified. +The optional additional =N specifies to set the default abort at N 1/10ths of a +second, not the calculated value, which is 112 for 2.6316ns + +To determine the hash time value for a non Icarus Rev3 device or an Icarus Rev3 +with a different bitstream to the default one, use 'long' mode and give it at +least a few hundred shares, or use 'short' mode and take note of the final hash +time value (Hs) calculated. +You can also use the RPC API 'stats' command to see the current hash time (Hs) +at any time. + +The Icarus code currently only works with devices that support the same commands +as Icarus Rev3 requires and also is less than ~840Mh/s and greater than 2Mh/s. +If your device does hash faster than ~840Mh/s it should work correctly if you +supply the correct hash time nanoseconds value. + +The timing code itself will affect the Icarus performance since it increases +the delay after work is completed or aborted until it starts again. +The increase is, however, extremely small and the actual increase is reported +with the RPC API 'stats' command (a very slow CPU will make it more noticeable). +Using the 'short' mode will remove this delay after 'short' mode completes. +The delay doesn't affect the calculation of the correct hash time. + + +X6500 +----- + +Since X6500 FPGAs do not use serial ports for communication, the --scan-serial +option instead works with product serial numbers. By default, any devices with +the X6500 USB product id will be used, but some X6500s may have shipped without +this product id being configured. If you have any of these, you will need to +specify their serial numbers explicitly, and also add -S x6500:auto if you +still want to use the autodetection for other properly-configured FPGAs. +The serial number of X6500s is usually found on a label applied to the ATX +power connector slot. If yours is missing, devices seen by the system can be +displayed by starting bfgminer in debug mode. To get a simple list of devices, +with the debug output shown, you can use: bfgminer -D -d? -T + +X6500 does not have any persistent storage for bitstreams, so BFGMiner must +upload it after power on. For this to work, you must first download the +necessary bitstream file to BFGMiner's "bitstreams" directory, and give it the +name "fpgaminer_x6500-overclocker-0402.bit". You can download this bitstream +from FPGA Mining LLC's website: + http://www.fpgamining.com/documentation/firmware + + +ZTEX FPGA Boards +---------------- + +http://www.ztex.de sells two boards suitable for mining: the 1.15x with 1 FPGA +and the 1.15y with 4 FPGAs. ZTEX distributes their own mining software and +drivers. BFGMiner has full support for these boards, as long as they have at +least the "dummy" mining bitstreams installed on them. + +If your boards do not have a mining bitstream yet, you must first, install +ZTEX's BTCMiner (requires Java JDK version 6 or later) and install one. + +=== WINDOWS NOTE === +Upon first powering up and connecting the board via USB, windows will attempt +and fail to find the appropriate drivers. To load the initial firmware on the +board, you'll need the EZ-USB FX2 SDK from here: + http://www.ztex.de/downloads/#firmware_kit +Extract the firmware kit and use the driver within libusb-win32/ztex.inf. +Windows should now recognize the board and you're ready to program it. +=== END OF WINDOWS === + +Grab the latest miner jar from http://www.ztex.de/btcminer/#download and program +the appropriate dummy firmware for your board. The command should look +something like (for a single FPGA board): + java -cp ZtexBTCMiner-120417.jar BTCMiner -m p -f **FILENAME** -s 01-02-01 +For ZTEX 1.15x boards, the dummy bitstream filename is ztex_ufm1_15d.ihx +For ZTEX 1.15y boards, the dummy bitstream filename is ztex_ufm1_15y.ihx + +=== WINDOWS NOTE === +To mine using BFGMiner, you'll have to swap the USB drivers. The BFGMiner- +compatible WinUSB drivers for the board can be generated with this tool: + http://sourceforge.net/projects/libwdi/files/zadig/ +Basic usage instructions for Zadig can be found here: + https://github.com/pbatard/libwdi/wiki/Zadig +Once Zadig generates and installs a WinUSB driver, ensure everything is working +by running: + bfgminer -D -d? -T +You should see something like this in the output: + [2013-01-22 20:19:11] Found 1 ztex board + [2013-01-22 20:19:11] ZTX 0: Found Ztex (ZTEX 0001-02-01-1) +=== END OF WINDOWS === + +If you have installed a dummy bitstream, you will now need to copy the main +mining bitstream where BFGMiner can find it. This are usually the same as the +dummy bitstream filename, but with a number added to the end. Extract the +ZtexBTCMiner-120417.jar file using any unzip utility, and look for the proper +*.ihx and *.bit files (the latter will be inside the 'fpga' directory of the +jar). Copy them to BFGMiner's "bitstreams" directory, and you're ready to start +mining. diff --git a/README.GPU b/README.GPU new file mode 100644 index 0000000000..7ae38527fb --- /dev/null +++ b/README.GPU @@ -0,0 +1,489 @@ +EXECUTIVE SUMMARY ON GPU USAGE (SEE ALSO README.scrypt FOR SCRYPT MINING): + +By default, BFGMiner will NOT mine on any GPUs unless in scrypt mode. If you +wish to use your GPU to mine SHA256d (generally not a good idea), you can +explicitly enable it with the -S opencl:auto option. + +Single pool, regular desktop: + +bfgminer -S opencl:auto -o http://pool:port -u username -p password + +If you have configured your system properly, BFGMiner will mine on all GPUs in +"dynamic" mode which is designed to keep your system usable and sacrifice some +mining performance. + +Single pool, dedicated miner: + +bfgminer -S opencl:auto -o http://pool:port -u username -p password --set-device intensity=9 + +Single pool, first card regular desktop, 3 other dedicated cards: + +bfgminer -S opencl:auto -o http://pool:port -u username -p password --set-device intensity=9 --set-device OCL0:intensity=d + +Multiple pool, dedicated miner: + +bfgminer -S opencl:auto -o http://pool1:port -u pool1username -p pool1password -o http://pool2:port -u pool2usernmae -p pool2password --set-device intensity=9 + +Add overclocking settings, GPU and fan control for all cards: + +bfgminer -S opencl:auto -o http://pool:port -u username -p password --set-device intensity=9 --auto-fan --auto-gpu --set-device OCL:clock=750-950 --set-device OCL:memclock=300 + +Add overclocking settings, GPU and fan control with different engine settings for 4 cards: + +bfgminer -S opencl:auto -o http://pool:port -u username -p password --set-device intensity=9 --auto-fan --auto-gpu --set-device OCL0:clock=750-950 --set-device OCL1:clock=945 --set-device OCL2:clock=700-930 --set-device OCL3:clock=960 --set-device OCL:memclock=300 + +READ WARNINGS AND DOCUMENTATION BELOW ABOUT OVERCLOCKING + +To configure multiple displays on linux you need to configure your Xorg cleanly +to use them all: + +sudo aticonfig --adapter=all -f --initial + +On Linux you virtually always need to export your display settings before +starting to get all the cards recognised and/or temperature+clocking working: + +export DISPLAY=:0 + +--- +SETUP FOR GPU SUPPORT: + +To setup GPU mining support: + +Install the AMD APP sdk, ideal version (see FAQ!) - put it into a system +location. +Download the correct version for either 32 bit or 64 bit from here: + http://developer.amd.com/tools/heterogeneous-computing/amd-accelerated-parallel-processing-app-sdk/downloads/ + +The best version for Radeon 5xxx and 6xxx is v2.5, while 7xxx cards need v2.6 or +later, 2.7 seems the best. + +For versions 2.4 or earlier you will need to manually install them: +This will give you a file with a name like: + AMD-APP-SDK-v2.4-lnx64.tgz (64-bit) +or + AMD-APP-SDK-v2.4-lnx32.tgz (32-bit) + +Then: + +sudo -i +cd /opt +tar xf /path/to/AMD-APP-SDK-v2.4-lnx##.tgz +cd / +tar xf /opt/AMD-APP-SDK-v2.4-lnx##/icd-registration.tgz +ln -s /opt/AMD-APP-SDK-v2.4-lnx##/include/CL /usr/include +ln -s /opt/AMD-APP-SDK-v2.4-lnx##/lib/x86_64/* /usr/lib/ +ldconfig + +Where ## is 32 or 64, depending on the bitness of the SDK you downloaded. +If you are on 32 bit, x86_64 in the 2nd last line should be x86 + + +--- +INTENSITY INFORMATION: + +Intensity correlates with the size of work being submitted at any one time to +a GPU. The higher the number the larger the size of work. Generally speaking +finding an optimal value rather than the highest value is the correct approach +as hash rate rises up to a point with higher intensities but above that, the +device may be very slow to return responses, or produce errors. + +NOTE: Running intensities above 9 with current hardware is likely to only +diminish return performance even if the hash rate might appear better. A good +starting baseline intensity to try on dedicated miners is 9. 11 is the upper +limit for intensity while Bitcoin mining, if the GPU_USE_SYNC_OBJECTS variable +is set (see FAQ). The upper limit for SHA256d mining is 14 and 20 for scrypt. + + +--- +OVERCLOCKING WARNING AND INFORMATION + +AS WITH ALL OVERCLOCKING TOOLS YOU ARE ENTIRELY RESPONSIBLE FOR ANY HARM YOU +MAY CAUSE TO YOUR HARDWARE. OVERCLOCKING CAN INVALIDATE WARRANTIES, DAMAGE +HARDWARE AND EVEN CAUSE FIRES. THE AUTHOR ASSUMES NO RESPONSIBILITY FOR ANY +DAMAGE YOU MAY CAUSE OR UNPLANNED CHILDREN THAT MAY OCCUR AS A RESULT. + +The GPU monitoring, clocking and fanspeed control incorporated into BFGMiner +comes through use of the ATI Display Library. As such, it only supports ATI +GPUs. Even if ADL support is successfully built into BFGMiner, unless the card +and driver supports it, no GPU monitoring/settings will be available. + +BFGMiner supports initial setting of GPU engine clock speed, memory clock +speed, voltage, fanspeed, and the undocumented powertune feature of 69x0+ GPUs. +The setting passed to BFGMiner is used by all GPUs unless separate values are +specified. All settings can all be changed within the menu on the fly on a +per-GPU basis. + +For example: +--set-device OCL:clock=950 --set-device OCL:memclock=825 + +will try to set all GPU engine clocks to 950 and all memory clocks to 825, +while: +--set-device OCL0:clock=950 --set-device OCL1:clock=945 --set-device OCL2:clock=930 --set-device OCL3:clock=960 --set-device OCL:memclock=300 + +will try to set the engine clock of card 0 to 950, 1 to 945, 2 to 930, 3 to +960 and all memory clocks to 300. + +AUTO MODES: +There are two "auto" modes in BFGMiner, --auto-fan and --auto-gpu. These can be +used independently of each other and are complementary. Both auto modes are +designed to safely change settings while trying to maintain a target +temperature. By default this is set to 75 degrees C but can be changed with the +--set-device option. For example: + +--set-device OCL:temp-target=80 +Sets all cards' target temperature to 80 degrees. + +--set-device OCL0:temp-target=75 --set-device OCL1:temp-target=85 +Sets card 0 target temperature to 75, and card 1 to 85 degrees. + +AUTO FAN: +e.g. +--auto-fan (implies 85% upper limit) +--set-device OCL0:fan=25-85 --set-device OCL1:fan=65 --auto-fan + +Fan control in auto fan works off the theory that the minimum possible fan +required to maintain an optimal temperature will use less power, make less +noise, and prolong the life of the fan. In auto-fan mode, the fan speed is +limited to 85% if the temperature is below "overheat" intentionally, as higher +fanspeeds on GPUs do not produce signficantly more cooling, yet significantly +shorten the lifespan of the fans. If temperature reaches the overheat value, +fanspeed will still be increased to 100%. The overheat value is set to 85 +degrees by default and can be changed with the temp_overheat setting: + +e.g. +--set-device OCL0:temp_overheat=75 --set-device OCL1:temp_overheat=85 +Sets card 0 overheat threshold to 75 degrees and card 1 to 85. + +AUTO GPU: +e.g. +--auto-gpu --set-device OCL:clock=750-950 +--auto-gpu --set-device OCL0:clock=750-950 --set-device OCL1:clock=945 --set-device OCL2:clock=700-930 --set-device OCL3:clock=960 + +GPU control in auto gpu tries to maintain as high a clock speed as possible +while not reaching overheat temperatures. As a lower clock speed limit, the +auto-gpu mode checks the GPU card's "normal" clock speed and will not go below +this unless you have manually set a lower speed in the range. Also, unless a +higher clock speed was specified at startup, it will not raise the clockspeed. +If the temperature climbs, fanspeed is adjusted and optimised before GPU engine +clockspeed is adjusted. If fan speed control is not available or already +optimal, then GPU clock speed is only decreased if it goes over the target +temperature by the hysteresis amount, which is set to 3 by default and can be +changed with: +--temp-hysteresis +If the temperature drops below the target temperature, and engine clock speed +is not at the highest level set at startup, BFGMiner will raise the clock speed. +If at any time you manually set an even higher clock speed successfully in +BFGMiner, it will record this value and use it as its new upper limit (and the +same for low clock speeds and lower limits). If the temperature goes over the +cutoff limit (95 degrees by default), BFGMiner will completely disable the GPU +from mining and it will not be re-enabled unless manually done so. The cutoff +temperature can be changed with: + +--set-device OCL0:temp-cutoff=95 --set-device OCL1:temp-cutoff=105 +Sets card 0 cutoff temperature to 95 and card 1 to 105. + +--set-device OCL:memdiff=-125 +This setting will modify the memory speed whenever the GPU clock speed is +modified by --auto-gpu. In this example, it will set the memory speed to be 125 +MHz lower than the GPU speed. This is useful for some cards like the 6970 which +normally don't allow a bigger clock speed difference. The 6970 is known to only +allow -125, while the 7970 only allows -150. + + +CHANGING SETTINGS: +When setting values, it is important to realise that even though the driver +may report the value was changed successfully, and the new card power profile +information contains the values you set it to, that the card itself may +refuse to use those settings. As the performance profile changes dynamically, +querying the "current" value on the card can be wrong as well. So when changing +values in BFGMiner, after a pause of 1 second, it will report to you the current +values where you should check that your change has taken. An example is that +6970 reference cards will accept low memory values but refuse to actually run +those lower memory values unless they're within 125 of the engine clock speed. +In that scenario, they usually set their real speed back to their default. + +BFGMiner reports the so-called "safe" range of whatever it is you are modifying +when you ask to modify it on the fly. However, you can change settings to values +outside this range. Despite this, the card can easily refuse to accept your +changes, or worse, to accept your changes and then silently ignore them. So +there is absolutely to know how far to/from where/to it can set things safely or +otherwise, and there is nothing stopping you from at least trying to set them +outside this range. Being very conscious of these possible failures is why +BFGMiner will report back the current values for you to examine how exactly the +card has responded. Even within the reported range of accepted values by the +card, it is very easy to crash just about any card, so it cannot use those +values to determine what range to set. You have to provide something meaningful +manually for BFGMiner to work with through experimentation. + +STARTUP / SHUTDOWN: +When BFGMiner starts up, it tries to read off the current profile information +for clock and fan speeds and stores these values. When quitting BFGMiner, it +will then try to restore the original values. Changing settings outside of +BFGMiner while it's running may be reset to the startup BFGMiner values when +BFGMiner shuts down because of this. + +--- + +GPU DEVICE ISSUES and use of --gpu-map + +GPUs mine with OpenCL software via the GPU device driver. This means you need +to have both an OpenCL SDK installed, and the GPU device driver RUNNING (i.e. +Xorg up and running configured for all devices that will mine on linux etc.) +Meanwhile, the hardware monitoring that BFGMiner offers for AMD devices relies +on the ATI Display Library (ADL) software to work. OpenCL DOES NOT TALK TO THE +ADL. There is no 100% reliable way to know that OpenCL devices are identical +to the ADL devices, as neither give off the same information. BFGMiner does its +best to correlate these devices based on the order that OpenCL and ADL numbers +them. It is possible that this will fail for the following reasons: + +1. The device order is listed differently by OpenCL and ADL (rare), even if the +number of devices is the same. +2. There are more OpenCL devices than ADL. OpenCL stupidly sees one GPU as two +devices if you have two monitors connected to the one GPU. +3. There are more ADL devices than OpenCL. ADL devices include any ATI GPUs, +including ones that can't mine, like some older R4xxx cards. + +To cope with this, the ADVANCED option for --gpu-map is provided with BFGMiner. +DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. The default will work the +vast majority of the time unless you know you have a problem already. + +To get useful information, start BFGMiner with just the -n option. You will get +output that looks like this: + +[2012-04-25 13:17:34] CL Platform 0 vendor: Advanced Micro Devices, Inc. +[2012-04-25 13:17:34] CL Platform 0 name: AMD Accelerated Parallel Processing +[2012-04-25 13:17:34] CL Platform 0 version: OpenCL 1.1 AMD-APP (844.4) +[2012-04-25 13:17:34] Platform 0 devices: 3 +[2012-04-25 13:17:34] 0 Tahiti +[2012-04-25 13:17:34] 1 Tahiti +[2012-04-25 13:17:34] 2 Cayman +[2012-04-25 13:17:34] GPU 0 AMD Radeon HD 7900 Series hardware monitoring enabled +[2012-04-25 13:17:34] GPU 1 AMD Radeon HD 7900 Series hardware monitoring enabled +[2012-04-25 13:17:34] GPU 2 AMD Radeon HD 6900 Series hardware monitoring enabled +[2012-04-25 13:17:34] 3 GPU devices max detected + +Note the number of devices here match, and the order is the same. If devices 1 +and 2 were different between Tahiti and Cayman, you could run BFGMiner with: +--gpu-map 2:1,1:2 +And it would swap the monitoring it received from ADL device 1 and put it to +OpenCL device 2 and vice versa. + +If you have 2 monitors connected to the first device it would look like this: + +[2012-04-25 13:17:34] Platform 0 devices: 4 +[2012-04-25 13:17:34] 0 Tahiti +[2012-04-25 13:17:34] 1 Tahiti +[2012-04-25 13:17:34] 2 Tahiti +[2012-04-25 13:17:34] 3 Cayman +[2012-04-25 13:17:34] GPU 0 AMD Radeon HD 7900 Series hardware monitoring enabled +[2012-04-25 13:17:34] GPU 1 AMD Radeon HD 7900 Series hardware monitoring enabled +[2012-04-25 13:17:34] GPU 2 AMD Radeon HD 6900 Series hardware monitoring enabled + +To work around this, you would use: +-d 0 -d 2 -d 3 --gpu-map 2:1,3:2 + +If you have an older card as well as the rest it would look like this: + +[2012-04-25 13:17:34] Platform 0 devices: 3 +[2012-04-25 13:17:34] 0 Tahiti +[2012-04-25 13:17:34] 1 Tahiti +[2012-04-25 13:17:34] 2 Cayman +[2012-04-25 13:17:34] GPU 0 AMD Radeon HD 4500 Series hardware monitoring enabled +[2012-04-25 13:17:34] GPU 1 AMD Radeon HD 7900 Series hardware monitoring enabled +[2012-04-25 13:17:34] GPU 2 AMD Radeon HD 7900 Series hardware monitoring enabled +[2012-04-25 13:17:34] GPU 3 AMD Radeon HD 6900 Series hardware monitoring enabled + +To work around this you would use: +--gpu-map 0:1,1:2,2:3 + + +--- +GPU FAQ: + +Q: Can I change the intensity settings individually for each GPU? +A: Yes, specify the devices by identifier: --set-device intensity=9 --set-device +OCL0:intensity=d --set-device OCL1:intensity=4 (be sure you set the catch-all +first!) + +Q: The CPU usage is high. +A: The ATI drivers after 11.6 have a bug that makes them consume 100% of one +CPU core unnecessarily, so downgrade to 11.6. Binding BFGMiner to one CPU core +on windows can minimise it to 100% (instead of more than one core). Driver +version 11.11 on linux and 11.12 on windows appear to have fixed this issue. +Note that later drivers may have an apparent return of high CPU usage. Try +'export GPU_USE_SYNC_OBJECTS=1' on Linux before starting BFGMiner. You can also +set this variable in windows via a batch file or on the command line before +starting BFGMiner with 'setx GPU_USE_SYNC_OBJECTS 1' + +Q: My GPU hangs and I have to reboot it to get it going again? +A: The more aggressively the mining software uses your GPU, the less overclock +you will be able to run. You are more likely to hit your limits with BFGMiner +and you will find you may need to overclock your GPU less aggressively. The +software cannot be responsible and make your GPU hang directly. If you simply +cannot get it to ever stop hanging, try decreasing the intensity, and if even +that fails, try changing to the poclbm kernel with --set-device +OCL:kernel=poclbm, though you will sacrifice performance. BFGMiner is designed +to try and safely restart GPUs as much as possible, but NOT if that restart +might actually crash the rest of the GPUs mining, or even the machine. It tries +to restart them with a separate thread and if that separate thread dies, it +gives up trying to restart any more GPUs. + +Q: Can you change the autofan/autogpu to change speeds in a different manner? +A: The defaults are sane and safe. I'm not interested in changing them further. +The starting fan speed is set to 50% in auto-fan mode as a safety precaution. + +Q: I upgraded BFGMiner version and my hashrate suddenly dropped! +A: No, you upgraded your SDK version unwittingly between upgrades of BFGMiner +and that caused your hashrate to drop. Please see the next question. + +Q: I upgraded my ATI driver/SDK/BFGMiner and my hashrate suddenly dropped! +A: The hashrate performance in BFGMiner is tied to the version of the ATI SDK +that is installed only for the very first time BFGMiner is run. This generates +binaries that are used by the GPU every time after that. Any upgrades to the +SDK after that time will have no effect on the binaries. However, if you +install a fresh version of BFGMiner, and have since upgraded your SDK, new +binaries will be built. It is known that the 2.6 ATI SDK has a huge hashrate +penalty on generating new binaries. It is recommended to not use this SDK at +this time unless you are using an ATI 7xxx card that needs it. + +Q: Which AMD SDK is the best for BFGMiner? +A: At the moment, versions 2.4 and 2.5 work the best for 5xxx and 6xxx GPUs. SDK +2.6 or 2.7 works best for 7xxx. SDK 2.8 is known to have many problems. If you +need to use the 2.6+ SDK (7xxx and later), the phatk kernel will perform poorly, +while the diablo or (modified) poclbm kernel are optimised for it. + +Q: Which AMD driver is the best? +A: Unfortunately AMD has a history of having quite a few releases with issues +when it comes to mining, either in terms of breaking mining, increasing CPU +usage or very low hashrates. Only experimentation can tell you for sure, but +some good releases were 11.6, 11.12, 12.4 and 12.8. Note that older cards may +not work with the newer drivers. + +Q: I have multiple SDKs installed, can I choose which one it uses? +A: Run bfgminer with the -n option and it will list all the platforms currently +installed. Then you can tell BFGMiner which platform to use with --gpu-platform. + +Q: BFGMiner reports no devices or only one device on startup on Linux although +I have multiple devices and drivers+SDK installed properly? +A: Try "export DISPLAY=:0" before running BFGMiner. + +Q: BFGMiner crashes immediately on startup. +A: One of the common reasons for this is that you have mixed files on your +machine for the driver or SDK. Windows has a nasty history of not cleanly +uninstalling files so you may have to use third party tools like driversweeper +to remove old versions. The other common reason for this is windows antivirus +software is disabling one of the DLLs from working. If BFGMiner starts with the +-T option but never starts without it, this is a sure fire sign you have this +problem and will have to disable your antivirus or set up some exceptions in it +if possible. + +Q: Is it faster to mine on Windows or Linux? +A: It makes no difference. It comes down to choice of operating system for their +various features. Linux offers much better long term stability and remote +monitoring and security, while Windows offers you overclocking tools that can +achieve much more than BFGMiner can do on Linux. + +Q: BFGMiner cannot see any of my GPUs even though I have configured them all to +be enabled and installed OpenCL (+/- Xorg is running and the DISPLAY variable is +exported on Linux)? +A: Check the output of 'bfgminer -S opencl:auto -d?', it will list what OpenCL +devices your installed SDK recognises. If it lists none, you have a problem with +your version or installation of the SDK. + +Q: BFGMiner is mining on the wrong GPU, I want it on the AMD but it's mining on +my on board GPU? +A: Make sure the AMD OpenCL SDK is installed, check the output of 'bfgminer -S +opencl:auto -d?' and use the appropriate parameter with --gpu-platform. + +Q: I'm getting much lower hashrates than I should be for my GPU? +A: Look at your driver/SDK combination and disable power saving options for your +GPU. Specifically look to disable ULPS. Make sure not to set intensity above 11 +for Bitcoin mining. + +Q: Can I mine with AMD while running Nvidia or Intel GPUs at the same time? +A: If you can install both drivers successfully (easier on windows) then yes, +using the --gpu-platform option. + +Q: Can I mine with Nvidia or Intel GPUs? +A: Yes, but the hashrate on these is very poor and it is likely you'll be using +much more energy than you'll be earning in coins. + +Q: Can I mine on both Nvidia and AMD GPUs at the same time? +A: No, you must run one instance of BFGMiner with the --gpu-platform option for +each. + +Q: Can I mine on Linux without running Xorg? +A: With Nvidia you can, but with AMD you cannot. + +Q: I'm trying to mine a scrypt cryptocurrency but BFGMiner shows MH values +instead of kH and submits no shares? +A: Add the --scrypt parameter to your BFGMiner startup command. + +Q: I can't get anywhere near enough hashrate for scrypt compared to other +people? +A: You may not have enough system RAM, as this is also required. + +Q: My scrypt hashrate is high but the pool reports only a tiny proportion of my +hashrate? +A: You are generating garbage hashes due to your choice of settings. Try +decreasing your intensity, do not increase the number of gpu-threads, and +consider adding system RAM to match your GPU ram. You may also be using a bad +combination of driver and/or SDK. + +Q: Scrypt fails to initialise the kernel every time? +A: Your parameters are too high. Don't add GPU threads, don't set intensity too +high, decrease thread concurrency. See the README.scrypt for a lot more help. + +Q: Are OpenCL kernels from other mining software useable in BFGMiner? +A: The interfaces are often slightly different between the different software, +so in most cases they will not work without modifying BFGMiner itself. However, +if the kernel is compatible with one BFGMiner supports, you can edit it in a +text editor and add a line that looks like this to the top: + // kernel-interface: poclbm +This will instruct BFGMiner to use the poclbm kernel interface. Then to use the +kernel, just use --set OCL:kernel=mykernel where the filename is mykernel.cl. + +Q: BFGMiner stops mining (or my GPUs go DEAD) and I can't close it? +A: Once the driver has crashed, there is no way for BFGMiner to close cleanly. +You will have to kill it, and depending on how corrupted your driver state has +gotten, you may even need to reboot. Windows is known to reset drivers when they +fail and BFGMiner will be stuck trying to use the old driver instance. + +Q: I can't get any monitoring of temperatures or fanspeed with BFGMiner when I +start it remotely? +A: With Linux, make sure to export the DISPLAY variable. On Windows, you cannot +access these monitoring values via RDP. This should work with TightVNC or +TeamViewer, though. + +Q: I change my GPU engine/memory/voltage and BFGMiner reports back no change? +A: BFGMiner asks the GPU using the ATI Display Library to change settings, but +the driver and hardware are free to do what it wants with that query, including +ignoring it. Some GPUs are locked with one or more of those properties as well. +The most common of these is that many GPUs only allow a fixed difference +between the engine clock speed and the memory clock speed (such as the memory +being no lower than the engine - 150). Other 3rd party tools have unofficial +data on these devices on windows and can get the memory clock speed down +further but BFGMiner does not have access to these means. + +Q: I have multiple GPUs and although many devices show up, it appears to be +working only on one GPU splitting it up. +A: Your driver setup is failing to properly use the accessory GPUs. Your driver +may be misconfigured or you have a driver version that needs a dummy plug on all +the GPUs that aren't connected to a monitor. + +Q: I have some random GPU performance related problem not addressed above. +A: Seriously, it's the driver and/or SDK. Uninstall them and start again, +also noting there is no clean way to uninstall them so you will likely have to +use extra tools or do it manually. + +Q: Do I need to recompile after updating my driver/SDK? +A: No. The software is unchanged regardless of which driver/SDK/ADL version you +are running. + +Q: I do not want BFGMiner to modify my engine/clock/fanspeed? +A: BFGMiner only modifies values if you tell it to via the parameters. +Otherwise it will just monitor the values. + +Q: Should I use crossfire/SLI? +A: It does not benefit mining at all and depending on the GPU may actually +worsen performance. diff --git a/README.OpenWrt b/README.OpenWrt new file mode 100644 index 0000000000..41ef79ec04 --- /dev/null +++ b/README.OpenWrt @@ -0,0 +1,27 @@ +First, look at /etc/openwrt_release (on your router). You will see a bunch of +attributes for the OpenWrt system. The DISTRIB_RELEASE attribute is your +OpenWrt version, the first part of DISTRIB_TARGET (before the slash) is the +router's platform, and (only on newer versions) DISTRIB_ARCH is the package +architecture. Older versions of OpenWrt (up to 15.05) use the router's +platform for packages instead of the package architecture. + +Now, open up /etc/opkg.conf (again, on your router) in your favourite editor. +Add a new line at the bottom, similar to this: + src/gz bfgminer http://luke.dashjr.org/programs/bitcoin/files/bfgminer/latest/openwrt/17.01/mips_24kc +In this example, 17.01 is the version of OpenWrt, and mips_24kc is the package +architecture. Be sure to change those to match your router! You can also change +"latest" to "stable" or "testing" to get better-tested versions. + +Next, save the file and exit your editor. Tell opkg to reload its package lists +by running the command: + opkg update +If you get a "404 Not Found" error, then your router may not be supported. If +you open an issue for your router's platform, it may be possible to add +support. + +If all went well updating your package list, you can now install BFGMiner and +any drivers you might need: + opkg install bfgminer + opkg install kmod-usb-serial-ftdi + opkg install kmod-usb-serial-cp210x + opkg install kmod-usb-serial-pl2303 diff --git a/README.RPC b/README.RPC new file mode 100644 index 0000000000..5bb29e914a --- /dev/null +++ b/README.RPC @@ -0,0 +1,1766 @@ + +This README contains details about the BFGMiner RPC API + +It also includes some detailed information at the end, +about using miner.php + + +If you start BFGMiner with the "--api-listen" option, it will listen on a +simple TCP/IP socket for single string API requests from the same machine +running BFGMiner and reply with a string and then close the socket each time +If you add the "--api-network" option, it will accept API requests from any +network attached computer. + +You can only access the commands that reply with data in this mode. +By default, you cannot access any privileged command that affects the miner - +you will receive an access denied status message instead. See --api-allow below +for more details. + +You can specify IP addresses/prefixes that are only allowed to access the API +with the "--api-allow" option, e.g. --api-allow W:192.168.0.1,10.0.0/24 +will allow 192.168.0.1 or any address matching 10.0.0.*, but nothing else. +IP addresses are automatically padded with extra '.0's as needed +Without a /prefix is the same as specifying /32. +0/0 means all IP addresses. +The 'W:' on the front gives that address/subnet privileged access to commands +that modify BFGMiner (thus all API commands). +Without it those commands return an access denied status. +See --api-groups below to define other groups like W: +Privileged access is checked in the order the IP addresses were supplied to +"--api-allow" +The first match determines the privilege level. +Using the "--api-allow" option overrides the "--api-network" option if they +are both specified +With "--api-allow", 127.0.0.1 is not by default given access unless specified + +If you start BFGMiner also with the "--api-mcast" option, it will listen for +a multicast message and reply to it with a message containing it's API port +number, but only if the IP address of the sender is allowed API access. + +More groups (like the privileged group W:) can be defined using the +--api-groups command +Valid groups are only the letters A-Z (except R & W are predefined) and are +not case sensitive. +The R: group is the same as not privileged access. +The W: group is (as stated) privileged access (thus all API commands). +To give an IP address/subnet access to a group you use the group letter +in front of the IP address instead of W: e.g. P:192.168.0/32 +An IP address/subnet can only be a member of one group. +A sample API group would be: + --api-groups + P:switchpool:enablepool:addpool:disablepool:removepool:poolpriority:* +This would create a group 'P' that can do all current pool commands and all +non-privileged commands - the '*' means all non-privileged commands. +Without the '*' the group would only have access to the pool commands. +Defining multiple groups example: + --api-groups Q:quit:restart:*,S:save +This would define 2 groups: + Q: that can 'quit' and 'restart' as well as all non-privileged commands. + S: that can only 'save' and no other commands. + +The RPC API request can be either simple text or JSON. + +If the request is JSON (starts with '{'), it will reply with a JSON formatted +response, otherwise it replies with text formatted as described further below. + +The JSON request format required is '{"command":"CMD","parameter":"PARAM"}' +(though of course parameter is not required for all requests) +where "CMD" is from the "Request" column below and "PARAM" would be e.g. +the device number if required. + +An example request in both formats to set device 0 fan to 80%: + pgaset|0,fan,80 + {"command":"pgaset","parameter":"0,fan,80"} + +The format of each reply (unless stated otherwise) is a STATUS section +followed by an optional detail section. + +From API version 1.7 onwards, reply strings in JSON and Text have the +necessary escaping as required to avoid ambiguity - they didn't before 1.7. +For JSON the 2 characters '"' and '\' are escaped with a '\' before them. +For Text the 4 characters '|' ',' '=' and '\' are escaped the same way. + +Only user entered information will contain characters that require being +escaped, such as Pool URL, User and Password or the Config save filename, +when they are returned in messages or as their values by the API. + +For API version 1.4 and later: + +The STATUS section is: + + STATUS=X,When=NNN,Code=N,Msg=string,Description=string| + + STATUS=X Where X is one of: + W - Warning + I - Informational + S - Success + E - Error + F - Fatal (code bug) + + When=NNN + Standard long time of request in seconds. + + Code=N + Each unique reply has a unique Code (See api.c - #define MSG_NNNNNN). + + Msg=string + Message matching the Code value N. + + Description=string + This defaults to the BFGMiner version but is the value of --api-description + if it was specified at runtime. + +With API V3.1 you can also request multiple report replies in a single command +request +e.g. to request both summary and devs, the command would be summary+devs + +This is only available for report commands that don't need parameters, +and is not available for commands that change anything +Any parameters supplied will be ignored + +The extra formatting of the result is to have a section for each command +e.g. CMD=summary|STATUS=....|CMD=devs|STATUS=... +With JSON, each result is within a section of the command name +e.g. {"summary":{"STATUS":[{"STATUS":"S"...}],"SUMMARY":[...],"id":1}, + "devs":{"STATUS":[{"STATUS:"S"...}],"DEVS":[...],"id":1},"id":1} + +As before, if you supply bad JSON you'll just get a single 'E' STATUS section +in the old format, since it doesn't switch to using the new format until it +correctly processes the JSON and can match a '+' in the command + +If you request a command multiple times, e.g. devs+devs +you'll just get it once +If this results in only one command, it will still use the new layout +with just the one command + +If you request a command that can't be used due to requiring parameters, +a command that isn't a report, or an invalid command, you'll get an 'E' STATUS +for that one but it will still attempt to process all other commands supplied + +Blank/missing commands are ignore e.g. +devs++ +will just show 'devs' using the new layout + +For API version 1.10 and later: + +The list of requests - a (*) means it requires privileged access - and replies: + + Request Reply Section Details + ------- ------------- ------- + version VERSION Miner="BFGMiner " BFGMiner version + CGMiner=BFGMiner version + API=API version + + config CONFIG Some miner configuration information: + PGA Count=N, <- the number of PGAs + Pool Count=N, <- the number of Pools + ADL=X, <- Y or N if ADL is compiled in the code + ADL in use=X, <- Y or N if any GPU has ADL + Strategy=Name, <- the current pool strategy + Rotate Period=N, <- rotate strategy period + Log Interval=N, <- log interval (--log N) + Device Code=GPU ICA , <- spaced list of compiled + device drivers + OS=Linux/Apple/..., <- operating System + Failover-Only=true/false, <- failover-only setting + ScanTime=N, <- --scan-time setting + Queue=N, <- --queue setting + Expiry=N, <- --expiry setting + Coinbase-Sig=X, <- extra coinbase data in blocks + ConfigFileN=X| <- filename of configs loaded + + summary SUMMARY The status summary of the miner + e.g. Elapsed=NNN,Found Blocks=N,Getworks=N,...| + + pools POOLS The status of each pool e.g. + Pool=0,URL=http://pool.com:6311,Status=Alive,...| + + devs DEVS Each available device with their status + e.g. PGA=0,Accepted=NN,MHS av=NNN,...,Intensity=D| + Last Share Time=NNN, <- standard long time in sec + (or 0 if none) of last accepted share + Last Share Pool=N, <- pool number (or -1 if none) + Last Valid Work=NNN, <- standand long time in sec + of last work returned that wasn't an HW: + + procs DEVS The details of each processor in the same format + and details as for DEVS + + devscan|info DEVS Probes for a device specified by info, which is + the same format as the --scan-serial command line + option + + pga|N PGA The details of a single PGA number N in the same + format and details as for DEVS + This is only available if PGA mining is enabled + Use 'pgacount' or 'config' first to see if there + are any + + proc|N PGA The details of a single processor number N in the + same format and details as for DEVS + + pgacount PGAS Count=N| <- the number of PGAs + Always returns 0 if PGA mining is disabled + + proccount PGAS Count=N| <- the number of processors + + switchpool|N (*) + none There is no reply section just the STATUS section + stating the results of switching pool N to the + highest priority (the pool is also enabled) + The Msg includes the pool URL + + enablepool|N (*) + none There is no reply section just the STATUS section + stating the results of enabling pool N + The Msg includes the pool URL + + addpool|URL,USR,PASS[,GOAL] (*) + none There is no reply section just the STATUS section + stating the results of attempting to add pool N + The Msg includes the pool URL + Use '\\' to get a '\' and '\,' to include a comma + inside URL, USR, PASS, or GOAL + + poolpriority|N,... (*) + none There is no reply section just the STATUS section + stating the results of changing pool priorities + See usage below + + poolquota|N,Q (*) + none There is no reply section just the STATUS section + stating the results of changing pool quota to Q + + disablepool|N (*) + none There is no reply section just the STATUS section + stating the results of disabling pool N + The Msg includes the pool URL + + removepool|N (*) + none There is no reply section just the STATUS section + stating the results of removing pool N + The Msg includes the pool URL + N.B. all details for the pool will be lost + + save|filename (*) + none There is no reply section just the STATUS section + stating success or failure saving the BFGMiner + config to filename + The filename is optional and will use the BFGMiner + default if not specified + + quit (*) none There is no reply section just the STATUS section + before BFGMiner quits + + notify NOTIFY The last status and history count of each devices + problem + e.g. NOTIFY=0,Name=PGA,ID=0,ProcID=0,Last Well=1332432290,...| + + privileged (*) + none There is no reply section just the STATUS section + stating an error if you do not have privileged + access to the API and success if you do have + privilege + The command doesn't change anything in BFGMiner + + pgaenable|N (*) + none There is no reply section just the STATUS section + stating the results of the enable request + You cannot enable a PGA if its status is not WELL + This is only available if PGA mining is enabled + + pgadisable|N (*) + none There is no reply section just the STATUS section + stating the results of the disable request + This is only available if PGA mining is enabled + + pgarestart|N (*) + none There is no reply section just the STATUS section + stating the results of the restart request + + pgaidentify|N (*) + none This is equivalent to PROCIDENTIFY on the first + processor of any given device + This is only available if PGA mining is enabled + + procenable|N (*) + none There is no reply section just the STATUS section + stating the results of the enable request + + procdisable|N (*) + none There is no reply section just the STATUS section + stating the results of the disable request + + procidentify|N (*) + none There is no reply section just the STATUS section + stating the results of the identify request + On most supported devices, it will flash the led + for approximately 4s + All unsupported devices, it will return a warning + status message stating that they don't support it + For BFL, this adds a 4s delay to the share being + processed so you may get a message stating that + processing took longer than 7000ms if the request + was sent towards the end of the timing of any work + being worked on + e.g.: BFL0: took 8438ms - longer than 7000ms + You should ignore this + + devdetails DEVDETAILS Each device with a list of their static details + This lists all devices including those not + supported by the 'devs' command + e.g. DEVDETAILS=0,Name=BFL,ID=0,ProcID=0,Driver=bitforce,...| + + restart (*) none There is no reply section just the STATUS section + before BFGMiner restarts + + stats STATS Each device or pool that has 1 or more getworks + with a list of stats regarding getwork times + The values returned by stats may change in future + versions thus would not normally be displayed + Device drivers are also able to add stats to the + end of the details returned + + check|cmd COMMAND Exists=Y/N, <- 'cmd' exists in this version + Access=Y/N| <- you have access to use 'cmd' + + failover-only|true/false (*) + none There is no reply section just the STATUS section + stating what failover-only was set to + + coin COIN Coin mining information: + Hash Method=sha256/scrypt, + Current Block Time=N.N, <- 0 means none + Current Block Hash=XXXX..., <- blank if none + LP=true/false, <- LP is in use on at least 1 pool + Network Difficulty=NN.NN| + + debug|setting (*) + DEBUG Debug settings + The optional commands for 'setting' are the same + as the screen curses debug settings + You can only specify one setting + Only the first character is checked - case + insensitive: + Silent, Quiet, Verbose, Debug, RPCProto, + PerDevice, WorkTime, Normal + The output fields are (as above): + Silent=true/false, + Quiet=true/false, + Verbose=true/false, + Debug=true/false, + RPCProto=true/false, + PerDevice=true/false, + WorkTime=true/false| + + setconfig|name,value (*) + none There is no reply section just the STATUS section + stating the results of setting 'name' + The valid values for name are currently: + queue, scantime, expiry (integer in the range + 0 to 9999) + coinbase-sig (string) + http-port (valid port number) + strategy (name of valid strategy, and optional + number of minutes if rotate) + stratum-port (valid port number) + + pgaset|N,opt[,val] (*) + none This is equivalent to PROCSET on the first + processor of any given device + This is only available if PGA mining is enabled + + procset|N,opt[,val] (*) + none There is no reply section just the STATUS section + stating the results of setting processor N with + opt[,val] + + If the processor does not support any set options, + it will always return a WARN stating pgaset isn't + supported + + If opt=help it will return an INFO status with a + help message about the options available + + The current options are: + MMQ opt=clock val=2 to 250 (a multiple of 2) + XBS opt=clock val=2 to 250 (a multiple of 2) + + zero|Which,true/false (*) + none There is no reply section just the STATUS section + stating that the zero, and optional summary, was + done + If Which='all', all normal BFGMiner and API + statistics will be zeroed other than the numbers + displayed by the stats command + If Which='bestshare', only the 'Best Share' values + are zeroed for each pool and the global + 'Best Share' + The true/false option determines if a full summary + is shown on the BFGMiner display like is normally + displayed on exit. + +When you enable, disable or restart a device, you will also get Thread messages +in the BFGMiner status window. + +The 'poolpriority' command can be used to reset the priority order of multiple +pools with a single command - 'switchpool' only sets a single pool to first +priority. Each pool should be listed by id number in order of preference (first += most preferred). Any pools not listed will be prioritised after the ones that +are listed, in the priority order they were originally If the priority change +affects the miner's preference for mining, it may switch immediately. + +When you switch to a different pool to the current one (including by priority +change), you will get a 'Switching to URL' message in the BFGMiner status +windows. + +Obviously, the JSON format is simply just the names as given before the '=' +with the values after the '='. + +If you enable BFGMiner debug (--debug or using RPC), you will also get messages +showing some details of the requests received and the replies. + +There are included 5 program examples for accessing the API: + +api-example.php - a PHP script to access the API. + usage: php api-example.php command + by default it sends a 'summary' request to the miner at 127.0.0.1:4028 + If you specify a command it will send that request instead. + You must modify the line "$socket = getsock('127.0.0.1', 4028);" at the + beginning of "function request($cmd)" to change where it looks for BFGMiner. + +api-example.c - a 'C' program to access the API (with source code). + usage: api-example [command [ip/host [port]]] + again, as above, missing or blank parameters are replaced as if you entered: + api-example summary 127.0.0.1 4028 + +miner.php - an example web page to access the API. + This includes buttons and inputs to attempt access to the privileged commands. + See the end of this README.RPC for details of how to tune the display + and also to use the option to display a multi-rig summary. + +api-example.py - a Python script to access the API. + usage: python api-example.py [--host HOST] [--port PORT] [command] [parameter] + by default it sends a 'summary' request to the miner at 127.0.0.1:4028 + If you specify a command it will send that request instead. + +api-example.rb - a Ruby script to access the API. + usage: ruby api-example.rb command[:parameter] [HOST [PORT]] + +If you are using Node.js, you can also use the miner-rpc package and script: +https://www.npmjs.org/package/miner-rpc + +---------- + +Feature Changelog for external applications using the API: + + +API V3.4 (BFGMiner v5.4.0) + +Modified API commands: + 'config' - add 'Rotate Period' + 'setconfig' - add 'strategy' + +--------- + +API V3.3 (BFGMiner v5.0.0) + +Modified API command: + 'addpool' - accept an additional argument to indicate mining goal by name + 'coin' - return multiple elements, when there are multiple mining goals + defined; add 'Difficulty Accepted' + 'pools' - add 'Mining Goal' + +--------- + +API V3.2 (BFGMiner v4.1.0) + +Modified API command: + 'config' - add 'ConfigFile'N + +--------- + +API V3.1 (BFGMiner v4.0.0) + +Multiple report request command with '+' e.g. summary+devs + +CPU and OpenCL devices are now included as "PGAs", to enable migration to a simpler interface. + +Added API commands: + 'pgarestart' + +Modified API commands: + 'devs' - remove 'GPU Count' and 'CPU Count' + 'quit' - expand reply to include a complete STATUS section + 'restart' - expand reply to include a complete STATUS section + 'summary' - add 'MHS rolling' + 'version' - add 'Miner' + +Deprecated API commands: + 'cpu' + 'cpucount' + 'cpuenable' + 'cpudisable' + 'cpurestart' + 'gpu' + 'gpucount' + 'gpuenable' + 'gpudisable' + 'gpurestart' + 'gpuintensity' + 'gpumem' + 'gpuengine' + 'gpufan' + 'gpuvddc' + +--------- + +API V2.3 (BFGMiner v3.7.0) + +Modified API command: + 'devdetails' - Add 'Processors', 'Manufacturer', 'Product', 'Serial', + 'Target Temperature', 'Cutoff Temperature' + 'procdetails' - Add 'Manufacturer', 'Product', 'Serial', 'Target Temperature', + 'Cutoff Temperature' + +--------- + +API V2.2 (BFGMiner v3.6.0) + +Modified API command: + 'pools' - add 'Works' + +--------- + +API V2.1 (BFGMiner v3.4.0) + +Added API command: + 'poolquota' - Set pool quota for load-balance strategy. + +Modified API command: + 'devs', 'gpu', 'pga', 'procs' and 'asc' - add 'Device Elapsed', 'Stale', + 'Work Utility', 'Difficulty Stale' + 'pools' - add 'Quota' + 'summary' - add 'Diff1 Work', 'MHS %ds' (where %d is the log interval) + +--------- + +API V2.0 (BFGMiner v3.3.0) + +Removed API commands: + 'devdetail' - Use newer 'devdetails' for same information. + +Modified API commands: + 'devs' - display status of each full device only (not processors) + 'pga' - lookup and display device by device (not processor) number + 'pgacount' - count only full devices (not processors) + 'pgaenable' - enable all processors for a numbered full device + 'pgadisable' - disable all processors for a numbered full device + 'pgaidentify' - choose first processor of numbered full device + 'pgaset' - choose first processor of numbered full device + 'setconfig' - add 'stratum-port' number + +Added API commands: + 'procs' + 'proc' + 'proccount' + 'procenable' + 'procdisable' + 'procidentify' + 'procset' + +---------- + +API V1.25.3 (BFGMiner v3.2.0) + +Modified API commands: + 'devs', 'pga', 'gpu' - add 'Device Hardware%' and 'Device Rejected%' + 'pools' - add 'Pool Rejected%' and 'Pool Stale%' + 'setconfig' - add 'http-port' number + 'summary' - add 'Device Hardware%', 'Device Rejected%', 'Pool Rejected%', + 'Pool Stale%' + +Removed output limitation: + All replies can now be longer than the previous limitation of 64k, and will + only be truncated on a 50ms timeout sending. + +Basic support for cgminer-compatible multicast RPC detection added. + +---------- + +API V1.25.2 (BFGMiner v3.1.4) + +Modified API commands: + 'pgaset' - added: XBS opt=clock val=2 to 250 (and a multiple of 2) + +---------- + +API V1.25.1 (BFGMiner v3.1.2) + +Added API commands: + 'devscan' + +---------- + +API V1.25 (BFGMiner v3.0.1) + +Modified API commands: + 'devs' 'gpu' and 'pga' - add 'Last Valid Work' + +---------- + +API V1.24.1 (BFGMiner v3.0.0) + +Modified API commands: + 'cpustatus' - add 'ProcID' + 'gpustatus' - add 'ProcID' + 'pgastatus' - add 'ProcID' + 'devstatus' - add 'ProcID' + 'notify' - add 'ProcID' + 'devdetails' - add 'ProcID' + 'devdetail' - add 'Name', 'ID', and 'ProcID' + 'pools' - add 'Message' + 'coin' - add 'Network Difficulty' + +Pretty much updated every method returning 'Name' and 'ID' to also return +'ProcID'. This is a number starting with 0 for 'a', 1 for 'b', etc. + +---------- + +API V1.24 (BFGMiner v2.10.3) + +Added API commands: + 'zero' + +Modified API commands: + 'pools' - add 'Best Share' + 'stats' - rename 'Bytes Sent' and 'Bytes Recv' to 'Net Bytes Sent' and + 'Net Bytes Recv' + +---------- + +API V1.23 (BFGMiner v2.10.1) + +Added API commands: + 'pgaset' - with: MMQ opt=clock val=2 to 230 (and a multiple of 2) + +---------- + +API V1.22 (not released) + +Enforced output limitation: + all extra records beyond the output limit of the API (~64k) are ignored and + chopped off at the record boundary before the limit is reached however, JSON + brackets will be correctly closed and the JSON id will be set to 0 (instead + of 1) if any data was truncated. + +Modified API commands: + 'stats' - add 'Times Sent', 'Bytes Sent', 'Times Recv', 'Bytes Recv' + +---------- + +API V1.21 (BFGMiner v2.10.0) + +Modified API commands: + 'summary' - add 'Best Share' + +---------- + +API V1.20b (BFGMiner v2.9.1) + +Support for the X6500 FPGA was added. + +---------- + +API V1.20 (BFGMiner v2.9.0) + +Modified API commands: + 'pools' - add 'Has Stratum', 'Stratum Active', 'Stratum URL' + +---------- + +API V1.19b (BFGMiner v2.8.1) + +Added API commands: + 'pgaidentify|N' (only works for BitForce Singles so far) + +Modified API commands: + Change pool field name back from 'Diff1 Work' to 'Diff1 Shares' + 'devs' - add 'Difficulty Accepted', 'Difficulty Rejected', + 'Last Share Difficulty' to all devices + 'gpu|N' - add 'Difficulty Accepted', 'Difficulty Rejected', + 'Last Share Difficulty' + 'pga|N' - add 'Difficulty Accepted', 'Difficulty Rejected', + 'Last Share Difficulty' + 'notify' - add '*Dev Throttle' (for BitForce Singles) + 'pools' - add 'Difficulty Accepted', 'Difficulty Rejected', + 'Difficulty Stale', 'Last Share Difficulty' + 'stats' - add 'Work Diff', 'Min Diff', 'Max Diff', 'Min Diff Count', + 'Max Diff Count' to the pool stats + 'setconfig|name,value' - add 'Coinbase-Sig' string + +---------- + +API V1.19 (BFGMiner v2.8.0) + +Added API commands: + 'debug' + 'setconfig|name,N' + +Modified API commands: + Change pool field name 'Diff1 Shares' to 'Diff1 Work' + 'devs' - add 'Diff1 Work' to all devices + 'gpu|N' - add 'Diff1 Work' + 'pga|N' - add 'Diff1 Work' + 'pools' - add 'Proxy' + 'config' - add 'Queue', 'Expiry' + +---------- + +API V1.18 (BFGMiner v2.7.4) + +Modified API commands: + 'stats' - add 'Work Had Roll Time', 'Work Can Roll', 'Work Had Expire', + and 'Work Roll Time' to the pool stats + 'config' - include 'ScanTime' + +---------- + +API V1.17b (BFGMiner v2.7.1) + +Modified API commands: + 'summary' - add 'Work Utility' + 'pools' - add 'Diff1 Shares' + +---------- + +API V1.17 (BFGMiner v2.6.5) + +Added API commands: + 'coin' + +---------- + +API V1.16 (BFGMiner v2.6.5) + +Added API commands: + 'failover-only' + +Modified API commands: + 'config' - include failover-only state + +---------- + +API V1.15 (BFGMiner v2.5.2) + +Added API commands: + 'poolpriority' + +---------- + +API V1.14 (BFGMiner v2.5.0) + +Modified API commands: + 'stats' - more Icarus timing stats added + 'notify' - include new device comms error counter + +The internal code for handling data was rewritten (~25% of the code) +Completely backward compatible + +---------- + +API V1.13 (BFGMiner v2.4.4) + +Added API commands: + 'check' + +Support was added to BFGMiner for API access groups with the --api-groups option +It's 100% backward compatible with previous --api-access commands + +---------- + +API V1.12 (BFGMiner v2.4.3) + +Modified API commands: + 'stats' - more pool stats added + +Support for the ModMiner FPGA was added + +---------- + +API V1.11 (BFGMiner v2.4.2) + +Modified API commands: + 'save' no longer requires a filename (use default if not specified) + +'save' incorrectly returned status E (error) on success before. +It now correctly returns S (success) + +---------- + +API V1.10 (BFGMiner v2.4.1) + +Added API commands: + 'stats' + +N.B. the 'stats' command can change at any time so any specific content +present should not be relied upon. +The data content is mainly used for debugging purposes or hidden options +in BFGMiner and can change as development work requires. + +Modified API commands: + 'pools' added "Last Share Time" + +---------- + +API V1.9 (BFGMiner v2.4.0) + +Added API commands: + 'restart' + +Modified API commands: + 'notify' corrected invalid JSON + +---------- + +API V1.8 (BFGMiner v2.3.5) + +Added API commands: + 'devdetails' + +Support for the ZTEX FPGA was added. + +---------- + +API V1.8-pre (BFGMiner v2.3.4) + +Added API commands: + 'devdetail' + +---------- + +API V1.7 (BFGMiner v2.3.4) + +Added API commands: + 'removepool' + +Modified API commands: + 'pools' added "User" + +From API version 1.7 onwards, reply strings in JSON and Text have the +necessary escaping as required to avoid ambiguity. +For JSON the 2 characters '"' and '\' are escaped with a '\' before them. +For Text the 4 characters '|' ',' '=' and '\' are escaped the same way. + +---------- + +API V1.6 (cgminer v2.3.2) + +Added API commands: + 'pga' + 'pgaenable' + 'pgadisable' + 'pgacount' + +Modified API commands: + 'devs' now includes Icarus and BitForce FPGA devices. + 'notify' added "*" to the front of the name of all numeric error fields. + 'config' correct "Log Interval" to use numeric (not text) type for JSON. + +Support for Icarus and BitForce FPGAs was added. + +---------- + +API V1.5 was not released + +---------- + +API V1.4 (Kano's interim release of cgminer v2.3.1) + +Added API commands: + 'notify' + +Modified API commands: + 'config' added "Device Code" and "OS" + +Added "When" to the STATUS reply section of all commands. + +---------- + +API V1.3 (cgminer v2.3.1-2) + +Added API commands: + 'addpool' + +Modified API commands: + 'devs'/'gpu' added "Total MH" for each device + 'summary' added "Total MH" + +---------- + +API V1.2 (cgminer v2.3.0) + +Added API commands: + 'enablepool' + 'disablepool' + 'privileged' + +Modified API commands: + 'config' added "Log Interval" + +Starting with API V1.2, any attempt to access a command that requires +privileged security, from an IP address that does not have privileged +security, will return an "Access denied" Error Status. + +---------- + +API V1.1 (cgminer v2.2.4) + +There were no changes to the API commands in cgminer v2.2.4, +however support was added to cgminer for IP address restrictions +with the --api-allow option. + +---------- + +API V1.1 (cgminer v2.2.2) + +Prior to V1.1, devs/gpu incorrectly reported GPU0 Intensity for all GPUs. + +Modified API commands: + 'devs'/'gpu' added "Last Share Pool" and "Last Share Time" for each device + +---------- + +API V1.0 (cgminer v2.2.0) + +Remove default CPU support. + +Added API commands: + 'config' + 'gpucount' + 'cpucount' + 'switchpool' + 'gpuintensity' + 'gpumem' + 'gpuengine' + 'gpufan' + 'gpuvddc' + 'save' + +---------- + +API V0.7 (cgminer v2.1.0) + +Initial release of the API in the main cgminer git + +Commands: + 'version' + 'devs' + 'pools' + 'summary' + 'gpuenable' + 'gpudisable' + 'gpurestart' + 'gpu' + 'cpu' + 'gpucount' + 'cpucount' + 'quit' + +---------------------------------------- + +miner.php +========= + +miner.php is a PHP based interface to the BFGMiner RPC API +(referred to simply as the API below). + +It can show rig details, summaries and input fields to allow you to change +BFGMiner. +You can also create custom summary pages with it + +It has two levels to the security: +1) BFGMiner can be configured to allow or disallow API access and access level + security for miner.php +2) miner.php can be configured to allow or disallow privileged BFGMiner + access, if BFGMiner is configured to allow privileged access for miner.php + +--------- + +To use miner.php requires a web server with PHP. + +Basics: On Xubuntu 11.04, to install Apache and PHP, the commands are: + sudo apt-get install apache2 + sudo apt-get install php5 + sudo /etc/init.d/apache2 reload + +On Fedora 17: + yum install httpd php + systemctl restart httpd.service + systemctl enable httpd.service --system + +On windows there are a few options. +Try one of these (apparently the first one is easiest - thanks jborkl) + http://www.easyphp.org/ + http://www.apachefriends.org/en/xampp.html + http://www.wampserver.com/en/ + +--------- + +The basic BFGMiner option to enable the API is: + + --api-listen + +or in your bfgminer.conf: + + "api-listen" : true, + +(without the ',' on the end if it is the last item.) + +If the web server is running on the BFGMiner computer, the above +is the only change required to give miner.php basic access to +the BFGMiner API. + +- + +If the web server runs on a different computer to BFGMiner, +you will also need to tell BFGMiner to allow the web server +to access BFGMiner's API and tell miner.php where BFGMiner is. + +Assuming a.b.c.d is the IP address of the web server, you +would add the following to BFGMiner: + + --api-listen --api-allow a.b.c.d + +or in your bfgminer.conf: + + "api-listen" : true, + "api-allow" : "a.b.c.d", + +to tell BFGMiner to give the web server read access to the API. + +You also need to tell miner.php where BFGMiner is. +Assuming BFGMiner is at IP address e.f.g.h, then you would +edit miner.php and change the line: + + $rigs = array('127.0.0.1:4028'); + +to + + $rigs = array('e.f.g.h:4028'); + +See --api-network or --api-allow for more access details +and how to give write access. + +You can however, also tell miner.php to find your mining rigs automatically +on the local subnet. + +Add the following to each BFGMiner: + + --api-mcast + +or in your bfgminer.conf: + + "api-mcast" : true, + +And in miner.php set $mcast = true; + +This will ignore the value of $rigs and overwrite it with the list of zero or +more rigs found on the network in the timeout specified. +A rig will not reply if the API settings would mean it would also ignore an +API request from the web server running miner.php + +--------- + +Once you have a web server with PHP running: + + copy your miner.php to the main web folder + +On Xubuntu 11.04: + /var/www/ + +On Fedora 17: + /var/www/html/ + +On Windows: + Please check your windows Web/PHP documentation. + +Assuming the IP address of the web server is a.b.c.d +Then in your web browser go to: + + http://a.b.c.d/miner.php + +Done :) + +--------- + +The rest of this documentation deals with the more complex +functions of miner.php, using myminer.php, creating custom +summaries and displaying multiple BFGMiner rigs. + +--------- + +If you create a file called myminer.php in the same web folder +where you put miner.php, miner.php will load it when it runs. + +This is useful, to put any changes you need to make to miner.php +instead of changing miner.php. +Thus if you update/get a new miner.php, you won't lose the changes +you have made if you put all your changes in myminer.php +(and haven't changed miner.php at all) + +A simple example myminer.php that defines 2 rigs +(that I will keep referring to further below) is: + + + +Changes in myminer.php supersede what is in miner.php +However, this is only valid for variables in miner.php before the +2 lines where myminer.php is included by miner.php: + + if (file_exists('myminer.php')) + include_once('myminer.php'); + +Every variable in miner.php above those 2 lines, can be changed by +simply defining them in your myminer.php + +So although miner.php originally contains the line: + + $rigs = array('127.0.0.1:4028'); + +if you created the example myminer.php given above, it would actually +change the value of $rigs that is used when miner.php is running. +i.e. you don't have to remove or comment out the $rigs line in miner.php +It will be superseded by myminer.php + +--------- + +The example myminer.php above also shows how to define more that one rig +to be shown my miner.php: + +Each rig string is 2 or 3 values separated by colons ':' +They are simply an IP address or hostname, followed by the +port number (usually 4028) and an optional Name string. + +miner.php displays rig buttons that will show the details of a single +rig when you click on it - the button shows either the rig number, +or the 'Name' string if you provide it. + +PHP arrays contain each string separated by a comma, but no comma after +the last one. + +So an example for 3 rigs would be: + + $rigs = array('192.168.0.100:4028:A', '192.168.0.102:4028:B', + '192.168.0.110:4028:C'); + +Of course each of the rigs listed would also have to have the API +running and be set to allow the web server to access the API - as +covered earlier in this document. + +--------- + +So basically, any variable explained below can be put in myminer.php if you want +to set it to something different to its default value and did not want to change +miner.php itself every time you update it. + +Below is a list of the variables that can be changed and an explanation of each. + +--------- + +Default: + $dfmt = 'H:i:s j-M-Y \U\T\CP'; + +Define the date format used to print full length dates. +If you get the string 'UTCP' on the end of your dates shown, that +means you are using an older version of PHP and you can instead use: + $dfmt = 'H:i:s j-M-Y \U\T\CO'; + +The PHP documentation on the date format is here: + http://us.php.net/manual/en/function.date.php + +--------- + +Default: + $title = 'Mine'; + +Web page title. +If you know PHP you can of course use code to define it e.g. + $title = 'My Rig at: '.date($dfmt); + +Which would set the web page title to something like: + My Rig at: 10:34:00 22-Aug-2012 UTC+10:00 + +--------- + +Default: + $readonly = false; + +Set $readonly to true to force miner.php to be readonly. +This means it won't allow you to change BFGMiner even if the RPC API +options allow it to. + +If you set $readonly to false then it will check BFGMiner 'privileged' +and will show input fields and buttons on the single rig page, +allowing you to change devices, pools and even quit or restart +BFGMiner. + +However, if the 'privileged' test fails, the code will set $readonly to +true. + +--------- + +Default: + $userlist = null; + +Define password checking and default access null means there is no password +checking. + +$userlist is an array of 3 arrays, e.g. +$userlist = array('sys' => array('boss' => 'bpass'), + 'usr' => array('user' => 'upass', 'pleb' => 'ppass'), + 'def' => array('Pools')); + +'sys' is an array of system users and passwords (full access). +'usr' is an array of user level users and passwords (readonly access). +'def' is an array of custompages that anyone not logged in can view. + +Any of the 3 can be null, meaning there are none of that item. + +All validated 'usr' users are given $readonly = true; access. +All validated 'sys' users are given the $readonly access you defined. + +If 'def' has one or more values, and allowcustompages is true, then anyone +without a password can see the list of custompage buttons given in 'def' and +will see the first one when they go to the web page, with a login button at the +top right. + +From the login page, if you login with no username or password, it will show +the first 'def' custompage (if there are any). + +If you are logged in, it will show a logout button at the top right. + +--------- + +Default: + $notify = true; + +Set $notify to false to NOT attempt to display the notify command table of data + +Set $notify to true to attempt to display the notify command on the single rig +page. +If your older version of BFGMiner returns an 'Invalid command' because it +doesn't have notify - it just shows the error status table. + +--------- + +Default: + $checklastshare = true; + +Set $checklastshare to true to do the following checks: +If a device's last share is 12x expected ago then display as an error. +If a device's last share is 8x expected ago then display as a warning. +If either of the above is true, also display the whole line highlighted +This assumes shares are 1 difficulty shares. + +Set $checklastshare to false to not do the above checks. + +'expected' is calculated from the device Mh/s value. +So for example, a device that hashes at 380Mh/s should (on average) find a +share every 11.3s. +If the last share was found more than 11.3 x 12 seconds (135.6s) ago, it is +considered an error and highlighted. +If the last share was found more than 11.3 x 8 seconds (90.4s) ago, it is +considered a warning and highlighted. + +The default highlighting is very subtle, so change it if you want it to be more +obvious. + +--------- + +Default: + $poolinputs = false; + +Set $poolinputs to true to show the input fields for adding a pool and changing +the pool priorities on a single rig page. +However, if $readonly is true, it will not display them. + +--------- + +Default: + $rigport = 4028; + +Default port to use if any $rigs entries don't specify the port number + +--------- + +Default: + $rigs = array('127.0.0.1:4028'); + +Set $rigs to an array of your BFGMiner rigs that are running format: 'IP' or + 'Host' or 'IP:Port' or 'Host:Port' or 'Host:Port:Name'. +If you only have one rig, it will just show the detail of that rig. +If you have more than one rig it will show a summary of all the rigs with + buttons to show the details of each rig - the button contents will be 'Name' + rather than rig number, if you specify 'Name'. +If Port is missing or blank, it will try $rigport +e.g. $rigs = array('127.0.0.1:4028','myrig.com:4028:Sugoi'); + +--------- + +Default: + $rignames = false; + +Set $rignames to false to not affect the display. +Set $rignames to one of 'ip' or 'ipx' to alter the name displayed +if the rig doesn't have a 'name' in $rigs +Currently: + 'ip' means use the 4th byte of the rig IP address as an integer + 'ipx' means use the 4th byte of the rig IP address as 2 hex bytes + +--------- + +Default: + $rigbuttons = true; + +Set $rigbuttons to false to display a link rather than a button on +the left of any summary table with rig buttons, in order to reduce +the height of the table cells + +--------- + +Default: + $mcast = false; + +Set $mcast to true to look for your rigs and ignore $rigs. + +--------- + +Default: + $mcastexpect = 0; + +The minimum number of rigs expected to be found when $mcast is true. +If fewer are found, an error will be included at the top of the page. + +--------- + +Default: + $mcastaddr = '224.0.0.75'; + +API Multicast address all miners are listening on. + +--------- + +Default: + $mcastport = 4028; + +API Multicast UDP port all miners are listening on. + +--------- + +Default: + $mcastcode = 'FTW'; + +The code all miners expect in the Multicast message sent. +The message sent is "cgm-code-listport". +Don't use the '-' character if you change it. + +--------- + +Default: + $mcastlistport = 4027; + +UDP port number that is added to the broadcast message sent +that specifies to the miners the port to reply on. + +--------- + +Default: + $mcasttimeout = 1.5; + +Set $mcasttimeout to the number of seconds (floating point) +to wait for replies to the Multicast message. +N.B. the accuracy of the timing used to wait for the replies is +~0.1s so there's no point making it more than one decimal place. + +--------- + +Default: + $mcastretries = 0; + +Set $mcastretries to the number of times to retry the multicast. + +If $mcastexpect is 0, this is simply the number of extra times +that it will send the multicast request. +N.B. BFGMiner doesn't listen for multicast requests for 1000ms after +each one it hears. + +If $mcastexpect is > 0, it will stop looking for replies once it +has found at least $mcastexpect rigs, but it only checks this rig +limit each time it reaches the $mcasttimeout limit, thus it can find +more than $mcastexpect rigs if more exist. +It will send the multicast message up to $mcastretries extra times or +until it has found at least $mcastexpect rigs. +When using $mcastretries, it is however possible for it to sometimes +ignore some rigs on the network if $mcastexpect is less than the +number of rigs on the network and some rigs are too slow to reply. + +--------- + +Default: + $allowgen = false; + +Set $allowgen to true to allow customsummarypages to use 'gen', +false means ignore any 'gen' options. +This is disabled by default due to the possible security risk +of using it, please see the end of this document for an explanation. + +--------- + +Default: + $rigipsecurity = true; + +Set $rigipsecurity to false to show the IP/Port of the rig in the socket error + messages and also show the full socket message. + +--------- + +Default: + $rigtotals = true; + $forcerigtotals = false; + +Set $rigtotals to true to display totals on the single rig page, 'false' means + no totals (and ignores $forcerigtotals). + +If $rigtotals is true, all data is also right aligned. +With false, it's as before, left aligned. + +This option is just here to allow people to set it to false if they prefer the + old non-total display when viewing a single rig. + +Also, if there is only one line shown in any section, then no total will be + shown (to save screen space). +You can force it to always show rig totals on the single rig page, even if + there is only one line, by setting $forcerigtotals = true; + +--------- + +Default: + $socksndtimeoutsec = 10; + $sockrcvtimeoutsec = 40; + +The numbers are integer seconds. + +The defaults should be OK for most cases. +However, the longer SND is, the longer you have to wait while PHP hangs if the +target BFGMiner isn't running or listening. + +RCV should only ever be relevant if BFGMiner has hung but the API thread is +still running, RCV would normally be >= SND. + +Feel free to increase SND if your network is very slow or decrease RCV if that +happens often to you. + +Also, on some windows PHP, apparently the $usec is ignored (so usec can't be +specified). + +--------- + +Default: + $hidefields = array(); + +List of fields NOT to be displayed. +You can use this to hide data you don't want to see or don't want shown on a +public web page. +The list of sections are: + SUMMARY, POOL, PGA, GPU, NOTIFY, CONFIG, DEVDETAILS, DEVS +See the web page for the list of field names (the table headers). +It is an array of 'SECTION.Field Name' => 1 + +This example would hide the slightly more sensitive pool information: +Pool URL and pool username: + $hidefields = array('POOL.URL' => 1, 'POOL.User' => 1); + +If you just want to hide the pool username: + $hidefields = array('POOL.User' => 1); + +--------- + +Default: + $ignorerefresh = false; + $changerefresh = true; + $autorefresh = 0; + +Auto-refresh of the page (in seconds) - integers only. + +$ignorerefresh = true/false always ignore refresh parameters. +$changerefresh = true/false show buttons to change the value. +$autorefresh = default value, 0 means don't auto-refresh. + +--------- + +Default: + $placebuttons = 'top'; + +Where to place the Refresh, Summary, Custom Pages, Quit, etc. buttons. + +Valid values are: 'top' 'bot' 'both' + Anything else means don't show them. (case sensitive) + +--------- + +Default: + $miner_font_family = 'verdana,arial,sans'; + $miner_font_size = '13pt'; + +Change these to set the font and font size used on the web page. + +--------- + +Default: + $colouroverride = array(); + +Use this to change the web page colour scheme. + +See $colourtable in miner.php for the list of possible names to change. + +Simply put in $colouroverride, just the colours you wish to change. + +e.g. to change the colour of the header font and background +you could do the following: + + $colouroverride = array( + 'td.h color' => 'green', + 'td.h background' => 'blue' + ); + +--------- + +Default: + $allowcustompages = true; + +Should we allow custom pages? +(or just completely ignore them and don't display the buttons.) + +--------- + +OK this part is more complex: Custom Summary Pages. + +A custom summary page in an array of 'section' => array('FieldA','FieldB'...) + +The section defines what data you want in the summary table and the Fields +define what data you want shown from that section. + +Standard sections are: + SUMMARY, POOL, PGA, GPU, NOTIFY, CONFIG, DEVDETAILS, DEVS, STATS, COIN + +Fields are the names as shown on the headers on the normal pages. + +Fields can be 'name=new name' to display 'name' with a different heading +'new name'. + +There are also now joined sections: + SUMMARY+POOL, SUMMARY+DEVS, SUMMARY+CONFIG, DEVS+NOTIFY, DEVS+DEVDETAILS + SUMMARY+COIN + +These sections are an SQL join of the two sections and the fields in them +are named section.field where 'section.' is the section the field comes from +See the example further down. + +Also note: +- empty tables are not shown. +- empty columns (e.g. an unknown field) are not shown. +- missing field data shows as blank. +- the field name '*' matches all fields except in joined sections + (useful for STATS and COIN). + +There are 2 hard coded sections: + DATE - displays a date table like at the start of 'Summary'. + RIGS - displays a rig table like at the start of 'Summary'. + +Each custom summary requires a second array, that can be empty, listing fields +to be totalled for each section. +If there is no matching total data, no total will show. + +--------- + +Looking at the Mobile example: + + $mobilepage = array( + 'DATE' => null, + 'RIGS' => null, + 'SUMMARY' => array('Elapsed', 'MHS av', 'Found Blocks=Blks', + Accepted', 'Rejected=Rej', 'Utility'), + 'DEVS+NOTIFY' => array('DEVS.Name=Name', 'DEVS.ID=ID', 'DEVS.ProcID=Proc', + 'DEVS.Status=Status', + 'DEVS.Temperature=Temp', 'DEVS.MHS av=MHS av', + 'DEVS.Accepted=Accept', 'DEVS.Rejected=Rej', + 'DEVS.Utility=Utility', 'NOTIFY.Last Not Well=Not Well'), + 'POOL' => array('POOL', 'Status', 'Accepted', 'Rejected=Rej', + 'Last Share Time')); + + $mobilesum = array( + 'SUMMARY' => array('MHS av', 'Found Blocks', 'Accepted', 'Rejected', + 'Utility'), + 'DEVS+NOTIFY' => array('DEVS.MHS av', 'DEVS.Accepted', 'DEVS.Rejected', + 'DEVS.Utility'), + 'POOL' => array('Accepted', 'Rejected')); + + $customsummarypages = array('Mobile' => array($mobilepage, $mobilesum)); + +This will show 5 tables (according to $mobilepage). +Each table will have the chosen details for all the rigs specified in $rigs + + DATE + A single box with the web server's current date and time. + + RIGS + A table of the rigs: description, time, versions etc. + + SUMMARY + + This will use the API 'summary' command and show the selected fields: + Elapsed, MHS av, Found Blocks, Accepted, Rejected and Utility + However, 'Rejected=Rej' means that the header displayed for the 'Rejected' + field will be 'Rej', instead of 'Rejected' (to save space). + Same for 'Found Blocks=Blks' - to save space. + + DEVS+NOTIFY + + This will list each of the devices on each rig and display the list of + fields as shown. + It will also include the 'Last Not Well' field from the 'notify' command + so you know when the device was last not well. + + You will notice that you need to rename each field e.g. 'DEVS.Name=Name' + since each field name in the join between DEVS and NOTIFY is actually + section.fieldname, not just fieldname. + + The join code automatically adds 2 fields to each GPU device: 'Name', 'ID', + and 'ProcID'. They don't exist in the API 'devs' output but we can correctly + calculate them from the GPU device data. These two fields are used to join + DEVS to NOTIFY: i.e. find the NOTIFY record that has the same Name/ID/ProcID + as the DEVS record and join them. + + POOL + + This will use the API 'pools' command and show the selected fields: + POOL, Status, Accepted, Rejected, Last Share Time + Again, I renamed the 'Rejected' field using 'Rejected=Rej', to save space. + +$mobilesum lists the sections and fields that should have a total. +You can't define them for 'DATE' or 'RIGS' since they are hard coded tables. +The example given: + + SUMMARY + Show a total at the bottom of the columns for: + MHS av, Found Blocks, Accepted, Rejected, Utility + + Firstly note that you use the original name i.e. for 'Rejected=Rej' + you use 'Rejected', not 'Rej' and not 'Rejected=Rej'. + + Secondly note that it simply adds up the fields. + If you ask for a total of a string field you will get the numerical + sum of the string data. + + DEVS+NOTIFY + + Simply note in this join example that you must use the original field + names which are section.fieldname, not just fieldname. + + POOL + Show a total at the bottom of the columns for: + Accepted and Rejected + + Again remember to use the original field name 'Rejected'. + +--------- + +With BFGMiner 2.10.1 and later, miner.php includes an extension to the custom +pages that allows you to apply SQL style commands to the data: where, group, +and having +BFGMiner 3.4.0 also includes another option 'gen'. + +As an example, miner.php includes a more complex custom page called 'Pools' +which includes the extension: + +$poolsext = array( + 'POOL+STATS' => array( + 'where' => null, + 'group' => array('POOL.URL', 'POOL.Has Stratum', + 'POOL.Stratum Active'), + 'calc' => array('STATS.Bytes Sent' => 'sum', + 'STATS.Bytes Recv' => 'sum'), + 'gen' => array('AvShr', 'POOL.Difficulty Accepted/max(POOL.Accepted,1)), + 'having' => array(array('STATS.Bytes Recv', '>', 0))) +); + +This allows you to group records together from one or more rigs. +In the example, you'll get each Pool (with the same URL+Stratum info) listed +once for all rigs and a sum of each of the fields listed in 'calc'. + + +'where' and 'having' are an array of fields and restrictions to apply. + +In the above example, it will only display the rows where it contains the +'STATS.Bytes Recv' field with a value greater than zero. +If the row doesn't have the field, it will always be included. +All restrictions must be true in order for the row to be included. +Any restiction that is invalid or unknown is true. +An empty array, or null, means there are no restrictions. + +A restriction is formatted as: array('Field', 'restriction', 'value') +Field is the simple field name as normally displayed, or SECTION.Field if it is +a joined section (as in this case 'POOL+STATS'). +The list of restrictions are: +'set' - true if the row contains the 'Field' ('value' is not required or used) +'=', '<', '<=', '>', '>' - a numerical comparison. +'eq', 'lt', 'le', 'gt', 'ge' - a case insensitive string comparison. + +You can have multiple restrictions on a 'Field' - but all must be true to +include the row containing the 'Field'. +e.g. a number range between 0 and 10 would be: +array('STATS.Bytes Recv', '>', 0), array('STATS.Bytes Recv', '<', 10) + +The difference between 'where' and 'having' is that 'where' is applied to the +data before grouping it and 'having' is applied to the data after grouping it +- otherwise they work the same. + + +'group' lists the fields to group over and 'calc' lists the function to apply +to other fields that are not part of 'group'. + +You can only see fields listed in 'group' and 'calc'. + +A 'calc' is formatted as: 'Field' => 'function' +The current list of operations available for 'calc' are: +'sum', 'avg', 'min', 'max', 'lo', 'hi', 'count', 'any' +The first 4 are as expected - the numerical sum, average, minimum or maximum. +'lo' is the first string of the list, sorted ignoring case. +'hi' is the last string of the list, sorted ignoring case. +'count' is the number of rows in the section specified in the calc e.g. + ('DEVS.Name' => 'count') would be the number of DEVS selected in the 'where' + of course any valid 'DEVS.Xyz' would give the same 'count' value. +'any' is effectively random: the field value in the 1st row of the grouped data. +An unrecognised 'function' uses 'any'. + +A 'gen' allows you to generate new fields from any php valid function of any +of the other fields. + e.g. 'gen' => array('AvShr', 'POOL.Difficulty Accepted/max(POOL.Accepted,1)), +will generate a new field called GEN.AvShr that is the function shown, which +in this case is the average difficulty of each share submitted. + +THERE IS A SECURITY RISK WITH HOW GEN WORKS! +It simply replaces all the variables with their values and then requests PHP +to execute the formula - thus if a field value returned from a BFGMiner API +request contained PHP code, it could be executed by your web server. +Of course BFGMiner doesn't do this, but if you do not control the BFGMiner that +returns the data in the API calls, someone could modify BFGMiner to return a +PHP string in a field you use in 'gen'. +Thus use 'gen' at your own risk. +If someone feels the urge to write a mathematical interpreter in PHP to get +around this risk, feel free to write one and submit it to the API author for +consideration. diff --git a/README.scrypt b/README.scrypt new file mode 100644 index 0000000000..f609e6b2c0 --- /dev/null +++ b/README.scrypt @@ -0,0 +1,242 @@ +If you wish to donate to the author of scrypt support, Con Kolivas, for his past +work (he no longer maintains this), please send your donations to: +15qSxP1SQcUX3o4nhkfdbgyoWEFMomJ4rZ + +--- + +Scrypt mining for GPU is completely different to sha256 used for bitcoin +mining. It has very different requirements to bitcoin mining and is a +lot more complicated to get working well. Note that it is a ram dependent +workload, and requires you to have enough system ram as well as fast enough +GPU ram. + +Since scrypt ASICs are widely available, GPUs are not used by default. If you +want to use them, use the -S opencl:auto option. Note that scrypt ASICs are +documented in README.ASIC rather than this file, which only deals with GPU +mining. + +There are 5 main parameters to tuning scrypt, all of which are optional for +further fine tuning. When you start scrypt mining with the --scrypt option, +BFGMiner will fail IN RANDOM WAYS. They are all due to parameters being outside +what the GPU can cope with. + +NOTE that if it does not fail at startup, the presence of hardware errors (HW) +are a sure sign that you have set the parameters too high. + + +DRIVERS AND OPENCL SDK + +The choice of driver version for your GPU is critical, as some are known to +break scrypt mining entirely while others give poor hashrates. As for the +OpenCL SDK installed, for AMD it must be version 2.6 or later. + + +Step 1 on Linux: +export GPU_MAX_ALLOC_PERCENT=100 +If you do not do this, you may find it impossible to scrypt mine. You may find +a value of 40 is enough and increasing this further has little effect. + +export GPU_USE_SYNC_OBJECTS=1 +may help CPU usage a little as well. + +On windows the same commands can be passed via a batch file if the following +lines are in the .bat before starting BFGMiner: +setx GPU_MAX_ALLOC_PERCENT 100 +setx GPU_USE_SYNC_OBJECTS 1 + +intensity=XX + +Just like in Bitcoin mining, scrypt mining takes an intensity, however the +scale goes from 0 to 31. +The reason this is crucial is that too high an intensity can actually be +disastrous with scrypt because it CAN run out of ram. High intensities +start writing over the same ram and it is highly dependent on the GPU, but they +can start actually DECREASING your hashrate, or even worse, start producing +garbage with HW errors skyrocketing. Note that if you do NOT specify an +intensity, BFGMiner uses dynamic mode which is designed to minimise the harm +to a running desktop and performance WILL be poor. The lower limit to intensity +with scrypt is usually 8 and BFGMiner will prevent it going too low. +SUMMARY: Setting this for reasonable hashrates is mandatory. + +shaders=XXX + +is a new option where you tell BFGMiner how many shaders your GPU has. This +helps BFGMiner try to choose some meaningful baseline parameters. Use this table +below to determine how many shaders your GPU has, and note that there are some +variants of these cards, and Nvidia shaders are much much lower and virtually +pointless trying to mine on. If this is not set, BFGMiner will query the +device for how much memory it supports and will try to set a value based on +that instead. +SUMMARY: This will get you started but fine tuning for optimal performance is +required. + +GPU Shaders +7750 512 +7770 640 +7850 1024 +7870 1280 +7950 1792 +7970 2048 + +6850 960 +6870 1120 +6950 1408 +6970 1536 +6990 (6970x2) + +6570 480 +6670 480 +6790 800 + +6450 160 + +5670 400 +5750 720 +5770 800 +5830 1120 +5850 1440 +5870 1600 +5970 (5870x2) + +These are only used as a rough guide for BFGMiner, and it is rare that this is +all you will need to set. + + +Optional parameters to tune: +kernel, threads, thread-concurrency, lookup-gap + +kernel: +This selects the OpenCL code to use. By default, the kernel named "scrypt" will +be used. BFGMiner also includes optimised versions from Zuikkis and Pavel +Semjanov, which you can specify by filename: + --set-device OCL:kernel=zuikkis + --set-device OCL:kernel=psw +Note that Zuikkis' version requires the default lookup-gap of 2. + +thread-concurrency: +This tunes the optimal size of work that scrypt can do. It is internally tuned +by BFGMiner to be the highest reasonable multiple of shaders that it can +allocate on your GPU. Ideally it should be a multiple of your shader count. +vliw5 architecture (R5XXX) would be best at 5x shaders, while VLIW4 (R6xxx and +R7xxx) are best at 4x. Setting thread concurrency overrides anything you put +into the shaders config and is ultimately a BETTER way to tune performance. +SUMMARY: Spend lots of time finding the highest value that your device likes +and increases hashrate. + +threads: +Once you have found the optimal shaders and intensity, you can start increasing +the threads value till BFGMiner fails to start. This is really only of value if +you want to run low intensities as you will be unable to run more than 1. +SUMMARY: Don't touch this. + +lookup-gap: +This tunes a compromise between ram usage and performance. Performance peaks +at a gap of 2, but increasing the gap can save you some GPU ram, but almost +always at the cost of significant loss of hashrate. Setting lookup gap +overrides the default of 2, but BFGMiner will use the provided shaders value to +choose a thread-concurrency if you haven't chosen one. +SUMMARY: Don't touch this. + + +Related parameters: +work_size=XX +Has a minor effect, should be a multiple of 64 up to 256 maximum. +SUMMARY: Worth playing with once everything else has been tried but will +probably do nothing. + +vectors=XX +Vectors are NOT used by scrypt mining kernels. +SUMMARY: Does nothing. + + +Overclocking for scrypt mining: +First of all, do not underclock your memory initially. Scrypt mining requires +memory speed and on most, but not all, GPUs, lowering memory speed lowers +mining performance. + +Second, absolute engine clock speeds do NOT correlate with hashrate. The ratio +of engine clock speed to memory matters, so if you set your memory to the +default value, and then start overclocking as you are running it, you should +find a sweet spot where the hashrate peaks and then it might actually drop if +you increase the engine clock speed further. + +Third, the combination of motherboard, CPU and system ram ALSO makes a +difference, so values that work for a GPU on one system may not work for the +same GPU on a different system. A decent amount of system ram is actually +required for scrypt mining, and 4GB is suggested. + +Finally, the power consumption while mining at high engine clocks, very high +memory clocks can be far in excess of what you might imagine. +For example, a 7970 running with the following settings: +--set-device OCL:thread-concurrency=22392 --set-device OCL:clock=1135 +--set-device OCL:memclock=1890 +was using 305W! + +--- +TUNING AN AMD RADEON 7970 +Example tuning a 7970 for Scrypt mining: + +On Linux run this command: +export GPU_MAX_ALLOC_PERCENT=100 +or on Windows this: +setx GPU_MAX_ALLOC_PERCENT 100 +in the same console/bash/dos prompt/bat file/whatever you want to call it, +before running BFGMiner. + +First, find the highest thread concurrency that you can start it at. They should +all start at 8192 but some will go up to 3 times that. Don't go too high on the +intensity while testing and don't change gpu threads. If you cannot go above +8192, don't fret as you can still get a high hashrate. + +Delete any .bin files so you're starting from scratch and see what bins get +generated. + +First try without any thread concurrency or even shaders, as BFGMiner will try to +find an optimal value: +bfgminer --set-device OCL:intensity=13 + +If that starts mining, see what bin was generated, it is likely the largest +meaningful TC you can set. +Starting it on mine I get: +scrypt130302Tahitiglg2tc22392w64l8.bin + +Note that tc22392 tells you what thread concurrency it was. It should start +without TC parameters, but you never know. So if it doesn't, start with +--set-device OCL:thread-concurrency=8192 and add 2048 to it at a time till you +find the highest value it will start successfully at. + +If you wish to get a little extra from your hardware, you may also try +overclocking. Do note that this will damage your GPUs and void your warranty, +so unless you are willing to take that risk, skip the clock and memclock +parameters! + +Then start overclocking the eyeballs off your memory, as 7970s are exquisitely +sensitive to memory speed and amazingly overclockable but please make sure it +keeps adequately cooled with --auto-fan! Do it while it's running from the GPU +menu. Go up by 25 at a time every 30 seconds or so until your GPU crashes. Then +reboot and start it 25 lower as a rough start. One example runs stable at 1900 +memory without overvolting. + +Then once you find the maximum memory clock speed, you need to find the sweet +spot engine clock speed that matches it. It's a fine line where one more MHz +will make the hashrate drop by 20%. It's somewhere in the .57 - 0.6 ratio range. +Start your engine clock speed at half your memory clock speed and then increase +it by 5 at a time. The hashrate should climb a little each rise in engine speed +and then suddenly drop above a certain value. Decrease it by 1 then until you +find it climbs dramatically. If your engine clock speed cannot get that high +without crashing the GPU, you will have to use a lower memclock. + +Then, and only then, bother trying to increase intensity further. + +My final settings were: +--set-device OCL:clock=1141 --set-device OCL:memclock=1875 --set-device OCL:intensity=20 +for a hashrate of 745kH. + +Note I did not bother setting a thread concurrency. Once you have the magic +endpoint, look at what tc was chosen by the bin file generated and then hard +code that in next time (eg --set-device OCL:thread-concurrency=22392) as slight +changes in thread concurrency will happen every time if you don't specify one, +and the tc to clock ratios are critical! + +Your numbers will be your numbers depending on your hardware combination and OS, +so don't expect to get exactly the same results! diff --git a/adl.c b/adl.c index 7f584b84c9..3575a60e2e 100644 --- a/adl.c +++ b/adl.c @@ -1,5 +1,6 @@ /* - * Copyright 2011-2012 Con Kolivas + * Copyright 2011-2013 Con Kolivas + * Copyright 2012-2014 Luke Dashjr * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -9,21 +10,25 @@ #include "config.h" -#if defined(HAVE_ADL) && (defined(__linux) || defined (WIN32)) +#ifdef HAVE_ADL #include #include #include #ifdef HAVE_CURSES +// Must be before stdbool, since pdcurses typedefs bool :/ #include #endif +#include + +#include "driver-opencl.h" #include "miner.h" -#include "ADL_SDK/adl_sdk.h" +#include "ADL/adl_sdk.h" #include "compat.h" -#if defined (__linux) +#ifndef WIN32 #include #include #include @@ -33,6 +38,10 @@ #endif #include "adl_functions.h" +#ifndef __stdcall +#define __stdcall +#endif + #ifndef HAVE_CURSES #define wlogprint(...) applog(LOG_WARNING, __VA_ARGS__) #endif @@ -40,7 +49,7 @@ bool adl_active; bool opt_reorder = false; -int opt_hysteresis = 3; +static const int opt_targettemp = 75; const int opt_overheattemp = 85; static pthread_mutex_t adl_lock; @@ -69,7 +78,7 @@ static void __stdcall ADL_Main_Memory_Free (void **lpBuffer) } } -#if defined (LINUX) +#ifndef WIN32 // equivalent functions in linux static void *GetProcAddress(void *pLibrary, const char *name) { @@ -95,9 +104,9 @@ static ADL_OVERDRIVE5_POWERCONTROL_GET ADL_Overdrive5_PowerControl_Get; static ADL_OVERDRIVE5_POWERCONTROL_SET ADL_Overdrive5_PowerControl_Set; static ADL_OVERDRIVE5_FANSPEEDTODEFAULT_SET ADL_Overdrive5_FanSpeedToDefault_Set; -#if defined (LINUX) +#ifndef WIN32 static void *hDLL; // Handle to .so library -#else +#else /* WIN32 */ HINSTANCE hDLL; // Handle to DLL #endif static int iNumberAdapters; @@ -133,14 +142,17 @@ static bool prepare_adl(void) { int result; -#if defined (LINUX) - hDLL = dlopen( "libatiadlxx.so", RTLD_LAZY|RTLD_GLOBAL); -#else +#if defined(WIN32) || defined(__CYGWIN__) +# ifdef __CYGWIN__ +# define LoadLibrary(x) dlopen(x, RTLD_LAZY|RTLD_GLOBAL); +# endif hDLL = LoadLibrary("atiadlxx.dll"); if (hDLL == NULL) // A 32 bit calling application on 64 bit OS will fail to LoadLIbrary. // Try to load the 32 bit library (atiadlxy.dll) instead hDLL = LoadLibrary("atiadlxy.dll"); +#else + hDLL = dlopen( "libatiadlxx.so", RTLD_LAZY|RTLD_GLOBAL); #endif if (hDLL == NULL) { applog(LOG_INFO, "Unable to load ati adl library"); @@ -241,12 +253,18 @@ void init_adl(int nDevs) result = ADL_Adapter_ID_Get(iAdapterIndex, &lpAdapterID); if (result != ADL_OK) { applog(LOG_INFO, "Failed to ADL_Adapter_ID_Get. Error %d", result); - continue; + if (result == -10) + applog(LOG_INFO, "This error says the device is not enabled"); } - + else /* Each adapter may have multiple entries */ if (lpAdapterID == last_adapter) continue; + else + if (!lpAdapterID) + applog(LOG_INFO, "Adapter returns ID 0 meaning not AMD. Card order might be confused"); + else + last_adapter = lpAdapterID; applog(LOG_DEBUG, "GPU %d " "iAdapterIndex %d " @@ -279,12 +297,6 @@ void init_adl(int nDevs) applog(LOG_ERR, "Use the gpu map feature to reliably map OpenCL to ADL"); devs_match = false; } - last_adapter = lpAdapterID; - - if (!lpAdapterID) { - applog(LOG_INFO, "Adapter returns ID 0 meaning not AMD. Card order might be confused"); - continue; - } } if (devices < nDevs) { @@ -301,12 +313,14 @@ void init_adl(int nDevs) /* Apply manually provided OpenCL to ADL mapping, if any */ for (i = 0; i < nDevs; i++) { - if (gpus[i].mapped) { - vadapters[gpus[i].virtual_adl].virtual_gpu = i; - applog(LOG_INFO, "Mapping OpenCL device %d to ADL device %d", i, gpus[i].virtual_adl); - } + struct opencl_device_data * const data = gpus[i].device_data; + if (data->mapped) { + vadapters[data->virtual_adl].virtual_gpu = i; + applog(LOG_INFO, "Mapping OpenCL device %d to ADL device %d", i, data->virtual_adl); + } else + data->virtual_adl = i; } - + if (!devs_match) { applog(LOG_ERR, "WARNING: Number of OpenCL and ADL devices did not match!"); applog(LOG_ERR, "Hardware monitoring may NOT match up with devices!"); @@ -337,44 +351,53 @@ void init_adl(int nDevs) } } + if (devices > nDevs) + devices = nDevs; + for (gpu = 0; gpu < devices; gpu++) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; int iAdapterIndex; int lpAdapterID; ADLODPerformanceLevels *lpOdPerformanceLevels; - int lev; + int lev, adlGpu; - i = vadapters[gpu].id; + adlGpu = data->virtual_adl; + i = vadapters[adlGpu].id; iAdapterIndex = lpInfo[i].iAdapterIndex; - gpus[gpu].virtual_gpu = vadapters[gpu].virtual_gpu; + data->virtual_gpu = vadapters[adlGpu].virtual_gpu; /* Get unique identifier of the adapter, 0 means not AMD */ result = ADL_Adapter_ID_Get(iAdapterIndex, &lpAdapterID); if (result != ADL_OK) { applog(LOG_INFO, "Failed to ADL_Adapter_ID_Get. Error %d", result); - continue; + lpAdapterID = -1; } if (gpus[gpu].deven == DEV_DISABLED) { - gpus[i].gpu_engine = - gpus[i].gpu_memclock = - gpus[i].gpu_vddc = - gpus[i].gpu_fan = - gpus[i].gpu_powertune = 0; + data->gpu_engine = + data->gpu_memclock = + data->gpu_vddc = + data->gpu_fan = + data->gpu_powertune = 0; continue; } applog(LOG_INFO, "GPU %d %s hardware monitoring enabled", gpu, lpInfo[i].strAdapterName); - if (gpus[gpu].name) + if (gpus[gpu].name) { free((void*)gpus[gpu].name); - gpus[gpu].name = lpInfo[i].strAdapterName; - gpus[gpu].has_adl = true; + gpus[gpu].name = NULL; + } + if (lpInfo[i].strAdapterName[0]) + gpus[gpu].name = trimmed_strdup(lpInfo[i].strAdapterName); + data->has_adl = true; /* Flag adl as active if any card is successfully activated */ adl_active = true; /* From here on we know this device is a discrete device and * should support ADL */ - ga = &gpus[gpu].adl; + ga = &data->adl; ga->gpu = gpu; ga->iAdapterIndex = iAdapterIndex; ga->lpAdapterID = lpAdapterID; @@ -405,8 +428,8 @@ void init_adl(int nDevs) /* Save these values as the defaults in case we wish to reset to defaults */ ga->DefPerfLev = lpOdPerformanceLevels; - if (gpus[gpu].gpu_engine) { - int setengine = gpus[gpu].gpu_engine * 100; + if (data->gpu_engine) { + int setengine = data->gpu_engine * 100; /* Lower profiles can't have a higher setting */ for (j = 0; j < lev; j++) { @@ -414,38 +437,38 @@ void init_adl(int nDevs) lpOdPerformanceLevels->aLevels[j].iEngineClock = setengine; } lpOdPerformanceLevels->aLevels[lev].iEngineClock = setengine; - applog(LOG_INFO, "Setting GPU %d engine clock to %d", gpu, gpus[gpu].gpu_engine); + applog(LOG_INFO, "Setting GPU %d engine clock to %d", gpu, data->gpu_engine); ADL_Overdrive5_ODPerformanceLevels_Set(iAdapterIndex, lpOdPerformanceLevels); ga->maxspeed = setengine; - if (gpus[gpu].min_engine) - ga->minspeed = gpus[gpu].min_engine * 100; + if (data->min_engine) + ga->minspeed = data->min_engine * 100; ga->managed = true; - if (gpus[gpu].gpu_memdiff) - set_memoryclock(gpu, gpus[gpu].gpu_engine + gpus[gpu].gpu_memdiff); + if (data->gpu_memdiff) + set_memoryclock(gpu, data->gpu_engine + data->gpu_memdiff); } - if (gpus[gpu].gpu_memclock) { - int setmem = gpus[gpu].gpu_memclock * 100; + if (data->gpu_memclock) { + int setmem = data->gpu_memclock * 100; for (j = 0; j < lev; j++) { if (lpOdPerformanceLevels->aLevels[j].iMemoryClock > setmem) lpOdPerformanceLevels->aLevels[j].iMemoryClock = setmem; } lpOdPerformanceLevels->aLevels[lev].iMemoryClock = setmem; - applog(LOG_INFO, "Setting GPU %d memory clock to %d", gpu, gpus[gpu].gpu_memclock); + applog(LOG_INFO, "Setting GPU %d memory clock to %d", gpu, data->gpu_memclock); ADL_Overdrive5_ODPerformanceLevels_Set(iAdapterIndex, lpOdPerformanceLevels); ga->managed = true; } - if (gpus[gpu].gpu_vddc) { - int setv = gpus[gpu].gpu_vddc * 1000; + if (data->gpu_vddc) { + int setv = data->gpu_vddc * 1000; for (j = 0; j < lev; j++) { if (lpOdPerformanceLevels->aLevels[j].iVddc > setv) lpOdPerformanceLevels->aLevels[j].iVddc = setv; } lpOdPerformanceLevels->aLevels[lev].iVddc = setv; - applog(LOG_INFO, "Setting GPU %d voltage to %.3f", gpu, gpus[gpu].gpu_vddc); + applog(LOG_INFO, "Setting GPU %d voltage to %.3f", gpu, data->gpu_vddc); ADL_Overdrive5_ODPerformanceLevels_Set(iAdapterIndex, lpOdPerformanceLevels); ga->managed = true; } @@ -462,52 +485,65 @@ void init_adl(int nDevs) ga->has_fanspeed = true; /* Save the fanspeed values as defaults in case we reset later */ + ga->DefFanSpeedValue.iSpeedType = ADL_DL_FANCTRL_SPEED_TYPE_RPM; ADL_Overdrive5_FanSpeed_Get(ga->iAdapterIndex, 0, &ga->DefFanSpeedValue); - if (gpus[gpu].gpu_fan) - set_fanspeed(gpu, gpus[gpu].gpu_fan); + if (data->gpu_fan) + set_fanspeed(gpu, data->gpu_fan); else - gpus[gpu].gpu_fan = 85; /* Set a nominal upper limit of 85% */ + data->gpu_fan = 85; /* Set a nominal upper limit of 85% */ /* Not fatal if powercontrol get fails */ if (ADL_Overdrive5_PowerControl_Get(ga->iAdapterIndex, &ga->iPercentage, &dummy) != ADL_OK) applog(LOG_INFO, "Failed to ADL_Overdrive5_PowerControl_get"); - if (gpus[gpu].gpu_powertune) { - ADL_Overdrive5_PowerControl_Set(ga->iAdapterIndex, gpus[gpu].gpu_powertune); + if (data->gpu_powertune) { + ADL_Overdrive5_PowerControl_Set(ga->iAdapterIndex, data->gpu_powertune); ADL_Overdrive5_PowerControl_Get(ga->iAdapterIndex, &ga->iPercentage, &dummy); ga->managed = true; } /* Set some default temperatures for autotune when enabled */ - if (!ga->targettemp) - ga->targettemp = opt_targettemp; + if (!gpus[gpu].targettemp) + gpus[gpu].targettemp = opt_targettemp; if (!ga->overtemp) ga->overtemp = opt_overheattemp; if (!gpus[gpu].cutofftemp) gpus[gpu].cutofftemp = opt_cutofftemp; if (opt_autofan) { - ga->autofan = true; /* Set a safe starting default if we're automanaging fan speeds */ - set_fanspeed(gpu, 50); + int nominal = 50; + + ga->autofan = true; + /* Clamp fanspeed values to range provided */ + if (nominal > data->gpu_fan) + nominal = data->gpu_fan; + if (nominal < data->min_fan) + nominal = data->min_fan; + set_fanspeed(gpu, nominal); } if (opt_autoengine) { ga->autoengine = true; ga->managed = true; } + gpus[gpu].temp = ga->lasttemp = __gpu_temp(ga); } for (gpu = 0; gpu < devices; gpu++) { - struct gpu_adl *ga = &gpus[gpu].adl; + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; + struct gpu_adl *ga = &data->adl; int j; for (j = 0; j < devices; j++) { + struct cgpu_info * const other_cgpu = &gpus[j]; + struct opencl_device_data * const other_data = other_cgpu->device_data; struct gpu_adl *other_ga; if (j == gpu) continue; - other_ga = &gpus[j].adl; + other_ga = &other_data->adl; /* Search for twin GPUs on a single card. They will be * separated by one bus id and one will have fanspeed @@ -533,13 +569,15 @@ static float __gpu_temp(struct gpu_adl *ga) float gpu_temp(int gpu) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; float ret = -1; - if (!gpus[gpu].has_adl || !adl_active) + if (!data->has_adl || !adl_active) return ret; - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); ret = __gpu_temp(ga); unlock_adl(); @@ -554,13 +592,15 @@ static inline int __gpu_engineclock(struct gpu_adl *ga) int gpu_engineclock(int gpu) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; int ret = -1; - if (!gpus[gpu].has_adl || !adl_active) + if (!data->has_adl || !adl_active) return ret; - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); if (ADL_Overdrive5_CurrentActivity_Get(ga->iAdapterIndex, &ga->lpActivity) != ADL_OK) goto out; @@ -577,13 +617,15 @@ static inline int __gpu_memclock(struct gpu_adl *ga) int gpu_memclock(int gpu) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; int ret = -1; - if (!gpus[gpu].has_adl || !adl_active) + if (!data->has_adl || !adl_active) return ret; - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); if (ADL_Overdrive5_CurrentActivity_Get(ga->iAdapterIndex, &ga->lpActivity) != ADL_OK) goto out; @@ -600,13 +642,15 @@ static inline float __gpu_vddc(struct gpu_adl *ga) float gpu_vddc(int gpu) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; float ret = -1; - if (!gpus[gpu].has_adl || !adl_active) + if (!data->has_adl || !adl_active) return ret; - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); if (ADL_Overdrive5_CurrentActivity_Get(ga->iAdapterIndex, &ga->lpActivity) != ADL_OK) goto out; @@ -625,13 +669,15 @@ static inline int __gpu_activity(struct gpu_adl *ga) int gpu_activity(int gpu) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; int ret = -1; - if (!gpus[gpu].has_adl || !adl_active) + if (!data->has_adl || !adl_active) return ret; - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); ret = ADL_Overdrive5_CurrentActivity_Get(ga->iAdapterIndex, &ga->lpActivity); unlock_adl(); @@ -657,13 +703,15 @@ static inline int __gpu_fanspeed(struct gpu_adl *ga) int gpu_fanspeed(int gpu) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; int ret = -1; - if (!gpus[gpu].has_adl || !adl_active) + if (!data->has_adl || !adl_active) return ret; - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); ret = __gpu_fanspeed(ga); unlock_adl(); @@ -685,31 +733,18 @@ static int __gpu_fanpercent(struct gpu_adl *ga) int gpu_fanpercent(int gpu) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; int ret = -1; - if (!gpus[gpu].has_adl || !adl_active) + if (!data->has_adl || !adl_active) return ret; - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); ret = __gpu_fanpercent(ga); unlock_adl(); - if (unlikely(ga->has_fanspeed && ret == -1)) { - applog(LOG_WARNING, "GPU %d stopped reporting fanspeed due to driver corruption", gpu); - if (opt_restart) { - applog(LOG_WARNING, "Restart enabled, will attempt to restart BFGMiner"); - applog(LOG_WARNING, "You can disable this with the --no-restart option"); - app_restart(); - } - applog(LOG_WARNING, "Disabling fanspeed monitoring on this device"); - ga->has_fanspeed = false; - if (ga->twin) { - applog(LOG_WARNING, "Disabling fanspeed linking on GPU twins"); - ga->twin->twin = NULL;; - ga->twin = NULL; - } - } return ret; } @@ -724,13 +759,15 @@ static inline int __gpu_powertune(struct gpu_adl *ga) int gpu_powertune(int gpu) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; int ret = -1; - if (!gpus[gpu].has_adl || !adl_active) + if (!data->has_adl || !adl_active) return ret; - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); ret = __gpu_powertune(ga); unlock_adl(); @@ -740,14 +777,17 @@ int gpu_powertune(int gpu) bool gpu_stats(int gpu, float *temp, int *engineclock, int *memclock, float *vddc, int *activity, int *fanspeed, int *fanpercent, int *powertune) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; - if (!gpus[gpu].has_adl || !adl_active) + if (!data->has_adl || !adl_active) return false; - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); + gpus[gpu].temp = *temp = __gpu_temp(ga); if (ADL_Overdrive5_CurrentActivity_Get(ga->iAdapterIndex, &ga->lpActivity) != ADL_OK) { *engineclock = 0; @@ -771,13 +811,15 @@ bool gpu_stats(int gpu, float *temp, int *engineclock, int *memclock, float *vdd #ifdef HAVE_CURSES static void get_enginerange(int gpu, int *imin, int *imax) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; - if (!gpus[gpu].has_adl || !adl_active) { + if (!data->has_adl || !adl_active) { wlogprint("Get enginerange not supported\n"); return; } - ga = &gpus[gpu].adl; + ga = &data->adl; *imin = ga->lpOdParameters.sEngineClock.iMin / 100; *imax = ga->lpOdParameters.sEngineClock.iMax / 100; } @@ -785,17 +827,19 @@ static void get_enginerange(int gpu, int *imin, int *imax) int set_engineclock(int gpu, int iEngineClock) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; ADLODPerformanceLevels *lpOdPerformanceLevels; int i, lev, ret = 1; struct gpu_adl *ga; - if (!gpus[gpu].has_adl || !adl_active) { + if (!data->has_adl || !adl_active) { wlogprint("Set engineclock not supported\n"); return ret; } iEngineClock *= 100; - ga = &gpus[gpu].adl; + ga = &data->adl; /* Keep track of intended engine clock in case the device changes * profile and drops while idle, not taking the new engine clock */ @@ -827,19 +871,25 @@ int set_engineclock(int gpu, int iEngineClock) ga->managed = true; out: unlock_adl(); + + if (data->gpu_memdiff) + set_memoryclock(gpu, iEngineClock / 100 + data->gpu_memdiff); + return ret; } #ifdef HAVE_CURSES static void get_memoryrange(int gpu, int *imin, int *imax) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; - if (!gpus[gpu].has_adl || !adl_active) { + if (!data->has_adl || !adl_active) { wlogprint("Get memoryrange not supported\n"); return; } - ga = &gpus[gpu].adl; + ga = &data->adl; *imin = ga->lpOdParameters.sMemoryClock.iMin / 100; *imax = ga->lpOdParameters.sMemoryClock.iMax / 100; } @@ -847,17 +897,21 @@ static void get_memoryrange(int gpu, int *imin, int *imax) int set_memoryclock(int gpu, int iMemoryClock) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; ADLODPerformanceLevels *lpOdPerformanceLevels; int i, lev, ret = 1; struct gpu_adl *ga; - if (!gpus[gpu].has_adl || !adl_active) { + if (!data->has_adl || !adl_active) { wlogprint("Set memoryclock not supported\n"); return ret; } + data->gpu_memclock = iMemoryClock; + iMemoryClock *= 100; - ga = &gpus[gpu].adl; + ga = &data->adl; lev = ga->lpOdParameters.iNumberOfPerformanceLevels - 1; lpOdPerformanceLevels = alloca(sizeof(ADLODPerformanceLevels) + (lev * sizeof(ADLODPerformanceLevel))); @@ -887,13 +941,15 @@ int set_memoryclock(int gpu, int iMemoryClock) #ifdef HAVE_CURSES static void get_vddcrange(int gpu, float *imin, float *imax) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; - if (!gpus[gpu].has_adl || !adl_active) { + if (!data->has_adl || !adl_active) { wlogprint("Get vddcrange not supported\n"); return; } - ga = &gpus[gpu].adl; + ga = &data->adl; *imin = (float)ga->lpOdParameters.sVddc.iMin / 1000; *imax = (float)ga->lpOdParameters.sVddc.iMax / 1000; } @@ -904,6 +960,8 @@ static float curses_float(const char *query) char *cvar; cvar = curses_input(query); + if (unlikely(!cvar)) + return -1; ret = atof(cvar); free(cvar); return ret; @@ -912,17 +970,19 @@ static float curses_float(const char *query) int set_vddc(int gpu, float fVddc) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; ADLODPerformanceLevels *lpOdPerformanceLevels; int i, iVddc, lev, ret = 1; struct gpu_adl *ga; - if (!gpus[gpu].has_adl || !adl_active) { + if (!data->has_adl || !adl_active) { wlogprint("Set vddc not supported\n"); return ret; } iVddc = 1000 * fVddc; - ga = &gpus[gpu].adl; + ga = &data->adl; lev = ga->lpOdParameters.iNumberOfPerformanceLevels - 1; lpOdPerformanceLevels = alloca(sizeof(ADLODPerformanceLevels) + (lev * sizeof(ADLODPerformanceLevel))); @@ -951,28 +1011,32 @@ int set_vddc(int gpu, float fVddc) static void get_fanrange(int gpu, int *imin, int *imax) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; - if (!gpus[gpu].has_adl || !adl_active) { + if (!data->has_adl || !adl_active) { wlogprint("Get fanrange not supported\n"); return; } - ga = &gpus[gpu].adl; + ga = &data->adl; *imin = ga->lpFanSpeedInfo.iMinPercent; *imax = ga->lpFanSpeedInfo.iMaxPercent; } int set_fanspeed(int gpu, int iFanSpeed) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; int ret = 1; - if (!gpus[gpu].has_adl || !adl_active) { + if (!data->has_adl || !adl_active) { wlogprint("Set fanspeed not supported\n"); return ret; } - ga = &gpus[gpu].adl; + ga = &data->adl; if (!(ga->lpFanSpeedInfo.iFlags & (ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE | ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE ))) { applog(LOG_DEBUG, "GPU %d doesn't support rpm or percent write", gpu); return ret; @@ -983,20 +1047,21 @@ int set_fanspeed(int gpu, int iFanSpeed) ga->targetfan = iFanSpeed; lock_adl(); + ga->lpFanSpeedValue.iSpeedType = ADL_DL_FANCTRL_SPEED_TYPE_RPM; if (ADL_Overdrive5_FanSpeed_Get(ga->iAdapterIndex, 0, &ga->lpFanSpeedValue) != ADL_OK) { applog(LOG_DEBUG, "GPU %d call to fanspeed get failed", gpu); } + if (!(ga->lpFanSpeedValue.iFlags & ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED)) { + /* If user defined is not already specified, set it first */ + ga->lpFanSpeedValue.iFlags |= ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED; + ADL_Overdrive5_FanSpeed_Set(ga->iAdapterIndex, 0, &ga->lpFanSpeedValue); + } if (!(ga->lpFanSpeedInfo.iFlags & ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE)) { /* Must convert speed to an RPM */ iFanSpeed = ga->lpFanSpeedInfo.iMaxRPM * iFanSpeed / 100; ga->lpFanSpeedValue.iSpeedType = ADL_DL_FANCTRL_SPEED_TYPE_RPM; } else ga->lpFanSpeedValue.iSpeedType = ADL_DL_FANCTRL_SPEED_TYPE_PERCENT; - if (!(ga->lpFanSpeedValue.iFlags & ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED)) { - /* If user defined is not already specified, set it first */ - ga->lpFanSpeedValue.iFlags = ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED; - ADL_Overdrive5_FanSpeed_Set(ga->iAdapterIndex, 0, &ga->lpFanSpeedValue); - } ga->lpFanSpeedValue.iFanSpeed = iFanSpeed; ret = ADL_Overdrive5_FanSpeed_Set(ga->iAdapterIndex, 0, &ga->lpFanSpeedValue); ga->managed = true; @@ -1008,15 +1073,17 @@ int set_fanspeed(int gpu, int iFanSpeed) #ifdef HAVE_CURSES static int set_powertune(int gpu, int iPercentage) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; int dummy, ret = 1; - if (!gpus[gpu].has_adl || !adl_active) { + if (!data->has_adl || !adl_active) { wlogprint("Set powertune not supported\n"); return ret; } - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); ADL_Overdrive5_PowerControl_Set(ga->iAdapterIndex, iPercentage); @@ -1035,30 +1102,29 @@ static int set_powertune(int gpu, int iPercentage) static bool fan_autotune(int gpu, int temp, int fanpercent, int lasttemp, bool *fan_window) { struct cgpu_info *cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; int tdiff = round(temp - lasttemp); - struct gpu_adl *ga = &cgpu->adl; - int top = gpus[gpu].gpu_fan; - int bot = gpus[gpu].min_fan; + struct gpu_adl *ga = &data->adl; + const int top = data->gpu_fan; + const int bot = data->min_fan; int newpercent = fanpercent; int iMin = 0, iMax = 100; get_fanrange(gpu, &iMin, &iMax); if (temp > ga->overtemp && fanpercent < iMax) { - applog(LOG_WARNING, "Overheat detected on GPU %d, increasing fan to 100%", gpu); + applog(LOG_WARNING, "Overheat detected on GPU %d, increasing fan to 100%%", gpu); newpercent = iMax; - cgpu->device_last_not_well = time(NULL); - cgpu->device_not_well_reason = REASON_DEV_OVER_HEAT; - cgpu->dev_over_heat_count++; - } else if (temp > ga->targettemp && fanpercent < top && tdiff >= 0) { + dev_error(cgpu, REASON_DEV_OVER_HEAT); + } else if (temp > gpus[gpu].targettemp && fanpercent < top && tdiff >= 0) { applog(LOG_DEBUG, "Temperature over target, increasing fanspeed"); - if (temp > ga->targettemp + opt_hysteresis) + if (temp > gpus[gpu].targettemp + opt_hysteresis) newpercent = ga->targetfan + 10; else newpercent = ga->targetfan + 5; if (newpercent > top) newpercent = top; - } else if (fanpercent > bot && temp < ga->targettemp - opt_hysteresis) { + } else if (fanpercent > bot && temp < gpus[gpu].targettemp - opt_hysteresis) { /* Detect large swings of 5 degrees or more and change fan by * a proportion more */ if (tdiff <= 0) { @@ -1072,10 +1138,10 @@ static bool fan_autotune(int gpu, int temp, int fanpercent, int lasttemp, bool * /* We're in the optimal range, make minor adjustments if the * temp is still drifting */ - if (fanpercent > bot && tdiff < 0 && lasttemp < ga->targettemp) { + if (fanpercent > bot && tdiff < 0 && lasttemp < gpus[gpu].targettemp) { applog(LOG_DEBUG, "Temperature dropping while in target range, decreasing fanspeed"); newpercent = ga->targetfan + tdiff; - } else if (fanpercent < top && tdiff > 0 && temp > ga->targettemp - opt_hysteresis) { + } else if (fanpercent < top && tdiff > 0 && temp > gpus[gpu].targettemp - opt_hysteresis) { applog(LOG_DEBUG, "Temperature rising while in target range, increasing fanspeed"); newpercent = ga->targetfan + tdiff; } @@ -1112,10 +1178,12 @@ void gpu_autotune(int gpu, enum dev_enable *denable) struct gpu_adl *ga; cgpu = &gpus[gpu]; - ga = &cgpu->adl; + struct opencl_device_data * const data = cgpu->device_data; + ga = &data->adl; lock_adl(); ADL_Overdrive5_CurrentActivity_Get(ga->iAdapterIndex, &ga->lpActivity); + gpus[gpu].temp = temp = __gpu_temp(ga); if (ga->twin) twintemp = __gpu_temp(ga->twin); @@ -1150,33 +1218,24 @@ void gpu_autotune(int gpu, enum dev_enable *denable) if (engine && ga->autoengine) { if (temp > cgpu->cutofftemp) { - applog(LOG_WARNING, "Hit thermal cutoff limit on GPU %d, disabling!", gpu); - *denable = DEV_RECOVER; + // Shutoff and recovery happens back in watchdog_thread newengine = ga->minspeed; - - cgpu->device_last_not_well = time(NULL); - cgpu->device_not_well_reason = REASON_DEV_THERMAL_CUTOFF; - cgpu->dev_thermal_cutoff_count++; } else if (temp > ga->overtemp && engine > ga->minspeed) { applog(LOG_WARNING, "Overheat detected, decreasing GPU %d clock speed", gpu); newengine = ga->minspeed; - cgpu->device_last_not_well = time(NULL); - cgpu->device_not_well_reason = REASON_DEV_OVER_HEAT; - cgpu->dev_over_heat_count++; - } else if (temp > ga->targettemp + opt_hysteresis && engine > ga->minspeed && fan_optimal) { + dev_error(cgpu, REASON_DEV_OVER_HEAT); + } else if (temp > gpus[gpu].targettemp + opt_hysteresis && engine > ga->minspeed && fan_optimal) { applog(LOG_DEBUG, "Temperature %d degrees over target, decreasing clock speed", opt_hysteresis); newengine = engine - ga->lpOdParameters.sEngineClock.iStep; /* Only try to tune engine speed up if this GPU is not disabled */ - } else if (temp < ga->targettemp && engine < ga->maxspeed && fan_window && *denable == DEV_ENABLED) { + } else if (temp < gpus[gpu].targettemp && engine < ga->maxspeed && fan_window && *denable == DEV_ENABLED) { + int iStep = ga->lpOdParameters.sEngineClock.iStep; + applog(LOG_DEBUG, "Temperature below target, increasing clock speed"); - if (temp < ga->targettemp - opt_hysteresis) - newengine = ga->maxspeed; - else - newengine = engine + ga->lpOdParameters.sEngineClock.iStep; - } else if (temp < ga->targettemp && *denable == DEV_RECOVER && opt_restart) { - applog(LOG_NOTICE, "Device recovered to temperature below target, re-enabling"); - *denable = DEV_ENABLED; + if (temp < gpus[gpu].targettemp - opt_hysteresis) + iStep *= 2; + newengine = engine + iStep; } if (newengine > ga->maxspeed) @@ -1192,8 +1251,6 @@ void gpu_autotune(int gpu, enum dev_enable *denable) newengine /= 100; applog(LOG_INFO, "Setting GPU %d engine clock to %d", gpu, newengine); set_engineclock(gpu, newengine); - if (cgpu->gpu_memdiff) - set_memoryclock(gpu, newengine + cgpu->gpu_memdiff); } } ga->lasttemp = temp; @@ -1201,11 +1258,13 @@ void gpu_autotune(int gpu, enum dev_enable *denable) void set_defaultfan(int gpu) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; - if (!gpus[gpu].has_adl || !adl_active) + if (!data->has_adl || !adl_active) return; - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); ADL_Overdrive5_FanSpeed_Set(ga->iAdapterIndex, 0, &ga->DefFanSpeedValue); unlock_adl(); @@ -1213,11 +1272,13 @@ void set_defaultfan(int gpu) void set_defaultengine(int gpu) { + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; struct gpu_adl *ga; - if (!gpus[gpu].has_adl || !adl_active) + if (!data->has_adl || !adl_active) return; - ga = &gpus[gpu].adl; + ga = &data->adl; lock_adl(); ADL_Overdrive5_ODPerformanceLevels_Set(ga->iAdapterIndex, ga->DefPerfLev); unlock_adl(); @@ -1226,11 +1287,13 @@ void set_defaultengine(int gpu) #ifdef HAVE_CURSES void change_autosettings(int gpu) { - struct gpu_adl *ga = &gpus[gpu].adl; + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; + struct gpu_adl *ga = &data->adl; char input; int val; - wlogprint("Target temperature: %d\n", ga->targettemp); + wlogprint("Target temperature: %d\n", gpus[gpu].targettemp); wlogprint("Overheat temperature: %d\n", ga->overtemp); wlogprint("Cutoff temperature: %d\n", gpus[gpu].cutofftemp); wlogprint("Toggle [F]an auto [G]PU auto\nChange [T]arget [O]verheat [C]utoff\n"); @@ -1255,11 +1318,11 @@ void change_autosettings(int gpu) if (val < 0 || val > 200) wlogprint("Invalid temperature"); else - ga->targettemp = val; + gpus[gpu].targettemp = val; } else if (!strncasecmp(&input, "o", 1)) { - wlogprint("Enter overheat temperature for this GPU in C (%d+)", ga->targettemp); + wlogprint("Enter overheat temperature for this GPU in C (%d+)", gpus[gpu].targettemp); val = curses_int(""); - if (val <= ga->targettemp || val > 200) + if (val <= gpus[gpu].targettemp || val > 200) wlogprint("Invalid temperature"); else ga->overtemp = val; @@ -1275,7 +1338,9 @@ void change_autosettings(int gpu) void change_gpusettings(int gpu) { - struct gpu_adl *ga = &gpus[gpu].adl; + struct cgpu_info * const cgpu = &gpus[gpu]; + struct opencl_device_data * const data = cgpu->device_data; + struct gpu_adl *ga = &data->adl; float fval, fmin = 0, fmax = 0; int val, imin = 0, imax = 0; char input; @@ -1293,10 +1358,10 @@ void change_gpusettings(int gpu) wlogprint("(%d RPM)", fanspeed); wlogprint("\n"); } - wlogprint("Engine Clock: %d MHz\nMemory Clock: %d Mhz\nVddc: %.3f V\nActivity: %d%%\nPowertune: %d%%\n", + wlogprint("Engine Clock: %d MHz\nMemory Clock: %d MHz\nVddc: %.3f V\nActivity: %d%%\nPowertune: %d%%\n", engineclock, memclock, vddc, activity, powertune); wlogprint("Fan autotune is %s (%d-%d)\n", ga->autofan ? "enabled" : "disabled", - gpus[gpu].min_fan, gpus[gpu].gpu_fan); + data->min_fan, data->gpu_fan); wlogprint("GPU engine clock autotune is %s (%d-%d)\n", ga->autoengine ? "enabled" : "disabled", ga->minspeed / 100, ga->maxspeed / 100); wlogprint("Change [A]utomatic [E]ngine [F]an [M]emory [V]oltage [P]owertune\n"); @@ -1307,7 +1372,7 @@ void change_gpusettings(int gpu) change_autosettings(gpu); } else if (!strncasecmp(&input, "e", 1)) { get_enginerange(gpu, &imin, &imax); - wlogprint("Enter GPU engine clock speed (%d - %d Mhz)", imin, imax); + wlogprint("Enter GPU engine clock speed (%d - %d MHz)", imin, imax); val = curses_int(""); if (val < imin || val > imax) { wlogprint("Value is outside safe range, are you sure?\n"); @@ -1321,7 +1386,7 @@ void change_gpusettings(int gpu) wlogprint("Failed to modify engine clock speed\n"); } else if (!strncasecmp(&input, "f", 1)) { get_fanrange(gpu, &imin, &imax); - wlogprint("Enter fan percentage (%d - %d %)", imin, imax); + wlogprint("Enter fan percentage (%d - %d %%)", imin, imax); val = curses_int(""); if (val < imin || val > imax) { wlogprint("Value is outside safe range, are you sure?\n"); @@ -1335,7 +1400,7 @@ void change_gpusettings(int gpu) wlogprint("Failed to modify fan speed\n"); } else if (!strncasecmp(&input, "m", 1)) { get_memoryrange(gpu, &imin, &imax); - wlogprint("Enter GPU memory clock speed (%d - %d Mhz)", imin, imax); + wlogprint("Enter GPU memory clock speed (%d - %d MHz)", imin, imax); val = curses_int(""); if (val < imin || val > imax) { wlogprint("Value is outside safe range, are you sure?\n"); @@ -1377,7 +1442,7 @@ void change_gpusettings(int gpu) clear_logwin(); return; } - sleep(1); + cgsleep_ms(1000); goto updated; } #endif @@ -1386,7 +1451,7 @@ static void free_adl(void) { ADL_Main_Memory_Free ((void **)&lpInfo); ADL_Main_Control_Destroy (); -#if defined (LINUX) +#ifndef WIN32 dlclose(hDLL); #else FreeLibrary(hDLL); @@ -1404,9 +1469,11 @@ void clear_adl(int nDevs) lock_adl(); /* Try to reset values to their defaults */ for (i = 0; i < nDevs; i++) { - ga = &gpus[i].adl; + struct cgpu_info * const cgpu = &gpus[i]; + struct opencl_device_data * const data = cgpu->device_data; + ga = &data->adl; /* Only reset the values if we've changed them at any time */ - if (!gpus[i].has_adl || !ga->managed) + if (!data->has_adl || !ga->managed) continue; ADL_Overdrive5_ODPerformanceLevels_Set(ga->iAdapterIndex, ga->DefPerfLev); free(ga->DefPerfLev); diff --git a/adl.h b/adl.h index ca67550c1c..f37aa8ef7a 100644 --- a/adl.h +++ b/adl.h @@ -1,11 +1,13 @@ -#ifndef __ADL_H__ -#define __ADL_H__ +#ifndef BFG_ADL_H +#define BFG_ADL_H #ifdef HAVE_ADL -bool adl_active; -bool opt_reorder; -int opt_hysteresis; -const int opt_targettemp; -const int opt_overheattemp; + +#include + +extern bool adl_active; +extern bool opt_reorder; +extern const int opt_targettemp; +extern const int opt_overheattemp; void init_adl(int nDevs); float gpu_temp(int gpu); int gpu_engineclock(int gpu); diff --git a/adl_functions.h b/adl_functions.h index 6d4a9a1b0f..f8409a3dbb 100644 --- a/adl_functions.h +++ b/adl_functions.h @@ -7,7 +7,7 @@ * e.g. INCREASING THE VOLTAGES AND FREQUENCIES IN CONJUNCTION WITH LOWERING THE * FAN SPEED IS NOT ADVISABLE! - * Copyright(C) Thorsten Gilling (tgilling@web.de) + * Copyright 2010-2011 Thorsten Gilling * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -29,7 +29,7 @@ // AMD ADL function types from Version 3.0 // ------------------------------------------------------------------------------------------------------------ -#if defined (linux) +#ifndef WIN32 #include //dyopen, dlsym, dlclose #include #include //memeset @@ -38,7 +38,7 @@ #include #endif -#include "ADL_SDK/adl_sdk.h" +#include "ADL/adl_sdk.h" // Definitions of the used function pointers. Add more if you use other ADL APIs diff --git a/api-example.c b/api-example.c old mode 100755 new mode 100644 index 99efc0661c..5a5e91b687 --- a/api-example.c +++ b/api-example.c @@ -1,5 +1,6 @@ /* - * Copyright 2011 Kano + * Copyright 2011-2012 Andrew Smith + * Copyright 2012-2013 Luke Dashjr * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -7,12 +8,9 @@ * any later version. See COPYING for more details. */ -/* Compile: - * gcc api-example.c -I compat/jansson -o bfgminer-api - */ - #include "config.h" +#include #include #include #include @@ -23,9 +21,8 @@ #include #include "compat.h" -#include "miner.h" -#if defined(unix) +#ifndef WIN32 #include #include #include @@ -37,12 +34,10 @@ #define INVSOCK -1 #define CLOSESOCKET close - #define SOCKETINIT {} + #define SOCKETINIT do{}while(0) #define SOCKERRMSG strerror(errno) -#endif - -#ifdef WIN32 +#else #include #define SOCKETTYPE SOCKET @@ -111,7 +106,6 @@ static char *WSAErrorMsg() { - char *msg; int i; int id = WSAGetLastError(); @@ -129,11 +123,13 @@ static WSADATA WSA_Data; - #define SOCKETINIT int wsa; \ - if (wsa = WSAStartup(0x0202, &WSA_Data)) { \ + #define SOCKETINIT do { \ + int wsa; \ + if ( (wsa = WSAStartup(0x0202, &WSA_Data)) ) { \ printf("Socket startup failed: %d\n", wsa); \ return 1; \ - } + } \ + } while (0) #ifndef SHUT_RDWR #define SHUT_RDWR SD_BOTH @@ -145,6 +141,7 @@ static const char SEPARATOR = '|'; static const char COMMA = ','; static const char EQ = '='; +static int ONLY; void display(char *buf) { @@ -191,16 +188,23 @@ void display(char *buf) int callapi(char *command, char *host, short int port) { - char buf[RECVSIZE+1]; + size_t bufsz = RECVSIZE; + char *buf = malloc(bufsz+1); struct hostent *ip; struct sockaddr_in serv; SOCKETTYPE sock; int ret = 0; int n, p; + assert(buf); SOCKETINIT; ip = gethostbyname(host); + if (!ip) + { + printf("Failed to resolve host %s\n", host); + return 1; + } sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVSOCK) { @@ -226,8 +230,16 @@ int callapi(char *command, char *host, short int port) else { p = 0; buf[0] = '\0'; - while (p < RECVSIZE) { - n = recv(sock, &buf[p], RECVSIZE - p , 0); + while (true) + { + if (bufsz < RECVSIZE + p) + { + bufsz *= 2; + buf = realloc(buf, bufsz); + assert(buf); + } + + n = recv(sock, &buf[p], RECVSIZE, 0); if (SOCKETFAIL(n)) { printf("Recv failed: %s\n", SOCKERRMSG); @@ -242,9 +254,13 @@ int callapi(char *command, char *host, short int port) buf[p] = '\0'; } - printf("Reply was '%s'\n", buf); + if (!ONLY) + printf("Reply was '%s'\n", buf); + else + printf("%s\n", buf); - display(buf); + if (!ONLY) + display(buf); } CLOSESOCKET(sock); @@ -274,29 +290,36 @@ int main(int argc, char *argv[]) char *host = "127.0.0.1"; short int port = 4028; char *ptr; + int i = 1; if (argc > 1) if (strcmp(argv[1], "-?") == 0 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { - fprintf(stderr, "usAge: %s [command [ip/host [port]]]\n", argv[0]); + fprintf(stderr, "Usage: %s [command [ip/host [port]]]\n", argv[0]); return 1; } - if (argc > 1) { - ptr = trim(argv[1]); + if (argc > 1) + if (strcmp(argv[1], "-o") == 0) { + ONLY = 1; + i = 2; + } + + if (argc > i) { + ptr = trim(argv[i++]); if (strlen(ptr) > 0) command = ptr; } - if (argc > 2) { - ptr = trim(argv[2]); + if (argc > i) { + ptr = trim(argv[i++]); if (strlen(ptr) > 0) host = ptr; } - if (argc > 3) { - ptr = trim(argv[3]); + if (argc > i) { + ptr = trim(argv[i]); if (strlen(ptr) > 0) port = atoi(ptr); } diff --git a/api-example.py b/api-example.py new file mode 100755 index 0000000000..470e30333c --- /dev/null +++ b/api-example.py @@ -0,0 +1,62 @@ +#!/usr/bin/python +# Copyright 2013 Christian Berendt +# Copyright 2013 Luke Dashjr +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. See COPYING for more details. + +import argparse +import json +import logging +import pprint +import socket + +logging.basicConfig( + format='%(asctime)s %(levelname)s %(message)s', + level=logging.DEBUG +) + +parser = argparse.ArgumentParser() +parser.add_argument("command", default="summary", nargs='?') +parser.add_argument("parameter", default="", nargs='?') +parser.add_argument("--hostname", default="localhost") +parser.add_argument("--port", type=int, default=4028) +args = parser.parse_args() + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + +try: + s.connect((args.hostname, args.port)) +except socket.error, e: + logging.error(e) + +try: + s.send("{\"command\" : \"%s\", \"parameter\" : \"%s\"}" + % (args.command, args.parameter) + ) +except socket.error, e: + logging.error(e) + + +data = '' +while True: + try: + newdata = s.recv(1024) + if newdata: + data += newdata + else: + break + except socket.error, e: + break + +try: + s.close() +except socket.error,e: + logging.error(e) + +if data: + data = json.loads(data.replace('\x00', '')) + pp = pprint.PrettyPrinter() + pp.pprint(data) diff --git a/api-example.rb b/api-example.rb new file mode 100644 index 0000000000..28c4402f91 --- /dev/null +++ b/api-example.rb @@ -0,0 +1,38 @@ +#!/usr/bin/env ruby + +# Copyright 2014 James Hilliard +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. See COPYING for more details. + +require 'socket' +require 'json' + +api_command = ARGV[0].split(":") + +if ARGV.length == 3 + api_ip = ARGV[1] + api_port = ARGV[2] +elsif ARGV.length == 2 + api_ip = ARGV[1] + api_port = 4028 +else + api_ip = "127.0.0.1" + api_port = 4028 +end + +s = TCPSocket.open(api_ip, api_port) + +if api_command.count == 2 + s.write({ :command => api_command[0], :parameter => api_command[1]}.to_json) +else + s.write({ :command => api_command[0]}.to_json) +end + +response = s.read.strip +response = JSON.parse(response) + +puts response +s.close diff --git a/api.c b/api.c index 67320161b1..5bd67afdc4 100644 --- a/api.c +++ b/api.c @@ -1,6 +1,7 @@ /* - * Copyright 2011-2012 Andrew Smith - * Copyright 2011-2012 Con Kolivas + * Copyright 2011-2014 Andrew Smith + * Copyright 2011-2014 Con Kolivas + * Copyright 2012-2017 Luke Dashjr * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -11,9 +12,11 @@ * this simplifies handling multiple other device code being included * depending on compile options */ +#define _MEMORY_DEBUG_MASTER 1 #include "config.h" +#include #include #include #include @@ -23,128 +26,23 @@ #include #include +#include +#include + #include "compat.h" +#include "deviceapi.h" +#ifdef USE_LIBMICROHTTPD +#include "httpsrv.h" +#endif #include "miner.h" +#include "util.h" #include "driver-cpu.h" /* for algo_names[], TODO: re-factor dependency */ +#include "driver-opencl.h" -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) || defined(USE_MODMINER) #define HAVE_AN_FPGA 1 -#endif - -#if defined(unix) || defined(__APPLE__) - #include - #include - #include - #include - - #define SOCKETTYPE int - #define SOCKETFAIL(a) ((a) < 0) - #define INVSOCK -1 - #define INVINETADDR -1 - #define CLOSESOCKET close - - #define SOCKERRMSG strerror(errno) -#endif - -#ifdef WIN32 - #include - #include - - #define SOCKETTYPE SOCKET - #define SOCKETFAIL(a) ((a) == SOCKET_ERROR) - #define INVSOCK INVALID_SOCKET - #define INVINETADDR INADDR_NONE - #define CLOSESOCKET closesocket - - static char WSAbuf[1024]; - - struct WSAERRORS { - int id; - char *code; - } WSAErrors[] = { - { 0, "No error" }, - { WSAEINTR, "Interrupted system call" }, - { WSAEBADF, "Bad file number" }, - { WSAEACCES, "Permission denied" }, - { WSAEFAULT, "Bad address" }, - { WSAEINVAL, "Invalid argument" }, - { WSAEMFILE, "Too many open sockets" }, - { WSAEWOULDBLOCK, "Operation would block" }, - { WSAEINPROGRESS, "Operation now in progress" }, - { WSAEALREADY, "Operation already in progress" }, - { WSAENOTSOCK, "Socket operation on non-socket" }, - { WSAEDESTADDRREQ, "Destination address required" }, - { WSAEMSGSIZE, "Message too long" }, - { WSAEPROTOTYPE, "Protocol wrong type for socket" }, - { WSAENOPROTOOPT, "Bad protocol option" }, - { WSAEPROTONOSUPPORT, "Protocol not supported" }, - { WSAESOCKTNOSUPPORT, "Socket type not supported" }, - { WSAEOPNOTSUPP, "Operation not supported on socket" }, - { WSAEPFNOSUPPORT, "Protocol family not supported" }, - { WSAEAFNOSUPPORT, "Address family not supported" }, - { WSAEADDRINUSE, "Address already in use" }, - { WSAEADDRNOTAVAIL, "Can't assign requested address" }, - { WSAENETDOWN, "Network is down" }, - { WSAENETUNREACH, "Network is unreachable" }, - { WSAENETRESET, "Net connection reset" }, - { WSAECONNABORTED, "Software caused connection abort" }, - { WSAECONNRESET, "Connection reset by peer" }, - { WSAENOBUFS, "No buffer space available" }, - { WSAEISCONN, "Socket is already connected" }, - { WSAENOTCONN, "Socket is not connected" }, - { WSAESHUTDOWN, "Can't send after socket shutdown" }, - { WSAETOOMANYREFS, "Too many references, can't splice" }, - { WSAETIMEDOUT, "Connection timed out" }, - { WSAECONNREFUSED, "Connection refused" }, - { WSAELOOP, "Too many levels of symbolic links" }, - { WSAENAMETOOLONG, "File name too long" }, - { WSAEHOSTDOWN, "Host is down" }, - { WSAEHOSTUNREACH, "No route to host" }, - { WSAENOTEMPTY, "Directory not empty" }, - { WSAEPROCLIM, "Too many processes" }, - { WSAEUSERS, "Too many users" }, - { WSAEDQUOT, "Disc quota exceeded" }, - { WSAESTALE, "Stale NFS file handle" }, - { WSAEREMOTE, "Too many levels of remote in path" }, - { WSASYSNOTREADY, "Network system is unavailable" }, - { WSAVERNOTSUPPORTED, "Winsock version out of range" }, - { WSANOTINITIALISED, "WSAStartup not yet called" }, - { WSAEDISCON, "Graceful shutdown in progress" }, - { WSAHOST_NOT_FOUND, "Host not found" }, - { WSANO_DATA, "No host data of that type was found" }, - { -1, "Unknown error code" } - }; - - static char *WSAErrorMsg() - { - int i; - int id = WSAGetLastError(); - - /* Assume none of them are actually -1 */ - for (i = 0; WSAErrors[i].id != -1; i++) - if (WSAErrors[i].id == id) - break; - - sprintf(WSAbuf, "Socket Error: (%d) %s", id, WSAErrors[i].code); - return &(WSAbuf[0]); - } - - #define SOCKERRMSG WSAErrorMsg() - - #ifndef SHUT_RDWR - #define SHUT_RDWR SD_BOTH - #endif - - #ifndef in_addr_t - #define in_addr_t uint32_t - #endif -#endif - -// Big enough for largest API request -// though a PC with 100s of PGAs/CPUs may exceed the size ... -// Current code assumes it can socket send this size also -#define MYBUFSIZ 65432 // TODO: intercept before it's exceeded +// Max amount of data to buffer before sending on the socket +#define RPC_SOCKBUFSIZ 0x10000 // BUFSIZ varies on Windows and Linux #define TMPBUFSIZ 8192 @@ -153,20 +51,20 @@ // However lots of PGA's may mean more #define QUEUE 100 -static char *io_buffer = NULL; -static char *msg_buffer = NULL; -static SOCKETTYPE sock = INVSOCK; - static const char *UNAVAILABLE = " - API will not be available"; -static const char *INVAPIGROUPS = "Invalid --api-groups parameter"; +static const char *MUNAVAILABLE = " - API multicast listener will not be available"; static const char *BLANK = ""; static const char *COMMA = ","; +#define COMSTR "," static const char SEPARATOR = '|'; #define SEPSTR "|" static const char GPUSEP = ','; +#define CMDJOIN '+' +#define JOIN_CMD "CMD=" +#define BETWEEN_JOIN SEPSTR -static const char *APIVERSION = "1.14"; +static const char *APIVERSION = "3.1"; static const char *DEAD = "Dead"; static const char *SICK = "Sick"; static const char *NOSTART = "NoStart"; @@ -177,32 +75,23 @@ static const char *ALIVE = "Alive"; static const char *REJECTING = "Rejecting"; static const char *UNKNOWN = "Unknown"; #define _DYNAMIC "D" +#ifdef USE_OPENCL static const char *DYNAMIC = _DYNAMIC; +#endif static const char *YES = "Y"; static const char *NO = "N"; static const char *NULLSTR = "(null)"; -static const char *DEVICECODE = "" -#ifdef HAVE_OPENCL - "GPU " -#endif -#ifdef USE_BITFORCE - "BFL " -#endif -#ifdef USE_ICARUS - "ICA " -#endif -#ifdef USE_ZTEX - "ZTX " -#endif -#ifdef USE_MODMINER - "MMQ " +static const char *TRUESTR = "true"; +static const char *FALSESTR = "false"; + +#ifdef USE_SCRYPT +static const char *SCRYPTSTR = "scrypt"; #endif -#ifdef WANT_CPUMINE - "CPU " +#ifdef USE_SHA256D +static const char *SHA256STR = "sha256"; #endif - ""; static const char *OSINFO = #if defined(__linux) @@ -211,7 +100,9 @@ static const char *OSINFO = #if defined(__APPLE__) "Apple"; #else -#if defined (WIN32) +#if defined (__CYGWIN__) + "Cygwin"; +#elif defined (WIN32) "Windows"; #else #if defined(unix) @@ -228,14 +119,14 @@ static const char *OSINFO = #define _SUMMARY "SUMMARY" #define _STATUS "STATUS" #define _VERSION "VERSION" -#define _MINECON "CONFIG" +#define _MINECONFIG "CONFIG" #define _GPU "GPU" #ifdef HAVE_AN_FPGA #define _PGA "PGA" #endif -#ifdef WANT_CPUMINE +#ifdef USE_CPUMINING #define _CPU "CPU" #endif @@ -248,6 +139,9 @@ static const char *OSINFO = #define _RESTART "RESTART" #define _MINESTATS "STATS" #define _CHECK "CHECK" +#define _MINECOIN "COIN" +#define _DEBUGSET "DEBUG" +#define _SETCONFIG "SETCONFIG" static const char ISJSON = '{'; #define JSON0 "{" @@ -255,6 +149,8 @@ static const char ISJSON = '{'; #define JSON2 "\":[" #define JSON3 "]" #define JSON4 ",\"id\":1" +// If anyone cares, id=0 for truncated output +#define JSON4_TRUNCATED ",\"id\":0" #define JSON5 "}" #define JSON_START JSON0 @@ -263,14 +159,14 @@ static const char ISJSON = '{'; #define JSON_SUMMARY JSON1 _SUMMARY JSON2 #define JSON_STATUS JSON1 _STATUS JSON2 #define JSON_VERSION JSON1 _VERSION JSON2 -#define JSON_MINECON JSON1 _MINECON JSON2 +#define JSON_MINECONFIG JSON1 _MINECONFIG JSON2 #define JSON_GPU JSON1 _GPU JSON2 #ifdef HAVE_AN_FPGA #define JSON_PGA JSON1 _PGA JSON2 #endif -#ifdef WANT_CPUMINE +#ifdef USE_CPUMINING #define JSON_CPU JSON1 _CPU JSON2 #endif @@ -278,13 +174,14 @@ static const char ISJSON = '{'; #define JSON_PGAS JSON1 _PGAS JSON2 #define JSON_CPUS JSON1 _CPUS JSON2 #define JSON_NOTIFY JSON1 _NOTIFY JSON2 -#define JSON_DEVDETAILS JSON1 _DEVDETAILS JSON2 -#define JSON_BYE JSON1 _BYE JSON1 -#define JSON_RESTART JSON1 _RESTART JSON1 #define JSON_CLOSE JSON3 #define JSON_MINESTATS JSON1 _MINESTATS JSON2 #define JSON_CHECK JSON1 _CHECK JSON2 +#define JSON_DEBUGSET JSON1 _DEBUGSET JSON2 +#define JSON_SETCONFIG JSON1 _SETCONFIG JSON2 #define JSON_END JSON4 JSON5 +#define JSON_END_TRUNCATED JSON4_TRUNCATED JSON5 +#define JSON_BETWEEN_JOIN "," static const char *JSON_COMMAND = "command"; static const char *JSON_PARAMETER = "parameter"; @@ -306,10 +203,16 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_MISID 15 #define MSG_GPUDEV 17 -#ifdef WANT_CPUMINE +#ifdef USE_CPUMINING #define MSG_CPUNON 16 #define MSG_CPUDEV 18 #define MSG_INVCPU 19 +#define MSG_ALRENAC 98 +#define MSG_ALRDISC 99 +#define MSG_CPUMRE 100 +#define MSG_CPUREN 101 +#define MSG_CPUDIS 102 +#define MSG_CPUREI 103 #endif #define MSG_NUMGPU 20 @@ -325,7 +228,7 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_NOGPUADL 30 #define MSG_INVINT 31 #define MSG_GPUINT 32 -#define MSG_MINECON 33 +#define MSG_MINECONFIG 33 #define MSG_GPUMERR 34 #define MSG_GPUMEM 35 #define MSG_GPUEERR 36 @@ -340,7 +243,6 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_ACCDENY 45 #define MSG_ACCOK 46 #define MSG_ENAPOOL 47 -#define MSG_POOLPRIO 73 #define MSG_DISPOOL 48 #define MSG_ALRENAP 49 #define MSG_ALRDISP 50 @@ -364,6 +266,7 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_PGALRDIS 62 #define MSG_PGAENA 63 #define MSG_PGADIS 64 +#define MSG_PGAREI 0x101 #define MSG_PGAUNW 65 #endif @@ -374,6 +277,45 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_MINESTATS 70 #define MSG_MISCHK 71 #define MSG_CHECK 72 +#define MSG_POOLPRIO 73 +#define MSG_DUPPID 74 +#define MSG_MISBOOL 75 +#define MSG_INVBOOL 76 +#define MSG_FOO 77 +#define MSG_MINECOIN 78 +#define MSG_DEBUGSET 79 +#define MSG_PGAIDENT 80 +#define MSG_PGANOID 81 + +#define MSG_SETCONFIG 82 +#define MSG_UNKCON 83 +#define MSG_INVNUM 84 +#define MSG_CONPAR 85 +#define MSG_CONVAL 86 + +#ifdef HAVE_AN_FPGA +#define MSG_MISPGAOPT 89 +#define MSG_PGANOSET 90 +#define MSG_PGAHELP 91 +#define MSG_PGASETOK 92 +#define MSG_PGASETERR 93 +#endif + +#define MSG_ZERMIS 94 +#define MSG_ZERINV 95 +#define MSG_ZERSUM 96 +#define MSG_ZERNOSUM 97 + +#define MSG_DEVSCAN 0x100 +#define MSG_BYE 0x101 + +#define MSG_INVNEG 121 +#define MSG_SETQUOTA 122 + +#define MSG_INVSTRATEGY 0x102 +#define MSG_FAILPORT 0x103 + +#define USE_ALTMSG 0x4000 enum code_severity { SEVERITY_ERR, @@ -384,9 +326,11 @@ enum code_severity { }; enum code_parameters { + PARAM_COUNT, PARAM_GPU, PARAM_PGA, PARAM_CPU, + PARAM_PID, PARAM_GPUMAX, PARAM_PGAMAX, PARAM_CPUMAX, @@ -400,6 +344,8 @@ enum code_parameters { PARAM_POOL, PARAM_STR, PARAM_BOTH, + PARAM_BOOL, + PARAM_SET, PARAM_NONE }; @@ -409,7 +355,7 @@ struct CODES { const enum code_parameters params; const char *description; } codes[] = { -#ifdef HAVE_OPENCL +#ifdef USE_OPENCL { SEVERITY_ERR, MSG_INVGPU, PARAM_GPUMAX, "Invalid GPU id %d - range is 0 - %d" }, { SEVERITY_INFO, MSG_ALRENA, PARAM_GPU, "GPU %d already enabled" }, { SEVERITY_INFO, MSG_ALRDIS, PARAM_GPU, "GPU %d already disabled" }, @@ -421,40 +367,20 @@ struct CODES { { SEVERITY_ERR, MSG_NOPOOL, PARAM_NONE, "No pools" }, { SEVERITY_SUCC, MSG_DEVS, PARAM_DMAX, -#ifdef HAVE_OPENCL - "%d GPU(s)" -#endif -#if defined(HAVE_AN_FPGA) && defined(HAVE_OPENCL) - " - " -#endif -#ifdef HAVE_AN_FPGA "%d PGA(s)" -#endif -#if defined(WANT_CPUMINE) && (defined(HAVE_OPENCL) || defined(HAVE_AN_FPGA)) - " - " -#endif -#ifdef WANT_CPUMINE - "%d CPU(s)" -#endif }, - { SEVERITY_ERR, MSG_NODEVS, PARAM_NONE, "No GPUs" -#ifdef HAVE_AN_FPGA - "/PGAs" -#endif -#ifdef WANT_CPUMINE - "/CPUs" -#endif + { SEVERITY_ERR, MSG_NODEVS, PARAM_NONE, "No PGAs" }, { SEVERITY_SUCC, MSG_SUMM, PARAM_NONE, "Summary" }, -#ifdef HAVE_OPENCL +#ifdef USE_OPENCL { SEVERITY_INFO, MSG_GPUDIS, PARAM_GPU, "GPU %d set disable flag" }, { SEVERITY_INFO, MSG_GPUREI, PARAM_GPU, "GPU %d restart attempted" }, #endif { SEVERITY_ERR, MSG_INVCMD, PARAM_NONE, "Invalid command" }, { SEVERITY_ERR, MSG_MISID, PARAM_NONE, "Missing device id parameter" }, -#ifdef HAVE_OPENCL +#ifdef USE_OPENCL { SEVERITY_SUCC, MSG_GPUDEV, PARAM_GPU, "GPU%d" }, #endif #ifdef HAVE_AN_FPGA @@ -467,10 +393,16 @@ struct CODES { { SEVERITY_INFO, MSG_PGADIS, PARAM_PGA, "PGA %d set disable flag" }, { SEVERITY_ERR, MSG_PGAUNW, PARAM_PGA, "PGA %d is not flagged WELL, cannot enable" }, #endif -#ifdef WANT_CPUMINE +#ifdef USE_CPUMINING { SEVERITY_ERR, MSG_CPUNON, PARAM_NONE, "No CPUs" }, { SEVERITY_SUCC, MSG_CPUDEV, PARAM_CPU, "CPU%d" }, { SEVERITY_ERR, MSG_INVCPU, PARAM_CPUMAX, "Invalid CPU id %d - range is 0 - %d" }, + { SEVERITY_INFO, MSG_ALRENAC, PARAM_CPU, "CPU %d already enabled" }, + { SEVERITY_INFO, MSG_ALRDISC, PARAM_CPU, "CPU %d already disabled" }, + { SEVERITY_WARN, MSG_CPUMRE, PARAM_CPU, "CPU %d must be restarted first" }, + { SEVERITY_INFO, MSG_CPUREN, PARAM_CPU, "CPU %d sent enable message" }, + { SEVERITY_INFO, MSG_CPUDIS, PARAM_CPU, "CPU %d set disable flag" }, + { SEVERITY_INFO, MSG_CPUREI, PARAM_CPU, "CPU %d restart attempted" }, #endif { SEVERITY_SUCC, MSG_NUMGPU, PARAM_NONE, "GPU count" }, { SEVERITY_SUCC, MSG_NUMPGA, PARAM_NONE, "PGA count" }, @@ -484,10 +416,10 @@ struct CODES { { SEVERITY_ERR, MSG_MISVAL, PARAM_NONE, "Missing comma after GPU number" }, { SEVERITY_ERR, MSG_NOADL, PARAM_NONE, "ADL is not available" }, { SEVERITY_ERR, MSG_NOGPUADL,PARAM_GPU, "GPU %d does not have ADL" }, - { SEVERITY_ERR, MSG_INVINT, PARAM_STR, "Invalid intensity (%s) - must be '" _DYNAMIC "' or range " _MIN_INTENSITY_STR " - " _MAX_INTENSITY_STR }, + { SEVERITY_ERR, MSG_INVINT, PARAM_STR, "Invalid intensity (%s) - must be '" _DYNAMIC "' or range -10 - 31" }, { SEVERITY_INFO, MSG_GPUINT, PARAM_BOTH, "GPU %d set new intensity to %s" }, - { SEVERITY_SUCC, MSG_MINECON, PARAM_NONE, "BFGMiner config" }, -#ifdef HAVE_OPENCL + { SEVERITY_SUCC, MSG_MINECONFIG,PARAM_NONE, "BFGMiner config" }, +#ifdef USE_OPENCL { SEVERITY_ERR, MSG_GPUMERR, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported failure" }, { SEVERITY_SUCC, MSG_GPUMEM, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported success" }, { SEVERITY_ERR, MSG_GPUEERR, PARAM_BOTH, "Setting GPU %d clock to (%s) reported failure" }, @@ -504,6 +436,7 @@ struct CODES { { SEVERITY_SUCC, MSG_ACCOK, PARAM_NONE, "Privileged access OK" }, { SEVERITY_SUCC, MSG_ENAPOOL, PARAM_POOL, "Enabling pool %d:'%s'" }, { SEVERITY_SUCC, MSG_POOLPRIO,PARAM_NONE, "Changed pool priorities" }, + { SEVERITY_ERR, MSG_DUPPID, PARAM_PID, "Duplicate pool specified %d" }, { SEVERITY_SUCC, MSG_DISPOOL, PARAM_POOL, "Disabling pool %d:'%s'" }, { SEVERITY_INFO, MSG_ALRENAP, PARAM_POOL, "Pool %d:'%s' already enabled" }, { SEVERITY_INFO, MSG_ALRDISP, PARAM_POOL, "Pool %d:'%s' already disabled" }, @@ -517,15 +450,48 @@ struct CODES { { SEVERITY_SUCC, MSG_REMPOOL, PARAM_BOTH, "Removed pool %d:'%s'" }, { SEVERITY_SUCC, MSG_NOTIFY, PARAM_NONE, "Notify" }, { SEVERITY_SUCC, MSG_DEVDETAILS,PARAM_NONE, "Device Details" }, - { SEVERITY_SUCC, MSG_MINESTATS,PARAM_NONE, "CGMiner stats" }, + { SEVERITY_SUCC, MSG_MINESTATS,PARAM_NONE, "BFGMiner stats" }, { SEVERITY_ERR, MSG_MISCHK, PARAM_NONE, "Missing check cmd" }, { SEVERITY_SUCC, MSG_CHECK, PARAM_NONE, "Check command" }, + { SEVERITY_ERR, MSG_MISBOOL, PARAM_NONE, "Missing parameter: true/false" }, + { SEVERITY_ERR, MSG_INVBOOL, PARAM_NONE, "Invalid parameter should be true or false" }, + { SEVERITY_SUCC, MSG_FOO, PARAM_BOOL, "Failover-Only set to %s" }, + { SEVERITY_SUCC, MSG_MINECOIN,PARAM_NONE, "BFGMiner coin" }, + { SEVERITY_SUCC, MSG_DEBUGSET,PARAM_NONE, "Debug settings" }, +#ifdef HAVE_AN_FPGA + { SEVERITY_SUCC, MSG_PGAIDENT,PARAM_PGA, "Identify command sent to PGA%d" }, + { SEVERITY_WARN, MSG_PGANOID, PARAM_PGA, "PGA%d does not support identify" }, +#endif + { SEVERITY_SUCC, MSG_SETCONFIG,PARAM_SET, "Set config '%s' to %d" }, + { SEVERITY_ERR, MSG_UNKCON, PARAM_STR, "Unknown config '%s'" }, + { SEVERITY_ERR, MSG_INVNUM, PARAM_BOTH, "Invalid number (%d) for '%s' range is 0-9999" }, + { SEVERITY_ERR, MSG_INVNEG, PARAM_BOTH, "Invalid negative number (%d) for '%s'" }, + { SEVERITY_ERR, MSG_INVSTRATEGY, PARAM_STR, "Invalid strategy for '%s'" }, + { SEVERITY_ERR, MSG_FAILPORT, PARAM_BOTH, "Failed to set port (%d) for '%s'" }, + { SEVERITY_SUCC, MSG_SETQUOTA,PARAM_SET, "Set pool '%s' to quota %d'" }, + { SEVERITY_ERR, MSG_CONPAR, PARAM_NONE, "Missing config parameters 'name,N'" }, + { SEVERITY_ERR, MSG_CONVAL, PARAM_STR, "Missing config value N for '%s,N'" }, +#ifdef HAVE_AN_FPGA + { SEVERITY_ERR, MSG_MISPGAOPT, PARAM_NONE, "Missing option after PGA number" }, + { SEVERITY_WARN, MSG_PGANOSET, PARAM_PGA, "PGA %d does not support pgaset" }, + { SEVERITY_INFO, MSG_PGAHELP, PARAM_BOTH, "PGA %d set help: %s" }, + { SEVERITY_SUCC, MSG_PGASETOK, PARAM_PGA, "PGA %d set OK" }, + { SEVERITY_SUCC, MSG_PGASETOK | USE_ALTMSG, PARAM_BOTH, "PGA %d set OK: %s" }, + { SEVERITY_ERR, MSG_PGASETERR, PARAM_BOTH, "PGA %d set failed: %s" }, +#endif + { SEVERITY_ERR, MSG_ZERMIS, PARAM_NONE, "Missing zero parameters" }, + { SEVERITY_ERR, MSG_ZERINV, PARAM_STR, "Invalid zero parameter '%s'" }, + { SEVERITY_SUCC, MSG_ZERSUM, PARAM_STR, "Zeroed %s stats with summary" }, + { SEVERITY_SUCC, MSG_ZERNOSUM, PARAM_STR, "Zeroed %s stats without summary" }, + { SEVERITY_SUCC, MSG_DEVSCAN, PARAM_COUNT, "Added %d new device(s)" }, + { SEVERITY_SUCC, MSG_BYE, PARAM_STR, "%s" }, { SEVERITY_FAIL, 0, 0, NULL } }; +static const char *localaddr = "127.0.0.1"; + static int my_thr_id = 0; static bool bye; -static bool ping = true; // Used to control quit restart access to shutdown variables static pthread_mutex_t quit_restart_lock; @@ -534,6 +500,7 @@ static bool do_a_quit; static bool do_a_restart; static time_t when = 0; // when the request occurred +static bool per_proc; struct IP4ACCESS { in_addr_t ip; @@ -558,21 +525,98 @@ struct APIGROUPS { static struct IP4ACCESS *ipaccess = NULL; static int ips = 0; -#ifdef USE_BITFORCE -extern struct device_api bitforce_api; -#endif +struct io_data { + bytes_t data; + SOCKETTYPE sock; + + // Whether to add various things + bool close; +}; +static struct io_data *rpc_io_data; -#ifdef USE_ICARUS -extern struct device_api icarus_api; -#endif +static void io_reinit(struct io_data *io_data) +{ + bytes_reset(&io_data->data); + io_data->close = false; +} -#ifdef USE_ZTEX -extern struct device_api ztex_api; -#endif +static +struct io_data *sock_io_new() +{ + struct io_data *io_data = malloc(sizeof(struct io_data)); + bytes_init(&io_data->data); + io_data->sock = INVSOCK; + io_reinit(io_data); + return io_data; +} -#ifdef USE_MODMINER -extern struct device_api modminer_api; -#endif +static +size_t io_flush(struct io_data *io_data, bool complete) +{ + size_t sent = 0, tosend = bytes_len(&io_data->data); + ssize_t n; + struct timeval timeout = {0, complete ? 50000: 0}, tv; + fd_set wd; + int count = 0; + + while (tosend) + { + FD_ZERO(&wd); + FD_SET(io_data->sock, &wd); + tv = timeout; + if (select(io_data->sock + 1, NULL, &wd, NULL, &tv) < 1) + break; + + n = send(io_data->sock, (void*)&bytes_buf(&io_data->data)[sent], tosend, 0); + if (SOCKETFAIL(n)) + { + if (!sock_blocks()) + applog(LOG_WARNING, "API: send (%lu) failed: %s", (unsigned long)tosend, SOCKERRMSG); + break; + } + if (count <= 1) + { + if (n == tosend) + applog(LOG_DEBUG, "API: sent all of %lu first go", (unsigned long)tosend); + else + applog(LOG_DEBUG, "API: sent %ld of %lu first go", (long)n, (unsigned long)tosend); + } + else + { + if (n == tosend) + applog(LOG_DEBUG, "API: sent all of remaining %lu (count=%d)", (unsigned long)tosend, count); + else + applog(LOG_DEBUG, "API: sent %ld of remaining %lu (count=%d)", (long)n, (unsigned long)tosend, count); + } + sent += n; + tosend -= n; + } + + bytes_shift(&io_data->data, sent); + + return sent; +} + +static bool io_add(struct io_data *io_data, char *buf) +{ + size_t len = strlen(buf); + if (bytes_len(&io_data->data) + len > RPC_SOCKBUFSIZ) + io_flush(io_data, false); + bytes_append(&io_data->data, buf, len); + return true; +} + +static void io_close(struct io_data *io_data) +{ + io_data->close = true; +} + +static void io_free() +{ + bytes_free(&rpc_io_data->data); + free(rpc_io_data); + rpc_io_data = NULL; +} // This is only called when expected to be needed (rarely) // i.e. strings outside of the codes control (input from the user) @@ -663,13 +707,14 @@ static struct api_data *api_add_extra(struct api_data *root, struct api_data *ex return root; } -static struct api_data *api_add_data_full(struct api_data *root, char *name, enum api_data_type type, void *data, bool copy_data) +static +struct api_data *api_add_data_full(struct api_data *root, const char * const name, enum api_data_type type, const void *data, bool copy_data) { struct api_data *api_data; api_data = (struct api_data *)malloc(sizeof(struct api_data)); - api_data->name = name; + api_data->name = strdup(name); api_data->type = type; if (root == NULL) { @@ -689,7 +734,7 @@ static struct api_data *api_add_data_full(struct api_data *root, char *name, enu // Avoid crashing on bad data if (data == NULL) { api_data->type = type = API_CONST; - data = (void *)NULLSTR; + data = NULLSTR; api_data->data_was_malloc = copy_data = false; } @@ -700,28 +745,34 @@ static struct api_data *api_add_data_full(struct api_data *root, char *name, enu json_incref((json_t *)data); } else + { + size_t datalen = 0; switch(type) { case API_ESCAPE: case API_STRING: case API_CONST: - api_data->data = (void *)malloc(strlen((char *)data) + 1); - strcpy((char*)(api_data->data), (char *)data); + datalen = strlen(data) + 1; + break; + case API_UINT8: + datalen = sizeof(uint8_t); + break; + case API_INT16: + datalen = sizeof(int16_t); + break; + case API_UINT16: + datalen = sizeof(uint16_t); break; case API_INT: - api_data->data = (void *)malloc(sizeof(int)); - *((int *)(api_data->data)) = *((int *)data); + datalen = sizeof(int); break; case API_UINT: - api_data->data = (void *)malloc(sizeof(unsigned int)); - *((unsigned int *)(api_data->data)) = *((unsigned int *)data); + datalen = sizeof(unsigned int); break; case API_UINT32: - api_data->data = (void *)malloc(sizeof(uint32_t)); - *((uint32_t *)(api_data->data)) = *((uint32_t *)data); + datalen = sizeof(uint32_t); break; case API_UINT64: - api_data->data = (void *)malloc(sizeof(uint64_t)); - *((uint64_t *)(api_data->data)) = *((uint64_t *)data); + datalen = sizeof(uint64_t); break; case API_DOUBLE: case API_ELAPSED: @@ -730,148 +781,185 @@ static struct api_data *api_add_data_full(struct api_data *root, char *name, enu case API_UTILITY: case API_FREQ: case API_HS: - api_data->data = (void *)malloc(sizeof(double)); - *((double *)(api_data->data)) = *((double *)data); + case API_DIFF: + case API_PERCENT: + datalen = sizeof(double); break; case API_BOOL: - api_data->data = (void *)malloc(sizeof(bool)); - *((bool *)(api_data->data)) = *((bool *)data); + datalen = sizeof(bool); break; case API_TIMEVAL: - api_data->data = (void *)malloc(sizeof(struct timeval)); - memcpy(api_data->data, data, sizeof(struct timeval)); + datalen = sizeof(struct timeval); break; case API_TIME: - api_data->data = (void *)malloc(sizeof(time_t)); - *(time_t *)(api_data->data) = *((time_t *)data); + datalen = sizeof(time_t); break; case API_VOLTS: case API_TEMP: - api_data->data = (void *)malloc(sizeof(float)); - *((float *)(api_data->data)) = *((float *)data); + datalen = sizeof(float); break; case API_JSON: api_data->data_was_malloc = false; - api_data->data = (void *)json_deep_copy((json_t *)data); + api_data->data = json_deep_copy((json_t *)data); break; default: applog(LOG_ERR, "API: unknown1 data type %d ignored", type); api_data->type = API_STRING; api_data->data_was_malloc = false; - api_data->data = (void *)UNKNOWN; + api_data->data = UNKNOWN; break; } + if (datalen) + { + void * const copied_data = malloc(datalen); + memcpy(copied_data, data, datalen); + api_data->data = copied_data; + } + } return root; } -struct api_data *api_add_escape(struct api_data *root, char *name, char *data, bool copy_data) +struct api_data *api_add_escape(struct api_data * const root, const char * const name, const char * const data, const bool copy_data) +{ + return api_add_data_full(root, name, API_ESCAPE, data, copy_data); +} + +struct api_data *api_add_string(struct api_data * const root, const char * const name, const char * const data, const bool copy_data) +{ + return api_add_data_full(root, name, API_STRING, data, copy_data); +} + +struct api_data *api_add_const(struct api_data * const root, const char * const name, const char * const data, const bool copy_data) +{ + return api_add_data_full(root, name, API_CONST, data, copy_data); +} + +struct api_data *api_add_uint8(struct api_data * const root, const char * const name, const uint8_t * const data, const bool copy_data) +{ + return api_add_data_full(root, name, API_UINT8, data, copy_data); +} + +struct api_data *api_add_int16(struct api_data * const root, const char * const name, const uint16_t * const data, const bool copy_data) { - return api_add_data_full(root, name, API_ESCAPE, (void *)data, copy_data); + return api_add_data_full(root, name, API_INT16, data, copy_data); } -struct api_data *api_add_string(struct api_data *root, char *name, const char *data, bool copy_data) +struct api_data *api_add_uint16(struct api_data * const root, const char * const name, const uint16_t * const data, const bool copy_data) { - return api_add_data_full(root, name, API_STRING, (void *)data, copy_data); + return api_add_data_full(root, name, API_UINT16, data, copy_data); } -struct api_data *api_add_const(struct api_data *root, char *name, const char *data, bool copy_data) +struct api_data *api_add_int(struct api_data * const root, const char * const name, const int * const data, const bool copy_data) { - return api_add_data_full(root, name, API_CONST, (void *)data, copy_data); + return api_add_data_full(root, name, API_INT, data, copy_data); } -struct api_data *api_add_int(struct api_data *root, char *name, int *data, bool copy_data) +struct api_data *api_add_uint(struct api_data * const root, const char * const name, const unsigned int * const data, const bool copy_data) { - return api_add_data_full(root, name, API_INT, (void *)data, copy_data); + return api_add_data_full(root, name, API_UINT, data, copy_data); } -struct api_data *api_add_uint(struct api_data *root, char *name, unsigned int *data, bool copy_data) +struct api_data *api_add_uint32(struct api_data * const root, const char * const name, const uint32_t * const data, const bool copy_data) { - return api_add_data_full(root, name, API_UINT, (void *)data, copy_data); + return api_add_data_full(root, name, API_UINT32, data, copy_data); } -struct api_data *api_add_uint32(struct api_data *root, char *name, uint32_t *data, bool copy_data) +struct api_data *api_add_uint64(struct api_data * const root, const char * const name, const uint64_t * const data, const bool copy_data) { - return api_add_data_full(root, name, API_UINT32, (void *)data, copy_data); + return api_add_data_full(root, name, API_UINT64, data, copy_data); } -struct api_data *api_add_uint64(struct api_data *root, char *name, uint64_t *data, bool copy_data) +struct api_data *api_add_double(struct api_data * const root, const char * const name, const double * const data, const bool copy_data) { - return api_add_data_full(root, name, API_UINT64, (void *)data, copy_data); + return api_add_data_full(root, name, API_DOUBLE, data, copy_data); } -struct api_data *api_add_double(struct api_data *root, char *name, double *data, bool copy_data) +struct api_data *api_add_elapsed(struct api_data * const root, const char * const name, const double * const data, const bool copy_data) { - return api_add_data_full(root, name, API_DOUBLE, (void *)data, copy_data); + return api_add_data_full(root, name, API_ELAPSED, data, copy_data); } -struct api_data *api_add_elapsed(struct api_data *root, char *name, double *data, bool copy_data) +struct api_data *api_add_bool(struct api_data * const root, const char * const name, const bool * const data, const bool copy_data) { - return api_add_data_full(root, name, API_ELAPSED, (void *)data, copy_data); + return api_add_data_full(root, name, API_BOOL, data, copy_data); } -struct api_data *api_add_bool(struct api_data *root, char *name, bool *data, bool copy_data) +struct api_data *api_add_timeval(struct api_data * const root, const char * const name, const struct timeval * const data, const bool copy_data) { - return api_add_data_full(root, name, API_BOOL, (void *)data, copy_data); + return api_add_data_full(root, name, API_TIMEVAL, data, copy_data); } -struct api_data *api_add_timeval(struct api_data *root, char *name, struct timeval *data, bool copy_data) +struct api_data *api_add_time(struct api_data * const root, const char * const name, const time_t * const data, const bool copy_data) { - return api_add_data_full(root, name, API_TIMEVAL, (void *)data, copy_data); + return api_add_data_full(root, name, API_TIME, data, copy_data); } -struct api_data *api_add_time(struct api_data *root, char *name, time_t *data, bool copy_data) +struct api_data *api_add_mhs(struct api_data * const root, const char * const name, const double * const data, const bool copy_data) { - return api_add_data_full(root, name, API_TIME, (void *)data, copy_data); + return api_add_data_full(root, name, API_MHS, data, copy_data); } -struct api_data *api_add_mhs(struct api_data *root, char *name, double *data, bool copy_data) +struct api_data *api_add_mhtotal(struct api_data * const root, const char * const name, const double * const data, const bool copy_data) { - return api_add_data_full(root, name, API_MHS, (void *)data, copy_data); + return api_add_data_full(root, name, API_MHTOTAL, data, copy_data); } -struct api_data *api_add_mhtotal(struct api_data *root, char *name, double *data, bool copy_data) +struct api_data *api_add_temp(struct api_data * const root, const char * const name, const float * const data, const bool copy_data) { - return api_add_data_full(root, name, API_MHTOTAL, (void *)data, copy_data); + return api_add_data_full(root, name, API_TEMP, data, copy_data); } -struct api_data *api_add_temp(struct api_data *root, char *name, float *data, bool copy_data) +struct api_data *api_add_utility(struct api_data * const root, const char * const name, const double * const data, const bool copy_data) { - return api_add_data_full(root, name, API_TEMP, (void *)data, copy_data); + return api_add_data_full(root, name, API_UTILITY, data, copy_data); } -struct api_data *api_add_utility(struct api_data *root, char *name, double *data, bool copy_data) +struct api_data *api_add_freq(struct api_data * const root, const char * const name, const double * const data, const bool copy_data) { - return api_add_data_full(root, name, API_UTILITY, (void *)data, copy_data); + return api_add_data_full(root, name, API_FREQ, data, copy_data); } -struct api_data *api_add_freq(struct api_data *root, char *name, double *data, bool copy_data) +struct api_data *api_add_volts(struct api_data * const root, const char * const name, const float * const data, const bool copy_data) { - return api_add_data_full(root, name, API_FREQ, (void *)data, copy_data); + return api_add_data_full(root, name, API_VOLTS, data, copy_data); } -struct api_data *api_add_volts(struct api_data *root, char *name, float *data, bool copy_data) +struct api_data *api_add_hs(struct api_data * const root, const char * const name, const double * const data, const bool copy_data) { - return api_add_data_full(root, name, API_VOLTS, (void *)data, copy_data); + return api_add_data_full(root, name, API_HS, data, copy_data); } -struct api_data *api_add_hs(struct api_data *root, char *name, double *data, bool copy_data) +struct api_data *api_add_diff(struct api_data * const root, const char * const name, const double * const data, const bool copy_data) { - return api_add_data_full(root, name, API_HS, (void *)data, copy_data); + return api_add_data_full(root, name, API_DIFF, data, copy_data); } -struct api_data *api_add_json(struct api_data *root, char *name, json_t *data, bool copy_data) +// json_t is not const since we generally increase the refcount +struct api_data *api_add_json(struct api_data * const root, const char * const name, json_t * const data, const bool copy_data) { - return api_add_data_full(root, name, API_JSON, (void *)data, copy_data); + return api_add_data_full(root, name, API_JSON, data, copy_data); } -static struct api_data *print_data(struct api_data *root, char *buf, bool isjson) +struct api_data *api_add_percent(struct api_data * const root, const char * const name, const double * const data, const bool copy_data) +{ + return api_add_data_full(root, name, API_PERCENT, data, copy_data); +} + +static struct api_data *print_data(struct api_data *root, char *buf, bool isjson, bool precom) { struct api_data *tmp; bool first = true; char *original, *escape; char *quote; + *buf = '\0'; + + if (precom) { + *(buf++) = *COMMA; + *buf = '\0'; + } + if (isjson) { strcpy(buf, JSON0); buf = strchr(buf, '\0'); @@ -901,6 +989,15 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson if (escape != original) free(escape); break; + case API_UINT8: + sprintf(buf, "%u", *(uint8_t *)root->data); + break; + case API_INT16: + sprintf(buf, "%d", *(int16_t *)root->data); + break; + case API_UINT16: + sprintf(buf, "%u", *(uint16_t *)root->data); + break; case API_INT: sprintf(buf, "%d", *((int *)(root->data))); break; @@ -925,7 +1022,7 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson case API_UTILITY: case API_FREQ: case API_MHS: - sprintf(buf, "%.2f", *((double *)(root->data))); + sprintf(buf, "%.3f", *((double *)(root->data))); break; case API_VOLTS: sprintf(buf, "%.3f", *((float *)(root->data))); @@ -936,13 +1033,22 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson case API_HS: sprintf(buf, "%.15f", *((double *)(root->data))); break; + case API_DIFF: + { + const double *fp = root->data; + if (fmod(*fp, 1.)) + sprintf(buf, "%.8f", *fp); + else + sprintf(buf, "%.0f", *fp); + break; + } case API_BOOL: - sprintf(buf, "%s", *((bool *)(root->data)) ? "true" : "false"); + sprintf(buf, "%s", *((bool *)(root->data)) ? TRUESTR : FALSESTR); break; case API_TIMEVAL: - sprintf(buf, "%ld.%06ld", - ((struct timeval *)(root->data))->tv_sec, - ((struct timeval *)(root->data))->tv_usec); + sprintf(buf, "%"PRIu64".%06lu", + (uint64_t)((struct timeval *)(root->data))->tv_sec, + (unsigned long)((struct timeval *)(root->data))->tv_usec); break; case API_TEMP: sprintf(buf, "%.2f", *((float *)(root->data))); @@ -952,6 +1058,9 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson strcpy(buf, escape); free(escape); break; + case API_PERCENT: + sprintf(buf, "%.4f", *((double *)(root->data)) * 100.0); + break; default: applog(LOG_ERR, "API: unknown2 data type %d ignored", root->type); sprintf(buf, "%s%s%s", quote, UNKNOWN, quote); @@ -960,10 +1069,11 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson buf = strchr(buf, '\0'); + free(root->name); if (root->type == API_JSON) json_decref((json_t *)root->data); if (root->data_was_malloc) - free(root->data); + free((void*)root->data); if (root->next == root) { free(root); @@ -988,24 +1098,13 @@ static int numpgas() int count = 0; int i; + rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { -#ifdef USE_BITFORCE - if (devices[i]->api == &bitforce_api) - count++; -#endif -#ifdef USE_ICARUS - if (devices[i]->api == &icarus_api) - count++; -#endif -#ifdef USE_ZTEX - if (devices[i]->api == &ztex_api) - count++; -#endif -#ifdef USE_MODMINER - if (devices[i]->api == &modminer_api) - count++; -#endif + if (devices[i]->device != devices[i] && !per_proc) + continue; + ++count; } + rd_unlock(&devices_lock); return count; } @@ -1014,56 +1113,48 @@ static int pgadevice(int pgaid) int count = 0; int i; + rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { -#ifdef USE_BITFORCE - if (devices[i]->api == &bitforce_api) - count++; -#endif -#ifdef USE_ICARUS - if (devices[i]->api == &icarus_api) - count++; -#endif -#ifdef USE_ZTEX - if (devices[i]->api == &ztex_api) - count++; -#endif -#ifdef USE_MODMINER - if (devices[i]->api == &modminer_api) - count++; -#endif + if (devices[i]->device != devices[i] && !per_proc) + continue; + ++count; if (count == (pgaid + 1)) - return i; + goto foundit; } + + rd_unlock(&devices_lock); return -1; + +foundit: + + rd_unlock(&devices_lock); + return i; } #endif // All replies (except BYE and RESTART) start with a message // thus for JSON, message() inserts JSON_START at the front // and send_result() adds JSON_END at the end -static char *message(int messageid, int paramid, char *param2, bool isjson) +static void message(struct io_data * const io_data, const int messageid2, const int paramid, const char * const param2, const bool isjson) { struct api_data *root = NULL; char buf[TMPBUFSIZ]; + char buf2[TMPBUFSIZ]; char severity[2]; - char *ptr; #ifdef HAVE_AN_FPGA int pga; #endif -#ifdef WANT_CPUMINE +#ifdef USE_CPUMINING int cpu; #endif int i; + int messageid = messageid2 & ~USE_ALTMSG; - if (!isjson) - msg_buffer[0] = '\0'; - else - strcpy(msg_buffer, JSON_START JSON_STATUS); - - ptr = strchr(msg_buffer, '\0'); + if (isjson) + io_add(io_data, JSON_START JSON_STATUS); for (i = 0; codes[i].severity != SEVERITY_FAIL; i++) { - if (codes[i].code == messageid) { + if (codes[i].code == messageid2) { switch (codes[i].severity) { case SEVERITY_WARN: severity[0] = 'W'; @@ -1082,15 +1173,17 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) severity[1] = '\0'; switch(codes[i].params) { + case PARAM_COUNT: case PARAM_GPU: case PARAM_PGA: case PARAM_CPU: + case PARAM_PID: sprintf(buf, codes[i].description, paramid); break; case PARAM_POOL: sprintf(buf, codes[i].description, paramid, pools[paramid]->rpc_url); break; -#ifdef HAVE_OPENCL +#ifdef USE_OPENCL case PARAM_GPUMAX: sprintf(buf, codes[i].description, paramid, nDevs - 1); break; @@ -1101,7 +1194,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) sprintf(buf, codes[i].description, paramid, pga - 1); break; #endif -#ifdef WANT_CPUMINE +#ifdef USE_CPUMINING case PARAM_CPUMAX: if (opt_n_threads > 0) cpu = num_processors; @@ -1117,26 +1210,10 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) sprintf(buf, codes[i].description, paramid, total_pools - 1); break; case PARAM_DMAX: -#ifdef HAVE_AN_FPGA pga = numpgas(); -#endif -#ifdef WANT_CPUMINE - if (opt_n_threads > 0) - cpu = num_processors; - else - cpu = 0; -#endif sprintf(buf, codes[i].description -#ifdef HAVE_OPENCL - , nDevs -#endif -#ifdef HAVE_AN_FPGA , pga -#endif -#ifdef WANT_CPUMINE - , cpu -#endif ); break; case PARAM_CMD: @@ -1148,6 +1225,12 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) case PARAM_BOTH: sprintf(buf, codes[i].description, paramid, param2); break; + case PARAM_BOOL: + sprintf(buf, codes[i].description, paramid ? TRUESTR : FALSESTR); + break; + case PARAM_SET: + sprintf(buf, codes[i].description, param2, paramid); + break; case PARAM_NONE: default: strcpy(buf, codes[i].description); @@ -1156,13 +1239,14 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) root = api_add_string(root, _STATUS, severity, false); root = api_add_time(root, "When", &when, false); root = api_add_int(root, "Code", &messageid, false); - root = api_add_string(root, "Msg", buf, false); - root = api_add_string(root, "Description", opt_api_description, false); + root = api_add_escape(root, "Msg", buf, false); + root = api_add_escape(root, "Description", opt_api_description, false); - root = print_data(root, ptr, isjson); + root = print_data(root, buf2, isjson, false); + io_add(io_data, buf2); if (isjson) - strcat(ptr, JSON_CLOSE); - return msg_buffer; + io_add(io_data, JSON_CLOSE); + return; } } @@ -1171,48 +1255,49 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) int id = -1; root = api_add_int(root, "Code", &id, false); sprintf(buf, "%d", messageid); - root = api_add_string(root, "Msg", buf, false); - root = api_add_string(root, "Description", opt_api_description, false); + root = api_add_escape(root, "Msg", buf, false); + root = api_add_escape(root, "Description", opt_api_description, false); - root = print_data(root, ptr, isjson); + root = print_data(root, buf2, isjson, false); + io_add(io_data, buf2); if (isjson) - strcat(ptr, JSON_CLOSE); - return msg_buffer; + io_add(io_data, JSON_CLOSE); } -static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static void apiversion(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { struct api_data *root = NULL; char buf[TMPBUFSIZ]; + bool io_open; - sprintf(io_buffer, isjson - ? "%s," JSON_VERSION - : "%s" _VERSION ",", - message(MSG_VERSION, 0, NULL, isjson)); + message(io_data, MSG_VERSION, 0, NULL, isjson); + io_open = io_add(io_data, isjson ? COMSTR JSON_VERSION : _VERSION COMSTR); - root = api_add_string(root, "CGMiner", VERSION, false); + root = api_add_string(root, "Miner", bfgminer_name_space_ver, false); + root = api_add_string(root, "CGMiner", bfgminer_ver, false); root = api_add_const(root, "API", APIVERSION, false); - root = print_data(root, buf, isjson); - if (isjson) - strcat(buf, JSON_CLOSE); - strcat(io_buffer, buf); + root = print_data(root, buf, isjson, false); + io_add(io_data, buf); + if (isjson && io_open) + io_close(io_data); } -static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static void minerconfig(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { struct api_data *root = NULL; char buf[TMPBUFSIZ]; - int gpucount = 0; + bool io_open; + struct driver_registration *reg; int pgacount = 0; - int cpucount = 0; char *adlinuse = (char *)NO; + int i; #ifdef HAVE_ADL const char *adl = YES; - int i; for (i = 0; i < nDevs; i++) { - if (gpus[i].has_adl) { + struct opencl_device_data * const data = gpus[i].device_data; + if (data->has_adl) { adlinuse = (char *)YES; break; } @@ -1221,38 +1306,59 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, const char *adl = NO; #endif -#ifdef HAVE_OPENCL - gpucount = nDevs; -#endif - #ifdef HAVE_AN_FPGA pgacount = numpgas(); #endif -#ifdef WANT_CPUMINE - cpucount = opt_n_threads > 0 ? num_processors : 0; -#endif - - sprintf(io_buffer, isjson - ? "%s," JSON_MINECON - : "%s" _MINECON ",", - message(MSG_MINECON, 0, NULL, isjson)); + message(io_data, MSG_MINECONFIG, 0, NULL, isjson); + io_open = io_add(io_data, isjson ? COMSTR JSON_MINECONFIG : _MINECONFIG COMSTR); - root = api_add_int(root, "GPU Count", &gpucount, false); root = api_add_int(root, "PGA Count", &pgacount, false); - root = api_add_int(root, "CPU Count", &cpucount, false); root = api_add_int(root, "Pool Count", &total_pools, false); root = api_add_const(root, "ADL", (char *)adl, false); root = api_add_string(root, "ADL in use", adlinuse, false); root = api_add_const(root, "Strategy", strategies[pool_strategy].s, false); + if (pool_strategy == POOL_ROTATE) + root = api_add_int(root, "Rotate Period", &opt_rotate_period, false); root = api_add_int(root, "Log Interval", &opt_log_interval, false); - root = api_add_const(root, "Device Code", DEVICECODE, false); + + strcpy(buf, "" +#ifdef USE_LIBMICROHTTPD + " SGW" +#endif +#ifdef USE_LIBEVENT + " SSM" +#endif + ); + + BFG_FOREACH_DRIVER_BY_DNAME(reg) + { + const struct device_drv * const drv = reg->drv; + tailsprintf(buf, sizeof(buf), " %s", drv->name); + } + root = api_add_const(root, "Device Code", &buf[1], true); + root = api_add_const(root, "OS", OSINFO, false); + root = api_add_bool(root, "Failover-Only", &opt_fail_only, false); + root = api_add_int(root, "ScanTime", &opt_scantime, false); + root = api_add_int(root, "Queue", &opt_queue, false); + root = api_add_int(root, "Expiry", &opt_expiry, false); +#if BLKMAKER_VERSION > 0 + root = api_add_string(root, "Coinbase-Sig", opt_coinbase_sig, true); +#endif + + struct bfg_loaded_configfile *configfile; + i = 0; + LL_FOREACH(bfg_loaded_configfiles, configfile) + { + snprintf(buf, sizeof(buf), "ConfigFile%d", i++); + root = api_add_string(root, buf, configfile->filename, false); + } - root = print_data(root, buf, isjson); - if (isjson) - strcat(buf, JSON_CLOSE); - strcat(io_buffer, buf); + root = print_data(root, buf, isjson, false); + io_add(io_data, buf); + if (isjson && io_open) + io_close(io_data); } static const char* @@ -1261,8 +1367,7 @@ bool2str(bool b) return b ? YES : NO; } -static const char* -status2str(enum alive status) +static const char *status2str(enum alive status) { switch (status) { case LIFE_WELL: @@ -1270,384 +1375,538 @@ status2str(enum alive status) case LIFE_SICK: return SICK; case LIFE_DEAD: + case LIFE_DEAD2: return DEAD; case LIFE_NOSTART: return NOSTART; case LIFE_INIT: + case LIFE_INIT2: return INIT; case LIFE_WAIT: return WAIT; + case LIFE_MIXED: + return "Mixed"; default: return UNKNOWN; } } -static void -devdetail_an(struct cgpu_info *cgpu, bool isjson) +static +struct api_data *api_add_device_identifier(struct api_data *root, struct cgpu_info *cgpu) +{ + root = api_add_string(root, "Name", cgpu->drv->name, false); + root = api_add_int(root, "ID", &(cgpu->device_id), false); + if (per_proc) + root = api_add_int(root, "ProcID", &(cgpu->proc_id), false); + return root; +} + +static +int find_index_by_cgpu(struct cgpu_info *cgpu) +{ + if (per_proc) + return cgpu->cgminer_id; + + int n = 0, i; + + // Quickly traverse the devices array backward until we reach the 0th device, counting as we go + rd_lock(&devices_lock); + while (true) + { + i = cgpu->device->cgminer_id; + if (!i) + break; + cgpu = devices[--i]; + ++n; + } + rd_unlock(&devices_lock); + return n; +} + +static void devdetail_an(struct io_data *io_data, struct cgpu_info *cgpu, bool isjson, bool precom) { struct api_data *root = NULL; char buf[TMPBUFSIZ]; - int n = 0, i; + int n; - cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; + cgpu_utility(cgpu); - for (i = 0; i < total_devices; ++i) { - if (devices[i] == cgpu) - break; - if (cgpu->devtype == devices[i]->devtype) - ++n; - } + n = find_index_by_cgpu(cgpu); - root = api_add_int(root, (char*)cgpu->devtype, &n, true); - root = api_add_string(root, "Driver", cgpu->api->dname, false); + root = api_add_int(root, "DEVDETAILS", &n, true); + root = api_add_device_identifier(root, cgpu); + if (!per_proc) + root = api_add_int(root, "Processors", &cgpu->procs, false); + root = api_add_string(root, "Driver", cgpu->drv->dname, false); if (cgpu->kname) root = api_add_string(root, "Kernel", cgpu->kname, false); if (cgpu->name) root = api_add_string(root, "Model", cgpu->name, false); + if (cgpu->dev_manufacturer) + root = api_add_string(root, "Manufacturer", cgpu->dev_manufacturer, false); + if (cgpu->dev_product) + root = api_add_string(root, "Product", cgpu->dev_product, false); + if (cgpu->dev_serial) + root = api_add_string(root, "Serial", cgpu->dev_serial, false); if (cgpu->device_path) root = api_add_string(root, "Device Path", cgpu->device_path, false); + + root = api_add_int(root, "Target Temperature", &cgpu->targettemp, false); + root = api_add_int(root, "Cutoff Temperature", &cgpu->cutofftemp, false); - if (cgpu->api->get_api_extra_device_detail) - root = api_add_extra(root, cgpu->api->get_api_extra_device_detail(cgpu)); + if ((per_proc || cgpu->procs <= 1) && cgpu->drv->get_api_extra_device_detail) + root = api_add_extra(root, cgpu->drv->get_api_extra_device_detail(cgpu)); - root = print_data(root, buf, isjson); - strcat(io_buffer, buf); + root = print_data(root, buf, isjson, precom); + io_add(io_data, buf); } -static void devstatus_an(struct cgpu_info *cgpu, bool isjson) +static +void devstatus_an(struct io_data *io_data, struct cgpu_info *cgpu, bool isjson, bool precom) { + struct cgpu_info *proc; struct api_data *root = NULL; char buf[TMPBUFSIZ]; - int n = 0, i; - - cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; + int n; - for (i = 0; i < total_devices; ++i) { - if (devices[i] == cgpu) + n = find_index_by_cgpu(cgpu); + + double runtime = cgpu_runtime(cgpu); + bool enabled = false; + double total_mhashes = 0, rolling = 0, utility = 0; + enum alive status = cgpu->status; + float temp = -1; + int accepted = 0, rejected = 0, stale = 0, hw_errors = 0; + double diff1 = 0, bad_diff1 = 0; + double diff_accepted = 0, diff_rejected = 0, diff_stale = 0; + int last_share_pool = -1; + time_t last_share_pool_time = -1, last_device_valid_work = -1; + double last_share_diff = -1; + int procs = per_proc ? 1 : cgpu->procs, i; + for (i = 0, proc = cgpu; i < procs; ++i, proc = proc->next_proc) + { + cgpu_utility(proc); + if (proc->deven != DEV_DISABLED) + enabled = true; + total_mhashes += proc->total_mhashes; + rolling += proc->drv->get_proc_rolling_hashrate ? proc->drv->get_proc_rolling_hashrate(proc) : proc->rolling; + utility += proc->utility; + accepted += proc->accepted; + rejected += proc->rejected; + stale += proc->stale; + hw_errors += proc->hw_errors; + diff1 += proc->diff1; + diff_accepted += proc->diff_accepted; + diff_rejected += proc->diff_rejected; + diff_stale += proc->diff_stale; + bad_diff1 += proc->bad_diff1; + if (status != proc->status) + status = LIFE_MIXED; + if (proc->temp > temp) + temp = proc->temp; + if (proc->last_share_pool_time > last_share_pool_time) + { + last_share_pool_time = proc->last_share_pool_time; + last_share_pool = proc->last_share_pool; + last_share_diff = proc->last_share_diff; + } + if (proc->last_device_valid_work > last_device_valid_work) + last_device_valid_work = proc->last_device_valid_work; + if (per_proc) break; - if (cgpu->devtype == devices[i]->devtype) - ++n; } - root = api_add_int(root, (char*)cgpu->devtype, &n, true); - root = api_add_string(root, "Name", cgpu->api->name, false); - root = api_add_int(root, "ID", &(cgpu->device_id), false); - root = api_add_string(root, "Enabled", bool2str(cgpu->deven != DEV_DISABLED), false); - root = api_add_string(root, "Status", status2str(cgpu->status), false); - if (cgpu->temp) - root = api_add_temp(root, "Temperature", &cgpu->temp, false); - double mhs = cgpu->total_mhashes / total_secs; + root = api_add_int(root, "PGA", &n, true); + root = api_add_device_identifier(root, cgpu); + root = api_add_string(root, "Enabled", bool2str(enabled), false); + root = api_add_string(root, "Status", status2str(status), false); + if (temp > 0) + root = api_add_temp(root, "Temperature", &temp, false); + + root = api_add_elapsed(root, "Device Elapsed", &runtime, false); + double mhs = total_mhashes / runtime; root = api_add_mhs(root, "MHS av", &mhs, false); char mhsname[27]; sprintf(mhsname, "MHS %ds", opt_log_interval); - root = api_add_mhs(root, mhsname, &(cgpu->rolling), false); - root = api_add_int(root, "Accepted", &(cgpu->accepted), false); - root = api_add_int(root, "Rejected", &(cgpu->rejected), false); - root = api_add_int(root, "Hardware Errors", &(cgpu->hw_errors), false); - root = api_add_utility(root, "Utility", &(cgpu->utility), false); - int last_share_pool = cgpu->last_share_pool_time > 0 ? - cgpu->last_share_pool : -1; - root = api_add_int(root, "Last Share Pool", &last_share_pool, false); - root = api_add_time(root, "Last Share Time", &(cgpu->last_share_pool_time), false); - root = api_add_mhtotal(root, "Total MH", &(cgpu->total_mhashes), false); - - if (cgpu->api->get_api_extra_device_status) - root = api_add_extra(root, cgpu->api->get_api_extra_device_status(cgpu)); - - root = print_data(root, buf, isjson); - strcat(io_buffer, buf); + root = api_add_mhs(root, mhsname, &rolling, false); + root = api_add_mhs(root, "MHS rolling", &rolling, false); + root = api_add_int(root, "Accepted", &accepted, false); + root = api_add_int(root, "Rejected", &rejected, false); + root = api_add_int(root, "Hardware Errors", &hw_errors, false); + root = api_add_utility(root, "Utility", &utility, false); + root = api_add_int(root, "Stale", &stale, false); + if (last_share_pool != -1) + { + root = api_add_int(root, "Last Share Pool", &last_share_pool, false); + root = api_add_time(root, "Last Share Time", &last_share_pool_time, false); + } + root = api_add_mhtotal(root, "Total MH", &total_mhashes, false); + double work_utility = diff1 / runtime * 60; + root = api_add_diff(root, "Diff1 Work", &diff1, false); + root = api_add_utility(root, "Work Utility", &work_utility, false); + root = api_add_diff(root, "Difficulty Accepted", &diff_accepted, false); + root = api_add_diff(root, "Difficulty Rejected", &diff_rejected, false); + root = api_add_diff(root, "Difficulty Stale", &diff_stale, false); + if (last_share_diff > 0) + root = api_add_diff(root, "Last Share Difficulty", &last_share_diff, false); + if (last_device_valid_work != -1) + root = api_add_time(root, "Last Valid Work", &last_device_valid_work, false); + double hwp = (bad_diff1 + diff1) ? + (double)(bad_diff1) / (double)(bad_diff1 + diff1) : 0; + root = api_add_percent(root, "Device Hardware%", &hwp, false); + double rejp = diff1 ? + (double)(diff_rejected) / (double)(diff1) : 0; + root = api_add_percent(root, "Device Rejected%", &rejp, false); + + if ((per_proc || cgpu->procs <= 1) && cgpu->drv->get_api_extra_device_status) + root = api_add_extra(root, cgpu->drv->get_api_extra_device_status(cgpu)); + + root = print_data(root, buf, isjson, precom); + io_add(io_data, buf); } -#ifdef HAVE_OPENCL -static void gpustatus(int gpu, bool isjson) +#ifdef USE_OPENCL +static void gpustatus(struct io_data *io_data, int gpu, bool isjson, bool precom) { if (gpu < 0 || gpu >= nDevs) return; - devstatus_an(&gpus[gpu], isjson); + devstatus_an(io_data, &gpus[gpu], isjson, precom); } #endif #ifdef HAVE_AN_FPGA -static void pgastatus(int pga, bool isjson) +static void pgastatus(struct io_data *io_data, int pga, bool isjson, bool precom) { int dev = pgadevice(pga); if (dev < 0) // Should never happen return; - devstatus_an(devices[dev], isjson); + devstatus_an(io_data, get_devices(dev), isjson, precom); } #endif -#ifdef WANT_CPUMINE -static void cpustatus(int cpu, bool isjson) +#ifdef USE_CPUMINING +static void cpustatus(struct io_data *io_data, int cpu, bool isjson, bool precom) { if (opt_n_threads <= 0 || cpu < 0 || cpu >= num_processors) return; - devstatus_an(&cpus[cpu], isjson); + devstatus_an(io_data, &cpus[cpu], isjson, precom); } #endif static void -devinfo_internal(void (*func)(struct cgpu_info*, bool), __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +devinfo_internal(void (*func)(struct io_data *, struct cgpu_info*, bool, bool), int msg, struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { + struct cgpu_info *cgpu; + bool io_open = false; int i; if (total_devices == 0) { - strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson)); + message(io_data, MSG_NODEVS, 0, NULL, isjson); return; } - strcpy(io_buffer, message(MSG_DEVS, 0, NULL, isjson)); - if (isjson) { - strcat(io_buffer, COMMA); - strcat(io_buffer, JSON_DEVS); - } + message(io_data, msg, 0, NULL, isjson); + if (isjson) + io_open = io_add(io_data, COMSTR JSON_DEVS); for (i = 0; i < total_devices; ++i) { - if (isjson && i > 0) - strcat(io_buffer, COMMA); - - func(devices[i], isjson); + cgpu = get_devices(i); + if (per_proc || cgpu->device == cgpu) + func(io_data, cgpu, isjson, isjson && i > 0); } - if (isjson) - strcat(io_buffer, JSON_CLOSE); + if (isjson && io_open) + io_close(io_data); } -static void -devdetail(SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void devdetail(struct io_data *io_data, SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { - return devinfo_internal(devdetail_an, c, param, isjson, group); + return devinfo_internal(devdetail_an, MSG_DEVDETAILS, io_data, c, param, isjson, group); } -static void -devstatus(SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void devstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { - return devinfo_internal(devstatus_an, c, param, isjson, group); + return devinfo_internal(devstatus_an, MSG_DEVS, io_data, c, param, isjson, group); } -#ifdef HAVE_OPENCL -static void gpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +#ifdef USE_OPENCL +static void gpudev(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { + bool io_open = false; int id; if (nDevs == 0) { - strcpy(io_buffer, message(MSG_GPUNON, 0, NULL, isjson)); + message(io_data, MSG_GPUNON, 0, NULL, isjson); return; } if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); + message(io_data, MSG_MISID, 0, NULL, isjson); return; } id = atoi(param); if (id < 0 || id >= nDevs) { - strcpy(io_buffer, message(MSG_INVGPU, id, NULL, isjson)); + message(io_data, MSG_INVGPU, id, NULL, isjson); return; } - strcpy(io_buffer, message(MSG_GPUDEV, id, NULL, isjson)); + message(io_data, MSG_GPUDEV, id, NULL, isjson); - if (isjson) { - strcat(io_buffer, COMMA); - strcat(io_buffer, JSON_GPU); - } + if (isjson) + io_open = io_add(io_data, COMSTR JSON_GPU); - gpustatus(id, isjson); + gpustatus(io_data, id, isjson, false); - if (isjson) - strcat(io_buffer, JSON_CLOSE); + if (isjson && io_open) + io_close(io_data); } #endif + +static void devscan(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +{ + int n; + bool io_open = false; + + applog(LOG_DEBUG, "RPC: request to scan %s for devices", + param); + + if (param && !param[0]) + param = NULL; + + n = scan_serial(param); + + message(io_data, MSG_DEVSCAN, n, NULL, isjson); + + io_open = io_add(io_data, isjson ? COMSTR JSON_DEVS : _DEVS COMSTR); + + n = total_devices - n; + for (int i = n; i < total_devices; ++i) + devdetail_an(io_data, get_devices(i), isjson, i > n); + + if (isjson && io_open) + io_close(io_data); +} + #ifdef HAVE_AN_FPGA -static void pgadev(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static +struct cgpu_info *get_pga_cgpu(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group, int *id_p, int *dev_p) { int numpga = numpgas(); - int id; - + if (numpga == 0) { - strcpy(io_buffer, message(MSG_PGANON, 0, NULL, isjson)); - return; + message(io_data, MSG_PGANON, 0, NULL, isjson); + return NULL; } - + if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); - return; + message(io_data, MSG_MISID, 0, NULL, isjson); + return NULL; } - - id = atoi(param); - if (id < 0 || id >= numpga) { - strcpy(io_buffer, message(MSG_INVPGA, id, NULL, isjson)); - return; + + *id_p = atoi(param); + if (*id_p < 0 || *id_p >= numpga) { + message(io_data, MSG_INVPGA, *id_p, NULL, isjson); + return NULL; } - - strcpy(io_buffer, message(MSG_PGADEV, id, NULL, isjson)); - - if (isjson) { - strcat(io_buffer, COMMA); - strcat(io_buffer, JSON_PGA); + + *dev_p = pgadevice(*id_p); + if (*dev_p < 0) { // Should never happen + message(io_data, MSG_INVPGA, *id_p, NULL, isjson); + return NULL; } + + return get_devices(*dev_p); +} + +static void pgadev(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + bool io_open = false; + int id, dev; - pgastatus(id, isjson); + if (!get_pga_cgpu(io_data, c, param, isjson, group, &id, &dev)) + return; + + message(io_data, MSG_PGADEV, id, NULL, isjson); if (isjson) - strcat(io_buffer, JSON_CLOSE); + io_open = io_add(io_data, COMSTR JSON_PGA); + + pgastatus(io_data, id, isjson, false); + + if (isjson && io_open) + io_close(io_data); } -static void pgaenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void pgaenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { - int numpga = numpgas(); - struct thr_info *thr; - int pga; - int id; - int i; + struct cgpu_info *cgpu, *proc; + int id, dev; + bool already; - if (numpga == 0) { - strcpy(io_buffer, message(MSG_PGANON, 0, NULL, isjson)); + cgpu = get_pga_cgpu(io_data, c, param, isjson, group, &id, &dev); + if (!cgpu) return; - } + + applog(LOG_DEBUG, "API: request to pgaenable %s id %d device %d %s", + per_proc ? "proc" : "dev", id, dev, cgpu->proc_repr_ns); - if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); - return; + already = true; + int procs = per_proc ? 1 : cgpu->procs, i; + for (i = 0, proc = cgpu; i < procs; ++i, proc = proc->next_proc) + { + if (proc->deven == DEV_DISABLED) + { + proc_enable(proc); + already = false; + } } - - id = atoi(param); - if (id < 0 || id >= numpga) { - strcpy(io_buffer, message(MSG_INVPGA, id, NULL, isjson)); + + if (already) + { + message(io_data, MSG_PGALRENA, id, NULL, isjson); return; } - int dev = pgadevice(id); - if (dev < 0) { // Should never happen - strcpy(io_buffer, message(MSG_INVPGA, id, NULL, isjson)); +#if 0 /* A DISABLED device wont change status FIXME: should disabling make it WELL? */ + if (cgpu->status != LIFE_WELL) { + message(io_data, MSG_PGAUNW, id, NULL, isjson); return; } +#endif - struct cgpu_info *cgpu = devices[dev]; + message(io_data, MSG_PGAENA, id, NULL, isjson); +} - if (cgpu->deven != DEV_DISABLED) { - strcpy(io_buffer, message(MSG_PGALRENA, id, NULL, isjson)); - return; - } +static void pgadisable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + struct cgpu_info *cgpu, *proc; + int id, dev; + bool already; -#if 0 /* A DISABLED device wont change status FIXME: should disabling make it WELL? */ - if (cgpu->status != LIFE_WELL) { - strcpy(io_buffer, message(MSG_PGAUNW, id, NULL, isjson)); + cgpu = get_pga_cgpu(io_data, c, param, isjson, group, &id, &dev); + if (!cgpu) return; - } -#endif + + applog(LOG_DEBUG, "API: request to pgadisable %s id %d device %d %s", + per_proc ? "proc" : "dev", id, dev, cgpu->proc_repr_ns); - for (i = 0; i < mining_threads; i++) { - pga = thr_info[i].cgpu->device_id; - if (pga == dev) { - thr = &thr_info[i]; - cgpu->deven = DEV_ENABLED; - tq_push(thr->q, &ping); + already = true; + int procs = per_proc ? 1 : cgpu->procs, i; + for (i = 0, proc = cgpu; i < procs; ++i, proc = proc->next_proc) + { + if (proc->deven != DEV_DISABLED) + { + cgpu->deven = DEV_DISABLED; + already = false; } } + + if (already) + { + message(io_data, MSG_PGALRDIS, id, NULL, isjson); + return; + } - strcpy(io_buffer, message(MSG_PGAENA, id, NULL, isjson)); + message(io_data, MSG_PGADIS, id, NULL, isjson); } -static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void pgarestart(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { - int numpga = numpgas(); - int id; - - if (numpga == 0) { - strcpy(io_buffer, message(MSG_PGANON, 0, NULL, isjson)); - return; - } - - if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); - return; - } - - id = atoi(param); - if (id < 0 || id >= numpga) { - strcpy(io_buffer, message(MSG_INVPGA, id, NULL, isjson)); - return; - } - - int dev = pgadevice(id); - if (dev < 0) { // Should never happen - strcpy(io_buffer, message(MSG_INVPGA, id, NULL, isjson)); + struct cgpu_info *cgpu; + int id, dev; + + cgpu = get_pga_cgpu(io_data, c, param, isjson, group, &id, &dev); + if (!cgpu) return; - } + + applog(LOG_DEBUG, "API: request to pgarestart dev id %d device %d %s", + id, dev, cgpu->dev_repr); + + reinit_device(cgpu); + + message(io_data, MSG_PGAREI, id, NULL, isjson); +} - struct cgpu_info *cgpu = devices[dev]; +static void pgaidentify(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + struct cgpu_info *cgpu; + struct device_drv *drv; + int id, dev; - if (cgpu->deven == DEV_DISABLED) { - strcpy(io_buffer, message(MSG_PGALRDIS, id, NULL, isjson)); + cgpu = get_pga_cgpu(io_data, c, param, isjson, group, &id, &dev); + if (!cgpu) return; - } + + drv = cgpu->drv; - cgpu->deven = DEV_DISABLED; - - strcpy(io_buffer, message(MSG_PGADIS, id, NULL, isjson)); + if (drv->identify_device && drv->identify_device(cgpu)) + message(io_data, MSG_PGAIDENT, id, NULL, isjson); + else + message(io_data, MSG_PGANOID, id, NULL, isjson); } #endif -#ifdef WANT_CPUMINE -static void cpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +#ifdef USE_CPUMINING +static void cpudev(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { + bool io_open = false; int id; - if (opt_n_threads == 0) { - strcpy(io_buffer, message(MSG_CPUNON, 0, NULL, isjson)); + if (opt_n_threads <= 0) + { + message(io_data, MSG_CPUNON, 0, NULL, isjson); return; } if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); + message(io_data, MSG_MISID, 0, NULL, isjson); return; } id = atoi(param); if (id < 0 || id >= num_processors) { - strcpy(io_buffer, message(MSG_INVCPU, id, NULL, isjson)); + message(io_data, MSG_INVCPU, id, NULL, isjson); return; } - strcpy(io_buffer, message(MSG_CPUDEV, id, NULL, isjson)); + message(io_data, MSG_CPUDEV, id, NULL, isjson); - if (isjson) { - strcat(io_buffer, COMMA); - strcat(io_buffer, JSON_CPU); - } + if (isjson) + io_open = io_add(io_data, COMSTR JSON_CPU); - cpustatus(id, isjson); + cpustatus(io_data, id, isjson, false); - if (isjson) - strcat(io_buffer, JSON_CLOSE); + if (isjson && io_open) + io_close(io_data); } #endif -static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static void poolstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { struct api_data *root = NULL; char buf[TMPBUFSIZ]; + bool io_open = false; char *status, *lp; int i; if (total_pools == 0) { - strcpy(io_buffer, message(MSG_NOPOOL, 0, NULL, isjson)); + message(io_data, MSG_NOPOOL, 0, NULL, isjson); return; } - strcpy(io_buffer, message(MSG_POOL, 0, NULL, isjson)); + message(io_data, MSG_POOL, 0, NULL, isjson); - if (isjson) { - strcat(io_buffer, COMMA); - strcat(io_buffer, JSON_POOLS); - } + if (isjson) + io_open = io_add(io_data, COMSTR JSON_POOLS); for (i = 0; i < total_pools; i++) { struct pool *pool = pools[i]; + if (pool->removed) + continue; + switch (pool->enabled) { case POOL_DISABLED: status = (char *)DISABLED; @@ -1658,6 +1917,9 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, case POOL_ENABLED: if (pool->idle) status = (char *)DEAD; + else + if (pool->failover_only) + status = "Failover"; else status = (char *)ALIVE; break; @@ -1675,270 +1937,414 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, root = api_add_escape(root, "URL", pool->rpc_url, false); root = api_add_string(root, "Status", status, false); root = api_add_int(root, "Priority", &(pool->prio), false); + root = api_add_int(root, "Quota", &pool->quota, false); + root = api_add_string(root, "Mining Goal", pool->goal->name, false); root = api_add_string(root, "Long Poll", lp, false); root = api_add_uint(root, "Getworks", &(pool->getwork_requested), false); root = api_add_int(root, "Accepted", &(pool->accepted), false); root = api_add_int(root, "Rejected", &(pool->rejected), false); + root = api_add_int(root, "Works", &pool->works, false); root = api_add_uint(root, "Discarded", &(pool->discarded_work), false); root = api_add_uint(root, "Stale", &(pool->stale_shares), false); root = api_add_uint(root, "Get Failures", &(pool->getfail_occasions), false); root = api_add_uint(root, "Remote Failures", &(pool->remotefail_occasions), false); root = api_add_escape(root, "User", pool->rpc_user, false); root = api_add_time(root, "Last Share Time", &(pool->last_share_time), false); - - if (isjson && (i > 0)) - strcat(io_buffer, COMMA); - - root = print_data(root, buf, isjson); - strcat(io_buffer, buf); + root = api_add_diff(root, "Diff1 Shares", &(pool->diff1), false); + if (pool->rpc_proxy) { + root = api_add_escape(root, "Proxy", pool->rpc_proxy, false); + } else { + root = api_add_const(root, "Proxy", BLANK, false); + } + root = api_add_diff(root, "Difficulty Accepted", &(pool->diff_accepted), false); + root = api_add_diff(root, "Difficulty Rejected", &(pool->diff_rejected), false); + root = api_add_diff(root, "Difficulty Stale", &(pool->diff_stale), false); + root = api_add_diff(root, "Last Share Difficulty", &(pool->last_share_diff), false); + root = api_add_bool(root, "Has Stratum", &(pool->has_stratum), false); + root = api_add_bool(root, "Stratum Active", &(pool->stratum_active), false); + if (pool->stratum_active) + root = api_add_escape(root, "Stratum URL", pool->stratum_url, false); + else + root = api_add_const(root, "Stratum URL", BLANK, false); + root = api_add_diff(root, "Best Share", &(pool->best_diff), true); + if (pool->admin_msg) + root = api_add_escape(root, "Message", pool->admin_msg, true); + double rejp = (pool->diff_accepted + pool->diff_rejected + pool->diff_stale) ? + (double)(pool->diff_rejected) / (double)(pool->diff_accepted + pool->diff_rejected + pool->diff_stale) : 0; + root = api_add_percent(root, "Pool Rejected%", &rejp, false); + double stalep = (pool->diff_accepted + pool->diff_rejected + pool->diff_stale) ? + (double)(pool->diff_stale) / (double)(pool->diff_accepted + pool->diff_rejected + pool->diff_stale) : 0; + root = api_add_percent(root, "Pool Stale%", &stalep, false); + + root = print_data(root, buf, isjson, isjson && (i > 0)); + io_add(io_data, buf); } - if (isjson) - strcat(io_buffer, JSON_CLOSE); + if (isjson && io_open) + io_close(io_data); } -static void summary(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static void summary(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { struct api_data *root = NULL; char buf[TMPBUFSIZ]; - double utility, mhs; + bool io_open; + double utility, mhs, work_utility; -#ifdef WANT_CPUMINE - char *algo = (char *)(algo_names[opt_algo]); - if (algo == NULL) - algo = (char *)NULLSTR; -#endif + message(io_data, MSG_SUMM, 0, NULL, isjson); + io_open = io_add(io_data, isjson ? COMSTR JSON_SUMMARY : _SUMMARY COMSTR); + + // stop hashmeter() changing some while copying + mutex_lock(&hash_lock); utility = total_accepted / ( total_secs ? total_secs : 1 ) * 60; mhs = total_mhashes_done / total_secs; + work_utility = total_diff1 / ( total_secs ? total_secs : 1 ) * 60; - sprintf(io_buffer, isjson - ? "%s," JSON_SUMMARY - : "%s" _SUMMARY ",", - message(MSG_SUMM, 0, NULL, isjson)); - - root = api_add_elapsed(root, "Elapsed", &(total_secs), false); -#ifdef WANT_CPUMINE - if (opt_n_threads) - root = api_add_string(root, "Algorithm", algo, false); + root = api_add_elapsed(root, "Elapsed", &(total_secs), true); +#if defined(USE_CPUMINING) && defined(USE_SHA256D) + if (opt_n_threads > 0) + root = api_add_string(root, "Algorithm", (algo_names[opt_algo] ?: NULLSTR), false); #endif root = api_add_mhs(root, "MHS av", &(mhs), false); - root = api_add_uint(root, "Found Blocks", &(found_blocks), false); - root = api_add_int(root, "Getworks", &(total_getworks), false); - root = api_add_int(root, "Accepted", &(total_accepted), false); - root = api_add_int(root, "Rejected", &(total_rejected), false); - root = api_add_int(root, "Hardware Errors", &(hw_errors), false); + char mhsname[27]; + sprintf(mhsname, "MHS %ds", opt_log_interval); + root = api_add_mhs(root, mhsname, &(total_rolling), false); + root = api_add_uint(root, "Found Blocks", &(found_blocks), true); + root = api_add_int(root, "Getworks", &(total_getworks), true); + root = api_add_int(root, "Accepted", &(total_accepted), true); + root = api_add_int(root, "Rejected", &(total_rejected), true); + root = api_add_int(root, "Hardware Errors", &(hw_errors), true); root = api_add_utility(root, "Utility", &(utility), false); - root = api_add_int(root, "Discarded", &(total_discarded), false); - root = api_add_int(root, "Stale", &(total_stale), false); - root = api_add_uint(root, "Get Failures", &(total_go), false); - root = api_add_uint(root, "Local Work", &(local_work), false); - root = api_add_uint(root, "Remote Failures", &(total_ro), false); - root = api_add_uint(root, "Network Blocks", &(new_blocks), false); - root = api_add_mhtotal(root, "Total MH", &(total_mhashes_done), false); - - root = print_data(root, buf, isjson); - if (isjson) - strcat(buf, JSON_CLOSE); - strcat(io_buffer, buf); + root = api_add_int(root, "Discarded", &(total_discarded), true); + root = api_add_int(root, "Stale", &(total_stale), true); + root = api_add_uint(root, "Get Failures", &(total_go), true); + root = api_add_uint(root, "Local Work", &(local_work), true); + root = api_add_uint(root, "Remote Failures", &(total_ro), true); + root = api_add_uint(root, "Network Blocks", &(new_blocks), true); + root = api_add_mhtotal(root, "Total MH", &(total_mhashes_done), true); + root = api_add_diff(root, "Diff1 Work", &total_diff1, true); + root = api_add_utility(root, "Work Utility", &(work_utility), false); + root = api_add_diff(root, "Difficulty Accepted", &(total_diff_accepted), true); + root = api_add_diff(root, "Difficulty Rejected", &(total_diff_rejected), true); + root = api_add_diff(root, "Difficulty Stale", &(total_diff_stale), true); + root = api_add_diff(root, "Best Share", &(best_diff), true); + double hwp = (total_bad_diff1 + total_diff1) ? + (double)(total_bad_diff1) / (double)(total_bad_diff1 + total_diff1) : 0; + root = api_add_percent(root, "Device Hardware%", &hwp, false); + double rejp = total_diff1 ? + (double)(total_diff_rejected) / (double)(total_diff1) : 0; + root = api_add_percent(root, "Device Rejected%", &rejp, false); + double prejp = (total_diff_accepted + total_diff_rejected + total_diff_stale) ? + (double)(total_diff_rejected) / (double)(total_diff_accepted + total_diff_rejected + total_diff_stale) : 0; + root = api_add_percent(root, "Pool Rejected%", &prejp, false); + double stalep = (total_diff_accepted + total_diff_rejected + total_diff_stale) ? + (double)(total_diff_stale) / (double)(total_diff_accepted + total_diff_rejected + total_diff_stale) : 0; + root = api_add_percent(root, "Pool Stale%", &stalep, false); + root = api_add_time(root, "Last getwork", &last_getwork, false); + + mutex_unlock(&hash_lock); + + root = print_data(root, buf, isjson, false); + io_add(io_data, buf); + if (isjson && io_open) + io_close(io_data); } -#ifdef HAVE_OPENCL -static void gpuenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) + +#ifdef USE_OPENCL +static void gpuenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { - struct thr_info *thr; - int gpu; int id; - int i; - if (gpu_threads == 0) { - strcpy(io_buffer, message(MSG_GPUNON, 0, NULL, isjson)); + if (!nDevs) { + message(io_data, MSG_GPUNON, 0, NULL, isjson); return; } if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); + message(io_data, MSG_MISID, 0, NULL, isjson); return; } id = atoi(param); if (id < 0 || id >= nDevs) { - strcpy(io_buffer, message(MSG_INVGPU, id, NULL, isjson)); + message(io_data, MSG_INVGPU, id, NULL, isjson); return; } + applog(LOG_DEBUG, "API: request to gpuenable gpuid %d %s", + id, gpus[id].proc_repr_ns); + if (gpus[id].deven != DEV_DISABLED) { - strcpy(io_buffer, message(MSG_ALRENA, id, NULL, isjson)); + message(io_data, MSG_ALRENA, id, NULL, isjson); return; } - for (i = 0; i < gpu_threads; i++) { - gpu = thr_info[i].cgpu->device_id; - if (gpu == id) { - thr = &thr_info[i]; - if (thr->cgpu->status != LIFE_WELL) { - strcpy(io_buffer, message(MSG_GPUMRE, id, NULL, isjson)); - return; - } - - gpus[id].deven = DEV_ENABLED; - tq_push(thr->q, &ping); - - } + if (gpus[id].status != LIFE_WELL) + { + message(io_data, MSG_GPUMRE, id, NULL, isjson); + return; } + proc_enable(&gpus[id]); - strcpy(io_buffer, message(MSG_GPUREN, id, NULL, isjson)); + message(io_data, MSG_GPUREN, id, NULL, isjson); } -static void gpudisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void gpudisable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { int id; if (nDevs == 0) { - strcpy(io_buffer, message(MSG_GPUNON, 0, NULL, isjson)); + message(io_data, MSG_GPUNON, 0, NULL, isjson); return; } if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); + message(io_data, MSG_MISID, 0, NULL, isjson); return; } id = atoi(param); if (id < 0 || id >= nDevs) { - strcpy(io_buffer, message(MSG_INVGPU, id, NULL, isjson)); + message(io_data, MSG_INVGPU, id, NULL, isjson); return; } + applog(LOG_DEBUG, "API: request to gpudisable gpuid %d %s", + id, gpus[id].proc_repr_ns); + if (gpus[id].deven == DEV_DISABLED) { - strcpy(io_buffer, message(MSG_ALRDIS, id, NULL, isjson)); + message(io_data, MSG_ALRDIS, id, NULL, isjson); return; } gpus[id].deven = DEV_DISABLED; - strcpy(io_buffer, message(MSG_GPUDIS, id, NULL, isjson)); + message(io_data, MSG_GPUDIS, id, NULL, isjson); } -static void gpurestart(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void gpurestart(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { int id; if (nDevs == 0) { - strcpy(io_buffer, message(MSG_GPUNON, 0, NULL, isjson)); + message(io_data, MSG_GPUNON, 0, NULL, isjson); return; } if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); + message(io_data, MSG_MISID, 0, NULL, isjson); return; } id = atoi(param); if (id < 0 || id >= nDevs) { - strcpy(io_buffer, message(MSG_INVGPU, id, NULL, isjson)); + message(io_data, MSG_INVGPU, id, NULL, isjson); return; } reinit_device(&gpus[id]); - strcpy(io_buffer, message(MSG_GPUREI, id, NULL, isjson)); + message(io_data, MSG_GPUREI, id, NULL, isjson); } #endif -static void gpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) + +static void gpucount(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { struct api_data *root = NULL; char buf[TMPBUFSIZ]; + bool io_open; int numgpu = 0; -#ifdef HAVE_OPENCL +#ifdef USE_OPENCL numgpu = nDevs; #endif - sprintf(io_buffer, isjson - ? "%s," JSON_GPUS - : "%s" _GPUS ",", - message(MSG_NUMGPU, 0, NULL, isjson)); + message(io_data, MSG_NUMGPU, 0, NULL, isjson); + io_open = io_add(io_data, isjson ? COMSTR JSON_GPUS : _GPUS COMSTR); root = api_add_int(root, "Count", &numgpu, false); - root = print_data(root, buf, isjson); - if (isjson) - strcat(buf, JSON_CLOSE); - strcat(io_buffer, buf); + root = print_data(root, buf, isjson, false); + io_add(io_data, buf); + if (isjson && io_open) + io_close(io_data); } -static void pgacount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static void pgacount(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { struct api_data *root = NULL; char buf[TMPBUFSIZ]; + bool io_open; int count = 0; #ifdef HAVE_AN_FPGA count = numpgas(); #endif - sprintf(io_buffer, isjson - ? "%s," JSON_PGAS - : "%s" _PGAS ",", - message(MSG_NUMPGA, 0, NULL, isjson)); + message(io_data, MSG_NUMPGA, 0, NULL, isjson); + io_open = io_add(io_data, isjson ? COMSTR JSON_PGAS : _PGAS COMSTR); root = api_add_int(root, "Count", &count, false); - root = print_data(root, buf, isjson); - if (isjson) - strcat(buf, JSON_CLOSE); - strcat(io_buffer, buf); + root = print_data(root, buf, isjson, false); + io_add(io_data, buf); + if (isjson && io_open) + io_close(io_data); +} + +#ifdef USE_CPUMINING +static void cpuenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + int id; + + if (opt_n_threads <= 0) + { + message(io_data, MSG_CPUNON, 0, NULL, isjson); + return; + } + + if (param == NULL || *param == '\0') { + message(io_data, MSG_MISID, 0, NULL, isjson); + return; + } + + id = atoi(param); + if (id < 0 || id >= opt_n_threads) { + message(io_data, MSG_INVCPU, id, NULL, isjson); + return; + } + + applog(LOG_DEBUG, "API: request to cpuenable cpuid %d %s", + id, cpus[id].proc_repr_ns); + + if (cpus[id].deven != DEV_DISABLED) { + message(io_data, MSG_ALRENAC, id, NULL, isjson); + return; + } + + if (cpus[id].status != LIFE_WELL) + { + message(io_data, MSG_CPUMRE, id, NULL, isjson); + return; + } + proc_enable(&cpus[id]); + + message(io_data, MSG_CPUREN, id, NULL, isjson); +} + +static void cpudisable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + int id; + + if (opt_n_threads <= 0) + { + message(io_data, MSG_CPUNON, 0, NULL, isjson); + return; + } + + if (param == NULL || *param == '\0') { + message(io_data, MSG_MISID, 0, NULL, isjson); + return; + } + + id = atoi(param); + if (id < 0 || id >= opt_n_threads) { + message(io_data, MSG_INVCPU, id, NULL, isjson); + return; + } + + applog(LOG_DEBUG, "API: request to cpudisable cpuid %d %s", + id, cpus[id].proc_repr_ns); + + if (cpus[id].deven == DEV_DISABLED) { + message(io_data, MSG_ALRDISC, id, NULL, isjson); + return; + } + + cpus[id].deven = DEV_DISABLED; + + message(io_data, MSG_CPUDIS, id, NULL, isjson); +} + +static void cpurestart(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + int id; + + if (opt_n_threads <= 0) + { + message(io_data, MSG_CPUNON, 0, NULL, isjson); + return; + } + + if (param == NULL || *param == '\0') { + message(io_data, MSG_MISID, 0, NULL, isjson); + return; + } + + id = atoi(param); + if (id < 0 || id >= opt_n_threads) { + message(io_data, MSG_INVCPU, id, NULL, isjson); + return; + } + + reinit_device(&cpus[id]); + + message(io_data, MSG_CPUREI, id, NULL, isjson); } +#endif -static void cpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static void cpucount(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { struct api_data *root = NULL; char buf[TMPBUFSIZ]; + bool io_open; int count = 0; -#ifdef WANT_CPUMINE +#ifdef USE_CPUMINING count = opt_n_threads > 0 ? num_processors : 0; #endif - sprintf(io_buffer, isjson - ? "%s," JSON_CPUS - : "%s" _CPUS ",", - message(MSG_NUMCPU, 0, NULL, isjson)); + message(io_data, MSG_NUMCPU, 0, NULL, isjson); + io_open = io_add(io_data, isjson ? COMSTR JSON_CPUS : _CPUS COMSTR); root = api_add_int(root, "Count", &count, false); - root = print_data(root, buf, isjson); - if (isjson) - strcat(buf, JSON_CLOSE); - strcat(io_buffer, buf); + root = print_data(root, buf, isjson, false); + io_add(io_data, buf); + if (isjson && io_open) + io_close(io_data); } -static void switchpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void switchpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { struct pool *pool; int id; if (total_pools == 0) { - strcpy(io_buffer, message(MSG_NOPOOL, 0, NULL, isjson)); + message(io_data, MSG_NOPOOL, 0, NULL, isjson); return; } if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISPID, 0, NULL, isjson)); + message(io_data, MSG_MISPID, 0, NULL, isjson); return; } id = atoi(param); + cg_rlock(&control_lock); if (id < 0 || id >= total_pools) { - strcpy(io_buffer, message(MSG_INVPID, id, NULL, isjson)); + cg_runlock(&control_lock); + message(io_data, MSG_INVPID, id, NULL, isjson); return; } pool = pools[id]; - pool->enabled = POOL_ENABLED; + manual_enable_pool(pool); + cg_runlock(&control_lock); switch_pools(pool); - strcpy(io_buffer, message(MSG_SWITCHP, id, NULL, isjson)); + message(io_data, MSG_SWITCHP, id, NULL, isjson); } static void copyadvanceafter(char ch, char **param, char **buf) @@ -1958,7 +2364,7 @@ static void copyadvanceafter(char ch, char **param, char **buf) *(dst_b++) = '\0'; } -static bool pooldetails(char *param, char **url, char **user, char **pass) +static bool pooldetails(char *param, char **url, char **user, char **pass, char **goalname) { char *ptr, *buf; @@ -1986,6 +2392,12 @@ static bool pooldetails(char *param, char **url, char **user, char **pass) // copy pass copyadvanceafter(',', ¶m, &buf); + + if (*param) + *goalname = buf; + + // copy goalname + copyadvanceafter(',', ¶m, &buf); return true; @@ -1994,153 +2406,175 @@ static bool pooldetails(char *param, char **url, char **user, char **pass) return false; } -static void addpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void addpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { - char *url, *user, *pass; + char *url, *user, *pass, *goalname = "default"; + struct pool *pool; char *ptr; if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISPDP, 0, NULL, isjson)); + message(io_data, MSG_MISPDP, 0, NULL, isjson); return; } - if (!pooldetails(param, &url, &user, &pass)) { + if (!pooldetails(param, &url, &user, &pass, &goalname)) + { ptr = escape_string(param, isjson); - strcpy(io_buffer, message(MSG_INVPDP, 0, ptr, isjson)); + message(io_data, MSG_INVPDP, 0, ptr, isjson); if (ptr != param) free(ptr); ptr = NULL; return; } - add_pool_details(true, url, user, pass); + struct mining_goal_info * const goal = get_mining_goal(goalname); + pool = add_pool2(goal); + detect_stratum(pool, url); + add_pool_details(pool, true, url, user, pass); ptr = escape_string(url, isjson); - strcpy(io_buffer, message(MSG_ADDPOOL, 0, ptr, isjson)); + message(io_data, MSG_ADDPOOL, 0, ptr, isjson); if (ptr != url) free(ptr); ptr = NULL; } -static void enablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void enablepool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { struct pool *pool; int id; if (total_pools == 0) { - strcpy(io_buffer, message(MSG_NOPOOL, 0, NULL, isjson)); + message(io_data, MSG_NOPOOL, 0, NULL, isjson); return; } if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISPID, 0, NULL, isjson)); + message(io_data, MSG_MISPID, 0, NULL, isjson); return; } id = atoi(param); if (id < 0 || id >= total_pools) { - strcpy(io_buffer, message(MSG_INVPID, id, NULL, isjson)); + message(io_data, MSG_INVPID, id, NULL, isjson); return; } pool = pools[id]; - if (pool->enabled == POOL_ENABLED) { - strcpy(io_buffer, message(MSG_ALRENAP, id, NULL, isjson)); + if (pool->enabled == POOL_ENABLED && !pool->failover_only) { + message(io_data, MSG_ALRENAP, id, NULL, isjson); return; } - pool->enabled = POOL_ENABLED; - if (pool->prio < current_pool()->prio) - switch_pools(pool); + manual_enable_pool(pool); + + message(io_data, MSG_ENAPOOL, id, NULL, isjson); +} + +static void poolpriority(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + int i; - strcpy(io_buffer, message(MSG_ENAPOOL, id, NULL, isjson)); + switch (prioritize_pools(param, &i)) { + case MSG_NOPOOL: + message(io_data, MSG_NOPOOL, 0, NULL, isjson); + return; + case MSG_MISPID: + message(io_data, MSG_MISPID, 0, NULL, isjson); + return; + case MSG_INVPID: + message(io_data, MSG_INVPID, i, NULL, isjson); + return; + case MSG_DUPPID: + message(io_data, MSG_DUPPID, i, NULL, isjson); + return; + case MSG_POOLPRIO: + default: + message(io_data, MSG_POOLPRIO, 0, NULL, isjson); + return; + } } -static void poolpriority(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void poolquota(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { - SETUP_STRTOK_TS; - int total_pools_ = total_pools; // Keep a local copy, to be more threadsafe - char *a; - int i, prio = 0, e = -1; + struct pool *pool; + int quota, id; + char *comma; - if (total_pools_ == 0) { - strcpy(io_buffer, message(MSG_NOPOOL, 0, NULL, isjson)); + if (total_pools == 0) { + message(io_data, MSG_NOPOOL, 0, NULL, isjson); return; } - bool pools_changed[total_pools_]; - for (i = 0; i < total_pools_; ++i) - pools_changed[i] = false; + if (param == NULL || *param == '\0') { + message(io_data, MSG_MISPID, 0, NULL, isjson); + return; + } - a = strtok_ts(param, ","); - do { - i = strtol(a, &a, 10); - if (unlikely(*a > 0x20 || i < 0 || i >= total_pools)) { - e = (*a > 0x20) ? -2 : i; - continue; - } - pools[i]->prio = prio++; - pools_changed[i] = true; - } while ( (a = strtok_ts(NULL, ",")) ); + comma = strchr(param, ','); + if (!comma) { + message(io_data, MSG_CONVAL, 0, param, isjson); + return; + } - for (i = 0; i < total_pools_; ++i) - if (!pools_changed[i]) - pools[i]->prio = prio++; + *(comma++) = '\0'; - if (current_pool()->prio) - switch_pools(NULL); + id = atoi(param); + if (id < 0 || id >= total_pools) { + message(io_data, MSG_INVPID, id, NULL, isjson); + return; + } + pool = pools[id]; - if (e != -1) { - if (e == -2) - strcpy(io_buffer, message(MSG_MISPID, 0, NULL, isjson)); - else - strcpy(io_buffer, message(MSG_INVPID, e, NULL, isjson)); + quota = atoi(comma); + if (quota < 0) { + message(io_data, MSG_INVNEG, quota, pool->rpc_url, isjson); return; } - strcpy(io_buffer, message(MSG_POOLPRIO, 0, NULL, isjson)); + pool->quota = quota; + adjust_quota_gcd(); + message(io_data, MSG_SETQUOTA, quota, pool->rpc_url, isjson); } -static void disablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void disablepool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { struct pool *pool; int id; if (total_pools == 0) { - strcpy(io_buffer, message(MSG_NOPOOL, 0, NULL, isjson)); + message(io_data, MSG_NOPOOL, 0, NULL, isjson); return; } if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISPID, 0, NULL, isjson)); + message(io_data, MSG_MISPID, 0, NULL, isjson); return; } id = atoi(param); if (id < 0 || id >= total_pools) { - strcpy(io_buffer, message(MSG_INVPID, id, NULL, isjson)); + message(io_data, MSG_INVPID, id, NULL, isjson); return; } pool = pools[id]; if (pool->enabled == POOL_DISABLED) { - strcpy(io_buffer, message(MSG_ALRDISP, id, NULL, isjson)); + message(io_data, MSG_ALRDISP, id, NULL, isjson); return; } if (enabled_pools <= 1) { - strcpy(io_buffer, message(MSG_DISLASTP, id, NULL, isjson)); + message(io_data, MSG_DISLASTP, id, NULL, isjson); return; } - pool->enabled = POOL_DISABLED; - if (pool == current_pool()) - switch_pools(NULL); + disable_pool(pool, POOL_DISABLED); - strcpy(io_buffer, message(MSG_DISPOOL, id, NULL, isjson)); + message(io_data, MSG_DISPOOL, id, NULL, isjson); } -static void removepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +static void removepool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { struct pool *pool; char *rpc_url; @@ -2148,23 +2582,23 @@ static void removepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __ int id; if (total_pools == 0) { - strcpy(io_buffer, message(MSG_NOPOOL, 0, NULL, isjson)); + message(io_data, MSG_NOPOOL, 0, NULL, isjson); return; } if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISPID, 0, NULL, isjson)); + message(io_data, MSG_MISPID, 0, NULL, isjson); return; } id = atoi(param); if (id < 0 || id >= total_pools) { - strcpy(io_buffer, message(MSG_INVPID, id, NULL, isjson)); + message(io_data, MSG_INVPID, id, NULL, isjson); return; } if (total_pools <= 1) { - strcpy(io_buffer, message(MSG_REMLASTP, id, NULL, isjson)); + message(io_data, MSG_REMLASTP, id, NULL, isjson); return; } @@ -2173,43 +2607,42 @@ static void removepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __ switch_pools(NULL); if (pool == current_pool()) { - strcpy(io_buffer, message(MSG_ACTPOOL, id, NULL, isjson)); + message(io_data, MSG_ACTPOOL, id, NULL, isjson); return; } - pool->enabled = POOL_DISABLED; rpc_url = escape_string(pool->rpc_url, isjson); if (rpc_url != pool->rpc_url) dofree = true; remove_pool(pool); - strcpy(io_buffer, message(MSG_REMPOOL, id, rpc_url, isjson)); + message(io_data, MSG_REMPOOL, id, rpc_url, isjson); if (dofree) free(rpc_url); rpc_url = NULL; } -#ifdef HAVE_OPENCL -static bool splitgpuvalue(char *param, int *gpu, char **value, bool isjson) +#ifdef USE_OPENCL +static bool splitgpuvalue(struct io_data *io_data, char *param, int *gpu, char **value, bool isjson) { int id; char *gpusep; if (nDevs == 0) { - strcpy(io_buffer, message(MSG_GPUNON, 0, NULL, isjson)); + message(io_data, MSG_GPUNON, 0, NULL, isjson); return false; } if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); + message(io_data, MSG_MISID, 0, NULL, isjson); return false; } gpusep = strchr(param, GPUSEP); if (gpusep == NULL) { - strcpy(io_buffer, message(MSG_MISVAL, 0, NULL, isjson)); + message(io_data, MSG_MISVAL, 0, NULL, isjson); return false; } @@ -2217,7 +2650,7 @@ static bool splitgpuvalue(char *param, int *gpu, char **value, bool isjson) id = atoi(param); if (id < 0 || id >= nDevs) { - strcpy(io_buffer, message(MSG_INVGPU, id, NULL, isjson)); + message(io_data, MSG_INVGPU, id, NULL, isjson); return false; } @@ -2226,156 +2659,196 @@ static bool splitgpuvalue(char *param, int *gpu, char **value, bool isjson) return true; } -static void gpuintensity(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) + +static void gpuintensity(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { int id; char *value; - int intensity; char intensitystr[7]; + char buf[TMPBUFSIZ]; - if (!splitgpuvalue(param, &id, &value, isjson)) + if (!splitgpuvalue(io_data, param, &id, &value, isjson)) return; - if (!strncasecmp(value, DYNAMIC, 1)) { - gpus[id].dynamic = true; - strcpy(intensitystr, DYNAMIC); - } - else { - intensity = atoi(value); - if (intensity < MIN_INTENSITY || intensity > MAX_INTENSITY) { - strcpy(io_buffer, message(MSG_INVINT, 0, value, isjson)); - return; + struct cgpu_info * const cgpu = &gpus[id]; + struct opencl_device_data * const data = gpus[id].device_data; + + enum bfg_set_device_replytype success; + proc_set_device(cgpu, "intensity", value, buf, &success); + if (success == SDR_OK) + { + if (data->dynamic) + strcpy(intensitystr, DYNAMIC); + else + { + const char *iunit; + float intensity = opencl_proc_get_intensity(cgpu, &iunit); + snprintf(intensitystr, sizeof(intensitystr), "%s%g", iunit, intensity); } - - gpus[id].dynamic = false; - gpus[id].intensity = intensity; - sprintf(intensitystr, "%d", intensity); + } + else + { + message(io_data, MSG_INVINT, 0, value, isjson); + return; } - strcpy(io_buffer, message(MSG_GPUINT, id, intensitystr, isjson)); + message(io_data, MSG_GPUINT, id, intensitystr, isjson); } -static void gpumem(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static void gpumem(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { #ifdef HAVE_ADL int id; char *value; - int clock; + char buf[TMPBUFSIZ]; - if (!splitgpuvalue(param, &id, &value, isjson)) + if (!splitgpuvalue(io_data, param, &id, &value, isjson)) return; - clock = atoi(value); - - if (set_memoryclock(id, clock)) - strcpy(io_buffer, message(MSG_GPUMERR, id, value, isjson)); + struct cgpu_info * const cgpu = &gpus[id]; + + enum bfg_set_device_replytype success; + proc_set_device(cgpu, "memclock", value, buf, &success); + if (success != SDR_OK) + message(io_data, MSG_GPUMERR, id, value, isjson); else - strcpy(io_buffer, message(MSG_GPUMEM, id, value, isjson)); + message(io_data, MSG_GPUMEM, id, value, isjson); #else - strcpy(io_buffer, message(MSG_NOADL, 0, NULL, isjson)); + message(io_data, MSG_NOADL, 0, NULL, isjson); #endif } -static void gpuengine(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static void gpuengine(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { #ifdef HAVE_ADL int id; char *value; - int clock; + char buf[TMPBUFSIZ]; - if (!splitgpuvalue(param, &id, &value, isjson)) + if (!splitgpuvalue(io_data, param, &id, &value, isjson)) return; - clock = atoi(value); - - if (set_engineclock(id, clock)) - strcpy(io_buffer, message(MSG_GPUEERR, id, value, isjson)); + struct cgpu_info * const cgpu = &gpus[id]; + + enum bfg_set_device_replytype success; + proc_set_device(cgpu, "clock", value, buf, &success); + if (success != SDR_OK) + message(io_data, MSG_GPUEERR, id, value, isjson); else - strcpy(io_buffer, message(MSG_GPUENG, id, value, isjson)); + message(io_data, MSG_GPUENG, id, value, isjson); #else - strcpy(io_buffer, message(MSG_NOADL, 0, NULL, isjson)); + message(io_data, MSG_NOADL, 0, NULL, isjson); #endif } -static void gpufan(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static void gpufan(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { #ifdef HAVE_ADL int id; char *value; - int fan; + char buf[TMPBUFSIZ]; - if (!splitgpuvalue(param, &id, &value, isjson)) + if (!splitgpuvalue(io_data, param, &id, &value, isjson)) return; - fan = atoi(value); - - if (set_fanspeed(id, fan)) - strcpy(io_buffer, message(MSG_GPUFERR, id, value, isjson)); + struct cgpu_info * const cgpu = &gpus[id]; + + enum bfg_set_device_replytype success; + proc_set_device(cgpu, "fan", value, buf, &success); + if (success != SDR_OK) + message(io_data, MSG_GPUFERR, id, value, isjson); else - strcpy(io_buffer, message(MSG_GPUFAN, id, value, isjson)); + message(io_data, MSG_GPUFAN, id, value, isjson); #else - strcpy(io_buffer, message(MSG_NOADL, 0, NULL, isjson)); + message(io_data, MSG_NOADL, 0, NULL, isjson); #endif } -static void gpuvddc(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static void gpuvddc(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { #ifdef HAVE_ADL int id; char *value; - float vddc; + char buf[TMPBUFSIZ]; - if (!splitgpuvalue(param, &id, &value, isjson)) + if (!splitgpuvalue(io_data, param, &id, &value, isjson)) return; - vddc = atof(value); - - if (set_vddc(id, vddc)) - strcpy(io_buffer, message(MSG_GPUVERR, id, value, isjson)); + struct cgpu_info * const cgpu = &gpus[id]; + + enum bfg_set_device_replytype success; + proc_set_device(cgpu, "voltage", value, buf, &success); + if (success != SDR_OK) + message(io_data, MSG_GPUVERR, id, value, isjson); else - strcpy(io_buffer, message(MSG_GPUVDDC, id, value, isjson)); + message(io_data, MSG_GPUVDDC, id, value, isjson); #else - strcpy(io_buffer, message(MSG_NOADL, 0, NULL, isjson)); + message(io_data, MSG_NOADL, 0, NULL, isjson); #endif } #endif -void doquit(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) + +void doquit(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { - if (isjson) - strcpy(io_buffer, JSON_START JSON_BYE); - else - strcpy(io_buffer, _BYE); + message(io_data, MSG_BYE, 0, _BYE, isjson); bye = true; do_a_quit = true; } -void dorestart(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +void dorestart(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { - if (isjson) - strcpy(io_buffer, JSON_START JSON_RESTART); - else - strcpy(io_buffer, _RESTART); + message(io_data, MSG_BYE, 0, _RESTART, isjson); bye = true; do_a_restart = true; } -void privileged(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +void privileged(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { - strcpy(io_buffer, message(MSG_ACCOK, 0, NULL, isjson)); + message(io_data, MSG_ACCOK, 0, NULL, isjson); } -void notifystatus(int device, struct cgpu_info *cgpu, bool isjson, __maybe_unused char group) +void notifystatus(struct io_data *io_data, int device, struct cgpu_info *cgpu, bool isjson, __maybe_unused char group) { + struct cgpu_info *proc; struct api_data *root = NULL; char buf[TMPBUFSIZ]; char *reason; - - if (cgpu->device_last_not_well == 0) + + time_t last_not_well = 0; + enum dev_reason uninitialised_var(enum_reason); + int thread_fail_init_count = 0, thread_zero_hash_count = 0, thread_fail_queue_count = 0; + int dev_sick_idle_60_count = 0, dev_dead_idle_600_count = 0; + int dev_nostart_count = 0, dev_over_heat_count = 0, dev_thermal_cutoff_count = 0, dev_comms_error_count = 0, dev_throttle_count = 0; + + int procs = per_proc ? 1 : cgpu->procs, i; + for (i = 0, proc = cgpu; i < procs; ++i, proc = proc->next_proc) + { + if (proc->device_last_not_well > last_not_well) + { + last_not_well = proc->device_last_not_well; + enum_reason = proc->device_not_well_reason; + thread_fail_init_count += proc->thread_fail_init_count; + thread_zero_hash_count += proc->thread_zero_hash_count; + thread_fail_queue_count += proc->thread_fail_queue_count; + dev_sick_idle_60_count += proc->dev_sick_idle_60_count; + dev_dead_idle_600_count += proc->dev_dead_idle_600_count; + dev_nostart_count += proc->dev_nostart_count; + dev_over_heat_count += proc->dev_over_heat_count; + dev_thermal_cutoff_count += proc->dev_thermal_cutoff_count; + dev_comms_error_count += proc->dev_comms_error_count; + dev_throttle_count += proc->dev_throttle_count; + } + if (per_proc) + break; + } + + if (last_not_well == 0) reason = REASON_NONE; else - switch(cgpu->device_not_well_reason) { + switch (enum_reason) + { case REASON_THREAD_FAIL_INIT: reason = REASON_THREAD_FAIL_INIT_STR; break; @@ -2411,93 +2884,54 @@ void notifystatus(int device, struct cgpu_info *cgpu, bool isjson, __maybe_unuse // ALL counters (and only counters) must start the name with a '*' // Simplifies future external support for identifying new counters root = api_add_int(root, "NOTIFY", &device, false); - root = api_add_string(root, "Name", cgpu->api->name, false); - root = api_add_int(root, "ID", &(cgpu->device_id), false); - root = api_add_time(root, "Last Well", &(cgpu->device_last_well), false); - root = api_add_time(root, "Last Not Well", &(cgpu->device_last_not_well), false); + root = api_add_device_identifier(root, cgpu); + if (per_proc) + root = api_add_time(root, "Last Well", &(cgpu->device_last_well), false); + root = api_add_time(root, "Last Not Well", &last_not_well, false); root = api_add_string(root, "Reason Not Well", reason, false); - root = api_add_int(root, "*Thread Fail Init", &(cgpu->thread_fail_init_count), false); - root = api_add_int(root, "*Thread Zero Hash", &(cgpu->thread_zero_hash_count), false); - root = api_add_int(root, "*Thread Fail Queue", &(cgpu->thread_fail_queue_count), false); - root = api_add_int(root, "*Dev Sick Idle 60s", &(cgpu->dev_sick_idle_60_count), false); - root = api_add_int(root, "*Dev Dead Idle 600s", &(cgpu->dev_dead_idle_600_count), false); - root = api_add_int(root, "*Dev Nostart", &(cgpu->dev_nostart_count), false); - root = api_add_int(root, "*Dev Over Heat", &(cgpu->dev_over_heat_count), false); - root = api_add_int(root, "*Dev Thermal Cutoff", &(cgpu->dev_thermal_cutoff_count), false); - root = api_add_int(root, "*Dev Comms Error", &(cgpu->dev_comms_error_count), false); - - if (isjson && (device > 0)) - strcat(io_buffer, COMMA); - - root = print_data(root, buf, isjson); - strcat(io_buffer, buf); -} - -static void notify(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, char group) -{ - int i; - - if (total_devices == 0) { - strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson)); - return; - } - - strcpy(io_buffer, message(MSG_NOTIFY, 0, NULL, isjson)); - - if (isjson) { - strcat(io_buffer, COMMA); - strcat(io_buffer, JSON_NOTIFY); - } - - for (i = 0; i < total_devices; i++) - notifystatus(i, devices[i], isjson, group); - - if (isjson) - strcat(io_buffer, JSON_CLOSE); + root = api_add_int(root, "*Thread Fail Init", &thread_fail_init_count, false); + root = api_add_int(root, "*Thread Zero Hash", &thread_zero_hash_count, false); + root = api_add_int(root, "*Thread Fail Queue", &thread_fail_queue_count, false); + root = api_add_int(root, "*Dev Sick Idle 60s", &dev_sick_idle_60_count, false); + root = api_add_int(root, "*Dev Dead Idle 600s", &dev_dead_idle_600_count, false); + root = api_add_int(root, "*Dev Nostart", &dev_nostart_count, false); + root = api_add_int(root, "*Dev Over Heat", &dev_over_heat_count, false); + root = api_add_int(root, "*Dev Thermal Cutoff", &dev_thermal_cutoff_count, false); + root = api_add_int(root, "*Dev Comms Error", &dev_comms_error_count, false); + root = api_add_int(root, "*Dev Throttle", &dev_throttle_count, false); + + root = print_data(root, buf, isjson, isjson && (device > 0)); + io_add(io_data, buf); } -static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static +void notify(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, char group) { - struct api_data *root = NULL; - char buf[TMPBUFSIZ]; struct cgpu_info *cgpu; - int i; + bool io_open = false; + int i, n = 0; if (total_devices == 0) { - strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson)); + message(io_data, MSG_NODEVS, 0, NULL, isjson); return; } - strcpy(io_buffer, message(MSG_DEVDETAILS, 0, NULL, isjson)); + message(io_data, MSG_NOTIFY, 0, NULL, isjson); - if (isjson) { - strcat(io_buffer, COMMA); - strcat(io_buffer, JSON_DEVDETAILS); - } + if (isjson) + io_open = io_add(io_data, COMSTR JSON_NOTIFY); for (i = 0; i < total_devices; i++) { - cgpu = devices[i]; - - root = api_add_int(root, "DEVDETAILS", &i, false); - root = api_add_string(root, "Name", cgpu->api->name, false); - root = api_add_int(root, "ID", &(cgpu->device_id), false); - root = api_add_string(root, "Driver", cgpu->api->dname, false); - root = api_add_const(root, "Kernel", cgpu->kname ? : BLANK, false); - root = api_add_const(root, "Model", cgpu->name ? : BLANK, false); - root = api_add_const(root, "Device Path", cgpu->device_path ? : BLANK, false); - - if (isjson && (i > 0)) - strcat(io_buffer, COMMA); - - root = print_data(root, buf, isjson); - strcat(io_buffer, buf); + cgpu = get_devices(i); + if (cgpu->device == cgpu || per_proc) + notifystatus(io_data, n++, cgpu, isjson, group); } - if (isjson) - strcat(io_buffer, JSON_CLOSE); + if (isjson && io_open) + io_close(io_data); } -void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +void dosave(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { char filename[PATH_MAX]; FILE *fcfg; @@ -2511,7 +2945,7 @@ void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unuse fcfg = fopen(param, "w"); if (!fcfg) { ptr = escape_string(param, isjson); - strcpy(io_buffer, message(MSG_BADFN, 0, ptr, isjson)); + message(io_data, MSG_BADFN, 0, ptr, isjson); if (ptr != param) free(ptr); ptr = NULL; @@ -2522,20 +2956,22 @@ void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unuse fclose(fcfg); ptr = escape_string(param, isjson); - strcpy(io_buffer, message(MSG_SAVED, 0, ptr, isjson)); + message(io_data, MSG_SAVED, 0, ptr, isjson); if (ptr != param) free(ptr); ptr = NULL; } -static int itemstats(int i, char *id, struct cgminer_stats *stats, struct cgminer_pool_stats *pool_stats, struct api_data *extra, bool isjson) +static int itemstats(struct io_data *io_data, int i, char *id, struct cgminer_stats *stats, struct cgminer_pool_stats *pool_stats, struct api_data *extra, bool isjson) { struct api_data *root = NULL; char buf[TMPBUFSIZ]; + double elapsed; root = api_add_int(root, "STATS", &i, false); root = api_add_string(root, "ID", id, false); - root = api_add_elapsed(root, "Elapsed", &(total_secs), false); + elapsed = stats_elapsed(stats); + root = api_add_elapsed(root, "Elapsed", &elapsed, false); root = api_add_uint32(root, "Calls", &(stats->getwork_calls), false); root = api_add_timeval(root, "Wait", &(stats->getwork_wait), false); root = api_add_timeval(root, "Max", &(stats->getwork_wait_max), false); @@ -2548,45 +2984,56 @@ static int itemstats(int i, char *id, struct cgminer_stats *stats, struct cgmine root = api_add_timeval(root, "Pool Max", &(pool_stats->getwork_wait_max), false); root = api_add_timeval(root, "Pool Min", &(pool_stats->getwork_wait_min), false); root = api_add_double(root, "Pool Av", &(pool_stats->getwork_wait_rolling), false); + root = api_add_bool(root, "Work Had Roll Time", &(pool_stats->hadrolltime), false); + root = api_add_bool(root, "Work Can Roll", &(pool_stats->canroll), false); + root = api_add_bool(root, "Work Had Expire", &(pool_stats->hadexpire), false); + root = api_add_uint32(root, "Work Roll Time", &(pool_stats->rolltime), false); + root = api_add_diff(root, "Work Diff", &(pool_stats->last_diff), false); + root = api_add_diff(root, "Min Diff", &(pool_stats->min_diff), false); + root = api_add_diff(root, "Max Diff", &(pool_stats->max_diff), false); + root = api_add_uint32(root, "Min Diff Count", &(pool_stats->min_diff_count), false); + root = api_add_uint32(root, "Max Diff Count", &(pool_stats->max_diff_count), false); + root = api_add_uint64(root, "Times Sent", &(pool_stats->times_sent), false); + root = api_add_uint64(root, "Bytes Sent", &(pool_stats->bytes_sent), false); + root = api_add_uint64(root, "Times Recv", &(pool_stats->times_received), false); + root = api_add_uint64(root, "Bytes Recv", &(pool_stats->bytes_received), false); + root = api_add_uint64(root, "Net Bytes Sent", &(pool_stats->net_bytes_sent), false); + root = api_add_uint64(root, "Net Bytes Recv", &(pool_stats->net_bytes_received), false); } if (extra) root = api_add_extra(root, extra); - if (isjson && (i > 0)) - strcat(io_buffer, COMMA); - - root = print_data(root, buf, isjson); - strcat(io_buffer, buf); + root = print_data(root, buf, isjson, isjson && (i > 0)); + io_add(io_data, buf); return ++i; } -static void minerstats(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +static void minerstats(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { + struct cgpu_info *cgpu; + bool io_open = false; struct api_data *extra; char id[20]; int i, j; - strcpy(io_buffer, message(MSG_MINESTATS, 0, NULL, isjson)); + message(io_data, MSG_MINESTATS, 0, NULL, isjson); - if (isjson) { - strcat(io_buffer, COMMA); - strcat(io_buffer, JSON_MINESTATS); - } + if (isjson) + io_open = io_add(io_data, COMSTR JSON_MINESTATS); i = 0; for (j = 0; j < total_devices; j++) { - struct cgpu_info *cgpu = devices[j]; + cgpu = get_devices(j); - if (cgpu && cgpu->api) { - if (cgpu->api->get_api_stats) - extra = cgpu->api->get_api_stats(cgpu); + if (cgpu && cgpu->drv) { + if (cgpu->drv->get_api_stats) + extra = cgpu->drv->get_api_stats(cgpu); else extra = NULL; - sprintf(id, "%s%d", cgpu->api->name, cgpu->device_id); - i = itemstats(i, id, &(cgpu->cgminer_stats), NULL, extra, isjson); + i = itemstats(io_data, i, cgpu->proc_repr_ns, &(cgpu->cgminer_stats), NULL, extra, isjson); } } @@ -2594,157 +3041,590 @@ static void minerstats(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, struct pool *pool = pools[j]; sprintf(id, "POOL%d", j); - i = itemstats(i, id, &(pool->cgminer_stats), &(pool->cgminer_pool_stats), NULL, isjson); + i = itemstats(io_data, i, id, &(pool->cgminer_stats), &(pool->cgminer_pool_stats), NULL, isjson); } - if (isjson) - strcat(io_buffer, JSON_CLOSE); + if (isjson && io_open) + io_close(io_data); } -static void checkcommand(__maybe_unused SOCKETTYPE c, char *param, bool isjson, char group); - -struct CMDS { - char *name; - void (*func)(SOCKETTYPE, char *, bool, char); - bool iswritemode; -} cmds[] = { - { "version", apiversion, false }, - { "config", minerconfig, false }, - { "devs", devstatus, false }, - { "devdetail", devdetail, false }, - { "pools", poolstatus, false }, - { "summary", summary, false }, -#ifdef HAVE_OPENCL - { "gpuenable", gpuenable, true }, - { "gpudisable", gpudisable, true }, - { "gpurestart", gpurestart, true }, - { "gpu", gpudev, false }, -#endif -#ifdef HAVE_AN_FPGA - { "pga", pgadev, false }, - { "pgaenable", pgaenable, true }, - { "pgadisable", pgadisable, true }, -#endif -#ifdef WANT_CPUMINE - { "cpu", cpudev, false }, -#endif - { "gpucount", gpucount, false }, - { "pgacount", pgacount, false }, - { "cpucount", cpucount, false }, - { "switchpool", switchpool, true }, - { "addpool", addpool, true }, - { "poolpriority", poolpriority, true }, - { "enablepool", enablepool, true }, - { "disablepool", disablepool, true }, - { "removepool", removepool, true }, -#ifdef HAVE_OPENCL - { "gpuintensity", gpuintensity, true }, - { "gpumem", gpumem, true }, - { "gpuengine", gpuengine, true }, - { "gpufan", gpufan, true }, - { "gpuvddc", gpuvddc, true }, -#endif - { "save", dosave, true }, - { "quit", doquit, true }, - { "privileged", privileged, true }, - { "notify", notify, false }, - { "devdetails", devdetails, false }, - { "restart", dorestart, true }, - { "stats", minerstats, false }, - { "check", checkcommand, false }, - { NULL, NULL, false } -}; - -static void checkcommand(__maybe_unused SOCKETTYPE c, char *param, bool isjson, char group) +static void failoveronly(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) { - struct api_data *root = NULL; - char buf[TMPBUFSIZ]; - char cmdbuf[100]; - bool found, access; - int i; - if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISCHK, 0, NULL, isjson)); + message(io_data, MSG_MISBOOL, 0, NULL, isjson); return; } - found = false; - access = false; - for (i = 0; cmds[i].name != NULL; i++) { - if (strcmp(cmds[i].name, param) == 0) { - found = true; - - sprintf(cmdbuf, "|%s|", param); - if (ISPRIVGROUP(group) || strstr(COMMANDS(group), cmdbuf)) - access = true; + *param = tolower(*param); - break; - } + if (*param != 't' && *param != 'f') { + message(io_data, MSG_INVBOOL, 0, NULL, isjson); + return; } - sprintf(io_buffer, isjson - ? "%s," JSON_CHECK - : "%s" _CHECK ",", - message(MSG_CHECK, 0, NULL, isjson)); + bool tf = (*param == 't'); - root = api_add_const(root, "Exists", found ? YES : NO, false); - root = api_add_const(root, "Access", access ? YES : NO, false); + opt_fail_only = tf; - root = print_data(root, buf, isjson); - if (isjson) - strcat(buf, JSON_CLOSE); - strcat(io_buffer, buf); + message(io_data, MSG_FOO, tf, NULL, isjson); } -static void send_result(SOCKETTYPE c, bool isjson) +static void minecoin(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { - int n; - int len; + struct api_data *root = NULL; + char buf[TMPBUFSIZ]; - if (isjson) - strcat(io_buffer, JSON_END); + message(io_data, MSG_MINECOIN, 0, NULL, isjson); - len = strlen(io_buffer); + struct mining_goal_info *goal, *tmpgoal; + bool precom = false; + HASH_ITER(hh, mining_goals, goal, tmpgoal) + { + if (goal->is_default) + io_add(io_data, isjson ? COMSTR JSON1 _MINECOIN JSON2 : _MINECOIN COMSTR); + else + { + sprintf(buf, isjson ? COMSTR JSON1 _MINECOIN "%u" JSON2 : _MINECOIN "%u" COMSTR, goal->id); + io_add(io_data, buf); + } + + switch (goal->malgo->algo) + { +#ifdef USE_SCRYPT + case POW_SCRYPT: + root = api_add_const(root, "Hash Method", SCRYPTSTR, false); + break; +#endif +#ifdef USE_SHA256D + case POW_SHA256D: + root = api_add_const(root, "Hash Method", SHA256STR, false); + break; +#endif + default: + root = api_add_const(root, "Hash Method", goal->malgo->name, false); + break; + } - applog(LOG_DEBUG, "API: send reply: (%d) '%.10s%s'", len+1, io_buffer, len > 10 ? "..." : BLANK); + cg_rlock(&ch_lock); + struct blockchain_info * const blkchain = goal->blkchain; + struct block_info * const blkinfo = blkchain->currentblk; + root = api_add_time(root, "Current Block Time", &blkinfo->first_seen_time, true); + char fullhash[(sizeof(blkinfo->prevblkhash) * 2) + 1]; + blkhashstr(fullhash, blkinfo->prevblkhash); + root = api_add_string(root, "Current Block Hash", fullhash, true); + cg_runlock(&ch_lock); + + root = api_add_bool(root, "LP", &goal->have_longpoll, false); + root = api_add_diff(root, "Network Difficulty", &goal->current_diff, true); + + root = api_add_diff(root, "Difficulty Accepted", &goal->diff_accepted, false); + + root = print_data(root, buf, isjson, precom); + io_add(io_data, buf); + if (isjson) + io_add(io_data, JSON_CLOSE); + } +} - // ignore failure - it's closed immediately anyway - n = send(c, io_buffer, len+1, 0); +static void debugstate(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + struct api_data *root = NULL; + char buf[TMPBUFSIZ]; + bool io_open; - if (opt_debug) { - if (SOCKETFAIL(n)) - applog(LOG_DEBUG, "API: send failed: %s", SOCKERRMSG); - else - applog(LOG_DEBUG, "API: sent %d", n); + if (param == NULL) + param = (char *)BLANK; + else + *param = tolower(*param); + + switch(*param) { + case 's': + opt_realquiet = true; + break; + case 'q': + opt_quiet ^= true; + break; + case 'v': + opt_log_output ^= true; + if (opt_log_output) + opt_quiet = false; + break; + case 'd': + opt_debug ^= true; + opt_log_output = opt_debug; + if (opt_debug) + opt_quiet = false; + break; + case 'r': + opt_protocol ^= true; + if (opt_protocol) + opt_quiet = false; + break; + case 'p': + want_per_device_stats ^= true; + opt_log_output = want_per_device_stats; + break; + case 'n': + opt_log_output = false; + opt_debug = false; + opt_quiet = false; + opt_protocol = false; + want_per_device_stats = false; + opt_worktime = false; + break; + case 'w': + opt_worktime ^= true; + break; +#ifdef _MEMORY_DEBUG + case 'y': + cgmemspeedup(); + break; + case 'z': + cgmemrpt(); + break; +#endif + default: + // anything else just reports the settings + break; + } + + message(io_data, MSG_DEBUGSET, 0, NULL, isjson); + io_open = io_add(io_data, isjson ? COMSTR JSON_DEBUGSET : _DEBUGSET COMSTR); + + root = api_add_bool(root, "Silent", &opt_realquiet, false); + root = api_add_bool(root, "Quiet", &opt_quiet, false); + root = api_add_bool(root, "Verbose", &opt_log_output, false); + root = api_add_bool(root, "Debug", &opt_debug, false); + root = api_add_bool(root, "RPCProto", &opt_protocol, false); + root = api_add_bool(root, "PerDevice", &want_per_device_stats, false); + root = api_add_bool(root, "WorkTime", &opt_worktime, false); + + root = print_data(root, buf, isjson, false); + io_add(io_data, buf); + if (isjson && io_open) + io_close(io_data); +} + +extern bool stratumsrv_change_port(unsigned); + +static void setconfig(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + char *comma; + long value; + + if (param == NULL || *param == '\0') { + message(io_data, MSG_CONPAR, 0, NULL, isjson); + return; + } + + comma = strchr(param, ','); + if (!comma) { + message(io_data, MSG_CONVAL, 0, param, isjson); + return; + } + + *(comma++) = '\0'; + +#if BLKMAKER_VERSION > 0 + if (strcasecmp(param, "coinbase-sig") == 0) { + free(opt_coinbase_sig); + opt_coinbase_sig = strdup(comma); + message(io_data, MSG_SETCONFIG, 1, param, isjson); + return; + } + else +#endif + if (strcasecmp(param, "strategy") == 0) { + char * const strategy_name = comma; + comma = strchr(strategy_name, ','); + if (comma) { + *(comma++) = '\0'; + } + value = bfg_strategy_parse(strategy_name); + if (value < 0) { + message(io_data, MSG_INVSTRATEGY, 0, param, isjson); + return; + } + if (!bfg_strategy_change(value, comma)) { + message(io_data, MSG_INVNUM, atoi(comma), param, isjson); + return; + } + message(io_data, MSG_SETCONFIG, value, param, isjson); + return; + } + + value = atol(comma); + if (value < 0 || value > 9999) { + message(io_data, MSG_INVNUM, value, param, isjson); + return; + } + + if (strcasecmp(param, "queue") == 0) + opt_queue = value; + else if (strcasecmp(param, "scantime") == 0) + opt_scantime = value; + else if (strcasecmp(param, "expiry") == 0) + opt_expiry = value; +#ifdef USE_LIBMICROHTTPD + else if (strcasecmp(param, "http-port") == 0) + { + httpsrv_stop(); + httpsrv_port = value; + if (httpsrv_port != -1) + httpsrv_start(httpsrv_port); + } +#endif +#ifdef USE_LIBEVENT + else if (strcasecmp(param, "stratum-port") == 0) + { + if (!stratumsrv_change_port(value)) { + message(io_data, MSG_FAILPORT, value, param, isjson); + return; + } + } +#endif + else { + message(io_data, MSG_UNKCON, 0, param, isjson); + return; + } + + message(io_data, MSG_SETCONFIG, value, param, isjson); +} + +#ifdef HAVE_AN_FPGA +static void pgaset(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +{ + struct cgpu_info *cgpu; + char buf[TMPBUFSIZ]; + int numpga = numpgas(); + + if (numpga == 0) { + message(io_data, MSG_PGANON, 0, NULL, isjson); + return; + } + + if (param == NULL || *param == '\0') { + message(io_data, MSG_MISID, 0, NULL, isjson); + return; + } + + char *opt = strchr(param, ','); + if (opt) + *(opt++) = '\0'; + if (!opt || !*opt) { + message(io_data, MSG_MISPGAOPT, 0, NULL, isjson); + return; + } + + int id = atoi(param); + if (id < 0 || id >= numpga) { + message(io_data, MSG_INVPGA, id, NULL, isjson); + return; + } + + int dev = pgadevice(id); + if (dev < 0) { // Should never happen + message(io_data, MSG_INVPGA, id, NULL, isjson); + return; + } + + cgpu = get_devices(dev); + + char *set = strchr(opt, ','); + if (set) + *(set++) = '\0'; + + enum bfg_set_device_replytype success; + const char *ret = proc_set_device(cgpu, opt, set, buf, &success); + switch (success) + { + case SDR_HELP: + message(io_data, MSG_PGAHELP, id, ret, isjson); + break; + case SDR_OK: + if (ret) + message(io_data, MSG_PGASETOK | USE_ALTMSG, id, ret, isjson); + else + message(io_data, MSG_PGASETOK, id, NULL, isjson); + break; + case SDR_UNKNOWN: + case SDR_ERR: + message(io_data, MSG_PGASETERR, id, ret, isjson); + break; + case SDR_AUTO: + case SDR_NOSUPP: + message(io_data, MSG_PGANOSET, id, NULL, isjson); + } +} +#endif + +static void dozero(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + if (param == NULL || *param == '\0') { + message(io_data, MSG_ZERMIS, 0, NULL, isjson); + return; + } + + char *sum = strchr(param, ','); + if (sum) + *(sum++) = '\0'; + if (!sum || !*sum) { + message(io_data, MSG_MISBOOL, 0, NULL, isjson); + return; + } + + bool all = false; + bool bs = false; + if (strcasecmp(param, "all") == 0) + all = true; + else if (strcasecmp(param, "bestshare") == 0) + bs = true; + + if (all == false && bs == false) { + message(io_data, MSG_ZERINV, 0, param, isjson); + return; + } + + *sum = tolower(*sum); + if (*sum != 't' && *sum != 'f') { + message(io_data, MSG_INVBOOL, 0, NULL, isjson); + return; + } + + bool dosum = (*sum == 't'); + if (dosum) + print_summary(); + + if (all) + zero_stats(); + if (bs) + zero_bestshare(); + + if (dosum) + message(io_data, MSG_ZERSUM, 0, all ? "All" : "BestShare", isjson); + else + message(io_data, MSG_ZERNOSUM, 0, all ? "All" : "BestShare", isjson); +} + +static void checkcommand(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, char group); + +struct CMDS { + char *name; + void (*func)(struct io_data *, SOCKETTYPE, char *, bool, char); + bool iswritemode; + bool joinable; +} cmds[] = { + { "version", apiversion, false, true }, + { "config", minerconfig, false, true }, + { "devscan", devscan, true, false }, + { "devs", devstatus, false, true }, + { "procs", devstatus, false, true }, + { "pools", poolstatus, false, true }, + { "summary", summary, false, true }, +#ifdef USE_OPENCL + { "gpuenable", gpuenable, true, false }, + { "gpudisable", gpudisable, true, false }, + { "gpurestart", gpurestart, true, false }, + { "gpu", gpudev, false, false }, +#endif +#ifdef HAVE_AN_FPGA + { "pga", pgadev, false, false }, + { "pgaenable", pgaenable, true, false }, + { "pgadisable", pgadisable, true, false }, + { "pgarestart", pgarestart, true, false }, + { "pgaidentify", pgaidentify, true, false }, + { "proc", pgadev, false, false }, + { "procenable", pgaenable, true, false }, + { "procdisable", pgadisable, true, false }, + { "procidentify", pgaidentify, true, false }, +#endif +#ifdef USE_CPUMINING + { "cpuenable", cpuenable, true, false }, + { "cpudisable", cpudisable, true, false }, + { "cpurestart", cpurestart, true, false }, + { "cpu", cpudev, false, false }, +#endif + { "gpucount", gpucount, false, true }, + { "pgacount", pgacount, false, true }, + { "proccount", pgacount, false, true }, + { "cpucount", cpucount, false, true }, + { "switchpool", switchpool, true, false }, + { "addpool", addpool, true, false }, + { "poolpriority", poolpriority, true, false }, + { "poolquota", poolquota, true, false }, + { "enablepool", enablepool, true, false }, + { "disablepool", disablepool, true, false }, + { "removepool", removepool, true, false }, +#ifdef USE_OPENCL + { "gpuintensity", gpuintensity, true, false }, + { "gpumem", gpumem, true, false }, + { "gpuengine", gpuengine, true, false }, + { "gpufan", gpufan, true, false }, + { "gpuvddc", gpuvddc, true, false }, +#endif + { "save", dosave, true, false }, + { "quit", doquit, true, false }, + { "privileged", privileged, true, false }, + { "notify", notify, false, true }, + { "procnotify", notify, false, true }, + { "devdetails", devdetail, false, true }, + { "procdetails", devdetail, false, true }, + { "restart", dorestart, true, false }, + { "stats", minerstats, false, true }, + { "check", checkcommand, false, false }, + { "failover-only", failoveronly, true, false }, + { "coin", minecoin, false, true }, + { "debug", debugstate, true, false }, + { "setconfig", setconfig, true, false }, +#ifdef HAVE_AN_FPGA + { "pgaset", pgaset, true, false }, + { "procset", pgaset, true, false }, +#endif + { "zero", dozero, true, false }, + { NULL, NULL, false, false } +}; + +static void checkcommand(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, char group) +{ + struct api_data *root = NULL; + char buf[TMPBUFSIZ]; + bool io_open; + char cmdbuf[100]; + bool found, access; + int i; + + if (param == NULL || *param == '\0') { + message(io_data, MSG_MISCHK, 0, NULL, isjson); + return; + } + + found = false; + access = false; + for (i = 0; cmds[i].name != NULL; i++) { + if (strcmp(cmds[i].name, param) == 0) { + found = true; + + sprintf(cmdbuf, "|%s|", param); + if (ISPRIVGROUP(group) || strstr(COMMANDS(group), cmdbuf)) + access = true; + + break; + } + } + + message(io_data, MSG_CHECK, 0, NULL, isjson); + io_open = io_add(io_data, isjson ? COMSTR JSON_CHECK : _CHECK COMSTR); + + root = api_add_const(root, "Exists", found ? YES : NO, false); + root = api_add_const(root, "Access", access ? YES : NO, false); + + root = print_data(root, buf, isjson, false); + io_add(io_data, buf); + if (isjson && io_open) + io_close(io_data); +} + +static void head_join(struct io_data *io_data, char *cmdptr, bool isjson, bool *firstjoin) +{ + char *ptr; + + if (*firstjoin) { + if (isjson) + io_add(io_data, JSON0); + *firstjoin = false; + } else { + if (isjson) + io_add(io_data, JSON_BETWEEN_JOIN); + } + + // External supplied string + ptr = escape_string(cmdptr, isjson); + + if (isjson) { + io_add(io_data, JSON1); + io_add(io_data, ptr); + io_add(io_data, JSON2); + } else { + io_add(io_data, JOIN_CMD); + io_add(io_data, ptr); + io_add(io_data, BETWEEN_JOIN); + } + + if (ptr != cmdptr) + free(ptr); +} + +static void tail_join(struct io_data *io_data, bool isjson) +{ + if (io_data->close) { + io_add(io_data, JSON_CLOSE); + io_data->close = false; + } + + if (isjson) { + io_add(io_data, JSON_END); + io_add(io_data, JSON3); } } +static void send_result(struct io_data *io_data, SOCKETTYPE c, bool isjson) +{ + if (io_data->close) + io_add(io_data, JSON_CLOSE); + + if (isjson) + io_add(io_data, JSON_END); + + // Null-terminate reply, including sending the \0 on the socket + bytes_append(&io_data->data, "", 1); + + applog(LOG_DEBUG, "API: send reply: (%ld) '%.10s%s'", + (long)bytes_len(&io_data->data), + bytes_buf(&io_data->data), + bytes_len(&io_data->data) > 10 ? "..." : BLANK); + + io_flush(io_data, true); + + if (bytes_len(&io_data->data)) + applog(LOG_WARNING, "RPC: Timed out with %ld bytes left to send", + (long)bytes_len(&io_data->data)); +} + +static +void _tidyup_socket(SOCKETTYPE * const sockp) +{ + if (*sockp != INVSOCK) { + shutdown(*sockp, SHUT_RDWR); + CLOSESOCKET(*sockp); + *sockp = INVSOCK; + free(sockp); + } +} + +static +void tidyup_socket(void * const arg) +{ + mutex_lock(&quit_restart_lock); + _tidyup_socket(arg); + mutex_unlock(&quit_restart_lock); +} + static void tidyup(__maybe_unused void *arg) { mutex_lock(&quit_restart_lock); + SOCKETTYPE *apisock = (SOCKETTYPE *)arg; + bye = true; - if (sock != INVSOCK) { - shutdown(sock, SHUT_RDWR); - CLOSESOCKET(sock); - sock = INVSOCK; - } + _tidyup_socket(apisock); if (ipaccess != NULL) { free(ipaccess); ipaccess = NULL; } - if (msg_buffer != NULL) { - free(msg_buffer); - msg_buffer = NULL; - } - - if (io_buffer != NULL) { - free(io_buffer); - io_buffer = NULL; - } + io_free(); mutex_unlock(&quit_restart_lock); } @@ -2782,30 +3662,21 @@ static void setup_groups() colon = strchr(ptr, ':'); if (colon) *colon = '\0'; - applog(LOG_WARNING, "API invalid group name '%s'", ptr); - quit(1, INVAPIGROUPS); + quit(1, "API invalid group name '%s'", ptr); } group = GROUP(*ptr); - if (!VALIDGROUP(group)) { - applog(LOG_WARNING, "API invalid group name '%c'", *ptr); - quit(1, INVAPIGROUPS); - } + if (!VALIDGROUP(group)) + quit(1, "API invalid group name '%c'", *ptr); - if (group == PRIVGROUP) { - applog(LOG_WARNING, "API group name can't be '%c'", PRIVGROUP); - quit(1, INVAPIGROUPS); - } + if (group == PRIVGROUP) + quit(1, "API group name can't be '%c'", PRIVGROUP); - if (group == NOPRIVGROUP) { - applog(LOG_WARNING, "API group name can't be '%c'", NOPRIVGROUP); - quit(1, INVAPIGROUPS); - } + if (group == NOPRIVGROUP) + quit(1, "API group name can't be '%c'", NOPRIVGROUP); - if (apigroups[GROUPOFFSET(group)].commands != NULL) { - applog(LOG_WARNING, "API duplicate group name '%c'", *ptr); - quit(1, INVAPIGROUPS); - } + if (apigroups[GROUPOFFSET(group)].commands != NULL) + quit(1, "API duplicate group name '%c'", *ptr); ptr += 2; @@ -2839,8 +3710,7 @@ static void setup_groups() *cmd = '\0'; } } else { - applog(LOG_WARNING, "API unknown command '%s' in group '%c'", ptr, group); - quit(1, INVAPIGROUPS); + quit(1, "API unknown command '%s' in group '%c'", ptr, group); } } @@ -2943,7 +3813,7 @@ static void setup_ipaccess() group = NOPRIVGROUP; - if (isalpha(*ptr) && *(ptr+1) == ':') { + if (VALIDGROUP(*ptr) && *(ptr+1) == ':') { if (DEFINEDGROUP(*ptr)) group = GROUP(*ptr); @@ -2999,12 +3869,14 @@ static void setup_ipaccess() static void *quit_thread(__maybe_unused void *userdata) { + RenameThread("rpc_quit"); + // allow thread creator to finish whatever it's doing mutex_lock(&quit_restart_lock); mutex_unlock(&quit_restart_lock); if (opt_debug) - applog(LOG_DEBUG, "API: killing cgminer"); + applog(LOG_DEBUG, "API: killing BFGMiner"); kill_work(); @@ -3013,55 +3885,261 @@ static void *quit_thread(__maybe_unused void *userdata) static void *restart_thread(__maybe_unused void *userdata) { + RenameThread("rpc_restart"); + // allow thread creator to finish whatever it's doing mutex_lock(&quit_restart_lock); mutex_unlock(&quit_restart_lock); if (opt_debug) - applog(LOG_DEBUG, "API: restarting cgminer"); + applog(LOG_DEBUG, "API: restarting BFGMiner"); app_restart(); return NULL; } +static bool check_connect(struct sockaddr_in *cli, char **connectaddr, char *group) +{ + bool addrok = false; + int i; + + *connectaddr = inet_ntoa(cli->sin_addr); + + *group = NOPRIVGROUP; + if (opt_api_allow) { + int client_ip = htonl(cli->sin_addr.s_addr); + for (i = 0; i < ips; i++) { + if ((client_ip & ipaccess[i].mask) == ipaccess[i].ip) { + addrok = true; + *group = ipaccess[i].group; + break; + } + } + } else { + if (opt_api_network) + addrok = true; + else + addrok = (strcmp(*connectaddr, localaddr) == 0); + } + + return addrok; +} + +static void mcast() +{ + struct sockaddr_in listen; + struct ip_mreq grp; + struct sockaddr_in came_from; + struct timeval bindstart; + const char *binderror; + SOCKETTYPE *mcastsock; + SOCKETTYPE reply_sock; + socklen_t came_from_siz; + char *connectaddr; + ssize_t rep; + int bound; + int count; + int reply_port; + bool addrok; + char group; + + char expect[] = "cgminer-"; // first 8 bytes constant + char *expect_code; + size_t expect_code_len; + char buf[1024]; + char replybuf[1024]; + + memset(&grp, 0, sizeof(grp)); + grp.imr_multiaddr.s_addr = inet_addr(opt_api_mcast_addr); + if (grp.imr_multiaddr.s_addr == INADDR_NONE) + quit(1, "Invalid Multicast Address"); + grp.imr_interface.s_addr = INADDR_ANY; + + mcastsock = malloc(sizeof(*mcastsock)); + *mcastsock = INVSOCK; + pthread_cleanup_push(tidyup_socket, mcastsock); + + *mcastsock = bfg_socket(AF_INET, SOCK_DGRAM, 0); + + int optval = 1; + if (SOCKETFAIL(setsockopt(*mcastsock, SOL_SOCKET, SO_REUSEADDR, (void *)(&optval), sizeof(optval)))) { + applog(LOG_ERR, "API mcast setsockopt SO_REUSEADDR failed (%s)%s", SOCKERRMSG, MUNAVAILABLE); + goto die; + } + + memset(&listen, 0, sizeof(listen)); + listen.sin_family = AF_INET; + listen.sin_addr.s_addr = INADDR_ANY; + listen.sin_port = htons(opt_api_mcast_port); + + // try for more than 1 minute ... in case the old one hasn't completely gone yet + bound = 0; + timer_set_now(&bindstart); + while (bound == 0) { + if (SOCKETFAIL(bind(*mcastsock, (struct sockaddr *)(&listen), sizeof(listen)))) { + binderror = SOCKERRMSG; + if (timer_elapsed(&bindstart, NULL) > 61) + break; + else + cgsleep_ms(30000); + } else + bound = 1; + } + + if (bound == 0) { + applog(LOG_ERR, "API mcast bind to port %d failed (%s)%s", opt_api_port, binderror, MUNAVAILABLE); + goto die; + } + + if (SOCKETFAIL(setsockopt(*mcastsock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)(&grp), sizeof(grp)))) { + applog(LOG_ERR, "API mcast join failed (%s)%s", SOCKERRMSG, MUNAVAILABLE); + goto die; + } + + expect_code_len = sizeof(expect) + strlen(opt_api_mcast_code); + expect_code = malloc(expect_code_len+1); + if (!expect_code) + quit(1, "Failed to malloc mcast expect_code"); + snprintf(expect_code, expect_code_len+1, "%s%s-", expect, opt_api_mcast_code); + + count = 0; + while (80085) { + cgsleep_ms(1000); + + count++; + came_from_siz = sizeof(came_from); + if (SOCKETFAIL(rep = recvfrom(*mcastsock, buf, sizeof(buf) - 1, + 0, (struct sockaddr *)(&came_from), &came_from_siz))) { + applog(LOG_DEBUG, "API mcast failed count=%d (%s) (%d)", + count, SOCKERRMSG, (int)*mcastsock); + continue; + } + + addrok = check_connect(&came_from, &connectaddr, &group); + applog(LOG_DEBUG, "API mcast from %s - %s", + connectaddr, addrok ? "Accepted" : "Ignored"); + if (!addrok) + continue; + + buf[rep] = '\0'; + if (rep > 0 && buf[rep-1] == '\n') + buf[--rep] = '\0'; + + applog(LOG_DEBUG, "API mcast request rep=%d (%s) from %s:%d", + (int)rep, buf, + inet_ntoa(came_from.sin_addr), + ntohs(came_from.sin_port)); + + if ((size_t)rep > expect_code_len && memcmp(buf, expect_code, expect_code_len) == 0) { + reply_port = atoi(&buf[expect_code_len]); + if (reply_port < 1 || reply_port > 65535) { + applog(LOG_DEBUG, "API mcast request ignored - invalid port (%s)", + &buf[expect_code_len]); + } else { + applog(LOG_DEBUG, "API mcast request OK port %s=%d", + &buf[expect_code_len], reply_port); + + came_from.sin_port = htons(reply_port); + reply_sock = bfg_socket(AF_INET, SOCK_DGRAM, 0); + + snprintf(replybuf, sizeof(replybuf), + "cgm-%s-%d-%s", + opt_api_mcast_code, + opt_api_port, opt_api_mcast_des); + + rep = sendto(reply_sock, replybuf, strlen(replybuf)+1, + 0, (struct sockaddr *)(&came_from), + sizeof(came_from)); + if (SOCKETFAIL(rep)) { + applog(LOG_DEBUG, "API mcast send reply failed (%s) (%d)", + SOCKERRMSG, (int)reply_sock); + } else { + applog(LOG_DEBUG, "API mcast send reply (%s) succeeded (%d) (%d)", + replybuf, (int)rep, (int)reply_sock); + } + + shutdown(reply_sock, SHUT_RDWR); + CLOSESOCKET(reply_sock); + } + } else + applog(LOG_DEBUG, "API mcast request was no good"); + } + +die: + ; // statement in case pthread_cleanup_pop doesn't start with one + pthread_cleanup_pop(true); +} + +static void *mcast_thread(void *userdata) +{ + pthread_detach(pthread_self()); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + + RenameThread("api_mcast"); + + mcast(); + + return NULL; +} + +void mcast_init() +{ + struct thr_info *thr; + + thr = calloc(1, sizeof(*thr)); + if (!thr) + quit(1, "Failed to calloc mcast thr"); + + if (thr_info_create(thr, NULL, mcast_thread, thr)) + quit(1, "API mcast thread create failed"); +} + void api(int api_thr_id) { + struct io_data *io_data; struct thr_info bye_thr; char buf[TMPBUFSIZ]; char param_buf[TMPBUFSIZ]; - const char *localaddr = "127.0.0.1"; SOCKETTYPE c; int n, bound; char *connectaddr; - char *binderror; - time_t bindstart; + const char *binderror; + struct timeval bindstart; short int port = opt_api_port; struct sockaddr_in serv; struct sockaddr_in cli; socklen_t clisiz; char cmdbuf[100]; - char *cmd; + char *cmd = NULL, *cmdptr, *cmdsbuf; char *param; bool addrok; char group; json_error_t json_err; - json_t *json_config; + json_t *json_config = NULL; json_t *json_val; bool isjson; - bool did; + bool did, isjoin, firstjoin; int i; - mutex_init(&quit_restart_lock); - - pthread_cleanup_push(tidyup, NULL); - my_thr_id = api_thr_id; + SOCKETTYPE *apisock; if (!opt_api_listen) { applog(LOG_DEBUG, "API not running%s", UNAVAILABLE); return; } + apisock = malloc(sizeof(*apisock)); + *apisock = INVSOCK; + + rpc_io_data = + io_data = sock_io_new(); + + mutex_init(&quit_restart_lock); + + pthread_cleanup_push(tidyup, (void *)apisock); + my_thr_id = api_thr_id; + setup_groups(); if (opt_api_allow) { @@ -3069,20 +4147,16 @@ void api(int api_thr_id) if (ips == 0) { applog(LOG_WARNING, "API not running (no valid IPs specified)%s", UNAVAILABLE); - return; + pthread_exit(NULL); } } - /* This should be done before curl in needed - * to ensure curl has already called WSAStartup() in windows */ - sleep(opt_log_interval); - - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock == INVSOCK) { + *apisock = bfg_socket(AF_INET, SOCK_STREAM, 0); + if (*apisock == INVSOCK) { applog(LOG_ERR, "API1 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE); - return; + pthread_exit(NULL); } - + memset(&serv, 0, sizeof(serv)); serv.sin_family = AF_INET; @@ -3091,23 +4165,37 @@ void api(int api_thr_id) serv.sin_addr.s_addr = inet_addr(localaddr); if (serv.sin_addr.s_addr == (in_addr_t)INVINETADDR) { applog(LOG_ERR, "API2 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE); - return; + pthread_exit(NULL); } } serv.sin_port = htons(port); +#ifndef WIN32 + // On linux with SO_REUSEADDR, bind will get the port if the previous + // socket is closed (even if it is still in TIME_WAIT) but fail if + // another program has it open - which is what we want + int optval = 1; + // If it doesn't work, we don't really care - just show a debug message + if (SOCKETFAIL(setsockopt(*apisock, SOL_SOCKET, SO_REUSEADDR, (void *)(&optval), sizeof(optval)))) + applog(LOG_DEBUG, "API setsockopt SO_REUSEADDR failed (ignored): %s", SOCKERRMSG); +#else + // On windows a 2nd program can bind to a port>1024 already in use unless + // SO_EXCLUSIVEADDRUSE is used - however then the bind to a closed port + // in TIME_WAIT will fail until the timeout - so we leave the options alone +#endif + // try for more than 1 minute ... in case the old one hasn't completely gone yet bound = 0; - bindstart = time(NULL); + cgtime(&bindstart); while (bound == 0) { - if (SOCKETFAIL(bind(sock, (struct sockaddr *)(&serv), sizeof(serv)))) { + if (SOCKETFAIL(bind(*apisock, (struct sockaddr *)(&serv), sizeof(serv)))) { binderror = SOCKERRMSG; - if ((time(NULL) - bindstart) > 61) + if (timer_elapsed(&bindstart, NULL) > 61) break; else { applog(LOG_WARNING, "API bind to port %d failed - trying again in 30sec", port); - sleep(30); + cgsleep_ms(30000); } } else bound = 1; @@ -3115,56 +4203,36 @@ void api(int api_thr_id) if (bound == 0) { applog(LOG_ERR, "API bind to port %d failed (%s)%s", port, binderror, UNAVAILABLE); - return; + pthread_exit(NULL); } - if (SOCKETFAIL(listen(sock, QUEUE))) { + if (SOCKETFAIL(listen(*apisock, QUEUE))) { applog(LOG_ERR, "API3 initialisation failed (%s)%s", SOCKERRMSG, UNAVAILABLE); - CLOSESOCKET(sock); - return; + pthread_exit(NULL); } if (opt_api_allow) - applog(LOG_WARNING, "API running in IP access mode"); + applog(LOG_WARNING, "API running in IP access mode on port %d", port); else { if (opt_api_network) - applog(LOG_WARNING, "API running in UNRESTRICTED access mode"); + applog(LOG_WARNING, "API running in UNRESTRICTED read access mode on port %d", port); else - applog(LOG_WARNING, "API running in local access mode"); + applog(LOG_WARNING, "API running in local read access mode on port %d", port); } - io_buffer = malloc(MYBUFSIZ+1); - msg_buffer = malloc(MYBUFSIZ+1); + if (opt_api_mcast) + mcast_init(); while (!bye) { clisiz = sizeof(cli); - if (SOCKETFAIL(c = accept(sock, (struct sockaddr *)(&cli), &clisiz))) { + if (SOCKETFAIL(c = accept(*apisock, (struct sockaddr *)(&cli), &clisiz))) { applog(LOG_ERR, "API failed (%s)%s", SOCKERRMSG, UNAVAILABLE); goto die; } - connectaddr = inet_ntoa(cli.sin_addr); - - addrok = false; - group = NOPRIVGROUP; - if (opt_api_allow) { - int client_ip = htonl(cli.sin_addr.s_addr); - for (i = 0; i < ips; i++) { - if ((client_ip & ipaccess[i].mask) == ipaccess[i].ip) { - addrok = true; - group = ipaccess[i].group; - break; - } - } - } else { - if (opt_api_network) - addrok = true; - else - addrok = (strcmp(connectaddr, localaddr) == 0); - } - - if (opt_debug) - applog(LOG_DEBUG, "API: connection from %s - %s", connectaddr, addrok ? "Accepted" : "Ignored"); + addrok = check_connect(&cli, &connectaddr, &group); + applog(LOG_DEBUG, "API: connection from %s - %s", + connectaddr, addrok ? "Accepted" : "Ignored"); if (addrok) { n = recv(c, &buf[0], TMPBUFSIZ-1, 0); @@ -3180,9 +4248,12 @@ void api(int api_thr_id) applog(LOG_DEBUG, "API: recv command: (%d) '%s'", n, buf); } + firstjoin = isjoin = false; if (!SOCKETFAIL(n)) { // the time of the request in now when = time(NULL); + io_reinit(io_data); + io_data->sock = c; did = false; @@ -3209,21 +4280,21 @@ void api(int api_thr_id) #endif if (!json_is_object(json_config)) { - strcpy(io_buffer, message(MSG_INVJSON, 0, NULL, isjson)); - send_result(c, isjson); + message(io_data, MSG_INVJSON, 0, NULL, isjson); + send_result(io_data, c, isjson); did = true; } else { json_val = json_object_get(json_config, JSON_COMMAND); if (json_val == NULL) { - strcpy(io_buffer, message(MSG_MISCMD, 0, NULL, isjson)); - send_result(c, isjson); + message(io_data, MSG_MISCMD, 0, NULL, isjson); + send_result(io_data, c, isjson); did = true; } else { if (!json_is_string(json_val)) { - strcpy(io_buffer, message(MSG_INVCMD, 0, NULL, isjson)); - send_result(c, isjson); + message(io_data, MSG_INVCMD, 0, NULL, isjson); + send_result(io_data, c, isjson); did = true; } else { @@ -3243,29 +4314,88 @@ void api(int api_thr_id) } } - if (!did) - for (i = 0; cmds[i].name != NULL; i++) { - if (strcmp(cmd, cmds[i].name) == 0) { - sprintf(cmdbuf, "|%s|", cmd); - if (ISPRIVGROUP(group) || strstr(COMMANDS(group), cmdbuf)) - (cmds[i].func)(c, param, isjson, group); - else { - strcpy(io_buffer, message(MSG_ACCDENY, 0, cmds[i].name, isjson)); - applog(LOG_DEBUG, "API: access denied to '%s' for '%s' command", connectaddr, cmds[i].name); - } + if (!did) { + if (strchr(cmd, CMDJOIN)) { + firstjoin = isjoin = true; + // cmd + leading+tailing '|' + '\0' + cmdsbuf = malloc(strlen(cmd) + 3); + if (!cmdsbuf) + quithere(1, "OOM cmdsbuf"); + strcpy(cmdsbuf, "|"); + param = NULL; + } - send_result(c, isjson); - did = true; - break; + cmdptr = cmd; + do { + did = false; + if (isjoin) { + cmd = strchr(cmdptr, CMDJOIN); + if (cmd) + *(cmd++) = '\0'; + if (!*cmdptr) + goto inochi; } - } - if (!did) { - strcpy(io_buffer, message(MSG_INVCMD, 0, NULL, isjson)); - send_result(c, isjson); + for (i = 0; cmds[i].name != NULL; i++) { + if (strcmp(cmdptr, cmds[i].name) == 0) { + sprintf(cmdbuf, "|%s|", cmdptr); + if (isjoin) { + if (strstr(cmdsbuf, cmdbuf)) { + did = true; + break; + } + strcat(cmdsbuf, cmdptr); + strcat(cmdsbuf, "|"); + head_join(io_data, cmdptr, isjson, &firstjoin); + if (!cmds[i].joinable) { + message(io_data, MSG_ACCDENY, 0, cmds[i].name, isjson); + did = true; + tail_join(io_data, isjson); + break; + } + } + if (ISPRIVGROUP(group) || strstr(COMMANDS(group), cmdbuf)) + { + per_proc = !strncmp(cmds[i].name, "proc", 4); + (cmds[i].func)(io_data, c, param, isjson, group); + } + else { + message(io_data, MSG_ACCDENY, 0, cmds[i].name, isjson); + applog(LOG_DEBUG, "API: access denied to '%s' for '%s' command", connectaddr, cmds[i].name); + } + + did = true; + if (!isjoin) + send_result(io_data, c, isjson); + else + tail_join(io_data, isjson); + break; + } + } + + if (!did) { + if (isjoin) + head_join(io_data, cmdptr, isjson, &firstjoin); + message(io_data, MSG_INVCMD, 0, NULL, isjson); + if (isjoin) + tail_join(io_data, isjson); + else + send_result(io_data, c, isjson); + } +inochi: + if (isjoin) + cmdptr = cmd; + } while (isjoin && cmdptr); } + + if (isjson) + json_decref(json_config); + + if (isjoin) + send_result(io_data, c, isjson); } } + shutdown(c, SHUT_RDWR); CLOSESOCKET(c); } die: diff --git a/autogen.sh b/autogen.sh index bf564eb1cc..5ea879a520 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,12 +1,30 @@ -#!/bin/sh +#!/bin/sh -e +# Written by Luke Dashjr in 2012-2014 +# This program is released under the terms of the Creative Commons "CC0 1.0 Universal" license and/or copyright waiver. -# You need autoconf 2.5x, preferably 2.57 or later -# You need automake 1.7 or later. 1.6 might work. +bs_dir="$(dirname "$0")" -set -e +if test -z "$NOSUBMODULES" ; then + echo 'Getting submodules...' + + # Older versions had INSTALL in git; remove it so git can update cleanly + rm -f libblkmaker/INSTALL + + ( + cd "${bs_dir}" + git submodule update --init + ) +fi -aclocal -I m4 -autoheader -automake --add-missing --copy -autoconf +echo 'Running autoreconf -if...' +( + cd "${bs_dir}" + rm -rf autom4te.cache + rm -f aclocal.m4 ltmain.sh + autoreconf -if ${AC_FLAGS} +) +echo 'Updating version.h...' +if ./gen-version.sh >version.h.new; then + cmp version.h version.h.new && rm version.h.new || mv version.h.new version.h +fi diff --git a/avalonhost-raminst b/avalonhost-raminst new file mode 100755 index 0000000000..4c17b63b8c --- /dev/null +++ b/avalonhost-raminst @@ -0,0 +1,49 @@ +#!/bin/sh +# Copyright 2013 Luke Dashjr +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. See COPYING for more details. + +set -e +if test "$#" -lt 2; then + echo "Usage: $0 " + echo "Example: $0 testing bfgminer screen" + echo "Installs to RAM, on an Avalon-host router" + echo "Version can be 'stable', 'testing', or any 3-digit version; eg '3.1.0'" + echo "Do NOT attempt to reverse (uninstall) except by rebooting" + echo "Do NOT attempt to use this script more than once per boot" + exit 1 +fi +die() { + echo "$@" + echo 'ABORTING' + exit 1 +} +if ! grep TL-WR703N /proc/cpuinfo; then + die 'This doesn'\''t seem to be an Avalon host system' +fi +if test "$USER" != "root"; then + die "Must be run as root" +fi +echo "WARNING: If anything fails other than opkg and crontab, reboot ASAP" +source /lib/functions.sh +mkdir -p /tmp/root/.oldroot +mount -o noatime,lowerdir=/rom,upperdir=/tmp/root -t overlayfs "overlayfs:/tmp/root" /mnt +pivot /mnt /.oldroot +mount -o noatime,move /.oldroot/rom /rom +sed -i 's/\(^option[[:space:]]\+overlay_root[[:space:]]\+\).*//;T;d' /etc/opkg.conf +{ + echo 'option overlay_root /' + echo "src/gz bfgminer http://luke.dashjr.org/programs/bitcoin/files/bfgminer/$1/openwrt/12.09/ar71xx" +} >> /etc/opkg.conf +shift +set +e +opkg update +opkg install "$@" +crontab -r # disabled cgminer-monitor +set -e +mount -o noatime,lowerdir=/,upperdir=/overlay -t overlayfs "overlayfs:/overlay" /mnt +pivot /mnt /.oldroot +mount -o noatime,move /.oldroot/rom /rom diff --git a/bench_block.h b/bench_block.h deleted file mode 100644 index a1aa35a80b..0000000000 --- a/bench_block.h +++ /dev/null @@ -1,39 +0,0 @@ -#if !defined(__BENCH_BLOCK_H__) - #define __BENCH_BLOCK_H__ 1 - - // Random work pulled from a pool - #define CGMINER_BENCHMARK_BLOCK \ - 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0xD8, 0x07, 0x17, 0xC9, 0x13, 0x6F, 0xDC, 0xBE, 0xDE, 0xB7, \ - 0xB2, 0x14, 0xEF, 0xD1, 0x72, 0x7F, 0xA3, 0x72, 0xB2, 0x5D, 0x88, 0xF0, 0x00, 0x00, 0x05, 0xAA, \ - 0x00, 0x00, 0x00, 0x00, 0x92, 0x8B, 0x4C, 0x77, 0xF5, 0xB2, 0xE6, 0x56, 0x96, 0x27, 0xE0, 0x66, \ - 0x3C, 0x5B, 0xDD, 0xDC, 0x88, 0x6A, 0x7D, 0x7C, 0x7B, 0x8C, 0xE4, 0x92, 0x38, 0x92, 0x58, 0x2E, \ - 0x18, 0x4D, 0x95, 0x9E, 0x4E, 0x44, 0xF1, 0x5F, 0x1A, 0x08, 0xE1, 0xE5, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, \ - 0x86, 0x7E, 0x3A, 0xAF, 0x37, 0x83, 0xAF, 0xA0, 0xB5, 0x33, 0x2C, 0x28, 0xED, 0xA9, 0x89, 0x3E, \ - 0x0A, 0xB6, 0x46, 0x81, 0xC2, 0x71, 0x4F, 0x34, 0x5A, 0x74, 0x89, 0x0E, 0x2B, 0x04, 0xB3, 0x16, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xF6, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, \ - 0x55, 0xF1, 0x44, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x79, 0x63, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - -#endif // !defined(__BENCH_BLOCK_H__) diff --git a/binloader.c b/binloader.c new file mode 100644 index 0000000000..4922dd6454 --- /dev/null +++ b/binloader.c @@ -0,0 +1,213 @@ +/* + * Copyright 2012-2013 Luke Dashjr + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) + * any later version. See COPYING for more details. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "deviceapi.h" +#include "logging.h" +#include "miner.h" +#include "util.h" + +#define bailout(...) do { \ + applog(__VA_ARGS__); \ + return NULL; \ +} while(0) + +#define check_magic(L) do { \ + if (1 != fread(buf, 1, 1, f)) \ + bailout(LOG_ERR, "%s: Error reading bitstream ('%c')", \ + repr, L); \ + if (buf[0] != L) \ + bailout(LOG_ERR, "%s: Firmware has wrong magic ('%c')", \ + repr, L); \ +} while(0) + +#define read_str(eng) do { \ + if (1 != fread(buf, 2, 1, f)) \ + bailout(LOG_ERR, "%s: Error reading bitstream (" eng " len)", \ + repr); \ + len = (ubuf[0] << 8) | ubuf[1]; \ + if (len >= sizeof(buf)) \ + bailout(LOG_ERR, "%s: Firmware " eng " too long", \ + repr); \ + if (1 != fread(buf, len, 1, f)) \ + bailout(LOG_ERR, "%s: Error reading bitstream (" eng ")", \ + repr); \ + buf[len] = '\0'; \ +} while(0) + +void _bitstream_not_found(const char *repr, const char *fn) +{ + applog(LOG_ERR, "ERROR: Unable to load '%s', required for %s to work!", fn, repr); + applog(LOG_ERR, "ERROR: Please read README.FPGA for instructions"); +} + +FILE *open_xilinx_bitstream(const char *dname, const char *repr, const char *fwfile, unsigned long *out_len) +{ + char buf[0x100]; + unsigned char *ubuf = (unsigned char*)buf; + unsigned long len; + char *p; + + FILE *f = open_bitstream(dname, fwfile); + if (!f) + { + _bitstream_not_found(repr, fwfile); + return NULL; + } + if (1 != fread(buf, 2, 1, f)) + bailout(LOG_ERR, "%s: Error reading bitstream (magic)", + repr); + if (buf[0] || buf[1] != 9) + bailout(LOG_ERR, "%s: Firmware has wrong magic (9)", + repr); + if (-1 == fseek(f, 11, SEEK_CUR)) + bailout(LOG_ERR, "%s: Firmware seek failed", + repr); + check_magic('a'); + read_str("design name"); + applog(LOG_DEBUG, "%s: Firmware file %s info:", + repr, fwfile); + applog(LOG_DEBUG, " Design name: %s", buf); + p = strrchr(buf, ';') ?: buf; + p = strrchr(buf, '=') ?: p; + if (p[0] == '=') + ++p; + unsigned long fwusercode = (unsigned long)strtoll(p, &p, 16); + if (p[0] != '\0') + bailout(LOG_ERR, "%s: Bad usercode in bitstream file", + repr); + if (fwusercode == 0xffffffff) + bailout(LOG_ERR, "%s: Firmware doesn't support user code", + repr); + applog(LOG_DEBUG, " Version: %u, build %u", (unsigned)((fwusercode >> 8) & 0xff), (unsigned)(fwusercode & 0xff)); + check_magic('b'); + read_str("part number"); + applog(LOG_DEBUG, " Part number: %s", buf); + check_magic('c'); + read_str("build date"); + applog(LOG_DEBUG, " Build date: %s", buf); + check_magic('d'); + read_str("build time"); + applog(LOG_DEBUG, " Build time: %s", buf); + check_magic('e'); + if (1 != fread(buf, 4, 1, f)) + bailout(LOG_ERR, "%s: Error reading bitstream (data len)", + repr); + len = ((unsigned long)ubuf[0] << 24) | ((unsigned long)ubuf[1] << 16) | (ubuf[2] << 8) | ubuf[3]; + applog(LOG_DEBUG, " Bitstream size: %lu", len); + + *out_len = len; + return f; +} + +bool load_bitstream_intelhex(bytes_t *rv, const char *dname, const char *repr, const char *fn) +{ + char buf[0x100]; + size_t sz; + uint8_t xsz, xrt; + uint16_t xaddr; + FILE *F = open_bitstream(dname, fn); + if (!F) + return false; + while (!feof(F)) + { + if (unlikely(ferror(F))) + { + applog(LOG_ERR, "Error reading '%s'", fn); + goto ihxerr; + } + if (!fgets(buf, sizeof(buf), F)) + goto ihxerr; + if (unlikely(buf[0] != ':')) + goto ihxerr; + if (unlikely(!( + hex2bin(&xsz, &buf[1], 1) + && hex2bin((unsigned char*)&xaddr, &buf[3], 2) + && hex2bin(&xrt, &buf[7], 1) + ))) + { + applog(LOG_ERR, "Error parsing in '%s'", fn); + goto ihxerr; + } + switch (xrt) + { + case 0: // data + break; + case 1: // EOF + fclose(F); + return true; + default: + applog(LOG_ERR, "Unsupported record type in '%s'", fn); + goto ihxerr; + } + xaddr = be16toh(xaddr); + sz = bytes_len(rv); + bytes_resize(rv, xaddr + xsz); + if (sz < xaddr) + memset(&bytes_buf(rv)[sz], 0xff, xaddr - sz); + if (unlikely(!(hex2bin(&bytes_buf(rv)[xaddr], &buf[9], xsz)))) + { + applog(LOG_ERR, "Error parsing data in '%s'", fn); + goto ihxerr; + } + // TODO: checksum + } + +ihxerr: + fclose(F); + bytes_reset(rv); + return false; +} + +bool load_bitstream_bytes(bytes_t *rv, const char *dname, const char *repr, const char *fileprefix) +{ + FILE *F; + size_t fplen = strlen(fileprefix); + char fnbuf[fplen + 4 + 1]; + int e; + + bytes_reset(rv); + memcpy(fnbuf, fileprefix, fplen); + + strcpy(&fnbuf[fplen], ".bin"); + F = open_bitstream(dname, fnbuf); + if (F) + { + char buf[0x100]; + size_t sz; + while ( (sz = fread(buf, 1, sizeof(buf), F)) ) + bytes_append(rv, buf, sz); + e = ferror(F); + fclose(F); + if (unlikely(e)) + { + applog(LOG_ERR, "Error reading '%s'", fnbuf); + bytes_reset(rv); + } + else + return true; + } + + strcpy(&fnbuf[fplen], ".ihx"); + if (load_bitstream_intelhex(rv, dname, repr, fnbuf)) + return true; + + // TODO: Xilinx + + _bitstream_not_found(repr, fnbuf); + return false; +} diff --git a/binloader.h b/binloader.h new file mode 100644 index 0000000000..28711336a1 --- /dev/null +++ b/binloader.h @@ -0,0 +1,14 @@ +#ifndef BFG_BINLOADER_H +#define BFG_BINLOADER_H + +#include +#include + +#include "util.h" + +extern void _bitstream_not_found(const char *repr, const char *fn); +extern FILE *open_xilinx_bitstream(const char *dname, const char *repr, const char *fwfile, unsigned long *out_len); +extern bool load_bitstream_intelhex(bytes_t *out, const char *dname, const char *repr, const char *fn); +extern bool load_bitstream_bytes(bytes_t *out, const char *dname, const char *repr, const char *fileprefix); + +#endif diff --git a/bitstreams/.gitignore b/bitstreams/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/bitstreams/COPYING_fpgaminer b/bitstreams/COPYING_fpgaminer deleted file mode 100644 index 9db2c5fd0e..0000000000 --- a/bitstreams/COPYING_fpgaminer +++ /dev/null @@ -1,23 +0,0 @@ -All the bitstream files included in this directory that follow the name pattern fpgaminer_*.ncd are: - ----- - -Copyright (c) 2011-2012 fpgaminer@bitcoin-mining.com - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - ----- - -You can find the original sources at the Open Source FPGA Bitcoin Miner project GitHub repository: -https://github.com/progranism/Open-Source-FPGA-Bitcoin-Miner/tree/master/projects/X6000_ztex_comm4/hdl diff --git a/bitstreams/COPYING_ztex b/bitstreams/COPYING_ztex deleted file mode 100644 index 99cd2ed9fb..0000000000 --- a/bitstreams/COPYING_ztex +++ /dev/null @@ -1,24 +0,0 @@ -All the bitstream files included in this directory that follow the name pattern ztex_*.bit are: - ----- - -Copyright (C) 2009-2011 ZTEX GmbH. -http://www.ztex.de - - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 3 as -published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, see http://www.gnu.org/licenses/. - ----- - -You can find the original sources at the BTCMiner project home page: http://www.ztex.de/btcminer/ - diff --git a/bitstreams/fpgaminer_top_fixed7_197MHz.ncd b/bitstreams/fpgaminer_top_fixed7_197MHz.ncd deleted file mode 100644 index 1df4e1d051..0000000000 Binary files a/bitstreams/fpgaminer_top_fixed7_197MHz.ncd and /dev/null differ diff --git a/bitstreams/ztex_ufm1_15b1.bit b/bitstreams/ztex_ufm1_15b1.bit deleted file mode 100644 index 4ed6f4c830..0000000000 Binary files a/bitstreams/ztex_ufm1_15b1.bit and /dev/null differ diff --git a/bitstreams/ztex_ufm1_15d1.bit b/bitstreams/ztex_ufm1_15d1.bit deleted file mode 100644 index b87eaf4f5e..0000000000 Binary files a/bitstreams/ztex_ufm1_15d1.bit and /dev/null differ diff --git a/bitstreams/ztex_ufm1_15d3.bit b/bitstreams/ztex_ufm1_15d3.bit deleted file mode 100644 index 78157a53d5..0000000000 Binary files a/bitstreams/ztex_ufm1_15d3.bit and /dev/null differ diff --git a/bitstreams/ztex_ufm1_15d4.bit b/bitstreams/ztex_ufm1_15d4.bit deleted file mode 100644 index 09519764d1..0000000000 Binary files a/bitstreams/ztex_ufm1_15d4.bit and /dev/null differ diff --git a/bitstreams/ztex_ufm1_15y1.bit b/bitstreams/ztex_ufm1_15y1.bit deleted file mode 100644 index c9b38ae059..0000000000 Binary files a/bitstreams/ztex_ufm1_15y1.bit and /dev/null differ diff --git a/ccan-upstream b/ccan-upstream new file mode 160000 index 0000000000..118708edd4 --- /dev/null +++ b/ccan-upstream @@ -0,0 +1 @@ +Subproject commit 118708edd46530fa0848d01b8920ddd673eb72c0 diff --git a/ccan.bfg/Makefile.am b/ccan.bfg/Makefile.am new file mode 100644 index 0000000000..86de83004c --- /dev/null +++ b/ccan.bfg/Makefile.am @@ -0,0 +1,14 @@ +noinst_LIBRARIES = libccan.a + +libccan_a_SOURCES = \ + ../ccan-upstream/ccan/build_assert/build_assert.h \ + ../ccan-upstream/ccan/cast/cast.h \ + ../ccan-upstream/ccan/compiler/compiler.h \ + ../ccan-upstream/ccan/opt/helpers.c \ + ../ccan-upstream/ccan/opt/opt.c \ + ../ccan-upstream/ccan/opt/opt.h \ + ../ccan-upstream/ccan/opt/parse.c \ + ../ccan-upstream/ccan/opt/private.h \ + ../ccan-upstream/ccan/opt/usage.c \ + ../ccan-upstream/ccan/typesafe_cb/typesafe_cb.h +libccan_a_CPPFLAGS = -I$(top_srcdir)/ccan-upstream diff --git a/ccan/Makefile.am b/ccan/Makefile.am deleted file mode 100644 index 1514f6f153..0000000000 --- a/ccan/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -noinst_LIBRARIES = libccan.a - -libccan_a_SOURCES = compiler/compiler.h opt/helpers.c opt/opt.c opt/opt.h opt/parse.c opt/private.h opt/usage.c typesafe_cb/typesafe_cb.h diff --git a/ccan/compiler/LICENSE b/ccan/compiler/LICENSE deleted file mode 100644 index fc8a5de7ed..0000000000 --- a/ccan/compiler/LICENSE +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/ccan/compiler/_info b/ccan/compiler/_info deleted file mode 100644 index c55ba22f08..0000000000 --- a/ccan/compiler/_info +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include "config.h" - -/** - * compiler - macros for common compiler extensions - * - * Abstracts away some compiler hints. Currently these include: - * - COLD - * For functions not called in fast paths (aka. cold functions) - * - PRINTF_FMT - * For functions which take printf-style parameters. - * - IDEMPOTENT - * For functions which return the same value for same parameters. - * - NEEDED - * For functions and variables which must be emitted even if unused. - * - UNNEEDED - * For functions and variables which need not be emitted if unused. - * - UNUSED - * For parameters which are not used. - * - IS_COMPILE_CONSTANT - * For using different tradeoffs for compiletime vs runtime evaluation. - * - * License: LGPL (3 or any later version) - * Author: Rusty Russell - * - * Example: - * #include - * #include - * #include - * - * // Example of a (slow-path) logging function. - * static int log_threshold = 2; - * static void COLD PRINTF_FMT(2,3) - * logger(int level, const char *fmt, ...) - * { - * va_list ap; - * va_start(ap, fmt); - * if (level >= log_threshold) - * vfprintf(stderr, fmt, ap); - * va_end(ap); - * } - * - * int main(int argc, char *argv[]) - * { - * if (argc != 1) { - * logger(3, "Don't want %i arguments!\n", argc-1); - * return 1; - * } - * return 0; - * } - */ -int main(int argc, char *argv[]) -{ - /* Expect exactly one argument */ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - return 0; - } - - return 1; -} diff --git a/ccan/compiler/compiler.h b/ccan/compiler/compiler.h deleted file mode 100644 index 74e0f1835c..0000000000 --- a/ccan/compiler/compiler.h +++ /dev/null @@ -1,216 +0,0 @@ -#ifndef CCAN_COMPILER_H -#define CCAN_COMPILER_H -#include "config.h" - -#ifndef COLD -#if HAVE_ATTRIBUTE_COLD -/** - * COLD - a function is unlikely to be called. - * - * Used to mark an unlikely code path and optimize appropriately. - * It is usually used on logging or error routines. - * - * Example: - * static void COLD moan(const char *reason) - * { - * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno)); - * } - */ -#define COLD __attribute__((cold)) -#else -#define COLD -#endif -#endif - -#ifndef NORETURN -#if HAVE_ATTRIBUTE_NORETURN -/** - * NORETURN - a function does not return - * - * Used to mark a function which exits; useful for suppressing warnings. - * - * Example: - * static void NORETURN fail(const char *reason) - * { - * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno)); - * exit(1); - * } - */ -#define NORETURN __attribute__((noreturn)) -#else -#define NORETURN -#endif -#endif - -#ifndef PRINTF_FMT -#if HAVE_ATTRIBUTE_PRINTF -/** - * PRINTF_FMT - a function takes printf-style arguments - * @nfmt: the 1-based number of the function's format argument. - * @narg: the 1-based number of the function's first variable argument. - * - * This allows the compiler to check your parameters as it does for printf(). - * - * Example: - * void PRINTF_FMT(2,3) my_printf(const char *prefix, const char *fmt, ...); - */ -#define PRINTF_FMT(nfmt, narg) \ - __attribute__((format(__printf__, nfmt, narg))) -#else -#define PRINTF_FMT(nfmt, narg) -#endif -#endif - -#ifndef IDEMPOTENT -#if HAVE_ATTRIBUTE_CONST -/** - * IDEMPOTENT - a function's return depends only on its argument - * - * This allows the compiler to assume that the function will return the exact - * same value for the exact same arguments. This implies that the function - * must not use global variables, or dereference pointer arguments. - */ -#define IDEMPOTENT __attribute__((const)) -#else -#define IDEMPOTENT -#endif -#endif - -#if HAVE_ATTRIBUTE_UNUSED -#ifndef UNNEEDED -/** - * UNNEEDED - a variable/function may not be needed - * - * This suppresses warnings about unused variables or functions, but tells - * the compiler that if it is unused it need not emit it into the source code. - * - * Example: - * // With some preprocessor options, this is unnecessary. - * static UNNEEDED int counter; - * - * // With some preprocessor options, this is unnecessary. - * static UNNEEDED void add_to_counter(int add) - * { - * counter += add; - * } - */ -#define UNNEEDED __attribute__((unused)) -#endif - -#ifndef NEEDED -#if HAVE_ATTRIBUTE_USED -/** - * NEEDED - a variable/function is needed - * - * This suppresses warnings about unused variables or functions, but tells - * the compiler that it must exist even if it (seems) unused. - * - * Example: - * // Even if this is unused, these are vital for debugging. - * static NEEDED int counter; - * static NEEDED void dump_counter(void) - * { - * printf("Counter is %i\n", counter); - * } - */ -#define NEEDED __attribute__((used)) -#else -/* Before used, unused functions and vars were always emitted. */ -#define NEEDED __attribute__((unused)) -#endif -#endif - -#ifndef UNUSED -/** - * UNUSED - a parameter is unused - * - * Some compilers (eg. gcc with -W or -Wunused) warn about unused - * function parameters. This suppresses such warnings and indicates - * to the reader that it's deliberate. - * - * Example: - * // This is used as a callback, so needs to have this prototype. - * static int some_callback(void *unused UNUSED) - * { - * return 0; - * } - */ -#define UNUSED __attribute__((unused)) -#endif -#else -#ifndef UNNEEDED -#define UNNEEDED -#endif -#ifndef NEEDED -#define NEEDED -#endif -#ifndef UNUSED -#define UNUSED -#endif -#endif - -#ifndef IS_COMPILE_CONSTANT -#if HAVE_BUILTIN_CONSTANT_P -/** - * IS_COMPILE_CONSTANT - does the compiler know the value of this expression? - * @expr: the expression to evaluate - * - * When an expression manipulation is complicated, it is usually better to - * implement it in a function. However, if the expression being manipulated is - * known at compile time, it is better to have the compiler see the entire - * expression so it can simply substitute the result. - * - * This can be done using the IS_COMPILE_CONSTANT() macro. - * - * Example: - * enum greek { ALPHA, BETA, GAMMA, DELTA, EPSILON }; - * - * // Out-of-line version. - * const char *greek_name(enum greek greek); - * - * // Inline version. - * static inline const char *_greek_name(enum greek greek) - * { - * switch (greek) { - * case ALPHA: return "alpha"; - * case BETA: return "beta"; - * case GAMMA: return "gamma"; - * case DELTA: return "delta"; - * case EPSILON: return "epsilon"; - * default: return "**INVALID**"; - * } - * } - * - * // Use inline if compiler knows answer. Otherwise call function - * // to avoid copies of the same code everywhere. - * #define greek_name(g) \ - * (IS_COMPILE_CONSTANT(greek) ? _greek_name(g) : greek_name(g)) - */ -#define IS_COMPILE_CONSTANT(expr) __builtin_constant_p(expr) -#else -/* If we don't know, assume it's not. */ -#define IS_COMPILE_CONSTANT(expr) 0 -#endif -#endif - -#ifndef WARN_UNUSED_RESULT -#if HAVE_WARN_UNUSED_RESULT -/** - * WARN_UNUSED_RESULT - warn if a function return value is unused. - * - * Used to mark a function where it is extremely unlikely that the caller - * can ignore the result, eg realloc(). - * - * Example: - * // buf param may be freed by this; need return value! - * static char *WARN_UNUSED_RESULT enlarge(char *buf, unsigned *size) - * { - * return realloc(buf, (*size) *= 2); - * } - */ -#define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define WARN_UNUSED_RESULT -#endif -#endif -#endif /* CCAN_COMPILER_H */ diff --git a/ccan/compiler/test/compile_fail-printf.c b/ccan/compiler/test/compile_fail-printf.c deleted file mode 100644 index 8f34ae5a12..0000000000 --- a/ccan/compiler/test/compile_fail-printf.c +++ /dev/null @@ -1,22 +0,0 @@ -#include - -static void PRINTF_FMT(2,3) my_printf(int x, const char *fmt, ...) -{ -} - -int main(int argc, char *argv[]) -{ - unsigned int i = 0; - - my_printf(1, "Not a pointer " -#ifdef FAIL - "%p", -#if !HAVE_ATTRIBUTE_PRINTF -#error "Unfortunately we don't fail if !HAVE_ATTRIBUTE_PRINTF." -#endif -#else - "%i", -#endif - i); - return 0; -} diff --git a/ccan/compiler/test/run-is_compile_constant.c b/ccan/compiler/test/run-is_compile_constant.c deleted file mode 100644 index a66f2e13e6..0000000000 --- a/ccan/compiler/test/run-is_compile_constant.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -int main(int argc, char *argv[]) -{ - plan_tests(2); - - ok1(!IS_COMPILE_CONSTANT(argc)); -#if HAVE_BUILTIN_CONSTANT_P - ok1(IS_COMPILE_CONSTANT(7)); -#else - pass("If !HAVE_BUILTIN_CONSTANT_P, IS_COMPILE_CONSTANT always false"); -#endif - return exit_status(); -} diff --git a/ccan/opt/LICENSE b/ccan/opt/LICENSE deleted file mode 100644 index d511905c16..0000000000 --- a/ccan/opt/LICENSE +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/ccan/opt/_info b/ccan/opt/_info deleted file mode 100644 index 97b98f2960..0000000000 --- a/ccan/opt/_info +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include "config.h" - -/** - * opt - simple command line parsing - * - * Simple but powerful command line parsing. - * - * Example: - * #include - * #include - * #include - * - * static bool someflag; - * static int verbose; - * static char *somestring; - * - * static struct opt_table opts[] = { - * OPT_WITHOUT_ARG("--verbose|-v", opt_inc_intval, &verbose, - * "Verbose mode (can be specified more than once)"), - * OPT_WITHOUT_ARG("--someflag", opt_set_bool, &someflag, - * "Set someflag"), - * OPT_WITH_ARG("--somefile=", opt_set_charp, opt_show_charp, - * &somestring, "Set somefile to "), - * OPT_WITHOUT_ARG("--usage|--help|-h", opt_usage_and_exit, - * "args...\nA silly test program.", - * "Print this message."), - * OPT_ENDTABLE - * }; - * - * int main(int argc, char *argv[]) - * { - * int i; - * - * opt_register_table(opts, NULL); - * // For fun, register an extra one. - * opt_register_noarg("--no-someflag", opt_set_invbool, &someflag, - * "Unset someflag"); - * if (!opt_parse(&argc, argv, opt_log_stderr)) - * exit(1); - * - * printf("someflag = %i, verbose = %i, somestring = %s\n", - * someflag, verbose, somestring); - * printf("%u args left over:", argc - 1); - * for (i = 1; i < argc; i++) - * printf(" %s", argv[i]); - * printf("\n"); - * return 0; - * } - * - * License: GPL (2 or any later version) - * Author: Rusty Russell - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - printf("ccan/typesafe_cb\n"); - printf("ccan/compiler\n"); - return 0; - } - - return 1; -} diff --git a/ccan/opt/helpers.c b/ccan/opt/helpers.c deleted file mode 100644 index 8d0ac54794..0000000000 --- a/ccan/opt/helpers.c +++ /dev/null @@ -1,193 +0,0 @@ -#include -#include -#include -#include -#include -#include "private.h" - -/* Upper bound to sprintf this simple type? Each 3 bits < 1 digit. */ -#define CHAR_SIZE(type) (((sizeof(type)*CHAR_BIT + 2) / 3) + 1) - -/* FIXME: asprintf module? */ -static char *arg_bad(const char *fmt, const char *arg) -{ - char *str = malloc(strlen(fmt) + strlen(arg)); - sprintf(str, fmt, arg); - return str; -} - -char *opt_set_bool(bool *b) -{ - *b = true; - return NULL; -} - -char *opt_set_invbool(bool *b) -{ - *b = false; - return NULL; -} - -char *opt_set_bool_arg(const char *arg, bool *b) -{ - if (!strcasecmp(arg, "yes") || !strcasecmp(arg, "true")) - return opt_set_bool(b); - if (!strcasecmp(arg, "no") || !strcasecmp(arg, "false")) - return opt_set_invbool(b); - - return opt_invalid_argument(arg); -} - -char *opt_set_invbool_arg(const char *arg, bool *b) -{ - char *err = opt_set_bool_arg(arg, b); - - if (!err) - *b = !*b; - return err; -} - -/* Set a char *. */ -char *opt_set_charp(const char *arg, char **p) -{ - *p = (char *)arg; - return NULL; -} - -/* Set an integer value, various forms. Sets to 1 on arg == NULL. */ -char *opt_set_intval(const char *arg, int *i) -{ - long l; - char *err = opt_set_longval(arg, &l); - - if (err) - return err; - *i = l; - /* Beware truncation... */ - if (*i != l) - return arg_bad("value '%s' does not fit into an integer", arg); - return err; -} - -char *opt_set_floatval(const char *arg, float *f) -{ - char *endp; - - errno = 0; - *f = strtof(arg, &endp); - if (*endp || !arg[0]) - return arg_bad("'%s' is not a number", arg); - if (errno) - return arg_bad("'%s' is out of range", arg); - return NULL; -} - -char *opt_set_uintval(const char *arg, unsigned int *ui) -{ - int i; - char *err = opt_set_intval(arg, &i); - - if (err) - return err; - if (i < 0) - return arg_bad("'%s' is negative", arg); - *ui = i; - return NULL; -} - -char *opt_set_longval(const char *arg, long *l) -{ - char *endp; - - /* This is how the manpage says to do it. Yech. */ - errno = 0; - *l = strtol(arg, &endp, 0); - if (*endp || !arg[0]) - return arg_bad("'%s' is not a number", arg); - if (errno) - return arg_bad("'%s' is out of range", arg); - return NULL; -} - -char *opt_set_ulongval(const char *arg, unsigned long *ul) -{ - long int l; - char *err; - - err = opt_set_longval(arg, &l); - if (err) - return err; - *ul = l; - if (l < 0) - return arg_bad("'%s' is negative", arg); - return NULL; -} - -char *opt_inc_intval(int *i) -{ - (*i)++; - return NULL; -} - -/* Display version string. */ -char *opt_version_and_exit(const char *version) -{ - printf("%s\n", version); - fflush(stdout); - exit(0); -} - -char *opt_usage_and_exit(const char *extra) -{ - printf("%s", opt_usage(opt_argv0, extra)); - fflush(stdout); - exit(0); -} - -void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b) -{ - strncpy(buf, *b ? "true" : "false", OPT_SHOW_LEN); -} - -void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b) -{ - strncpy(buf, *b ? "false" : "true", OPT_SHOW_LEN); -} - -void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p) -{ - size_t len = strlen(*p); - buf[0] = '"'; - if (len > OPT_SHOW_LEN - 2) - len = OPT_SHOW_LEN - 2; - strncpy(buf+1, *p, len); - buf[1+len] = '"'; - if (len < OPT_SHOW_LEN - 2) - buf[2+len] = '\0'; -} - -/* Set an integer value, various forms. Sets to 1 on arg == NULL. */ -void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i) -{ - snprintf(buf, OPT_SHOW_LEN, "%i", *i); -} - -void opt_show_floatval(char buf[OPT_SHOW_LEN], const float *f) -{ - snprintf(buf, OPT_SHOW_LEN, "%.1f", *f); -} - -void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui) -{ - snprintf(buf, OPT_SHOW_LEN, "%u", *ui); -} - -void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l) -{ - snprintf(buf, OPT_SHOW_LEN, "%li", *l); -} - -void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul) -{ - snprintf(buf, OPT_SHOW_LEN, "%lu", *ul); -} diff --git a/ccan/opt/helpers.d b/ccan/opt/helpers.d deleted file mode 100644 index 669baaff5f..0000000000 --- a/ccan/opt/helpers.d +++ /dev/null @@ -1,24 +0,0 @@ -ccan/opt/helpers.o: ccan/opt/helpers.c ccan/opt/opt.h \ - ccan/compiler/compiler.h config.h ccan/typesafe_cb/typesafe_cb.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stdbool.h \ - /usr/include/stdlib.h /usr/include/features.h \ - /usr/include/bits/predefs.h /usr/include/sys/cdefs.h \ - /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \ - /usr/include/gnu/stubs-32.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stddef.h \ - /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \ - /usr/include/endian.h /usr/include/bits/endian.h \ - /usr/include/bits/byteswap.h /usr/include/xlocale.h \ - /usr/include/sys/types.h /usr/include/bits/types.h \ - /usr/include/bits/typesizes.h /usr/include/time.h \ - /usr/include/sys/select.h /usr/include/bits/select.h \ - /usr/include/bits/sigset.h /usr/include/bits/time.h \ - /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \ - /usr/include/alloca.h /usr/include/string.h /usr/include/errno.h \ - /usr/include/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/i386-linux-gnu/asm/errno.h /usr/include/asm-generic/errno.h \ - /usr/include/asm-generic/errno-base.h /usr/include/stdio.h \ - /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stdarg.h \ - /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \ - ccan/opt/private.h diff --git a/ccan/opt/helpers.o b/ccan/opt/helpers.o deleted file mode 100644 index 586212640e..0000000000 Binary files a/ccan/opt/helpers.o and /dev/null differ diff --git a/ccan/opt/opt.c b/ccan/opt/opt.c deleted file mode 100644 index 9bc34d92e9..0000000000 --- a/ccan/opt/opt.c +++ /dev/null @@ -1,255 +0,0 @@ -#include -#include -#include -#include -#include - -#ifndef WIN32 - #include -#else -#include - #define errx(status, fmt, ...) { \ - fprintf(stderr, fmt, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - exit(status); } -#endif - -#include -#include -#include -#include "private.h" - -struct opt_table *opt_table; -unsigned int opt_count, opt_num_short, opt_num_short_arg, opt_num_long; -const char *opt_argv0; - -/* Returns string after first '-'. */ -static const char *first_name(const char *names, unsigned *len) -{ - *len = strcspn(names + 1, "|= "); - return names + 1; -} - -static const char *next_name(const char *names, unsigned *len) -{ - names += *len; - if (names[0] == ' ' || names[0] == '=' || names[0] == '\0') - return NULL; - return first_name(names + 1, len); -} - -static const char *first_opt(unsigned *i, unsigned *len) -{ - for (*i = 0; *i < opt_count; (*i)++) { - if (opt_table[*i].type == OPT_SUBTABLE) - continue; - return first_name(opt_table[*i].names, len); - } - return NULL; -} - -static const char *next_opt(const char *p, unsigned *i, unsigned *len) -{ - for (; *i < opt_count; (*i)++) { - if (opt_table[*i].type == OPT_SUBTABLE) - continue; - if (!p) - return first_name(opt_table[*i].names, len); - p = next_name(p, len); - if (p) - return p; - } - return NULL; -} - -const char *first_lopt(unsigned *i, unsigned *len) -{ - const char *p; - for (p = first_opt(i, len); p; p = next_opt(p, i, len)) { - if (p[0] == '-') { - /* Skip leading "-" */ - (*len)--; - p++; - break; - } - } - return p; -} - -const char *next_lopt(const char *p, unsigned *i, unsigned *len) -{ - for (p = next_opt(p, i, len); p; p = next_opt(p, i, len)) { - if (p[0] == '-') { - /* Skip leading "-" */ - (*len)--; - p++; - break; - } - } - return p; -} - -const char *first_sopt(unsigned *i) -{ - const char *p; - unsigned int len = 0 /* GCC bogus warning */; - - for (p = first_opt(i, &len); p; p = next_opt(p, i, &len)) { - if (p[0] != '-') - break; - } - return p; -} - -const char *next_sopt(const char *p, unsigned *i) -{ - unsigned int len = 1; - for (p = next_opt(p, i, &len); p; p = next_opt(p, i, &len)) { - if (p[0] != '-') - break; - } - return p; -} - -static void check_opt(const struct opt_table *entry) -{ - const char *p; - unsigned len; - - if (entry->type != OPT_HASARG && entry->type != OPT_NOARG) - errx(1, "Option %s: unknown entry type %u", - entry->names, entry->type); - - if (!entry->desc) - errx(1, "Option %s: description cannot be NULL", entry->names); - - - if (entry->names[0] != '-') - errx(1, "Option %s: does not begin with '-'", entry->names); - - for (p = first_name(entry->names, &len); p; p = next_name(p, &len)) { - if (*p == '-') { - if (len == 1) - errx(1, "Option %s: invalid long option '--'", - entry->names); - opt_num_long++; - } else { - if (len != 1) - errx(1, "Option %s: invalid short option" - " '%.*s'", entry->names, len+1, p-1); - opt_num_short++; - if (entry->type == OPT_HASARG) - opt_num_short_arg++; - } - /* Don't document args unless there are some. */ - if (entry->type == OPT_NOARG) { - if (p[len] == ' ' || p[len] == '=') - errx(1, "Option %s: does not take arguments" - " '%s'", entry->names, p+len+1); - } - } -} - -static void add_opt(const struct opt_table *entry) -{ - opt_table = realloc(opt_table, sizeof(opt_table[0]) * (opt_count+1)); - opt_table[opt_count++] = *entry; -} - -void _opt_register(const char *names, enum opt_type type, - char *(*cb)(void *arg), - char *(*cb_arg)(const char *optarg, void *arg), - void (*show)(char buf[OPT_SHOW_LEN], const void *arg), - const void *arg, const char *desc) -{ - struct opt_table opt; - opt.names = names; - opt.type = type; - opt.cb = cb; - opt.cb_arg = cb_arg; - opt.show = show; - opt.u.carg = arg; - opt.desc = desc; - check_opt(&opt); - add_opt(&opt); -} - -void opt_register_table(const struct opt_table entry[], const char *desc) -{ - unsigned int i, start = opt_count; - - if (desc) { - struct opt_table heading = OPT_SUBTABLE(NULL, desc); - add_opt(&heading); - } - for (i = 0; entry[i].type != OPT_END; i++) { - if (entry[i].type == OPT_SUBTABLE) - opt_register_table(subtable_of(&entry[i]), - entry[i].desc); - else { - check_opt(&entry[i]); - add_opt(&entry[i]); - } - } - /* We store the table length in arg ptr. */ - if (desc) - opt_table[start].u.tlen = (opt_count - start); -} - -/* Parse your arguments. */ -bool opt_parse(int *argc, char *argv[], void (*errlog)(const char *fmt, ...)) -{ - int ret; - unsigned offset = 0; - - #ifdef WIN32 - char *original_argv0 = argv[0]; - argv[0] = (char*)basename(argv[0]); - #endif - - /* This helps opt_usage. */ - opt_argv0 = argv[0]; - - while ((ret = parse_one(argc, argv, &offset, errlog)) == 1); - - #ifdef WIN32 - argv[0] = original_argv0; - #endif - - /* parse_one returns 0 on finish, -1 on error */ - return (ret == 0); -} - -void opt_free_table(void) -{ - free(opt_table); - opt_table=0; -} - -void opt_log_stderr(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); -} - -void opt_log_stderr_exit(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - exit(1); -} - -char *opt_invalid_argument(const char *arg) -{ - char *str = malloc(sizeof("Invalid argument '%s'") + strlen(arg)); - sprintf(str, "Invalid argument '%s'", arg); - return str; -} diff --git a/ccan/opt/opt.d b/ccan/opt/opt.d deleted file mode 100644 index 7320564365..0000000000 --- a/ccan/opt/opt.d +++ /dev/null @@ -1,26 +0,0 @@ -ccan/opt/opt.o: ccan/opt/opt.c ccan/opt/opt.h ccan/compiler/compiler.h \ - config.h ccan/typesafe_cb/typesafe_cb.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stdbool.h \ - /usr/include/stdlib.h /usr/include/features.h \ - /usr/include/bits/predefs.h /usr/include/sys/cdefs.h \ - /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \ - /usr/include/gnu/stubs-32.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stddef.h \ - /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \ - /usr/include/endian.h /usr/include/bits/endian.h \ - /usr/include/bits/byteswap.h /usr/include/xlocale.h \ - /usr/include/sys/types.h /usr/include/bits/types.h \ - /usr/include/bits/typesizes.h /usr/include/time.h \ - /usr/include/sys/select.h /usr/include/bits/select.h \ - /usr/include/bits/sigset.h /usr/include/bits/time.h \ - /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \ - /usr/include/alloca.h /usr/include/string.h /usr/include/errno.h \ - /usr/include/bits/errno.h /usr/include/linux/errno.h \ - /usr/include/i386-linux-gnu/asm/errno.h /usr/include/asm-generic/errno.h \ - /usr/include/asm-generic/errno-base.h /usr/include/stdio.h \ - /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stdarg.h \ - /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \ - /usr/include/err.h /usr/include/assert.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stdint.h \ - /usr/include/stdint.h /usr/include/bits/wchar.h ccan/opt/private.h diff --git a/ccan/opt/opt.h b/ccan/opt/opt.h deleted file mode 100644 index 6fe2fb0ec0..0000000000 --- a/ccan/opt/opt.h +++ /dev/null @@ -1,347 +0,0 @@ -#ifndef CCAN_OPT_H -#define CCAN_OPT_H -#include -#include -#include -#include - -struct opt_table; - -/** - * OPT_WITHOUT_ARG() - macro for initializing an opt_table entry (without arg) - * @names: the names of the option eg. "--foo", "-f" or "--foo|-f|--foobar". - * @cb: the callback when the option is found. - * @arg: the argument to hand to @cb. - * @desc: the description for opt_usage(), or opt_hidden. - * - * This is a typesafe wrapper for initializing a struct opt_table. The callback - * of type "char *cb(type *)", "char *cb(const type *)" or "char *cb(void *)", - * where "type" is the type of the @arg argument. - * - * If the @cb returns non-NULL, opt_parse() will stop parsing, use the - * returned string to form an error message for errlog(), free() the - * string and return false. - * - * Any number of equivalent short or long options can be listed in @names, - * separated by '|'. Short options are a single hyphen followed by a single - * character, long options are two hyphens followed by one or more characters. - * - * See Also: - * OPT_WITH_ARG() - */ -#define OPT_WITHOUT_ARG(names, cb, arg, desc) \ - { (names), OPT_CB_NOARG((cb), (arg)), { (arg) }, (desc) } - -/** - * OPT_WITH_ARG() - macro for initializing long and short option (with arg) - * @names: the option names eg. "--foo=", "-f" or "-f|--foo ". - * @cb: the callback when the option is found (along with ). - * @show: the callback to print the value in get_usage (or NULL) - * @arg: the argument to hand to @cb and @show - * @desc: the description for opt_usage(), or opt_hidden. - * - * This is a typesafe wrapper for initializing a struct opt_table. The callback - * is of type "char *cb(const char *, type *)", - * "char *cb(const char *, const type *)" or "char *cb(const char *, void *)", - * where "type" is the type of the @arg argument. The first argument to the - * @cb is the argument found on the commandline. - * - * Similarly, if @show is not NULL, it should be of type "void *show(char *, - * const type *)". It should write up to OPT_SHOW_LEN bytes into the first - * argument; unless it uses the entire OPT_SHOW_LEN bytes it should - * nul-terminate that buffer. - * - * Any number of equivalent short or long options can be listed in @names, - * separated by '|'. Short options are a single hyphen followed by a single - * character, long options are two hyphens followed by one or more characters. - * A space or equals in @names is ignored for parsing, and only used - * for printing the usage. - * - * If the @cb returns non-NULL, opt_parse() will stop parsing, use the - * returned string to form an error message for errlog(), free() the - * string and return false. - * - * See Also: - * OPT_WITHOUT_ARG() - */ -#define OPT_WITH_ARG(name, cb, show, arg, desc) \ - { (name), OPT_CB_ARG((cb), (show), (arg)), { (arg) }, (desc) } - -/** - * OPT_SUBTABLE() - macro for including another table inside a table. - * @table: the table to include in this table. - * @desc: description of this subtable (for opt_usage()) or NULL. - */ -#define OPT_SUBTABLE(table, desc) \ - { (const char *)(table), OPT_SUBTABLE, \ - sizeof(_check_is_entry(table)) ? NULL : NULL, NULL, NULL, \ - { NULL }, (desc) } - -/** - * OPT_ENDTABLE - macro to create final entry in table. - * - * This must be the final element in the opt_table array. - */ -#define OPT_ENDTABLE { NULL, OPT_END, NULL, NULL, NULL, { NULL }, NULL } - -/** - * opt_register_table - register a table of options - * @table: the table of options - * @desc: description of this subtable (for opt_usage()) or NULL. - * - * The table must be terminated by OPT_ENDTABLE. - * - * Example: - * static int verbose = 0; - * static struct opt_table opts[] = { - * OPT_WITHOUT_ARG("--verbose", opt_inc_intval, &verbose, - * "Verbose mode (can be specified more than once)"), - * OPT_WITHOUT_ARG("-v", opt_inc_intval, &verbose, - * "Verbose mode (can be specified more than once)"), - * OPT_WITHOUT_ARG("--usage", opt_usage_and_exit, - * "args...\nA silly test program.", - * "Print this message."), - * OPT_ENDTABLE - * }; - * - * ... - * opt_register_table(opts, NULL); - */ -void opt_register_table(const struct opt_table *table, const char *desc); - -/** - * opt_register_noarg - register an option with no arguments - * @names: the names of the option eg. "--foo", "-f" or "--foo|-f|--foobar". - * @cb: the callback when the option is found. - * @arg: the argument to hand to @cb. - * @desc: the verbose description of the option (for opt_usage()), or NULL. - * - * This is used for registering a single commandline option which takes - * no argument. - * - * The callback is of type "char *cb(type *)", "char *cb(const type *)" - * or "char *cb(void *)", where "type" is the type of the @arg - * argument. - * - * If the @cb returns non-NULL, opt_parse() will stop parsing, use the - * returned string to form an error message for errlog(), free() the - * string and return false. - */ -#define opt_register_noarg(names, cb, arg, desc) \ - _opt_register((names), OPT_CB_NOARG((cb), (arg)), (arg), (desc)) - -/** - * opt_register_arg - register an option with an arguments - * @names: the names of the option eg. "--foo", "-f" or "--foo|-f|--foobar". - * @cb: the callback when the option is found. - * @show: the callback to print the value in get_usage (or NULL) - * @arg: the argument to hand to @cb. - * @desc: the verbose description of the option (for opt_usage()), or NULL. - * - * This is used for registering a single commandline option which takes - * an argument. - * - * The callback is of type "char *cb(const char *, type *)", - * "char *cb(const char *, const type *)" or "char *cb(const char *, void *)", - * where "type" is the type of the @arg argument. The first argument to the - * @cb is the argument found on the commandline. - * - * At least one of @longopt and @shortopt must be non-zero. If the - * @cb returns false, opt_parse() will stop parsing and return false. - * - * Example: - * static char *explode(const char *optarg, void *unused) - * { - * errx(1, "BOOM! %s", optarg); - * } - * ... - * opt_register_arg("--explode|--boom", explode, NULL, NULL, opt_hidden); - */ -#define opt_register_arg(names, cb, show, arg, desc) \ - _opt_register((names), OPT_CB_ARG((cb), (show), (arg)), (arg), (desc)) - -/** - * opt_parse - parse arguments. - * @argc: pointer to argc - * @argv: argv array. - * @errlog: the function to print errors - * - * This iterates through the command line and calls callbacks registered with - * opt_register_table()/opt_register_arg()/opt_register_noarg(). If there - * are unknown options, missing arguments or a callback returns false, then - * an error message is printed and false is returned. - * - * On success, argc and argv are adjusted so only the non-option elements - * remain, and true is returned. - * - * Example: - * if (!opt_parse(&argc, argv, opt_log_stderr)) { - * printf("You screwed up, aborting!\n"); - * exit(1); - * } - * - * See Also: - * opt_log_stderr, opt_log_stderr_exit - */ -bool opt_parse(int *argc, char *argv[], void (*errlog)(const char *fmt, ...)); - -/** - * opt_free_table - free the table. - * - * This frees the internal memory. Call this as the last - * opt function. - */ -void opt_free_table(void); - -/** - * opt_log_stderr - print message to stderr. - * @fmt: printf-style format. - * - * This is a helper for opt_parse, to print errors to stderr. - * - * See Also: - * opt_log_stderr_exit - */ -void opt_log_stderr(const char *fmt, ...); - -/** - * opt_log_stderr_exit - print message to stderr, then exit(1) - * @fmt: printf-style format. - * - * Just like opt_log_stderr, only then does exit(1). This means that - * when handed to opt_parse, opt_parse will never return false. - * - * Example: - * // This never returns false; just exits if there's an erorr. - * opt_parse(&argc, argv, opt_log_stderr_exit); - */ -void opt_log_stderr_exit(const char *fmt, ...); - -/** - * opt_invalid_argument - helper to allocate an "Invalid argument '%s'" string - * @arg: the argument which was invalid. - * - * This is a helper for callbacks to return a simple error string. - */ -char *opt_invalid_argument(const char *arg); - -/** - * opt_usage - create usage message - * @argv0: the program name - * @extra: extra details to print after the initial command, or NULL. - * - * Creates a usage message, with the program name, arguments, some extra details - * and a table of all the options with their descriptions. If an option has - * description opt_hidden, it is not shown here. - * - * If "extra" is NULL, then the extra information is taken from any - * registered option which calls opt_usage_and_exit(). This avoids duplicating - * that string in the common case. - * - * The result should be passed to free(). - */ -char *opt_usage(const char *argv0, const char *extra); - -/** - * opt_hidden - string for undocumented options. - * - * This can be used as the desc parameter if you want an option not to be - * shown by opt_usage(). - */ -extern const char opt_hidden[]; - -/* Maximum length of arg to show in opt_usage */ -#define OPT_SHOW_LEN 80 - -/* Standard helpers. You can write your own: */ -/* Sets the @b to true. */ -char *opt_set_bool(bool *b); -/* Sets @b based on arg: (yes/no/true/false). */ -char *opt_set_bool_arg(const char *arg, bool *b); -void opt_show_bool(char buf[OPT_SHOW_LEN], const bool *b); -/* The inverse */ -char *opt_set_invbool(bool *b); -void opt_show_invbool(char buf[OPT_SHOW_LEN], const bool *b); -/* Sets @b based on !arg: (yes/no/true/false). */ -char *opt_set_invbool_arg(const char *arg, bool *b); - -/* Set a char *. */ -char *opt_set_charp(const char *arg, char **p); -void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p); - -/* Set an integer value, various forms. Sets to 1 on arg == NULL. */ -char *opt_set_intval(const char *arg, int *i); -void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i); -char *opt_set_floatval(const char *arg, float *f); -void opt_show_floatval(char buf[OPT_SHOW_LEN], const float *f); -char *opt_set_uintval(const char *arg, unsigned int *ui); -void opt_show_uintval(char buf[OPT_SHOW_LEN], const unsigned int *ui); -char *opt_set_longval(const char *arg, long *l); -void opt_show_longval(char buf[OPT_SHOW_LEN], const long *l); -char *opt_set_ulongval(const char *arg, unsigned long *ul); -void opt_show_ulongval(char buf[OPT_SHOW_LEN], const unsigned long *ul); - -/* Increment. */ -char *opt_inc_intval(int *i); - -/* Display version string to stdout, exit(0). */ -char *opt_version_and_exit(const char *version); - -/* Display usage string to stdout, exit(0). */ -char *opt_usage_and_exit(const char *extra); - -/* Below here are private declarations. */ -/* You can use this directly to build tables, but the macros will ensure - * consistency and type safety. */ -enum opt_type { - OPT_NOARG = 1, /* -f|--foo */ - OPT_HASARG = 2, /* -f arg|--foo=arg|--foo arg */ - OPT_SUBTABLE = 4, /* Actually, longopt points to a subtable... */ - OPT_END = 8, /* End of the table. */ -}; - -struct opt_table { - const char *names; /* pipe-separated names, --longopt or -s */ - enum opt_type type; - char *(*cb)(void *arg); /* OPT_NOARG */ - char *(*cb_arg)(const char *optarg, void *arg); /* OPT_HASARG */ - void (*show)(char buf[OPT_SHOW_LEN], const void *arg); - union { - const void *carg; - void *arg; - size_t tlen; - } u; - const char *desc; -}; - -/* Resolves to the four parameters for non-arg callbacks. */ -#define OPT_CB_NOARG(cb, arg) \ - OPT_NOARG, \ - typesafe_cb_cast3(char *(*)(void *), \ - char *(*)(typeof(*(arg))*), \ - char *(*)(const typeof(*(arg))*), \ - char *(*)(const void *), (cb)), \ - NULL, NULL - -/* Resolves to the four parameters for arg callbacks. */ -#define OPT_CB_ARG(cb, show, arg) \ - OPT_HASARG, NULL, \ - typesafe_cb_cast3(char *(*)(const char *,void *), \ - char *(*)(const char *, typeof(*(arg))*), \ - char *(*)(const char *, const typeof(*(arg))*), \ - char *(*)(const char *, const void *), \ - (cb)), \ - typesafe_cb_cast(void (*)(char buf[], const void *), \ - void (*)(char buf[], const typeof(*(arg))*), (show)) - -/* Non-typesafe register function. */ -void _opt_register(const char *names, enum opt_type type, - char *(*cb)(void *arg), - char *(*cb_arg)(const char *optarg, void *arg), - void (*show)(char buf[OPT_SHOW_LEN], const void *arg), - const void *arg, const char *desc); - -/* We use this to get typechecking for OPT_SUBTABLE */ -static inline int _check_is_entry(struct opt_table *e UNUSED) { return 0; } - -#endif /* CCAN_OPT_H */ diff --git a/ccan/opt/opt.o b/ccan/opt/opt.o deleted file mode 100644 index f57d5914b0..0000000000 Binary files a/ccan/opt/opt.o and /dev/null differ diff --git a/ccan/opt/parse.c b/ccan/opt/parse.c deleted file mode 100644 index 7b7c02c593..0000000000 --- a/ccan/opt/parse.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Actual code to parse commandline. */ -#include -#include -#include -#include -#include "private.h" - -/* glibc does this as: -/tmp/opt-example: invalid option -- 'x' -/tmp/opt-example: unrecognized option '--long' -/tmp/opt-example: option '--someflag' doesn't allow an argument -/tmp/opt-example: option '--s' is ambiguous -/tmp/opt-example: option requires an argument -- 's' -*/ -static int parse_err(void (*errlog)(const char *fmt, ...), - const char *argv0, const char *arg, unsigned len, - const char *problem) -{ - errlog("%s: %.*s: %s", argv0, len, arg, problem); - return -1; -} - -static void consume_option(int *argc, char *argv[], unsigned optnum) -{ - memmove(&argv[optnum], &argv[optnum+1], - sizeof(argv[optnum]) * (*argc-optnum)); - (*argc)--; -} - -/* Returns 1 if argument consumed, 0 if all done, -1 on error. */ -int parse_one(int *argc, char *argv[], unsigned *offset, - void (*errlog)(const char *fmt, ...)) -{ - unsigned i, arg, len; - const char *o, *optarg = NULL; - char *problem; - - if (getenv("POSIXLY_CORRECT")) { - /* Don't find options after non-options. */ - arg = 1; - } else { - for (arg = 1; argv[arg]; arg++) { - if (argv[arg][0] == '-') - break; - } - } - - if (!argv[arg] || argv[arg][0] != '-') - return 0; - - /* Special arg terminator option. */ - if (strcmp(argv[arg], "--") == 0) { - consume_option(argc, argv, arg); - return 0; - } - - /* Long options start with -- */ - if (argv[arg][1] == '-') { - assert(*offset == 0); - for (o = first_lopt(&i, &len); o; o = next_lopt(o, &i, &len)) { - if (strncmp(argv[arg] + 2, o, len) != 0) - continue; - if (argv[arg][2 + len] == '=') - optarg = argv[arg] + 2 + len + 1; - else if (argv[arg][2 + len] != '\0') - continue; - break; - } - if (!o) - return parse_err(errlog, argv[0], - argv[arg], strlen(argv[arg]), - "unrecognized option"); - /* For error messages, we include the leading '--' */ - o -= 2; - len += 2; - } else { - /* offset allows us to handle -abc */ - for (o = first_sopt(&i); o; o = next_sopt(o, &i)) { - if (argv[arg][*offset + 1] != *o) - continue; - (*offset)++; - break; - } - if (!o) - return parse_err(errlog, argv[0], - argv[arg], strlen(argv[arg]), - "unrecognized option"); - /* For error messages, we include the leading '-' */ - o--; - len = 2; - } - - if (opt_table[i].type == OPT_NOARG) { - if (optarg) - return parse_err(errlog, argv[0], o, len, - "doesn't allow an argument"); - problem = opt_table[i].cb(opt_table[i].u.arg); - } else { - if (!optarg) { - /* Swallow any short options as optarg, eg -afile */ - if (*offset && argv[arg][*offset + 1]) { - optarg = argv[arg] + *offset + 1; - *offset = 0; - } else - optarg = argv[arg+1]; - } - if (!optarg) - return parse_err(errlog, argv[0], o, len, - "requires an argument"); - problem = opt_table[i].cb_arg(optarg, opt_table[i].u.arg); - } - - if (problem) { - parse_err(errlog, argv[0], o, len, problem); - free(problem); - return -1; - } - - /* If no more letters in that short opt, reset offset. */ - if (*offset && !argv[arg][*offset + 1]) - *offset = 0; - - /* All finished with that option? */ - if (*offset == 0) { - consume_option(argc, argv, arg); - if (optarg && optarg == argv[arg]) - consume_option(argc, argv, arg); - } - return 1; -} diff --git a/ccan/opt/parse.d b/ccan/opt/parse.d deleted file mode 100644 index 016ba9e07d..0000000000 --- a/ccan/opt/parse.d +++ /dev/null @@ -1,18 +0,0 @@ -ccan/opt/parse.o: ccan/opt/parse.c ccan/opt/opt.h \ - ccan/compiler/compiler.h config.h ccan/typesafe_cb/typesafe_cb.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stdbool.h \ - /usr/include/stdlib.h /usr/include/features.h \ - /usr/include/bits/predefs.h /usr/include/sys/cdefs.h \ - /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \ - /usr/include/gnu/stubs-32.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stddef.h \ - /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \ - /usr/include/endian.h /usr/include/bits/endian.h \ - /usr/include/bits/byteswap.h /usr/include/xlocale.h \ - /usr/include/sys/types.h /usr/include/bits/types.h \ - /usr/include/bits/typesizes.h /usr/include/time.h \ - /usr/include/sys/select.h /usr/include/bits/select.h \ - /usr/include/bits/sigset.h /usr/include/bits/time.h \ - /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \ - /usr/include/alloca.h /usr/include/string.h /usr/include/assert.h \ - ccan/opt/private.h diff --git a/ccan/opt/parse.o b/ccan/opt/parse.o deleted file mode 100644 index ef7ac29dad..0000000000 Binary files a/ccan/opt/parse.o and /dev/null differ diff --git a/ccan/opt/private.h b/ccan/opt/private.h deleted file mode 100644 index 048951e90c..0000000000 --- a/ccan/opt/private.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CCAN_OPT_PRIVATE_H -#define CCAN_OPT_PRIVATE_H - -extern struct opt_table *opt_table; -extern unsigned int opt_count, opt_num_short, opt_num_short_arg, opt_num_long; - -extern const char *opt_argv0; - -#define subtable_of(entry) ((struct opt_table *)((entry)->names)) - -const char *first_sopt(unsigned *i); -const char *next_sopt(const char *names, unsigned *i); -const char *first_lopt(unsigned *i, unsigned *len); -const char *next_lopt(const char *p, unsigned *i, unsigned *len); - -int parse_one(int *argc, char *argv[], unsigned *offset, - void (*errlog)(const char *fmt, ...)); - -#endif /* CCAN_OPT_PRIVATE_H */ diff --git a/ccan/opt/test/compile_ok-const-arg.c b/ccan/opt/test/compile_ok-const-arg.c deleted file mode 100644 index f1d10da106..0000000000 --- a/ccan/opt/test/compile_ok-const-arg.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -#include -#include -#include - -int main(int argc, char *argv[]) -{ - opt_register_noarg("-v", opt_version_and_exit, - (const char *)"1.2.3", - (const char *)"Print version"); - return 0; -} diff --git a/ccan/opt/test/run-checkopt.c b/ccan/opt/test/run-checkopt.c deleted file mode 100644 index 71ee3c41dc..0000000000 --- a/ccan/opt/test/run-checkopt.c +++ /dev/null @@ -1,144 +0,0 @@ -#include "config.h" -#include -#include -#include -#include -#include -#include -#include "utils.h" - -/* We don't actually want it to exit... */ -static jmp_buf exited; -#define errx save_and_jump - -static void save_and_jump(int ecode, const char *fmt, ...); - -#include -#include -#include -#include - -static char *output = NULL; - -static int saved_vprintf(const char *fmt, va_list ap) -{ - char *p; - int ret = vasprintf(&p, fmt, ap); - - if (output) { - output = realloc(output, strlen(output) + strlen(p) + 1); - strcat(output, p); - free(p); - } else - output = p; - return ret; -} - -static void save_and_jump(int ecode, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - saved_vprintf(fmt, ap); - va_end(ap); - longjmp(exited, ecode + 1); -} - -static void reset(void) -{ - free(output); - output = NULL; - free(opt_table); - opt_table = NULL; - opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0; -} - -int main(int argc, char *argv[]) -{ - int exitval; - - plan_tests(14); - - exitval = setjmp(exited); - if (exitval == 0) { - /* Bad type. */ - _opt_register("-a", OPT_SUBTABLE, (void *)opt_version_and_exit, - NULL, NULL, "1.2.3", ""); - fail("_opt_register returned?"); - } else { - ok1(exitval - 1 == 1); - ok1(strstr(output, "Option -a: unknown entry type")); - } - reset(); - - exitval = setjmp(exited); - if (exitval == 0) { - /* NULL description. */ - opt_register_noarg("-a", test_noarg, "", NULL); - fail("_opt_register returned?"); - } else { - ok1(exitval - 1 == 1); - ok1(strstr(output, "Option -a: description cannot be NULL")); - } - reset(); - - exitval = setjmp(exited); - if (exitval == 0) { - /* Bad option name. */ - opt_register_noarg("a", test_noarg, "", ""); - fail("_opt_register returned?"); - } else { - ok1(exitval - 1 == 1); - ok1(strstr(output, "Option a: does not begin with '-'")); - } - - reset(); - - exitval = setjmp(exited); - if (exitval == 0) { - /* Bad option name. */ - opt_register_noarg("--", test_noarg, "", ""); - fail("_opt_register returned?"); - } else { - ok1(exitval - 1 == 1); - ok1(strstr(output, "Option --: invalid long option '--'")); - } - - reset(); - - exitval = setjmp(exited); - if (exitval == 0) { - /* Bad option name. */ - opt_register_noarg("--a|-aaa", test_noarg, "", ""); - fail("_opt_register returned?"); - } else { - ok1(exitval - 1 == 1); - ok1(strstr(output, - "Option --a|-aaa: invalid short option '-aaa'")); - } - reset(); - - exitval = setjmp(exited); - if (exitval == 0) { - /* Documentation for non-optios. */ - opt_register_noarg("--a foo", test_noarg, "", ""); - fail("_opt_register returned?"); - } else { - ok1(exitval - 1 == 1); - ok1(strstr(output, - "Option --a foo: does not take arguments 'foo'")); - } - reset(); - - exitval = setjmp(exited); - if (exitval == 0) { - /* Documentation for non-optios. */ - opt_register_noarg("--a=foo", test_noarg, "", ""); - fail("_opt_register returned?"); - } else { - ok1(exitval - 1 == 1); - ok1(strstr(output, - "Option --a=foo: does not take arguments 'foo'")); - } - return exit_status(); -} diff --git a/ccan/opt/test/run-correct-reporting.c b/ccan/opt/test/run-correct-reporting.c deleted file mode 100644 index 8534f291ac..0000000000 --- a/ccan/opt/test/run-correct-reporting.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Make sure when multiple equivalent options, correct one is used for errors */ - -#include -#include -#include -#include -#include -#include -#include "utils.h" - -int main(int argc, char *argv[]) -{ - plan_tests(12); - - /* --aaa without args. */ - opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", ""); - ok1(!parse_args(&argc, &argv, "--aaa", NULL)); - ok1(strstr(err_output, ": --aaa: requires an argument")); - free(err_output); - err_output = NULL; - ok1(!parse_args(&argc, &argv, "-a", NULL)); - ok1(strstr(err_output, ": -a: requires an argument")); - free(err_output); - err_output = NULL; - - /* Multiple */ - opt_register_arg("--bbb|-b|-c|--ccc", test_arg, NULL, "aaa", ""); - ok1(!parse_args(&argc, &argv, "--bbb", NULL)); - ok1(strstr(err_output, ": --bbb: requires an argument")); - free(err_output); - err_output = NULL; - ok1(!parse_args(&argc, &argv, "-b", NULL)); - ok1(strstr(err_output, ": -b: requires an argument")); - free(err_output); - err_output = NULL; - ok1(!parse_args(&argc, &argv, "-c", NULL)); - ok1(strstr(err_output, ": -c: requires an argument")); - free(err_output); - err_output = NULL; - ok1(!parse_args(&argc, &argv, "--ccc", NULL)); - ok1(strstr(err_output, ": --ccc: requires an argument")); - free(err_output); - err_output = NULL; - - /* parse_args allocates argv */ - free(argv); - return exit_status(); -} - diff --git a/ccan/opt/test/run-helpers.c b/ccan/opt/test/run-helpers.c deleted file mode 100644 index a58e4d9179..0000000000 --- a/ccan/opt/test/run-helpers.c +++ /dev/null @@ -1,440 +0,0 @@ -#include "config.h" -#include -#include -#include -#include -#include -#include "utils.h" - -/* We don't actually want it to exit... */ -static jmp_buf exited; -#define exit(status) longjmp(exited, (status) + 1) - -#define printf saved_printf -static int saved_printf(const char *fmt, ...); - -#define fprintf saved_fprintf -static int saved_fprintf(FILE *ignored, const char *fmt, ...); - -#define vfprintf(f, fmt, ap) saved_vprintf(fmt, ap) -static int saved_vprintf(const char *fmt, va_list ap); - -#define malloc(size) saved_malloc(size) -static void *saved_malloc(size_t size); - -#include -#include -#include -#include - -static void reset_options(void) -{ - free(opt_table); - opt_table = NULL; - opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0; -} - -static char *output = NULL; - -static int saved_vprintf(const char *fmt, va_list ap) -{ - char *p; - int ret = vasprintf(&p, fmt, ap); - - if (output) { - output = realloc(output, strlen(output) + strlen(p) + 1); - strcat(output, p); - free(p); - } else - output = p; - return ret; -} - -static int saved_printf(const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = saved_vprintf(fmt, ap); - va_end(ap); - return ret; -} - -static int saved_fprintf(FILE *ignored, const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = saved_vprintf(fmt, ap); - va_end(ap); - return ret; -} - -#undef malloc -static void *last_allocation; -static void *saved_malloc(size_t size) -{ - return last_allocation = malloc(size); -} - -/* Test helpers. */ -int main(int argc, char *argv[]) -{ - plan_tests(100); - - /* opt_set_bool */ - { - bool arg = false; - reset_options(); - opt_register_noarg("-a", opt_set_bool, &arg, ""); - ok1(parse_args(&argc, &argv, "-a", NULL)); - ok1(arg); - opt_register_arg("-b", opt_set_bool_arg, NULL, &arg, ""); - ok1(parse_args(&argc, &argv, "-b", "no", NULL)); - ok1(!arg); - ok1(parse_args(&argc, &argv, "-b", "yes", NULL)); - ok1(arg); - ok1(parse_args(&argc, &argv, "-b", "false", NULL)); - ok1(!arg); - ok1(parse_args(&argc, &argv, "-b", "true", NULL)); - ok1(arg); - ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL)); - ok1(arg); - ok1(strstr(err_output, ": -b: Invalid argument 'unknown'")); - } - /* opt_set_invbool */ - { - bool arg = true; - reset_options(); - opt_register_noarg("-a", opt_set_invbool, &arg, ""); - ok1(parse_args(&argc, &argv, "-a", NULL)); - ok1(!arg); - opt_register_arg("-b", opt_set_invbool_arg, NULL, - &arg, ""); - ok1(parse_args(&argc, &argv, "-b", "no", NULL)); - ok1(arg); - ok1(parse_args(&argc, &argv, "-b", "yes", NULL)); - ok1(!arg); - ok1(parse_args(&argc, &argv, "-b", "false", NULL)); - ok1(arg); - ok1(parse_args(&argc, &argv, "-b", "true", NULL)); - ok1(!arg); - ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL)); - ok1(!arg); - ok1(strstr(err_output, ": -b: Invalid argument 'unknown'")); - } - /* opt_set_charp */ - { - char *arg = (char *)"wrong"; - reset_options(); - opt_register_arg("-a", opt_set_charp, NULL, &arg, "All"); - ok1(parse_args(&argc, &argv, "-a", "string", NULL)); - ok1(strcmp(arg, "string") == 0); - } - /* opt_set_intval */ - { - int arg = 1000; - reset_options(); - opt_register_arg("-a", opt_set_intval, NULL, &arg, "All"); - ok1(parse_args(&argc, &argv, "-a", "9999", NULL)); - ok1(arg == 9999); - ok1(parse_args(&argc, &argv, "-a", "-9999", NULL)); - ok1(arg == -9999); - ok1(parse_args(&argc, &argv, "-a", "0", NULL)); - ok1(arg == 0); - ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL)); - if (sizeof(int) == 4) - ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL)); - else - fail("Handle other int sizes"); - } - /* opt_set_uintval */ - { - unsigned int arg = 1000; - reset_options(); - opt_register_arg("-a", opt_set_uintval, NULL, &arg, "All"); - ok1(parse_args(&argc, &argv, "-a", "9999", NULL)); - ok1(arg == 9999); - ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL)); - ok1(parse_args(&argc, &argv, "-a", "0", NULL)); - ok1(arg == 0); - ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL)); - ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL)); - if (ULONG_MAX == UINT_MAX) { - pass("Can't test overflow"); - pass("Can't test error message"); - } else { - char buf[30]; - sprintf(buf, "%lu", ULONG_MAX); - ok1(!parse_args(&argc, &argv, "-a", buf, NULL)); - ok1(strstr(err_output, ": -a: value '") - && strstr(err_output, buf) - && strstr(err_output, "' does not fit into an integer")); - } - } - /* opt_set_longval */ - { - long int arg = 1000; - reset_options(); - opt_register_arg("-a", opt_set_longval, NULL, &arg, "All"); - ok1(parse_args(&argc, &argv, "-a", "9999", NULL)); - ok1(arg == 9999); - ok1(parse_args(&argc, &argv, "-a", "-9999", NULL)); - ok1(arg == -9999); - ok1(parse_args(&argc, &argv, "-a", "0", NULL)); - ok1(arg == 0); - ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL)); - if (sizeof(long) == 4) - ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL)); - else if (sizeof(long)== 8) - ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL)); - else - fail("FIXME: Handle other long sizes"); - } - /* opt_set_ulongval */ - { - unsigned long int arg = 1000; - reset_options(); - opt_register_arg("-a", opt_set_ulongval, NULL, &arg, "All"); - ok1(parse_args(&argc, &argv, "-a", "9999", NULL)); - ok1(arg == 9999); - ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL)); - ok1(parse_args(&argc, &argv, "-a", "0", NULL)); - ok1(arg == 0); - ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL)); - if (sizeof(long) == 4) - ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL)); - else if (sizeof(long)== 8) - ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL)); - else - fail("FIXME: Handle other long sizes"); - } - /* opt_inc_intval */ - { - int arg = 1000; - reset_options(); - opt_register_noarg("-a", opt_inc_intval, &arg, ""); - ok1(parse_args(&argc, &argv, "-a", NULL)); - ok1(arg == 1001); - ok1(parse_args(&argc, &argv, "-a", "-a", NULL)); - ok1(arg == 1003); - ok1(parse_args(&argc, &argv, "-aa", NULL)); - ok1(arg == 1005); - } - - /* opt_show_version_and_exit. */ - { - int exitval; - reset_options(); - opt_register_noarg("-a", - opt_version_and_exit, "1.2.3", ""); - /* parse_args allocates argv */ - free(argv); - - argc = 2; - argv = malloc(sizeof(argv[0]) * 3); - argv[0] = "thisprog"; - argv[1] = "-a"; - argv[2] = NULL; - - exitval = setjmp(exited); - if (exitval == 0) { - opt_parse(&argc, argv, save_err_output); - fail("opt_show_version_and_exit returned?"); - } else { - ok1(exitval - 1 == 0); - } - ok1(strcmp(output, "1.2.3\n") == 0); - free(output); - free(argv); - output = NULL; - } - - /* opt_usage_and_exit. */ - { - int exitval; - reset_options(); - opt_register_noarg("-a", - opt_usage_and_exit, "[args]", ""); - - argc = 2; - argv = malloc(sizeof(argv[0]) * 3); - argv[0] = "thisprog"; - argv[1] = "-a"; - argv[2] = NULL; - - exitval = setjmp(exited); - if (exitval == 0) { - opt_parse(&argc, argv, save_err_output); - fail("opt_usage_and_exit returned?"); - } else { - ok1(exitval - 1 == 0); - } - ok1(strstr(output, "[args]")); - ok1(strstr(output, argv[0])); - ok1(strstr(output, "[-a]")); - free(output); - free(argv); - /* It exits without freeing usage string. */ - free(last_allocation); - output = NULL; - } - - /* opt_show_bool */ - { - bool b; - char buf[OPT_SHOW_LEN+2] = { 0 }; - buf[OPT_SHOW_LEN] = '!'; - - b = true; - opt_show_bool(buf, &b); - ok1(strcmp(buf, "true") == 0); - ok1(buf[OPT_SHOW_LEN] == '!'); - - b = false; - opt_show_bool(buf, &b); - ok1(strcmp(buf, "false") == 0); - ok1(buf[OPT_SHOW_LEN] == '!'); - } - - /* opt_show_invbool */ - { - bool b; - char buf[OPT_SHOW_LEN+2] = { 0 }; - buf[OPT_SHOW_LEN] = '!'; - - b = true; - opt_show_invbool(buf, &b); - ok1(strcmp(buf, "false") == 0); - ok1(buf[OPT_SHOW_LEN] == '!'); - - b = false; - opt_show_invbool(buf, &b); - ok1(strcmp(buf, "true") == 0); - ok1(buf[OPT_SHOW_LEN] == '!'); - } - - /* opt_show_charp */ - { - char str[OPT_SHOW_LEN*2], *p; - char buf[OPT_SHOW_LEN+2] = { 0 }; - buf[OPT_SHOW_LEN] = '!'; - - /* Short test. */ - p = str; - strcpy(p, "short"); - opt_show_charp(buf, &p); - ok1(strcmp(buf, "\"short\"") == 0); - ok1(buf[OPT_SHOW_LEN] == '!'); - - /* Truncate test. */ - memset(p, 'x', OPT_SHOW_LEN*2); - p[OPT_SHOW_LEN*2-1] = '\0'; - opt_show_charp(buf, &p); - ok1(buf[0] == '"'); - ok1(buf[OPT_SHOW_LEN-1] == '"'); - ok1(buf[OPT_SHOW_LEN] == '!'); - ok1(strspn(buf+1, "x") == OPT_SHOW_LEN-2); - } - - /* opt_show_intval */ - { - int i; - char buf[OPT_SHOW_LEN+2] = { 0 }; - buf[OPT_SHOW_LEN] = '!'; - - i = -77; - opt_show_intval(buf, &i); - ok1(strcmp(buf, "-77") == 0); - ok1(buf[OPT_SHOW_LEN] == '!'); - - i = 77; - opt_show_intval(buf, &i); - ok1(strcmp(buf, "77") == 0); - ok1(buf[OPT_SHOW_LEN] == '!'); - } - - /* opt_show_uintval */ - { - unsigned int ui; - char buf[OPT_SHOW_LEN+2] = { 0 }; - buf[OPT_SHOW_LEN] = '!'; - - ui = 4294967295U; - opt_show_uintval(buf, &ui); - ok1(strcmp(buf, "4294967295") == 0); - ok1(buf[OPT_SHOW_LEN] == '!'); - } - - /* opt_show_longval */ - { - long l; - char buf[OPT_SHOW_LEN+2] = { 0 }; - buf[OPT_SHOW_LEN] = '!'; - - l = 1234567890L; - opt_show_longval(buf, &l); - ok1(strcmp(buf, "1234567890") == 0); - ok1(buf[OPT_SHOW_LEN] == '!'); - } - - /* opt_show_ulongval */ - { - unsigned long ul; - char buf[OPT_SHOW_LEN+2] = { 0 }; - buf[OPT_SHOW_LEN] = '!'; - - ul = 4294967295UL; - opt_show_ulongval(buf, &ul); - ok1(strcmp(buf, "4294967295") == 0); - ok1(buf[OPT_SHOW_LEN] == '!'); - } - - /* opt_log_stderr. */ - { - reset_options(); - opt_register_noarg("-a", - opt_usage_and_exit, "[args]", ""); - - argc = 2; - argv = malloc(sizeof(argv[0]) * 3); - argv[0] = "thisprog"; - argv[1] = "--garbage"; - argv[2] = NULL; - ok1(!opt_parse(&argc, argv, opt_log_stderr)); - ok1(!strcmp(output, - "thisprog: --garbage: unrecognized option\n")); - free(output); - free(argv); - output = NULL; - } - - /* opt_log_stderr_exit. */ - { - int exitval; - reset_options(); - opt_register_noarg("-a", - opt_usage_and_exit, "[args]", ""); - argc = 2; - argv = malloc(sizeof(argv[0]) * 3); - argv[0] = "thisprog"; - argv[1] = "--garbage"; - argv[2] = NULL; - exitval = setjmp(exited); - if (exitval == 0) { - opt_parse(&argc, argv, opt_log_stderr_exit); - fail("opt_log_stderr_exit returned?"); - } else { - ok1(exitval - 1 == 1); - } - free(argv); - ok1(!strcmp(output, - "thisprog: --garbage: unrecognized option\n")); - free(output); - output = NULL; - } - - return exit_status(); -} diff --git a/ccan/opt/test/run-iter.c b/ccan/opt/test/run-iter.c deleted file mode 100644 index 66fd5db8b0..0000000000 --- a/ccan/opt/test/run-iter.c +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include -#include -#include -#include -#include "utils.h" -#include -#include -#include -#include - -static void reset_options(void) -{ - free(opt_table); - opt_table = NULL; - opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0; -} - -/* Test iterators. */ -int main(int argc, char *argv[]) -{ - unsigned j, i, len = 0; - const char *p; - - plan_tests(37 * 2); - for (j = 0; j < 2; j ++) { - reset_options(); - /* Giving subtable a title makes an extra entry! */ - opt_register_table(subtables, j == 0 ? NULL : "subtable"); - - p = first_lopt(&i, &len); - ok1(i == j + 0); - ok1(len == 3); - ok1(strncmp(p, "jjj", len) == 0); - p = next_lopt(p, &i, &len); - ok1(i == j + 0); - ok1(len == 3); - ok1(strncmp(p, "lll", len) == 0); - p = next_lopt(p, &i, &len); - ok1(i == j + 1); - ok1(len == 3); - ok1(strncmp(p, "mmm", len) == 0); - p = next_lopt(p, &i, &len); - ok1(i == j + 5); - ok1(len == 3); - ok1(strncmp(p, "ddd", len) == 0); - p = next_lopt(p, &i, &len); - ok1(i == j + 6); - ok1(len == 3); - ok1(strncmp(p, "eee", len) == 0); - p = next_lopt(p, &i, &len); - ok1(i == j + 7); - ok1(len == 3); - ok1(strncmp(p, "ggg", len) == 0); - p = next_lopt(p, &i, &len); - ok1(i == j + 8); - ok1(len == 3); - ok1(strncmp(p, "hhh", len) == 0); - p = next_lopt(p, &i, &len); - ok1(!p); - - p = first_sopt(&i); - ok1(i == j + 0); - ok1(*p == 'j'); - p = next_sopt(p, &i); - ok1(i == j + 0); - ok1(*p == 'l'); - p = next_sopt(p, &i); - ok1(i == j + 1); - ok1(*p == 'm'); - p = next_sopt(p, &i); - ok1(i == j + 2); - ok1(*p == 'a'); - p = next_sopt(p, &i); - ok1(i == j + 3); - ok1(*p == 'b'); - p = next_sopt(p, &i); - ok1(i == j + 7); - ok1(*p == 'g'); - p = next_sopt(p, &i); - ok1(i == j + 8); - ok1(*p == 'h'); - p = next_sopt(p, &i); - ok1(!p); - } - - return exit_status(); -} diff --git a/ccan/opt/test/run-no-options.c b/ccan/opt/test/run-no-options.c deleted file mode 100644 index cf255fee0a..0000000000 --- a/ccan/opt/test/run-no-options.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Make sure we still work with no options registered */ -#include -#include -#include -#include -#include -#include -#include "utils.h" - -int main(int argc, char *argv[]) -{ - const char *myname = argv[0]; - - plan_tests(7); - - /* Simple short arg.*/ - ok1(!parse_args(&argc, &argv, "-a", NULL)); - /* Simple long arg.*/ - ok1(!parse_args(&argc, &argv, "--aaa", NULL)); - - /* Extra arguments preserved. */ - ok1(parse_args(&argc, &argv, "extra", "args", NULL)); - ok1(argc == 3); - ok1(argv[0] == myname); - ok1(strcmp(argv[1], "extra") == 0); - ok1(strcmp(argv[2], "args") == 0); - - /* parse_args allocates argv */ - free(argv); - - return exit_status(); -} - diff --git a/ccan/opt/test/run-usage.c b/ccan/opt/test/run-usage.c deleted file mode 100644 index 2af2c7eeba..0000000000 --- a/ccan/opt/test/run-usage.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include -#include -#include "utils.h" -#include -#include -#include -#include - -static char *my_cb(void *p) -{ - return NULL; -} - -static void reset_options(void) -{ - free(opt_table); - opt_table = NULL; - opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0; -} - -/* Test helpers. */ -int main(int argc, char *argv[]) -{ - char *output; - char *longname = strdup("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); - char *shortname = strdup("shortname"); - - plan_tests(48); - opt_register_table(subtables, NULL); - opt_register_noarg("--kkk|-k", my_cb, NULL, "magic kkk option"); - opt_register_noarg("-?", opt_usage_and_exit, "...", - "This message"); - opt_register_arg("--longname", opt_set_charp, opt_show_charp, - &longname, "a really long option default"); - opt_register_arg("--shortname", opt_set_charp, opt_show_charp, - &shortname, "a short option default"); - output = opt_usage("my name", "ExTrA Args"); - diag("%s", output); - ok1(strstr(output, "Usage: my name")); - ok1(strstr(output, "--jjj|-j|--lll|-l ")); - ok1(strstr(output, "ExTrA Args")); - ok1(strstr(output, "-a ")); - ok1(strstr(output, " Description of a\n")); - ok1(strstr(output, "-b ")); - ok1(strstr(output, " Description of b (default: b)\n")); - ok1(strstr(output, "--ddd ")); - ok1(strstr(output, " Description of ddd\n")); - ok1(strstr(output, "--eee ")); - ok1(strstr(output, " (default: eee)\n")); - ok1(strstr(output, "long table options:\n")); - ok1(strstr(output, "--ggg|-g ")); - ok1(strstr(output, " Description of ggg\n")); - ok1(strstr(output, "-h|--hhh ")); - ok1(strstr(output, " Description of hhh\n")); - ok1(strstr(output, "--kkk|-k")); - ok1(strstr(output, "magic kkk option")); - /* This entry is hidden. */ - ok1(!strstr(output, "--mmm|-m")); - free(output); - - /* NULL should use string from registered options. */ - output = opt_usage("my name", NULL); - diag("%s", output); - ok1(strstr(output, "Usage: my name")); - ok1(strstr(output, "--jjj|-j|--lll|-l ")); - ok1(strstr(output, "...")); - ok1(strstr(output, "-a ")); - ok1(strstr(output, " Description of a\n")); - ok1(strstr(output, "-b ")); - ok1(strstr(output, " Description of b (default: b)\n")); - ok1(strstr(output, "--ddd ")); - ok1(strstr(output, " Description of ddd\n")); - ok1(strstr(output, "--eee ")); - ok1(strstr(output, " (default: eee)\n")); - ok1(strstr(output, "long table options:\n")); - ok1(strstr(output, "--ggg|-g ")); - ok1(strstr(output, " Description of ggg\n")); - ok1(strstr(output, "-h|--hhh ")); - ok1(strstr(output, " Description of hhh\n")); - ok1(strstr(output, "--kkk|-k")); - ok1(strstr(output, "magic kkk option")); - ok1(strstr(output, "--longname")); - ok1(strstr(output, "a really long option default")); - ok1(strstr(output, "(default: \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"...)")); - ok1(strstr(output, "--shortname")); - ok1(strstr(output, "a short option default")); - ok1(strstr(output, "(default: \"shortname\")")); - /* This entry is hidden. */ - ok1(!strstr(output, "--mmm|-m")); - free(output); - - reset_options(); - /* Empty table test. */ - output = opt_usage("nothing", NULL); - ok1(strstr(output, "Usage: nothing \n")); - free(output); - - /* No short args. */ - opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll"); - output = opt_usage("onearg", NULL); - ok1(strstr(output, "Usage: onearg \n")); - ok1(strstr(output, "--aaa")); - ok1(strstr(output, "AAAAll")); - free(output); - - free(shortname); - free(longname); - return exit_status(); -} diff --git a/ccan/opt/test/run.c b/ccan/opt/test/run.c deleted file mode 100644 index 9a769bad12..0000000000 --- a/ccan/opt/test/run.c +++ /dev/null @@ -1,297 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "utils.h" - -static void reset_options(void) -{ - free(opt_table); - opt_table = NULL; - opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0; - free(err_output); - err_output = NULL; -} - -int main(int argc, char *argv[]) -{ - const char *myname = argv[0]; - - plan_tests(215); - - /* Simple short arg.*/ - opt_register_noarg("-a", test_noarg, NULL, "All"); - ok1(parse_args(&argc, &argv, "-a", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 1); - - /* Simple long arg. */ - opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll"); - ok1(parse_args(&argc, &argv, "--aaa", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 2); - - /* Both long and short args. */ - opt_register_noarg("--aaa|-a", test_noarg, NULL, "AAAAAAll"); - ok1(parse_args(&argc, &argv, "--aaa", "-a", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 4); - - /* Extra arguments preserved. */ - ok1(parse_args(&argc, &argv, "--aaa", "-a", "extra", "args", NULL)); - ok1(argc == 3); - ok1(argv[0] == myname); - ok1(strcmp(argv[1], "extra") == 0); - ok1(strcmp(argv[2], "args") == 0); - ok1(test_cb_called == 6); - - /* Malformed versions. */ - ok1(!parse_args(&argc, &argv, "--aaa=arg", NULL)); - ok1(strstr(err_output, ": --aaa: doesn't allow an argument")); - ok1(!parse_args(&argc, &argv, "--aa", NULL)); - ok1(strstr(err_output, ": --aa: unrecognized option")); - ok1(!parse_args(&argc, &argv, "--aaargh", NULL)); - ok1(strstr(err_output, ": --aaargh: unrecognized option")); - - /* Argument variants. */ - reset_options(); - test_cb_called = 0; - opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", "AAAAAAll"); - ok1(parse_args(&argc, &argv, "--aaa", "aaa", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(test_cb_called == 1); - - ok1(parse_args(&argc, &argv, "--aaa=aaa", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(test_cb_called == 2); - - ok1(parse_args(&argc, &argv, "-a", "aaa", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(test_cb_called == 3); - - /* Malformed versions. */ - ok1(!parse_args(&argc, &argv, "-a", NULL)); - ok1(strstr(err_output, ": -a: requires an argument")); - ok1(!parse_args(&argc, &argv, "--aaa", NULL)); - ok1(strstr(err_output, ": --aaa: requires an argument")); - ok1(!parse_args(&argc, &argv, "--aa", NULL)); - ok1(strstr(err_output, ": --aa: unrecognized option")); - ok1(!parse_args(&argc, &argv, "--aaargh", NULL)); - ok1(strstr(err_output, ": --aaargh: unrecognized option")); - - /* Now, tables. */ - /* Short table: */ - reset_options(); - test_cb_called = 0; - opt_register_table(short_table, NULL); - ok1(parse_args(&argc, &argv, "-a", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 1); - /* This one needs an arg. */ - ok1(parse_args(&argc, &argv, "-b", NULL) == false); - ok1(test_cb_called == 1); - ok1(parse_args(&argc, &argv, "-b", "b", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 2); - - /* Long table: */ - reset_options(); - test_cb_called = 0; - opt_register_table(long_table, NULL); - ok1(parse_args(&argc, &argv, "--ddd", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 1); - /* This one needs an arg. */ - ok1(parse_args(&argc, &argv, "--eee", NULL) == false); - ok1(test_cb_called == 1); - ok1(parse_args(&argc, &argv, "--eee", "eee", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 2); - - /* Short and long, both. */ - reset_options(); - test_cb_called = 0; - opt_register_table(long_and_short_table, NULL); - ok1(parse_args(&argc, &argv, "-g", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 1); - ok1(parse_args(&argc, &argv, "--ggg", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 2); - /* This one needs an arg. */ - ok1(parse_args(&argc, &argv, "-h", NULL) == false); - ok1(test_cb_called == 2); - ok1(parse_args(&argc, &argv, "-h", "hhh", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 3); - ok1(parse_args(&argc, &argv, "--hhh", NULL) == false); - ok1(test_cb_called == 3); - ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 4); - - /* Those will all work as tables. */ - test_cb_called = 0; - reset_options(); - opt_register_table(subtables, NULL); - ok1(parse_args(&argc, &argv, "-a", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 1); - /* This one needs an arg. */ - ok1(parse_args(&argc, &argv, "-b", NULL) == false); - ok1(test_cb_called == 1); - ok1(parse_args(&argc, &argv, "-b", "b", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 2); - - ok1(parse_args(&argc, &argv, "--ddd", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 3); - /* This one needs an arg. */ - ok1(parse_args(&argc, &argv, "--eee", NULL) == false); - ok1(test_cb_called == 3); - ok1(parse_args(&argc, &argv, "--eee", "eee", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 4); - - /* Short and long, both. */ - ok1(parse_args(&argc, &argv, "-g", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 5); - ok1(parse_args(&argc, &argv, "--ggg", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 6); - /* This one needs an arg. */ - ok1(parse_args(&argc, &argv, "-h", NULL) == false); - ok1(test_cb_called == 6); - ok1(parse_args(&argc, &argv, "-h", "hhh", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 7); - ok1(parse_args(&argc, &argv, "--hhh", NULL) == false); - ok1(test_cb_called == 7); - ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL)); - ok1(argc == 1); - ok1(argv[0] == myname); - ok1(argv[1] == NULL); - ok1(test_cb_called == 8); - - /* Now the tricky one: -? must not be confused with an unknown option */ - test_cb_called = 0; - reset_options(); - - /* glibc's getopt does not handle ? with arguments. */ - opt_register_noarg("-?", test_noarg, NULL, "Help"); - ok1(parse_args(&argc, &argv, "-?", NULL)); - ok1(test_cb_called == 1); - ok1(parse_args(&argc, &argv, "-a", NULL) == false); - ok1(test_cb_called == 1); - ok1(strstr(err_output, ": -a: unrecognized option")); - ok1(parse_args(&argc, &argv, "--aaaa", NULL) == false); - ok1(test_cb_called == 1); - ok1(strstr(err_output, ": --aaaa: unrecognized option")); - - test_cb_called = 0; - reset_options(); - - /* Corner cases involving short arg parsing weirdness. */ - opt_register_noarg("-a|--aaa", test_noarg, NULL, "a"); - opt_register_arg("-b|--bbb", test_arg, NULL, "bbb", "b"); - opt_register_arg("-c|--ccc", test_arg, NULL, "aaa", "c"); - /* -aa == -a -a */ - ok1(parse_args(&argc, &argv, "-aa", NULL)); - ok1(test_cb_called == 2); - ok1(parse_args(&argc, &argv, "-aab", NULL) == false); - ok1(test_cb_called == 4); - ok1(strstr(err_output, ": -b: requires an argument")); - ok1(parse_args(&argc, &argv, "-bbbb", NULL)); - ok1(test_cb_called == 5); - ok1(parse_args(&argc, &argv, "-aabbbb", NULL)); - ok1(test_cb_called == 8); - ok1(parse_args(&argc, &argv, "-aabbbb", "-b", "bbb", NULL)); - ok1(test_cb_called == 12); - ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb", "bbb", NULL)); - ok1(test_cb_called == 16); - ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb=bbb", NULL)); - ok1(test_cb_called == 20); - ok1(parse_args(&argc, &argv, "-aacaaa", NULL)); - ok1(test_cb_called == 23); - ok1(parse_args(&argc, &argv, "-aacaaa", "-a", NULL)); - ok1(test_cb_called == 27); - ok1(parse_args(&argc, &argv, "-aacaaa", "--bbb", "bbb", "-aacaaa", - NULL)); - ok1(test_cb_called == 34); - - test_cb_called = 0; - reset_options(); - - /* -- and POSIXLY_CORRECT */ - opt_register_noarg("-a|--aaa", test_noarg, NULL, "a"); - ok1(parse_args(&argc, &argv, "-a", "--", "-a", NULL)); - ok1(test_cb_called == 1); - ok1(argc == 2); - ok1(strcmp(argv[1], "-a") == 0); - ok1(!argv[2]); - - unsetenv("POSIXLY_CORRECT"); - ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL)); - ok1(test_cb_called == 3); - ok1(argc == 3); - ok1(strcmp(argv[1], "somearg") == 0); - ok1(strcmp(argv[2], "-a") == 0); - ok1(!argv[3]); - - setenv("POSIXLY_CORRECT", "1", 1); - ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL)); - ok1(test_cb_called == 4); - ok1(argc == 5); - ok1(strcmp(argv[1], "somearg") == 0); - ok1(strcmp(argv[2], "-a") == 0); - ok1(strcmp(argv[3], "--") == 0); - ok1(strcmp(argv[4], "-a") == 0); - ok1(!argv[5]); - - /* parse_args allocates argv */ - free(argv); - return exit_status(); -} diff --git a/ccan/opt/test/utils.c b/ccan/opt/test/utils.c deleted file mode 100644 index 9544fa77bd..0000000000 --- a/ccan/opt/test/utils.c +++ /dev/null @@ -1,110 +0,0 @@ -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include "utils.h" - -unsigned int test_cb_called; -char *test_noarg(void *arg) -{ - test_cb_called++; - return NULL; -} - -char *test_arg(const char *optarg, const char *arg) -{ - test_cb_called++; - ok1(strcmp(optarg, arg) == 0); - return NULL; -} - -void show_arg(char buf[OPT_SHOW_LEN], const char *arg) -{ - strncpy(buf, arg, OPT_SHOW_LEN); -} - -char *err_output = NULL; - -void save_err_output(const char *fmt, ...) -{ - va_list ap; - char *p; - - va_start(ap, fmt); - /* Check return, for fascist gcc */ - if (vasprintf(&p, fmt, ap) == -1) - p = NULL; - va_end(ap); - - if (err_output) { - err_output = realloc(err_output, - strlen(err_output) + strlen(p) + 1); - strcat(err_output, p); - free(p); - } else - err_output = p; -} - -static bool allocated = false; - -bool parse_args(int *argc, char ***argv, ...) -{ - char **a; - va_list ap; - - va_start(ap, argv); - *argc = 1; - a = malloc(sizeof(*a) * (*argc + 1)); - a[0] = (*argv)[0]; - while ((a[*argc] = va_arg(ap, char *)) != NULL) { - (*argc)++; - a = realloc(a, sizeof(*a) * (*argc + 1)); - } - - if (allocated) - free(*argv); - - *argv = a; - allocated = true; - /* Re-set before parsing. */ - optind = 0; - - return opt_parse(argc, *argv, save_err_output); -} - -struct opt_table short_table[] = { - /* Short opts, different args. */ - OPT_WITHOUT_ARG("-a", test_noarg, "a", "Description of a"), - OPT_WITH_ARG("-b", test_arg, show_arg, "b", "Description of b"), - OPT_ENDTABLE -}; - -struct opt_table long_table[] = { - /* Long opts, different args. */ - OPT_WITHOUT_ARG("--ddd", test_noarg, "ddd", "Description of ddd"), - OPT_WITH_ARG("--eee ", test_arg, show_arg, "eee", ""), - OPT_ENDTABLE -}; - -struct opt_table long_and_short_table[] = { - /* Short and long, different args. */ - OPT_WITHOUT_ARG("--ggg|-g", test_noarg, "ggg", "Description of ggg"), - OPT_WITH_ARG("-h|--hhh", test_arg, NULL, "hhh", "Description of hhh"), - OPT_ENDTABLE -}; - -/* Sub-table test. */ -struct opt_table subtables[] = { - /* Two short, and two long long, no description */ - OPT_WITH_ARG("--jjj|-j|--lll|-l", test_arg, show_arg, "jjj", ""), - /* Hidden option */ - OPT_WITH_ARG("--mmm|-m", test_arg, show_arg, "mmm", opt_hidden), - OPT_SUBTABLE(short_table, NULL), - OPT_SUBTABLE(long_table, "long table options"), - OPT_SUBTABLE(long_and_short_table, NULL), - OPT_ENDTABLE -}; diff --git a/ccan/opt/test/utils.h b/ccan/opt/test/utils.h deleted file mode 100644 index f7c18967ab..0000000000 --- a/ccan/opt/test/utils.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CCAN_OPT_TEST_UTILS_H -#define CCAN_OPT_TEST_UTILS_H -#include -#include - -bool parse_args(int *argc, char ***argv, ...); -extern char *err_output; -void save_err_output(const char *fmt, ...); - -extern unsigned int test_cb_called; -char *test_noarg(void *arg); -char *test_arg(const char *optarg, const char *arg); -void show_arg(char buf[OPT_SHOW_LEN], const char *arg); - -extern struct opt_table short_table[]; -extern struct opt_table long_table[]; -extern struct opt_table long_and_short_table[]; -extern struct opt_table subtables[]; -#endif /* CCAN_OPT_TEST_UTILS_H */ diff --git a/ccan/opt/usage.c b/ccan/opt/usage.c deleted file mode 100644 index 4d784bc2be..0000000000 --- a/ccan/opt/usage.c +++ /dev/null @@ -1,111 +0,0 @@ -#include -#include -#include -#include -#include -#include "private.h" - -/* We only use this for pointer comparisons. */ -const char opt_hidden[1]; - -static unsigned write_short_options(char *str) -{ - unsigned int i, num = 0; - const char *p; - - for (p = first_sopt(&i); p; p = next_sopt(p, &i)) { - if (opt_table[i].desc != opt_hidden) - str[num++] = *p; - } - return num; -} - -#define OPT_SPACE_PAD " " - -/* FIXME: Get all purdy. */ -char *opt_usage(const char *argv0, const char *extra) -{ - unsigned int i, num, len; - char *ret, *p; - - if (!extra) { - extra = ""; - for (i = 0; i < opt_count; i++) { - if (opt_table[i].cb == (void *)opt_usage_and_exit - && opt_table[i].u.carg) { - extra = opt_table[i].u.carg; - break; - } - } - } - - /* An overestimate of our length. */ - len = strlen("Usage: %s ") + strlen(argv0) - + strlen("[-%.*s]") + opt_num_short + 1 - + strlen(" ") + strlen(extra) - + strlen("\n"); - - for (i = 0; i < opt_count; i++) { - if (opt_table[i].type == OPT_SUBTABLE) { - len += strlen("\n") + strlen(opt_table[i].desc) - + strlen(":\n"); - } else if (opt_table[i].desc != opt_hidden) { - len += strlen(opt_table[i].names) + strlen(" "); - len += strlen(OPT_SPACE_PAD) - + strlen(opt_table[i].desc) + 1; - if (opt_table[i].show) { - len += strlen("(default: %s)") - + OPT_SHOW_LEN + sizeof("..."); - } - len += strlen("\n"); - } - } - - p = ret = malloc(len); - if (!ret) - return NULL; - - p += sprintf(p, "Usage: %s", argv0); - p += sprintf(p, " [-"); - num = write_short_options(p); - if (num) { - p += num; - p += sprintf(p, "]"); - } else { - /* Remove start of single-entry options */ - p -= 3; - } - if (extra) - p += sprintf(p, " %s", extra); - p += sprintf(p, "\n"); - - for (i = 0; i < opt_count; i++) { - if (opt_table[i].desc == opt_hidden) - continue; - if (opt_table[i].type == OPT_SUBTABLE) { - p += sprintf(p, "%s:\n", opt_table[i].desc); - continue; - } - len = sprintf(p, "%s", opt_table[i].names); - if (opt_table[i].type == OPT_HASARG - && !strchr(opt_table[i].names, ' ') - && !strchr(opt_table[i].names, '=')) - len += sprintf(p + len, " "); - len += sprintf(p + len, "%.*s", - len < strlen(OPT_SPACE_PAD) - ? (unsigned)strlen(OPT_SPACE_PAD) - len : 1, - OPT_SPACE_PAD); - - len += sprintf(p + len, "%s", opt_table[i].desc); - if (opt_table[i].show) { - char buf[OPT_SHOW_LEN + sizeof("...")]; - strcpy(buf + OPT_SHOW_LEN, "..."); - opt_table[i].show(buf, opt_table[i].u.arg); - len += sprintf(p + len, " (default: %s)", buf); - } - p += len; - p += sprintf(p, "\n"); - } - *p = '\0'; - return ret; -} diff --git a/ccan/opt/usage.d b/ccan/opt/usage.d deleted file mode 100644 index 0cacbfd171..0000000000 --- a/ccan/opt/usage.d +++ /dev/null @@ -1,22 +0,0 @@ -ccan/opt/usage.o: ccan/opt/usage.c ccan/opt/opt.h \ - ccan/compiler/compiler.h config.h ccan/typesafe_cb/typesafe_cb.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stdbool.h \ - /usr/include/stdlib.h /usr/include/features.h \ - /usr/include/bits/predefs.h /usr/include/sys/cdefs.h \ - /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \ - /usr/include/gnu/stubs-32.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stddef.h \ - /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \ - /usr/include/endian.h /usr/include/bits/endian.h \ - /usr/include/bits/byteswap.h /usr/include/xlocale.h \ - /usr/include/sys/types.h /usr/include/bits/types.h \ - /usr/include/bits/typesizes.h /usr/include/time.h \ - /usr/include/sys/select.h /usr/include/bits/select.h \ - /usr/include/bits/sigset.h /usr/include/bits/time.h \ - /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \ - /usr/include/alloca.h /usr/include/string.h /usr/include/stdio.h \ - /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stdarg.h \ - /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \ - /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include/stdint.h \ - /usr/include/stdint.h /usr/include/bits/wchar.h ccan/opt/private.h diff --git a/ccan/opt/usage.o b/ccan/opt/usage.o deleted file mode 100644 index 1e72da3558..0000000000 Binary files a/ccan/opt/usage.o and /dev/null differ diff --git a/ccan/typesafe_cb/LICENSE b/ccan/typesafe_cb/LICENSE deleted file mode 100644 index 2d2d780e60..0000000000 --- a/ccan/typesafe_cb/LICENSE +++ /dev/null @@ -1,510 +0,0 @@ - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations -below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it -becomes a de-facto standard. To achieve this, non-free programs must -be allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at least - three years, to give the same user the materials specified in - Subsection 6a, above, for a charge no more than the cost of - performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply, and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License -may add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms -of the ordinary General Public License). - - To apply these terms, attach the following notices to the library. -It is safest to attach them to the start of each source file to most -effectively convey the exclusion of warranty; and each file should -have at least the "copyright" line and a pointer to where the full -notice is found. - - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or -your school, if any, to sign a "copyright disclaimer" for the library, -if necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James - Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/ccan/typesafe_cb/_info b/ccan/typesafe_cb/_info deleted file mode 100644 index 2fe4fec029..0000000000 --- a/ccan/typesafe_cb/_info +++ /dev/null @@ -1,151 +0,0 @@ -#include -#include -#include "config.h" - -/** - * typesafe_cb - macros for safe callbacks. - * - * The basis of the typesafe_cb header is typesafe_cb_cast(): a - * conditional cast macro. If an expression exactly matches a given - * type, it is cast to the target type, otherwise it is left alone. - * - * This allows us to create functions which take a small number of - * specific types, rather than being forced to use a void *. In - * particular, it is useful for creating typesafe callbacks as the - * helpers typesafe_cb(), typesafe_cb_preargs() and - * typesafe_cb_postargs() demonstrate. - * - * The standard way of passing arguments to callback functions in C is - * to use a void pointer, which the callback then casts back to the - * expected type. This unfortunately subverts the type checking the - * compiler would perform if it were a direct call. Here's an example: - * - * static void my_callback(void *_obj) - * { - * struct obj *obj = _obj; - * ... - * } - * ... - * register_callback(my_callback, &my_obj); - * - * If we wanted to use the natural type for my_callback (ie. "void - * my_callback(struct obj *obj)"), we could make register_callback() - * take a void * as its first argument, but this would subvert all - * type checking. We really want register_callback() to accept only - * the exactly correct function type to match the argument, or a - * function which takes a void *. - * - * This is where typesafe_cb() comes in: it uses typesafe_cb_cast() to - * cast the callback function if it matches the argument type: - * - * void _register_callback(void (*cb)(void *arg), void *arg); - * #define register_callback(cb, arg) \ - * _register_callback(typesafe_cb(void, void *, (cb), (arg)), \ - * (arg)) - * - * On compilers which don't support the extensions required - * typesafe_cb_cast() and friend become an unconditional cast, so your - * code will compile but you won't get type checking. - * - * Example: - * #include - * #include - * #include - * - * // Generic callback infrastructure. - * struct callback { - * struct callback *next; - * int value; - * int (*callback)(int value, void *arg); - * void *arg; - * }; - * static struct callback *callbacks; - * - * static void _register_callback(int value, int (*cb)(int, void *), - * void *arg) - * { - * struct callback *new = malloc(sizeof(*new)); - * new->next = callbacks; - * new->value = value; - * new->callback = cb; - * new->arg = arg; - * callbacks = new; - * } - * #define register_callback(value, cb, arg) \ - * _register_callback(value, \ - * typesafe_cb_preargs(int, void *, \ - * (cb), (arg), int),\ - * (arg)) - * - * static struct callback *find_callback(int value) - * { - * struct callback *i; - * - * for (i = callbacks; i; i = i->next) - * if (i->value == value) - * return i; - * return NULL; - * } - * - * // Define several silly callbacks. Note they don't use void *! - * #define DEF_CALLBACK(name, op) \ - * static int name(int val, int *arg) \ - * { \ - * printf("%s", #op); \ - * return val op *arg; \ - * } - * DEF_CALLBACK(multiply, *); - * DEF_CALLBACK(add, +); - * DEF_CALLBACK(divide, /); - * DEF_CALLBACK(sub, -); - * DEF_CALLBACK(or, |); - * DEF_CALLBACK(and, &); - * DEF_CALLBACK(xor, ^); - * DEF_CALLBACK(assign, =); - * - * // Silly game to find the longest chain of values. - * int main(int argc, char *argv[]) - * { - * int i, run = 1, num = argv[1] ? atoi(argv[1]) : 0; - * - * for (i = 1; i < 1024;) { - * // Since run is an int, compiler checks "add" does too. - * register_callback(i++, add, &run); - * register_callback(i++, divide, &run); - * register_callback(i++, sub, &run); - * register_callback(i++, multiply, &run); - * register_callback(i++, or, &run); - * register_callback(i++, and, &run); - * register_callback(i++, xor, &run); - * register_callback(i++, assign, &run); - * } - * - * printf("%i ", num); - * while (run < 56) { - * struct callback *cb = find_callback(num % i); - * if (!cb) { - * printf("-> STOP\n"); - * return 1; - * } - * num = cb->callback(num, cb->arg); - * printf("->%i ", num); - * run++; - * } - * printf("-> Winner!\n"); - * return 0; - * } - * - * License: LGPL (2 or any later version) - * Author: Rusty Russell - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - return 0; - } - - return 1; -} diff --git a/ccan/typesafe_cb/test/compile_fail-cast_if_type-promotable.c b/ccan/typesafe_cb/test/compile_fail-cast_if_type-promotable.c deleted file mode 100644 index 11d42f4c6b..0000000000 --- a/ccan/typesafe_cb/test/compile_fail-cast_if_type-promotable.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include - -static void _set_some_value(void *val) -{ -} - -#define set_some_value(expr) \ - _set_some_value(typesafe_cb_cast(void *, long, (expr))) - -int main(int argc, char *argv[]) -{ -#ifdef FAIL - bool x = 0; -#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P -#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." -#endif -#else - long x = 0; -#endif - set_some_value(x); - return 0; -} diff --git a/ccan/typesafe_cb/test/compile_fail-typesafe_cb-int.c b/ccan/typesafe_cb/test/compile_fail-typesafe_cb-int.c deleted file mode 100644 index c4033364d4..0000000000 --- a/ccan/typesafe_cb/test/compile_fail-typesafe_cb-int.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include - -void _callback(void (*fn)(void *arg), void *arg); -void _callback(void (*fn)(void *arg), void *arg) -{ - fn(arg); -} - -/* Callback is set up to warn if arg isn't a pointer (since it won't - * pass cleanly to _callback's second arg. */ -#define callback(fn, arg) \ - _callback(typesafe_cb(void, (fn), (arg)), (arg)) - -void my_callback(int something); -void my_callback(int something) -{ -} - -int main(int argc, char *argv[]) -{ -#ifdef FAIL - /* This fails due to arg, not due to cast. */ - callback(my_callback, 100); -#endif - return 0; -} diff --git a/ccan/typesafe_cb/test/compile_fail-typesafe_cb.c b/ccan/typesafe_cb/test/compile_fail-typesafe_cb.c deleted file mode 100644 index 81e36d7b87..0000000000 --- a/ccan/typesafe_cb/test/compile_fail-typesafe_cb.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include - -static void _register_callback(void (*cb)(void *arg), void *arg) -{ -} - -#define register_callback(cb, arg) \ - _register_callback(typesafe_cb(void, void *, (cb), (arg)), (arg)) - -static void my_callback(char *p) -{ -} - -int main(int argc, char *argv[]) -{ - char str[] = "hello world"; -#ifdef FAIL - int *p; -#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P -#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." -#endif -#else - char *p; -#endif - p = NULL; - - /* This should work always. */ - register_callback(my_callback, str); - - /* This will fail with FAIL defined */ - register_callback(my_callback, p); - return 0; -} diff --git a/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast-multi.c b/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast-multi.c deleted file mode 100644 index 62b5f91e18..0000000000 --- a/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast-multi.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include - -struct foo { - int x; -}; - -struct bar { - int x; -}; - -struct baz { - int x; -}; - -struct any { - int x; -}; - -struct other { - int x; -}; - -static void take_any(struct any *any) -{ -} - -int main(int argc, char *argv[]) -{ -#ifdef FAIL - struct other -#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P -#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." -#endif -#else - struct foo -#endif - *arg = NULL; - take_any(typesafe_cb_cast3(struct any *, - struct foo *, struct bar *, struct baz *, - arg)); - return 0; -} diff --git a/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast.c b/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast.c deleted file mode 100644 index d2e6f2ab40..0000000000 --- a/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast.c +++ /dev/null @@ -1,25 +0,0 @@ -#include - -void _set_some_value(void *val); - -void _set_some_value(void *val) -{ -} - -#define set_some_value(expr) \ - _set_some_value(typesafe_cb_cast(void *, unsigned long, (expr))) - -int main(int argc, char *argv[]) -{ -#ifdef FAIL - int x = 0; - set_some_value(x); -#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P -#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." -#endif -#else - void *p = 0; - set_some_value(p); -#endif - return 0; -} diff --git a/ccan/typesafe_cb/test/compile_fail-typesafe_cb_postargs.c b/ccan/typesafe_cb/test/compile_fail-typesafe_cb_postargs.c deleted file mode 100644 index 7d3530851d..0000000000 --- a/ccan/typesafe_cb/test/compile_fail-typesafe_cb_postargs.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include - -static void _register_callback(void (*cb)(void *arg, int x), void *arg) -{ -} -#define register_callback(cb, arg) \ - _register_callback(typesafe_cb_postargs(void, void *, (cb), (arg), int), (arg)) - -static void my_callback(char *p, int x) -{ -} - -int main(int argc, char *argv[]) -{ -#ifdef FAIL - int *p; -#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P -#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." -#endif -#else - char *p; -#endif - p = NULL; - register_callback(my_callback, p); - return 0; -} diff --git a/ccan/typesafe_cb/test/compile_fail-typesafe_cb_preargs.c b/ccan/typesafe_cb/test/compile_fail-typesafe_cb_preargs.c deleted file mode 100644 index bd55c6722c..0000000000 --- a/ccan/typesafe_cb/test/compile_fail-typesafe_cb_preargs.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -static void _register_callback(void (*cb)(int x, void *arg), void *arg) -{ -} - -#define register_callback(cb, arg) \ - _register_callback(typesafe_cb_preargs(void, void *, (cb), (arg), int), (arg)) - -static void my_callback(int x, char *p) -{ -} - -int main(int argc, char *argv[]) -{ -#ifdef FAIL - int *p; -#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P -#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." -#endif -#else - char *p; -#endif - p = NULL; - register_callback(my_callback, p); - return 0; -} diff --git a/ccan/typesafe_cb/test/compile_ok-typesafe_cb-NULL.c b/ccan/typesafe_cb/test/compile_ok-typesafe_cb-NULL.c deleted file mode 100644 index 265de8b14e..0000000000 --- a/ccan/typesafe_cb/test/compile_ok-typesafe_cb-NULL.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include - -/* NULL args for callback function should be OK for normal and _def. */ - -static void _register_callback(void (*cb)(const void *arg), const void *arg) -{ -} - -#define register_callback(cb, arg) \ - _register_callback(typesafe_cb(void, const void *, (cb), (arg)), (arg)) - -int main(int argc, char *argv[]) -{ - register_callback(NULL, "hello world"); - return 0; -} diff --git a/ccan/typesafe_cb/test/compile_ok-typesafe_cb-undefined.c b/ccan/typesafe_cb/test/compile_ok-typesafe_cb-undefined.c deleted file mode 100644 index aa50bad6a9..0000000000 --- a/ccan/typesafe_cb/test/compile_ok-typesafe_cb-undefined.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include - -/* const args in callbacks should be OK. */ - -static void _register_callback(void (*cb)(void *arg), void *arg) -{ -} - -#define register_callback(cb, arg) \ - _register_callback(typesafe_cb(void, void *, (cb), (arg)), (arg)) - -static void _register_callback_pre(void (*cb)(int x, void *arg), void *arg) -{ -} - -#define register_callback_pre(cb, arg) \ - _register_callback_pre(typesafe_cb_preargs(void, void *, (cb), (arg), int), (arg)) - -static void _register_callback_post(void (*cb)(void *arg, int x), void *arg) -{ -} - -#define register_callback_post(cb, arg) \ - _register_callback_post(typesafe_cb_postargs(void, void *, (cb), (arg), int), (arg)) - -struct undefined; - -static void my_callback(struct undefined *undef) -{ -} - -static void my_callback_pre(int x, struct undefined *undef) -{ -} - -static void my_callback_post(struct undefined *undef, int x) -{ -} - -int main(int argc, char *argv[]) -{ - struct undefined *handle = NULL; - - register_callback(my_callback, handle); - register_callback_pre(my_callback_pre, handle); - register_callback_post(my_callback_post, handle); - return 0; -} diff --git a/ccan/typesafe_cb/test/compile_ok-typesafe_cb-vars.c b/ccan/typesafe_cb/test/compile_ok-typesafe_cb-vars.c deleted file mode 100644 index f6a2bfecbc..0000000000 --- a/ccan/typesafe_cb/test/compile_ok-typesafe_cb-vars.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include - -/* const args in callbacks should be OK. */ - -static void _register_callback(void (*cb)(void *arg), void *arg) -{ -} - -#define register_callback(cb, arg) \ - _register_callback(typesafe_cb(void, void *, (cb), (arg)), (arg)) - -static void _register_callback_pre(void (*cb)(int x, void *arg), void *arg) -{ -} - -#define register_callback_pre(cb, arg) \ - _register_callback_pre(typesafe_cb_preargs(void, void *, (cb), (arg), int), (arg)) - -static void _register_callback_post(void (*cb)(void *arg, int x), void *arg) -{ -} - -#define register_callback_post(cb, arg) \ - _register_callback_post(typesafe_cb_postargs(void, void *, (cb), (arg), int), (arg)) - -struct undefined; - -static void my_callback(struct undefined *undef) -{ -} - -static void my_callback_pre(int x, struct undefined *undef) -{ -} - -static void my_callback_post(struct undefined *undef, int x) -{ -} - -int main(int argc, char *argv[]) -{ - struct undefined *handle = NULL; - void (*cb)(struct undefined *undef) = my_callback; - void (*pre)(int x, struct undefined *undef) = my_callback_pre; - void (*post)(struct undefined *undef, int x) = my_callback_post; - - register_callback(cb, handle); - register_callback_pre(pre, handle); - register_callback_post(post, handle); - return 0; -} diff --git a/ccan/typesafe_cb/test/compile_ok-typesafe_cb_cast.c b/ccan/typesafe_cb/test/compile_ok-typesafe_cb_cast.c deleted file mode 100644 index 4bb3b8bf10..0000000000 --- a/ccan/typesafe_cb/test/compile_ok-typesafe_cb_cast.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include - -struct foo { - int x; -}; - -struct bar { - int x; -}; - -struct baz { - int x; -}; - -struct any { - int x; -}; - -static void take_any(struct any *any) -{ -} - -int main(int argc, char *argv[]) -{ - /* Otherwise we get unused warnings for these. */ - struct foo *foo = NULL; - struct bar *bar = NULL; - struct baz *baz = NULL; - - take_any(typesafe_cb_cast3(struct any *, - struct foo *, struct bar *, struct baz *, - foo)); - take_any(typesafe_cb_cast3(struct any *, - struct foo *, struct bar *, struct baz *, - bar)); - take_any(typesafe_cb_cast3(struct any *, - struct foo *, struct bar *, struct baz *, - baz)); - return 0; -} diff --git a/ccan/typesafe_cb/test/run.c b/ccan/typesafe_cb/test/run.c deleted file mode 100644 index 79863db841..0000000000 --- a/ccan/typesafe_cb/test/run.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include -#include - -static char dummy = 0; - -/* The example usage. */ -static void _set_some_value(void *val) -{ - ok1(val == &dummy); -} - -#define set_some_value(expr) \ - _set_some_value(typesafe_cb_cast(void *, unsigned long, (expr))) - -static void _callback_onearg(void (*fn)(void *arg), void *arg) -{ - fn(arg); -} - -static void _callback_preargs(void (*fn)(int a, int b, void *arg), void *arg) -{ - fn(1, 2, arg); -} - -static void _callback_postargs(void (*fn)(void *arg, int a, int b), void *arg) -{ - fn(arg, 1, 2); -} - -#define callback_onearg(cb, arg) \ - _callback_onearg(typesafe_cb(void, void *, (cb), (arg)), (arg)) - -#define callback_preargs(cb, arg) \ - _callback_preargs(typesafe_cb_preargs(void, void *, (cb), (arg), int, int), (arg)) - -#define callback_postargs(cb, arg) \ - _callback_postargs(typesafe_cb_postargs(void, void *, (cb), (arg), int, int), (arg)) - -static void my_callback_onearg(char *p) -{ - ok1(strcmp(p, "hello world") == 0); -} - -static void my_callback_preargs(int a, int b, char *p) -{ - ok1(a == 1); - ok1(b == 2); - ok1(strcmp(p, "hello world") == 0); -} - -static void my_callback_postargs(char *p, int a, int b) -{ - ok1(a == 1); - ok1(b == 2); - ok1(strcmp(p, "hello world") == 0); -} - -/* This is simply a compile test; we promised typesafe_cb_cast can be in a - * static initializer. */ -struct callback_onearg -{ - void (*fn)(void *arg); - const void *arg; -}; - -struct callback_onearg cb_onearg -= { typesafe_cb(void, void *, my_callback_onearg, (char *)(intptr_t)"hello world"), - "hello world" }; - -struct callback_preargs -{ - void (*fn)(int a, int b, void *arg); - const void *arg; -}; - -struct callback_preargs cb_preargs -= { typesafe_cb_preargs(void, void *, my_callback_preargs, - (char *)(intptr_t)"hi", int, int), "hi" }; - -struct callback_postargs -{ - void (*fn)(void *arg, int a, int b); - const void *arg; -}; - -struct callback_postargs cb_postargs -= { typesafe_cb_postargs(void, void *, my_callback_postargs, - (char *)(intptr_t)"hi", int, int), "hi" }; - -int main(int argc, char *argv[]) -{ - void *p = &dummy; - unsigned long l = (unsigned long)p; - char str[] = "hello world"; - - plan_tests(2 + 1 + 3 + 3); - set_some_value(p); - set_some_value(l); - - callback_onearg(my_callback_onearg, str); - - callback_preargs(my_callback_preargs, str); - - callback_postargs(my_callback_postargs, str); - - return exit_status(); -} diff --git a/ccan/typesafe_cb/typesafe_cb.h b/ccan/typesafe_cb/typesafe_cb.h deleted file mode 100644 index 40cfa39798..0000000000 --- a/ccan/typesafe_cb/typesafe_cb.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef CCAN_TYPESAFE_CB_H -#define CCAN_TYPESAFE_CB_H -#include "config.h" - -#if HAVE_TYPEOF && HAVE_BUILTIN_CHOOSE_EXPR && HAVE_BUILTIN_TYPES_COMPATIBLE_P -/** - * typesafe_cb_cast - only cast an expression if it matches a given type - * @desttype: the type to cast to - * @oktype: the type we allow - * @expr: the expression to cast - * - * This macro is used to create functions which allow multiple types. - * The result of this macro is used somewhere that a @desttype type is - * expected: if @expr is exactly of type @oktype, then it will be - * cast to @desttype type, otherwise left alone. - * - * This macro can be used in static initializers. - * - * This is merely useful for warnings: if the compiler does not - * support the primitives required for typesafe_cb_cast(), it becomes an - * unconditional cast, and the @oktype argument is not used. In - * particular, this means that @oktype can be a type which uses the - * "typeof": it will not be evaluated if typeof is not supported. - * - * Example: - * // We can take either an unsigned long or a void *. - * void _set_some_value(void *val); - * #define set_some_value(e) \ - * _set_some_value(typesafe_cb_cast(void *, (e), unsigned long)) - */ -#define typesafe_cb_cast(desttype, oktype, expr) \ - __builtin_choose_expr( \ - __builtin_types_compatible_p(__typeof__(0?(expr):(expr)), \ - oktype), \ - (desttype)(expr), (expr)) -#else -#define typesafe_cb_cast(desttype, oktype, expr) ((desttype)(expr)) -#endif - -/** - * typesafe_cb_cast3 - only cast an expression if it matches given types - * @desttype: the type to cast to - * @ok1: the first type we allow - * @ok2: the second type we allow - * @ok3: the third type we allow - * @expr: the expression to cast - * - * This is a convenient wrapper for multiple typesafe_cb_cast() calls. - * You can chain them inside each other (ie. use typesafe_cb_cast() - * for expr) if you need more than 3 arguments. - * - * Example: - * // We can take either a long, unsigned long, void * or a const void *. - * void _set_some_value(void *val); - * #define set_some_value(expr) \ - * _set_some_value(typesafe_cb_cast3(void *,, \ - * long, unsigned long, const void *,\ - * (expr))) - */ -#define typesafe_cb_cast3(desttype, ok1, ok2, ok3, expr) \ - typesafe_cb_cast(desttype, ok1, \ - typesafe_cb_cast(desttype, ok2, \ - typesafe_cb_cast(desttype, ok3, \ - (expr)))) - -/** - * typesafe_cb - cast a callback function if it matches the arg - * @rtype: the return type of the callback function - * @atype: the (pointer) type which the callback function expects. - * @fn: the callback function to cast - * @arg: the (pointer) argument to hand to the callback function. - * - * If a callback function takes a single argument, this macro does - * appropriate casts to a function which takes a single atype argument if the - * callback provided matches the @arg. - * - * It is assumed that @arg is of pointer type: usually @arg is passed - * or assigned to a void * elsewhere anyway. - * - * Example: - * void _register_callback(void (*fn)(void *arg), void *arg); - * #define register_callback(fn, arg) \ - * _register_callback(typesafe_cb(void, (fn), void*, (arg)), (arg)) - */ -#define typesafe_cb(rtype, atype, fn, arg) \ - typesafe_cb_cast(rtype (*)(atype), \ - rtype (*)(__typeof__(arg)), \ - (fn)) - -/** - * typesafe_cb_preargs - cast a callback function if it matches the arg - * @rtype: the return type of the callback function - * @atype: the (pointer) type which the callback function expects. - * @fn: the callback function to cast - * @arg: the (pointer) argument to hand to the callback function. - * - * This is a version of typesafe_cb() for callbacks that take other arguments - * before the @arg. - * - * Example: - * void _register_callback(void (*fn)(int, void *arg), void *arg); - * #define register_callback(fn, arg) \ - * _register_callback(typesafe_cb_preargs(void, (fn), void *, \ - * (arg), int), \ - * (arg)) - */ -#define typesafe_cb_preargs(rtype, atype, fn, arg, ...) \ - typesafe_cb_cast(rtype (*)(__VA_ARGS__, atype), \ - rtype (*)(__VA_ARGS__, __typeof__(arg)), \ - (fn)) - -/** - * typesafe_cb_postargs - cast a callback function if it matches the arg - * @rtype: the return type of the callback function - * @atype: the (pointer) type which the callback function expects. - * @fn: the callback function to cast - * @arg: the (pointer) argument to hand to the callback function. - * - * This is a version of typesafe_cb() for callbacks that take other arguments - * after the @arg. - * - * Example: - * void _register_callback(void (*fn)(void *arg, int), void *arg); - * #define register_callback(fn, arg) \ - * _register_callback(typesafe_cb_postargs(void, (fn), void *, \ - * (arg), int), \ - * (arg)) - */ -#define typesafe_cb_postargs(rtype, atype, fn, arg, ...) \ - typesafe_cb_cast(rtype (*)(atype, __VA_ARGS__), \ - rtype (*)(__typeof__(arg), __VA_ARGS__), \ - (fn)) -#endif /* CCAN_CAST_IF_TYPE_H */ diff --git a/compat.h b/compat.h index a82a3aa27a..f4cab680bb 100644 --- a/compat.h +++ b/compat.h @@ -1,26 +1,129 @@ -#ifndef __COMPAT_H__ -#define __COMPAT_H__ +/* + * Copyright 2012-2013 Luke Dashjr + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) + * any later version. See COPYING for more details. + */ + +#ifndef BFG_COMPAT_H +#define BFG_COMPAT_H + +#include "config.h" + +#include + +#if !(defined(WIN32) || defined(unix)) +#define unix +#endif + +#if defined(LL_FOREACH) && !defined(LL_FOREACH2) + +// Missing from uthash before 1.9.7 + +#define LL_DELETE2(head,del,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (del))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = ((del)->next); \ + } \ + } \ +} while (0) + +#define LL_FOREACH2(head,el,next) \ + for(el=head;el;el=(el)->next) + +#define LL_FOREACH_SAFE2(head,el,tmp,next) \ + for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + +#define LL_PREPEND2(head,add,next) \ +do { \ + (add)->next = head; \ + head = add; \ +} while (0) + +#endif #ifdef WIN32 #include +#include #include #include #include #include -// NOTE: Windows strtok uses a thread-local static buffer, so this is safe -#define SETUP_STRTOK_TS /*nothing needed*/ -#define strtok_ts strtok +#ifndef __maybe_unused +#define __maybe_unused __attribute__((unused)) +#endif + + #ifndef timersub + #define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) + #endif + #ifndef timeradd + # define timeradd(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ + if ((result)->tv_usec >= 1000000) \ + { \ + ++(result)->tv_sec; \ + (result)->tv_usec -= 1000000; \ + } \ + } while (0) + #endif + +// Some versions of MingW define this, but don't handle the timeval.tv_sec case that we use +#ifdef localtime_r +#undef localtime_r +#endif +// localtime is thread-safe on Windows +// We also use this with timeval.tv_sec, which is incorrectly smaller than time_t on Windows +// Need to cast to time_t* to suppress warning - actual problem shouldn't be possible in practice +#define localtime_r(timep, result) ( \ + memcpy(result, \ + ( \ + (sizeof(*timep) == sizeof(time_t)) \ + ? localtime((time_t*)timep) \ + : localtime_convert(*timep) \ + ), \ + sizeof(*result) \ + ) \ +) + +static inline +struct tm *localtime_convert(time_t t) +{ + return localtime(&t); +} +#endif -#include "miner.h" // for timersub +#ifndef HAVE_NANOSLEEP +extern void (*timer_set_now)(struct timeval *); +#define cgtime(tvp) timer_set_now(tvp) static inline int nanosleep(const struct timespec *req, struct timespec *rem) { struct timeval tstart; DWORD msecs; - gettimeofday(&tstart, NULL); + cgtime(&tstart); msecs = (req->tv_sec * 1000) + ((999999 + req->tv_nsec) / 1000000); if (SleepEx(msecs, true) == WAIT_IO_COMPLETION) { @@ -33,7 +136,7 @@ static inline int nanosleep(const struct timespec *req, struct timespec *rem) ++tdone.tv_sec; } - gettimeofday(&tnow, NULL); + cgtime(&tnow); if (timercmp(&tnow, &tdone, >)) return 0; timersub(&tdone, &tnow, &tleft); @@ -47,6 +150,10 @@ static inline int nanosleep(const struct timespec *req, struct timespec *rem) return 0; } +#undef cgtime +#endif + +#ifndef HAVE_SLEEP static inline int sleep(unsigned int secs) { struct timespec req, rem; @@ -56,14 +163,16 @@ static inline int sleep(unsigned int secs) return 0; return rem.tv_sec + (rem.tv_nsec ? 1 : 0); } +#endif +#ifdef WIN32 enum { PRIO_PROCESS = 0, }; -static inline int setpriority(int which, int who, int prio) +static inline int setpriority(__maybe_unused int which, __maybe_unused int who, __maybe_unused int prio) { - return -!SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); + return -!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE); } typedef unsigned long int ulong; @@ -74,14 +183,31 @@ typedef unsigned int uint; typedef long suseconds_t; #endif -#define PTH(thr) ((thr)->pth.p) -#else /* ! WIN32 */ +#endif /* WIN32 */ -#define PTH(thr) ((thr)->pth) +#ifndef HAVE_LOG2 +# define log2(n) (log(n) / log(2)) +#endif -#define SETUP_STRTOK_TS char*_strtok_ts_saveptr -#define strtok_ts(str, delim) strtok_r(str, delim, &_strtok_ts_saveptr) +#ifndef HAVE_PTHREAD_CANCEL -#endif /* WIN32 */ +// Bionic (Android) is intentionally missing pthread_cancel, so it is implemented using pthread_kill (handled in util.c) +#include +#include +#define pthread_cancel(pth) pthread_kill(pth, SIGTERM) +extern void pthread_testcancel(void); +#ifndef PTHREAD_CANCEL_ENABLE +#define PTHREAD_CANCEL_ENABLE 0 +#define PTHREAD_CANCEL_DISABLE 1 +#endif +#ifndef PTHREAD_CANCEL_DEFERRED +#define PTHREAD_CANCEL_DEFERRED 0 +#define PTHREAD_CANCEL_ASYNCHRONOUS 1 +#endif +#ifndef PTHREAD_CANCELED +#define PTHREAD_CANCELED ((void*)-1) +#endif + +#endif #endif /* __COMPAT_H__ */ diff --git a/compat/Makefile.am b/compat/Makefile.am deleted file mode 100644 index 77af3c54b3..0000000000 --- a/compat/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ - -if WANT_JANSSON -SUBDIRS = jansson -else -SUBDIRS = -endif - diff --git a/compat/jansson/.gitignore b/compat/jansson/.gitignore deleted file mode 100644 index 173737b67f..0000000000 --- a/compat/jansson/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -libjansson.a - diff --git a/compat/jansson/LICENSE b/compat/jansson/LICENSE deleted file mode 100644 index 552b3498b0..0000000000 --- a/compat/jansson/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2009, 2010 Petri Lehtinen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/compat/jansson/Makefile.am b/compat/jansson/Makefile.am deleted file mode 100644 index f007b2c937..0000000000 --- a/compat/jansson/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ - -noinst_LIBRARIES = libjansson.a - -libjansson_a_SOURCES = \ - config.h \ - jansson_config.h \ - dump.c \ - hashtable.c \ - hashtable.h \ - jansson.h \ - jansson_private.h \ - load.c \ - strbuffer.c \ - strbuffer.h \ - utf.c \ - utf.h \ - util.h \ - value.c \ - memory.c \ - error.c - diff --git a/compat/jansson/config.h b/compat/jansson/config.h deleted file mode 100644 index 43858aa61f..0000000000 --- a/compat/jansson/config.h +++ /dev/null @@ -1,73 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#define LT_OBJDIR ".libs/" - -/* Name of package */ -#define PACKAGE "jansson" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "petri@digip.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "jansson" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "jansson 1.3" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "jansson" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "1.3" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "1.3" - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to the type of a signed integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -/* #undef int32_t */ diff --git a/compat/jansson/dump.c b/compat/jansson/dump.c deleted file mode 100644 index f32f66760b..0000000000 --- a/compat/jansson/dump.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#define _GNU_SOURCE -#include -#include -#include -#include - -#include -#include "jansson_private.h" -#include "strbuffer.h" -#include "utf.h" - -#define MAX_INTEGER_STR_LENGTH 100 -#define MAX_REAL_STR_LENGTH 100 - -typedef int (*dump_func)(const char *buffer, int size, void *data); - -struct string -{ - char *buffer; - int length; - int size; -}; - -static int dump_to_strbuffer(const char *buffer, int size, void *data) -{ - return strbuffer_append_bytes((strbuffer_t *)data, buffer, size); -} - -static int dump_to_file(const char *buffer, int size, void *data) -{ - FILE *dest = (FILE *)data; - if(fwrite(buffer, size, 1, dest) != 1) - return -1; - return 0; -} - -/* 32 spaces (the maximum indentation size) */ -static char whitespace[] = " "; - -static int dump_indent(size_t flags, int depth, int space, dump_func dump, void *data) -{ - if(JSON_INDENT(flags) > 0) - { - int i, ws_count = JSON_INDENT(flags); - - if(dump("\n", 1, data)) - return -1; - - for(i = 0; i < depth; i++) - { - if(dump(whitespace, ws_count, data)) - return -1; - } - } - else if(space && !(flags & JSON_COMPACT)) - { - return dump(" ", 1, data); - } - return 0; -} - -static int dump_string(const char *str, int ascii, dump_func dump, void *data) -{ - const char *pos, *end; - int32_t codepoint; - - if(dump("\"", 1, data)) - return -1; - - end = pos = str; - while(1) - { - const char *text; - char seq[13]; - int length; - - while(*end) - { - end = utf8_iterate(pos, &codepoint); - if(!end) - return -1; - - /* mandatory escape or control char */ - if(codepoint == '\\' || codepoint == '"' || codepoint < 0x20) - break; - - /* non-ASCII */ - if(ascii && codepoint > 0x7F) - break; - - pos = end; - } - - if(pos != str) { - if(dump(str, pos - str, data)) - return -1; - } - - if(end == pos) - break; - - /* handle \, ", and control codes */ - length = 2; - switch(codepoint) - { - case '\\': text = "\\\\"; break; - case '\"': text = "\\\""; break; - case '\b': text = "\\b"; break; - case '\f': text = "\\f"; break; - case '\n': text = "\\n"; break; - case '\r': text = "\\r"; break; - case '\t': text = "\\t"; break; - default: - { - /* codepoint is in BMP */ - if(codepoint < 0x10000) - { - sprintf(seq, "\\u%04x", codepoint); - length = 6; - } - - /* not in BMP -> construct a UTF-16 surrogate pair */ - else - { - int32_t first, last; - - codepoint -= 0x10000; - first = 0xD800 | ((codepoint & 0xffc00) >> 10); - last = 0xDC00 | (codepoint & 0x003ff); - - sprintf(seq, "\\u%04x\\u%04x", first, last); - length = 12; - } - - text = seq; - break; - } - } - - if(dump(text, length, data)) - return -1; - - str = pos = end; - } - - return dump("\"", 1, data); -} - -static int object_key_compare_keys(const void *key1, const void *key2) -{ - return strcmp((*(const object_key_t **)key1)->key, - (*(const object_key_t **)key2)->key); -} - -static int object_key_compare_serials(const void *key1, const void *key2) -{ - return (*(const object_key_t **)key1)->serial - - (*(const object_key_t **)key2)->serial; -} - -static int do_dump(const json_t *json, size_t flags, int depth, - dump_func dump, void *data) -{ - int ascii = flags & JSON_ENSURE_ASCII ? 1 : 0; - - switch(json_typeof(json)) { - case JSON_NULL: - return dump("null", 4, data); - - case JSON_TRUE: - return dump("true", 4, data); - - case JSON_FALSE: - return dump("false", 5, data); - - case JSON_INTEGER: - { - char buffer[MAX_INTEGER_STR_LENGTH]; - int size; - - size = snprintf(buffer, MAX_INTEGER_STR_LENGTH, - "%" JSON_INTEGER_FORMAT, - json_integer_value(json)); - if(size >= MAX_INTEGER_STR_LENGTH) - return -1; - - return dump(buffer, size, data); - } - - case JSON_REAL: - { - char buffer[MAX_REAL_STR_LENGTH]; - int size; - - size = snprintf(buffer, MAX_REAL_STR_LENGTH, "%.17g", - json_real_value(json)); - if(size >= MAX_REAL_STR_LENGTH) - return -1; - - /* Make sure there's a dot or 'e' in the output. Otherwise - a real is converted to an integer when decoding */ - if(strchr(buffer, '.') == NULL && - strchr(buffer, 'e') == NULL) - { - if(size + 2 >= MAX_REAL_STR_LENGTH) { - /* No space to append ".0" */ - return -1; - } - buffer[size] = '.'; - buffer[size + 1] = '0'; - size += 2; - } - - return dump(buffer, size, data); - } - - case JSON_STRING: - return dump_string(json_string_value(json), ascii, dump, data); - - case JSON_ARRAY: - { - int i; - int n; - json_array_t *array; - - /* detect circular references */ - array = json_to_array(json); - if(array->visited) - goto array_error; - array->visited = 1; - - n = json_array_size(json); - - if(dump("[", 1, data)) - goto array_error; - if(n == 0) { - array->visited = 0; - return dump("]", 1, data); - } - if(dump_indent(flags, depth + 1, 0, dump, data)) - goto array_error; - - for(i = 0; i < n; ++i) { - if(do_dump(json_array_get(json, i), flags, depth + 1, - dump, data)) - goto array_error; - - if(i < n - 1) - { - if(dump(",", 1, data) || - dump_indent(flags, depth + 1, 1, dump, data)) - goto array_error; - } - else - { - if(dump_indent(flags, depth, 0, dump, data)) - goto array_error; - } - } - - array->visited = 0; - return dump("]", 1, data); - - array_error: - array->visited = 0; - return -1; - } - - case JSON_OBJECT: - { - json_object_t *object; - void *iter; - const char *separator; - int separator_length; - - if(flags & JSON_COMPACT) { - separator = ":"; - separator_length = 1; - } - else { - separator = ": "; - separator_length = 2; - } - - /* detect circular references */ - object = json_to_object(json); - if(object->visited) - goto object_error; - object->visited = 1; - - iter = json_object_iter((json_t *)json); - - if(dump("{", 1, data)) - goto object_error; - if(!iter) { - object->visited = 0; - return dump("}", 1, data); - } - if(dump_indent(flags, depth + 1, 0, dump, data)) - goto object_error; - - if(flags & JSON_SORT_KEYS || flags & JSON_PRESERVE_ORDER) - { - const object_key_t **keys; - size_t size, i; - int (*cmp_func)(const void *, const void *); - - size = json_object_size(json); - keys = jsonp_malloc(size * sizeof(object_key_t *)); - if(!keys) - goto object_error; - - i = 0; - while(iter) - { - keys[i] = jsonp_object_iter_fullkey(iter); - iter = json_object_iter_next((json_t *)json, iter); - i++; - } - assert(i == size); - - if(flags & JSON_SORT_KEYS) - cmp_func = object_key_compare_keys; - else - cmp_func = object_key_compare_serials; - - qsort(keys, size, sizeof(object_key_t *), cmp_func); - - for(i = 0; i < size; i++) - { - const char *key; - json_t *value; - - key = keys[i]->key; - value = json_object_get(json, key); - assert(value); - - dump_string(key, ascii, dump, data); - if(dump(separator, separator_length, data) || - do_dump(value, flags, depth + 1, dump, data)) - { - jsonp_free(keys); - goto object_error; - } - - if(i < size - 1) - { - if(dump(",", 1, data) || - dump_indent(flags, depth + 1, 1, dump, data)) - { - jsonp_free(keys); - goto object_error; - } - } - else - { - if(dump_indent(flags, depth, 0, dump, data)) - { - jsonp_free(keys); - goto object_error; - } - } - } - - jsonp_free(keys); - } - else - { - /* Don't sort keys */ - - while(iter) - { - void *next = json_object_iter_next((json_t *)json, iter); - - dump_string(json_object_iter_key(iter), ascii, dump, data); - if(dump(separator, separator_length, data) || - do_dump(json_object_iter_value(iter), flags, depth + 1, - dump, data)) - goto object_error; - - if(next) - { - if(dump(",", 1, data) || - dump_indent(flags, depth + 1, 1, dump, data)) - goto object_error; - } - else - { - if(dump_indent(flags, depth, 0, dump, data)) - goto object_error; - } - - iter = next; - } - } - - object->visited = 0; - return dump("}", 1, data); - - object_error: - object->visited = 0; - return -1; - } - - default: - /* not reached */ - return -1; - } -} - - -char *json_dumps(const json_t *json, size_t flags) -{ - strbuffer_t strbuff; - char *result; - - if(!(flags & JSON_ENCODE_ANY)) { - if(!json_is_array(json) && !json_is_object(json)) - return NULL; - } - - if(strbuffer_init(&strbuff)) - return NULL; - - if(do_dump(json, flags, 0, dump_to_strbuffer, (void *)&strbuff)) { - strbuffer_close(&strbuff); - return NULL; - } - - result = jsonp_strdup(strbuffer_value(&strbuff)); - strbuffer_close(&strbuff); - - return result; -} - -int json_dumpf(const json_t *json, FILE *output, size_t flags) -{ - if(!(flags & JSON_ENCODE_ANY)) { - if(!json_is_array(json) && !json_is_object(json)) - return -1; - } - - return do_dump(json, flags, 0, dump_to_file, (void *)output); -} - -int json_dump_file(const json_t *json, const char *path, size_t flags) -{ - int result; - - FILE *output = fopen(path, "w"); - if(!output) - return -1; - - result = json_dumpf(json, output, flags); - - fclose(output); - return result; -} diff --git a/compat/jansson/error.c b/compat/jansson/error.c deleted file mode 100644 index a7c8cbb9e5..0000000000 --- a/compat/jansson/error.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include "jansson_private.h" - -void jsonp_error_init(json_error_t *error, const char *source) -{ - if(error) - { - error->text[0] = '\0'; - error->line = -1; - error->column = -1; - error->position = 0; - if(source) - jsonp_error_set_source(error, source); - else - error->source[0] = '\0'; - } -} - -void jsonp_error_set_source(json_error_t *error, const char *source) -{ - size_t length; - - if(!error || !source) - return; - - length = strlen(source); - if(length < JSON_ERROR_SOURCE_LENGTH) - strcpy(error->source, source); - else { - size_t extra = length - JSON_ERROR_SOURCE_LENGTH + 4; - strcpy(error->source, "..."); - strcpy(error->source + 3, source + extra); - } -} - -void jsonp_error_set(json_error_t *error, int line, int column, - size_t position, const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - jsonp_error_vset(error, line, column, position, msg, ap); - va_end(ap); -} - -void jsonp_error_vset(json_error_t *error, int line, int column, - size_t position, const char *msg, va_list ap) -{ - if(!error) - return; - - if(error->text[0] != '\0') { - /* error already set */ - return; - } - - error->line = line; - error->column = column; - error->position = position; - - vsnprintf(error->text, JSON_ERROR_TEXT_LENGTH, msg, ap); -} diff --git a/compat/jansson/hashtable.c b/compat/jansson/hashtable.c deleted file mode 100644 index 9a3f73b36f..0000000000 --- a/compat/jansson/hashtable.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#include -#include /* for JSON_INLINE */ -#include "jansson_private.h" /* for container_of() */ -#include "hashtable.h" - -typedef struct hashtable_list list_t; -typedef struct hashtable_pair pair_t; -typedef struct hashtable_bucket bucket_t; - -#define list_to_pair(list_) container_of(list_, pair_t, list) - -static JSON_INLINE void list_init(list_t *list) -{ - list->next = list; - list->prev = list; -} - -static JSON_INLINE void list_insert(list_t *list, list_t *node) -{ - node->next = list; - node->prev = list->prev; - list->prev->next = node; - list->prev = node; -} - -static JSON_INLINE void list_remove(list_t *list) -{ - list->prev->next = list->next; - list->next->prev = list->prev; -} - -static JSON_INLINE int bucket_is_empty(hashtable_t *hashtable, bucket_t *bucket) -{ - return bucket->first == &hashtable->list && bucket->first == bucket->last; -} - -static void insert_to_bucket(hashtable_t *hashtable, bucket_t *bucket, - list_t *list) -{ - if(bucket_is_empty(hashtable, bucket)) - { - list_insert(&hashtable->list, list); - bucket->first = bucket->last = list; - } - else - { - list_insert(bucket->first, list); - bucket->first = list; - } -} - -static size_t primes[] = { - 5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, - 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, - 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, - 805306457, 1610612741 -}; -static const size_t num_primes = sizeof(primes) / sizeof(size_t); - -static JSON_INLINE size_t num_buckets(hashtable_t *hashtable) -{ - return primes[hashtable->num_buckets]; -} - - -static pair_t *hashtable_find_pair(hashtable_t *hashtable, bucket_t *bucket, - const void *key, size_t hash) -{ - list_t *list; - pair_t *pair; - - if(bucket_is_empty(hashtable, bucket)) - return NULL; - - list = bucket->first; - while(1) - { - pair = list_to_pair(list); - if(pair->hash == hash && hashtable->cmp_keys(pair->key, key)) - return pair; - - if(list == bucket->last) - break; - - list = list->next; - } - - return NULL; -} - -/* returns 0 on success, -1 if key was not found */ -static int hashtable_do_del(hashtable_t *hashtable, - const void *key, size_t hash) -{ - pair_t *pair; - bucket_t *bucket; - size_t index; - - index = hash % num_buckets(hashtable); - bucket = &hashtable->buckets[index]; - - pair = hashtable_find_pair(hashtable, bucket, key, hash); - if(!pair) - return -1; - - if(&pair->list == bucket->first && &pair->list == bucket->last) - bucket->first = bucket->last = &hashtable->list; - - else if(&pair->list == bucket->first) - bucket->first = pair->list.next; - - else if(&pair->list == bucket->last) - bucket->last = pair->list.prev; - - list_remove(&pair->list); - - if(hashtable->free_key) - hashtable->free_key(pair->key); - if(hashtable->free_value) - hashtable->free_value(pair->value); - - jsonp_free(pair); - hashtable->size--; - - return 0; -} - -static void hashtable_do_clear(hashtable_t *hashtable) -{ - list_t *list, *next; - pair_t *pair; - - for(list = hashtable->list.next; list != &hashtable->list; list = next) - { - next = list->next; - pair = list_to_pair(list); - if(hashtable->free_key) - hashtable->free_key(pair->key); - if(hashtable->free_value) - hashtable->free_value(pair->value); - jsonp_free(pair); - } -} - -static int hashtable_do_rehash(hashtable_t *hashtable) -{ - list_t *list, *next; - pair_t *pair; - size_t i, index, new_size; - - jsonp_free(hashtable->buckets); - - hashtable->num_buckets++; - new_size = num_buckets(hashtable); - - hashtable->buckets = jsonp_malloc(new_size * sizeof(bucket_t)); - if(!hashtable->buckets) - return -1; - - for(i = 0; i < num_buckets(hashtable); i++) - { - hashtable->buckets[i].first = hashtable->buckets[i].last = - &hashtable->list; - } - - list = hashtable->list.next; - list_init(&hashtable->list); - - for(; list != &hashtable->list; list = next) { - next = list->next; - pair = list_to_pair(list); - index = pair->hash % new_size; - insert_to_bucket(hashtable, &hashtable->buckets[index], &pair->list); - } - - return 0; -} - - -hashtable_t *hashtable_create(key_hash_fn hash_key, key_cmp_fn cmp_keys, - free_fn free_key, free_fn free_value) -{ - hashtable_t *hashtable = jsonp_malloc(sizeof(hashtable_t)); - if(!hashtable) - return NULL; - - if(hashtable_init(hashtable, hash_key, cmp_keys, free_key, free_value)) - { - jsonp_free(hashtable); - return NULL; - } - - return hashtable; -} - -void hashtable_destroy(hashtable_t *hashtable) -{ - hashtable_close(hashtable); - jsonp_free(hashtable); -} - -int hashtable_init(hashtable_t *hashtable, - key_hash_fn hash_key, key_cmp_fn cmp_keys, - free_fn free_key, free_fn free_value) -{ - size_t i; - - hashtable->size = 0; - hashtable->num_buckets = 0; /* index to primes[] */ - hashtable->buckets = jsonp_malloc(num_buckets(hashtable) * sizeof(bucket_t)); - if(!hashtable->buckets) - return -1; - - list_init(&hashtable->list); - - hashtable->hash_key = hash_key; - hashtable->cmp_keys = cmp_keys; - hashtable->free_key = free_key; - hashtable->free_value = free_value; - - for(i = 0; i < num_buckets(hashtable); i++) - { - hashtable->buckets[i].first = hashtable->buckets[i].last = - &hashtable->list; - } - - return 0; -} - -void hashtable_close(hashtable_t *hashtable) -{ - hashtable_do_clear(hashtable); - jsonp_free(hashtable->buckets); -} - -int hashtable_set(hashtable_t *hashtable, void *key, void *value) -{ - pair_t *pair; - bucket_t *bucket; - size_t hash, index; - - /* rehash if the load ratio exceeds 1 */ - if(hashtable->size >= num_buckets(hashtable)) - if(hashtable_do_rehash(hashtable)) - return -1; - - hash = hashtable->hash_key(key); - index = hash % num_buckets(hashtable); - bucket = &hashtable->buckets[index]; - pair = hashtable_find_pair(hashtable, bucket, key, hash); - - if(pair) - { - if(hashtable->free_key) - hashtable->free_key(key); - if(hashtable->free_value) - hashtable->free_value(pair->value); - pair->value = value; - } - else - { - pair = jsonp_malloc(sizeof(pair_t)); - if(!pair) - return -1; - - pair->key = key; - pair->value = value; - pair->hash = hash; - list_init(&pair->list); - - insert_to_bucket(hashtable, bucket, &pair->list); - - hashtable->size++; - } - return 0; -} - -void *hashtable_get(hashtable_t *hashtable, const void *key) -{ - pair_t *pair; - size_t hash; - bucket_t *bucket; - - hash = hashtable->hash_key(key); - bucket = &hashtable->buckets[hash % num_buckets(hashtable)]; - - pair = hashtable_find_pair(hashtable, bucket, key, hash); - if(!pair) - return NULL; - - return pair->value; -} - -int hashtable_del(hashtable_t *hashtable, const void *key) -{ - size_t hash = hashtable->hash_key(key); - return hashtable_do_del(hashtable, key, hash); -} - -void hashtable_clear(hashtable_t *hashtable) -{ - size_t i; - - hashtable_do_clear(hashtable); - - for(i = 0; i < num_buckets(hashtable); i++) - { - hashtable->buckets[i].first = hashtable->buckets[i].last = - &hashtable->list; - } - - list_init(&hashtable->list); - hashtable->size = 0; -} - -void *hashtable_iter(hashtable_t *hashtable) -{ - return hashtable_iter_next(hashtable, &hashtable->list); -} - -void *hashtable_iter_at(hashtable_t *hashtable, const void *key) -{ - pair_t *pair; - size_t hash; - bucket_t *bucket; - - hash = hashtable->hash_key(key); - bucket = &hashtable->buckets[hash % num_buckets(hashtable)]; - - pair = hashtable_find_pair(hashtable, bucket, key, hash); - if(!pair) - return NULL; - - return &pair->list; -} - -void *hashtable_iter_next(hashtable_t *hashtable, void *iter) -{ - list_t *list = (list_t *)iter; - if(list->next == &hashtable->list) - return NULL; - return list->next; -} - -void *hashtable_iter_key(void *iter) -{ - pair_t *pair = list_to_pair((list_t *)iter); - return pair->key; -} - -void *hashtable_iter_value(void *iter) -{ - pair_t *pair = list_to_pair((list_t *)iter); - return pair->value; -} - -void hashtable_iter_set(hashtable_t *hashtable, void *iter, void *value) -{ - pair_t *pair = list_to_pair((list_t *)iter); - - if(hashtable->free_value) - hashtable->free_value(pair->value); - - pair->value = value; -} diff --git a/compat/jansson/hashtable.h b/compat/jansson/hashtable.h deleted file mode 100644 index 5aed14f2ef..0000000000 --- a/compat/jansson/hashtable.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#ifndef HASHTABLE_H -#define HASHTABLE_H - -typedef size_t (*key_hash_fn)(const void *key); -typedef int (*key_cmp_fn)(const void *key1, const void *key2); -typedef void (*free_fn)(void *key); - -struct hashtable_list { - struct hashtable_list *prev; - struct hashtable_list *next; -}; - -struct hashtable_pair { - void *key; - void *value; - size_t hash; - struct hashtable_list list; -}; - -struct hashtable_bucket { - struct hashtable_list *first; - struct hashtable_list *last; -}; - -typedef struct hashtable { - size_t size; - struct hashtable_bucket *buckets; - size_t num_buckets; /* index to primes[] */ - struct hashtable_list list; - - key_hash_fn hash_key; - key_cmp_fn cmp_keys; /* returns non-zero for equal keys */ - free_fn free_key; - free_fn free_value; -} hashtable_t; - -/** - * hashtable_create - Create a hashtable object - * - * @hash_key: The key hashing function - * @cmp_keys: The key compare function. Returns non-zero for equal and - * zero for unequal unequal keys - * @free_key: If non-NULL, called for a key that is no longer referenced. - * @free_value: If non-NULL, called for a value that is no longer referenced. - * - * Returns a new hashtable object that should be freed with - * hashtable_destroy when it's no longer used, or NULL on failure (out - * of memory). - */ -hashtable_t *hashtable_create(key_hash_fn hash_key, key_cmp_fn cmp_keys, - free_fn free_key, free_fn free_value); - -/** - * hashtable_destroy - Destroy a hashtable object - * - * @hashtable: The hashtable - * - * Destroys a hashtable created with hashtable_create(). - */ -void hashtable_destroy(hashtable_t *hashtable); - -/** - * hashtable_init - Initialize a hashtable object - * - * @hashtable: The (statically allocated) hashtable object - * @hash_key: The key hashing function - * @cmp_keys: The key compare function. Returns non-zero for equal and - * zero for unequal unequal keys - * @free_key: If non-NULL, called for a key that is no longer referenced. - * @free_value: If non-NULL, called for a value that is no longer referenced. - * - * Initializes a statically allocated hashtable object. The object - * should be cleared with hashtable_close when it's no longer used. - * - * Returns 0 on success, -1 on error (out of memory). - */ -int hashtable_init(hashtable_t *hashtable, - key_hash_fn hash_key, key_cmp_fn cmp_keys, - free_fn free_key, free_fn free_value); - -/** - * hashtable_close - Release all resources used by a hashtable object - * - * @hashtable: The hashtable - * - * Destroys a statically allocated hashtable object. - */ -void hashtable_close(hashtable_t *hashtable); - -/** - * hashtable_set - Add/modify value in hashtable - * - * @hashtable: The hashtable object - * @key: The key - * @value: The value - * - * If a value with the given key already exists, its value is replaced - * with the new value. - * - * Key and value are "stealed" in the sense that hashtable frees them - * automatically when they are no longer used. The freeing is - * accomplished by calling free_key and free_value functions that were - * supplied to hashtable_new. In case one or both of the free - * functions is NULL, the corresponding item is not "stealed". - * - * Returns 0 on success, -1 on failure (out of memory). - */ -int hashtable_set(hashtable_t *hashtable, void *key, void *value); - -/** - * hashtable_get - Get a value associated with a key - * - * @hashtable: The hashtable object - * @key: The key - * - * Returns value if it is found, or NULL otherwise. - */ -void *hashtable_get(hashtable_t *hashtable, const void *key); - -/** - * hashtable_del - Remove a value from the hashtable - * - * @hashtable: The hashtable object - * @key: The key - * - * Returns 0 on success, or -1 if the key was not found. - */ -int hashtable_del(hashtable_t *hashtable, const void *key); - -/** - * hashtable_clear - Clear hashtable - * - * @hashtable: The hashtable object - * - * Removes all items from the hashtable. - */ -void hashtable_clear(hashtable_t *hashtable); - -/** - * hashtable_iter - Iterate over hashtable - * - * @hashtable: The hashtable object - * - * Returns an opaque iterator to the first element in the hashtable. - * The iterator should be passed to hashtable_iter_* functions. - * The hashtable items are not iterated over in any particular order. - * - * There's no need to free the iterator in any way. The iterator is - * valid as long as the item that is referenced by the iterator is not - * deleted. Other values may be added or deleted. In particular, - * hashtable_iter_next() may be called on an iterator, and after that - * the key/value pair pointed by the old iterator may be deleted. - */ -void *hashtable_iter(hashtable_t *hashtable); - -/** - * hashtable_iter_at - Return an iterator at a specific key - * - * @hashtable: The hashtable object - * @key: The key that the iterator should point to - * - * Like hashtable_iter() but returns an iterator pointing to a - * specific key. - */ -void *hashtable_iter_at(hashtable_t *hashtable, const void *key); - -/** - * hashtable_iter_next - Advance an iterator - * - * @hashtable: The hashtable object - * @iter: The iterator - * - * Returns a new iterator pointing to the next element in the - * hashtable or NULL if the whole hastable has been iterated over. - */ -void *hashtable_iter_next(hashtable_t *hashtable, void *iter); - -/** - * hashtable_iter_key - Retrieve the key pointed by an iterator - * - * @iter: The iterator - */ -void *hashtable_iter_key(void *iter); - -/** - * hashtable_iter_value - Retrieve the value pointed by an iterator - * - * @iter: The iterator - */ -void *hashtable_iter_value(void *iter); - -/** - * hashtable_iter_set - Set the value pointed by an iterator - * - * @iter: The iterator - * @value: The value to set - */ -void hashtable_iter_set(hashtable_t *hashtable, void *iter, void *value); - -#endif diff --git a/compat/jansson/jansson.h b/compat/jansson/jansson.h deleted file mode 100644 index 9372ec2087..0000000000 --- a/compat/jansson/jansson.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#ifndef JANSSON_H -#define JANSSON_H - -#include -#include /* for size_t */ -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* version */ - -#define JANSSON_MAJOR_VERSION 2 -#define JANSSON_MINOR_VERSION 1 -#define JANSSON_MICRO_VERSION 0 - -/* Micro version is omitted if it's 0 */ -#define JANSSON_VERSION "2.1" - -/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this - for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */ -#define JANSSON_VERSION_HEX ((JANSSON_MAJOR_VERSION << 16) | \ - (JANSSON_MINOR_VERSION << 8) | \ - (JANSSON_MICRO_VERSION << 0)) - - -/* types */ - -typedef enum { - JSON_OBJECT, - JSON_ARRAY, - JSON_STRING, - JSON_INTEGER, - JSON_REAL, - JSON_TRUE, - JSON_FALSE, - JSON_NULL -} json_type; - -typedef struct { - json_type type; - size_t refcount; -} json_t; - -#if JSON_INTEGER_IS_LONG_LONG && (!defined(WIN32)) -#define JSON_INTEGER_FORMAT "lld" -typedef long long json_int_t; -#else -#define JSON_INTEGER_FORMAT "ld" -typedef long json_int_t; -#endif /* JSON_INTEGER_IS_LONG_LONG */ - -#define json_typeof(json) ((json)->type) -#define json_is_object(json) (json && json_typeof(json) == JSON_OBJECT) -#define json_is_array(json) (json && json_typeof(json) == JSON_ARRAY) -#define json_is_string(json) (json && json_typeof(json) == JSON_STRING) -#define json_is_integer(json) (json && json_typeof(json) == JSON_INTEGER) -#define json_is_real(json) (json && json_typeof(json) == JSON_REAL) -#define json_is_number(json) (json_is_integer(json) || json_is_real(json)) -#define json_is_true(json) (json && json_typeof(json) == JSON_TRUE) -#define json_is_false(json) (json && json_typeof(json) == JSON_FALSE) -#define json_is_boolean(json) (json_is_true(json) || json_is_false(json)) -#define json_is_null(json) (json && json_typeof(json) == JSON_NULL) - -/* construction, destruction, reference counting */ - -json_t *json_object(void); -json_t *json_array(void); -json_t *json_string(const char *value); -json_t *json_string_nocheck(const char *value); -json_t *json_integer(json_int_t value); -json_t *json_real(double value); -json_t *json_true(void); -json_t *json_false(void); -json_t *json_null(void); - -static JSON_INLINE -json_t *json_incref(json_t *json) -{ - if(json && json->refcount != (size_t)-1) - ++json->refcount; - return json; -} - -/* do not call json_delete directly */ -void json_delete(json_t *json); - -static JSON_INLINE -void json_decref(json_t *json) -{ - if(json && json->refcount != (size_t)-1 && --json->refcount == 0) - json_delete(json); -} - - -/* error reporting */ - -#define JSON_ERROR_TEXT_LENGTH 160 -#define JSON_ERROR_SOURCE_LENGTH 80 - -typedef struct { - int line; - int column; - int position; - char source[JSON_ERROR_SOURCE_LENGTH]; - char text[JSON_ERROR_TEXT_LENGTH]; -} json_error_t; - - -/* getters, setters, manipulation */ - -size_t json_object_size(const json_t *object); -json_t *json_object_get(const json_t *object, const char *key); -int json_object_set_new(json_t *object, const char *key, json_t *value); -int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value); -int json_object_del(json_t *object, const char *key); -int json_object_clear(json_t *object); -int json_object_update(json_t *object, json_t *other); -void *json_object_iter(json_t *object); -void *json_object_iter_at(json_t *object, const char *key); -void *json_object_iter_next(json_t *object, void *iter); -const char *json_object_iter_key(void *iter); -json_t *json_object_iter_value(void *iter); -int json_object_iter_set_new(json_t *object, void *iter, json_t *value); - -static JSON_INLINE -int json_object_set(json_t *object, const char *key, json_t *value) -{ - return json_object_set_new(object, key, json_incref(value)); -} - -static JSON_INLINE -int json_object_set_nocheck(json_t *object, const char *key, json_t *value) -{ - return json_object_set_new_nocheck(object, key, json_incref(value)); -} - -static JSON_INLINE -int json_object_iter_set(json_t *object, void *iter, json_t *value) -{ - return json_object_iter_set_new(object, iter, json_incref(value)); -} - -size_t json_array_size(const json_t *array); -json_t *json_array_get(const json_t *array, size_t index); -int json_array_set_new(json_t *array, size_t index, json_t *value); -int json_array_append_new(json_t *array, json_t *value); -int json_array_insert_new(json_t *array, size_t index, json_t *value); -int json_array_remove(json_t *array, size_t index); -int json_array_clear(json_t *array); -int json_array_extend(json_t *array, json_t *other); - -static JSON_INLINE -int json_array_set(json_t *array, size_t index, json_t *value) -{ - return json_array_set_new(array, index, json_incref(value)); -} - -static JSON_INLINE -int json_array_append(json_t *array, json_t *value) -{ - return json_array_append_new(array, json_incref(value)); -} - -static JSON_INLINE -int json_array_insert(json_t *array, size_t index, json_t *value) -{ - return json_array_insert_new(array, index, json_incref(value)); -} - -const char *json_string_value(const json_t *string); -json_int_t json_integer_value(const json_t *integer); -double json_real_value(const json_t *real); -double json_number_value(const json_t *json); - -int json_string_set(json_t *string, const char *value); -int json_string_set_nocheck(json_t *string, const char *value); -int json_integer_set(json_t *integer, json_int_t value); -int json_real_set(json_t *real, double value); - - -/* pack, unpack */ - -json_t *json_pack(const char *fmt, ...); -json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...); -json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap); - -#define JSON_VALIDATE_ONLY 0x1 -#define JSON_STRICT 0x2 - -int json_unpack(json_t *root, const char *fmt, ...); -int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...); -int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, va_list ap); - - -/* equality */ - -int json_equal(json_t *value1, json_t *value2); - - -/* copying */ - -json_t *json_copy(json_t *value); -json_t *json_deep_copy(json_t *value); - - -/* decoding */ - -#define JSON_REJECT_DUPLICATES 0x1 -#define JSON_DISABLE_EOF_CHECK 0x2 - -json_t *json_loads(const char *input, size_t flags, json_error_t *error); -json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error); -json_t *json_loadf(FILE *input, size_t flags, json_error_t *error); -json_t *json_load_file(const char *path, size_t flags, json_error_t *error); - - -/* encoding */ - -#define JSON_INDENT(n) (n & 0x1F) -#define JSON_COMPACT 0x20 -#define JSON_ENSURE_ASCII 0x40 -#define JSON_SORT_KEYS 0x80 -#define JSON_PRESERVE_ORDER 0x100 -#define JSON_ENCODE_ANY 0x200 - -char *json_dumps(const json_t *json, size_t flags); -int json_dumpf(const json_t *json, FILE *output, size_t flags); -int json_dump_file(const json_t *json, const char *path, size_t flags); - - -/* custom memory allocation */ - -typedef void *(*json_malloc_t)(size_t); -typedef void (*json_free_t)(void *); - -void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/compat/jansson/jansson_config.h b/compat/jansson/jansson_config.h deleted file mode 100644 index b3bb72a4cf..0000000000 --- a/compat/jansson/jansson_config.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2010-2011 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - * - * - * This file specifies a part of the site-specific configuration for - * Jansson, namely those things that affect the public API in - * jansson.h. - * - * The configure script copies this file to jansson_config.h and - * replaces @var@ substitutions by values that fit your system. If you - * cannot run the configure script, you can do the value substitution - * by hand. - */ - -#ifndef JANSSON_CONFIG_H -#define JANSSON_CONFIG_H - -/* If your compiler supports the inline keyword in C, JSON_INLINE is - defined to `inline', otherwise empty. In C++, the inline is always - supported. */ -#ifdef __cplusplus -#define JSON_INLINE inline -#else -#define JSON_INLINE inline -#endif - -/* If your compiler supports the `long long` type, - JSON_INTEGER_IS_LONG_LONG is defined to 1, otherwise to 0. */ -#define JSON_INTEGER_IS_LONG_LONG 1 - -#endif diff --git a/compat/jansson/jansson_config.h.in b/compat/jansson/jansson_config.h.in deleted file mode 100644 index 7f519cd645..0000000000 --- a/compat/jansson/jansson_config.h.in +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2010-2011 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - * - * - * This file specifies a part of the site-specific configuration for - * Jansson, namely those things that affect the public API in - * jansson.h. - * - * The configure script copies this file to jansson_config.h and - * replaces @var@ substitutions by values that fit your system. If you - * cannot run the configure script, you can do the value substitution - * by hand. - */ - -#ifndef JANSSON_CONFIG_H -#define JANSSON_CONFIG_H - -/* If your compiler supports the inline keyword in C, JSON_INLINE is - defined to `inline', otherwise empty. In C++, the inline is always - supported. */ -#ifdef __cplusplus -#define JSON_INLINE inline -#else -#define JSON_INLINE @json_inline@ -#endif - -/* If your compiler supports the `long long` type, - JSON_INTEGER_IS_LONG_LONG is defined to 1, otherwise to 0. */ -#define JSON_INTEGER_IS_LONG_LONG @json_have_long_long@ - -#endif diff --git a/compat/jansson/jansson_private.h b/compat/jansson/jansson_private.h deleted file mode 100644 index 452a4f08e3..0000000000 --- a/compat/jansson/jansson_private.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#ifndef JANSSON_PRIVATE_H -#define JANSSON_PRIVATE_H - -#include -#include "jansson.h" -#include "hashtable.h" - -#define container_of(ptr_, type_, member_) \ - ((type_ *)((char *)ptr_ - offsetof(type_, member_))) - -/* On some platforms, max() may already be defined */ -#ifndef max -#define max(a, b) ((a) > (b) ? (a) : (b)) -#endif - -/* va_copy is a C99 feature. In C89 implementations, it's sometimes - available as __va_copy. If not, memcpy() should do the trick. */ -#ifndef va_copy -#ifdef __va_copy -#define va_copy __va_copy -#else -#define va_copy(a, b) memcpy(&(a), &(b), sizeof(va_list)) -#endif -#endif - -typedef struct { - json_t json; - hashtable_t hashtable; - size_t serial; - int visited; -} json_object_t; - -typedef struct { - json_t json; - size_t size; - size_t entries; - json_t **table; - int visited; -} json_array_t; - -typedef struct { - json_t json; - char *value; -} json_string_t; - -typedef struct { - json_t json; - double value; -} json_real_t; - -typedef struct { - json_t json; - json_int_t value; -} json_integer_t; - -#define json_to_object(json_) container_of(json_, json_object_t, json) -#define json_to_array(json_) container_of(json_, json_array_t, json) -#define json_to_string(json_) container_of(json_, json_string_t, json) -#define json_to_real(json_) container_of(json_, json_real_t, json) -#define json_to_integer(json_) container_of(json_, json_integer_t, json) - -size_t jsonp_hash_str(const void *ptr); -int jsonp_str_equal(const void *ptr1, const void *ptr2); - -typedef struct { - size_t serial; - char key[1]; -} object_key_t; - -const object_key_t *jsonp_object_iter_fullkey(void *iter); - -void jsonp_error_init(json_error_t *error, const char *source); -void jsonp_error_set_source(json_error_t *error, const char *source); -void jsonp_error_set(json_error_t *error, int line, int column, - size_t position, const char *msg, ...); -void jsonp_error_vset(json_error_t *error, int line, int column, - size_t position, const char *msg, va_list ap); - -/* Wrappers for custom memory functions */ -void* jsonp_malloc(size_t size); -void jsonp_free(void *ptr); -char *jsonp_strdup(const char *str); - -#endif diff --git a/compat/jansson/load.c b/compat/jansson/load.c deleted file mode 100644 index 8a53f135f9..0000000000 --- a/compat/jansson/load.c +++ /dev/null @@ -1,960 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include - -#include -#include "jansson_private.h" -#include "strbuffer.h" -#include "utf.h" - -#define STREAM_STATE_OK 0 -#define STREAM_STATE_EOF -1 -#define STREAM_STATE_ERROR -2 - -#define TOKEN_INVALID -1 -#define TOKEN_EOF 0 -#define TOKEN_STRING 256 -#define TOKEN_INTEGER 257 -#define TOKEN_REAL 258 -#define TOKEN_TRUE 259 -#define TOKEN_FALSE 260 -#define TOKEN_NULL 261 - -/* Read one byte from stream, convert to unsigned char, then int, and - return. return EOF on end of file. This corresponds to the - behaviour of fgetc(). */ -typedef int (*get_func)(void *data); - -typedef struct { - get_func get; - void *data; - char buffer[5]; - int buffer_pos; - int state; - int line; - int column, last_column; - size_t position; -} stream_t; - -typedef struct { - stream_t stream; - strbuffer_t saved_text; - int token; - union { - char *string; - json_int_t integer; - double real; - } value; -} lex_t; - -#define stream_to_lex(stream) container_of(stream, lex_t, stream) - - -/*** error reporting ***/ - -static void error_set(json_error_t *error, const lex_t *lex, - const char *msg, ...) -{ - va_list ap; - char msg_text[JSON_ERROR_TEXT_LENGTH]; - - int line = -1, col = -1; - size_t pos = 0; - const char *result = msg_text; - - if(!error) - return; - - va_start(ap, msg); - vsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap); - va_end(ap); - - if(lex) - { - const char *saved_text = strbuffer_value(&lex->saved_text); - char msg_with_context[JSON_ERROR_TEXT_LENGTH]; - - line = lex->stream.line; - col = lex->stream.column; - pos = lex->stream.position; - - if(saved_text && saved_text[0]) - { - if(lex->saved_text.length <= 20) { - snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, - "%s near '%s'", msg_text, saved_text); - result = msg_with_context; - } - } - else - { - if(lex->stream.state == STREAM_STATE_ERROR) { - /* No context for UTF-8 decoding errors */ - result = msg_text; - } - else { - snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, - "%s near end of file", msg_text); - result = msg_with_context; - } - } - } - - jsonp_error_set(error, line, col, pos, "%s", result); -} - - -/*** lexical analyzer ***/ - -static void -stream_init(stream_t *stream, get_func get, void *data) -{ - stream->get = get; - stream->data = data; - stream->buffer[0] = '\0'; - stream->buffer_pos = 0; - - stream->state = STREAM_STATE_OK; - stream->line = 1; - stream->column = 0; - stream->position = 0; -} - -static int stream_get(stream_t *stream, json_error_t *error) -{ - int c; - - if(stream->state != STREAM_STATE_OK) - return stream->state; - - if(!stream->buffer[stream->buffer_pos]) - { - c = stream->get(stream->data); - if(c == EOF) { - stream->state = STREAM_STATE_EOF; - return STREAM_STATE_EOF; - } - - stream->buffer[0] = c; - stream->buffer_pos = 0; - - if(0x80 <= c && c <= 0xFF) - { - /* multi-byte UTF-8 sequence */ - int i, count; - - count = utf8_check_first(c); - if(!count) - goto out; - - assert(count >= 2); - - for(i = 1; i < count; i++) - stream->buffer[i] = stream->get(stream->data); - - if(!utf8_check_full(stream->buffer, count, NULL)) - goto out; - - stream->buffer[count] = '\0'; - } - else - stream->buffer[1] = '\0'; - } - - c = stream->buffer[stream->buffer_pos++]; - - stream->position++; - if(c == '\n') { - stream->line++; - stream->last_column = stream->column; - stream->column = 0; - } - else if(utf8_check_first(c)) { - /* track the Unicode character column, so increment only if - this is the first character of a UTF-8 sequence */ - stream->column++; - } - - return c; - -out: - stream->state = STREAM_STATE_ERROR; - error_set(error, stream_to_lex(stream), "unable to decode byte 0x%x", c); - return STREAM_STATE_ERROR; -} - -static void stream_unget(stream_t *stream, int c) -{ - if(c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR) - return; - - stream->position--; - if(c == '\n') { - stream->line--; - stream->column = stream->last_column; - } - else if(utf8_check_first(c)) - stream->column--; - - assert(stream->buffer_pos > 0); - stream->buffer_pos--; - assert(stream->buffer[stream->buffer_pos] == c); -} - - -static int lex_get(lex_t *lex, json_error_t *error) -{ - return stream_get(&lex->stream, error); -} - -static void lex_save(lex_t *lex, int c) -{ - strbuffer_append_byte(&lex->saved_text, c); -} - -static int lex_get_save(lex_t *lex, json_error_t *error) -{ - int c = stream_get(&lex->stream, error); - if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) - lex_save(lex, c); - return c; -} - -static void lex_unget(lex_t *lex, int c) -{ - stream_unget(&lex->stream, c); -} - -static void lex_unget_unsave(lex_t *lex, int c) -{ - if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) { - char d; - stream_unget(&lex->stream, c); - d = strbuffer_pop(&lex->saved_text); - assert(c == d); - } -} - -static void lex_save_cached(lex_t *lex) -{ - while(lex->stream.buffer[lex->stream.buffer_pos] != '\0') - { - lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]); - lex->stream.buffer_pos++; - lex->stream.position++; - } -} - -/* assumes that str points to 'u' plus at least 4 valid hex digits */ -static int32_t decode_unicode_escape(const char *str) -{ - int i; - int32_t value = 0; - - assert(str[0] == 'u'); - - for(i = 1; i <= 4; i++) { - char c = str[i]; - value <<= 4; - if(isdigit(c)) - value += c - '0'; - else if(islower(c)) - value += c - 'a' + 10; - else if(isupper(c)) - value += c - 'A' + 10; - else - assert(0); - } - - return value; -} - -static void lex_scan_string(lex_t *lex, json_error_t *error) -{ - int c; - const char *p; - char *t; - int i; - - lex->value.string = NULL; - lex->token = TOKEN_INVALID; - - c = lex_get_save(lex, error); - - while(c != '"') { - if(c == STREAM_STATE_ERROR) - goto out; - - else if(c == STREAM_STATE_EOF) { - error_set(error, lex, "premature end of input"); - goto out; - } - - else if(0 <= c && c <= 0x1F) { - /* control character */ - lex_unget_unsave(lex, c); - if(c == '\n') - error_set(error, lex, "unexpected newline", c); - else - error_set(error, lex, "control character 0x%x", c); - goto out; - } - - else if(c == '\\') { - c = lex_get_save(lex, error); - if(c == 'u') { - c = lex_get_save(lex, error); - for(i = 0; i < 4; i++) { - if(!isxdigit(c)) { - error_set(error, lex, "invalid escape"); - goto out; - } - c = lex_get_save(lex, error); - } - } - else if(c == '"' || c == '\\' || c == '/' || c == 'b' || - c == 'f' || c == 'n' || c == 'r' || c == 't') - c = lex_get_save(lex, error); - else { - error_set(error, lex, "invalid escape"); - goto out; - } - } - else - c = lex_get_save(lex, error); - } - - /* the actual value is at most of the same length as the source - string, because: - - shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte - - a single \uXXXX escape (length 6) is converted to at most 3 bytes - - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair - are converted to 4 bytes - */ - lex->value.string = jsonp_malloc(lex->saved_text.length + 1); - if(!lex->value.string) { - /* this is not very nice, since TOKEN_INVALID is returned */ - goto out; - } - - /* the target */ - t = lex->value.string; - - /* + 1 to skip the " */ - p = strbuffer_value(&lex->saved_text) + 1; - - while(*p != '"') { - if(*p == '\\') { - p++; - if(*p == 'u') { - char buffer[4]; - int length; - int32_t value; - - value = decode_unicode_escape(p); - p += 5; - - if(0xD800 <= value && value <= 0xDBFF) { - /* surrogate pair */ - if(*p == '\\' && *(p + 1) == 'u') { - int32_t value2 = decode_unicode_escape(++p); - p += 5; - - if(0xDC00 <= value2 && value2 <= 0xDFFF) { - /* valid second surrogate */ - value = - ((value - 0xD800) << 10) + - (value2 - 0xDC00) + - 0x10000; - } - else { - /* invalid second surrogate */ - error_set(error, lex, - "invalid Unicode '\\u%04X\\u%04X'", - value, value2); - goto out; - } - } - else { - /* no second surrogate */ - error_set(error, lex, "invalid Unicode '\\u%04X'", - value); - goto out; - } - } - else if(0xDC00 <= value && value <= 0xDFFF) { - error_set(error, lex, "invalid Unicode '\\u%04X'", value); - goto out; - } - else if(value == 0) - { - error_set(error, lex, "\\u0000 is not allowed"); - goto out; - } - - if(utf8_encode(value, buffer, &length)) - assert(0); - - memcpy(t, buffer, length); - t += length; - } - else { - switch(*p) { - case '"': case '\\': case '/': - *t = *p; break; - case 'b': *t = '\b'; break; - case 'f': *t = '\f'; break; - case 'n': *t = '\n'; break; - case 'r': *t = '\r'; break; - case 't': *t = '\t'; break; - default: assert(0); - } - t++; - p++; - } - } - else - *(t++) = *(p++); - } - *t = '\0'; - lex->token = TOKEN_STRING; - return; - -out: - jsonp_free(lex->value.string); -} - -#if JSON_INTEGER_IS_LONG_LONG -#define json_strtoint strtoll -#else -#define json_strtoint strtol -#endif - -static int lex_scan_number(lex_t *lex, int c, json_error_t *error) -{ - const char *saved_text; - char *end; - double value; - - lex->token = TOKEN_INVALID; - - if(c == '-') - c = lex_get_save(lex, error); - - if(c == '0') { - c = lex_get_save(lex, error); - if(isdigit(c)) { - lex_unget_unsave(lex, c); - goto out; - } - } - else if(isdigit(c)) { - c = lex_get_save(lex, error); - while(isdigit(c)) - c = lex_get_save(lex, error); - } - else { - lex_unget_unsave(lex, c); - goto out; - } - - if(c != '.' && c != 'E' && c != 'e') { - json_int_t value; - - lex_unget_unsave(lex, c); - - saved_text = strbuffer_value(&lex->saved_text); - - errno = 0; - value = json_strtoint(saved_text, &end, 10); - if(errno == ERANGE) { - if(value < 0) - error_set(error, lex, "too big negative integer"); - else - error_set(error, lex, "too big integer"); - goto out; - } - - assert(end == saved_text + lex->saved_text.length); - - lex->token = TOKEN_INTEGER; - lex->value.integer = value; - return 0; - } - - if(c == '.') { - c = lex_get(lex, error); - if(!isdigit(c)) { - lex_unget(lex, c); - goto out; - } - lex_save(lex, c); - - c = lex_get_save(lex, error); - while(isdigit(c)) - c = lex_get_save(lex, error); - } - - if(c == 'E' || c == 'e') { - c = lex_get_save(lex, error); - if(c == '+' || c == '-') - c = lex_get_save(lex, error); - - if(!isdigit(c)) { - lex_unget_unsave(lex, c); - goto out; - } - - c = lex_get_save(lex, error); - while(isdigit(c)) - c = lex_get_save(lex, error); - } - - lex_unget_unsave(lex, c); - - saved_text = strbuffer_value(&lex->saved_text); - errno = 0; - value = strtod(saved_text, &end); - assert(end == saved_text + lex->saved_text.length); - - if(errno == ERANGE && value != 0) { - error_set(error, lex, "real number overflow"); - goto out; - } - - lex->token = TOKEN_REAL; - lex->value.real = value; - return 0; - -out: - return -1; -} - -static int lex_scan(lex_t *lex, json_error_t *error) -{ - int c; - - strbuffer_clear(&lex->saved_text); - - if(lex->token == TOKEN_STRING) { - jsonp_free(lex->value.string); - lex->value.string = NULL; - } - - c = lex_get(lex, error); - while(c == ' ' || c == '\t' || c == '\n' || c == '\r') - c = lex_get(lex, error); - - if(c == STREAM_STATE_EOF) { - lex->token = TOKEN_EOF; - goto out; - } - - if(c == STREAM_STATE_ERROR) { - lex->token = TOKEN_INVALID; - goto out; - } - - lex_save(lex, c); - - if(c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',') - lex->token = c; - - else if(c == '"') - lex_scan_string(lex, error); - - else if(isdigit(c) || c == '-') { - if(lex_scan_number(lex, c, error)) - goto out; - } - - else if(isupper(c) || islower(c)) { - /* eat up the whole identifier for clearer error messages */ - const char *saved_text; - - c = lex_get_save(lex, error); - while(isupper(c) || islower(c)) - c = lex_get_save(lex, error); - lex_unget_unsave(lex, c); - - saved_text = strbuffer_value(&lex->saved_text); - - if(strcmp(saved_text, "true") == 0) - lex->token = TOKEN_TRUE; - else if(strcmp(saved_text, "false") == 0) - lex->token = TOKEN_FALSE; - else if(strcmp(saved_text, "null") == 0) - lex->token = TOKEN_NULL; - else - lex->token = TOKEN_INVALID; - } - - else { - /* save the rest of the input UTF-8 sequence to get an error - message of valid UTF-8 */ - lex_save_cached(lex); - lex->token = TOKEN_INVALID; - } - -out: - return lex->token; -} - -static char *lex_steal_string(lex_t *lex) -{ - char *result = NULL; - if(lex->token == TOKEN_STRING) - { - result = lex->value.string; - lex->value.string = NULL; - } - return result; -} - -static int lex_init(lex_t *lex, get_func get, void *data) -{ - stream_init(&lex->stream, get, data); - if(strbuffer_init(&lex->saved_text)) - return -1; - - lex->token = TOKEN_INVALID; - return 0; -} - -static void lex_close(lex_t *lex) -{ - if(lex->token == TOKEN_STRING) - jsonp_free(lex->value.string); - strbuffer_close(&lex->saved_text); -} - - -/*** parser ***/ - -static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error); - -static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error) -{ - json_t *object = json_object(); - if(!object) - return NULL; - - lex_scan(lex, error); - if(lex->token == '}') - return object; - - while(1) { - char *key; - json_t *value; - - if(lex->token != TOKEN_STRING) { - error_set(error, lex, "string or '}' expected"); - goto error; - } - - key = lex_steal_string(lex); - if(!key) - return NULL; - - if(flags & JSON_REJECT_DUPLICATES) { - if(json_object_get(object, key)) { - jsonp_free(key); - error_set(error, lex, "duplicate object key"); - goto error; - } - } - - lex_scan(lex, error); - if(lex->token != ':') { - jsonp_free(key); - error_set(error, lex, "':' expected"); - goto error; - } - - lex_scan(lex, error); - value = parse_value(lex, flags, error); - if(!value) { - jsonp_free(key); - goto error; - } - - if(json_object_set_nocheck(object, key, value)) { - jsonp_free(key); - json_decref(value); - goto error; - } - - json_decref(value); - jsonp_free(key); - - lex_scan(lex, error); - if(lex->token != ',') - break; - - lex_scan(lex, error); - } - - if(lex->token != '}') { - error_set(error, lex, "'}' expected"); - goto error; - } - - return object; - -error: - json_decref(object); - return NULL; -} - -static json_t *parse_array(lex_t *lex, size_t flags, json_error_t *error) -{ - json_t *array = json_array(); - if(!array) - return NULL; - - lex_scan(lex, error); - if(lex->token == ']') - return array; - - while(lex->token) { - json_t *elem = parse_value(lex, flags, error); - if(!elem) - goto error; - - if(json_array_append(array, elem)) { - json_decref(elem); - goto error; - } - json_decref(elem); - - lex_scan(lex, error); - if(lex->token != ',') - break; - - lex_scan(lex, error); - } - - if(lex->token != ']') { - error_set(error, lex, "']' expected"); - goto error; - } - - return array; - -error: - json_decref(array); - return NULL; -} - -static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error) -{ - json_t *json; - - switch(lex->token) { - case TOKEN_STRING: { - json = json_string_nocheck(lex->value.string); - break; - } - - case TOKEN_INTEGER: { - json = json_integer(lex->value.integer); - break; - } - - case TOKEN_REAL: { - json = json_real(lex->value.real); - break; - } - - case TOKEN_TRUE: - json = json_true(); - break; - - case TOKEN_FALSE: - json = json_false(); - break; - - case TOKEN_NULL: - json = json_null(); - break; - - case '{': - json = parse_object(lex, flags, error); - break; - - case '[': - json = parse_array(lex, flags, error); - break; - - case TOKEN_INVALID: - error_set(error, lex, "invalid token"); - return NULL; - - default: - error_set(error, lex, "unexpected token"); - return NULL; - } - - if(!json) - return NULL; - - return json; -} - -static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error) -{ - json_t *result; - - lex_scan(lex, error); - if(lex->token != '[' && lex->token != '{') { - error_set(error, lex, "'[' or '{' expected"); - return NULL; - } - - result = parse_value(lex, flags, error); - if(!result) - return NULL; - - if(!(flags & JSON_DISABLE_EOF_CHECK)) { - lex_scan(lex, error); - if(lex->token != TOKEN_EOF) { - error_set(error, lex, "end of file expected"); - json_decref(result); - result = NULL; - } - } - - return result; -} - -typedef struct -{ - const char *data; - int pos; -} string_data_t; - -static int string_get(void *data) -{ - char c; - string_data_t *stream = (string_data_t *)data; - c = stream->data[stream->pos]; - if(c == '\0') - return EOF; - else - { - stream->pos++; - return (unsigned char)c; - } -} - -json_t *json_loads(const char *string, size_t flags, json_error_t *error) -{ - lex_t lex; - json_t *result; - string_data_t stream_data; - - stream_data.data = string; - stream_data.pos = 0; - - if(lex_init(&lex, string_get, (void *)&stream_data)) - return NULL; - - jsonp_error_init(error, ""); - result = parse_json(&lex, flags, error); - - lex_close(&lex); - return result; -} - -typedef struct -{ - const char *data; - size_t len; - size_t pos; -} buffer_data_t; - -static int buffer_get(void *data) -{ - char c; - buffer_data_t *stream = data; - if(stream->pos >= stream->len) - return EOF; - - c = stream->data[stream->pos]; - stream->pos++; - return (unsigned char)c; -} - -json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) -{ - lex_t lex; - json_t *result; - buffer_data_t stream_data; - - stream_data.data = buffer; - stream_data.pos = 0; - stream_data.len = buflen; - - if(lex_init(&lex, buffer_get, (void *)&stream_data)) - return NULL; - - jsonp_error_init(error, ""); - result = parse_json(&lex, flags, error); - - lex_close(&lex); - return result; -} - -json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) -{ - lex_t lex; - const char *source; - json_t *result; - - if(lex_init(&lex, (get_func)fgetc, input)) - return NULL; - - if(input == stdin) - source = ""; - else - source = ""; - - jsonp_error_init(error, source); - result = parse_json(&lex, flags, error); - - lex_close(&lex); - return result; -} - -json_t *json_load_file(const char *path, size_t flags, json_error_t *error) -{ - json_t *result; - FILE *fp; - - jsonp_error_init(error, path); - - fp = fopen(path, "r"); - if(!fp) - { - error_set(error, NULL, "unable to open %s: %s", - path, strerror(errno)); - return NULL; - } - - result = json_loadf(fp, flags, error); - - fclose(fp); - return result; -} diff --git a/compat/jansson/memory.c b/compat/jansson/memory.c deleted file mode 100644 index 127b5ac8e4..0000000000 --- a/compat/jansson/memory.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * Copyright (c) 2011 Basile Starynkevitch - * - * Jansson is free software; you can redistribute it and/or modify it - * under the terms of the MIT license. See LICENSE for details. - */ - -#include -#include - -#include -#include "jansson_private.h" - -/* memory function pointers */ -static json_malloc_t do_malloc = malloc; -static json_free_t do_free = free; - -void *jsonp_malloc(size_t size) -{ - if(!size) - return NULL; - - return (*do_malloc)(size); -} - -void jsonp_free(void *ptr) -{ - if(!ptr) - return; - - (*do_free)(ptr); -} - -char *jsonp_strdup(const char *str) -{ - char *new_str; - - new_str = jsonp_malloc(strlen(str) + 1); - if(!new_str) - return NULL; - - strcpy(new_str, str); - return new_str; -} - -void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn) -{ - do_malloc = malloc_fn; - do_free = free_fn; -} diff --git a/compat/jansson/strbuffer.c b/compat/jansson/strbuffer.c deleted file mode 100644 index 1b20e2b3c8..0000000000 --- a/compat/jansson/strbuffer.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#define _GNU_SOURCE -#include -#include -#include "jansson_private.h" -#include "strbuffer.h" - -#define STRBUFFER_MIN_SIZE 16 -#define STRBUFFER_FACTOR 2 - -int strbuffer_init(strbuffer_t *strbuff) -{ - strbuff->size = STRBUFFER_MIN_SIZE; - strbuff->length = 0; - - strbuff->value = jsonp_malloc(strbuff->size); - if(!strbuff->value) - return -1; - - /* initialize to empty */ - strbuff->value[0] = '\0'; - return 0; -} - -void strbuffer_close(strbuffer_t *strbuff) -{ - jsonp_free(strbuff->value); - strbuff->size = 0; - strbuff->length = 0; - strbuff->value = NULL; -} - -void strbuffer_clear(strbuffer_t *strbuff) -{ - strbuff->length = 0; - strbuff->value[0] = '\0'; -} - -const char *strbuffer_value(const strbuffer_t *strbuff) -{ - return strbuff->value; -} - -char *strbuffer_steal_value(strbuffer_t *strbuff) -{ - char *result = strbuff->value; - strbuffer_init(strbuff); - return result; -} - -int strbuffer_append(strbuffer_t *strbuff, const char *string) -{ - return strbuffer_append_bytes(strbuff, string, strlen(string)); -} - -int strbuffer_append_byte(strbuffer_t *strbuff, char byte) -{ - return strbuffer_append_bytes(strbuff, &byte, 1); -} - -int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, int size) -{ - if(strbuff->length + size >= strbuff->size) - { - size_t new_size; - char *new_value; - - new_size = max(strbuff->size * STRBUFFER_FACTOR, - strbuff->length + size + 1); - - new_value = jsonp_malloc(new_size); - if(!new_value) - return -1; - - memcpy(new_value, strbuff->value, strbuff->length); - - jsonp_free(strbuff->value); - strbuff->value = new_value; - strbuff->size = new_size; - } - - memcpy(strbuff->value + strbuff->length, data, size); - strbuff->length += size; - strbuff->value[strbuff->length] = '\0'; - - return 0; -} - -char strbuffer_pop(strbuffer_t *strbuff) -{ - if(strbuff->length > 0) { - char c = strbuff->value[--strbuff->length]; - strbuff->value[strbuff->length] = '\0'; - return c; - } - else - return '\0'; -} diff --git a/compat/jansson/strbuffer.h b/compat/jansson/strbuffer.h deleted file mode 100644 index b21ef8b068..0000000000 --- a/compat/jansson/strbuffer.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#ifndef STRBUFFER_H -#define STRBUFFER_H - -typedef struct { - char *value; - int length; /* bytes used */ - int size; /* bytes allocated */ -} strbuffer_t; - -int strbuffer_init(strbuffer_t *strbuff); -void strbuffer_close(strbuffer_t *strbuff); - -void strbuffer_clear(strbuffer_t *strbuff); - -const char *strbuffer_value(const strbuffer_t *strbuff); -char *strbuffer_steal_value(strbuffer_t *strbuff); - -int strbuffer_append(strbuffer_t *strbuff, const char *string); -int strbuffer_append_byte(strbuffer_t *strbuff, char byte); -int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, int size); - -char strbuffer_pop(strbuffer_t *strbuff); - -#endif diff --git a/compat/jansson/utf.c b/compat/jansson/utf.c deleted file mode 100644 index f48c2e7b24..0000000000 --- a/compat/jansson/utf.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#include -#include "utf.h" - -int utf8_encode(int32_t codepoint, char *buffer, int *size) -{ - if(codepoint < 0) - return -1; - else if(codepoint < 0x80) - { - buffer[0] = (char)codepoint; - *size = 1; - } - else if(codepoint < 0x800) - { - buffer[0] = 0xC0 + ((codepoint & 0x7C0) >> 6); - buffer[1] = 0x80 + ((codepoint & 0x03F)); - *size = 2; - } - else if(codepoint < 0x10000) - { - buffer[0] = 0xE0 + ((codepoint & 0xF000) >> 12); - buffer[1] = 0x80 + ((codepoint & 0x0FC0) >> 6); - buffer[2] = 0x80 + ((codepoint & 0x003F)); - *size = 3; - } - else if(codepoint <= 0x10FFFF) - { - buffer[0] = 0xF0 + ((codepoint & 0x1C0000) >> 18); - buffer[1] = 0x80 + ((codepoint & 0x03F000) >> 12); - buffer[2] = 0x80 + ((codepoint & 0x000FC0) >> 6); - buffer[3] = 0x80 + ((codepoint & 0x00003F)); - *size = 4; - } - else - return -1; - - return 0; -} - -int utf8_check_first(char byte) -{ - unsigned char u = (unsigned char)byte; - - if(u < 0x80) - return 1; - - if(0x80 <= u && u <= 0xBF) { - /* second, third or fourth byte of a multi-byte - sequence, i.e. a "continuation byte" */ - return 0; - } - else if(u == 0xC0 || u == 0xC1) { - /* overlong encoding of an ASCII byte */ - return 0; - } - else if(0xC2 <= u && u <= 0xDF) { - /* 2-byte sequence */ - return 2; - } - - else if(0xE0 <= u && u <= 0xEF) { - /* 3-byte sequence */ - return 3; - } - else if(0xF0 <= u && u <= 0xF4) { - /* 4-byte sequence */ - return 4; - } - else { /* u >= 0xF5 */ - /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid - UTF-8 */ - return 0; - } -} - -int utf8_check_full(const char *buffer, int size, int32_t *codepoint) -{ - int i; - int32_t value = 0; - unsigned char u = (unsigned char)buffer[0]; - - if(size == 2) - { - value = u & 0x1F; - } - else if(size == 3) - { - value = u & 0xF; - } - else if(size == 4) - { - value = u & 0x7; - } - else - return 0; - - for(i = 1; i < size; i++) - { - u = (unsigned char)buffer[i]; - - if(u < 0x80 || u > 0xBF) { - /* not a continuation byte */ - return 0; - } - - value = (value << 6) + (u & 0x3F); - } - - if(value > 0x10FFFF) { - /* not in Unicode range */ - return 0; - } - - else if(0xD800 <= value && value <= 0xDFFF) { - /* invalid code point (UTF-16 surrogate halves) */ - return 0; - } - - else if((size == 2 && value < 0x80) || - (size == 3 && value < 0x800) || - (size == 4 && value < 0x10000)) { - /* overlong encoding */ - return 0; - } - - if(codepoint) - *codepoint = value; - - return 1; -} - -const char *utf8_iterate(const char *buffer, int32_t *codepoint) -{ - int count; - int32_t value; - - if(!*buffer) - return buffer; - - count = utf8_check_first(buffer[0]); - if(count <= 0) - return NULL; - - if(count == 1) - value = (unsigned char)buffer[0]; - else - { - if(!utf8_check_full(buffer, count, &value)) - return NULL; - } - - if(codepoint) - *codepoint = value; - - return buffer + count; -} - -int utf8_check_string(const char *string, int length) -{ - int i; - - if(length == -1) - length = strlen(string); - - for(i = 0; i < length; i++) - { - int count = utf8_check_first(string[i]); - if(count == 0) - return 0; - else if(count > 1) - { - if(i + count > length) - return 0; - - if(!utf8_check_full(&string[i], count, NULL)) - return 0; - - i += count - 1; - } - } - - return 1; -} diff --git a/compat/jansson/utf.h b/compat/jansson/utf.h deleted file mode 100644 index 0c3ab3136f..0000000000 --- a/compat/jansson/utf.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#ifndef UTF_H -#define UTF_H - -#ifdef HAVE_CONFIG_H -#include - -#ifdef HAVE_INTTYPES_H -/* inttypes.h includes stdint.h in a standard environment, so there's -no need to include stdint.h separately. If inttypes.h doesn't define -int32_t, it's defined in config.h. */ -#include -#endif /* HAVE_INTTYPES_H */ - -#else /* !HAVE_CONFIG_H */ -#ifdef _WIN32 -typedef int int32_t; -#else /* !_WIN32 */ -/* Assume a standard environment */ -#include -#endif /* _WIN32 */ - -#endif /* HAVE_CONFIG_H */ - -int utf8_encode(int codepoint, char *buffer, int *size); - -int utf8_check_first(char byte); -int utf8_check_full(const char *buffer, int size, int32_t *codepoint); -const char *utf8_iterate(const char *buffer, int32_t *codepoint); - -int utf8_check_string(const char *string, int length); - -#endif diff --git a/compat/jansson/util.h b/compat/jansson/util.h deleted file mode 100644 index 06a547b8aa..0000000000 --- a/compat/jansson/util.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2009, 2010 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#ifndef UTIL_H -#define UTIL_H - -#define max(a, b) ((a) > (b) ? (a) : (b)) - -#endif diff --git a/compat/jansson/value.c b/compat/jansson/value.c deleted file mode 100644 index 47ebb2c8bd..0000000000 --- a/compat/jansson/value.c +++ /dev/null @@ -1,983 +0,0 @@ -/* - * Copyright (c) 2009-2011 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#define _GNU_SOURCE - -#include -#include -#include - -#include -#include "hashtable.h" -#include "jansson_private.h" -#include "utf.h" - - -static JSON_INLINE void json_init(json_t *json, json_type type) -{ - json->type = type; - json->refcount = 1; -} - - -/*** object ***/ - -/* From http://www.cse.yorku.ca/~oz/hash.html */ -size_t jsonp_hash_str(const void *ptr) -{ - const char *str = (const char *)ptr; - - size_t hash = 5381; - size_t c; - - while((c = (size_t)*str)) - { - hash = ((hash << 5) + hash) + c; - str++; - } - - return hash; -} - -int jsonp_str_equal(const void *ptr1, const void *ptr2) -{ - return strcmp((const char *)ptr1, (const char *)ptr2) == 0; -} - -/* This macro just returns a pointer that's a few bytes backwards from - string. This makes it possible to pass a pointer to object_key_t - when only the string inside it is used, without actually creating - an object_key_t instance. */ -#define string_to_key(string) container_of(string, object_key_t, key) - -static size_t hash_key(const void *ptr) -{ - return jsonp_hash_str(((const object_key_t *)ptr)->key); -} - -static int key_equal(const void *ptr1, const void *ptr2) -{ - return jsonp_str_equal(((const object_key_t *)ptr1)->key, - ((const object_key_t *)ptr2)->key); -} - -static void value_decref(void *value) -{ - json_decref((json_t *)value); -} - -json_t *json_object(void) -{ - json_object_t *object = jsonp_malloc(sizeof(json_object_t)); - if(!object) - return NULL; - json_init(&object->json, JSON_OBJECT); - - if(hashtable_init(&object->hashtable, - hash_key, key_equal, - jsonp_free, value_decref)) - { - jsonp_free(object); - return NULL; - } - - object->serial = 0; - object->visited = 0; - - return &object->json; -} - -static void json_delete_object(json_object_t *object) -{ - hashtable_close(&object->hashtable); - jsonp_free(object); -} - -size_t json_object_size(const json_t *json) -{ - json_object_t *object; - - if(!json_is_object(json)) - return 0; - - object = json_to_object(json); - return object->hashtable.size; -} - -json_t *json_object_get(const json_t *json, const char *key) -{ - json_object_t *object; - - if(!json_is_object(json)) - return NULL; - - object = json_to_object(json); - return hashtable_get(&object->hashtable, string_to_key(key)); -} - -int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) -{ - json_object_t *object; - object_key_t *k; - - if(!key || !value) - return -1; - - if(!json_is_object(json) || json == value) - { - json_decref(value); - return -1; - } - object = json_to_object(json); - - /* offsetof(...) returns the size of object_key_t without the - last, flexible member. This way, the correct amount is - allocated. */ - k = jsonp_malloc(offsetof(object_key_t, key) + strlen(key) + 1); - if(!k) - { - json_decref(value); - return -1; - } - - k->serial = object->serial++; - strcpy(k->key, key); - - if(hashtable_set(&object->hashtable, k, value)) - { - json_decref(value); - return -1; - } - - return 0; -} - -int json_object_set_new(json_t *json, const char *key, json_t *value) -{ - if(!key || !utf8_check_string(key, -1)) - { - json_decref(value); - return -1; - } - - return json_object_set_new_nocheck(json, key, value); -} - -int json_object_del(json_t *json, const char *key) -{ - json_object_t *object; - - if(!json_is_object(json)) - return -1; - - object = json_to_object(json); - return hashtable_del(&object->hashtable, string_to_key(key)); -} - -int json_object_clear(json_t *json) -{ - json_object_t *object; - - if(!json_is_object(json)) - return -1; - - object = json_to_object(json); - hashtable_clear(&object->hashtable); - - return 0; -} - -int json_object_update(json_t *object, json_t *other) -{ - void *iter; - - if(!json_is_object(object) || !json_is_object(other)) - return -1; - - iter = json_object_iter(other); - while(iter) { - const char *key; - json_t *value; - - key = json_object_iter_key(iter); - value = json_object_iter_value(iter); - - if(json_object_set_nocheck(object, key, value)) - return -1; - - iter = json_object_iter_next(other, iter); - } - - return 0; -} - -void *json_object_iter(json_t *json) -{ - json_object_t *object; - - if(!json_is_object(json)) - return NULL; - - object = json_to_object(json); - return hashtable_iter(&object->hashtable); -} - -void *json_object_iter_at(json_t *json, const char *key) -{ - json_object_t *object; - - if(!key || !json_is_object(json)) - return NULL; - - object = json_to_object(json); - return hashtable_iter_at(&object->hashtable, string_to_key(key)); -} - -void *json_object_iter_next(json_t *json, void *iter) -{ - json_object_t *object; - - if(!json_is_object(json) || iter == NULL) - return NULL; - - object = json_to_object(json); - return hashtable_iter_next(&object->hashtable, iter); -} - -const object_key_t *jsonp_object_iter_fullkey(void *iter) -{ - if(!iter) - return NULL; - - return hashtable_iter_key(iter); -} - -const char *json_object_iter_key(void *iter) -{ - if(!iter) - return NULL; - - return jsonp_object_iter_fullkey(iter)->key; -} - -json_t *json_object_iter_value(void *iter) -{ - if(!iter) - return NULL; - - return (json_t *)hashtable_iter_value(iter); -} - -int json_object_iter_set_new(json_t *json, void *iter, json_t *value) -{ - json_object_t *object; - - if(!json_is_object(json) || !iter || !value) - return -1; - - object = json_to_object(json); - hashtable_iter_set(&object->hashtable, iter, value); - - return 0; -} - -static int json_object_equal(json_t *object1, json_t *object2) -{ - void *iter; - - if(json_object_size(object1) != json_object_size(object2)) - return 0; - - iter = json_object_iter(object1); - while(iter) - { - const char *key; - json_t *value1, *value2; - - key = json_object_iter_key(iter); - value1 = json_object_iter_value(iter); - value2 = json_object_get(object2, key); - - if(!json_equal(value1, value2)) - return 0; - - iter = json_object_iter_next(object1, iter); - } - - return 1; -} - -static json_t *json_object_copy(json_t *object) -{ - json_t *result; - void *iter; - - result = json_object(); - if(!result) - return NULL; - - iter = json_object_iter(object); - while(iter) - { - const char *key; - json_t *value; - - key = json_object_iter_key(iter); - value = json_object_iter_value(iter); - json_object_set_nocheck(result, key, value); - - iter = json_object_iter_next(object, iter); - } - - return result; -} - -static json_t *json_object_deep_copy(json_t *object) -{ - json_t *result; - void *iter; - - result = json_object(); - if(!result) - return NULL; - - iter = json_object_iter(object); - while(iter) - { - const char *key; - json_t *value; - - key = json_object_iter_key(iter); - value = json_object_iter_value(iter); - json_object_set_new_nocheck(result, key, json_deep_copy(value)); - - iter = json_object_iter_next(object, iter); - } - - return result; -} - - -/*** array ***/ - -json_t *json_array(void) -{ - json_array_t *array = jsonp_malloc(sizeof(json_array_t)); - if(!array) - return NULL; - json_init(&array->json, JSON_ARRAY); - - array->entries = 0; - array->size = 8; - - array->table = jsonp_malloc(array->size * sizeof(json_t *)); - if(!array->table) { - jsonp_free(array); - return NULL; - } - - array->visited = 0; - - return &array->json; -} - -static void json_delete_array(json_array_t *array) -{ - size_t i; - - for(i = 0; i < array->entries; i++) - json_decref(array->table[i]); - - jsonp_free(array->table); - jsonp_free(array); -} - -size_t json_array_size(const json_t *json) -{ - if(!json_is_array(json)) - return 0; - - return json_to_array(json)->entries; -} - -json_t *json_array_get(const json_t *json, size_t index) -{ - json_array_t *array; - if(!json_is_array(json)) - return NULL; - array = json_to_array(json); - - if(index >= array->entries) - return NULL; - - return array->table[index]; -} - -int json_array_set_new(json_t *json, size_t index, json_t *value) -{ - json_array_t *array; - - if(!value) - return -1; - - if(!json_is_array(json) || json == value) - { - json_decref(value); - return -1; - } - array = json_to_array(json); - - if(index >= array->entries) - { - json_decref(value); - return -1; - } - - json_decref(array->table[index]); - array->table[index] = value; - - return 0; -} - -static void array_move(json_array_t *array, size_t dest, - size_t src, size_t count) -{ - memmove(&array->table[dest], &array->table[src], count * sizeof(json_t *)); -} - -static void array_copy(json_t **dest, size_t dpos, - json_t **src, size_t spos, - size_t count) -{ - memcpy(&dest[dpos], &src[spos], count * sizeof(json_t *)); -} - -static json_t **json_array_grow(json_array_t *array, - size_t amount, - int copy) -{ - size_t new_size; - json_t **old_table, **new_table; - - if(array->entries + amount <= array->size) - return array->table; - - old_table = array->table; - - new_size = max(array->size + amount, array->size * 2); - new_table = jsonp_malloc(new_size * sizeof(json_t *)); - if(!new_table) - return NULL; - - array->size = new_size; - array->table = new_table; - - if(copy) { - array_copy(array->table, 0, old_table, 0, array->entries); - jsonp_free(old_table); - return array->table; - } - - return old_table; -} - -int json_array_append_new(json_t *json, json_t *value) -{ - json_array_t *array; - - if(!value) - return -1; - - if(!json_is_array(json) || json == value) - { - json_decref(value); - return -1; - } - array = json_to_array(json); - - if(!json_array_grow(array, 1, 1)) { - json_decref(value); - return -1; - } - - array->table[array->entries] = value; - array->entries++; - - return 0; -} - -int json_array_insert_new(json_t *json, size_t index, json_t *value) -{ - json_array_t *array; - json_t **old_table; - - if(!value) - return -1; - - if(!json_is_array(json) || json == value) { - json_decref(value); - return -1; - } - array = json_to_array(json); - - if(index > array->entries) { - json_decref(value); - return -1; - } - - old_table = json_array_grow(array, 1, 0); - if(!old_table) { - json_decref(value); - return -1; - } - - if(old_table != array->table) { - array_copy(array->table, 0, old_table, 0, index); - array_copy(array->table, index + 1, old_table, index, - array->entries - index); - jsonp_free(old_table); - } - else - array_move(array, index + 1, index, array->entries - index); - - array->table[index] = value; - array->entries++; - - return 0; -} - -int json_array_remove(json_t *json, size_t index) -{ - json_array_t *array; - - if(!json_is_array(json)) - return -1; - array = json_to_array(json); - - if(index >= array->entries) - return -1; - - json_decref(array->table[index]); - - array_move(array, index, index + 1, array->entries - index); - array->entries--; - - return 0; -} - -int json_array_clear(json_t *json) -{ - json_array_t *array; - size_t i; - - if(!json_is_array(json)) - return -1; - array = json_to_array(json); - - for(i = 0; i < array->entries; i++) - json_decref(array->table[i]); - - array->entries = 0; - return 0; -} - -int json_array_extend(json_t *json, json_t *other_json) -{ - json_array_t *array, *other; - size_t i; - - if(!json_is_array(json) || !json_is_array(other_json)) - return -1; - array = json_to_array(json); - other = json_to_array(other_json); - - if(!json_array_grow(array, other->entries, 1)) - return -1; - - for(i = 0; i < other->entries; i++) - json_incref(other->table[i]); - - array_copy(array->table, array->entries, other->table, 0, other->entries); - - array->entries += other->entries; - return 0; -} - -static int json_array_equal(json_t *array1, json_t *array2) -{ - size_t i, size; - - size = json_array_size(array1); - if(size != json_array_size(array2)) - return 0; - - for(i = 0; i < size; i++) - { - json_t *value1, *value2; - - value1 = json_array_get(array1, i); - value2 = json_array_get(array2, i); - - if(!json_equal(value1, value2)) - return 0; - } - - return 1; -} - -static json_t *json_array_copy(json_t *array) -{ - json_t *result; - size_t i; - - result = json_array(); - if(!result) - return NULL; - - for(i = 0; i < json_array_size(array); i++) - json_array_append(result, json_array_get(array, i)); - - return result; -} - -static json_t *json_array_deep_copy(json_t *array) -{ - json_t *result; - size_t i; - - result = json_array(); - if(!result) - return NULL; - - for(i = 0; i < json_array_size(array); i++) - json_array_append_new(result, json_deep_copy(json_array_get(array, i))); - - return result; -} - -/*** string ***/ - -json_t *json_string_nocheck(const char *value) -{ - json_string_t *string; - - if(!value) - return NULL; - - string = jsonp_malloc(sizeof(json_string_t)); - if(!string) - return NULL; - json_init(&string->json, JSON_STRING); - - string->value = jsonp_strdup(value); - if(!string->value) { - jsonp_free(string); - return NULL; - } - - return &string->json; -} - -json_t *json_string(const char *value) -{ - if(!value || !utf8_check_string(value, -1)) - return NULL; - - return json_string_nocheck(value); -} - -const char *json_string_value(const json_t *json) -{ - if(!json_is_string(json)) - return NULL; - - return json_to_string(json)->value; -} - -int json_string_set_nocheck(json_t *json, const char *value) -{ - char *dup; - json_string_t *string; - - dup = jsonp_strdup(value); - if(!dup) - return -1; - - string = json_to_string(json); - jsonp_free(string->value); - string->value = dup; - - return 0; -} - -int json_string_set(json_t *json, const char *value) -{ - if(!value || !utf8_check_string(value, -1)) - return -1; - - return json_string_set_nocheck(json, value); -} - -static void json_delete_string(json_string_t *string) -{ - jsonp_free(string->value); - jsonp_free(string); -} - -static int json_string_equal(json_t *string1, json_t *string2) -{ - return strcmp(json_string_value(string1), json_string_value(string2)) == 0; -} - -static json_t *json_string_copy(json_t *string) -{ - return json_string_nocheck(json_string_value(string)); -} - - -/*** integer ***/ - -json_t *json_integer(json_int_t value) -{ - json_integer_t *integer = jsonp_malloc(sizeof(json_integer_t)); - if(!integer) - return NULL; - json_init(&integer->json, JSON_INTEGER); - - integer->value = value; - return &integer->json; -} - -json_int_t json_integer_value(const json_t *json) -{ - if(!json_is_integer(json)) - return 0; - - return json_to_integer(json)->value; -} - -int json_integer_set(json_t *json, json_int_t value) -{ - if(!json_is_integer(json)) - return -1; - - json_to_integer(json)->value = value; - - return 0; -} - -static void json_delete_integer(json_integer_t *integer) -{ - jsonp_free(integer); -} - -static int json_integer_equal(json_t *integer1, json_t *integer2) -{ - return json_integer_value(integer1) == json_integer_value(integer2); -} - -static json_t *json_integer_copy(json_t *integer) -{ - return json_integer(json_integer_value(integer)); -} - - -/*** real ***/ - -json_t *json_real(double value) -{ - json_real_t *real = jsonp_malloc(sizeof(json_real_t)); - if(!real) - return NULL; - json_init(&real->json, JSON_REAL); - - real->value = value; - return &real->json; -} - -double json_real_value(const json_t *json) -{ - if(!json_is_real(json)) - return 0; - - return json_to_real(json)->value; -} - -int json_real_set(json_t *json, double value) -{ - if(!json_is_real(json)) - return 0; - - json_to_real(json)->value = value; - - return 0; -} - -static void json_delete_real(json_real_t *real) -{ - jsonp_free(real); -} - -static int json_real_equal(json_t *real1, json_t *real2) -{ - return json_real_value(real1) == json_real_value(real2); -} - -static json_t *json_real_copy(json_t *real) -{ - return json_real(json_real_value(real)); -} - - -/*** number ***/ - -double json_number_value(const json_t *json) -{ - if(json_is_integer(json)) - return json_integer_value(json); - else if(json_is_real(json)) - return json_real_value(json); - else - return 0.0; -} - - -/*** simple values ***/ - -json_t *json_true(void) -{ - static json_t the_true = {JSON_TRUE, (size_t)-1}; - return &the_true; -} - - -json_t *json_false(void) -{ - static json_t the_false = {JSON_FALSE, (size_t)-1}; - return &the_false; -} - - -json_t *json_null(void) -{ - static json_t the_null = {JSON_NULL, (size_t)-1}; - return &the_null; -} - - -/*** deletion ***/ - -void json_delete(json_t *json) -{ - if(json_is_object(json)) - json_delete_object(json_to_object(json)); - - else if(json_is_array(json)) - json_delete_array(json_to_array(json)); - - else if(json_is_string(json)) - json_delete_string(json_to_string(json)); - - else if(json_is_integer(json)) - json_delete_integer(json_to_integer(json)); - - else if(json_is_real(json)) - json_delete_real(json_to_real(json)); - - /* json_delete is not called for true, false or null */ -} - - -/*** equality ***/ - -int json_equal(json_t *json1, json_t *json2) -{ - if(!json1 || !json2) - return 0; - - if(json_typeof(json1) != json_typeof(json2)) - return 0; - - /* this covers true, false and null as they are singletons */ - if(json1 == json2) - return 1; - - if(json_is_object(json1)) - return json_object_equal(json1, json2); - - if(json_is_array(json1)) - return json_array_equal(json1, json2); - - if(json_is_string(json1)) - return json_string_equal(json1, json2); - - if(json_is_integer(json1)) - return json_integer_equal(json1, json2); - - if(json_is_real(json1)) - return json_real_equal(json1, json2); - - return 0; -} - - -/*** copying ***/ - -json_t *json_copy(json_t *json) -{ - if(!json) - return NULL; - - if(json_is_object(json)) - return json_object_copy(json); - - if(json_is_array(json)) - return json_array_copy(json); - - if(json_is_string(json)) - return json_string_copy(json); - - if(json_is_integer(json)) - return json_integer_copy(json); - - if(json_is_real(json)) - return json_real_copy(json); - - if(json_is_true(json) || json_is_false(json) || json_is_null(json)) - return json; - - return NULL; -} - -json_t *json_deep_copy(json_t *json) -{ - if(!json) - return NULL; - - if(json_is_object(json)) - return json_object_deep_copy(json); - - if(json_is_array(json)) - return json_array_deep_copy(json); - - /* for the rest of the types, deep copying doesn't differ from - shallow copying */ - - if(json_is_string(json)) - return json_string_copy(json); - - if(json_is_integer(json)) - return json_integer_copy(json); - - if(json_is_real(json)) - return json_real_copy(json); - - if(json_is_true(json) || json_is_false(json) || json_is_null(json)) - return json; - - return NULL; -} diff --git a/configure.ac b/configure.ac index 60f91869d6..df6dd05942 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,21 @@ +dnl * Copyright 2011-2016 Luke Dashjr +dnl * Copyright 2011-2013 Con Kolivas +dnl * Copyright 2010-2011 Jeff Garzik +dnl * Copyright 2012 Xiangfu +dnl * Copyright 2011 Rusty Russell +dnl * Copyright 2011 Mark Crichton +dnl * Copyright 2013-2014 Nate Woolls +dnl * +dnl * This program is free software; you can redistribute it and/or modify it +dnl * under the terms of the GNU General Public License as published by the Free +dnl * Software Foundation; either version 3 of the License, or (at your option) +dnl * any later version. See COPYING for more details. + ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## -m4_define([v_maj], [2]) +m4_define([v_maj], [5]) m4_define([v_min], [5]) -m4_define([v_mic], [3]) +m4_define([v_mic], [0]) ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## m4_define([v_ver], [v_maj.v_min.v_mic]) m4_define([lt_rev], m4_eval(v_maj + v_min)) @@ -19,7 +32,13 @@ AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([miner.c]) AC_CONFIG_HEADERS([config.h]) -AM_INIT_AUTOMAKE([foreign]) +AH_BOTTOM([ +#ifdef WIN32 +#include "winhacks.h" +#endif +]) + +AM_INIT_AUTOMAKE([foreign subdir-objects]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_USE_SYSTEM_EXTENSIONS @@ -43,7 +62,7 @@ AC_CANONICAL_BUILD AC_CANONICAL_HOST dnl Make sure anyone changing configure.ac/Makefile.am has a clue -AM_MAINTAINER_MODE +AM_MAINTAINER_MODE([enable]) dnl Checks for programs AC_PROG_CC_C99 @@ -51,151 +70,974 @@ gl_EARLY AC_PROG_GCC_TRADITIONAL AM_PROG_CC_C_O AC_PROG_RANLIB +AC_PROG_CPP +AC_PROG_SED gl_INIT +AC_SYS_LARGEFILE + dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(syslog.h) AC_CHECK_HEADERS([sys/epoll.h]) +AC_CHECK_HEADERS([sys/mman.h]) +AC_CHECK_HEADERS([sys/prctl.h]) +AC_CHECK_HEADERS([sys/file.h]) +AC_CHECK_HEADERS([sys/termios.h]) +AC_CHECK_HEADERS([sys/unistd.h]) +AC_CHECK_HEADERS([linux/spi/spidev.h]) + +AC_CHECK_MEMBER([struct i2c_msg.buf],[ + true +],[ + dnl Note the member is different here to avoid caching screwing things up + AC_CHECK_MEMBER([struct i2c_msg.len],[ + AC_DEFINE([NEED_LINUX_I2C_H],[1],[Defined if linux/i2c.h is needed to supplement linux/i2c-dev.h]) + ],[ + true + ],[ + AC_INCLUDES_DEFAULT + #include + #include + ]) +],[ + AC_INCLUDES_DEFAULT + #include +]) + +# Setuid +AC_CHECK_HEADERS([pwd.h]) + +# Check for chroot support +AC_CHECK_FUNCS([chroot]) + +AC_CHECK_FUNCS([sleep]) AC_FUNC_ALLOCA +lowllist= +driverlist= +algolist= +optlist= + +has_fpga=no +has_asic=no +need_binloader=no +need_dynclock=no +need_gc3355=no +need_linux_i2c_dev=no +need_lowl_vcom=no +need_lowlevel=no +need_lowl_ftdi=no +need_lowl_hid=no +need_lowl_mswin=no +need_lowl_pci=no +need_lowl_spi=no +need_lowl_usb=no +need_knc_asic=no +need_work2d=no +have_cygwin=false have_win32=false -PTHREAD_FLAGS="-lpthread" -USB_LIBS="" -USB_FLAGS="" +have_macho=false +use_udevrules=true +have_udevrules=false +AUTOSCAN_CPPFLAGS="" +AUTOSCAN_LIBS="" DLOPEN_FLAGS="-ldl" WS2_LIBS="" +MM_LIBS="" MATH_LIBS="-lm" +RT_LIBS="" case $target in - x86_64-*) + amd64-* | x86_64-*) + have_x86_32=false have_x86_64=true + bitness="64" + ;; + i386-* | i486-* | i586-* | i686-* | x86-*) + have_x86_32=true + have_x86_64=false + bitness="32" ;; *) + have_x86_32=false have_x86_64=false ;; esac case $target in - x86_64-w64-mingw32) - have_x86_64=true - have_win32=true - PTHREAD_FLAGS="" - DLOPEN_FLAGS="" - WS2_LIBS="-lws2_32" - ;; *-*-mingw*) - have_x86_64=false have_win32=true - PTHREAD_FLAGS="" + use_udevrules=false DLOPEN_FLAGS="" WS2_LIBS="-lws2_32" + MM_LIBS="-lwinmm" + AC_DEFINE([_WIN32_WINNT], [0x0501], "WinNT version for XP+ support") + AC_DEFINE([FD_SETSIZE], [4096], [Maximum sockets before fd_set overflows]) ;; + *-*-cygwin*) + have_cygwin=true + use_udevrules=false + ;; powerpc-*-darwin*) CFLAGS="$CFLAGS -faltivec" - PTHREAD_FLAGS="" + have_macho=true + use_udevrules=false ;; - *-*-darwin*) - PTHREAD_FLAGS="" - ;; + *-*-darwin*) + LDFLAGS="$LDFLAGS -framework IOKit -framework CoreFoundation" + have_macho=true + use_udevrules=false + ;; esac -cpumining="no" -AC_ARG_ENABLE([cpumining], - [AC_HELP_STRING([--enable-cpumining],[Build with cpu mining support(default disabled)])], - [cpumining=$enableval] +m4_define([BFG_INCLUDE], + if test "x$2" = "x"; then + $1='' + else + $1="[#]include <$2>" + fi +) + +m4_define([BFG_PREPROC_IFELSE], + BFG_INCLUDE([headerinclude], $2) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ + ${headerinclude} + ], [ + #if !( $1 ) + #error "$1 false in preprocessor" + #endif + ]) + ],[$3],[$4]) +) + +m4_define([BFG_FIND_INCLUDE_PATH],[ + m4_pushdef([_rel_path],[$1]) + m4_pushdef([_header_file],[$2]) + m4_pushdef([_iffound],[$3]) + m4_pushdef([_ifnotfound],[$4]) + m4_pushdef([_includes],[$5]) + m4_pushdef([_result_var],[inclpath_[]patsubst(_header_file,[[./]],[_])]) + AC_CHECK_HEADER([_rel_path/_header_file],[ + AC_MSG_CHECKING([_header_file path]) + _result_var=`echo '[#]include <'"_rel_path"'/_header_file>' | ${CPP} -M - 2>/dev/null | ${SED} [-E -e ':a' -e '/\\$/!b b' -e N -e 's/\\\n/ /' -e 't a' -e ':b' -e 's/^[^:]*:[[:space:]]*(([^[:space:]\]|\\.)*[[:space:]])*(([^[:space:]\]|\\.)*)(\\|\\\\|\/)?]patsubst([_header_file],[\.],[\\.])[([[:space:]].*)?$/\3/' -e 't' -e d]` + if test "x$_result_var" = "x"; then + AC_MSG_RESULT([failed]) + AC_MSG_ERROR([Couldn't determine include path for _header_file]) + else + AC_MSG_RESULT([$_result_var]) + _iffound + fi + ],[ + true + _ifnotfound + ],[ + _includes + ]) + m4_popdef([_rel_path],[_header_file],[_iffound],[_ifnotfound],[_result_var]) +]) + +bfg_enableaction() { + _var=$1 + eval "_missingdeps=\"\$${_var}_missingdeps\"" + if test -n "$_missingdeps"; then + _enableaction= + for _missingdep in $_missingdeps; do + eval "_howto=\"\$howto_${_missingdep}\"" + if test "x$_howto" = "x"; then + eval "_label=\"\${label_${_missingdep}-${_missingdep}}\"" + _howto="enable $_label" + fi + if test "$_howto" != "x"; then + _enableaction="$_enableaction; $_howto" + fi + done + _enableaction="${_enableaction:2}" + else + eval "_enableaction=\"\$${_var}_enableaction\"" + fi + echo "$_enableaction" +} + +dnl _BFG_AUTOITEM(list,driver,DriverName,dependency list,default:no/auto,CodeIfEnabled) +m4_define([_BFG_AUTOITEM],[ + m4_pushdef([_list],[$1]) + m4_pushdef([_this_drv],m4_default([$2],m4_tolower([$3]))) + m4_pushdef([_this_drvuc],m4_toupper(_this_drv)) + m4_pushdef([_this_USE],USE_[]_this_drvuc) + m4_pushdef([_this_name],[$3]) + m4_pushdef([_deplist],[$4]) + m4_pushdef([_this_default],[$5]) + m4_pushdef([_this_enablecode],[$6]) + m4_case(_list, + [algo],[algolist="$algolist []_this_name/[]_this_USE"], + [driver],[driverlist="$driverlist []_this_drv/[]_this_USE"], + [] ) -if test "x$cpumining" = xyes; then - AC_DEFINE_UNQUOTED([WANT_CPUMINE], [1], [Enable CPUMINING]) + label_[]_this_drvuc="[]_this_name" + AC_ARG_ENABLE([]_this_drv, + m4_bmatch(_this_default,[.*no$], + AC_HELP_STRING([--enable-[]_this_drv],[Compile support for ]_this_name[ (default disabled)]), + AC_HELP_STRING([--disable-[]_this_drv],[Compile support for ]_this_name[ (default enabled)])), + [[]_this_USE=$enableval], + [[]_this_USE=[]_this_default] + ) + []_this_drv[]_opt= + if test "x$[]_this_USE" = "xno"; then + true + else + if test "x$[]_this_USE" = xauto; then + _wasauto=yes + else + _wasauto=no + fi + if test "x$[]_this_USE" != xyes; then + if test "x$[]_this_USE" != xauto; then + []_this_drv[]_opt="$[]_this_USE" + fi + []_this_USE=yes + fi + for __drvdep in []m4_toupper(_deplist); do + eval "_drvdep=\"\$USE_$__drvdep\"" + if test "x$_drvdep" != "xyes"; then + []_this_USE[]_missingdeps="$[]_this_USE[]_missingdeps $__drvdep" + []_this_USE=no + fi + done + if test "x$[]_this_USE[]$_wasauto" = xnono; then + _enableaction=`bfg_enableaction []_this_USE` + AC_MSG_ERROR([To enable []_this_name: $_enableaction]) + fi + fi + if test "x$[]_this_USE" = "xyes"; then + AC_DEFINE([]_this_USE,[1],[Defined to 1 if []_this_name support is wanted]) + []_this_enablecode + fi + AM_CONDITIONAL([]_this_USE,[test x$[]_this_USE = xyes]) + m4_popdef([_this_drv],[_this_drvuc],[_this_USE],[_this_name],[_deplist],[_this_default],[_this_enablecode]) +]) + +dnl BFG_ALGO(AlgoName,default:no/yes,CodeIfEnabled) +m4_define([BFG_ALGO],[ + _BFG_AUTOITEM([algo],,[$1],,[$2],[$3]) +]) + +dnl BFG_DRIVER(driver,DriverName,dependency list,default:no/auto,CodeIfEnabled) +m4_define([BFG_DRIVER],[ + _BFG_AUTOITEM([driver],[$1],[$2],[$3],$dd[$4],[$5]) +]) + + +AC_CHECK_DECL([HASH_ITER],[ + AC_CHECK_DECL([DL_CONCAT],[ + true + ],[ + AC_MSG_ERROR([Could not find DL_FOREACH_SAFE - install uthash-dev 1.9.4+]) + ],[ + #include + ]) +],[ + AC_MSG_ERROR([Could not find HASH_ITER - please install uthash-dev 1.9.4+]) +],[ + #include +]) + + +ddyes=yes +ddauto=auto +ddno=no +AC_ARG_ENABLE([other-drivers], + [AC_HELP_STRING([--disable-other-drivers],[Build without drivers by default unless explicitly enabled])], + [ + if test x$enableval = xyes; then + ddno=yes + else + ddyes=no + ddauto=no + fi + ] +) + + +broad_udevrules=false +AC_ARG_ENABLE([broad-udevrules], + [AC_HELP_STRING([--enable-broad-udevrules],[Include udev rules for ambiguous devices which may not be miners])], + [ + if test "x$enableval" = "xyes"; then + broad_udevrules=true + fi + ] +) + +use_udevrules_group=true +udevrules_group="video" +AC_ARG_WITH([udevrules-group], + [AC_HELP_STRING([--with-udevrules-group=groupname],[Configure mining devices to be owned by a specific group (default `video')])], + [ + if test "x$withval" = "xno"; then + use_udevrules_group=false + else + udevrules_group="$withval" + fi + ] +) +AM_CONDITIONAL([USE_UDEVRULES_GROUP], [$use_udevrules_group]) +AC_SUBST([UDEVRULES_GROUP], [$udevrules_group]) + + +BFG_ALGO(Keccak,no) +BFG_ALGO(SHA256d,yes) +BFG_ALGO(scrypt,no) + +lowl_pci=no +if test "x$ac_cv_header_sys_mman_h" = "xyes"; then + AC_ARG_WITH([uio], + [AC_HELP_STRING([--without-uio],[Compile support for PCI devices via Linux UIO interface (default enabled)])], + [uio=$withval], + [uio=yes]) + AC_ARG_WITH([vfio], + [AC_HELP_STRING([--without-vfio],[Compile support for PCI devices via Linux VFIO interface (default enabled)])], + [vfio=$withval], + [vfio=auto]) + if test "x$vfio" != "xno"; then + AC_CHECK_HEADER([linux/vfio.h],[ + vfio=yes + ],[ + if test "x$vfio" = "xyes"; then + AC_MSG_ERROR([Unable to find linux/vfio.h]) + elif test "x$uio" = "xyes"; then + AC_MSG_WARN([linux/vfio.h not found; PCI device support will require UIO (and root access)]) + else + AC_MSG_WARN([linux/vfio.h not found; PCI device support will not be available]) + fi + vfio=no + ]) + fi + if test "x$vfio$uio" != xnono; then + lowl_pci=yes + fi fi -AM_CONDITIONAL([HAS_CPUMINE], [test x$cpumining = xyes]) -opencl="yes" -AC_ARG_ENABLE([opencl], - [AC_HELP_STRING([--disable-opencl],[Build without support for OpenCL (default enabled)])], - [opencl=$enableval] - ) -if test "x$opencl" = xyes; then - AC_DEFINE([HAVE_OPENCL], [1], [Defined to 1 if OpenCL support is wanted]) +BFG_DRIVER(cpumining,CPU mining,,no,[ + driverlist="$driverlist cpu:asm/has_yasm" + driverlist="$driverlist cpu:sse2/have_sse2" +]) +driverlist=`echo "${driverlist}" | ${SED} -e 's/ cpumining/ cpu/'` + +BFG_DRIVER(,OpenCL,,no) + +m4_define([BFG_PTHREAD_FLAG_CHECK], + AC_MSG_CHECKING([for $1]) + for cflag in ' -pthread' ''; do + for lib in ' -lpthread' ' -lwinpthread' ''; do + CFLAGS="${save_CFLAGS}${cflag}" + LIBS="${save_LIBS}${lib}" + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ + #include + ], [ + void *f = $1; + ]) + ], [ + found_pthread=true + PTHREAD_FLAGS="${cflag}" + PTHREAD_LIBS="${lib}" + if test "x${cflag}${lib}" = "x"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([with${cflag}${lib}]) + fi + $2 + break 2 + ]) + done + done + if test "x${found_pthread}" = "xfalse"; then + AC_MSG_RESULT([no]) + fi +) + +save_CFLAGS="${CFLAGS}" +save_LIBS="${LIBS}" +found_pthread=false +BFG_PTHREAD_FLAG_CHECK([pthread_cancel],[ + AC_DEFINE([HAVE_PTHREAD_CANCEL], [1], [Define if you have a native pthread_cancel]) +]) +if test "x${found_pthread}" = "xfalse"; then + BFG_PTHREAD_FLAG_CHECK([pthread_create]) + if test "x${found_pthread}" = "xfalse"; then + AC_MSG_ERROR([Could not find pthread library - please install libpthread]) + fi fi -AM_CONDITIONAL([HAVE_OPENCL], [test x$opencl = xyes]) +# check for nanosleep here, since it is provided by winpthread +AC_CHECK_FUNCS([nanosleep]) +CFLAGS="${save_CFLAGS}" +LIBS="${save_LIBS}" -AC_CHECK_LIB(pthread, pthread_create, , - AC_MSG_ERROR([Could not find pthread library - please install libpthread])) -PTHREAD_LIBS=-lpthread +PKG_CHECK_MODULES([JANSSON],[jansson],[ + true +],[ + AC_MSG_CHECKING([for jansson in system-default locations]) + LIBS="$LIBS -ljansson" + AC_TRY_LINK([ + #include + ],[ + json_object(); + ],[ + AC_MSG_RESULT([found]) + JANSSON_LIBS=-ljansson + ],[ + AC_MSG_RESULT([not found]) + AC_MSG_ERROR([Could not find jansson library]) + ]) + LIBS="${save_LIBS}" +]) +AC_SUBST(JANSSON_CFLAGS) +AC_SUBST(JANSSON_LIBS) -AC_CHECK_LIB(jansson, json_loads, request_jansson=false, request_jansson=true) +if test "x$USE_OPENCL" = xyes; then + adl="yes" + + if test "x$USE_KECCAK" = xyes; then + AC_DEFINE([USE_OPENCL_FULLHEADER],[1],[Defined to 1 if OpenCL fullheader kernel interface is wanted]) + fi + +driverlist="$driverlist opencl:sensors/with_sensors" +AC_ARG_WITH([sensors], + [AC_HELP_STRING([--without-sensors],[Build with libsensors monitoring (default enabled)])], + [true],[with_sensors=auto]) +if test "x$USE_OPENCL" != xyes; then + with_sensors=no +fi +if test "x$with_sensors" != xno; then + AC_MSG_CHECKING([for libsensors]) + save_LIBS="${LIBS}" + LIBS="$LIBS -lsensors" + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #include + #include + ],[ + const sensors_chip_name *cn; + cn = sensors_get_detected_chips(NULL, NULL); + ])],[ + with_sensors=yes + sensors_LIBS="-lsensors" + AC_DEFINE([HAVE_SENSORS], [1], [Defined if libsensors was found]) + AC_MSG_RESULT([yes]) + ],[ + with_sensors=no + AC_MSG_RESULT([no]) + if ! $have_win32; then + with_sensors_enableaction="install libsensors" + fi + ]) + LIBS="$save_LIBS" +fi +AC_SUBST(sensors_LIBS) +driverlist="$driverlist opencl:adl/adl" AC_ARG_ENABLE([adl], - [AC_HELP_STRING([--disable-adl],[Override detection and disable building with adl])], + [AC_HELP_STRING([--disable-adl],[Build without ADL monitoring (default enabled)])], [adl=$enableval] ) -if test "x$opencl" = xyes; then - if test "x$adl" != xno; then - if test -f ADL_SDK/adl_sdk.h; then - have_adl=true - else - have_adl=false - fi - if test x$have_adl = xtrue + if test x$adl = xyes then AC_DEFINE([HAVE_ADL], [1], [Defined if ADL headers were found]) + fi +else + adl="no" +fi + +BFG_DRIVER(,AlcheMist,scrypt,no,[ + need_lowl_vcom=yes + has_asic=yes +]) + +BFG_DRIVER(,BitForce,SHA256d,auto,[ + driverlist="$driverlist bitforce:pci/need_lowl_pci" + if test "x$lowl_pci" = "xyes"; then + need_lowl_pci=yes + fi + need_lowl_vcom=yes + driverlist="$driverlist bitforce:mswin/need_lowl_mswin" + if test x$have_win32 = xtrue; then + need_lowl_mswin=yes + fi + has_fpga=yes + has_asic=yes + have_udevrules=true +]) + +BFG_DRIVER(bitmain,Bitmain Antminer S* series,SHA256d,no,[ + need_lowl_vcom=yes + has_asic=yes +]) + +BFG_DRIVER(,Icarus,SHA256d,auto,[ + need_dynclock=yes + need_lowl_vcom=yes + has_fpga=yes + has_asic=yes + have_udevrules=true +]) +driverlist="$driverlist cairnsmore/USE_ICARUS erupter/USE_ICARUS antminer/USE_ICARUS compac/USE_ICARUS" + +BFG_DRIVER(,DualMiner,Icarus,auto,[ + need_gc3355=yes + $broad_udevrules && have_udevrules=true +]) + +BFG_DRIVER(,ZeusMiner,scrypt Icarus,auto,[ + need_lowl_vcom=yes + has_asic=yes + $broad_udevrules && have_udevrules=true +]) + +BFG_DRIVER(,GridSeed,scrypt,auto,[ + need_gc3355=yes + need_lowl_vcom=yes + has_asic=yes + $broad_udevrules && have_udevrules=true +]) + +BFG_DRIVER(,Avalon,SHA256d,auto,[ + need_lowl_vcom=yes + has_asic=yes + $broad_udevrules && have_udevrules=true +]) + +BFG_DRIVER(avalonmm,Avalon2/3,SHA256d,auto,[ + need_lowl_vcom=yes + need_work2d=yes + has_asic=yes + $broad_udevrules && have_udevrules=true +]) + +BFG_DRIVER(,KnC,SHA256d,no,[ + need_linux_i2c_dev=yes + need_lowl_spi=yes +]) + +BFG_DRIVER(kncasic,KnC gen 2,SHA256d,no,[ + kncasic_controller="$kncasic_opt" + if test "x$kncasic_opt" = "x"; then + kncasic_controller=BBB + fi + need_knc_asic=yes + AC_DEFINE_UNQUOTED([CONTROLLER_BOARD_$kncasic_controller],[1]) +]) + +AC_ARG_WITH([libmicrohttpd], + [AC_HELP_STRING([--without-libmicrohttpd],[Compile support for libmicrohttpd getwork server (default enabled)])], + [httpsrv=$withval], + [httpsrv=$ddauto] +) +if test "x$httpsrv" != "xno"; then + PKG_CHECK_MODULES([libmicrohttpd],[libmicrohttpd >= 0.9.5],[ + AC_DEFINE([USE_LIBMICROHTTPD],[1],[Defined to 1 if libmicrohttpd support is wanted]) + httpsrv=yes + ],[ + httpsrv=no + httpsrv_enableaction="install libmicrohttpd 0.9.5+" + need_bfg_driver_proxy_enableaction="install libmicrohttpd 0.9.5+" + if test "x$httpsrv" = "xyes"; then + AC_MSG_ERROR([Unable to find libmicrohttpd 0.9.5+]) + else + AC_MSG_WARN([libmicrohttpd 0.9.5+ not found; getwork proxy will be unavailable]) + fi + ]) +fi +AM_CONDITIONAL([USE_LIBMICROHTTPD], [test x$httpsrv = xyes]) + +AC_ARG_WITH([libevent], + [AC_HELP_STRING([--without-libevent],[Compile support for libevent stratum server (default enabled)])], + [libevent=$withval], + [libevent=$ddauto] +) +if test "x$libevent" != "xno"; then + PKG_CHECK_MODULES([libevent],[libevent >= 2.0.3],[ + PKG_CHECK_MODULES([libevent_pthreads],[libevent_pthreads],[ + libevent_CFLAGS="${libevent_CFLAGS} ${libevent_pthreads_CFLAGS}" + libevent_LIBS="${libevent_LIBS} ${libevent_pthreads_LIBS}" + ],[true]) + AC_MSG_CHECKING([if libevent supports threading]) + BFG_PREPROC_IFELSE([EVTHREAD_USE_PTHREADS_IMPLEMENTED || EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED],[event2/thread.h],[ + AC_MSG_RESULT([yes]) + have_libevent=yes + ],[ + AC_MSG_RESULT([no]) + ]) + ]) + if test "x$have_libevent" = "xyes"; then + libevent=yes + need_work2d=yes + AC_DEFINE([USE_LIBEVENT],[1],[Defined to 1 if libevent support is wanted]) + else + libevent_enableaction="install libevent 2.0.3+" + if test -n "$need_bfg_driver_proxy_enableaction"; then + need_bfg_driver_proxy_enableaction="${need_bfg_driver_proxy_enableaction} (getwork) or libevent 2.0.3+ (stratum)" else - DLOPEN_FLAGS="" + need_bfg_driver_proxy_enableaction="install libevent 2.0.3+" fi + if test "x$libevent" = "xyes"; then + AC_MSG_ERROR([Unable to find libevent 2.0.3+]) + else + AC_MSG_WARN([libevent 2.0.3+ not found; stratum proxy will be unavailable]) + fi + libevent=no fi +fi +AM_CONDITIONAL([USE_LIBEVENT], [test x$libevent = xyes]) + +driverlist="$driverlist proxy/need_bfg_driver_proxy" +if test x$libevent$httpsrv = xnono; then + need_bfg_driver_proxy=no else - DLOPEN_FLAGS="" + need_bfg_driver_proxy=yes + driverlist="$driverlist proxy:getwork/httpsrv proxy:stratum/libevent" fi +AM_CONDITIONAL([NEED_BFG_DRIVER_PROXY], [test x$libevent$httpsrv != xnono]) -bitforce="no" +BFG_DRIVER(,ModMiner,SHA256d,auto,[ + need_dynclock=yes + need_lowl_vcom=yes + need_binloader=yes + has_fpga=yes + have_udevrules=true +]) + +PKG_PROG_PKG_CONFIG() -AC_ARG_ENABLE([bitforce], - [AC_HELP_STRING([--enable-bitforce],[Compile support for BitForce FPGAs(default disabled)])], - [bitforce=$enableval] +label_LIBUSB=libusb +USE_LIBUSB=no +libusb_include_path="" +AC_ARG_WITH([libusb], + [AC_HELP_STRING([--without-libusb],[Compile using libusb (default enabled)])], + [want_libusb=$withval], + [want_libusb=auto] ) -if test "x$bitforce" = xyes; then - AC_DEFINE([USE_BITFORCE], [1], [Defined to 1 if BitForce support is wanted]) +if test "x$want_libusb" != "xno"; then + howto_LIBUSB="install libusb 1.0+" +PKG_CHECK_MODULES([LIBUSB], [libusb-1.0],[ + USE_LIBUSB=yes +],[ + for usb_lib in usb-1.0 usb; do + AC_CHECK_LIB($usb_lib, libusb_init, [ + USE_LIBUSB=yes + break + ]) + done + if test "x$USE_LIBUSB" = xyes; then + AC_CHECK_DECL([libusb_init],[ + LIBUSB_LIBS="-l$usb_lib" + ],[ + BFG_FIND_INCLUDE_PATH([libusb-1.0],[libusb.h],[ + LIBUSB_LIBS="-l$usb_lib" + LIBUSB_CFLAGS="-I${inclpath_libusb_h}" + ],[ + USE_LIBUSB=no + ]) + ],[#include ]) + fi +]) fi -AM_CONDITIONAL([HAS_BITFORCE], [test x$bitforce = xyes]) -icarus="no" +BFG_DRIVER(,CoinTerra,SHA256d libusb,auto,[ + need_lowl_usb=yes + has_asic=yes + have_udevrules=true +]) -AC_ARG_ENABLE([icarus], - [AC_HELP_STRING([--enable-icarus],[Compile support for Icarus (default disabled)])], - [icarus=$enableval] - ) -if test "x$icarus" = xyes; then - AC_DEFINE([USE_ICARUS], [1], [Defined to 1 if Icarus support is wanted]) +BFG_DRIVER(,Klondike,SHA256d libusb,auto,[ + need_lowl_usb=yes + has_asic=yes + have_udevrules=true +]) + +BFG_DRIVER(titan,KnC Titan,scrypt,no,[ + if test "x$titan_opt" = "x"; then + if test "x$USE_KNCASIC" = "xyes"; then + titan_controller="$kncasic_controller" + else + titan_controller=RPI + fi + else + titan_controller=$titan_opt + if test "x$USE_KNCASIC" = "xyes"; then + if test "x$kncasic_controller" != "$titan_controller"; then + AC_MSG_ERROR([Can only build kncasic and titan drivers together for the same controller (kncasic=$kncasic_controller vs titan=$titan_controller)]) + fi + fi + fi + need_knc_asic=yes + AC_DEFINE_UNQUOTED([CONTROLLER_BOARD_$titan_controller],[1]) + AH_TEMPLATE([CONTROLLER_BOARD_BACKPLANE]) + AH_TEMPLATE([CONTROLLER_BOARD_BBB]) + AH_TEMPLATE([CONTROLLER_BOARD_RPI]) +]) + +BFG_DRIVER(,X6500,SHA256d libusb,auto,[ + need_dynclock=yes + need_lowl_ftdi=yes + need_binloader=yes + has_fpga=yes + have_udevrules=true +]) + +BFG_DRIVER(,ZTEX,SHA256d libusb,auto,[ + need_dynclock=yes + need_lowl_usb=yes + need_binloader=yes + has_fpga=yes + have_udevrules=true +]) + +BFG_DRIVER(bifury,Bi*Fury,SHA256d,auto,[ + need_lowl_vcom=yes + has_asic=yes + have_udevrules=true +]) + +BFG_DRIVER(,Bitfury,SHA256d,auto,[ + need_lowl_spi=yes +]) + +BFG_DRIVER(,BFSB,SHA256d Bitfury,no) + +BFG_DRIVER(bigpic,Big Picture Mining USB,SHA256d Bitfury,auto,[ + need_lowl_vcom=yes + has_asic=yes + have_udevrules=true +]) + +BFG_DRIVER(bfx,BFx2,SHA256d libusb Bitfury,auto,[ + need_lowl_ftdi=yes + has_asic=yes + $broad_udevrules && have_udevrules=true +]) + +BFG_DRIVER(,DrillBit,SHA256d Bitfury,auto,[ + need_lowl_vcom=yes + has_asic=yes + have_udevrules=true +]) + +BFG_DRIVER(,Twinfury,SHA256d Bitfury,auto,[ + need_lowl_vcom=yes + has_asic=yes + have_udevrules=true +]) + +BFG_DRIVER(,LittleFury,SHA256d Bitfury,auto,[ + need_lowl_vcom=yes + has_asic=yes + have_udevrules=true +]) + + +label_HIDAPI=hidapi +howto_HIDAPI="install hidapi" +USE_HIDAPI=no +for _hidapi_lib in hidapi hidapi-hidraw hidapi-libusb; do + PKG_CHECK_MODULES([hidapi],[$_hidapi_lib],[ + USE_HIDAPI=yes + break + ],[ + true + ]) +done + + +BFG_DRIVER(,NanoFury,SHA256d hidapi Bitfury,auto,[ + need_lowl_hid=yes + has_asic=yes + have_udevrules=true +]) + +BFG_DRIVER(hashbuster,HashBuster Nano,SHA256d hidapi Bitfury,auto,[ + need_lowl_hid=yes + has_asic=yes + have_udevrules=true +]) + +BFG_DRIVER(hashbusterusb,HashBuster Micro,SHA256d libusb Bitfury,auto,[ + need_lowl_usb=yes + has_asic=yes + have_udevrules=true +]) + +BFG_DRIVER(,HashFast,SHA256d,auto,[ + need_lowl_vcom=yes + has_asic=yes + have_udevrules=true +]) + +BFG_DRIVER(,JingTian,SHA256d,no,[ + need_lowl_spi=yes + has_asic=yes +]) + +BFG_DRIVER(,Metabank,SHA256d Bitfury,no) + +BFG_DRIVER(minergate,Spondoolies minergate interface,SHA256d,no,[ + need_lowlevel=yes + has_asic=yes +]) + +BFG_DRIVER(,Minion,SHA256d,no,[ + need_lowl_spi=yes + has_asic=yes +]) + +BFG_DRIVER(,RockMiner,SHA256d,auto,[ + need_lowl_vcom=yes + has_asic=yes + have_udevrules=true +]) + + +if test "x$need_lowl_vcom" != "xno"; then + # Lowlevel VCOM doesn't need libusb, but it can take advantage of it to reattach drivers + if test "x$USE_LIBUSB" != xno; then + need_lowl_usb=yes + elif test "x$USE_LIBUSB$want_libusb" = xnoyes; then + AC_MSG_ERROR([Could not find libusb, which you specifically requested]) + fi fi -AM_CONDITIONAL([HAS_ICARUS], [test x$icarus = xyes]) -modminer="no" +lowllist="$lowllist ftdi/need_lowl_ftdi" +if test x$need_lowl_ftdi = xyes; then + AC_DEFINE([NEED_BFG_LOWL_FTDI], [1], [Defined to 1 if lowlevel ftdi drivers are being used]) + need_lowl_usb=yes +fi -AC_ARG_ENABLE([modminer], - [AC_HELP_STRING([--enable-modminer],[Compile support for ModMiner FPGAs(default disabled)])], - [modminer=$enableval] - ) -if test "x$modminer" = xyes; then - AC_DEFINE([USE_MODMINER], [1], [Defined to 1 if ModMiner support is wanted]) +lowllist="$lowllist spi/need_lowl_spi" +if test x$need_lowl_spi = xyes; then + AC_DEFINE([NEED_BFG_LOWL_SPI], [1], [Defined to 1 if lowlevel SPI drivers are being used]) fi -AM_CONDITIONAL([HAS_MODMINER], [test x$modminer = xyes]) -ztex="no" +if test "x$need_lowl_usb" = "xno"; then + USE_LIBUSB=no + LIBUSB_LIBS='' + LIBUSB_CFLAGS='' +fi +if test "x$USE_LIBUSB" = xyes; then + AC_DEFINE([HAVE_LIBUSB], [1], [Define if you have libusb-1.0]) + save_CFLAGS="$CFLAGS" + CFLAGS="$LIBUSB_CFLAGS $CFLAGS" + AC_CHECK_DECLS([libusb_error_name],[true],[true],[#include ]) + CFLAGS="$save_CFLAGS" +fi -AC_ARG_ENABLE([ztex], - [AC_HELP_STRING([--enable-ztex],[Compile support for Ztex (default disabled)])], - [ztex=$enableval] - ) -if test "x$ztex" = xyes; then - AC_DEFINE([USE_ZTEX], [1], [Defined to 1 if Ztex support is wanted]) + +if test x$need_lowl_vcom = xyes; then + AC_DEFINE([NEED_BFG_LOWL_VCOM], [1], [Defined to 1 if lowlevel VCOM drivers are being used]) + need_lowlevel=yes + + if $have_win32; then + echo '#include ' >iospeeds_local.h + + found_ddkusb=false + AC_CHECK_HEADER([usbiodef.h],[ + found_ddkusb=true + ],[ + BFG_FIND_INCLUDE_PATH([ddk],[usbiodef.h],[ + found_ddkusb=true + AUTOSCAN_CPPFLAGS="-I${inclpath_usbiodef_h}" + ],[],[ + #include + #include + AC_INCLUDES_DEFAULT + ]) + ],[ + #include + #include + AC_INCLUDES_DEFAULT + ]) + if $found_ddkusb; then + AUTOSCAN_LIBS="-lsetupapi" + AC_DEFINE([HAVE_WIN_DDKUSB],[1],[Defined to 1 if Windows DDK USB headers are being used]) + fi + else + AC_MSG_CHECKING([what baud rates your system supports]) + echo '#include ' | ${CPP} -dM - 2>/dev/null | ${SED} 's/.*[ ]B\([0-9][0-9]*\)[ ].*/IOSPEED(\1)/' | grep IOSPEED >iospeeds_local.h + if grep -q IOSPEED iospeeds_local.h; then + AC_MSG_RESULT([done]) + else + AC_MSG_RESULT([failed, using standard POSIX]) + echo '#include ' >iospeeds_local.h + fi + fi +fi + +if test "x$USE_OPENCL$need_lowl_hid" = xnono; then + DLOPEN_FLAGS="" +fi + +lowllist="$lowllist hid/need_lowl_hid" +if test x$need_lowl_hid = xyes; then + AC_DEFINE([NEED_BFG_LOWL_HID], [1], [Defined to 1 if lowlevel hid drivers are being used]) + need_lowlevel=yes +fi + +lowllist="$lowllist mswin/need_lowl_mswin" +if test x$need_lowl_mswin = xyes; then + AC_DEFINE([NEED_BFG_LOWL_MSWIN], [1], [Defined to 1 if lowlevel mswin drivers are being used]) + need_lowlevel=yes fi -AM_CONDITIONAL([HAS_ZTEX], [test x$ztex = xyes]) + +lowllist="$lowllist pci/need_lowl_pci" +if test x$need_lowl_pci = xyes; then + AC_DEFINE([NEED_BFG_LOWL_PCI], [1], [Defined to 1 if lowlevel PCI drivers are being used]) + need_lowlevel=yes + lowllist="$lowllist pci:uio/uio" + if test x$uio = xyes; then + AC_DEFINE([USE_UIO], [1], [Defined to 1 if lowlevel PCI drivers should support UIO]) + fi + lowllist="$lowllist pci:vfio/vfio" + if test x$vfio = xyes; then + AC_DEFINE([USE_VFIO], [1], [Defined to 1 if lowlevel PCI drivers should support VFIO]) + fi +fi +AM_CONDITIONAL([USE_VFIO], [test x$need_lowl_pci$vfio = xyesyes]) + +lowllist="$lowllist usb/need_lowl_usb" +if test x$need_lowl_usb = xyes; then + need_lowlevel=yes +fi + +lowllist="$lowllist vcom/need_lowl_vcom" +if test x$need_lowl_vcom = xyes; then + need_lowlevel=yes +fi + +if test x$need_lowlevel = xyes; then + AC_DEFINE([HAVE_BFG_LOWLEVEL], [1], [Defined to 1 if lowlevel drivers are being used]) +fi + +if test x$need_linux_i2c_dev = xyes; then + AC_CHECK_HEADERS([linux/i2c-dev-user.h]) + AC_CHECK_DECL([i2c_smbus_read_word_data],[true],[ + AC_MSG_ERROR([linux/i2c-dev.h header from i2c-tools/libi2c-dev (NOT linux headers) is required for KnCMiner drivers]) + ],[ + #include + #ifdef HAVE_LINUX_I2C_DEV_USER_H + #include + #else + #ifdef NEED_LINUX_I2C_H + #include + #endif + #include + #endif + ]) +fi + curses="auto" @@ -204,43 +1046,163 @@ AC_ARG_WITH([curses], [curses=$withval] ) if test "x$curses" = "xno"; then - cursesmsg='User specified --without-curses. TUI support DISABLED' + optlist="$optlist curses" else - AC_SEARCH_LIBS(addstr, ncurses pdcurses, [ - curses=yes - cursesmsg="FOUND: ${ac_cv_search_addstr:2}" - AC_DEFINE([HAVE_CURSES], [1], [Defined to 1 if curses TUI support is wanted]) - ], [ - if test "x$curses" = "xyes"; then - AC_MSG_ERROR([Could not find curses library - please install libncurses-dev or pdcurses-dev (or configure --without-curses)]) - else - AC_MSG_WARN([Could not find curses library - if you want a TUI, install libncurses-dev or pdcurses-dev]) - curses=no - cursesmsg='NOT FOUND. TUI support DISABLED' + curses_enableaction="install a curses library" + orig_libs="$LIBS" + if test "x${curses}" = "xyes"; then + preferl='' + else + preferl="${curses} ${curses}6 ${curses}5" + fi + for wideornot in w u ''; do + for ncursesver in '' 6 5; do + preferl="${preferl} ncurses${wideornot}${ncursesver}" + done + preferl="${preferl} pdcurses${wideornot}" + done + if test "x$cross_compiling" != "xyes"; then + AC_MSG_CHECKING([for best native curses library]) + orig_cflags="$CFLAGS" + for curses_lib in ${preferl}; do + if ! ${curses_lib}-config --cflags >/dev/null 2>/dev/null; then + continue + fi + CFLAGS="$orig_cflags $(${curses_lib}-config --cflags)" + LIBS="$orig_libs $(${curses_lib}-config --libs)" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + ]], [[ + WINDOW *w = NULL; + mvwprintw(w, 2, 2, "Testing %s", "o hai"); + ]])], [ + curses=yes + optlist="$optlist ${curses_lib}/curses" + AC_MSG_RESULT([$curses_lib]) + NCURSES_LIBS=`${curses_lib}-config --libs` + NCURSES_CPPFLAGS=`${curses_lib}-config --cflags` + break + ], [ + AC_MSG_WARN([${curses_lib} doesn't seem to be installed properly]) + ]) + done + CFLAGS="$orig_cflags" + if test "x$curses" != "xyes"; then + AC_MSG_RESULT([none?]) fi - ]) + fi + if test "x$curses" != "xyes"; then + sym=addstr + AC_SEARCH_LIBS(${sym}, ${preferl}, [ + curses=yes + eval "curseslib=\"\${ac_cv_search_${sym}}\"" + barelib=`echo "${curseslib}" | ${SED} -e 's/-l//'` + optlist="$optlist ${barelib}/curses" + if test "x${curseslib}" != "xnone required"; then + NCURSES_LIBS="${curseslib}" + fi + + # Need to check for headers in subdirectories, to ensure we get wide stuff + barelib=`echo "${barelib}" | ${SED} -e 's/6//'` + barelib=`echo "${barelib}" | ${SED} -e 's/5//'` + BFG_FIND_INCLUDE_PATH([${barelib}],[curses.h],[ + NCURSES_CPPFLAGS="-I${inclpath_curses_h}" + ]) + + break + ], [ + if test "x$curses" = "xyes"; then + AC_MSG_ERROR([Could not find curses library - please install libncurses-dev or pdcurses-dev (or configure --without-curses)]) + else + AC_MSG_WARN([Could not find curses library - if you want a TUI, install libncurses-dev or pdcurses-dev]) + curses=no + optlist="$optlist curses" + fi + ]) + fi + if test "x$curses" = "xyes"; then + AC_DEFINE([HAVE_CURSES], [1], [Defined to 1 if curses TUI support is wanted]) + AC_MSG_CHECKING([whether curses library supports wide characters]) + orig_cflags="$CFLAGS" + CFLAGS="$orig_cflags $NCURSES_CPPFLAGS" + LIBS="$orig_libs $NCURSES_LIBS" + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ + #define PDC_WIDE + #include + ],[ + addwstr(L"test"); + add_wch(WACS_VLINE); + ]) + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE([USE_UNICODE],[1],[Defined to 1 if curses supports wide characters]) + ],[ + AC_MSG_RESULT([no]) + ]) + CFLAGS="$orig_cflags" + fi + LIBS="$orig_libs" fi -AM_CONDITIONAL([NEED_FPGAUTILS], [test x$icarus$bitforce$modminer$ztex != xnononono]) +BFG_BUNDLED_LIB([libbase58],[libbase58],[auto],[libbase58],[base58],[],[--disable-tool --disable-static --enable-shared]) +BFG_BUNDLED_LIB([libblkmaker],[libblkmaker_jansson-0.1],[no],[libblkmaker],[blkmaker_jansson-0.1 blkmaker-0.1],[libbase58]) + + +$have_udevrules || use_udevrules=false +if $use_udevrules; then + AC_ARG_WITH([udevrulesdir], + AS_HELP_STRING([--with-udevrulesdir=DIR], [Install udev rules into this directory]), + [], [ + if test -d /lib/udev/rules.d; then + with_udevrulesdir=/lib/udev/rules.d + else + with_udevrulesdir=no + fi + ] + ) + if test "x$with_udevrulesdir" = "xno"; then + use_udevrules=false + fi + if $use_udevrules; then + AC_SUBST([udevrulesdir], [$with_udevrulesdir]) + fi +fi + + +AM_CONDITIONAL([NEED_BFG_BINLOADER], [test x$need_binloader = xyes]) +AM_CONDITIONAL([NEED_DYNCLOCK], [test x$need_dynclock = xyes]) +AM_CONDITIONAL([USE_GC3355], [test x$need_gc3355 = xyes]) +AM_CONDITIONAL([NEED_BFG_LOWL_VCOM], [test x$need_lowl_vcom = xyes]) +AM_CONDITIONAL([NEED_BFG_LOWL_FTDI], [test x$need_lowl_ftdi = xyes]) +AM_CONDITIONAL([NEED_BFG_LOWL_HID], [test x$need_lowl_hid = xyes]) +AM_CONDITIONAL([NEED_BFG_LOWL_MSWIN], [test x$need_lowl_mswin = xyes]) +AM_CONDITIONAL([NEED_BFG_LOWL_PCI], [test x$need_lowl_pci = xyes]) +AM_CONDITIONAL([NEED_BFG_LOWL_SPI], [test x$need_lowl_spi = xyes]) +AM_CONDITIONAL([NEED_BFG_LOWLEVEL], [test x$need_lowlevel = xyes]) +AM_CONDITIONAL([NEED_BFG_WORK2D], [test x$need_work2d = xyes]) +AM_CONDITIONAL([NEED_KNC_ASIC], [test x$need_knc_asic = xyes]) AM_CONDITIONAL([HAVE_CURSES], [test x$curses = xyes]) -AM_CONDITIONAL([WANT_JANSSON], [test x$request_jansson = xtrue]) +AM_CONDITIONAL([HAVE_SENSORS], [test x$with_sensors = xyes]) +AM_CONDITIONAL([HAVE_CYGWIN], [test x$have_cygwin = xtrue]) +AM_CONDITIONAL([HAVE_LIBUSB], [test x$USE_LIBUSB = xyes]) AM_CONDITIONAL([HAVE_WINDOWS], [test x$have_win32 = xtrue]) AM_CONDITIONAL([HAVE_x86_64], [test x$have_x86_64 = xtrue]) - -if test x$request_jansson = xtrue -then - JANSSON_LIBS="compat/jansson/libjansson.a" -else - JANSSON_LIBS=-ljansson -fi +AM_CONDITIONAL([HAVE_WIN_DDKUSB], [test x$found_ddkusb = xtrue]) +AM_CONDITIONAL([HAS_FPGA], [test x$has_fpga != xno]) +AM_CONDITIONAL([HAS_ASIC], [test x$has_asic != xno]) +AM_CONDITIONAL([USE_UDEVRULES], [$use_udevrules]) +AM_CONDITIONAL([BROAD_UDEVRULES], [$broad_udevrules]) dnl Find YASM has_yasm=false +if test "x$have_x86_32$have_x86_64" != "xfalsefalse"; then AC_PATH_PROG([YASM],[yasm],[false]) if test "x$YASM" != "xfalse" ; then + has_yasm_enableaction="install yasm 1.0.1+" AC_MSG_CHECKING([if yasm version is greater than 1.0.1]) - yasmver=`yasm --version | head -1 | cut -d\ -f2` + yasmver=`"$YASM" --version | head -1 | cut -d\ -f2` yamajor=`echo $yasmver | cut -d. -f1` yaminor=`echo $yasmver | cut -d. -f2` yamini=`echo $yasmver | cut -d. -f3` @@ -267,11 +1229,67 @@ if test "x$YASM" != "xfalse" ; then fi if test "x$has_yasm" = "xfalse" ; then AC_MSG_NOTICE([yasm is required for the assembly algorithms. They will be skipped.]) +else + AC_DEFINE([HAVE_YASM], [1], [Defined to 1 if yasm is being used]) + if test "x$have_win32$have_cygwin" != "xfalsefalse"; then + if test "x$have_x86_64" = xtrue; then + YASM_FMT="win64" + else + YASM_FMT="coff" + fi + elif test "x$have_macho" = "xtrue"; then + YASM_FMT="macho$bitness" + else + YASM_FMT="elf$bitness" + fi +fi + fi AM_CONDITIONAL([HAS_YASM], [test x$has_yasm = xtrue]) -if test "x$bitforce$modminer" != xnono; then +have_sse2=no +if test "x$USE_CPUMINING$have_x86_32" = "xyestrue"; then + AC_MSG_CHECKING([if SSE2 code compiles]) + save_CFLAGS="$CFLAGS" + for flags in '' '-msse2'; do + CFLAGS="$CFLAGS $flags" + AC_TRY_LINK([ + #include + ],[ + int *i = (int *)0xdeadbeef; + __m128i a, b; + a = _mm_set1_epi32(i[0]); + b = _mm_set_epi32(i[0], i[1], i[2], i[3]); + a = _mm_add_epi32(a, b); + a = _mm_andnot_si128(a, b); + a = _mm_or_si128(a, b); + a = _mm_slli_epi32(a, i[4]); + a = _mm_and_si128(a, b); + a = _mm_xor_si128(a, b); + ],[ + if test "x$flags" = "x"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([with $flags]) + fi + SSE2_CFLAGS="$flags" + have_sse2=yes + break + ],[ + true + ]) + done + CFLAGS="${save_CFLAGS}" + if test "x$have_sse2" = "xyes"; then + AC_DEFINE([HAVE_SSE2], [1], [Defined to 1 if yasm is being used]) + else + AC_MSG_RESULT([no]) + fi +fi +AM_CONDITIONAL([HAVE_SSE2], [test "x$have_sse2" = "xyes"]) + +if test "x$need_lowl_vcom" = "xyes"; then AC_ARG_WITH([libudev], [AC_HELP_STRING([--without-libudev], [Autodetect FPGAs using libudev (default enabled)])], [libudev=$withval], [libudev=auto] @@ -291,20 +1309,18 @@ if test "x$bitforce$modminer" != xnono; then fi AM_CONDITIONAL([HAVE_LIBUDEV], [test x$libudev != xno]) -if test "x$ztex" != xno; then - AC_CHECK_LIB(usb-1.0, libusb_init, , - AC_MSG_ERROR([Could not find usb library - please install libusb])) - AC_DEFINE([HAVE_LIBUSB], [1], [Defined to 1 if libusb is wanted]) - USB_LIBS="-lusb-1.0" - USB_FLAGS="" -fi - -PKG_PROG_PKG_CONFIG() +AC_SUBST(LIBUSB_LIBS) +AC_SUBST(LIBUSB_CFLAGS) -PKG_CHECK_MODULES([LIBCURL], [libcurl >= 7.15.6], [AC_DEFINE([CURL_HAS_SOCKOPT], [1], [Defined if version of curl supports sockopts.])], -[PKG_CHECK_MODULES([LIBCURL], [libcurl >= 7.10.1], ,[AC_MSG_ERROR([Missing required libcurl dev >= 7.10.1])])]) +PKG_CHECK_MODULES([LIBCURL], [libcurl >= 7.18.2], ,[AC_MSG_ERROR([Missing required libcurl dev >= 7.18.2])]) +if echo "$LIBCURL_CFLAGS" | grep '@CPPFLAG_CURL_STATICLIB@' >/dev/null 2>&1; then + AC_MSG_WARN([Your libcurl pkgconfig file is broken, applying workaround]) + LIBCURL_CFLAGS=`echo "$LIBCURL_CFLAGS" | ${SED} 's/@CPPFLAG_CURL_STATICLIB@//'` +fi AC_SUBST(LIBCURL_LIBS) +AC_CHECK_FUNCS([setrlimit]) + dnl CCAN wants to know a lot of vars. # All the configuration checks. Regrettably, the __attribute__ checks will # give false positives on old GCCs, since they just cause warnings. But that's @@ -316,8 +1332,14 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([static void __attribute__((const)) cleanup(vo AC_DEFINE([HAVE_ATTRIBUTE_CONST], [1], [Define if __attribute__((const))])) AC_COMPILE_IFELSE([AC_LANG_SOURCE([static void __attribute__((noreturn)) cleanup(void) { exit(1); }])], + [ AC_DEFINE([HAVE_ATTRIBUTE_NORETURN], [1], - [Define if __attribute__((noreturn))])) + [Define if __attribute__((noreturn))]) + AC_DEFINE_UNQUOTED([NORETURN], [__attribute__((noreturn))], [Syntax of noreturn attribute]) + ], [ + AC_DEFINE_UNQUOTED([NORETURN], []) + ] +) AC_COMPILE_IFELSE([AC_LANG_SOURCE([static void __attribute__((format(__printf__, 1, 2))) cleanup(const char *fmt, ...) { }])], AC_DEFINE([HAVE_ATTRIBUTE_PRINTF], [1], [Define if __attribute__((format(__printf__)))])) @@ -337,117 +1359,261 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([static int __attribute__((warn_unused_result) AC_DEFINE([HAVE_WARN_UNUSED_RESULT], [1], [Define if __attribute__((warn_unused_result))])) + +# byteswap functions +AH_TEMPLATE([HAVE_BYTESWAP_H], [Define to use byteswap macros from byteswap.h]) +AH_TEMPLATE([HAVE_ENDIAN_H], [Define to use byteswap macros from endian.h]) +AH_TEMPLATE([HAVE_SYS_ENDIAN_H], [Define to use byteswap macros from sys/endian.h]) +AH_TEMPLATE([HAVE_LIBKERN_OSBYTEORDER_H], [Define to use byteswap macros from libkern/OSByteOrder.h]) +BSWAP='' +for sym in bswap_ __builtin_bswap __bswap_ __swap swap OSSwapInt; do + AC_MSG_CHECKING([for ${sym}* functions]) + for headerfile in '' byteswap.h endian.h sys/endian.h libkern/OSByteOrder.h; do + BFG_INCLUDE([headerinclude], [${headerfile}]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ + ${headerinclude} + ], [ + (void) ${sym}16(0); + (void) ${sym}32(0); + (void) ${sym}64(0); + ]) + ], [ + BSWAP="${sym}" + if test "x${headerfile}" = "x"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([found in ${headerfile}]) + AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$headerfile]), 1) + fi + break 2 + ]) + done + AC_MSG_RESULT([no]) +done +if test "x$BSWAP" = "x"; then + true # Substitutes are provided in miner.h +elif test "x$BSWAP" = "xbswap_"; then + AC_MSG_CHECKING([if bswap_16 is already a macro]) + BFG_PREPROC_IFELSE([defined(bswap_16)], $headerfile, [ + AC_MSG_RESULT([yes]) + BSWAP="" + ],[ + AC_MSG_RESULT([no]) + ]) +fi +if test "x$BSWAP" != "x"; then + AC_DEFINE_UNQUOTED([bswap_16], ${BSWAP}16, [Define to 16-bit byteswap macro]) + AC_DEFINE_UNQUOTED([bswap_32], ${BSWAP}32, [Define to 16-bit byteswap macro]) + AC_DEFINE_UNQUOTED([bswap_64], ${BSWAP}64, [Define to 16-bit byteswap macro]) +fi + +# endian definition macros +AC_MSG_CHECKING([for platform endian]) +found_endian=no +for headerfile in '' endian.h sys/endian.h sys/param.h; do + for pfx in '' '__'; do + BFG_PREPROC_IFELSE([defined(${pfx}BYTE_ORDER) && defined(${pfx}BIG_ENDIAN) && defined(${pfx}LITTLE_ENDIAN) && (${pfx}BYTE_ORDER == ${pfx}BIG_ENDIAN || ${pfx}BYTE_ORDER == ${pfx}LITTLE_ENDIAN)], ${headerfile}, [ + if test "x$headerfile" = "x"; then + headerfilec='' + else + headerfilec=" (${headerfile})" + fi + BFG_PREPROC_IFELSE([${pfx}BYTE_ORDER == ${pfx}BIG_ENDIAN], ${headerfile}, [ + AC_MSG_RESULT([big endian${headerfilec}]) + AC_DEFINE(WORDS_BIGENDIAN, 1, [Define if your platform is big endian]) + ], [ + AC_MSG_RESULT([little endian${headerfilec}]) + ]) + found_endian=yes + break 2 + ],[true]) + done +done +if test "x$found_endian" = "xno"; then + if $have_win32 || $have_cygwin; then + AC_MSG_RESULT([assuming little endian (Windows)]) + else + # AC_C_BIGENDIAN is reported to have problems, and invasive even if buried in a conditional, so don't use it + AC_MSG_RESULT([unknown]) + AC_MSG_ERROR([Unable to identify platform endian]) + fi +fi + + +AC_MSG_CHECKING([if good static asserts compile]) +AC_TRY_LINK([ + #include +], [ + _Static_assert(1, ":)"); +], [ + AC_MSG_RESULT([yes]) +], [ + AC_MSG_RESULT([no]) + AC_DEFINE_UNQUOTED([_Static_assert(...)], [], [Turns _Static_assert into noop for compilers that don't support it]) +]) + + +AC_MSG_CHECKING([if GNU format attribute compiles]) +AC_TRY_COMPILE([ + #define FORMAT_SYNTAX_CHECK(...) __attribute__(( format(__VA_ARGS__) )) + int myfunc(char *fmt, ...) FORMAT_SYNTAX_CHECK(printf, 1, 2); + int myfunc(char *fmt, ...) { + return 42; + } +], [ + myfunc("abc%d", 42); +], [ + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED([FORMAT_SYNTAX_CHECK(...)], [__attribute__(( format(__VA_ARGS__) ))], [Syntax of format-checking attribute]) +], [ + AC_MSG_RESULT([no]) + AC_DEFINE_UNQUOTED([FORMAT_SYNTAX_CHECK(...)], []) +]) + + +AC_MSG_CHECKING([for clock_gettime(CLOCK_MONOTONIC)]) +AC_TRY_COMPILE([ + #define _GNU_SOURCE + #include +],[ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); +],[ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_CLOCK_GETTIME_MONOTONIC], [1], [Defined to 1 if clock_gettime(CLOCK_MONOTONIC) is defined]) + save_LIBS="${LIBS}" + AC_SEARCH_LIBS([clock_gettime],[rt posix4],[ + if test "x${ac_cv_search_clock_gettime}" != "xnone required"; then + RT_LIBS="${ac_cv_search_clock_gettime}" + fi + ]) + LIBS="${save_LIBS}" + AC_CHECK_FUNCS([clock_nanosleep]) + AC_MSG_CHECKING([for clock_gettime(CLOCK_MONOTONIC_RAW)]) + AC_TRY_COMPILE([ + #define _GNU_SOURCE + #include + ],[ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_CLOCK_GETTIME_MONOTONIC_RAW], [1], [Defined to 1 if clock_gettime(CLOCK_MONOTONIC_RAW) is defined]) + ],[ + AC_MSG_RESULT([no]) + ]) +],[ + AC_MSG_RESULT([no]) +]) + + +save_LIBS="$LIBS" +LIBS="$LIBS $MATH_LIBS" +AC_CHECK_FUNCS([log2]) +LIBS="$save_LIBS" + + if test "x$prefix" = xNONE; then prefix=/usr/local fi -AC_DEFINE_UNQUOTED([CGMINER_PREFIX], ["$prefix/bin"], [Path to bfgminer install]) +AM_CONDITIONAL([NEED_BITSTREAM_FPGAMINER], [test x$USE_MODMINER$USE_X6500 != xnono]) + +dnl Hide unnecessary explanations, only after any fatal errors +howto_SHA256D=x +if test "x$USE_SHA256D" = xno; then + howto_BITFURY=x +fi +if test "x$want_libusb" = xno; then + howto_LIBUSB=x +fi -AC_DEFINE_UNQUOTED([PHATK_KERNNAME], ["phatk120223"], [Filename for phatk kernel]) -AC_DEFINE_UNQUOTED([POCLBM_KERNNAME], ["poclbm120327"], [Filename for poclbm kernel]) -AC_DEFINE_UNQUOTED([DIAKGCN_KERNNAME], ["diakgcn120427"], [Filename for diakgcn kernel]) -AC_DEFINE_UNQUOTED([DIABLO_KERNNAME], ["diablo120328"], [Filename for diablo kernel]) +m4_define([BFG_PRINT_LIST],[ + eval _mylist="\$$2" + _yeslist= + _nolist= + _enableactions= + foundone=no + for _opt in $_mylist; do + IFS=/ read _opt _var <