diff --git a/extra/README b/extra/README deleted file mode 100644 index 86ca6270b..000000000 --- a/extra/README +++ /dev/null @@ -1,2 +0,0 @@ -This folder contains packages that we are unsure -whether they can be deleted or are needed. diff --git a/extra/af_alg/Makefile b/extra/af_alg/Makefile deleted file mode 100644 index 8998c2bd6..000000000 --- a/extra/af_alg/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# -# Copyright (C) 2006-2010 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_RELEASE:=1 -PKG_VERSION:=1 -PKG_SOURCE_URL:=git://git.carnivore.it/users/common/af_alg.git -PKG_SOURCE_VERSION:=1851bbb010c38878c83729be844f168192059189 - -PKG_NAME:=af_alg -PKG_VERSION:=0.1 - -DEPENDS:=libopenssl - -export BUILD_DIR - -PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz - - -TARGET_LDFLAGS+= \ - -Wl,-rpath-link=$(STAGING_DIR)/usr/lib -MAKE_FLAGS += TARGET="$(target)" -TARGET_CFLAGS += -Dtarget_$(target)=1 -Wall - -include $(INCLUDE_DIR)/package.mk - - -define Package/af_alg - CATEGORY:=Libraries - TITLE:=Openssl af_alg engine - URL:= -endef - -define Package/af_alg/description - Openssl af_alg engine -endef - -define Build/Compile - $(MAKE_VARS) \ - $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(MAKE_PATH) \ - $(MAKE_FLAGS) -endef - -define Package/af_alg/install - $(INSTALL_DIR) $(1)/usr - $(INSTALL_DIR) $(1)/usr/lib - $(INSTALL_DIR) $(1)/usr/lib/engines - cp $(PKG_BUILD_DIR)/libaf_alg.so $(1)/usr/lib/engines/ -endef - -$(eval $(call BuildPackage,af_alg)) diff --git a/extra/af_alg/patches/001-Makefile_fix.patch b/extra/af_alg/patches/001-Makefile_fix.patch deleted file mode 100644 index ab73643ad..000000000 --- a/extra/af_alg/patches/001-Makefile_fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/Makefile 2014-02-17 13:00:44.161670649 +0100 -+++ b/Makefile 2014-02-17 13:00:51.633670316 +0100 -@@ -24,7 +24,7 @@ - LDFLAGS = - - SPEC_LDFLAGS = \ -- -lcrypto -+ -lcrypt - - CC = cc - LD = $(CC) diff --git a/extra/compcache/Config.in b/extra/compcache/Config.in deleted file mode 100644 index b5f75d00d..000000000 --- a/extra/compcache/Config.in +++ /dev/null @@ -1,29 +0,0 @@ -menu "Configuration" - depends on PACKAGE_compcache - -config COMPCACHE_ENABLE - bool "enabled on boot" - default n - help - Enables compressed ram swap devices. - -config COMPCACHE_RAM_REPORTED - string "swap space reported to kernel in kb" - default "2048" - help - This is the amount of memory that will be reported - to the kernel as swap. The real ram in use will differ, - because of lzo compression. - Example: - 16 MB = 2048 KB - 32 MB = 4098 KB - -config COMPCACHE_BACKUP_DEV - string "Backup device for compcache" - default "" - help - Compcache will use this as a backup device for swap. - Example: - /dev/sda5 - -endmenu diff --git a/extra/compcache/Makefile b/extra/compcache/Makefile deleted file mode 100644 index 5106293e8..000000000 --- a/extra/compcache/Makefile +++ /dev/null @@ -1,75 +0,0 @@ -# -# Copyright (C) 2009-2010 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=compcache -PKG_VERSION:=0.6.2 -PKG_RELEASE:=2 -PKG_SOURCE_URL:=http://compcache.googlecode.com/files/ -PKG_MD5SUM:=27aec78dc50e34fb800c74e879057743 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz - -include $(INCLUDE_DIR)/package.mk - -define KernelPackage/ramzswap - SUBMENU:=Other modules - DEPENDS:=@BUSYBOX_CONFIG_SWAPONOFF - TITLE:=Driver for compressed ram swap device - VERSION:=$(LINUX_VERSION)-$(BOARD)-$(LINUX_RELEASE)+$(PKG_RELEASE) - FILES:=$(PKG_BUILD_DIR)/ramzswap.ko \ - $(PKG_BUILD_DIR)/sub-projects/compression/lzo-kmod/lzo1x.ko - URL:=http://code.google.com/p/compcache/ -endef - -define Package/compcache - SECTION:=util - CATEGORY:=Utilities - DEPENDS:=+kmod-ramzswap - TITLE:=Compressed ram swap device - URL:=http://code.google.com/p/compcache/ - MENU:=1 -endef - -include $(INCLUDE_DIR)/kernel-defaults.mk - -LZO = sub-projects/compression/lzo-kmod -RZSC = sub-projects/rzscontrol - -BUILDFLAGS:=-DCONFIG_RAMZSWAP_STATS \ - -I$(PKG_BUILD_DIR)/$(LZO) \ - -Wall - -RZSCFLAGS:=-I$(PKG_BUILD_DIR)/$(RZSC)/../include \ - -I$(PKG_BUILD_DIR)/$(RZSC)/../.. - -define Build/Compile - $(MAKE) $(KERNEL_MAKEOPTS) EXTRA_CFLAGS="$(BUILDFLAGS)" M="$(PKG_BUILD_DIR)" modules - $(TARGET_CC) $(TARGET_CFLAGS) $(RZSCFLAGS) $(PKG_BUILD_DIR)/$(RZSC)/rzscontrol.c -o $(PKG_BUILD_DIR)/rzscontrol -endef - -define Package/compcache/install - $(INSTALL_DIR) $(1)/etc/config - $(INSTALL_DATA) ./files/compcache.config $(1)/etc/config/compcache - $(SED) 's,%ENABLED%,$(if $(CONFIG_COMPCACHE_ENABLE),1,0),g' \ - -e 's,%RAM_REPORTED%,$(call qstrip,$(CONFIG_COMPCACHE_RAM_REPORTED)),g' \ - -e 's,%BACKUP_DEV%,$(call qstrip,$(CONFIG_COMPCACHE_BACKUP_DEV)),g' \ - $(1)/etc/config/compcache - $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_BIN) ./files/compcache.init $(1)/etc/init.d/compcache - $(INSTALL_DIR) $(1)/sbin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/rzscontrol $(1)/sbin/rzscontrol -endef - -define Package/compcache/config - source "$(SOURCE)/Config.in" -endef - -$(eval $(call BuildPackage,compcache)) -$(eval $(call KernelPackage,ramzswap)) diff --git a/extra/compcache/files/compcache.config b/extra/compcache/files/compcache.config deleted file mode 100644 index 3faab3e14..000000000 --- a/extra/compcache/files/compcache.config +++ /dev/null @@ -1,4 +0,0 @@ -config compcache - option 'enabled' '%ENABLED%' - option 'size_kbytes' '%RAM_REPORTED%' - option 'backup_dev' '%BACKUP_DEV%' diff --git a/extra/compcache/files/compcache.init b/extra/compcache/files/compcache.init deleted file mode 100644 index 5939d9f61..000000000 --- a/extra/compcache/files/compcache.init +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright (C) 2008 OpenWrt.org -START=14 - -load_modules() { - local section="$1" - config_get "size_kbytes" "$section" "size_kbytes" - config_get "backup_dev" "$section" "backup_dev" - #CC_PARAM_STR="memlimit_kb=$1 backing_dev=$BACKING_DEV" - config_get_bool "enabled" "$section" "enabled" '1' - if [ "$enabled" -gt 0 ]; then - if [ "`cat /proc/swaps | grep 'ramzswap0'`" != "" ]; then - echo "compcache already loaded" - else - if [ "$backup_dev" != "" ]; then - params_set="memlimit_kb=$size_kbytes backing_swap=$backup_dev" - else - params_set="disksize_kb=$size_kbytes" - fi - if [ "`lsmod | grep 'ramzswap'`" == "" ]; then - insmod lzo1x - insmod ramzswap $params_set - sleep 2 - swapon /dev/ramzswap0 - fi - fi - fi -} - -remove_modules() { - local section="$1" - config_get_bool "enabled" "$section" "enabled" '1' - if [ "$enabled" -gt 0 ]; then - [ "`cat /proc/swaps | grep 'ramzswap0'`" != "" ] && swapoff /dev/ramzswap0 - [ "`lsmod | grep 'ramzswap'`" != "" ] && rmmod ramzswap &> /dev/null - [ "`lsmod | grep 'lzo1x'`" != "" ] && rmmod lzo1x &> /dev/null - fi -} - -start() { - config_load "compcache" - config_foreach load_modules "compcache" -} - -stop() { - config_load "compcache" - config_foreach remove_modules "compcache" -} diff --git a/extra/compcache/patches/000-provide_lzo_kmod.patch b/extra/compcache/patches/000-provide_lzo_kmod.patch deleted file mode 100644 index 1dab08507..000000000 --- a/extra/compcache/patches/000-provide_lzo_kmod.patch +++ /dev/null @@ -1,647 +0,0 @@ ---- a/Makefile -+++ b/Makefile -@@ -1,14 +1,17 @@ - KERNEL_BUILD_PATH ?= "/lib/modules/$(shell uname -r)/build" - - XVM = sub-projects/allocators/xvmalloc-kmod -+LZO = sub-projects/compression/lzo-kmod - EXTRA_CFLAGS := -DCONFIG_RAMZSWAP_STATS \ - -Wall - --obj-m += ramzswap.o -+obj-m += ramzswap.o $(LZO)/lzo1x.o - ramzswap-objs := ramzswap_drv.o $(XVM)/xvmalloc.o -+ - - all: - make -C $(KERNEL_BUILD_PATH) M=$(PWD) modules -+ make -C $(KERNEL_BUILD_PATH) M=$(PWD)/$(LZO) modules - make -C sub-projects/rzscontrol - - doc: -@@ -16,5 +19,6 @@ doc: - - clean: - make -C $(KERNEL_BUILD_PATH) M=$(PWD) clean -+ make -C $(KERNEL_BUILD_PATH) M=$(PWD)/$(LZO) clean - make -C sub-projects/rzscontrol clean - @rm -rf *.ko ---- a/ramzswap_drv.c -+++ b/ramzswap_drv.c -@@ -23,13 +23,13 @@ - #include - #include - #include --#include - #include - #include - #include - #include - #include - -+#include "lzo.h" - #include "compat.h" - #include "ramzswap_drv.h" - ---- /dev/null -+++ b/sub-projects/compression/lzo-kmod/lzo1x.c -@@ -0,0 +1,7 @@ -+#include -+ -+#include "lzo1x_compress.c" -+#include "lzo1x_decompress.c" -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("LZO1X Lib"); ---- /dev/null -+++ b/sub-projects/compression/lzo-kmod/lzo1x_compress.c -@@ -0,0 +1,227 @@ -+/* -+ * LZO1X Compressor from MiniLZO -+ * -+ * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer -+ * -+ * The full LZO package can be found at: -+ * http://www.oberhumer.com/opensource/lzo/ -+ * -+ * Changed for kernel use by: -+ * Nitin Gupta -+ * Richard Purdie -+ */ -+ -+#include -+#include -+#include -+ -+#include "lzodefs.h" -+#include "lzo.h" -+ -+static noinline size_t -+_lzo1x_1_do_compress(const unsigned char *in, size_t in_len, -+ unsigned char *out, size_t *out_len, void *wrkmem) -+{ -+ const unsigned char * const in_end = in + in_len; -+ const unsigned char * const ip_end = in + in_len - M2_MAX_LEN - 5; -+ const unsigned char ** const dict = wrkmem; -+ const unsigned char *ip = in, *ii = ip; -+ const unsigned char *end, *m, *m_pos; -+ size_t m_off, m_len, dindex; -+ unsigned char *op = out; -+ -+ ip += 4; -+ -+ for (;;) { -+ dindex = ((size_t)(0x21 * DX3(ip, 5, 5, 6)) >> 5) & D_MASK; -+ m_pos = dict[dindex]; -+ -+ if (m_pos < in) -+ goto literal; -+ -+ if (ip == m_pos || ((size_t)(ip - m_pos) > M4_MAX_OFFSET)) -+ goto literal; -+ -+ m_off = ip - m_pos; -+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) -+ goto try_match; -+ -+ dindex = (dindex & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f); -+ m_pos = dict[dindex]; -+ -+ if (m_pos < in) -+ goto literal; -+ -+ if (ip == m_pos || ((size_t)(ip - m_pos) > M4_MAX_OFFSET)) -+ goto literal; -+ -+ m_off = ip - m_pos; -+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) -+ goto try_match; -+ -+ goto literal; -+ -+try_match: -+ if (get_unaligned((const unsigned short *)m_pos) -+ == get_unaligned((const unsigned short *)ip)) { -+ if (likely(m_pos[2] == ip[2])) -+ goto match; -+ } -+ -+literal: -+ dict[dindex] = ip; -+ ++ip; -+ if (unlikely(ip >= ip_end)) -+ break; -+ continue; -+ -+match: -+ dict[dindex] = ip; -+ if (ip != ii) { -+ size_t t = ip - ii; -+ -+ if (t <= 3) { -+ op[-2] |= t; -+ } else if (t <= 18) { -+ *op++ = (t - 3); -+ } else { -+ size_t tt = t - 18; -+ -+ *op++ = 0; -+ while (tt > 255) { -+ tt -= 255; -+ *op++ = 0; -+ } -+ *op++ = tt; -+ } -+ do { -+ *op++ = *ii++; -+ } while (--t > 0); -+ } -+ -+ ip += 3; -+ if (m_pos[3] != *ip++ || m_pos[4] != *ip++ -+ || m_pos[5] != *ip++ || m_pos[6] != *ip++ -+ || m_pos[7] != *ip++ || m_pos[8] != *ip++) { -+ --ip; -+ m_len = ip - ii; -+ -+ if (m_off <= M2_MAX_OFFSET) { -+ m_off -= 1; -+ *op++ = (((m_len - 1) << 5) -+ | ((m_off & 7) << 2)); -+ *op++ = (m_off >> 3); -+ } else if (m_off <= M3_MAX_OFFSET) { -+ m_off -= 1; -+ *op++ = (M3_MARKER | (m_len - 2)); -+ goto m3_m4_offset; -+ } else { -+ m_off -= 0x4000; -+ -+ *op++ = (M4_MARKER | ((m_off & 0x4000) >> 11) -+ | (m_len - 2)); -+ goto m3_m4_offset; -+ } -+ } else { -+ end = in_end; -+ m = m_pos + M2_MAX_LEN + 1; -+ -+ while (ip < end && *m == *ip) { -+ m++; -+ ip++; -+ } -+ m_len = ip - ii; -+ -+ if (m_off <= M3_MAX_OFFSET) { -+ m_off -= 1; -+ if (m_len <= 33) { -+ *op++ = (M3_MARKER | (m_len - 2)); -+ } else { -+ m_len -= 33; -+ *op++ = M3_MARKER | 0; -+ goto m3_m4_len; -+ } -+ } else { -+ m_off -= 0x4000; -+ if (m_len <= M4_MAX_LEN) { -+ *op++ = (M4_MARKER -+ | ((m_off & 0x4000) >> 11) -+ | (m_len - 2)); -+ } else { -+ m_len -= M4_MAX_LEN; -+ *op++ = (M4_MARKER -+ | ((m_off & 0x4000) >> 11)); -+m3_m4_len: -+ while (m_len > 255) { -+ m_len -= 255; -+ *op++ = 0; -+ } -+ -+ *op++ = (m_len); -+ } -+ } -+m3_m4_offset: -+ *op++ = ((m_off & 63) << 2); -+ *op++ = (m_off >> 6); -+ } -+ -+ ii = ip; -+ if (unlikely(ip >= ip_end)) -+ break; -+ } -+ -+ *out_len = op - out; -+ return in_end - ii; -+} -+ -+int lzo1x_1_compress(const unsigned char *in, size_t in_len, unsigned char *out, -+ size_t *out_len, void *wrkmem) -+{ -+ const unsigned char *ii; -+ unsigned char *op = out; -+ size_t t; -+ -+ if (unlikely(in_len <= M2_MAX_LEN + 5)) { -+ t = in_len; -+ } else { -+ t = _lzo1x_1_do_compress(in, in_len, op, out_len, wrkmem); -+ op += *out_len; -+ } -+ -+ if (t > 0) { -+ ii = in + in_len - t; -+ -+ if (op == out && t <= 238) { -+ *op++ = (17 + t); -+ } else if (t <= 3) { -+ op[-2] |= t; -+ } else if (t <= 18) { -+ *op++ = (t - 3); -+ } else { -+ size_t tt = t - 18; -+ -+ *op++ = 0; -+ while (tt > 255) { -+ tt -= 255; -+ *op++ = 0; -+ } -+ -+ *op++ = tt; -+ } -+ do { -+ *op++ = *ii++; -+ } while (--t > 0); -+ } -+ -+ *op++ = M4_MARKER | 1; -+ *op++ = 0; -+ *op++ = 0; -+ -+ *out_len = op - out; -+ return LZO_E_OK; -+} -+EXPORT_SYMBOL_GPL(lzo1x_1_compress); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("LZO1X-1 Compressor"); -+ ---- /dev/null -+++ b/sub-projects/compression/lzo-kmod/lzo1x_decompress.c -@@ -0,0 +1,255 @@ -+/* -+ * LZO1X Decompressor from MiniLZO -+ * -+ * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer -+ * -+ * The full LZO package can be found at: -+ * http://www.oberhumer.com/opensource/lzo/ -+ * -+ * Changed for kernel use by: -+ * Nitin Gupta -+ * Richard Purdie -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "lzodefs.h" -+#include "lzo.h" -+ -+#define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x)) -+#define HAVE_OP(x, op_end, op) ((size_t)(op_end - op) < (x)) -+#define HAVE_LB(m_pos, out, op) (m_pos < out || m_pos >= op) -+ -+#define COPY4(dst, src) \ -+ put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst)) -+ -+int lzo1x_decompress_safe(const unsigned char *in, size_t in_len, -+ unsigned char *out, size_t *out_len) -+{ -+ const unsigned char * const ip_end = in + in_len; -+ unsigned char * const op_end = out + *out_len; -+ const unsigned char *ip = in, *m_pos; -+ unsigned char *op = out; -+ size_t t; -+ -+ *out_len = 0; -+ -+ if (*ip > 17) { -+ t = *ip++ - 17; -+ if (t < 4) -+ goto match_next; -+ if (HAVE_OP(t, op_end, op)) -+ goto output_overrun; -+ if (HAVE_IP(t + 1, ip_end, ip)) -+ goto input_overrun; -+ do { -+ *op++ = *ip++; -+ } while (--t > 0); -+ goto first_literal_run; -+ } -+ -+ while ((ip < ip_end)) { -+ t = *ip++; -+ if (t >= 16) -+ goto match; -+ if (t == 0) { -+ if (HAVE_IP(1, ip_end, ip)) -+ goto input_overrun; -+ while (*ip == 0) { -+ t += 255; -+ ip++; -+ if (HAVE_IP(1, ip_end, ip)) -+ goto input_overrun; -+ } -+ t += 15 + *ip++; -+ } -+ if (HAVE_OP(t + 3, op_end, op)) -+ goto output_overrun; -+ if (HAVE_IP(t + 4, ip_end, ip)) -+ goto input_overrun; -+ -+ COPY4(op, ip); -+ op += 4; -+ ip += 4; -+ if (--t > 0) { -+ if (t >= 4) { -+ do { -+ COPY4(op, ip); -+ op += 4; -+ ip += 4; -+ t -= 4; -+ } while (t >= 4); -+ if (t > 0) { -+ do { -+ *op++ = *ip++; -+ } while (--t > 0); -+ } -+ } else { -+ do { -+ *op++ = *ip++; -+ } while (--t > 0); -+ } -+ } -+ -+first_literal_run: -+ t = *ip++; -+ if (t >= 16) -+ goto match; -+ m_pos = op - (1 + M2_MAX_OFFSET); -+ m_pos -= t >> 2; -+ m_pos -= *ip++ << 2; -+ -+ if (HAVE_LB(m_pos, out, op)) -+ goto lookbehind_overrun; -+ -+ if (HAVE_OP(3, op_end, op)) -+ goto output_overrun; -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ *op++ = *m_pos; -+ -+ goto match_done; -+ -+ do { -+match: -+ if (t >= 64) { -+ m_pos = op - 1; -+ m_pos -= (t >> 2) & 7; -+ m_pos -= *ip++ << 3; -+ t = (t >> 5) - 1; -+ if (HAVE_LB(m_pos, out, op)) -+ goto lookbehind_overrun; -+ if (HAVE_OP(t + 3 - 1, op_end, op)) -+ goto output_overrun; -+ goto copy_match; -+ } else if (t >= 32) { -+ t &= 31; -+ if (t == 0) { -+ if (HAVE_IP(1, ip_end, ip)) -+ goto input_overrun; -+ while (*ip == 0) { -+ t += 255; -+ ip++; -+ if (HAVE_IP(1, ip_end, ip)) -+ goto input_overrun; -+ } -+ t += 31 + *ip++; -+ } -+ m_pos = op - 1; -+ m_pos -= le16_to_cpu(get_unaligned( -+ (const unsigned short *)ip)) >> 2; -+ ip += 2; -+ } else if (t >= 16) { -+ m_pos = op; -+ m_pos -= (t & 8) << 11; -+ -+ t &= 7; -+ if (t == 0) { -+ if (HAVE_IP(1, ip_end, ip)) -+ goto input_overrun; -+ while (*ip == 0) { -+ t += 255; -+ ip++; -+ if (HAVE_IP(1, ip_end, ip)) -+ goto input_overrun; -+ } -+ t += 7 + *ip++; -+ } -+ m_pos -= le16_to_cpu(get_unaligned( -+ (const unsigned short *)ip)) >> 2; -+ ip += 2; -+ if (m_pos == op) -+ goto eof_found; -+ m_pos -= 0x4000; -+ } else { -+ m_pos = op - 1; -+ m_pos -= t >> 2; -+ m_pos -= *ip++ << 2; -+ -+ if (HAVE_LB(m_pos, out, op)) -+ goto lookbehind_overrun; -+ if (HAVE_OP(2, op_end, op)) -+ goto output_overrun; -+ -+ *op++ = *m_pos++; -+ *op++ = *m_pos; -+ goto match_done; -+ } -+ -+ if (HAVE_LB(m_pos, out, op)) -+ goto lookbehind_overrun; -+ if (HAVE_OP(t + 3 - 1, op_end, op)) -+ goto output_overrun; -+ -+ if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) { -+ COPY4(op, m_pos); -+ op += 4; -+ m_pos += 4; -+ t -= 4 - (3 - 1); -+ do { -+ COPY4(op, m_pos); -+ op += 4; -+ m_pos += 4; -+ t -= 4; -+ } while (t >= 4); -+ if (t > 0) -+ do { -+ *op++ = *m_pos++; -+ } while (--t > 0); -+ } else { -+copy_match: -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ do { -+ *op++ = *m_pos++; -+ } while (--t > 0); -+ } -+match_done: -+ t = ip[-2] & 3; -+ if (t == 0) -+ break; -+match_next: -+ if (HAVE_OP(t, op_end, op)) -+ goto output_overrun; -+ if (HAVE_IP(t + 1, ip_end, ip)) -+ goto input_overrun; -+ -+ *op++ = *ip++; -+ if (t > 1) { -+ *op++ = *ip++; -+ if (t > 2) -+ *op++ = *ip++; -+ } -+ -+ t = *ip++; -+ } while (ip < ip_end); -+ } -+ -+ *out_len = op - out; -+ return LZO_E_EOF_NOT_FOUND; -+ -+eof_found: -+ *out_len = op - out; -+ return (ip == ip_end ? LZO_E_OK : -+ (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); -+input_overrun: -+ *out_len = op - out; -+ return LZO_E_INPUT_OVERRUN; -+ -+output_overrun: -+ *out_len = op - out; -+ return LZO_E_OUTPUT_OVERRUN; -+ -+lookbehind_overrun: -+ *out_len = op - out; -+ return LZO_E_LOOKBEHIND_OVERRUN; -+} -+ -+EXPORT_SYMBOL_GPL(lzo1x_decompress_safe); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("LZO1X Decompressor"); -+ ---- /dev/null -+++ b/sub-projects/compression/lzo-kmod/lzodefs.h -@@ -0,0 +1,43 @@ -+/* -+ * lzodefs.h -- architecture, OS and compiler specific defines -+ * -+ * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer -+ * -+ * The full LZO package can be found at: -+ * http://www.oberhumer.com/opensource/lzo/ -+ * -+ * Changed for kernel use by: -+ * Nitin Gupta -+ * Richard Purdie -+ */ -+ -+#define LZO_VERSION 0x2020 -+#define LZO_VERSION_STRING "2.02" -+#define LZO_VERSION_DATE "Oct 17 2005" -+ -+#define M1_MAX_OFFSET 0x0400 -+#define M2_MAX_OFFSET 0x0800 -+#define M3_MAX_OFFSET 0x4000 -+#define M4_MAX_OFFSET 0xbfff -+ -+#define M1_MIN_LEN 2 -+#define M1_MAX_LEN 2 -+#define M2_MIN_LEN 3 -+#define M2_MAX_LEN 8 -+#define M3_MIN_LEN 3 -+#define M3_MAX_LEN 33 -+#define M4_MIN_LEN 3 -+#define M4_MAX_LEN 9 -+ -+#define M1_MARKER 0 -+#define M2_MARKER 64 -+#define M3_MARKER 32 -+#define M4_MARKER 16 -+ -+#define D_BITS 14 -+#define D_MASK ((1u << D_BITS) - 1) -+#define D_HIGH ((D_MASK >> 1) + 1) -+ -+#define DX2(p, s1, s2) (((((size_t)((p)[2]) << (s2)) ^ (p)[1]) \ -+ << (s1)) ^ (p)[0]) -+#define DX3(p, s1, s2, s3) ((DX2((p)+1, s2, s3) << (s1)) ^ (p)[0]) ---- /dev/null -+++ b/sub-projects/compression/lzo-kmod/lzo.h -@@ -0,0 +1,44 @@ -+#ifndef __LZO_H__ -+#define __LZO_H__ -+/* -+ * LZO Public Kernel Interface -+ * A mini subset of the LZO real-time data compression library -+ * -+ * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer -+ * -+ * The full LZO package can be found at: -+ * http://www.oberhumer.com/opensource/lzo/ -+ * -+ * Changed for kernel use by: -+ * Nitin Gupta -+ * Richard Purdie -+ */ -+ -+#define LZO1X_MEM_COMPRESS (16384 * sizeof(unsigned char *)) -+#define LZO1X_1_MEM_COMPRESS LZO1X_MEM_COMPRESS -+ -+#define lzo1x_worst_compress(x) ((x) + ((x) / 16) + 64 + 3) -+ -+/* This requires 'workmem' of size LZO1X_1_MEM_COMPRESS */ -+int lzo1x_1_compress(const unsigned char *src, size_t src_len, -+ unsigned char *dst, size_t *dst_len, void *wrkmem); -+ -+/* safe decompression with overrun testing */ -+int lzo1x_decompress_safe(const unsigned char *src, size_t src_len, -+ unsigned char *dst, size_t *dst_len); -+ -+/* -+ * Return values (< 0 = Error) -+ */ -+#define LZO_E_OK 0 -+#define LZO_E_ERROR (-1) -+#define LZO_E_OUT_OF_MEMORY (-2) -+#define LZO_E_NOT_COMPRESSIBLE (-3) -+#define LZO_E_INPUT_OVERRUN (-4) -+#define LZO_E_OUTPUT_OVERRUN (-5) -+#define LZO_E_LOOKBEHIND_OVERRUN (-6) -+#define LZO_E_EOF_NOT_FOUND (-7) -+#define LZO_E_INPUT_NOT_CONSUMED (-8) -+#define LZO_E_NOT_YET_IMPLEMENTED (-9) -+ -+#endif ---- /dev/null -+++ b/sub-projects/compression/lzo-kmod/Makefile -@@ -0,0 +1,8 @@ -+obj-m += lzo1x_compress.o lzo1x_decompress.o -+ -+all: -+ make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules -+ -+clean: -+ make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean -+ diff --git a/extra/compcache/patches/001-lzo-speed.patch b/extra/compcache/patches/001-lzo-speed.patch deleted file mode 100644 index 130f79da6..000000000 --- a/extra/compcache/patches/001-lzo-speed.patch +++ /dev/null @@ -1,181 +0,0 @@ ---- a/sub-projects/compression/lzo-kmod/lzo1x_compress.c -+++ b/sub-projects/compression/lzo-kmod/lzo1x_compress.c -@@ -62,8 +62,12 @@ _lzo1x_1_do_compress(const unsigned char - goto literal; - - try_match: -+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS - if (get_unaligned((const unsigned short *)m_pos) - == get_unaligned((const unsigned short *)ip)) { -+#else -+ if (m_pos[0] == ip[0] && m_pos[1] == ip[1]) { -+#endif - if (likely(m_pos[2] == ip[2])) - goto match; - } -@@ -94,9 +98,14 @@ match: - } - *op++ = tt; - } -- do { -- *op++ = *ii++; -- } while (--t > 0); -+ if (t >= 2 * 4) { -+ memcpy(op, ii, t); -+ op += t; -+ ii += t; -+ } else -+ do { -+ *op++ = *ii++; -+ } while (--t > 0); - } - - ip += 3; -@@ -208,9 +217,14 @@ int lzo1x_1_compress(const unsigned char - - *op++ = tt; - } -- do { -- *op++ = *ii++; -- } while (--t > 0); -+ if (t >= 2 * 4) { -+ memcpy(op, ii, t); -+ op += t; -+ ii += t; -+ } else -+ do { -+ *op++ = *ii++; -+ } while (--t > 0); - } - - *op++ = M4_MARKER | 1; -@@ -224,4 +238,3 @@ EXPORT_SYMBOL_GPL(lzo1x_1_compress); - - MODULE_LICENSE("GPL"); - MODULE_DESCRIPTION("LZO1X-1 Compressor"); -- ---- a/sub-projects/compression/lzo-kmod/lzo1x_decompress.c -+++ b/sub-projects/compression/lzo-kmod/lzo1x_decompress.c -@@ -45,10 +45,7 @@ int lzo1x_decompress_safe(const unsigned - goto output_overrun; - if (HAVE_IP(t + 1, ip_end, ip)) - goto input_overrun; -- do { -- *op++ = *ip++; -- } while (--t > 0); -- goto first_literal_run; -+ goto prep_first_literal_run; - } - - while ((ip < ip_end)) { -@@ -71,30 +68,27 @@ int lzo1x_decompress_safe(const unsigned - if (HAVE_IP(t + 4, ip_end, ip)) - goto input_overrun; - -- COPY4(op, ip); -- op += 4; -- ip += 4; -- if (--t > 0) { -- if (t >= 4) { -- do { -- COPY4(op, ip); -- op += 4; -- ip += 4; -- t -= 4; -- } while (t >= 4); -- if (t > 0) { -- do { -- *op++ = *ip++; -- } while (--t > 0); -- } -- } else { -+ t += (4 - 1); -+ if (t >= 2 * 4) { -+ memcpy(op, ip, t); -+ op += t; -+ ip += t; -+ } else { -+ do { -+ COPY4(op, ip); -+ op += 4; -+ ip += 4; -+ t -= 4; -+ } while (t >= 4); -+ if (t > 0) { -+prep_first_literal_run: - do { - *op++ = *ip++; - } while (--t > 0); - } - } - --first_literal_run: -+//first_literal_run: - t = *ip++; - if (t >= 16) - goto match; -@@ -139,8 +133,7 @@ match: - t += 31 + *ip++; - } - m_pos = op - 1; -- m_pos -= le16_to_cpu(get_unaligned( -- (const unsigned short *)ip)) >> 2; -+ m_pos -= get_unaligned_le16(ip) >> 2; - ip += 2; - } else if (t >= 16) { - m_pos = op; -@@ -158,8 +151,7 @@ match: - } - t += 7 + *ip++; - } -- m_pos -= le16_to_cpu(get_unaligned( -- (const unsigned short *)ip)) >> 2; -+ m_pos -= get_unaligned_le16(ip) >> 2; - ip += 2; - if (m_pos == op) - goto eof_found; -@@ -184,21 +176,33 @@ match: - if (HAVE_OP(t + 3 - 1, op_end, op)) - goto output_overrun; - -- if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) { -- COPY4(op, m_pos); -- op += 4; -- m_pos += 4; -- t -= 4 - (3 - 1); -- do { -+ if (t >= 2 * 4 - (3 - 1)) { -+ /* -+ * Assume memcpy don't copy -+ * more than 32 bytes at once -+ */ -+ if ((op - m_pos) >= 32) { -+ t += (3 - 1); -+ memcpy(op, m_pos, t); -+ op += t; -+ m_pos += t; -+ } else if ((op - m_pos) >= 4) { - COPY4(op, m_pos); - op += 4; - m_pos += 4; -- t -= 4; -- } while (t >= 4); -- if (t > 0) -+ t -= 4 - (3 - 1); - do { -- *op++ = *m_pos++; -- } while (--t > 0); -+ COPY4(op, m_pos); -+ op += 4; -+ m_pos += 4; -+ t -= 4; -+ } while (t >= 4); -+ if (t > 0) -+ do { -+ *op++ = *m_pos++; -+ } while (--t > 0); -+ } else -+ goto copy_match; - } else { - copy_match: - *op++ = *m_pos++; diff --git a/extra/compcache/patches/002-kernel-2.6.34-compat.patch b/extra/compcache/patches/002-kernel-2.6.34-compat.patch deleted file mode 100644 index 5cd8129f8..000000000 --- a/extra/compcache/patches/002-kernel-2.6.34-compat.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/ramzswap_drv.c -+++ b/ramzswap_drv.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/extra/compcache/patches/003-kernel-3.x-compat.patch b/extra/compcache/patches/003-kernel-3.x-compat.patch deleted file mode 100644 index 70996ebe7..000000000 --- a/extra/compcache/patches/003-kernel-3.x-compat.patch +++ /dev/null @@ -1,31 +0,0 @@ -Index: compcache-0.6.2/ramzswap_drv.c -=================================================================== ---- compcache-0.6.2.orig/ramzswap_drv.c 2012-07-25 01:02:39.000000000 +0200 -+++ compcache-0.6.2/ramzswap_drv.c 2012-07-25 01:04:29.270750850 +0200 -@@ -525,7 +525,7 @@ - - if (S_ISBLK(inode->i_mode)) { - bdev = I_BDEV(inode); -- ret = bd_claim(bdev, setup_backing_swap); -+ ret = blkdev_get(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL, setup_backing_swap); - if (ret < 0) { - bdev = NULL; - goto bad_param; -@@ -557,7 +557,7 @@ - - bad_param: - if (bdev) -- bd_release(bdev); -+ blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); - filp_close(swap_file, NULL); - - out: -@@ -1097,7 +1097,7 @@ - /* Close backing swap device, if present */ - if (rzs->backing_swap) { - if (is_backing_blkdev) -- bd_release(rzs->backing_swap); -+ blkdev_put(rzs->backing_swap, FMODE_READ | FMODE_WRITE | FMODE_EXCL); - filp_close(rzs->swap_file, NULL); - rzs->backing_swap = NULL; - memset(rzs->backing_swap_name, 0, MAX_SWAP_NAME_LEN); diff --git a/extra/crda/Makefile b/extra/crda/Makefile deleted file mode 100644 index 0d075f1da..000000000 --- a/extra/crda/Makefile +++ /dev/null @@ -1,74 +0,0 @@ -# -# Copyright (C) 2009-2012 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=crda -PKG_RELEASE:=1 -PKG_VERSION:=1.1.2 -PKG_SOURCE_URL:=http://wireless.kernel.org/download/crda -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 -PKG_MD5SUM:=5226f65aebacf94baaf820f8b4e06df4 - -PKG_REGULATORY_NAME:=regulatory -PKG_REGULATORY_VERSION:=2011.04.28 -PKG_REGULATORY_SOURCE_URL:=http://wireless.kernel.org/download/wireless-regdb/regulatory.bins -PKG_REGULATORY_SOURCE:=$(PKG_REGULATORY_VERSION)-$(PKG_REGULATORY_NAME).bin -PKG_REGULATORY_MD5SUM:=1535e98bcaba732e2f8e8f62dac6f369 - -include $(INCLUDE_DIR)/package.mk - -define Package/crda - SECTION:=net - CATEGORY:=Network - TITLE:=Central Regulatory Domain Agent (CRDA) - DEPENDS:=+libnl-tiny - URL:=http://wireless.kernel.org/en/developers/Regulatory/CRDA -endef - -define Download/wireless-regdb - FILE:=$(PKG_REGULATORY_SOURCE) - URL:=$(PKG_REGULATORY_SOURCE_URL) - VERSION:=$(PKG_REGULATORY_VERSION) - MD5SUM:=$(PKG_REGULATORY_MD5SUM) -endef -$(eval $(call Download,wireless-regdb)) - -define Package/crda/description - This is the Central Regulatory Domain Agent for Linux. It serves one - purpose: tell Linux kernel what to enforce. In essence it is a udev - helper for communication between the kernel and userspace. You only - need to run this manually for debugging purposes. For manual changing - of regulatory domains use iw (iw reg set) or wpa_supplicant (feature - yet to be added). -endef - -TARGET_CPPFLAGS := \ - -I$(STAGING_DIR)/usr/include/libnl-tiny \ - -D_GNU_SOURCE \ - $(TARGET_CPPFLAGS) - -MAKE_FLAGS += \ - NL1FOUND="" NL2FOUND=Y \ - NLLIBNAME="libnl-tiny" \ - NLLIBS="-lnl-tiny -lm" \ - REG_BIN="$(DL_DIR)/$(PKG_REGULATORY_SOURCE)" \ - crda - -define Package/crda/install - $(INSTALL_DIR) $(1)/sbin - $(INSTALL_DIR) $(1)/etc/hotplug.d - $(INSTALL_DIR) $(1)/etc/hotplug.d/platform - $(INSTALL_DIR) $(1)/usr/lib/crda - $(INSTALL_BIN) $(PKG_BUILD_DIR)/crda $(1)/sbin/ - $(INSTALL_DATA) ./files/hotplug.rule $(1)/etc/hotplug.d/platform/10-regulatory - $(INSTALL_DATA) $(DL_DIR)/$(PKG_REGULATORY_SOURCE) $(1)/usr/lib/crda/regulatory.bin -endef - -$(eval $(call BuildPackage,crda)) - diff --git a/extra/crda/files/hotplug.rule b/extra/crda/files/hotplug.rule deleted file mode 100644 index 1ec033f46..000000000 --- a/extra/crda/files/hotplug.rule +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# Copyright (C) 2009 OpenWrt.org - -[ change = "$ACTION" -a regulatory.0 = "$DEVICENAME" ] && { - /sbin/crda -} diff --git a/extra/crda/patches/101-make_crypto_use_optional.patch b/extra/crda/patches/101-make_crypto_use_optional.patch deleted file mode 100644 index c7ace42c8..000000000 --- a/extra/crda/patches/101-make_crypto_use_optional.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/Makefile -+++ b/Makefile -@@ -35,7 +35,9 @@ LDLIBS += `pkg-config --libs openssl` - - reglib.o: keys-ssl.c - --else -+endif -+ -+ifeq ($(USE_GCRYPT),1) - CFLAGS += -DUSE_GCRYPT - LDLIBS += -lgcrypt - diff --git a/extra/goldfish-qemu/Makefile b/extra/goldfish-qemu/Makefile deleted file mode 100644 index 7b02f15c4..000000000 --- a/extra/goldfish-qemu/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (C) 2006-2010 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=goldfish-qemu -PKG_REV:=2b8ea29e2bd12f876a4d06647e6077bf72de567e -PKG_VERSION:=20090429 -PKG_RELEASE:=1 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz -PKG_SOURCE_URL:=git://android.git.kernel.org/platform/external/qemu -PKG_SOURCE_PROTO:=git -PKG_SOURCE_VERSION:=$(PKG_REV) -PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -PKG_TARGETS:=bin - -include $(INCLUDE_DIR)/package.mk - -define Package/goldfish-qemu - SECTION:=emulator - CATEGORY:=Emulators - DEPENDS:=@TARGET_goldfish - TITLE:=A modified version of the Google Android Emulator - URL:=http://www.android.com/ -endef - -LIBSDL_PATCHED:=sdl-1.2.12-android-20080919 - -define Download/libsdl-patched - FILE:=$(LIBSDL_PATCHED).tar.gz - URL:=http://android.git.kernel.org/pub - MD5SUM:=22df8cbb2ecb811938eba8410e861650 -endef -$(eval $(call Download,libsdl-patched)) - -Build/Exports= - -define Build/Prepare - $(call Build/Prepare/Default) - zcat $(DL_DIR)/$(LIBSDL_PATCHED).tar.gz | tar x -C $(PKG_BUILD_DIR) -endef - -define Build/Configure - [ -x $(PKG_BUILD_DIR)/libsdl/bin/sdl-config ] || ( \ - cd $(PKG_BUILD_DIR)/$(LIBSDL_PATCHED); \ - ./android-configure --prefix=$(PKG_BUILD_DIR)/libsdl; \ - make all install; \ - ) -endef - -define Build/Compile - (cd $(PKG_BUILD_DIR); \ - [ -f $(PKG_BUILD_DIR)/objs/config.make ] || \ - ./android-configure.sh --sdl-config=$(PKG_BUILD_DIR)/libsdl/bin/sdl-config \ - ) - $(MAKE) -C $(PKG_BUILD_DIR) -endef - -define Package/goldfish-qemu/install - $(INSTALL_DIR) $(1) - $(CP) $(PKG_BUILD_DIR)/objs/emulator $(1)/ - $(CP) ./skins $(1)/ -endef - -$(eval $(call BuildPackage,goldfish-qemu)) diff --git a/extra/goldfish-qemu/patches/100-darwin_fix.patch b/extra/goldfish-qemu/patches/100-darwin_fix.patch deleted file mode 100644 index a5f56b3cf..000000000 --- a/extra/goldfish-qemu/patches/100-darwin_fix.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/android-configure.sh -+++ b/android-configure.sh -@@ -656,6 +656,9 @@ case "$CPU" in - *) HOST_CPU=$CPU - ;; - esac -+case "$OS" in -+ darwin*) echo "#define _BSD 1" >> $config_h;; -+esac - echo "#define HOST_$HOST_CPU 1" >> $config_h - log "Generate : $config_h" - ---- a/android/utils/display-quartz.m -+++ b/android/utils/display-quartz.m -@@ -34,6 +34,7 @@ get_monitor_resolution( int *px_dpi, in - int - get_nearest_monitor_rect( int *x, int *y, int *width, int *height ) - { -+#if 0 - SDL_SysWMinfo info; - NSWindow* window; - -@@ -108,4 +109,7 @@ get_nearest_monitor_rect( int *x, int - } - return 0; - } -+#else -+ return -1; -+#endif - }; diff --git a/extra/goldfish-qemu/patches/110-single_image.patch b/extra/goldfish-qemu/patches/110-single_image.patch deleted file mode 100644 index 92a9e543d..000000000 --- a/extra/goldfish-qemu/patches/110-single_image.patch +++ /dev/null @@ -1,233 +0,0 @@ ---- a/android/cmdline-option.c -+++ b/android/cmdline-option.c -@@ -50,16 +50,6 @@ android_parse_options( int *pargc, char - char arg2_tab[64], *arg2 = arg2_tab; - int nn; - -- /* process @ as a special exception meaning -- * '-avd ' -- */ -- if (aread[0][0] == '@') { -- opt->avd = aread[0]+1; -- nargs--; -- aread++; -- continue; -- } -- - /* anything that isn't an option past this points - * exits the loop - */ ---- a/android/cmdline-options.h -+++ b/android/cmdline-options.h -@@ -60,21 +60,16 @@ - */ - - CFG_PARAM( sysdir, "", "search for system disk images in " ) --CFG_PARAM( system, "", "read initial system image from " ) --CFG_PARAM( datadir, "", "write user data into " ) --CFG_PARAM( kernel, "", "use specific emulated kernel" ) --CFG_PARAM( ramdisk, "", "ramdisk image (default /ramdisk.img" ) --CFG_PARAM( image, "", "obsolete, use -system instead" ) --CFG_PARAM( init_data, "", "initial data image (default /userdata.img" ) --CFG_PARAM( initdata, "", "same as '-init-data '" ) --CFG_PARAM( data, "", "data image (default /userdata-qemu.img" ) -+CFG_PARAM( system, "", "read system image from , default: /system.img" ) -+CFG_PARAM( data, "", "data image, default: /data.img" ) -+CFG_PARAM( kernel, "", "use specific emulated kernel, default: kernel.bin" ) -+CFG_PARAM( ramdisk, "", "ramdisk image (default /ramdisk.bin" ) - CFG_PARAM( partition_size, "", "system/data partition size in MBs" ) - CFG_PARAM( cache, "", "cache partition image (default is temporary file)" ) - CFG_FLAG ( no_cache, "disable the cache partition" ) - CFG_FLAG ( nocache, "same as -no-cache" ) - OPT_PARAM( sdcard, "", "SD card image (default /sdcard.img") - OPT_FLAG ( wipe_data, "reset the use data image (copy it from initdata)" ) --CFG_PARAM( avd, "", "use a specific android virtual device" ) - CFG_PARAM( skindir, "", "search skins in (default /skins)" ) - CFG_PARAM( skin, "", "select a given skin" ) - CFG_FLAG ( no_skin, "don't use any emulator skin" ) ---- a/android/main.c -+++ b/android/main.c -@@ -1606,6 +1606,7 @@ report_console( const char* proto_port, - * containing 'fileName'. this is *not* the full - * path to 'fileName'. - */ -+ - static char* - _getSdkImagePath( const char* fileName ) - { -@@ -1617,8 +1618,6 @@ _getSdkImagePath( const char* fileName - - static const char* const searchPaths[] = { - "", /* program's directory */ -- "/lib/images", /* this is for SDK 1.0 */ -- "/../platforms/android-1.1/images", /* this is for SDK 1.1 */ - NULL - }; - -@@ -1841,25 +1840,7 @@ int main(int argc, char **argv) - } - } - -- /* legacy support: we used to use -system and -image -- * instead of -sysdir and -system , so handle this by checking -- * whether the options point to directories or files. -- */ -- if (opts->image != NULL) { -- if (opts->system != NULL) { -- if (opts->sysdir != NULL) { -- derror( "You can't use -sysdir, -system and -image at the same time.\n" -- "You should probably use '-sysdir -system '.\n" ); -- exit(2); -- } -- } -- dwarning( "Please note that -image is obsolete and that -system is now used to point\n" -- "to the system image. Next time, try using '-sysdir -system ' instead.\n" ); -- opts->sysdir = opts->system; -- opts->system = opts->image; -- opts->image = NULL; -- } -- else if (opts->system != NULL && path_is_dir(opts->system)) { -+ if (opts->system != NULL && path_is_dir(opts->system)) { - if (opts->sysdir != NULL) { - derror( "Option -system should now be followed by a file path, not a directory one.\n" - "Please use '-sysdir ' to point to the system directory.\n" ); -@@ -1885,49 +1866,11 @@ int main(int argc, char **argv) - if (opts->noskin) - opts->no_skin = opts->noskin; - -- if (opts->initdata) { -- opts->init_data = opts->initdata; -- opts->initdata = NULL; -- } -- -- /* If no AVD name was given, try to find the top of the -- * Android build tree -- */ -- if (opts->avd == NULL) { -- do { -- char* out = getenv("ANDROID_PRODUCT_OUT"); -- -- if (out == NULL || out[0] == 0) -- break; -- -- if (!path_exists(out)) { -- derror("Can't access ANDROID_PRODUCT_OUT as '%s'\n" -- "You need to build the Android system before launching the emulator", -- out); -- exit(2); -- } -- -- android_build_root = path_parent( out, 4 ); -- if (android_build_root == NULL || !path_exists(android_build_root)) { -- derror("Can't find the Android build root from '%s'\n" -- "Please check the definition of the ANDROID_PRODUCT_OUT variable.\n" -- "It should point to your product-specific build output directory.\n", -- out ); -- exit(2); -- } -- android_build_out = out; -- D( "found Android build root: %s", android_build_root ); -- D( "found Android build out: %s", android_build_out ); -- } while (0); -- } - /* if no virtual device name is given, and we're not in the - * Android build system, we'll need to perform some auto-detection - * magic :-) - */ -- if (opts->avd == NULL && !android_build_out) - { -- char dataDirIsSystem = 0; -- - if (!opts->sysdir) { - opts->sysdir = _getSdkImagePath("system.img"); - if (!opts->sysdir) { -@@ -1945,47 +1888,30 @@ int main(int argc, char **argv) - } - - if (!opts->system) { -- opts->system = _getSdkSystemImage(opts->sysdir, "-image", "system.img"); -- D("autoconfig: -image %s", opts->image); -+ opts->system = _getSdkSystemImage(opts->sysdir, "-system", "system.img"); -+ D("autoconfig: -system %s", opts->system); - } - - if (!opts->kernel) { -- opts->kernel = _getSdkSystemImage(opts->sysdir, "-kernel", "kernel-qemu"); -+ opts->kernel = _getSdkSystemImage(opts->sysdir, "-kernel", "kernel.bin"); - D("autoconfig: -kernel %s", opts->kernel); - } - - if (!opts->ramdisk) { -- opts->ramdisk = _getSdkSystemImage(opts->sysdir, "-ramdisk", "ramdisk.img"); -+ opts->ramdisk = _getSdkSystemImage(opts->sysdir, "-ramdisk", "ramdisk.bin"); - D("autoconfig: -ramdisk %s", opts->ramdisk); - } - -- /* if no data directory is specified, use the system directory */ -- if (!opts->datadir) { -- opts->datadir = qemu_strdup(opts->sysdir); -- dataDirIsSystem = 1; -- D("autoconfig: -datadir %s", opts->sysdir); -- } -- - if (!opts->data) { - /* check for userdata-qemu.img in the data directory */ -- bufprint(tmp, tmpend, "%s/userdata-qemu.img", opts->datadir); -- if (!path_exists(tmp)) { -- derror( -- "You did not provide the name of an Android Virtual Device\n" -- "with the '-avd ' option. Read -help-avd for more information.\n\n" -- -- "If you *really* want to *NOT* run an AVD, consider using '-data '\n" -- "to specify a data partition image file (I hope you know what you're doing).\n" -- ); -- exit(2); -- } -+ bufprint(tmp, tmpend, "%s/data.img", opts->sysdir); - - opts->data = qemu_strdup(tmp); - D("autoconfig: -data %s", opts->data); - } - -- if (!opts->sdcard && opts->datadir) { -- bufprint(tmp, tmpend, "%s/sdcard.img", opts->datadir); -+ if (!opts->sdcard && opts->sysdir) { -+ bufprint(tmp, tmpend, "%s/sdcard.img", opts->sysdir); - if (path_exists(tmp)) { - opts->sdcard = qemu_strdup(tmp); - D("autoconfig: -sdcard %s", opts->sdcard); -@@ -2029,19 +1955,6 @@ int main(int argc, char **argv) - android_avdParams->skinName = opts->skin; - android_avdParams->skinRootPath = opts->skindir; - -- /* setup the virtual device differently depending on whether -- * we are in the Android build system or not -- */ -- if (opts->avd != NULL) -- { -- android_avdInfo = avdInfo_new( opts->avd, android_avdParams ); -- if (android_avdInfo == NULL) { -- /* an error message has already been printed */ -- dprint("could not find virtual device named '%s'", opts->avd); -- exit(1); -- } -- } -- else - { - if (!android_build_out) { - android_build_out = android_build_root = opts->sysdir; ---- a/android/avd/info.c -+++ b/android/avd/info.c -@@ -1233,10 +1233,8 @@ _getBuildImagePaths( AvdInfo* i, AvdInf - ** take care of checking the state - **/ - imageLoader_set ( l, AVD_IMAGE_INITSYSTEM ); -- imageLoader_load( l, IMAGE_REQUIRED | IMAGE_DONT_LOCK ); -- -- /* force the system image to read-only status */ -- l->pState[0] = IMAGE_STATE_READONLY; -+ l->pState[0] = IMAGE_STATE_MUSTLOCK; -+ imageLoader_load( l, IMAGE_REQUIRED ); - - /** cache partition handling - **/ diff --git a/extra/goldfish-qemu/skins/HVGA/arrow_down.png b/extra/goldfish-qemu/skins/HVGA/arrow_down.png deleted file mode 100644 index 19b3764e8..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/arrow_down.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/arrow_left.png b/extra/goldfish-qemu/skins/HVGA/arrow_left.png deleted file mode 100644 index 113e58427..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/arrow_left.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/arrow_right.png b/extra/goldfish-qemu/skins/HVGA/arrow_right.png deleted file mode 100644 index ffe3356c0..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/arrow_right.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/arrow_up.png b/extra/goldfish-qemu/skins/HVGA/arrow_up.png deleted file mode 100644 index 81c54df51..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/arrow_up.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/back.png b/extra/goldfish-qemu/skins/HVGA/back.png deleted file mode 100644 index 41034d910..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/back.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/device.png b/extra/goldfish-qemu/skins/HVGA/device.png deleted file mode 100644 index 465eb029d..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/device.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/end.png b/extra/goldfish-qemu/skins/HVGA/end.png deleted file mode 100644 index 6830a603b..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/end.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/home.png b/extra/goldfish-qemu/skins/HVGA/home.png deleted file mode 100644 index 7d021369b..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/home.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/key.png b/extra/goldfish-qemu/skins/HVGA/key.png deleted file mode 100644 index 7a3f563bd..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/key.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/keyboard.png b/extra/goldfish-qemu/skins/HVGA/keyboard.png deleted file mode 100644 index bb076d315..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/keyboard.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/layout b/extra/goldfish-qemu/skins/HVGA/layout deleted file mode 100644 index 4c3d76420..000000000 --- a/extra/goldfish-qemu/skins/HVGA/layout +++ /dev/null @@ -1,380 +0,0 @@ -parts { - device { - background { - image device.png - } - display { - width 320 - height 480 - x 31 - y 72 - } - - buttons { - soft-left { - image menu.png - x 147 - y 555 - } - home { - image home.png - x 48 - y 590 - } - back { - image back.png - x 286 - y 590 - } - dpad-up { - image arrow_up.png - x 140 - y 595 - } - dpad-down { - image arrow_down.png - x 140 - y 656 - } - dpad-left { - image arrow_left.png - x 111 - y 598 - } - dpad-right { - image arrow_right.png - x 222 - y 598 - } - dpad-center { - image select.png - x 142 - y 626 - } - phone-dial { - image send.png - x 48 - y 646 - } - phone-hangup { - image end.png - x 286 - y 646 - } - - power { - image power.png - x -38 - y 52 - } - - volume-up { - image volume_up.png - x 362 - y 260 - } - - volume-down { - image volume_down.png - x 362 - y 310 - } - } - } - - keyboard { - background { - image keyboard.png - } - buttons { - 1 { - image key.png - x 0 - y 0 - } - 2 { - image key.png - x 37 - y 0 - } - 3 { - image key.png - x 74 - y 0 - } - 4 { - image key.png - x 111 - y 0 - } - 5 { - image key.png - x 148 - y 0 - } - 6 { - image key.png - x 185 - y 0 - } - 7 { - image key.png - x 222 - y 0 - } - 8 { - image key.png - x 259 - y 0 - } - 9 { - image key.png - x 296 - y 0 - } - 0 { - image key.png - x 333 - y 0 - } - - q { - image key.png - x 0 - y 36 - } - w { - image key.png - x 37 - y 36 - } - e { - image key.png - x 74 - y 36 - } - r { - image key.png - x 111 - y 36 - } - t { - image key.png - x 148 - y 36 - } - y { - image key.png - x 185 - y 36 - } - u { - image key.png - x 222 - y 36 - } - i { - image key.png - x 259 - y 36 - } - o { - image key.png - x 296 - y 36 - } - p { - image key.png - x 333 - y 36 - } - - a { - image key.png - x 0 - y 72 - } - s { - image key.png - x 37 - y 72 - } - d { - image key.png - x 74 - y 72 - } - f { - image key.png - x 111 - y 72 - } - g { - image key.png - x 148 - y 72 - } - h { - image key.png - x 185 - y 72 - } - j { - image key.png - x 222 - y 72 - } - k { - image key.png - x 259 - y 72 - } - l { - image key.png - x 296 - y 72 - } - DEL { - image key.png - x 333 - y 72 - } - - CAP { - image key.png - x 0 - y 108 - } - z { - image key.png - x 37 - y 108 - } - x { - image key.png - x 74 - y 108 - } - c { - image key.png - x 111 - y 108 - } - v { - image key.png - x 148 - y 108 - } - b { - image key.png - x 185 - y 108 - } - n { - image key.png - x 222 - y 108 - } - m { - image key.png - x 259 - y 108 - } - PERIOD { - image key.png - x 296 - y 108 - } - ENTER { - image key.png - x 333 - y 108 - } - - ALT { - image key.png - x 0 - y 144 - } - SYM { - image key.png - x 37 - y 144 - } - AT { - image key.png - x 74 - y 144 - } - SPACE { - image spacebar.png - x 111 - y 144 - } - SLASH { - image key.png - x 259 - y 144 - } - COMMA { - image key.png - x 296 - y 144 - } - ALT2 { - image key.png - x 333 - y 144 - } - - } - } -} - -layouts { - portrait { - width 900 - height 730 - color 0xe0e0e0 - event EV_SW:0:1 - - part1 { - name device - x 40 - y -18 - } - part2 { - name keyboard - x 480 - y 200 - } - } - - landscape { - width 900 - height 670 - color 0xe0e0e0 - event EV_SW:0:0 - - part1 { - name device - x 50 - y 440 - rotation 3 - } - part2 { - name keyboard - x 250 - y 470 - } - } -} - -keyboard { - charmap qwerty2 -} - -network { - speed full - delay none -} diff --git a/extra/goldfish-qemu/skins/HVGA/menu.png b/extra/goldfish-qemu/skins/HVGA/menu.png deleted file mode 100644 index e81d8abcf..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/menu.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/power.png b/extra/goldfish-qemu/skins/HVGA/power.png deleted file mode 100644 index 5894288f0..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/power.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/select.png b/extra/goldfish-qemu/skins/HVGA/select.png deleted file mode 100644 index 803d49315..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/select.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/send.png b/extra/goldfish-qemu/skins/HVGA/send.png deleted file mode 100644 index f547c8817..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/send.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/spacebar.png b/extra/goldfish-qemu/skins/HVGA/spacebar.png deleted file mode 100644 index 19fe60476..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/spacebar.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/volume_down.png b/extra/goldfish-qemu/skins/HVGA/volume_down.png deleted file mode 100644 index f8a88dec8..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/volume_down.png and /dev/null differ diff --git a/extra/goldfish-qemu/skins/HVGA/volume_up.png b/extra/goldfish-qemu/skins/HVGA/volume_up.png deleted file mode 100644 index 940457f70..000000000 Binary files a/extra/goldfish-qemu/skins/HVGA/volume_up.png and /dev/null differ diff --git a/extra/gpioctl/Makefile b/extra/gpioctl/Makefile deleted file mode 100644 index 50c4d3c65..000000000 --- a/extra/gpioctl/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright (C) 2008 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=gpioctl -PKG_RELEASE:=1 -PKG_VERSION:=1.0 - -include $(INCLUDE_DIR)/package.mk - -define Package/gpioctl - SECTION:=utils - CATEGORY:=Utilities - TITLE:=Tool for controlling gpio pins - DEPENDS:=@GPIO_SUPPORT -endef - -define Package/gpioctl/description - Tool for controlling gpio pins -endef - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) - $(CP) ./src/* $(PKG_BUILD_DIR)/ -endef - -define Build/Compile - $(MAKE) -C $(PKG_BUILD_DIR) \ - $(TARGET_CONFIGURE_OPTS) CFLAGS="$(TARGET_CFLAGS) -I$(LINUX_DIR)/include" -endef - -define Package/gpioctl/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/gpioctl $(1)/usr/bin/ -endef - -$(eval $(call BuildPackage,gpioctl)) diff --git a/extra/gpioctl/src/Makefile b/extra/gpioctl/src/Makefile deleted file mode 100644 index 467697410..000000000 --- a/extra/gpioctl/src/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -PROGS = gpioctl - -INSTDIR = $(prefix)/usr/bin -INSTMODE = 0755 -INSTOWNER = root -INSTGROUP = root - -OBJS = main.o - -all: $(PROGS) -$(PROGS): $(OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@ - $(STRIP) $@ - -%.o: %.c - $(CC) -c $(CFLAGS) $^ -o $@ - -install: $(PROGS) - $(INSTALL) -d $(INSTDIR) - $(INSTALL) -m $(INSTMODE) -o $(INSTOWNER) -g $(INSTGROUP) $(PROGS) $(INSTDIR) - -clean: - rm -f $(PROGS) *.o core - diff --git a/extra/gpioctl/src/main.c b/extra/gpioctl/src/main.c deleted file mode 100644 index 8ad27749b..000000000 --- a/extra/gpioctl/src/main.c +++ /dev/null @@ -1,76 +0,0 @@ -/* -* 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., 59 Temple Place, Suite 330, Boston, MA02111-1307USA -* -* Feedback, Bugs... blogic@openwrt.org -* -*/ - -#include -#include -#include -#include -#include -#include -#include - -void -print_usage() -{ - printf("gpioctl dirin|dirout|get|set|clear gpio\n"); - exit(0); -} - -int -main(int argc, char **argv) -{ - int gpio_pin; - int fd; - int result = 0; - - if (argc != 3) - { - print_usage(); - } - - if ((fd = open("/dev/gpio", O_RDWR)) < 0) - { - printf("Error whilst opening /dev/gpio\n"); - return -1; - } - - gpio_pin = atoi(argv[2]); - - printf("using gpio pin %d\n", gpio_pin); - - if (!strcmp(argv[1], "dirin")) - { - ioctl(fd, GPIO_DIR_IN, gpio_pin); - } else if (!strcmp(argv[1], "dirout")) - { - ioctl(fd, GPIO_DIR_OUT, gpio_pin); - } else if (!strcmp(argv[1], "get")) - { - result = ioctl(fd, GPIO_GET, gpio_pin); - printf("Pin %d is %s\n", gpio_pin, (result ? "HIGH" : "LOW")); - } else if (!strcmp(argv[1], "set")) - { - ioctl(fd, GPIO_SET, gpio_pin); - } else if (!strcmp(argv[1], "clear")) - { - ioctl(fd, GPIO_CLEAR, gpio_pin); - } else print_usage(); - - return result; -} diff --git a/extra/grub/Makefile b/extra/grub/Makefile deleted file mode 100644 index 80b79f29e..000000000 --- a/extra/grub/Makefile +++ /dev/null @@ -1,111 +0,0 @@ -# -# Copyright (C) 2006-2010 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=grub -PKG_VERSION:=0.97 -PKG_RELEASE:=3 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=ftp://alpha.gnu.org/gnu/grub -PKG_MD5SUM:=cd3f3eb54446be6003156158d51f4884 - -PKG_BUILD_DEPENDS:= grub/host -PKG_INSTALL:=1 - -include $(INCLUDE_DIR)/host-build.mk -include $(INCLUDE_DIR)/package.mk - -define Package/grub - SUBMENU:=Boot Loaders - CATEGORY:=Utilities - SECTION:=utils - TITLE:=GRand Unified Bootloader - URL:=http://www.gnu.org/software/grub/ - DEPENDS:=@TARGET_x86 -endef - - -MY_CONFIGURE_ARGS += \ - --disable-auto-linux-mem-opt \ - --disable-hercules \ - --without-curses \ - -MY_CONFIGURE_VARS += \ - grub_cv_prog_objcopy_absolute=yes \ - -CONFIGURE_ARGS += $(MY_CONFIGURE_ARGS) - -CONFIGURE_VARS += $(MY_CONFIGURE_VARS) - -ifeq ($(HOST_OS),Darwin) - HOST_CFLAGS += $(call host-cc-option,-m32) - HOST_CFLAGS += $(call host-cc-option,-fnested-functions) -endif - -ifeq ($(HOST_OS),FreeBSD) - ifeq ($(HOST_ARCH),amd64) - HOST_CFLAGS += $(call host-cc-option,-m32) - HOST_CFLAGS += $(call host-cc-option,-B/usr/lib32) - HOST_CFLAGS += $(call host-cc-option,-L/usr/lib32) - endif -endif - -HOST_CFLAGS += $(call host-cc-option,-fno-stack-protector) -HOST_CFLAGS += $(call host-cc-option,-U_FORTIFY_SOURCE) - -HOST_CONFIGURE_ARGS += $(MY_CONFIGURE_ARGS) \ - --sbindir="$(STAGING_DIR_HOST)/bin" \ - --disable-graphics \ - -HOST_CONFIGURE_VARS += $(MY_CONFIGURE_VARS) - -define Host/Configure - (cd $(HOST_BUILD_DIR); aclocal && autoconf && automake) - $(call Host/Configure/Default) -endef - -ifeq ($(HOST_OS),Darwin) - define Host/Compile - $(MAKE) -C $(HOST_BUILD_DIR)/lib - $(MAKE) -C $(HOST_BUILD_DIR)/stage2 libgrub.a - $(MAKE) -C $(HOST_BUILD_DIR)/grub - endef - define Host/Install - $(MAKE) -C $(HOST_BUILD_DIR)/grub install - endef -endif - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/grub $(1)/usr/lib/ -endef - -define Package/grub/install - $(INSTALL_DIR) $(1)/usr/bin - $(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/ - $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/ - $(INSTALL_DIR) $(1)/usr/sbin - $(CP) $(PKG_INSTALL_DIR)/usr/sbin/* $(1)/usr/sbin/ -endef - -ifeq ($(HOST_ARCH),x86_64) - define Require/working-gcc-m32 - echo 'int main(int argc, char **argv) { return 0; }' | \ - gcc -x c -o $(TMP_DIR)/a.out - -m32 -lc - endef -endif - -$(eval $(call Require,working-gcc-m32, \ - Please install 32 bit development files. (gcc-multilib on Debian/Ubuntu, gcc.i686, libgcc.i686, and glibc-devel.i686 on CentOS/Fedora/RHEL) \ -)) - -$(eval $(call HostBuild)) -$(eval $(call BuildPackage,grub)) diff --git a/extra/grub/patches/002-strip_note_gnu_build_id.patch b/extra/grub/patches/002-strip_note_gnu_build_id.patch deleted file mode 100644 index 40aa74dc7..000000000 --- a/extra/grub/patches/002-strip_note_gnu_build_id.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/stage1/Makefile.in -+++ b/stage1/Makefile.in -@@ -427,7 +427,7 @@ uninstall-am: uninstall-info-am uninstal - uninstall-nodist_pkglibDATA - - .exec: -- $(OBJCOPY) -O binary $< $@ -+ $(OBJCOPY) -O binary -R .comment -R .note -R .note.gnu.build-id $< $@ - # Tell versions [3.59,3.63) of GNU make to not export all variables. - # Otherwise a system limit (for SysV at least) may be exceeded. - .NOEXPORT: ---- a/stage2/Makefile.in -+++ b/stage2/Makefile.in -@@ -3244,7 +3244,7 @@ pxegrub: pxeloader diskless - -rm -f $@ - cat $^ > $@ - .exec: -- $(OBJCOPY) -O binary $< $@ -+ $(OBJCOPY) -O binary -R .comment -R .note -R .note.gnu.build-id $< $@ - # Tell versions [3.59,3.63) of GNU make to not export all variables. - # Otherwise a system limit (for SysV at least) may be exceeded. - .NOEXPORT: diff --git a/extra/grub/patches/010-fixes-1.patch b/extra/grub/patches/010-fixes-1.patch deleted file mode 100644 index 91a9e2190..000000000 --- a/extra/grub/patches/010-fixes-1.patch +++ /dev/null @@ -1,4466 +0,0 @@ -Submitted By: Jim Gifford (jim at linuxfromscratch dot org) -Date: 2006-07-04 -Initial Package Version: 0.97 -Origin: Debian -Upstream Status: Unknown -Description: Contains various fixes and enhancements - Graphics mode support - Fixes for Raid Support - XFS Filesystem Boot Freeze Fixes - Removed 2GB Memory Limitation - Freebsd support - Fixes for initrd support - Grub installation Fixes - Linux 2.6 geometry Fixes - Intel Mac Support - Autoconf and aclocal updates - -http://trac.cross-lfs.org/browser/trunk/patches/grub-0.97-fixes-1.patch - ---- a/aclocal.m4 -+++ b/aclocal.m4 -@@ -1,7 +1,7 @@ --# generated automatically by aclocal 1.9.4 -*- Autoconf -*- -+# generated automatically by aclocal 1.9.6 -*- Autoconf -*- - --# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 --# Free Software Foundation, Inc. -+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -+# 2005 Free Software Foundation, Inc. - # This file is free software; the Free Software Foundation - # gives unlimited permission to copy and/or distribute it, - # with or without modifications, as long as this notice is preserved. -@@ -11,23 +11,11 @@ - # even the implied warranty of MERCHANTABILITY or FITNESS FOR A - # PARTICULAR PURPOSE. - --# -*- Autoconf -*- --# Copyright (C) 2002, 2003 Free Software Foundation, Inc. --# Generated from amversion.in; do not edit by hand. -- --# 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, 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., 59 Temple Place - Suite 330, Boston, MA -+# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - - # AM_AUTOMAKE_VERSION(VERSION) - # ---------------------------- -@@ -40,26 +28,15 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api - # Call AM_AUTOMAKE_VERSION so it can be traced. - # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. - AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -- [AM_AUTOMAKE_VERSION([1.9.4])]) -- --# AM_AUX_DIR_EXPAND -- --# Copyright (C) 2001, 2003 Free Software Foundation, Inc. -+ [AM_AUTOMAKE_VERSION([1.9.6])]) - --# 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, or (at your option) --# any later version. -+# AM_AUX_DIR_EXPAND -*- Autoconf -*- - --# 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - - # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets - # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -@@ -106,26 +83,16 @@ AC_PREREQ([2.50])dnl - am_aux_dir=`cd $ac_aux_dir && pwd` - ]) - --# AM_CONDITIONAL -*- Autoconf -*- -+# AM_CONDITIONAL -*- Autoconf -*- - --# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. -- --# 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, 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 -+# Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - --# serial 6 -+# serial 7 - - # AM_CONDITIONAL(NAME, SHELL-CONDITION) - # ------------------------------------- -@@ -149,26 +116,15 @@ AC_CONFIG_COMMANDS_PRE( - Usually this means the macro was only invoked conditionally.]]) - fi])]) - --# serial 7 -*- Autoconf -*- - --# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 -+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - # Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - --# 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, 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -- -+# serial 8 - - # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be - # written in clear, in which case automake, when reading aclocal.m4, -@@ -177,7 +133,6 @@ fi])]) - # CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -- - # _AM_DEPENDENCIES(NAME) - # ---------------------- - # See how the compiler implements dependency checking. -@@ -317,27 +272,16 @@ AM_CONDITIONAL([AMDEP], [test "x$enable_ - AC_SUBST([AMDEPBACKSLASH]) - ]) - --# Generate code to set up dependency tracking. -*- Autoconf -*- -- --# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 --# Free Software Foundation, Inc. -- --# 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, or (at your option) --# any later version. -+# Generate code to set up dependency tracking. -*- Autoconf -*- - --# 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 -+# Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - --#serial 2 -+#serial 3 - - # _AM_OUTPUT_DEPENDENCY_COMMANDS - # ------------------------------ -@@ -396,30 +340,19 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS] - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) - ]) - --# Do all the work for Automake. -*- Autoconf -*- -+# Do all the work for Automake. -*- Autoconf -*- - --# This macro actually does too much some checks are only needed if --# your package does certain things. But this isn't really a big deal. -- --# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 -+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 - # Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - --# 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, 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -+# serial 12 - --# serial 11 -+# This macro actually does too much. Some checks are only needed if -+# your package does certain things. But this isn't really a big deal. - - # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) - # AM_INIT_AUTOMAKE([OPTIONS]) -@@ -521,51 +454,27 @@ for _am_header in $config_headers :; do - done - echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) - -+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. -+ - # AM_PROG_INSTALL_SH - # ------------------ - # Define $install_sh. -- --# Copyright (C) 2001, 2003 Free Software Foundation, Inc. -- --# 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, 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -- - AC_DEFUN([AM_PROG_INSTALL_SH], - [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl - install_sh=${install_sh-"$am_aux_dir/install-sh"} - AC_SUBST(install_sh)]) - --# -*- Autoconf -*- --# Copyright (C) 2003 Free Software Foundation, Inc. -- --# 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, 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -+# Copyright (C) 2003, 2005 Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - --# serial 1 -+# serial 2 - - # Check whether the underlying file-system supports filenames - # with a leading dot. For instance MS-DOS doesn't. -@@ -580,28 +489,17 @@ fi - rmdir .tst 2>/dev/null - AC_SUBST([am__leading_dot])]) - --# Add --enable-maintainer-mode option to configure. -+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- - # From Jim Meyering - --# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004 -+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 - # Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - --# 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, 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -- --# serial 3 -+# serial 4 - - AC_DEFUN([AM_MAINTAINER_MODE], - [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) -@@ -620,26 +518,15 @@ AC_DEFUN([AM_MAINTAINER_MODE], - - AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) - --# Check to see how 'make' treats includes. -*- Autoconf -*- -- --# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. -+# Check to see how 'make' treats includes. -*- Autoconf -*- - --# 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, 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - --# serial 2 -+# serial 3 - - # AM_MAKE_INCLUDE() - # ----------------- -@@ -683,27 +570,16 @@ AC_MSG_RESULT([$_am_result]) - rm -f confinc confmf - ]) - --# -*- Autoconf -*- -- -- --# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. -- --# 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, or (at your option) --# any later version. -+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - --# 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 -+# Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - --# serial 3 -+# serial 4 - - # AM_MISSING_PROG(NAME, PROGRAM) - # ------------------------------ -@@ -729,27 +605,16 @@ else - fi - ]) - -+# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. -+ - # AM_PROG_MKDIR_P - # --------------- - # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. -- --# Copyright (C) 2003, 2004 Free Software Foundation, Inc. -- --# 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, 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -- -+# - # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories - # created by `make install' are always world readable, even if the - # installer happens to have an overly restrictive umask (e.g. 077). -@@ -803,26 +668,15 @@ else - fi - AC_SUBST([mkdir_p])]) - --# Helper functions for option handling. -*- Autoconf -*- -+# Helper functions for option handling. -*- Autoconf -*- - --# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. -- --# 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, 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - --# serial 2 -+# serial 3 - - # _AM_MANGLE_OPTION(NAME) - # ----------------------- -@@ -847,28 +701,16 @@ AC_DEFUN([_AM_SET_OPTIONS], - AC_DEFUN([_AM_IF_OPTION], - [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - --# --# Check to make sure that the build environment is sane. --# -- --# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. -- --# 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, or (at your option) --# any later version. -+# Check to make sure that the build environment is sane. -*- Autoconf -*- - --# 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 -+# Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - --# serial 3 -+# serial 4 - - # AM_SANITY_CHECK - # --------------- -@@ -911,25 +753,14 @@ Check your system clock]) - fi - AC_MSG_RESULT(yes)]) - --# AM_PROG_INSTALL_STRIP -- --# Copyright (C) 2001, 2003 Free Software Foundation, Inc. -- --# 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, 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - -+# AM_PROG_INSTALL_STRIP -+# --------------------- - # One issue with vendor `install' (even GNU) is that you can't - # specify the program used to strip binaries. This is especially - # annoying in cross-compiling environments, where the build's strip -@@ -952,25 +783,13 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])]) - - # Check how to create a tarball. -*- Autoconf -*- - --# Copyright (C) 2004 Free Software Foundation, Inc. -- --# 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, 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., 59 Temple Place - Suite 330, Boston, MA --# 02111-1307, USA. -- --# serial 1 -+# Copyright (C) 2004, 2005 Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. - -+# serial 2 - - # _AM_PROG_TAR(FORMAT) - # -------------------- ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,3 +1,51 @@ -+2006-05-02 Pavel Roskin -+ -+ * stage2/stage2.c (run_menu): Fix "savedefault" to save only top -+ level menu positions. Remember current position when calling a -+ submenu. Don't recalculate it when booting from a submenu. -+ -+ * grub/main.c (main): Make sure the boot drive number doesn't -+ exceed 255. -+ -+2006-05-02 Vesa Jaaskelainen -+ -+ * stage2/shared.h (vbe_mode): Back ported aligment fix from GRUB 2 -+ to GRUB Legacy. Problem reported by Gerardo Richarte. -+ -+2006-04-23 Robert Millan -+ -+ * grub/asmstub.c (get_diskinfo): Optimize sysctl routine. -+ -+2006-04-20 Robert Millan -+ -+ Fixes for kernel of FreeBSD: -+ * grub/asmstub.c (get_diskinfo): Toggle "kern.geom.debugflags" sysctl -+ before opening a device for writing. -+ * util/grub-install.in: Devices don't have this "r" prefix anymore. -+ -+2006-04-16 Yoshinori K. Okuji -+ -+ * docs/multiboot.texi: Correct the offset of address -+ fields. Reported by Jeroen Dekkers. -+ -+2006-03-21 Yoshinori K. Okuji -+ -+ * stage2/builtins.c (setup_func): Specify the size of DEVICE to -+ grub_strncat instead of a strange number 256. Reported by Vitaly -+ Fertman . -+ -+2005-09-29 Yoshinori K. Okuji -+ -+ * docs/multiboot.texi: Fix a bug in the byte order of -+ boot_device. I hope this won't affect any OS image. -+ Increased the version number to 0.6.94. -+ -+2005-09-28 Yoshinori K. Okuji -+ -+ * stage2/boot.c (load_image): Even if an OS image is an ELF -+ object, use the a.out kludge if MULTIBOOT_AOUT_KLUDGE is -+ specified. -+ - 2005-05-08 Yoshinori K. Okuji - - * configure.ac (AC_INIT): Upgraded to 0.97. ---- a/configure -+++ b/configure -@@ -311,7 +311,7 @@ ac_includes_default="\ - # include - #endif" - --ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar build build_cpu build_vendor build_os host host_cpu host_vendor host_os MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT PERL CC ac_ct_CC CFLAGS LDFLAGS CPPFLAGS EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CCAS RANLIB ac_ct_RANLIB STAGE1_CFLAGS STAGE2_CFLAGS GRUB_CFLAGS OBJCOPY ac_ct_OBJCOPY GRUB_LIBS CPP EGREP NETBOOT_SUPPORT_TRUE NETBOOT_SUPPORT_FALSE DISKLESS_SUPPORT_TRUE DISKLESS_SUPPORT_FALSE HERCULES_SUPPORT_TRUE HERCULES_SUPPORT_FALSE SERIAL_SUPPORT_TRUE SERIAL_SUPPORT_FALSE SERIAL_SPEED_SIMULATION_TRUE SERIAL_SPEED_SIMULATION_FALSE BUILD_EXAMPLE_KERNEL_TRUE BUILD_EXAMPLE_KERNEL_FALSE FSYS_CFLAGS NET_CFLAGS NET_EXTRAFLAGS NETBOOT_DRIVERS CCASFLAGS LIBOBJS LTLIBOBJS' -+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar build build_cpu build_vendor build_os host host_cpu host_vendor host_os MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT PERL CC ac_ct_CC CFLAGS LDFLAGS CPPFLAGS EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CCAS RANLIB ac_ct_RANLIB STAGE1_CFLAGS STAGE2_CFLAGS GRUB_CFLAGS OBJCOPY ac_ct_OBJCOPY GRUB_LIBS CPP EGREP NETBOOT_SUPPORT_TRUE NETBOOT_SUPPORT_FALSE DISKLESS_SUPPORT_TRUE DISKLESS_SUPPORT_FALSE GRAPHICS_SUPPORT_TRUE GRAPHICS_SUPPORT_FALSE HERCULES_SUPPORT_TRUE HERCULES_SUPPORT_FALSE SERIAL_SUPPORT_TRUE SERIAL_SUPPORT_FALSE SERIAL_SPEED_SIMULATION_TRUE SERIAL_SPEED_SIMULATION_FALSE BUILD_EXAMPLE_KERNEL_TRUE BUILD_EXAMPLE_KERNEL_FALSE FSYS_CFLAGS NET_CFLAGS NET_EXTRAFLAGS NETBOOT_DRIVERS CCASFLAGS LIBOBJS LTLIBOBJS' - ac_subst_files='' - - # Initialize some variables set by options. -@@ -914,6 +914,7 @@ Optional Features: - set the default memory location for WD/SMC - --enable-cs-scan=LIST probe for CS89x0 base address using LIST - --enable-diskless enable diskless support -+ --disable-graphics disable graphics terminal support - --disable-hercules disable hercules terminal support - --disable-serial disable serial terminal support - --enable-serial-speed-simulation -@@ -5966,6 +5967,22 @@ else - fi - - -+# Check whether --enable-graphics or --disable-graphics was given. -+if test "${enable_graphics+set}" = set; then -+ enableval="$enable_graphics" -+ -+fi; -+ -+ -+if test "x$enable_graphics" != xno; then -+ GRAPHICS_SUPPORT_TRUE= -+ GRAPHICS_SUPPORT_FALSE='#' -+else -+ GRAPHICS_SUPPORT_TRUE='#' -+ GRAPHICS_SUPPORT_FALSE= -+fi -+ -+ - # Check whether --enable-hercules or --disable-hercules was given. - if test "${enable_hercules+set}" = set; then - enableval="$enable_hercules" -@@ -6270,6 +6287,13 @@ echo "$as_me: error: conditional \"DISKL - Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } - fi -+if test -z "${GRAPHICS_SUPPORT_TRUE}" && test -z "${GRAPHICS_SUPPORT_FALSE}"; then -+ { { echo "$as_me:$LINENO: error: conditional \"GRAPHICS_SUPPORT\" was never defined. -+Usually this means the macro was only invoked conditionally." >&5 -+echo "$as_me: error: conditional \"GRAPHICS_SUPPORT\" was never defined. -+Usually this means the macro was only invoked conditionally." >&2;} -+ { (exit 1); exit 1; }; } -+fi - if test -z "${HERCULES_SUPPORT_TRUE}" && test -z "${HERCULES_SUPPORT_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"HERCULES_SUPPORT\" was never defined. - Usually this means the macro was only invoked conditionally." >&5 -@@ -6907,6 +6931,8 @@ s,@NETBOOT_SUPPORT_TRUE@,$NETBOOT_SUPPOR - s,@NETBOOT_SUPPORT_FALSE@,$NETBOOT_SUPPORT_FALSE,;t t - s,@DISKLESS_SUPPORT_TRUE@,$DISKLESS_SUPPORT_TRUE,;t t - s,@DISKLESS_SUPPORT_FALSE@,$DISKLESS_SUPPORT_FALSE,;t t -+s,@GRAPHICS_SUPPORT_TRUE@,$GRAPHICS_SUPPORT_TRUE,;t t -+s,@GRAPHICS_SUPPORT_FALSE@,$GRAPHICS_SUPPORT_FALSE,;t t - s,@HERCULES_SUPPORT_TRUE@,$HERCULES_SUPPORT_TRUE,;t t - s,@HERCULES_SUPPORT_FALSE@,$HERCULES_SUPPORT_FALSE,;t t - s,@SERIAL_SUPPORT_TRUE@,$SERIAL_SUPPORT_TRUE,;t t ---- a/configure.ac -+++ b/configure.ac -@@ -595,6 +595,11 @@ AC_ARG_ENABLE(diskless, - [ --enable-diskless enable diskless support]) - AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes) - -+dnl Graphical splashscreen support -+AC_ARG_ENABLE(graphics, -+ [ --disable-graphics disable graphics terminal support]) -+AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno) -+ - dnl Hercules terminal - AC_ARG_ENABLE(hercules, - [ --disable-hercules disable hercules terminal support]) ---- a/docs/grub.8 -+++ b/docs/grub.8 -@@ -1,5 +1,5 @@ - .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23. --.TH GRUB "8" "May 2005" "grub (GNU GRUB 0.97)" FSF -+.TH GRUB "8" "September 2005" "grub (GNU GRUB 0.97)" FSF - .SH NAME - grub \- the grub shell - .SH SYNOPSIS ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -2199,6 +2199,7 @@ Commands usable anywhere in the menu and - * rarp:: Initialize a network device via RARP - * serial:: Set up a serial device - * setkey:: Configure the key map -+* splashimage:: Use a splash image - * terminal:: Choose a terminal - * terminfo:: Define escape sequences for a terminal - * tftpserver:: Specify a TFTP server -@@ -2578,6 +2579,16 @@ character each of the symbols correspond - @end deffn - - -+@node splashimage -+@subsection splashimage -+ -+@deffn Command splashimage file -+Select an image to use as the background image. This should be -+specified using normal GRUB device naming syntax. The format of the -+file is a gzipped xpm which is 640x480 with a 14 color palette. -+@end deffn -+ -+ - @node terminal - @subsection terminal - -@@ -2685,6 +2696,7 @@ you forget a command, you can run the co - * module:: Load a module - * modulenounzip:: Load a module without decompression - * pause:: Wait for a key press -+* print:: Print a message - * quit:: Exit from the grub shell - * reboot:: Reboot your computer - * read:: Read data from memory -@@ -3091,6 +3103,16 @@ change floppies. - @end deffn - - -+@node print -+@subsection print -+ -+@deffn Command print message @dots{} -+Print the @var{message}. Note that placing @key{^G} (ASCII code 7) in the -+message will cause the speaker to emit the standard beep sound, which is -+useful for visually impaired people. -+@end deffn -+ -+ - @node quit - @subsection quit - ---- a/docs/multiboot.texi -+++ b/docs/multiboot.texi -@@ -25,7 +25,7 @@ - @ifinfo - Copyright @copyright{} 1995, 96 Bryan Ford - Copyright @copyright{} 1995, 96 Erich Stefan Boleyn --Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -+Copyright @copyright{} 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of - this manual provided the copyright notice and this permission notice -@@ -57,7 +57,7 @@ into another language, under the above c - @vskip 0pt plus 1filll - Copyright @copyright{} 1995, 96 Bryan Ford - Copyright @copyright{} 1995, 96 Erich Stefan Boleyn --Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -+Copyright @copyright{} 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of - this manual provided the copyright notice and this permission notice -@@ -80,7 +80,7 @@ into another language, under the above c - @top Multiboot Specification - - This file documents Multiboot Specification, the proposal for the boot --sequence standard. This edition documents version 0.6.93. -+sequence standard. This edition documents version 0.6.94. - @end ifnottex - - @menu -@@ -426,7 +426,7 @@ mode table (@pxref{Boot information form - kernel. - - If bit 16 in the @samp{flags} word is set, then the fields at offsets --8-24 in the Multiboot header are valid, and the boot loader should use -+12-28 in the Multiboot header are valid, and the boot loader should use - them instead of the fields in the actual executable header to calculate - where to load the OS image. This information does not need to be - provided if the kernel image is in @sc{elf} format, but it @emph{must} -@@ -677,7 +677,7 @@ follows: - @example - @group - +-------+-------+-------+-------+ --| drive | part1 | part2 | part3 | -+| part3 | part2 | part1 | drive | - +-------+-------+-------+-------+ - @end group - @end example -@@ -1199,6 +1199,13 @@ The maintainer changes to the GNU GRUB m - @email{bug-grub@@gnu.org}, from Bryan Ford and Erich Stefan Boleyn. - @end itemize - -+@item -+The byte order of the @samp{boot_device} in Multiboot information is -+reversed. This was a mistake. -+ -+@item -+The offset of the address fields were wrong. -+ - @item 0.6 - @itemize @bullet - @item ---- a/grub/asmstub.c -+++ b/grub/asmstub.c -@@ -42,6 +42,12 @@ int grub_stage2 (void); - #include - #include - #include -+#include -+ -+#include -+#ifndef PAGESIZE -+#define PAGESIZE 4096 -+#endif - - #ifdef __linux__ - # include /* ioctl */ -@@ -55,6 +61,10 @@ int grub_stage2 (void); - # endif /* ! BLKFLSBUF */ - #endif /* __linux__ */ - -+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) -+# include -+#endif -+ - /* We want to prevent any circularararity in our stubs, as well as - libc name clashes. */ - #define WITHOUT_LIBC_STUBS 1 -@@ -144,6 +154,22 @@ grub_stage2 (void) - assert (grub_scratch_mem == 0); - scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15); - assert (scratch); -+ -+ { -+ char *p; -+ int ret; -+ -+ /* Align to a multiple of PAGESIZE, assumed to be a power of two. */ -+ p = (char *) (((long) scratch) & ~(PAGESIZE - 1)); -+ -+ /* The simulated stack needs to be executable, since GCC uses stack -+ * trampolines to implement nested functions. -+ */ -+ ret = mprotect (p, 0x100000 + EXTENDED_MEMSIZE + 15, -+ PROT_READ | PROT_WRITE | PROT_EXEC); -+ assert (ret == 0); -+ } -+ - grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4); - - /* FIXME: simulate the memory holes using mprot, if available. */ -@@ -777,7 +803,39 @@ get_diskinfo (int drive, struct geometry - - /* Open read/write, or read-only if that failed. */ - if (! read_only) -- disks[drive].flags = open (devname, O_RDWR); -+ { -+/* By default, kernel of FreeBSD does not allow overwriting MBR */ -+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) -+#define GEOM_SYSCTL "kern.geom.debugflags" -+ int old_flags, flags; -+ size_t sizeof_int = sizeof (int); -+ -+ if (sysctlbyname (GEOM_SYSCTL, &old_flags, &sizeof_int, NULL, 0) != 0) -+ grub_printf ("failed to get " GEOM_SYSCTL "sysctl: %s\n", strerror (errno)); -+ -+ if ((old_flags & 0x10) == 0) -+ { -+ /* "allow foot shooting", see geom(4) */ -+ flags = old_flags | 0x10; -+ -+ if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &flags, sizeof (int)) != 0) -+ { -+ flags = old_flags; -+ grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno)); -+ } -+ } -+ else -+ flags = old_flags; -+#endif -+ disks[drive].flags = open (devname, O_RDWR); -+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) -+ if (flags != old_flags) -+ { -+ if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &old_flags, sizeof (int)) != 0) -+ grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno)); -+ } -+#endif -+ } - - if (disks[drive].flags == -1) - { ---- a/grub/main.c -+++ b/grub/main.c -@@ -32,6 +32,7 @@ int grub_stage2 (void); - #define WITHOUT_LIBC_STUBS 1 - #include - #include -+#include - - char *program_name = 0; - int use_config_file = 1; -@@ -192,6 +193,12 @@ main (int argc, char **argv) - perror ("strtoul"); - exit (1); - } -+ if (boot_drive >= NUM_DISKS) -+ { -+ fprintf (stderr, "boot_drive should be from 0 to %d\n", -+ NUM_DISKS - 1); -+ exit (1); -+ } - break; - - case OPT_NO_CONFIG_FILE: ---- a/lib/device.c -+++ b/lib/device.c -@@ -131,6 +131,152 @@ get_kfreebsd_version () - #include - #include - -+#if defined(__linux__) -+/* The 2.6 kernel has removed all of the geometry handling for IDE drives -+ * that did fixups for LBA, etc. This means that the geometry we get -+ * with the ioctl has a good chance of being wrong. So, we get to -+ * also know about partition tables and try to read what the geometry -+ * is there. *grumble* Very closely based on code from cfdisk -+ */ -+static void get_kernel_geometry(int fd, long long *cyl, int *heads, int *sectors) { -+ struct hd_geometry hdg; -+ -+ if (ioctl (fd, HDIO_GETGEO, &hdg)) -+ return; -+ -+ *cyl = hdg.cylinders; -+ *heads = hdg.heads; -+ *sectors = hdg.sectors; -+} -+ -+struct partition { -+ unsigned char boot_ind; /* 0x80 - active */ -+ unsigned char head; /* starting head */ -+ unsigned char sector; /* starting sector */ -+ unsigned char cyl; /* starting cylinder */ -+ unsigned char sys_ind; /* What partition type */ -+ unsigned char end_head; /* end head */ -+ unsigned char end_sector; /* end sector */ -+ unsigned char end_cyl; /* end cylinder */ -+ unsigned char start4[4]; /* starting sector counting from 0 */ -+ unsigned char size4[4]; /* nr of sectors in partition */ -+}; -+ -+#define ALIGNMENT 2 -+typedef union { -+ struct { -+ unsigned char align[ALIGNMENT]; -+ unsigned char b[SECTOR_SIZE]; -+ } c; -+ struct { -+ unsigned char align[ALIGNMENT]; -+ unsigned char buffer[0x1BE]; -+ struct partition part[4]; -+ unsigned char magicflag[2]; -+ } p; -+} partition_table; -+ -+#define PART_TABLE_FLAG0 0x55 -+#define PART_TABLE_FLAG1 0xAA -+ -+static void -+get_partition_table_geometry(partition_table *bufp, long long *cyl, int *heads, -+ int *sectors) { -+ struct partition *p; -+ int i,h,s,hh,ss; -+ int first = 1; -+ int bad = 0; -+ -+ if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 || -+ bufp->p.magicflag[1] != PART_TABLE_FLAG1) { -+ /* Matthew Wilcox: slightly friendlier version of -+ fatal(_("Bad signature on partition table"), 3); -+ */ -+ fprintf(stderr, "Unknown partition table signature\n"); -+ return; -+ } -+ -+ hh = ss = 0; -+ for (i=0; i<4; i++) { -+ p = &(bufp->p.part[i]); -+ if (p->sys_ind != 0) { -+ h = p->end_head + 1; -+ s = (p->end_sector & 077); -+ if (first) { -+ hh = h; -+ ss = s; -+ first = 0; -+ } else if (hh != h || ss != s) -+ bad = 1; -+ } -+ } -+ -+ if (!first && !bad) { -+ *heads = hh; -+ *sectors = ss; -+ } -+} -+ -+static long long my_lseek (unsigned int fd, long long offset, -+ unsigned int origin) -+{ -+#if defined(__linux__) && (!defined(__GLIBC__) || \ -+ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))) -+ /* Maybe libc doesn't have large file support. */ -+ loff_t offset, result; -+ static int _llseek (uint filedes, ulong hi, ulong lo, -+ loff_t *res, uint wh); -+ _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo, -+ loff_t *, res, uint, wh); -+ -+ if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET) < 0) -+ return (long long) -1; -+ return result; -+#else -+ return lseek(fd, offset, SEEK_SET); -+#endif -+} -+ -+static void get_linux_geometry (int fd, struct geometry *geom) { -+ long long kern_cyl = 0; int kern_head = 0, kern_sectors = 0; -+ long long pt_cyl = 0; int pt_head = 0, pt_sectors = 0; -+ partition_table bufp; -+ char *buff, *buf_unaligned; -+ -+ buf_unaligned = malloc(sizeof(partition_table) + 4095); -+ buff = (char *) (((unsigned long)buf_unaligned + 4096 - 1) & -+ (~(4096-1))); -+ -+ get_kernel_geometry(fd, &kern_cyl, &kern_head, &kern_sectors); -+ -+ if (my_lseek (fd, 0*SECTOR_SIZE, SEEK_SET) < 0) { -+ fprintf(stderr, "Unable to seek"); -+ } -+ -+ if (read(fd, buff, SECTOR_SIZE) == SECTOR_SIZE) { -+ memcpy(bufp.c.b, buff, SECTOR_SIZE); -+ get_partition_table_geometry(&bufp, &pt_cyl, &pt_head, &pt_sectors); -+ } else { -+ fprintf(stderr, "Unable to read partition table: %s\n", strerror(errno)); -+ } -+ -+ if (pt_head && pt_sectors) { -+ int cyl_size; -+ -+ geom->heads = pt_head; -+ geom->sectors = pt_sectors; -+ cyl_size = pt_head * pt_sectors; -+ geom->cylinders = geom->total_sectors/cyl_size; -+ } else { -+ geom->heads = kern_head; -+ geom->sectors = kern_sectors; -+ geom->cylinders = kern_cyl; -+ } -+ -+ return; -+} -+#endif -+ - /* Get the geometry of a drive DRIVE. */ - void - get_drive_geometry (struct geometry *geom, char **map, int drive) -@@ -151,21 +297,16 @@ get_drive_geometry (struct geometry *geo - #if defined(__linux__) - /* Linux */ - { -- struct hd_geometry hdg; - unsigned long nr; -- -- if (ioctl (fd, HDIO_GETGEO, &hdg)) -- goto fail; - - if (ioctl (fd, BLKGETSIZE, &nr)) - goto fail; - - /* Got the geometry, so save it. */ -- geom->cylinders = hdg.cylinders; -- geom->heads = hdg.heads; -- geom->sectors = hdg.sectors; - geom->total_sectors = nr; -- -+ get_linux_geometry(fd, geom); -+ if (!geom->heads && !geom->cylinders && !geom->sectors) -+ goto fail; - goto success; - } - -@@ -403,6 +544,18 @@ get_dac960_disk_name (char *name, int co - } - - static void -+get_cciss_disk_name (char *name, int controller, int drive) -+{ -+ sprintf (name, "/dev/cciss/c%dd%d", controller, drive); -+} -+ -+static void -+get_ida_disk_name (char *name, int controller, int drive) -+{ -+ sprintf (name, "/dev/ida/c%dd%d", controller, drive); -+} -+ -+static void - get_ataraid_disk_name (char *name, int unit) - { - sprintf (name, "/dev/ataraid/d%c", unit + '0'); -@@ -801,6 +954,74 @@ init_device_map (char ***map, const char - } - } - } -+ -+ /* This is for CCISS, its like the DAC960 - we have -+ /dev/cciss/dp -+ -+ It currently supports up to 3 controllers, 10 logical volumes -+ and 10 partitions -+ -+ Code gratuitously copied from DAC960 above. -+ Horms 23rd July 2004 -+ */ -+ { -+ int controller, drive; -+ -+ for (controller = 0; controller < 2; controller++) -+ { -+ for (drive = 0; drive < 9; drive++) -+ { -+ char name[24]; -+ -+ get_cciss_disk_name (name, controller, drive); -+ if (check_device (name)) -+ { -+ (*map)[num_hd + 0x80] = strdup (name); -+ assert ((*map)[num_hd + 0x80]); -+ -+ /* If the device map file is opened, write the map. */ -+ if (fp) -+ fprintf (fp, "(hd%d)\t%s\n", num_hd, name); -+ -+ num_hd++; -+ } -+ } -+ } -+ } -+ -+ /* This is for Compaq Smart Array, its like the DAC960 - we have -+ /dev/ida/dp -+ -+ It currently supports up to 3 controllers, 10 logical volumes -+ and 15 partitions -+ -+ Code gratuitously copied from DAC960 above. -+ Piotr Roszatycki -+ */ -+ { -+ int controller, drive; -+ -+ for (controller = 0; controller < 2; controller++) -+ { -+ for (drive = 0; drive < 9; drive++) -+ { -+ char name[24]; -+ -+ get_ida_disk_name (name, controller, drive); -+ if (check_device (name)) -+ { -+ (*map)[num_hd + 0x80] = strdup (name); -+ assert ((*map)[num_hd + 0x80]); -+ -+ /* If the device map file is opened, write the map. */ -+ if (fp) -+ fprintf (fp, "(hd%d)\t%s\n", num_hd, name); -+ -+ num_hd++; -+ } -+ } -+ } -+ } - #endif /* __linux__ */ - - /* OK, close the device map file if opened. */ -@@ -844,6 +1065,7 @@ write_to_partition (char **map, int driv - { - char dev[PATH_MAX]; /* XXX */ - int fd; -+ off_t offset = (off_t) sector * (off_t) SECTOR_SIZE; - - if ((partition & 0x00FF00) != 0x00FF00) - { -@@ -861,8 +1083,14 @@ write_to_partition (char **map, int driv - if (strcmp (dev + strlen(dev) - 5, "/disc") == 0) - strcpy (dev + strlen(dev) - 5, "/part"); - } -- sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1); -- -+ sprintf (dev + strlen(dev), "%s%d", -+ /* Compaq smart and others */ -+ (strncmp(dev, "/dev/ida/", 9) == 0 || -+ strncmp(dev, "/dev/ataraid/", 13) == 0 || -+ strncmp(dev, "/dev/cciss/", 11) == 0 || -+ strncmp(dev, "/dev/rd/", 8) == 0) ? "p" : "", -+ ((partition >> 16) & 0xFF) + 1); -+ - /* Open the partition. */ - fd = open (dev, O_RDWR); - if (fd < 0) -@@ -870,35 +1098,13 @@ write_to_partition (char **map, int driv - errnum = ERR_NO_PART; - return 0; - } -- --#if defined(__linux__) && (!defined(__GLIBC__) || \ -- ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))) -- /* Maybe libc doesn't have large file support. */ -- { -- loff_t offset, result; -- static int _llseek (uint filedes, ulong hi, ulong lo, -- loff_t *res, uint wh); -- _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo, -- loff_t *, res, uint, wh); - -- offset = (loff_t) sector * (loff_t) SECTOR_SIZE; -- if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET)) -- { -- errnum = ERR_DEV_VALUES; -- return 0; -- } -- } --#else -- { -- off_t offset = (off_t) sector * (off_t) SECTOR_SIZE; - -- if (lseek (fd, offset, SEEK_SET) != offset) -- { -- errnum = ERR_DEV_VALUES; -- return 0; -- } -- } --#endif -+ if (my_lseek(fd, offset, SEEK_SET) != offset) -+ { -+ errnum = ERR_DEV_VALUES; -+ return 0; -+ } - - if (write (fd, buf, size * SECTOR_SIZE) != (size * SECTOR_SIZE)) - { ---- a/stage2/asm.S -+++ b/stage2/asm.S -@@ -1651,7 +1651,29 @@ ENTRY(gateA20) - jnz 3f - ret - --3: /* use keyboard controller */ -+3: /* -+ * try to switch gateA20 using PORT92, the "Fast A20 and Init" -+ * register -+ */ -+ mov $0x92, %dx -+ inb %dx, %al -+ /* skip the port92 code if it's unimplemented (read returns 0xff) */ -+ cmpb $0xff, %al -+ jz 6f -+ -+ /* set or clear bit1, the ALT_A20_GATE bit */ -+ movb 4(%esp), %ah -+ testb %ah, %ah -+ jz 4f -+ orb $2, %al -+ jmp 5f -+4: and $0xfd, %al -+ -+ /* clear the INIT_NOW bit don't accidently reset the machine */ -+5: and $0xfe, %al -+ outb %al, %dx -+ -+6: /* use keyboard controller */ - pushl %eax - - call gloop1 -@@ -1661,9 +1683,12 @@ ENTRY(gateA20) - - gloopint1: - inb $K_STATUS -+ cmpb $0xff, %al -+ jz gloopint1_done - andb $K_IBUF_FUL, %al - jnz gloopint1 - -+gloopint1_done: - movb $KB_OUTPUT_MASK, %al - cmpb $0, 0x8(%esp) - jz gdoit -@@ -1684,6 +1709,8 @@ gdoit: - - gloop1: - inb $K_STATUS -+ cmpb $0xff, %al -+ jz gloop2ret - andb $K_IBUF_FUL, %al - jnz gloop1 - -@@ -1991,6 +2018,11 @@ ENTRY(ascii_key_map) - ENTRY(console_getkey) - push %ebp - -+wait_for_key: -+ call EXT_C(console_checkkey) -+ incl %eax -+ jz wait_for_key -+ - call EXT_C(prot_to_real) - .code16 - -@@ -2216,7 +2248,304 @@ ENTRY(console_setcursor) - pop %ebx - pop %ebp - ret -- -+ -+ -+/* graphics mode functions */ -+#ifdef SUPPORT_GRAPHICS -+VARIABLE(cursorX) -+.word 0 -+VARIABLE(cursorY) -+.word 0 -+VARIABLE(cursorCount) -+.word 0 -+VARIABLE(cursorBuf) -+.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+ -+ -+/* -+ * set_int1c_handler(void) -+ */ -+ENTRY(set_int1c_handler) -+ pushl %edi -+ -+ /* save the original int1c handler */ -+ movl $0x70, %edi -+ movw (%edi), %ax -+ movw %ax, ABS(int1c_offset) -+ movw 2(%edi), %ax -+ movw %ax, ABS(int1c_segment) -+ -+ /* save the new int1c handler */ -+ movw $ABS(int1c_handler), %ax -+ movw %ax, (%edi) -+ xorw %ax, %ax -+ movw %ax, 2(%edi) -+ -+ popl %edi -+ ret -+ -+ -+/* -+ * unset_int1c_handler(void) -+ */ -+ENTRY(unset_int1c_handler) -+ pushl %edi -+ -+ /* check if int1c_handler is set */ -+ movl $0x70, %edi -+ movw $ABS(int1c_handler), %ax -+ cmpw %ax, (%edi) -+ jne int1c_1 -+ xorw %ax, %ax -+ cmpw %ax, 2(%edi) -+ jne int1c_1 -+ -+ /* restore the original */ -+ movw ABS(int1c_offset), %ax -+ movw %ax, (%edi) -+ movw ABS(int1c_segment), %ax -+ movw %ax, 2(%edi) -+ -+int1c_1: -+ popl %edi -+ ret -+ -+ -+/* -+ * blinks graphics cursor -+ */ -+ .code16 -+write_data: -+ movw $0, %ax -+ movw %ax, %ds -+ -+ mov $0xA000, %ax /* video in es:di */ -+ mov %ax, %es -+ mov $80, %ax -+ movw $ABS(cursorY), %si -+ mov %ds:(%si), %bx -+ mul %bx -+ movw $ABS(cursorX), %si -+ mov %ds:(%si), %bx -+ shr $3, %bx /* %bx /= 8 */ -+ add %bx, %ax -+ mov %ax, %di -+ -+ movw $ABS(cursorBuf), %si /* fontBuf in ds:si */ -+ -+ /* prepare for data moving */ -+ mov $16, %dx /* altura da fonte */ -+ mov $80, %bx /* bytes por linha */ -+ -+write_loop: -+ movb %ds:(%si), %al -+ xorb $0xff, %al -+ movb %al, %ds:(%si) /* invert cursorBuf */ -+ movb %al, %es:(%di) /* write to video */ -+ add %bx, %di -+ inc %si -+ dec %dx -+ jg write_loop -+ ret -+ -+int1c_handler: -+ pusha -+ mov $0, %ax -+ mov %ax, %ds -+ mov $ABS(cursorCount), %si -+ mov %ds:(%si), %ax -+ inc %ax -+ mov %ax, %ds:(%si) -+ cmp $9, %ax -+ jne int1c_done -+ -+ mov $0, %ax -+ mov %ax, %ds:(%si) -+ call write_data -+ -+int1c_done: -+ popa -+ iret -+ /* call previous int1c handler */ -+ /* ljmp */ -+ .byte 0xea -+int1c_offset: .word 0 -+int1c_segment: .word 0 -+ .code32 -+ -+ -+/* -+ * unsigned char set_videomode(unsigned char mode) -+ * BIOS call "INT 10H Function 0h" to set video mode -+ * Call with %ah = 0x0 -+ * %al = video mode -+ * Returns old videomode. -+ */ -+ENTRY(set_videomode) -+ pushl %ebp -+ movl %esp,%ebp -+ pushl %ebx -+ pushl %ecx -+ -+ movb 8(%ebp), %cl -+ -+ call EXT_C(prot_to_real) -+ .code16 -+ -+ xorb %al, %al -+ movb $0xf, %ah -+ int $0x10 /* Get Current Video mode */ -+ movb %al, %ch -+ xorb %ah, %ah -+ movb %cl, %al -+ int $0x10 /* Set Video mode */ -+ -+ DATA32 call EXT_C(real_to_prot) -+ .code32 -+ -+ xorl %eax, %eax -+ movb %ch, %al -+ -+ popl %ecx -+ popl %ebx -+ popl %ebp -+ ret -+ -+ -+/* -+ * int get_videomode() -+ * BIOS call "INT 10H Function 0Fh" to get current video mode -+ * Call with %al = 0x0 -+ * %ah = 0xF -+ * Returns current videomode. -+ */ -+ENTRY(get_videomode) -+ pushl %ebp -+ movl %esp,%ebp -+ pushl %ebx -+ pushl %ecx -+ -+ call EXT_C(prot_to_real) -+ .code16 -+ -+ xorb %al, %al -+ movb $0xF, %ah -+ int $0x10 /* Get Current Video mode */ -+ movb %al, %cl /* For now we only want display mode */ -+ -+ DATA32 call EXT_C(real_to_prot) -+ .code32 -+ -+ xorl %eax, %eax -+ movb %cl, %al -+ -+ popl %ecx -+ popl %ebx -+ popl %ebp -+ ret -+ -+ -+/* -+ * unsigned char * graphics_get_font() -+ * BIOS call "INT 10H Function 11h" to set font -+ * Call with %ah = 0x11 -+ */ -+ENTRY(graphics_get_font) -+ push %ebp -+ push %ebx -+ push %ecx -+ push %edx -+ -+ call EXT_C(prot_to_real) -+ .code16 -+ -+ movw $0x1130, %ax -+ movb $6, %bh /* font 8x16 */ -+ int $0x10 -+ movw %bp, %dx -+ movw %es, %cx -+ -+ DATA32 call EXT_C(real_to_prot) -+ .code32 -+ -+ xorl %eax, %eax -+ movw %cx, %ax -+ shll $4, %eax -+ movw %dx, %ax -+ -+ pop %edx -+ pop %ecx -+ pop %ebx -+ pop %ebp -+ ret -+ -+ -+/* -+ * graphics_set_palette(index, red, green, blue) -+ * BIOS call "INT 10H Function 10h" to set individual dac register -+ * Call with %ah = 0x10 -+ * %bx = register number -+ * %ch = new value for green (0-63) -+ * %cl = new value for blue (0-63) -+ * %dh = new value for red (0-63) -+ */ -+ -+ENTRY(graphics_set_palette) -+ push %ebp -+ push %eax -+ push %ebx -+ push %ecx -+ push %edx -+ -+ movw $0x3c8, %bx /* address write mode register */ -+ -+ /* wait vertical retrace */ -+ movw $0x3da, %dx -+l1b: -+ inb %dx, %al /* wait vertical active display */ -+ test $8, %al -+ jnz l1b -+ -+l2b: -+ inb %dx, %al /* wait vertical retrace */ -+ test $8, %al -+ jnz l2b -+ -+ mov %bx, %dx -+ movb 0x18(%esp), %al /* index */ -+ outb %al, %dx -+ inc %dx -+ -+ movb 0x1c(%esp), %al /* red */ -+ outb %al, %dx -+ -+ movb 0x20(%esp), %al /* green */ -+ outb %al, %dx -+ -+ movb 0x24(%esp), %al /* blue */ -+ outb %al, %dx -+ -+ movw 0x18(%esp), %bx -+ -+ call EXT_C(prot_to_real) -+ .code16 -+ -+ movb %bl, %bh -+ movw $0x1000, %ax -+ int $0x10 -+ -+ DATA32 call EXT_C(real_to_prot) -+ .code32 -+ -+ pop %edx -+ pop %ecx -+ pop %ebx -+ pop %eax -+ pop %ebp -+ ret -+#endif /* SUPPORT_GRAPHICS */ -+ -+ - /* - * getrtsecs() - * if a seconds value can be read, read it and return it (BCD), ---- a/stage2/boot.c -+++ b/stage2/boot.c -@@ -1,7 +1,7 @@ - /* boot.c - load and bootstrap a kernel */ - /* - * GRUB -- GRand Unified Bootloader -- * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. -+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc. - * - * 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 -@@ -29,6 +29,8 @@ static int cur_addr; - entry_func entry_addr; - static struct mod_list mll[99]; - static int linux_mem_size; -+static int elf_kernel_addr; -+static int elf_kernel_size; - - /* - * The next two functions, 'load_image' and 'load_module', are the building -@@ -96,7 +98,7 @@ load_image (char *kernel, char *arg, ker - lh = (struct linux_kernel_header *) buffer; - - /* ELF loading supported if multiboot, FreeBSD and NetBSD. */ -- if ((type == KERNEL_TYPE_MULTIBOOT -+ if (((type == KERNEL_TYPE_MULTIBOOT && ! (flags & MULTIBOOT_AOUT_KLUDGE)) - || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD - || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0 - || suggested_type == KERNEL_TYPE_NETBSD) -@@ -594,6 +596,7 @@ load_image (char *kernel, char *arg, ker - - /* reset this to zero for now */ - cur_addr = 0; -+ elf_kernel_addr = ~0; - - /* scan for program segments */ - for (i = 0; i < pu.elf->e_phnum; i++) -@@ -630,6 +633,8 @@ load_image (char *kernel, char *arg, ker - /* mark memory as used */ - if (cur_addr < memaddr + memsiz) - cur_addr = memaddr + memsiz; -+ if (elf_kernel_addr > cur_addr) -+ elf_kernel_addr = cur_addr; - printf (", <0x%x:0x%x:0x%x>", memaddr, filesiz, - memsiz - filesiz); - /* increment number of segments */ -@@ -647,6 +652,8 @@ load_image (char *kernel, char *arg, ker - } - } - -+ elf_kernel_size = cur_addr - elf_kernel_addr; -+ - if (! errnum) - { - if (! loaded) -@@ -824,8 +831,11 @@ load_initrd (char *initrd) - moveto = (mbi.mem_upper + 0x400) << 10; - - moveto = (moveto - len) & 0xfffff000; -- max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203 -- ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS); -+ max_addr = LINUX_INITRD_MAX_ADDRESS; -+ if (lh->header == LINUX_MAGIC_SIGNATURE && -+ lh->version >= 0x0203 && -+ lh->initrd_addr_max < max_addr) -+ max_addr = lh->initrd_addr_max; - if (moveto + len >= max_addr) - moveto = (max_addr - len) & 0xfffff000; - -@@ -864,6 +874,129 @@ bsd_boot_entry (int flags, int bootdev, - } - #endif - -+#define mem_align4k(p) ((p) + 0xFFF) & 0xFFFFF000 -+ -+static void -+kfreebsd_setenv (char *env, const char *var, const char *value) -+{ -+ while (1) -+ { -+ if (env[0] == '\0' && env[1] == '\0') -+ { -+ env++; -+ break; -+ } -+ else -+ env++; -+ } -+ -+ grub_sprintf (env, "%s=%s", var, value); -+ env[grub_strlen (env) + 1] = '\0'; -+} -+ -+static char * -+kfreebsd_read_hints (char *buf) -+{ -+ char *buf_end = buf; -+ -+ if (grub_open ("/boot/device.hints")) -+ { -+ char *line_start; -+ int line_len = 0; -+ char *envp; -+ int env_len; -+ -+ env_len = grub_read (buf, -1); -+ if (env_len) -+ { -+ buf_end += env_len; -+ *(buf_end++) = '\0'; -+ } -+ else -+ return buf_end; -+ -+ grub_close (); -+ -+ envp = line_start = buf; -+ while (*envp) -+ { -+ char *envp_current = envp; -+ -+ switch (*envp) -+ { -+ case ' ': -+ while (*envp == ' ') -+ { -+ envp++; -+ env_len--; -+ } -+ grub_memmove (envp_current, envp, env_len + 1); -+ envp = envp_current; -+ break; -+ case '#': -+ while (*envp != '\n') -+ { -+ envp++; -+ env_len--; -+ } -+ if (!line_len) -+ envp++; -+ grub_memmove (envp_current, envp, env_len + 1); -+ envp = envp_current; -+ break; -+ case '\n': -+ if (!line_len) -+ { -+ env_len--; -+ grub_memmove (line_start, envp, env_len + 1); -+ } -+ *(envp++) = '\0'; -+ line_len = 0; -+ line_start = envp; -+ default: -+ envp++; -+ line_len++; -+ break; -+ } -+ } -+ -+ buf_end = buf + env_len; -+ *(buf_end++) = '\0'; -+ } -+ -+ return buf_end; -+} -+ -+static u32_t * -+kfreebsd_set_module_string (u32_t type, u32_t *dst, char *src) -+{ -+ int size; -+ -+ *(dst++) = type; -+ *(dst++) = size = grub_strlen (src) + 1; -+ grub_strcpy ((void *) dst, src); -+ -+ return dst + (size + sizeof(u32_t) - 1) / sizeof(u32_t); -+} -+ -+static u32_t * -+kfreebsd_set_module_var (u32_t type, u32_t *dst, u32_t src) -+{ -+ *(dst++) = type; -+ *(dst++) = sizeof(u32_t); -+ *(dst++) = src; -+ -+ return dst; -+} -+ -+static u32_t * -+kfreebsd_set_modules (u32_t *modulep) -+{ -+ /* XXX: Need to copy the whole module structure. */ -+ /* XXX: How to pass the module name ? */ -+ -+ return modulep; -+} - - /* - * All "*_boot" commands depend on the images being loaded into memory -@@ -877,7 +1010,10 @@ void - bsd_boot (kernel_t type, int bootdev, char *arg) - { - char *str; -- int clval = 0, i; -+ char *kernelname; -+ char *bsd_root; -+ int clval = 0; -+ int i; - struct bootinfo bi; - - #ifdef GRUB_UTIL -@@ -886,8 +1022,21 @@ bsd_boot (kernel_t type, int bootdev, ch - stop_floppy (); - #endif - -+ while (*arg != '/') -+ arg++; -+ kernelname = arg; -+ - while (*(++arg) && *arg != ' '); -+ *(arg++) = 0; - str = arg; -+ -+ bsd_root = grub_strstr (str, "root="); -+ if (bsd_root) -+ { -+ bsd_root += 5; -+ /* XXX: should copy the str or terminate it. */ -+ } -+ - while (*str) - { - if (*str == '-') -@@ -910,6 +1059,8 @@ bsd_boot (kernel_t type, int bootdev, ch - clval |= RB_GDB; - if (*str == 'h') - clval |= RB_SERIAL; -+ if (*str == 'p') -+ clval |= RB_PAUSE; - if (*str == 'm') - clval |= RB_MUTE; - if (*str == 'r') -@@ -927,14 +1078,17 @@ bsd_boot (kernel_t type, int bootdev, ch - - if (type == KERNEL_TYPE_FREEBSD) - { -+ char *envp; -+ u32_t *modp; -+ - clval |= RB_BOOTINFO; - - bi.bi_version = BOOTINFO_VERSION; - -- *arg = 0; -- while ((--arg) > (char *) MB_CMDLINE_BUF && *arg != '/'); -- if (*arg == '/') -- bi.bi_kernelname = arg + 1; -+ bi.bi_pad[0] = bi.bi_pad[1] = 0; -+ -+ if (*kernelname == '/') -+ bi.bi_kernelname = kernelname; - else - bi.bi_kernelname = 0; - -@@ -961,6 +1115,30 @@ bsd_boot (kernel_t type, int bootdev, ch - bi.bi_basemem = mbi.mem_lower; - bi.bi_extmem = extended_memory; - -+ /* Setup the environment. */ -+ bi.bi_envp = cur_addr = mem_align4k (cur_addr); -+ grub_memset ((void *) cur_addr, 0, 2); -+ cur_addr = (int) kfreebsd_read_hints ((void *) cur_addr); -+ -+ envp = (char *) bi.bi_envp; -+ kfreebsd_setenv (envp, "kernelname", kernelname); -+ kfreebsd_setenv (envp, "vfs.root.mountfrom", bsd_root); -+ -+ /* Setup the modules list. */ -+ bi.bi_modulep = cur_addr = mem_align4k (cur_addr); -+ modp = (u32_t *) bi.bi_modulep; -+ /* The first module is the kernel. */ -+ modp = kfreebsd_set_module_string (MODINFO_NAME, modp, kernelname); -+ modp = kfreebsd_set_module_string (MODINFO_TYPE, modp, "elf kernel"); -+ modp = kfreebsd_set_module_string (MODINFO_ARGS, modp, arg); -+ modp = kfreebsd_set_module_var (MODINFO_ADDR, modp, elf_kernel_addr); -+ modp = kfreebsd_set_module_var (MODINFO_SIZE, modp, elf_kernel_size); -+ /* Now the real modules. */ -+ modp = kfreebsd_set_modules(modp); -+ -+ /* Set the kernel end. */ -+ bi.bi_kernend = cur_addr = mem_align4k (((int) modp) + 1); -+ - if (mbi.flags & MB_INFO_AOUT_SYMS) - { - bi.bi_symtab = mbi.syms.a.addr; -@@ -970,8 +1148,9 @@ bsd_boot (kernel_t type, int bootdev, ch - #if 0 - else if (mbi.flags & MB_INFO_ELF_SHDR) - { -- /* FIXME: Should check if a symbol table exists and, if exists, -- pass the table to BI. */ -+ bi.bi_symtab = mbi.syms.e.addr; -+ bi.bi_esymtab = mbi.syms.e.addr -+ + mbi.syms.e.size * mbi.syms.e.num * mbi.syms.e.shndx; - } - #endif - else ---- a/stage2/builtins.c -+++ b/stage2/builtins.c -@@ -28,6 +28,10 @@ - #include - #include - -+#ifdef SUPPORT_GRAPHICS -+# include -+#endif -+ - #ifdef SUPPORT_NETBOOT - # define GRUB 1 - # include -@@ -82,6 +86,10 @@ static unsigned short bios_drive_map[DRI - inside other functions. */ - static int configfile_func (char *arg, int flags); - -+static int savedefault_helper (char *arg, int flags); -+ -+static int savedefault_shell (char *arg, int flags); -+ - /* Initialize the data for builtins. */ - void - init_builtins (void) -@@ -237,12 +245,22 @@ static struct builtin builtin_blocklist - static int - boot_func (char *arg, int flags) - { -+ struct term_entry *prev_term = current_term; - /* Clear the int15 handler if we can boot the kernel successfully. - This assumes that the boot code never fails only if KERNEL_TYPE is - not KERNEL_TYPE_NONE. Is this assumption is bad? */ - if (kernel_type != KERNEL_TYPE_NONE) - unset_int15_handler (); - -+ /* if our terminal needed initialization, we should shut it down -+ * before booting the kernel, but we want to save what it was so -+ * we can come back if needed */ -+ if (current_term->shutdown) -+ { -+ current_term->shutdown(); -+ current_term = term_table; /* assumption: console is first */ -+ } -+ - #ifdef SUPPORT_NETBOOT - /* Shut down the networking. */ - cleanup_net (); -@@ -306,6 +324,13 @@ boot_func (char *arg, int flags) - return 1; - } - -+ /* if we get back here, we should go back to what our term was before */ -+ current_term = prev_term; -+ if (current_term->startup) -+ /* if our terminal fails to initialize, fall back to console since -+ * it should always work */ -+ if (current_term->startup() == 0) -+ current_term = term_table; /* we know that console is first */ - return 0; - } - -@@ -852,6 +877,251 @@ static struct builtin builtin_dhcp = - }; - #endif /* SUPPORT_NETBOOT */ - -+#ifdef SUPPORT_GRAPHICS -+ -+static int splashimage_func(char *arg, int flags) { -+ int i; -+ -+ /* filename can only be 256 characters due to our buffer size */ -+ if (grub_strlen(arg) > 256) { -+ grub_printf("Splash image filename too large\n"); -+ grub_printf("Press any key to continue..."); -+ getkey(); -+ return 1; -+ } -+ -+ /* get rid of TERM_NEED_INIT from the graphics terminal. */ -+ for (i = 0; term_table[i].name; i++) { -+ if (grub_strcmp (term_table[i].name, "graphics") == 0) { -+ term_table[i].flags &= ~TERM_NEED_INIT; -+ break; -+ } -+ } -+ -+ graphics_set_splash(arg); -+ -+ if (flags == BUILTIN_CMDLINE && graphics_inited) { -+ graphics_end(); -+ if (graphics_init() == 0) { -+ /* Fallback to default term */ -+ current_term = term_table; -+ max_lines = current_term->max_lines; -+ if (current_term->cls) -+ current_term->cls(); -+ grub_printf("Failed to set splash image and/or graphics mode\n"); -+ return 1; -+ } -+ graphics_cls(); -+ } -+ -+ if (flags == BUILTIN_MENU) -+ current_term = term_table + i; -+ -+ return 0; -+} -+ -+static struct builtin builtin_splashimage = -+{ -+ "splashimage", -+ splashimage_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "splashimage FILE", -+ "Load FILE as the background image when in graphics mode." -+}; -+ -+ -+/* shade */ -+static int -+shade_func(char *arg, int flags) -+{ -+ int new_shade; -+ -+ if (!arg || safe_parse_maxint(&arg, &new_shade) == 0) -+ return (1); -+ -+ if (shade != new_shade) { -+ shade = new_shade; -+ if (flags == BUILTIN_CMDLINE && graphics_inited) { -+ graphics_end(); -+ graphics_init(); -+ graphics_cls(); -+ } -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_shade = -+{ -+ "shade", -+ shade_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "shade INTEGER", -+ "If set to 0, disables the use of shaded text, else enables it." -+}; -+ -+ -+/* foreground */ -+static int -+foreground_func(char *arg, int flags) -+{ -+ if (grub_strlen(arg) == 6) { -+ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; -+ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; -+ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; -+ -+ foreground = (r << 16) | (g << 8) | b; -+ if (graphics_inited) -+ graphics_set_palette(15, r, g, b); -+ -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static struct builtin builtin_foreground = -+{ -+ "foreground", -+ foreground_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "foreground RRGGBB", -+ "Sets the foreground color when in graphics mode." -+ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." -+}; -+ -+ -+/* background */ -+static int -+background_func(char *arg, int flags) -+{ -+ if (grub_strlen(arg) == 6) { -+ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; -+ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; -+ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; -+ -+ background = (r << 16) | (g << 8) | b; -+ if (graphics_inited) -+ graphics_set_palette(0, r, g, b); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static struct builtin builtin_background = -+{ -+ "background", -+ background_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "background RRGGBB", -+ "Sets the background color when in graphics mode." -+ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." -+}; -+ -+ -+/* border */ -+static int -+border_func(char *arg, int flags) -+{ -+ if (grub_strlen(arg) == 6) { -+ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; -+ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; -+ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; -+ -+ window_border = (r << 16) | (g << 8) | b; -+ if (graphics_inited) -+ graphics_set_palette(0x11, r, g, b); -+ -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static struct builtin builtin_border = -+{ -+ "border", -+ border_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "border RRGGBB", -+ "Sets the border video color when in graphics mode." -+ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." -+}; -+ -+ -+/* viewport */ -+static int -+viewport_func (char *arg, int flags) -+{ -+ int i; -+ int x0 = 0, y0 = 0, x1 = 80, y1 = 30; -+ int *pos[4] = { &x0, &y0, &x1, &y1 }; -+ -+ if (!arg) -+ return (1); -+ for (i = 0; i < 4; i++) { -+ if (!*arg) -+ return (1); -+ while (*arg && (*arg == ' ' || *arg == '\t')) -+ ++arg; -+ if (!safe_parse_maxint(&arg, pos[i])) -+ return (1); -+ while (*arg && (*arg != ' ' && *arg != '\t')) -+ ++arg; -+ } -+ -+ /* minimum size is 65 colums and 16 rows */ -+ if (x0 > x1 - 66 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 30) -+ return 1; -+ -+ view_x0 = x0; -+ view_y0 = y0; -+ view_x1 = x1; -+ view_y1 = y1; -+ -+ if (flags == BUILTIN_CMDLINE && graphics_inited) { -+ graphics_end(); -+ graphics_init(); -+ graphics_cls(); -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_viewport = -+{ -+ "viewport", -+ viewport_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "viewport x0 y0 x1 y1", -+ "Changes grub internals to output text in the window defined by" -+ " four parameters. The x and y parameters are 0 based. This option" -+ " only works with the graphics interface." -+}; -+ -+#endif /* SUPPORT_GRAPHICS */ -+ -+ -+/* clear */ -+static int -+clear_func() -+{ -+ if (current_term->cls) -+ current_term->cls(); -+ -+ return 0; -+} -+ -+static struct builtin builtin_clear = -+{ -+ "clear", -+ clear_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "clear", -+ "Clear the screen" -+}; -+ - - /* displayapm */ - static int -@@ -1454,14 +1724,20 @@ static struct builtin builtin_halt = - - - /* help */ --#define MAX_SHORT_DOC_LEN 39 --#define MAX_LONG_DOC_LEN 66 -- - static int - help_func (char *arg, int flags) - { -- int all = 0; -- -+ int all = 0, max_short_doc_len, max_long_doc_len; -+ max_short_doc_len = 39; -+ max_long_doc_len = 66; -+#ifdef SUPPORT_GRAPHICS -+ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) -+ { -+ max_short_doc_len = (view_x1 - view_x0 + 1) / 2 - 1; -+ max_long_doc_len = (view_x1 - view_x0) - 14; -+ } -+#endif -+ - if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0) - { - all = 1; -@@ -1491,13 +1767,13 @@ help_func (char *arg, int flags) - - len = grub_strlen ((*builtin)->short_doc); - /* If the length of SHORT_DOC is too long, truncate it. */ -- if (len > MAX_SHORT_DOC_LEN - 1) -- len = MAX_SHORT_DOC_LEN - 1; -+ if (len > max_short_doc_len - 1) -+ len = max_short_doc_len - 1; - - for (i = 0; i < len; i++) - grub_putchar ((*builtin)->short_doc[i]); - -- for (; i < MAX_SHORT_DOC_LEN; i++) -+ for (; i < max_short_doc_len; i++) - grub_putchar (' '); - - if (! left) -@@ -1546,10 +1822,10 @@ help_func (char *arg, int flags) - int i; - - /* If LEN is too long, fold DOC. */ -- if (len > MAX_LONG_DOC_LEN) -+ if (len > max_long_doc_len) - { - /* Fold this line at the position of a space. */ -- for (len = MAX_LONG_DOC_LEN; len > 0; len--) -+ for (len = max_long_doc_len; len > 0; len--) - if (doc[len - 1] == ' ') - break; - } -@@ -2323,6 +2599,25 @@ static struct builtin builtin_ioprobe = - "Probe I/O ports used for the drive DRIVE." - }; - -+/* print */ -+static int -+print_func (char *arg, int flags) -+{ -+ printf("%s\n", arg); -+ -+ return 0; -+} -+ -+static struct builtin builtin_print = -+{ -+ "print", -+ print_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_NO_ECHO, -+ "print [MESSAGE ...]", -+ "Print MESSAGE." -+}; -+ -+ - - /* kernel */ - static int -@@ -3221,7 +3516,102 @@ static struct builtin builtin_rootnoveri - static int - savedefault_func (char *arg, int flags) - { --#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL) -+#if !defined(SUPPORT_DISKLESS) -+ #if !defined(GRUB_UTIL) -+ savedefault_helper(arg, flags); -+ #else -+ savedefault_shell(arg, flags); -+ #endif -+#else /* !SUPPORT_DISKLESS */ -+ errnum = ERR_UNRECOGNIZED; -+ return 1; -+#endif /* !SUPPORT_DISKLESS */ -+} -+ -+#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL) -+/* savedefault_shell */ -+static int -+savedefault_shell(char *arg, int flags) -+ { -+ int once_only = 0; -+ int new_default; -+ int curr_default = -1; -+ int curr_prev_default = -1; -+ int new_prev_default = -1; -+ FILE *fp; -+ size_t bytes = 10; -+ char line[bytes]; -+ char *default_file = (char *) DEFAULT_FILE_BUF; -+ char buf[bytes]; -+ int i; -+ -+ while (1) -+ { -+ if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0) -+ { -+ char *p = arg + sizeof ("--default=") - 1; -+ if (! safe_parse_maxint (&p, &new_default)) -+ return 1; -+ arg = skip_to (0, arg); -+ } -+ else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0) -+ { -+ once_only = 1; -+ arg = skip_to (0, arg); -+ } -+ else -+ break; -+ } -+ -+ *default_file = 0; -+ grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN); -+ for (i = grub_strlen(default_file); i >= 0; i--) -+ if (default_file[i] == '/') -+ { -+ i++; -+ break; -+ } -+ default_file[i] = 0; -+ grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i); -+ -+ if(!(fp = fopen(default_file,"w"))) -+ { -+ errnum = ERR_READ; -+ goto fail; -+ } -+ -+ read(&line, -1); -+ -+ sscanf(line, "%d:%d", &curr_prev_default, &curr_default); -+ -+ if(curr_default != -1) -+ new_prev_default = curr_default; -+ else -+ { -+ if(curr_prev_default != -1) -+ new_prev_default = curr_prev_default; -+ else -+ new_prev_default = 0; -+ } -+ -+ if(once_only) -+ sprintf(buf, "%d:%d\n", new_prev_default, new_default); -+ else -+ sprintf(buf, "%d\n", new_default); -+ -+ fprintf(fp, buf); -+ -+fail: -+ fclose(fp); -+ return errnum; -+} -+#endif -+ -+/* savedefault_helper */ -+static int -+savedefault_helper (char *arg, int flags) -+{ -+#if !defined(SUPPORT_DISKLESS) - unsigned long tmp_drive = saved_drive; - unsigned long tmp_partition = saved_partition; - char *default_file = (char *) DEFAULT_FILE_BUF; -@@ -3300,19 +3690,23 @@ savedefault_func (char *arg, int flags) - disk_read_hook = 0; - grub_close (); - -- if (len != sizeof (buf)) -- { -- /* This is too small. Do not modify the file manually, please! */ -- errnum = ERR_READ; -- goto fail; -- } -- - if (sector_count > 2) - { - /* Is this possible?! Too fragmented! */ - errnum = ERR_FSYS_CORRUPT; - goto fail; - } -+ -+ char *tmp; -+ if((tmp = grub_strstr(buf, ":")) != NULL) -+ { -+ int f_len = grub_strlen(buf) - grub_strlen(tmp); -+ char *def; -+ int a; -+ for(a = 0; a < f_len; a++) -+ grub_memcpy(&def[a], &buf[a], sizeof(char)); -+ safe_parse_maxint (&def, &entryno); -+ } - - /* Set up a string to be written. */ - grub_memset (buf, '\n', sizeof (buf)); -@@ -3830,15 +4224,15 @@ setup_func (char *arg, int flags) - { - char tmp[16]; - grub_sprintf (tmp, ",%d", (partition >> 16) & 0xFF); -- grub_strncat (device, tmp, 256); -+ grub_strncat (device, tmp, sizeof (device)); - } - if ((partition & 0x00FF00) != 0x00FF00) - { - char tmp[16]; - grub_sprintf (tmp, ",%c", 'a' + ((partition >> 8) & 0xFF)); -- grub_strncat (device, tmp, 256); -+ grub_strncat (device, tmp, sizeof (device)); - } -- grub_strncat (device, ")", 256); -+ grub_strncat (device, ")", sizeof (device)); - } - - int embed_stage1_5 (char *stage1_5, int drive, int partition) -@@ -4085,7 +4479,7 @@ static struct builtin builtin_setup = - }; - - --#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) -+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) - /* terminal */ - static int - terminal_func (char *arg, int flags) -@@ -4244,17 +4638,29 @@ terminal_func (char *arg, int flags) - end: - current_term = term_table + default_term; - current_term->flags = term_flags; -- -+ - if (lines) - max_lines = lines; - else -- /* 24 would be a good default value. */ -- max_lines = 24; -- -+ max_lines = current_term->max_lines; -+ - /* If the interface is currently the command-line, - restart it to repaint the screen. */ -- if (current_term != prev_term && (flags & BUILTIN_CMDLINE)) -+ if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){ -+ if (prev_term->shutdown) -+ prev_term->shutdown(); -+ if (current_term->startup) { -+ /* If startup fails, return to previous term */ -+ if (current_term->startup() == 0) { -+ current_term = prev_term; -+ max_lines = current_term->max_lines; -+ if (current_term->cls) { -+ current_term->cls(); -+ } -+ } -+ } - grub_longjmp (restart_cmdline_env, 0); -+ } - - return 0; - } -@@ -4264,7 +4670,7 @@ static struct builtin builtin_terminal = - "terminal", - terminal_func, - BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -- "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]", -+ "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]", - "Select a terminal. When multiple terminals are specified, wait until" - " you push any key to continue. If both console and serial are specified," - " the terminal to which you input a key first will be selected. If no" -@@ -4276,7 +4682,7 @@ static struct builtin builtin_terminal = - " seconds. The option --lines specifies the maximum number of lines." - " The option --silent is used to suppress messages." - }; --#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ -+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ - - - #ifdef SUPPORT_SERIAL -@@ -4795,13 +5201,20 @@ static struct builtin builtin_vbeprobe = - /* The table of builtin commands. Sorted in dictionary order. */ - struct builtin *builtin_table[] = - { -+#ifdef SUPPORT_GRAPHICS -+ &builtin_background, -+#endif - &builtin_blocklist, - &builtin_boot, - #ifdef SUPPORT_NETBOOT - &builtin_bootp, - #endif /* SUPPORT_NETBOOT */ -+#ifdef SUPPORT_GRAPHICS -+ &builtin_border, -+#endif - &builtin_cat, - &builtin_chainloader, -+ &builtin_clear, - &builtin_cmp, - &builtin_color, - &builtin_configfile, -@@ -4821,6 +5234,9 @@ struct builtin *builtin_table[] = - &builtin_embed, - &builtin_fallback, - &builtin_find, -+#ifdef SUPPORT_GRAPHICS -+ &builtin_foreground, -+#endif - &builtin_fstest, - &builtin_geometry, - &builtin_halt, -@@ -4848,6 +5264,7 @@ struct builtin *builtin_table[] = - &builtin_parttype, - &builtin_password, - &builtin_pause, -+ &builtin_print, - #ifdef GRUB_UTIL - &builtin_quit, - #endif /* GRUB_UTIL */ -@@ -4864,9 +5281,13 @@ struct builtin *builtin_table[] = - #endif /* SUPPORT_SERIAL */ - &builtin_setkey, - &builtin_setup, --#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) -+#ifdef SUPPORT_GRAPHICS -+ &builtin_shade, -+ &builtin_splashimage, -+#endif /* SUPPORT_GRAPHICS */ -+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) - &builtin_terminal, --#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ -+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ - #ifdef SUPPORT_SERIAL - &builtin_terminfo, - #endif /* SUPPORT_SERIAL */ -@@ -4880,5 +5301,8 @@ struct builtin *builtin_table[] = - &builtin_unhide, - &builtin_uppermem, - &builtin_vbeprobe, -+#ifdef SUPPORT_GRAPHICS -+ &builtin_viewport, -+#endif - 0 - }; ---- a/stage2/char_io.c -+++ b/stage2/char_io.c -@@ -29,12 +29,17 @@ - # include - #endif - -+#ifdef SUPPORT_GRAPHICS -+# include -+#endif -+ - #ifndef STAGE1_5 - struct term_entry term_table[] = - { - { - "console", - 0, -+ 24, - console_putchar, - console_checkkey, - console_getkey, -@@ -43,13 +48,16 @@ struct term_entry term_table[] = - console_cls, - console_setcolorstate, - console_setcolor, -- console_setcursor -+ console_setcursor, -+ 0, -+ 0 - }, - #ifdef SUPPORT_SERIAL - { - "serial", - /* A serial device must be initialized. */ - TERM_NEED_INIT, -+ 24, - serial_putchar, - serial_checkkey, - serial_getkey, -@@ -58,6 +66,8 @@ struct term_entry term_table[] = - serial_cls, - serial_setcolorstate, - 0, -+ 0, -+ 0, - 0 - }, - #endif /* SUPPORT_SERIAL */ -@@ -65,6 +75,7 @@ struct term_entry term_table[] = - { - "hercules", - 0, -+ 24, - hercules_putchar, - console_checkkey, - console_getkey, -@@ -73,11 +84,30 @@ struct term_entry term_table[] = - hercules_cls, - hercules_setcolorstate, - hercules_setcolor, -- hercules_setcursor -+ hercules_setcursor, -+ 0, -+ 0 - }, - #endif /* SUPPORT_HERCULES */ -+#ifdef SUPPORT_GRAPHICS -+ { "graphics", -+ TERM_NEED_INIT, /* flags */ -+ 30, /* number of lines */ -+ graphics_putchar, /* putchar */ -+ console_checkkey, /* checkkey */ -+ console_getkey, /* getkey */ -+ graphics_getxy, /* getxy */ -+ graphics_gotoxy, /* gotoxy */ -+ graphics_cls, /* cls */ -+ graphics_setcolorstate, /* setcolorstate */ -+ graphics_setcolor, /* setcolor */ -+ graphics_setcursor, /* nocursor */ -+ graphics_init, /* initialize */ -+ graphics_end /* shutdown */ -+ }, -+#endif /* SUPPORT_GRAPHICS */ - /* This must be the last entry. */ -- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } - }; - - /* This must be console. */ -@@ -305,9 +335,10 @@ real_get_cmdline (char *prompt, char *cm - - /* XXX: These should be defined in shared.h, but I leave these here, - until this code is freezed. */ --#define CMDLINE_WIDTH 78 - #define CMDLINE_MARGIN 10 -- -+ -+ /* command-line limits */ -+ int cmdline_width = 78, col_start = 0; - int xpos, lpos, c, section; - /* The length of PROMPT. */ - int plen; -@@ -338,7 +369,7 @@ real_get_cmdline (char *prompt, char *cm - - /* If the cursor is in the first section, display the first section - instead of the second. */ -- if (section == 1 && plen + lpos < CMDLINE_WIDTH) -+ if (section == 1 && plen + lpos < cmdline_width) - cl_refresh (1, 0); - else if (xpos - count < 1) - cl_refresh (1, 0); -@@ -354,7 +385,7 @@ real_get_cmdline (char *prompt, char *cm - grub_putchar ('\b'); - } - else -- gotoxy (xpos, getxy () & 0xFF); -+ gotoxy (xpos + col_start, getxy () & 0xFF); - } - } - -@@ -364,7 +395,7 @@ real_get_cmdline (char *prompt, char *cm - lpos += count; - - /* If the cursor goes outside, scroll the screen to the right. */ -- if (xpos + count >= CMDLINE_WIDTH) -+ if (xpos + count >= cmdline_width) - cl_refresh (1, 0); - else - { -@@ -383,7 +414,7 @@ real_get_cmdline (char *prompt, char *cm - } - } - else -- gotoxy (xpos, getxy () & 0xFF); -+ gotoxy (xpos + col_start, getxy () & 0xFF); - } - } - -@@ -398,14 +429,14 @@ real_get_cmdline (char *prompt, char *cm - if (full) - { - /* Recompute the section number. */ -- if (lpos + plen < CMDLINE_WIDTH) -+ if (lpos + plen < cmdline_width) - section = 0; - else -- section = ((lpos + plen - CMDLINE_WIDTH) -- / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1); -+ section = ((lpos + plen - cmdline_width) -+ / (cmdline_width - 1 - CMDLINE_MARGIN) + 1); - - /* From the start to the end. */ -- len = CMDLINE_WIDTH; -+ len = cmdline_width; - pos = 0; - grub_putchar ('\r'); - -@@ -445,8 +476,8 @@ real_get_cmdline (char *prompt, char *cm - if (! full) - offset = xpos - 1; - -- start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) -- + CMDLINE_WIDTH - plen - CMDLINE_MARGIN); -+ start = ((section - 1) * (cmdline_width - 1 - CMDLINE_MARGIN) -+ + cmdline_width - plen - CMDLINE_MARGIN); - xpos = lpos + 1 - start; - start += offset; - } -@@ -471,7 +502,7 @@ real_get_cmdline (char *prompt, char *cm - - /* If the cursor is at the last position, put `>' or a space, - depending on if there are more characters in BUF. */ -- if (pos == CMDLINE_WIDTH) -+ if (pos == cmdline_width) - { - if (start + len < llen) - grub_putchar ('>'); -@@ -488,7 +519,7 @@ real_get_cmdline (char *prompt, char *cm - grub_putchar ('\b'); - } - else -- gotoxy (xpos, getxy () & 0xFF); -+ gotoxy (xpos + col_start, getxy () & 0xFF); - } - - /* Initialize the command-line. */ -@@ -518,10 +549,10 @@ real_get_cmdline (char *prompt, char *cm - - llen += l; - lpos += l; -- if (xpos + l >= CMDLINE_WIDTH) -+ if (xpos + l >= cmdline_width) - cl_refresh (1, 0); -- else if (xpos + l + llen - lpos > CMDLINE_WIDTH) -- cl_refresh (0, CMDLINE_WIDTH - xpos); -+ else if (xpos + l + llen - lpos > cmdline_width) -+ cl_refresh (0, cmdline_width - xpos); - else - cl_refresh (0, l + llen - lpos); - } -@@ -533,12 +564,22 @@ real_get_cmdline (char *prompt, char *cm - grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1); - llen -= count; - -- if (xpos + llen + count - lpos > CMDLINE_WIDTH) -- cl_refresh (0, CMDLINE_WIDTH - xpos); -+ if (xpos + llen + count - lpos > cmdline_width) -+ cl_refresh (0, cmdline_width - xpos); - else - cl_refresh (0, llen + count - lpos); - } - -+ max_lines = current_term->max_lines; -+#ifdef SUPPORT_GRAPHICS -+ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) -+ { -+ cmdline_width = (view_x1 - view_x0) - 2; -+ col_start = view_x0; -+ max_lines = view_y1 - view_y0; -+ } -+#endif -+ - plen = grub_strlen (prompt); - llen = grub_strlen (cmdline); - -@@ -1006,6 +1047,48 @@ checkkey (void) - } - #endif /* ! STAGE1_5 */ - -+#ifndef STAGE1_5 -+/* Internal pager. */ -+int -+do_more (void) -+{ -+ if (count_lines >= 0) -+ { -+ count_lines++; -+ if (count_lines >= max_lines - 2) -+ { -+ int tmp; -+ -+ /* It's important to disable the feature temporarily, because -+ the following grub_printf call will print newlines. */ -+ count_lines = -1; -+ -+ grub_printf("\n"); -+ if (current_term->setcolorstate) -+ current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); -+ -+ grub_printf ("[Hit return to continue]"); -+ -+ if (current_term->setcolorstate) -+ current_term->setcolorstate (COLOR_STATE_NORMAL); -+ -+ -+ do -+ { -+ tmp = ASCII_CHAR (getkey ()); -+ } -+ while (tmp != '\n' && tmp != '\r'); -+ grub_printf ("\r \r"); -+ -+ /* Restart to count lines. */ -+ count_lines = 0; -+ return 1; -+ } -+ } -+ return 0; -+} -+#endif -+ - /* Display an ASCII character. */ - void - grub_putchar (int c) -@@ -1034,38 +1117,11 @@ grub_putchar (int c) - - if (c == '\n') - { -+ int flag; - /* Internal `more'-like feature. */ -- if (count_lines >= 0) -- { -- count_lines++; -- if (count_lines >= max_lines - 2) -- { -- int tmp; -- -- /* It's important to disable the feature temporarily, because -- the following grub_printf call will print newlines. */ -- count_lines = -1; -- -- if (current_term->setcolorstate) -- current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); -- -- grub_printf ("\n[Hit return to continue]"); -- -- if (current_term->setcolorstate) -- current_term->setcolorstate (COLOR_STATE_NORMAL); -- -- do -- { -- tmp = ASCII_CHAR (getkey ()); -- } -- while (tmp != '\n' && tmp != '\r'); -- grub_printf ("\r \r"); -- -- /* Restart to count lines. */ -- count_lines = 0; -- return; -- } -- } -+ flag = do_more (); -+ if (flag) -+ return; - } - - current_term->putchar (c); -@@ -1090,7 +1146,7 @@ void - cls (void) - { - /* If the terminal is dumb, there is no way to clean the terminal. */ -- if (current_term->flags & TERM_DUMB) -+ if (current_term->flags & TERM_DUMB) - grub_putchar ('\n'); - else - current_term->cls (); -@@ -1175,13 +1231,13 @@ grub_strlen (const char *str) - #endif /* ! STAGE1_5 */ - - int --memcheck (int addr, int len) -+memcheck (unsigned long int addr, unsigned long int len) - { - #ifdef GRUB_UTIL -- auto int start_addr (void); -- auto int end_addr (void); -+ auto unsigned long int start_addr (void); -+ auto int unsigned long end_addr (void); - -- auto int start_addr (void) -+ auto unsigned long int start_addr (void) - { - int ret; - # if defined(HAVE_START_SYMBOL) -@@ -1192,7 +1248,7 @@ memcheck (int addr, int len) - return ret; - } - -- auto int end_addr (void) -+ auto unsigned long int end_addr (void) - { - int ret; - # if defined(HAVE_END_SYMBOL) -@@ -1217,6 +1273,16 @@ memcheck (int addr, int len) - return ! errnum; - } - -+void -+grub_memcpy(void *dest, const void *src, int len) -+{ -+ int i; -+ register char *d = (char*)dest, *s = (char*)src; -+ -+ for (i = 0; i < len; i++) -+ d[i] = s[i]; -+} -+ - void * - grub_memmove (void *to, const void *from, int len) - { ---- a/stage2/cmdline.c -+++ b/stage2/cmdline.c -@@ -50,10 +50,11 @@ skip_to (int after_equal, char *cmdline) - void - print_cmdline_message (int forever) - { -- printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB\n" -- " lists possible command completions. Anywhere else TAB lists the possible\n" -- " completions of a device/filename.%s ]\n", -- (forever ? "" : " ESC at any time exits.")); -+ grub_printf(" [ Minimal BASH-like line editing is supported. For\n" -+ " the first word, TAB lists possible command\n" -+ " completions. Anywhere else TAB lists the possible\n" -+ " completions of a device/filename.%s ]\n", -+ (forever ? "" : " ESC at any time\n exits.")); - } - - /* Find the builtin whose command name is COMMAND and return the ---- a/stage2/freebsd.h -+++ b/stage2/freebsd.h -@@ -1,7 +1,7 @@ - - /* - * GRUB -- GRand Unified Bootloader -- * Copyright (C) 2001 Free Software Foundation, Inc. -+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc. - * - * 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 -@@ -35,6 +35,10 @@ - #define RB_CDROM 0x2000 /* use cdrom as root */ - #define RB_GDB 0x8000 /* use GDB remote debugger instead of DDB */ - #define RB_MUTE 0x10000 /* Come up with the console muted */ -+#define RB_SELFTEST 0x20000 /* don't complete the boot; do selftest */ -+#define RB_RESERVED1 0x40000 /* reserved for internal use of boot blocks */ -+#define RB_RESERVED2 0x80000 /* reserved for internal use of boot blocks */ -+#define RB_PAUSE 0x100000 /* pause after each output line during probe */ - #define RB_MULTIPLE 0x20000000 /* Use multiple consoles */ - - #define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */ -@@ -70,6 +74,9 @@ - - #define N_BIOS_GEOM 8 - -+typedef unsigned char u8_t; -+typedef unsigned int u32_t; -+ - /* - * A zero bootinfo field often means that there is no info available. - * Flags are used to indicate the validity of fields where zero is a -@@ -77,19 +84,33 @@ - */ - struct bootinfo - { -- unsigned int bi_version; -- unsigned char *bi_kernelname; -- struct nfs_diskless *bi_nfs_diskless; -+ u32_t bi_version; -+ u8_t *bi_kernelname; -+ u32_t bi_nfs_diskless; - /* End of fields that are always present. */ - #define bi_endcommon bi_n_bios_used -- unsigned int bi_n_bios_used; -- unsigned long bi_bios_geom[N_BIOS_GEOM]; -- unsigned int bi_size; -- unsigned char bi_memsizes_valid; -- unsigned char bi_bios_dev; -- unsigned char bi_pad[2]; -- unsigned long bi_basemem; -- unsigned long bi_extmem; -- unsigned long bi_symtab; -- unsigned long bi_esymtab; -+ u32_t bi_n_bios_used; -+ u32_t bi_bios_geom[N_BIOS_GEOM]; -+ u32_t bi_size; -+ u8_t bi_memsizes_valid; -+ u8_t bi_bios_dev; -+ u8_t bi_pad[2]; -+ u32_t bi_basemem; -+ u32_t bi_extmem; -+ u32_t bi_symtab; -+ u32_t bi_esymtab; -+ /* Items below only from advanced bootloader */ -+ u32_t bi_kernend; -+ u32_t bi_envp; -+ u32_t bi_modulep; - }; -+ -+#define MODINFO_END 0x0000 /* End of list */ -+#define MODINFO_NAME 0x0001 /* Name of module (string) */ -+#define MODINFO_TYPE 0x0002 /* Type of module (string) */ -+#define MODINFO_ADDR 0x0003 /* Loaded address */ -+#define MODINFO_SIZE 0x0004 /* Size of module */ -+#define MODINFO_EMPTY 0x0005 /* Has been deleted */ -+#define MODINFO_ARGS 0x0006 /* Parameters string */ -+#define MODINFO_METADATA 0x8000 /* Module-specfic */ -+ ---- /dev/null -+++ b/stage2/graphics.c -@@ -0,0 +1,585 @@ -+/* -+ * graphics.c - graphics mode support for GRUB -+ * Implemented as a terminal type by Jeremy Katz based -+ * on a patch by Paulo César Pereira de Andrade -+ * Options and enhancements made by Herton Ronaldo Krzesinski -+ * -+ * -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2001,2002 Red Hat, Inc. -+ * Portions copyright (C) 2000 Conectiva, Inc. -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#ifdef SUPPORT_GRAPHICS -+ -+#include -+#include -+#include -+ -+int saved_videomode; -+unsigned char *font8x16; -+ -+int graphics_inited = 0; -+static char splashimage[256]; -+ -+int shade = 1, no_cursor = 0; -+ -+#define VSHADOW VSHADOW1 -+unsigned char VSHADOW1[38400]; -+unsigned char VSHADOW2[38400]; -+unsigned char VSHADOW4[38400]; -+unsigned char VSHADOW8[38400]; -+ -+/* define the default viewable area */ -+int view_x0 = 0; -+int view_y0 = 0; -+int view_x1 = 80; -+int view_y1 = 30; -+ -+/* text buffer has to be kept around so that we can write things as we -+ * scroll and the like */ -+unsigned short text[80 * 30]; -+ -+/* graphics options */ -+int foreground = (63 << 16) | (63 << 8) | (63), background = 0, window_border = 0; -+ -+/* current position */ -+static int fontx = 0; -+static int fonty = 0; -+ -+/* global state so that we don't try to recursively scroll or cursor */ -+static int no_scroll = 0; -+ -+/* color state */ -+static int graphics_standard_color = A_NORMAL; -+static int graphics_normal_color = A_NORMAL; -+static int graphics_highlight_color = A_REVERSE; -+static int graphics_current_color = A_NORMAL; -+static color_state graphics_color_state = COLOR_STATE_STANDARD; -+ -+static inline void outb(unsigned short port, unsigned char val) -+{ -+ __asm __volatile ("outb %0,%1"::"a" (val), "d" (port)); -+} -+ -+static void MapMask(int value) { -+ outb(0x3c4, 2); -+ outb(0x3c5, value); -+} -+ -+/* bit mask register */ -+static void BitMask(int value) { -+ outb(0x3ce, 8); -+ outb(0x3cf, value); -+} -+ -+/* move the graphics cursor location to col, row */ -+static void graphics_setxy(int col, int row) { -+ if (col >= view_x0 && col < view_x1) { -+ fontx = col; -+ cursorX = col << 3; -+ } -+ if (row >= view_y0 && row < view_y1) { -+ fonty = row; -+ cursorY = row << 4; -+ } -+} -+ -+/* scroll the screen */ -+static void graphics_scroll() { -+ int i, j, k; -+ -+ /* we don't want to scroll recursively... that would be bad */ -+ if (no_scroll) -+ return; -+ no_scroll = 1; -+ -+ /* disable pager temporarily */ -+ k = count_lines; -+ count_lines = -1; -+ -+ /* move everything up a line */ -+ for (j = view_y0 + 1; j < view_y1; j++) { -+ graphics_gotoxy(view_x0, j - 1); -+ for (i = view_x0; i < view_x1; i++) { -+ graphics_putchar(text[j * 80 + i]); -+ } -+ } -+ -+ /* last line should be blank */ -+ graphics_gotoxy(view_x0, view_y1 - 1); -+ for (i = view_x0; i < view_x1; i++) -+ graphics_putchar(' '); -+ graphics_setxy(view_x0, view_y1 - 1); -+ -+ count_lines = k; -+ -+ no_scroll = 0; -+} -+ -+/* Set the splash image */ -+void graphics_set_splash(char *splashfile) { -+ grub_strcpy(splashimage, splashfile); -+} -+ -+/* Get the current splash image */ -+char *graphics_get_splash(void) { -+ return splashimage; -+} -+ -+/* -+ * Initialize a vga16 graphics display with the palette based off of -+ * the image in splashimage. If the image doesn't exist, leave graphics -+ * mode. The mode initiated is 12h. From "Ralf Brown's Interrupt List": -+ * text/ text pixel pixel colors disply scrn system -+ * grph resol box resolution pages addr -+ * 12h G 80x30 8x16 640x480 16/256K . A000 VGA,ATI VIP -+ * G 80x30 8x16 640x480 16/64 . A000 ATI EGA Wonder -+ * G . . 640x480 16 . . UltraVision+256K EGA -+ */ -+int graphics_init() -+{ -+ if (!graphics_inited) { -+ saved_videomode = set_videomode(0x12); -+ if (get_videomode() != 0x12) { -+ set_videomode(saved_videomode); -+ return 0; -+ } -+ graphics_inited = 1; -+ } -+ else -+ return 1; -+ -+ font8x16 = (unsigned char*)graphics_get_font(); -+ -+ /* make sure that the highlight color is set correctly */ -+ graphics_highlight_color = ((graphics_normal_color >> 4) | -+ ((graphics_normal_color & 0xf) << 4)); -+ -+ graphics_cls(); -+ -+ if (!read_image(splashimage)) { -+ grub_printf("Failed to read splash image (%s)\n", splashimage); -+ grub_printf("Press any key to continue..."); -+ getkey(); -+ set_videomode(saved_videomode); -+ graphics_inited = 0; -+ return 0; -+ } -+ -+ set_int1c_handler(); -+ -+ return 1; -+} -+ -+/* Leave graphics mode */ -+void graphics_end(void) -+{ -+ if (graphics_inited) { -+ unset_int1c_handler(); -+ set_videomode(saved_videomode); -+ graphics_inited = 0; -+ no_cursor = 0; -+ } -+} -+ -+/* Print ch on the screen. Handle any needed scrolling or the like */ -+void graphics_putchar(int ch) { -+ ch &= 0xff; -+ -+ graphics_cursor(0); -+ -+ if (ch == '\n') { -+ if (fonty + 1 < view_y1) -+ graphics_setxy(fontx, fonty + 1); -+ else -+ graphics_scroll(); -+ graphics_cursor(1); -+ return; -+ } else if (ch == '\r') { -+ graphics_setxy(view_x0, fonty); -+ graphics_cursor(1); -+ return; -+ } -+ -+ graphics_cursor(0); -+ -+ text[fonty * 80 + fontx] = ch; -+ text[fonty * 80 + fontx] &= 0x00ff; -+ if (graphics_current_color & 0xf0) -+ text[fonty * 80 + fontx] |= 0x100; -+ -+ graphics_cursor(0); -+ -+ if ((fontx + 1) >= view_x1) { -+ graphics_setxy(view_x0, fonty); -+ if (fonty + 1 < view_y1) -+ graphics_setxy(view_x0, fonty + 1); -+ else -+ graphics_scroll(); -+ graphics_cursor(1); -+ do_more (); -+ graphics_cursor(0); -+ } else { -+ graphics_setxy(fontx + 1, fonty); -+ } -+ -+ graphics_cursor(1); -+} -+ -+/* get the current location of the cursor */ -+int graphics_getxy(void) { -+ return (fontx << 8) | fonty; -+} -+ -+void graphics_gotoxy(int x, int y) { -+ graphics_cursor(0); -+ -+ graphics_setxy(x, y); -+ -+ graphics_cursor(1); -+} -+ -+void graphics_cls(void) { -+ int i; -+ unsigned char *mem, *s1, *s2, *s4, *s8; -+ -+ graphics_cursor(0); -+ graphics_gotoxy(view_x0, view_y0); -+ -+ mem = (unsigned char*)VIDEOMEM; -+ s1 = (unsigned char*)VSHADOW1; -+ s2 = (unsigned char*)VSHADOW2; -+ s4 = (unsigned char*)VSHADOW4; -+ s8 = (unsigned char*)VSHADOW8; -+ -+ for (i = 0; i < 80 * 30; i++) -+ text[i] = ' '; -+ graphics_cursor(1); -+ -+ BitMask(0xff); -+ -+ /* plane 1 */ -+ MapMask(1); -+ grub_memcpy(mem, s1, 38400); -+ -+ /* plane 2 */ -+ MapMask(2); -+ grub_memcpy(mem, s2, 38400); -+ -+ /* plane 3 */ -+ MapMask(4); -+ grub_memcpy(mem, s4, 38400); -+ -+ /* plane 4 */ -+ MapMask(8); -+ grub_memcpy(mem, s8, 38400); -+ -+ MapMask(15); -+ -+ if (no_cursor) { -+ no_cursor = 0; -+ set_int1c_handler(); -+ } -+} -+ -+void graphics_setcolorstate (color_state state) { -+ switch (state) { -+ case COLOR_STATE_STANDARD: -+ graphics_current_color = graphics_standard_color; -+ break; -+ case COLOR_STATE_NORMAL: -+ graphics_current_color = graphics_normal_color; -+ break; -+ case COLOR_STATE_HIGHLIGHT: -+ graphics_current_color = graphics_highlight_color; -+ break; -+ default: -+ graphics_current_color = graphics_standard_color; -+ break; -+ } -+ -+ graphics_color_state = state; -+} -+ -+void graphics_setcolor (int normal_color, int highlight_color) { -+ graphics_normal_color = normal_color; -+ graphics_highlight_color = highlight_color; -+ -+ graphics_setcolorstate (graphics_color_state); -+} -+ -+int graphics_setcursor (int on) { -+ if (!no_cursor && !on) { -+ no_cursor = 1; -+ unset_int1c_handler(); -+ graphics_cursor(0); -+ } -+ else if(no_cursor && on) { -+ no_cursor = 0; -+ set_int1c_handler(); -+ graphics_cursor(1); -+ } -+ return 0; -+} -+ -+/* Read in the splashscreen image and set the palette up appropriately. -+ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and -+ * 640x480. */ -+int read_image(char *s) -+{ -+ char buf[32], pal[16], c; -+ unsigned char base, mask, *s1, *s2, *s4, *s8; -+ unsigned i, len, idx, colors, x, y, width, height; -+ -+ if (!grub_open(s)) -+ return 0; -+ -+ /* read header */ -+ if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) { -+ grub_close(); -+ return 0; -+ } -+ -+ /* parse info */ -+ while (grub_read(&c, 1)) { -+ if (c == '"') -+ break; -+ } -+ -+ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) -+ ; -+ -+ i = 0; -+ width = c - '0'; -+ while (grub_read(&c, 1)) { -+ if (c >= '0' && c <= '9') -+ width = width * 10 + c - '0'; -+ else -+ break; -+ } -+ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) -+ ; -+ -+ height = c - '0'; -+ while (grub_read(&c, 1)) { -+ if (c >= '0' && c <= '9') -+ height = height * 10 + c - '0'; -+ else -+ break; -+ } -+ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) -+ ; -+ -+ colors = c - '0'; -+ while (grub_read(&c, 1)) { -+ if (c >= '0' && c <= '9') -+ colors = colors * 10 + c - '0'; -+ else -+ break; -+ } -+ -+ base = 0; -+ while (grub_read(&c, 1) && c != '"') -+ ; -+ -+ /* palette */ -+ for (i = 0, idx = 1; i < colors; i++) { -+ len = 0; -+ -+ while (grub_read(&c, 1) && c != '"') -+ ; -+ grub_read(&c, 1); /* char */ -+ base = c; -+ grub_read(buf, 4); /* \t c # */ -+ -+ while (grub_read(&c, 1) && c != '"') { -+ if (len < sizeof(buf)) -+ buf[len++] = c; -+ } -+ -+ if (len == 6 && idx < 15) { -+ int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2; -+ int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2; -+ int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2; -+ -+ pal[idx] = base; -+ graphics_set_palette(idx, r, g, b); -+ ++idx; -+ } -+ } -+ -+ x = y = len = 0; -+ -+ s1 = (unsigned char*)VSHADOW1; -+ s2 = (unsigned char*)VSHADOW2; -+ s4 = (unsigned char*)VSHADOW4; -+ s8 = (unsigned char*)VSHADOW8; -+ -+ for (i = 0; i < 38400; i++) -+ s1[i] = s2[i] = s4[i] = s8[i] = 0; -+ -+ /* parse xpm data */ -+ while (y < height) { -+ while (1) { -+ if (!grub_read(&c, 1)) { -+ grub_close(); -+ return 0; -+ } -+ if (c == '"') -+ break; -+ } -+ -+ while (grub_read(&c, 1) && c != '"') { -+ for (i = 1; i < 15; i++) -+ if (pal[i] == c) { -+ c = i; -+ break; -+ } -+ -+ mask = 0x80 >> (x & 7); -+ if (c & 1) -+ s1[len + (x >> 3)] |= mask; -+ if (c & 2) -+ s2[len + (x >> 3)] |= mask; -+ if (c & 4) -+ s4[len + (x >> 3)] |= mask; -+ if (c & 8) -+ s8[len + (x >> 3)] |= mask; -+ -+ if (++x >= 640) { -+ x = 0; -+ -+ if (y < 480) -+ len += 80; -+ ++y; -+ } -+ } -+ } -+ -+ grub_close(); -+ -+ graphics_set_palette(0, (background >> 16), (background >> 8) & 63, -+ background & 63); -+ graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63, -+ foreground & 63); -+ graphics_set_palette(0x11, (window_border >> 16), (window_border >> 8) & 63, -+ window_border & 63); -+ -+ return 1; -+} -+ -+/* Convert a character which is a hex digit to the appropriate integer */ -+int hex(int v) -+{ -+ if (v >= 'A' && v <= 'F') -+ return (v - 'A' + 10); -+ if (v >= 'a' && v <= 'f') -+ return (v - 'a' + 10); -+ return (v - '0'); -+} -+ -+void graphics_cursor(int set) { -+ unsigned char *pat, *mem, *ptr, chr[16 << 2]; -+ int i, ch, invert, offset; -+ -+ if (set && (no_cursor || no_scroll)) -+ return; -+ -+ offset = cursorY * 80 + fontx; -+ ch = text[fonty * 80 + fontx] & 0xff; -+ invert = (text[fonty * 80 + fontx] & 0xff00) != 0; -+ pat = font8x16 + (ch << 4); -+ -+ mem = (unsigned char*)VIDEOMEM + offset; -+ -+ if (!set) { -+ for (i = 0; i < 16; i++) { -+ unsigned char mask = pat[i]; -+ -+ if (!invert) { -+ chr[i ] = ((unsigned char*)VSHADOW1)[offset]; -+ chr[16 + i] = ((unsigned char*)VSHADOW2)[offset]; -+ chr[32 + i] = ((unsigned char*)VSHADOW4)[offset]; -+ chr[48 + i] = ((unsigned char*)VSHADOW8)[offset]; -+ -+ if (shade) { -+ if (ch == DISP_VERT || ch == DISP_LL || -+ ch == DISP_UR || ch == DISP_LR) { -+ unsigned char pmask = ~(pat[i] >> 1); -+ -+ chr[i ] &= pmask; -+ chr[16 + i] &= pmask; -+ chr[32 + i] &= pmask; -+ chr[48 + i] &= pmask; -+ } -+ if (i > 0 && ch != DISP_VERT) { -+ unsigned char pmask = ~(pat[i - 1] >> 1); -+ -+ chr[i ] &= pmask; -+ chr[16 + i] &= pmask; -+ chr[32 + i] &= pmask; -+ chr[48 + i] &= pmask; -+ if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) { -+ pmask = ~pat[i - 1]; -+ -+ chr[i ] &= pmask; -+ chr[16 + i] &= pmask; -+ chr[32 + i] &= pmask; -+ chr[48 + i] &= pmask; -+ } -+ } -+ } -+ chr[i ] |= mask; -+ chr[16 + i] |= mask; -+ chr[32 + i] |= mask; -+ chr[48 + i] |= mask; -+ -+ offset += 80; -+ } -+ else { -+ chr[i ] = mask; -+ chr[16 + i] = mask; -+ chr[32 + i] = mask; -+ chr[48 + i] = mask; -+ } -+ } -+ } -+ else { -+ MapMask(15); -+ ptr = mem; -+ for (i = 0; i < 16; i++, ptr += 80) { -+ cursorBuf[i] = pat[i]; -+ *ptr = ~pat[i]; -+ } -+ return; -+ } -+ -+ offset = 0; -+ for (i = 1; i < 16; i <<= 1, offset += 16) { -+ int j; -+ -+ MapMask(i); -+ ptr = mem; -+ for (j = 0; j < 16; j++, ptr += 80) -+ *ptr = chr[j + offset]; -+ } -+ -+ MapMask(15); -+} -+ -+#endif /* SUPPORT_GRAPHICS */ ---- /dev/null -+++ b/stage2/graphics.h -@@ -0,0 +1,44 @@ -+/* graphics.h - graphics console interface */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002 Free Software Foundation, Inc. -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#ifndef GRAPHICS_H -+#define GRAPHICS_H -+ -+/* magic constant */ -+#define VIDEOMEM 0xA0000 -+ -+/* function prototypes */ -+char *graphics_get_splash(void); -+ -+int read_image(char *s); -+void graphics_cursor(int set); -+ -+/* function prototypes for asm functions */ -+void * graphics_get_font(); -+void graphics_set_palette(int idx, int red, int green, int blue); -+void set_int1c_handler(); -+void unset_int1c_handler(); -+ -+extern short cursorX, cursorY; -+extern char cursorBuf[16]; -+extern int shade; -+extern int view_x0, view_y0, view_x1, view_y1; -+ -+#endif /* GRAPHICS_H */ ---- a/stage2/Makefile.am -+++ b/stage2/Makefile.am -@@ -7,7 +7,7 @@ noinst_HEADERS = apic.h defs.h dir.h dis - fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \ - imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \ - nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \ -- terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h -+ terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h - EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS) - - # For . -@@ -19,7 +19,7 @@ libgrub_a_SOURCES = boot.c builtins.c ch - disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \ - fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \ - fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \ -- terminfo.c tparm.c -+ terminfo.c tparm.c graphics.c - libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \ - -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \ - -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \ -@@ -79,8 +79,14 @@ else - HERCULES_FLAGS = - endif - -+if GRAPHICS_SUPPORT -+GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1 -+else -+GRAPHICS_FLAGS = -+endif -+ - STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \ -- $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) -+ $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS) - - STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 - STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 -@@ -90,7 +96,8 @@ pre_stage2_exec_SOURCES = asm.S bios.c b - cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \ - fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \ - fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \ -- hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c -+ hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \ -+ graphics.c - pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) - pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) - pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK) ---- a/stage2/shared.h -+++ b/stage2/shared.h -@@ -499,7 +499,11 @@ struct vbe_mode - unsigned char linear_reserved_field_position; - unsigned long max_pixel_clock; - -- unsigned char reserved3[189]; -+ /* Reserved field to make structure to be 256 bytes long, VESA BIOS -+ Extension 3.0 Specification says to reserve 189 bytes here but -+ that doesn't make structure to be 256 bytes. So additional one is -+ added here. */ -+ unsigned char reserved3[189 + 1]; - } __attribute__ ((packed)); - - -@@ -792,6 +796,11 @@ int getxy (void); - /* Set the cursor position. */ - void gotoxy (int x, int y); - -+/* Internal pager -+ Returns 1 = if pager was used -+ 0 = if pager wasn't used */ -+int do_more (void); -+ - /* Displays an ASCII character. IBM displays will translate some - characters to special graphical ones (see the DISP_* constants). */ - void grub_putchar (int c); -@@ -871,6 +880,7 @@ int grub_sprintf (char *buffer, const ch - int grub_tolower (int c); - int grub_isspace (int c); - int grub_strncat (char *s1, const char *s2, int n); -+void grub_memcpy(void *dest, const void *src, int len); - void *grub_memmove (void *to, const void *from, int len); - void *grub_memset (void *start, int c, int len); - int grub_strncat (char *s1, const char *s2, int n); -@@ -911,7 +921,7 @@ int substring (const char *s1, const cha - int nul_terminate (char *str); - int get_based_digit (int c, int base); - int safe_parse_maxint (char **str_ptr, int *myint_ptr); --int memcheck (int start, int len); -+int memcheck (unsigned long int start, unsigned long int len); - void grub_putstr (const char *str); - - #ifndef NO_DECOMPRESSION ---- a/stage2/stage2.c -+++ b/stage2/stage2.c -@@ -20,6 +20,12 @@ - #include - #include - -+#ifdef SUPPORT_GRAPHICS -+# include -+#endif -+ -+int col_start, col_end, row_start, box_size; -+ - grub_jmp_buf restart_env; - - #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) -@@ -105,13 +111,13 @@ print_entry (int y, int highlight, char - if (highlight && current_term->setcolorstate) - current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); - -- gotoxy (2, y); -+ gotoxy (2 + col_start, y); - grub_putchar (' '); -- for (x = 3; x < 75; x++) -+ for (x = 3 + col_start; x < (col_end - 5); x++) - { -- if (*entry && x <= 72) -+ if (*entry && x <= (col_end - 8)) - { -- if (x == 72) -+ if (x == (col_end - 8)) - grub_putchar (DISP_RIGHT); - else - grub_putchar (*entry++); -@@ -119,7 +125,7 @@ print_entry (int y, int highlight, char - else - grub_putchar (' '); - } -- gotoxy (74, y); -+ gotoxy ((col_end - 6), y); - - if (current_term->setcolorstate) - current_term->setcolorstate (COLOR_STATE_STANDARD); -@@ -131,7 +137,7 @@ print_entries (int y, int size, int firs - { - int i; - -- gotoxy (77, y + 1); -+ gotoxy ((col_end - 3), y + 1); - - if (first) - grub_putchar (DISP_UP); -@@ -151,14 +157,14 @@ print_entries (int y, int size, int firs - menu_entries++; - } - -- gotoxy (77, y + size); -+ gotoxy ((col_end - 3), y + size); - - if (*menu_entries) - grub_putchar (DISP_DOWN); - else - grub_putchar (' '); - -- gotoxy (74, y + entryno + 1); -+ gotoxy ((col_end - 6), y + entryno + 1); - } - - static void -@@ -196,30 +202,30 @@ print_border (int y, int size) - if (current_term->setcolorstate) - current_term->setcolorstate (COLOR_STATE_NORMAL); - -- gotoxy (1, y); -+ gotoxy (1 + col_start, y); - - grub_putchar (DISP_UL); -- for (i = 0; i < 73; i++) -+ for (i = col_start; i < (col_end - 7); i++) - grub_putchar (DISP_HORIZ); - grub_putchar (DISP_UR); - - i = 1; - while (1) - { -- gotoxy (1, y + i); -+ gotoxy (1 + col_start, y + i); - - if (i > size) - break; - - grub_putchar (DISP_VERT); -- gotoxy (75, y + i); -+ gotoxy ((col_end - 5), y + i); - grub_putchar (DISP_VERT); - - i++; - } - - grub_putchar (DISP_LL); -- for (i = 0; i < 73; i++) -+ for (i = col_start; i < (col_end - 7); i++) - grub_putchar (DISP_HORIZ); - grub_putchar (DISP_LR); - -@@ -233,6 +239,7 @@ run_menu (char *menu_entries, char *conf - { - int c, time1, time2 = -1, first_entry = 0; - char *cur_entry = 0; -+ struct term_entry *prev_term = NULL; - - /* - * Main loop for menu UI. -@@ -250,6 +257,22 @@ restart: - } - } - -+ col_start = 0; -+ col_end = 80; -+ row_start = 0; -+ box_size = 12; -+ /* if we're using viewport we need to make sure to setup -+ coordinates correctly. */ -+#ifdef SUPPORT_GRAPHICS -+ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) -+ { -+ col_start = view_x0; -+ col_end = view_x1; -+ row_start = view_y0; -+ box_size = (view_y1 - view_y0) - 13; -+ } -+#endif -+ - /* If the timeout was expired or wasn't set, force to show the menu - interface. */ - if (grub_timeout < 0) -@@ -302,36 +325,36 @@ restart: - if (current_term->flags & TERM_DUMB) - print_entries_raw (num_entries, first_entry, menu_entries); - else -- print_border (3, 12); -+ print_border (3 + row_start, box_size); - - grub_printf ("\n\ -- Use the %c and %c keys to select which entry is highlighted.\n", -+ Use the %c and %c keys to select which entry is highlighted.\n", - DISP_UP, DISP_DOWN); - - if (! auth && password) - { - printf ("\ -- Press enter to boot the selected OS or \'p\' to enter a\n\ -- password to unlock the next set of features."); -+ Press enter to boot the selected OS or \'p\' to enter a\n\ -+ password to unlock the next set of features."); - } - else - { - if (config_entries) - printf ("\ -- Press enter to boot the selected OS, \'e\' to edit the\n\ -- commands before booting, or \'c\' for a command-line."); -+ Press enter to boot the selected OS, \'e\' to edit the\n\ -+ commands before booting, or \'c\' for a command-line."); - else - printf ("\ -- Press \'b\' to boot, \'e\' to edit the selected command in the\n\ -- boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\ -- after (\'O\' for before) the selected line, \'d\' to remove the\n\ -- selected line, or escape to go back to the main menu."); -+ Press \'b\' to boot, \'e\' to edit the selected command in the\n\ -+ boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\ -+ after (\'O\' for before) the selected line, \'d\' to remove the\n\ -+ selected line, or escape to go back to the main menu."); - } - - if (current_term->flags & TERM_DUMB) - grub_printf ("\n\nThe selected entry is %d ", entryno); - else -- print_entries (3, 12, first_entry, entryno, menu_entries); -+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); - } - - /* XX using RT clock now, need to initialize value */ -@@ -358,10 +381,10 @@ restart: - entryno, grub_timeout); - else - { -- gotoxy (3, 22); -- grub_printf ("The highlighted entry will be booted automatically in %d seconds. ", -+ gotoxy (3 + col_start, 10 + box_size + row_start); -+ grub_printf (" The highlighted entry will be booted automatically in %d seconds. ", - grub_timeout); -- gotoxy (74, 4 + entryno); -+ gotoxy ((col_end - 6), 4 + entryno + row_start); - } - - grub_timeout--; -@@ -387,12 +410,12 @@ restart: - if (current_term->flags & TERM_DUMB) - grub_putchar ('\r'); - else -- gotoxy (3, 22); -+ gotoxy (3 + col_start, 10 + box_size + row_start); - printf (" "); - grub_timeout = -1; - fallback_entryno = -1; - if (! (current_term->flags & TERM_DUMB)) -- gotoxy (74, 4 + entryno); -+ gotoxy ((col_end - 6), 4 + entryno + row_start); - } - - /* We told them above (at least in SUPPORT_SERIAL) to use -@@ -408,12 +431,12 @@ restart: - { - if (entryno > 0) - { -- print_entry (4 + entryno, 0, -+ print_entry (4 + entryno + row_start, 0, - get_entry (menu_entries, - first_entry + entryno, - 0)); - entryno--; -- print_entry (4 + entryno, 1, -+ print_entry (4 + entryno + row_start, 1, - get_entry (menu_entries, - first_entry + entryno, - 0)); -@@ -421,7 +444,7 @@ restart: - else if (first_entry > 0) - { - first_entry--; -- print_entries (3, 12, first_entry, entryno, -+ print_entries (3 + row_start, box_size, first_entry, entryno, - menu_entries); - } - } -@@ -433,29 +456,29 @@ restart: - entryno++; - else - { -- if (entryno < 11) -+ if (entryno < (box_size - 1)) - { -- print_entry (4 + entryno, 0, -+ print_entry (4 + entryno + row_start, 0, - get_entry (menu_entries, - first_entry + entryno, - 0)); - entryno++; -- print_entry (4 + entryno, 1, -+ print_entry (4 + entryno + row_start, 1, - get_entry (menu_entries, - first_entry + entryno, - 0)); - } -- else if (num_entries > 12 + first_entry) -+ else if (num_entries > box_size + first_entry) - { - first_entry++; -- print_entries (3, 12, first_entry, entryno, menu_entries); -+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); - } - } - } - else if (c == 7) - { - /* Page Up */ -- first_entry -= 12; -+ first_entry -= box_size; - if (first_entry < 0) - { - entryno += first_entry; -@@ -463,20 +486,20 @@ restart: - if (entryno < 0) - entryno = 0; - } -- print_entries (3, 12, first_entry, entryno, menu_entries); -+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); - } - else if (c == 3) - { - /* Page Down */ -- first_entry += 12; -+ first_entry += box_size; - if (first_entry + entryno + 1 >= num_entries) - { -- first_entry = num_entries - 12; -+ first_entry = num_entries - box_size; - if (first_entry < 0) - first_entry = 0; - entryno = num_entries - first_entry - 1; - } -- print_entries (3, 12, first_entry, entryno, menu_entries); -+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); - } - - if (config_entries) -@@ -489,7 +512,7 @@ restart: - if ((c == 'd') || (c == 'o') || (c == 'O')) - { - if (! (current_term->flags & TERM_DUMB)) -- print_entry (4 + entryno, 0, -+ print_entry (4 + entryno + row_start, 0, - get_entry (menu_entries, - first_entry + entryno, - 0)); -@@ -537,7 +560,7 @@ restart: - - if (entryno >= num_entries) - entryno--; -- if (first_entry && num_entries < 12 + first_entry) -+ if (first_entry && num_entries < box_size + first_entry) - first_entry--; - } - -@@ -549,7 +572,7 @@ restart: - grub_printf ("\n"); - } - else -- print_entries (3, 12, first_entry, entryno, menu_entries); -+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); - } - - cur_entry = menu_entries; -@@ -570,7 +593,7 @@ restart: - if (current_term->flags & TERM_DUMB) - grub_printf ("\r "); - else -- gotoxy (1, 21); -+ gotoxy (1 + col_start, 9 + box_size + row_start); - - /* Wipe out the previously entered password */ - grub_memset (entered, 0, sizeof (entered)); -@@ -651,7 +674,10 @@ restart: - *(new_heap++) = 0; - - if (config_entries) -- run_menu (heap, NULL, new_num_entries, new_heap, 0); -+ { -+ current_entryno = first_entry + entryno; -+ run_menu (heap, NULL, new_num_entries, new_heap, 0); -+ } - else - { - cls (); -@@ -714,6 +740,15 @@ restart: - - cls (); - setcursor (1); -+ /* if our terminal needed initialization, we should shut it down -+ * before booting the kernel, but we want to save what it was so -+ * we can come back if needed */ -+ prev_term = current_term; -+ if (current_term->shutdown) -+ { -+ current_term->shutdown(); -+ current_term = term_table; /* assumption: console is first */ -+ } - - while (1) - { -@@ -727,7 +762,8 @@ restart: - cur_entry = get_entry (config_entries, first_entry + entryno, 1); - - /* Set CURRENT_ENTRYNO for the command "savedefault". */ -- current_entryno = first_entry + entryno; -+ if (config_entries) -+ current_entryno = first_entry + entryno; - - if (run_script (cur_entry, heap)) - { -@@ -748,6 +784,13 @@ restart: - break; - } - -+ /* if we get back here, we should go back to what our term was before */ -+ current_term = prev_term; -+ if (current_term->startup) -+ /* if our terminal fails to initialize, fall back to console since -+ * it should always work */ -+ if (current_term->startup() == 0) -+ current_term = term_table; /* we know that console is first */ - show_menu = 1; - goto restart; - } -@@ -891,8 +934,18 @@ cmain (void) - len = grub_read (buf, sizeof (buf)); - if (len > 0) - { -+ char *tmp; -+ char *def; - buf[sizeof (buf) - 1] = 0; -- safe_parse_maxint (&p, &saved_entryno); -+ -+ if((tmp = grub_strstr(p, ":")) != NULL) -+ { -+ *tmp++; -+ grub_memcpy(&def, &tmp, sizeof(p)); -+ }else -+ grub_memcpy(&def, &p, sizeof(p)); -+ -+ safe_parse_maxint (&def, &saved_entryno); - } - - grub_close (); -@@ -1050,6 +1103,16 @@ cmain (void) - while (is_preset); - } - -+ /* go ahead and make sure the terminal is setup */ -+ if (current_term->startup) -+ { -+ /* If initialization fails, go back to default terminal */ -+ if (current_term->startup() == 0) -+ { -+ current_term = term_table; -+ } -+ } -+ - if (! num_entries) - { - /* If no acceptable config file, goto command-line, starting ---- a/stage2/term.h -+++ b/stage2/term.h -@@ -60,6 +60,8 @@ struct term_entry - const char *name; - /* The feature flags defined above. */ - unsigned long flags; -+ /* Default for maximum number of lines if not specified */ -+ unsigned short max_lines; - /* Put a character. */ - void (*putchar) (int c); - /* Check if any input character is available. */ -@@ -79,6 +81,10 @@ struct term_entry - void (*setcolor) (int normal_color, int highlight_color); - /* Turn on/off the cursor. */ - int (*setcursor) (int on); -+ /* function to start a terminal */ -+ int (*startup) (void); -+ /* function to use to shutdown a terminal */ -+ void (*shutdown) (void); - }; - - /* This lists up available terminals. */ -@@ -124,4 +130,24 @@ void hercules_setcolor (int normal_color - int hercules_setcursor (int on); - #endif - -+#ifdef SUPPORT_GRAPHICS -+extern int foreground, background, window_border, graphics_inited, saved_videomode; -+ -+void graphics_set_splash(char *splashfile); -+int set_videomode(int mode); -+int get_videomode(void); -+void graphics_putchar (int c); -+int graphics_getxy(void); -+void graphics_gotoxy(int x, int y); -+void graphics_cls(void); -+void graphics_setcolorstate (color_state state); -+void graphics_setcolor (int normal_color, int highlight_color); -+int graphics_setcursor (int on); -+int graphics_init(void); -+void graphics_end(void); -+ -+int hex(int v); -+void graphics_set_palette(int idx, int red, int green, int blue); -+#endif /* SUPPORT_GRAPHICS */ -+ - #endif /* ! GRUB_TERM_HEADER */ ---- a/THANKS -+++ b/THANKS -@@ -121,3 +121,4 @@ Vesa Jaaskelainen - Yury V. Umanets - Yuri Zaporogets -+Vitaly Fertman ---- a/util/grub-install.in -+++ b/util/grub-install.in -@@ -81,6 +81,50 @@ Report bugs to . - EOF - } - -+# Usage: getraid_mdadm mddevice -+# Routine to find a physical device from an md device -+# If found, the first grub BIOS device (from device.map) is returned -+# If no BIOS drives match the RAID devices, the first device returned -+# from mdadm -D is returned -+getraid_mdadm() { -+ device=$1 -+ mdadm=$(mdadm -D "$device") || { -+ echo "$PROG: mdadm -D $device failed" >&2 -+ exit 1 -+ } -+ eval "$( -+ echo "$mdadm" | awk ' -+ $1 == "Number" && $2 == "Major" { start = 1; next } -+ $1 == "UUID" { print "uuid=" $3; start = 0; next } -+ !start { next } -+ $2 == 0 && $3 == 0 { next } -+ { devices = devices "\n" $NF } -+ END { print "devices='\''" devices "'\''" } -+ ' -+ )" -+ -+ # Convert RAID devices list into a list of disks -+ tmp_disks=`echo "$devices" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \ -+ -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \ -+ -e 's%\(fd[0-9]*\)$%\1%' \ -+ -e 's%/part[0-9]*$%/disc%' \ -+ -e 's%\(c[0-7]d[0-9]*\).*$%\1%' \ -+ -e '/^$/d' | -+ sed -n '1h;2,$H;${g;s/\n/|/g;p}'` -+ -+ # Find first BIOS disk that's a member of the RAID array -+ # Default to first RAID member if no tmp_disks are BIOS devices -+ set -- `egrep $tmp_disks $device_map | \ -+ sort | \ -+ sed -n 1p ` -+ device=${2:-${tmp_disks%%|*}} -+ -+ # Return first partition on BIOS disk that's part of the RAID -+ echo "$devices" | \ -+ sed -n "\:${device}:p" | \ -+ sed -n 1p -+} -+ - # Usage: convert os_device - # Convert an OS device to the corresponding GRUB drive. - # This part is OS-specific. -@@ -96,6 +140,10 @@ convert () { - # Break the device name into the disk part and the partition part. - case "$host_os" in - linux*) -+ # Find an actual physical device if we're passed a RAID device -+ case $1 in -+ /dev/md*) set -- `getraid_mdadm $1` -+ esac - tmp_disk=`echo "$1" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \ - -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \ - -e 's%\(fd[0-9]*\)$%\1%' \ -@@ -112,8 +160,8 @@ convert () { - tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'` - tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;; - freebsd* | kfreebsd*-gnu) -- tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%r\1%' \ -- | sed 's%r\{0,1\}\(da[0-9]*\).*$%r\1%'` -+ tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%\1%' \ -+ | sed 's%r\{0,1\}\(da[0-9]*\).*$%\1%'` - tmp_part=`echo "$1" \ - | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \ - | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"` -@@ -131,7 +179,7 @@ convert () { - - # Get the drive name. - tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \ -- | sed 's%.*\(([hf]d[0-9][a-g0-9,]*)\).*%\1%'` -+ | sed 's%.*\(([hf]d[0-9][a-z0-9,]*)\).*%\1%'` - - # If not found, print an error message and exit. - if test "x$tmp_drive" = x; then -@@ -148,13 +196,13 @@ convert () { - gnu*) - if echo $tmp_part | grep "^s" >/dev/null; then - tmp_pc_slice=`echo $tmp_part \ -- | sed "s%s\([0-9]*\)[a-g]*$%\1%"` -+ | sed "s%s\([0-9]*\)[a-z]*$%\1%"` - tmp_drive=`echo "$tmp_drive" \ - | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"` - fi -- if echo $tmp_part | grep "[a-g]$" >/dev/null; then -+ if echo $tmp_part | grep "[a-z]$" >/dev/null; then - tmp_bsd_partition=`echo "$tmp_part" \ -- | sed "s%[^a-g]*\([a-g]\)$%\1%"` -+ | sed "s%[^a-z]*\([a-z]\)$%\1%"` - tmp_drive=`echo "$tmp_drive" \ - | sed "s%)%,$tmp_bsd_partition)%"` - fi -@@ -336,6 +384,10 @@ else - # Create a safe temporary file. - test -n "$mklog" && log_file=`$mklog` - -+ # Before all invocations of the grub shell, call sync to make sure -+ # the raw device is in sync with any bufferring in filesystems. -+ sync -+ - $grub_shell --batch $no_floppy --device-map=$device_map <$log_file - quit - EOF -@@ -450,6 +502,24 @@ rm -f $log_file - # Create a safe temporary file. - test -n "$mklog" && log_file=`$mklog` - -+# Sync to prevent GRUB from not finding stage files (notably, on XFS) -+sync -+ -+# XFS needs special magic -+xfs_frozen=false -+if which xfs_freeze > /dev/null ; then -+ cat << EOF -+Due to a bug in xfs_freeze, the following command might produce a segmentation -+fault when ${grubdir} is not in an XFS filesystem. This error is harmless and -+can be ignored. -+EOF -+ if xfs_freeze -f ${grubdir} ; then xfs_frozen=true ; fi -+fi -+ -+# Before all invocations of the grub shell, call sync to make sure -+# the raw device is in sync with any bufferring in filesystems. -+sync -+ - # Now perform the installation. - $grub_shell --batch $no_floppy --device-map=$device_map <$log_file - root $root_drive -@@ -457,6 +527,10 @@ setup $force_lba --stage2=$grubdir/stage - quit - EOF - -+if ${xfs_frozen} ; then -+ xfs_freeze -u ${grubdir} -+fi -+ - if grep "Error [0-9]*: " $log_file >/dev/null || test $debug = yes; then - cat $log_file 1>&2 - exit 1 diff --git a/extra/grub/patches/020-ext4_support.patch b/extra/grub/patches/020-ext4_support.patch deleted file mode 100644 index 06cd2c261..000000000 --- a/extra/grub/patches/020-ext4_support.patch +++ /dev/null @@ -1,267 +0,0 @@ ---- a/stage2/fsys_ext2fs.c -+++ b/stage2/fsys_ext2fs.c -@@ -51,6 +51,9 @@ typedef unsigned int __u32; - #define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) - #define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) - -+/* Inode flags */ -+#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ -+ - /* include/linux/ext2_fs.h */ - struct ext2_super_block - { -@@ -191,6 +194,42 @@ struct ext2_dir_entry - #define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ - ~EXT2_DIR_ROUND) - -+/* linux/ext4_fs_extents.h */ -+/* -+ * This is the extent on-disk structure. -+ * It's used at the bottom of the tree. -+ */ -+struct ext4_extent { -+ __u32 ee_block; /* first logical block extent covers */ -+ __u16 ee_len; /* number of blocks covered by extent */ -+ __u16 ee_start_hi; /* high 16 bits of physical block */ -+ __u32 ee_start; /* low 32 bits of physical block */ -+}; -+ -+/* -+ * This is index on-disk structure. -+ * It's used at all the levels except the bottom. -+ */ -+struct ext4_extent_idx { -+ __u32 ei_block; /* index covers logical blocks from 'block' */ -+ __u32 ei_leaf; /* pointer to the physical block of the next * -+ * level. leaf or next index could be there */ -+ __u16 ei_leaf_hi; /* high 16 bits of physical block */ -+ __u16 ei_unused; -+}; -+ -+/* -+ * Each block (leaves and indexes), even inode-stored has header. -+ */ -+struct ext4_extent_header { -+ __u16 eh_magic; /* probably will support different formats */ -+ __u16 eh_entries; /* number of valid entries */ -+ __u16 eh_max; /* capacity of store in entries */ -+ __u16 eh_depth; /* has tree real underlying blocks? */ -+ __u32 eh_generation; /* generation of the tree */ -+}; -+ -+#define EXT4_EXT_MAGIC 0xf30a - - /* ext2/super.c */ - #define log2(n) ffz(~(n)) -@@ -279,6 +318,27 @@ ext2_rdfsb (int fsblock, int buffer) - EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer); - } - -+/* Walk through extents index tree to find the good leaf */ -+static struct ext4_extent_header * -+ext4_recurse_extent_index(struct ext4_extent_header *extent_block, int logical_block) -+{ -+ int i; -+ struct ext4_extent_idx *index = (struct ext4_extent_idx *) (extent_block + 1); -+ if (extent_block->eh_magic != EXT4_EXT_MAGIC) -+ return NULL; -+ if (extent_block->eh_depth == 0) -+ return extent_block; -+ for (i = 0; i < extent_block->eh_entries; i++) -+ { -+ if (logical_block < index[i].ei_block) -+ break; -+ } -+ if (i == 0 || !ext2_rdfsb(index[i-1].ei_leaf, DATABLOCK1)) -+ return NULL; -+ return (ext4_recurse_extent_index((struct ext4_extent_header *) DATABLOCK1, logical_block)); -+} -+ -+ - /* from - ext2/inode.c:ext2_bmap() - */ -@@ -287,7 +347,6 @@ ext2_rdfsb (int fsblock, int buffer) - static int - ext2fs_block_map (int logical_block) - { -- - #ifdef E2DEBUG - unsigned char *i; - for (i = (unsigned char *) INODE; -@@ -308,82 +367,106 @@ ext2fs_block_map (int logical_block) - printf ("logical block %d\n", logical_block); - #endif /* E2DEBUG */ - -- /* if it is directly pointed to by the inode, return that physical addr */ -- if (logical_block < EXT2_NDIR_BLOCKS) -+ if (!(INODE->i_flags & EXT4_EXTENTS_FL)) - { --#ifdef E2DEBUG -- printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block])); -- printf ("returning %d\n", INODE->i_block[logical_block]); --#endif /* E2DEBUG */ -- return INODE->i_block[logical_block]; -- } -- /* else */ -- logical_block -= EXT2_NDIR_BLOCKS; -- /* try the indirect block */ -- if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK)) -- { -- if (mapblock1 != 1 -- && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1)) -- { -- errnum = ERR_FSYS_CORRUPT; -- return -1; -- } -- mapblock1 = 1; -- return ((__u32 *) DATABLOCK1)[logical_block]; -- } -- /* else */ -- logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK); -- /* now try the double indirect block */ -- if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2))) -- { -- int bnum; -- if (mapblock1 != 2 -- && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1)) -- { -- errnum = ERR_FSYS_CORRUPT; -- return -1; -- } -- mapblock1 = 2; -- if ((bnum = (((__u32 *) DATABLOCK1) -- [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)])) -- != mapblock2 -- && !ext2_rdfsb (bnum, DATABLOCK2)) -- { -- errnum = ERR_FSYS_CORRUPT; -- return -1; -- } -- mapblock2 = bnum; -+ /* if it is directly pointed to by the inode, return that physical addr */ -+ if (logical_block < EXT2_NDIR_BLOCKS) -+ { -+#ifdef E2DEBUG -+ printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block])); -+ printf ("returning %d\n", INODE->i_block[logical_block]); -+#endif /* E2DEBUG */ -+ return INODE->i_block[logical_block]; -+ } -+ /* else */ -+ logical_block -= EXT2_NDIR_BLOCKS; -+ /* try the indirect block */ -+ if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK)) -+ { -+ if (mapblock1 != 1 && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1)) -+ { -+ errnum = ERR_FSYS_CORRUPT; -+ return -1; -+ } -+ mapblock1 = 1; -+ return ((__u32 *) DATABLOCK1)[logical_block]; -+ } -+ /* else */ -+ logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK); -+ /* now try the double indirect block */ -+ if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2))) -+ { -+ int bnum; -+ if (mapblock1 != 2 && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1)) -+ { -+ errnum = ERR_FSYS_CORRUPT; -+ return -1; -+ } -+ mapblock1 = 2; -+ if ((bnum = (((__u32 *) DATABLOCK1) -+ [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)])) -+ != mapblock2 -+ && !ext2_rdfsb (bnum, DATABLOCK2)) -+ { -+ errnum = ERR_FSYS_CORRUPT; -+ return -1; -+ } -+ mapblock2 = bnum; -+ return ((__u32 *) DATABLOCK2) -+ [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; -+ } -+ /* else */ -+ mapblock2 = -1; -+ logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)); -+ if (mapblock1 != 3 -+ && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1)) -+ { -+ errnum = ERR_FSYS_CORRUPT; -+ return -1; -+ } -+ mapblock1 = 3; -+ if (!ext2_rdfsb (((__u32 *) DATABLOCK1) -+ [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) -+ * 2)], -+ DATABLOCK2)) -+ { -+ errnum = ERR_FSYS_CORRUPT; -+ return -1; -+ } -+ if (!ext2_rdfsb (((__u32 *) DATABLOCK2) -+ [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)) -+ & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)], -+ DATABLOCK2)) -+ { -+ errnum = ERR_FSYS_CORRUPT; -+ return -1; -+ } -+ - return ((__u32 *) DATABLOCK2) -- [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; -+ [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; - } -- /* else */ -- mapblock2 = -1; -- logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)); -- if (mapblock1 != 3 -- && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1)) -- { -- errnum = ERR_FSYS_CORRUPT; -- return -1; -- } -- mapblock1 = 3; -- if (!ext2_rdfsb (((__u32 *) DATABLOCK1) -- [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) -- * 2)], -- DATABLOCK2)) -- { -- errnum = ERR_FSYS_CORRUPT; -- return -1; -- } -- if (!ext2_rdfsb (((__u32 *) DATABLOCK2) -- [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)) -- & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)], -- DATABLOCK2)) -+ /* inode is in extents format */ -+ else - { -+ int i; -+ struct ext4_extent_header *extent_hdr = -+ ext4_recurse_extent_index((struct ext4_extent_header *) INODE->i_block, logical_block); -+ struct ext4_extent *extent = (struct ext4_extent *) (extent_hdr + 1); -+ if ( extent_hdr == NULL || extent_hdr->eh_magic != EXT4_EXT_MAGIC) -+ { -+ errnum = ERR_FSYS_CORRUPT; -+ return -1; -+ } -+ for (i = 0; ieh_entries; i++) -+ { -+ if (extent[i].ee_block <= logical_block && logical_block < extent[i].ee_block + extent[i].ee_len && !(extent[i].ee_len>>15)) -+ return (logical_block - extent[i].ee_block + extent[i].ee_start); -+ } -+ /* We should not arrive here */ -+ - errnum = ERR_FSYS_CORRUPT; - return -1; - } -- return ((__u32 *) DATABLOCK2) -- [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; - } - - /* preconditions: all preconds of ext2fs_block_map */ diff --git a/extra/grub/patches/030-add-stage2-ldscripts.patch b/extra/grub/patches/030-add-stage2-ldscripts.patch deleted file mode 100644 index aff7ed466..000000000 --- a/extra/grub/patches/030-add-stage2-ldscripts.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 8858927ddc6797489cad322fc2d2134aeae543cd Mon Sep 17 00:00:00 2001 -From: Arnaud Lacombe -Date: Sun, 11 Dec 2011 16:44:02 -0500 -Subject: [PATCH] add-stage2-ldscripts - ---- - stage2/Makefile.am | 2 +- - stage2/Makefile.in | 2 +- - stage2/stage2.ldscripts | 30 ++++++++++++++++++++++++++++++ - 3 files changed, 32 insertions(+), 2 deletions(-) - create mode 100644 stage2/stage2.ldscripts - -diff --git a/stage2/Makefile.am b/stage2/Makefile.am -index f8e6d42..ea28a4d 100644 ---- a/stage2/Makefile.am -+++ b/stage2/Makefile.am -@@ -55,7 +55,7 @@ noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \ - endif - MOSTLYCLEANFILES = $(noinst_PROGRAMS) - --PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8200 -+PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Tstage2.ldscripts - START_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000 - NBLOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0 - PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 -diff --git a/stage2/Makefile.in b/stage2/Makefile.in -index d0062bd..7bee2d5 100644 ---- a/stage2/Makefile.in -+++ b/stage2/Makefile.in -@@ -468,7 +468,7 @@ libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \ - @DISKLESS_SUPPORT_FALSE@noinst_DATA = pre_stage2 start start_eltorito - @DISKLESS_SUPPORT_TRUE@noinst_DATA = pre_stage2 start start_eltorito nbloader pxeloader diskless - MOSTLYCLEANFILES = $(noinst_PROGRAMS) --PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8200 -+PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Tstage2.ldscripts - START_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000 - NBLOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0 - PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 -diff --git a/stage2/stage2.ldscripts b/stage2/stage2.ldscripts -new file mode 100644 -index 0000000..2c8b8e1 ---- /dev/null -+++ b/stage2/stage2.ldscripts -@@ -0,0 +1,30 @@ -+/* Script for -N: mix text and data on same page; don't align data */ -+OUTPUT_FORMAT("elf32-i386", "elf32-i386", -+ "elf32-i386") -+OUTPUT_ARCH(i386) -+ENTRY(_start) -+SECTIONS -+{ -+ . = 0x8200; -+ .text : -+ { -+ _start = .; -+ *(.text .text.* ) -+ } -+ .rodata : { *(.rodata .rodata.* ) } -+ /* Adjust the address for the data segment. We want to adjust up to -+ the same address within the page on the next page up. */ -+ . = .; -+ .data : { *(.data .data.* ) } -+ __bss_start = .; -+ .bss : -+ { -+ *(.bss .bss.* ) -+ *(COMMON) -+ . = ALIGN(. != 0 ? 32 / 8 : 1); -+ } -+ . = ALIGN(32 / 8); -+ . = ALIGN(32 / 8); -+ _end = .; PROVIDE (end = .); -+ .comment 0 : { *(.comment) } -+} --- -1.7.6.153.g78432 - diff --git a/extra/grub/patches/040-automake-compat.patch b/extra/grub/patches/040-automake-compat.patch deleted file mode 100644 index da13cea7e..000000000 --- a/extra/grub/patches/040-automake-compat.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- a/stage1/Makefile.am -+++ b/stage1/Makefile.am -@@ -1,7 +1,7 @@ - pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor) --nodist_pkglib_DATA = stage1 -+nodist_pkgdata_DATA = stage1 - --CLEANFILES = $(nodist_pkglib_DATA) -+CLEANFILES = $(nodist_pkgdata_DATA) - - # We can't use builtins or standard includes. - AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc ---- a/stage2/Makefile.am -+++ b/stage2/Makefile.am -@@ -32,7 +32,7 @@ pkglibdir = $(libdir)/$(PACKAGE)/$(host_ - EXTRA_PROGRAMS = nbloader.exec pxeloader.exec diskless.exec - - if DISKLESS_SUPPORT --pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ -+pkgdata_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ - ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \ - reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 \ - nbgrub pxegrub -@@ -43,7 +43,7 @@ noinst_PROGRAMS = pre_stage2.exec start. - reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \ - xfs_stage1_5.exec nbloader.exec pxeloader.exec diskless.exec - else --pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ -+pkgdata_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ - ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \ - reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 - noinst_DATA = pre_stage2 start start_eltorito -@@ -112,7 +112,7 @@ else - BUILT_SOURCES = stage2_size.h - endif - --CLEANFILES = $(pkglib_DATA) $(noinst_DATA) $(BUILT_SOURCES) -+CLEANFILES = $(pkgdata_DATA) $(noinst_DATA) $(BUILT_SOURCES) - - stage2_size.h: pre_stage2 - -rm -f stage2_size.h diff --git a/extra/grub/patches/100-add_configure_macros.patch b/extra/grub/patches/100-add_configure_macros.patch deleted file mode 100644 index 476f778bc..000000000 --- a/extra/grub/patches/100-add_configure_macros.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/configure.ac -+++ b/configure.ac -@@ -56,6 +56,8 @@ fi - - AC_CHECK_TOOL(CC, gcc) - AC_PROG_CC -+AM_PROG_CC_C_O -+AM_PROG_AS - # We need this for older versions of Autoconf. - _AM_DEPENDENCIES(CC) - diff --git a/extra/grub/patches/110-remove_configure_errors.patch b/extra/grub/patches/110-remove_configure_errors.patch deleted file mode 100644 index f090aa975..000000000 --- a/extra/grub/patches/110-remove_configure_errors.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- a/configure.ac -+++ b/configure.ac -@@ -177,26 +177,22 @@ grub_ASM_ABSOLUTE_WITHOUT_ASTERISK - - grub_CHECK_START_SYMBOL - grub_CHECK_USCORE_START_SYMBOL --if test "x$grub_cv_check_start_symbol" != "xyes" \ -- -a "x$grub_cv_check_uscore_start_symbol" != "xyes"; then -- AC_MSG_ERROR([Neither start nor _start is defined]) --fi - - grub_CHECK_USCORE_USCORE_BSS_START_SYMBOL - grub_CHECK_USCORE_EDATA_SYMBOL - grub_CHECK_EDATA_SYMBOL --if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" != "xyes" \ -- -a "x$grub_cv_check_uscore_edata_symbol" != "xyes" \ -- -a "x$grub_cv_check_edata_symbol" != "xyes"; then -- AC_MSG_ERROR([None of __bss_start, _edata, edata defined]) --fi -+# if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" != "xyes" \ -+# -a "x$grub_cv_check_uscore_edata_symbol" != "xyes" \ -+# -a "x$grub_cv_check_edata_symbol" != "xyes"; then -+# AC_MSG_ERROR([None of __bss_start, _edata, edata defined]) -+# fi - - grub_CHECK_END_SYMBOL - grub_CHECK_USCORE_END_SYMBOL --if test "x$grub_cv_check_end_symbol" != "xyes" \ -- -a "x$grub_cv_check_uscore_end_symbol" != "xyes"; then -- AC_MSG_ERROR([Neither end nor _end is defined]) --fi -+#if test "x$grub_cv_check_end_symbol" != "xyes" \ -+# -a "x$grub_cv_check_uscore_end_symbol" != "xyes"; then -+# AC_MSG_ERROR([Neither end nor _end is defined]) -+#fi - - # Check for curses libraries. - AC_ARG_WITH(curses, diff --git a/extra/grub/patches/200-darwin_fixes.patch b/extra/grub/patches/200-darwin_fixes.patch deleted file mode 100644 index c5c55a918..000000000 --- a/extra/grub/patches/200-darwin_fixes.patch +++ /dev/null @@ -1,48 +0,0 @@ ---- a/stage2/asm.S -+++ b/stage2/asm.S -@@ -95,14 +95,16 @@ VARIABLE(stage2_id) - VARIABLE(force_lba) - .byte 0 - VARIABLE(version_string) -- .string VERSION -+ .ascii VERSION -+ .byte 0 - VARIABLE(config_file) - #ifndef STAGE1_5 -- .string "/boot/grub/menu.lst" -+ .ascii "/boot/grub/menu.lst" - #else /* STAGE1_5 */ - .long 0xffffffff -- .string "/boot/grub/stage2" -+ .ascii "/boot/grub/stage2" - #endif /* STAGE1_5 */ -+ .byte 0 - - /* - * Leave some breathing room for the config file name. -@@ -762,7 +764,9 @@ ENTRY(chain_stage1) - call EXT_C(prot_to_real) - .code16 - --#ifdef ABSOLUTE_WITHOUT_ASTERISK -+#ifdef __APPLE__ -+ DATA32 ADDR32 ljmp offset -+#elif defined(ABSOLUTE_WITHOUT_ASTERISK) - DATA32 ADDR32 ljmp (offset) - #else - DATA32 ADDR32 ljmp *(offset) ---- a/stage2/char_io.c -+++ b/stage2/char_io.c -@@ -1345,5 +1345,12 @@ grub_strcpy (char *dest, const char *src - #ifndef GRUB_UTIL - # undef memcpy - /* GCC emits references to memcpy() for struct copies etc. */ -+#ifdef __APPLE__ -+void *memcpy (void *dest, const void *src, int n) -+{ -+ return grub_memmove(dest, src, n); -+} -+#else - void *memcpy (void *dest, const void *src, int n) __attribute__ ((alias ("grub_memmove"))); - #endif -+#endif diff --git a/extra/grub/patches/210-remove_inline_asm.patch b/extra/grub/patches/210-remove_inline_asm.patch deleted file mode 100644 index 8eb9fc2c9..000000000 --- a/extra/grub/patches/210-remove_inline_asm.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/stage2/fsys_iso9660.c -+++ b/stage2/fsys_iso9660.c -@@ -83,10 +83,7 @@ iso9660_devread (int sector, int byte_of - - sector += (byte_offset >> sector_size_lg2); - byte_offset &= (buf_geom.sector_size - 1); -- asm volatile ("shl%L0 %1,%0" -- : "=r"(sector) -- : "Ic"((int8_t)(ISO_SECTOR_BITS - sector_size_lg2)), -- "0"(sector)); -+ sector <<= ISO_SECTOR_BITS - sector_size_lg2; - - #if !defined(STAGE1_5) - if (disk_read_hook && debug) diff --git a/extra/jansson/Makefile b/extra/jansson/Makefile deleted file mode 100644 index 8f36299d1..000000000 --- a/extra/jansson/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright (C) 2011-2012 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - - -include $(TOPDIR)/rules.mk - -PKG_NAME:=jansson -PKG_VERSION:=2.4 -PKG_RELEASE:=2 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=http://www.digip.org/jansson/releases/ -PKG_MD5SUM:=c4629b89bf0432f3158c461e88fe0113 - -PKG_INSTALL:=1 -PKG_BUILD_PARALLEL:=1 - -include $(INCLUDE_DIR)/package.mk - -define Package/jansson - SECTION:=libs - CATEGORY:=Libraries - TITLE:=JSON library -endef - -TARGET_CFLAGS += $(FPIC) - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/{lib,include} - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libjansson* $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/ -endef - -define Package/jansson/install -$(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libjansson*so* $(1)/usr/lib/ -endef - -$(eval $(call BuildPackage,jansson)) diff --git a/extra/owsip/Makefile b/extra/owsip/Makefile deleted file mode 100644 index 8c9c65e8e..000000000 --- a/extra/owsip/Makefile +++ /dev/null @@ -1,73 +0,0 @@ -# -# Copyright (C) 2012 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -OWSIP_VERSION=2012-02-14 -OWSIP_RELEASE=1 - -PKG_NAME:=owsip -PKG_VERSION:=$(OWSIP_VERSION)$(if $(OWSIP_RELEASE),.$(OWSIP_RELEASE)) -PKG_RELEASE:=1 -PKG_REV:=da53a53db28b47ca1714ffba72d0df5bea357706 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz -PKG_SOURCE_URL:=git://nbd.name/owsip.git -PKG_SOURCE_SUBDIR:=owsip-$(PKG_VERSION) -PKG_SOURCE_VERSION:=$(PKG_REV) -PKG_SOURCE_PROTO:=git -PKG_MIRROR_MD5SUM:=74b0ab930321c4f85f220ff3852e210a - -include $(INCLUDE_DIR)/ltqtapi.mk -include $(INCLUDE_DIR)/package.mk - -define Package/owsip-template - SUBMENU:=Telephony - SECTION:=net - CATEGORY:=Network - TITLE:=owsip using $(2) - VARIANT:=$(1) - DEPENDS:=+librt +libuci +libubox +pjsip-$(1) $(3) -endef - -Package/owsip-oss=$(call Package/owsip-template,oss,OSS,BROKEN) -Package/owsip-ltq-tapi=$(call Package/owsip-template,ltq-tapi,Lantiq VMMC,$(LTQ_TAPI_DEPENDS) +kmod-ltq-kpi2udp) - -define Package/owsip-$(BUILD_VARIANT)/description - OpenWrt sip daemon - $(BUILD_VARIANT) -endef - -USE_LOCAL=$(shell ls ./src/ 2>/dev/null >/dev/null && echo 1) -ifneq ($(USE_LOCAL),) -define Build/Prepare - $(CP) ./src/* $(PKG_BUILD_DIR)/ -endef -endif - -EXTRA_CFLAGS=-I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include \ - -I$(STAGING_DIR)/usr/pjsip-$(BUILD_VARIANT)/include -EXTRA_LDFLAGS=-L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/usr/pjsip-$(BUILD_VARIANT)/lib - -define Build/Compile - PKG_CONFIG_PATH=$(STAGING_DIR)/usr/pjsip-$(BUILD_VARIANT)/lib/pkgconfig \ - BACKEND=$(BUILD_VARIANT) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS="$(EXTRA_LDFLAGS)" $(MAKE) -C $(PKG_BUILD_DIR) $(TARGET_CONFIGURE_OPTS) -endef - -define Package/owsip-$(BUILD_VARIANT)/conffiles -/etc/config/telephony.conf -endef - -define Package/owsip-$(BUILD_VARIANT)/install - $(INSTALL_DIR) $(1)/usr/bin $(1)/etc/init.d $(1)/etc/config $(1)/etc/uci-defaults - $(INSTALL_BIN) $(PKG_BUILD_DIR)/owsip_ua $(1)/usr/bin - $(INSTALL_BIN) ./files/telephony.init $(1)/etc/init.d/telephony - $(INSTALL_DATA) ./files/telephony.conf $(1)/etc/config/telephony - $(INSTALL_DATA) ./files/telephony.defaults $(1)/etc/uci-defaults/telephony -endef - -$(eval $(call BuildPackage,owsip-oss)) -$(eval $(call BuildPackage,owsip-ltq-tapi)) diff --git a/extra/owsip/files/telephony.conf b/extra/owsip/files/telephony.conf deleted file mode 100644 index 7cc1e9f0f..000000000 --- a/extra/owsip/files/telephony.conf +++ /dev/null @@ -1,32 +0,0 @@ -config general general - option name owsip - option backend ltq_tapi - option ossdev 0 - option log_level 3 - option interface nas0 - option local_port 5060 - option rtp_port 4000 - option locale germany - -config stun stun - option host stun.myrealm.com - option port 3478 - -config account example1 - option realm myrealm1.com - option username myuser1 - option password mypass1 - option disabled 1 - -config account example2 - option realm myrealm2.com - option username myuser2 - option password mypass2 - option disabled 1 - -config contact - option desc "example contact description" - option code "example" - option dial "0123456789" - option type realm - diff --git a/extra/owsip/files/telephony.defaults b/extra/owsip/files/telephony.defaults deleted file mode 100755 index bec2878a0..000000000 --- a/extra/owsip/files/telephony.defaults +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2011 OpenWrt.org -# based on ar71xx -# - -COMMIT_TELEPHONY=0 - -set_relay() { - local cfg="relay_$1" - local gpio=$1 - local val=$2 - - uci -q get telephony.$cfg && return 0 - - uci batch < /sys/class/gpio/export - [ -f "/sys/class/gpio/gpio$gpio/direction" ] && { - echo "out" > /sys/class/gpio/gpio$gpio/direction - echo "$value" > /sys/class/gpio/gpio$gpio/value - } -} - -start() { - config_load telephony - config_foreach relay_set relay - service_start /usr/bin/owsip_ua -} - -stop() { - service_stop /usr/bin/owsip_ua -} diff --git a/extra/pjsip/Makefile b/extra/pjsip/Makefile deleted file mode 100644 index d2c6f6b88..000000000 --- a/extra/pjsip/Makefile +++ /dev/null @@ -1,101 +0,0 @@ -# -# Copyright (C) 2010-2012 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=pjsip -PKG_VERSION:=1.14.2 -PKG_RELEASE:=1 - -PKG_SOURCE:=pjproject-$(PKG_VERSION).tar.bz2 -PKG_SOURCE_URL:=http://www.pjsip.org/release/$(PKG_VERSION)/ -PKG_MD5SUM:=05428502384c16e7abd85f047e6e2f6c - -PKG_INSTALL:=1 -PKG_BUILD_PARALLEL:=1 - -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/pjproject-$(PKG_VERSION) - -include $(INCLUDE_DIR)/ltqtapi.mk -PKG_BUILD_DEPENDS:=$(LTQ_TAPI_BUILD_DEPENDS) - -include $(INCLUDE_DIR)/package.mk - -define Package/pjsip-template - SECTION:=lib - CATEGORY:=Libraries - URL:=http://www.pjsip.org/ - MAINTAINER:=John Crispin - TITLE:=pjsip-$(1) - VARIANT:=$(1) - DEPENDS:=+libuuid $(2) -endef - -CONFIGURE_PREFIX=/usr/pjsip-$(BUILD_VARIANT) - -ifeq ($(BUILD_VARIANT),oss) -CONFIGURE_ARGS += \ - --disable-floating-point \ - --enable-g711-codec \ - --disable-l16-codec \ - --disable-g722-codec \ - --disable-g7221-codec \ - --disable-gsm-codec \ - --disable-ilbc-coder \ - --disable-libsamplerate \ - --disable-ipp \ - --disable-ssl \ - --enable-oss \ - --enable-sound -endif - -ifeq ($(BUILD_VARIANT),ltq-tapi) -CONFIGURE_ARGS += \ - --disable-floating-point \ - --enable-g711-codec \ - --disable-l16-codec \ - --disable-g722-codec \ - --disable-g7221-codec \ - --disable-ilbc-coder \ - --disable-gsm-codec \ - --disable-libsamplerate \ - --disable-ipp \ - --disable-ssl \ - --enable-sound \ - --enable-ltq-tapi -EXTRA_CFLAGS:=-I$(STAGING_DIR)/usr/include/drv_tapi -I$(STAGING_DIR)/usr/include/drv_vmmc -endif - -Package/pjsip-oss=$(call Package/pjsip-template,oss,BROKEN) -Package/pjsip-ltq-tapi=$(call Package/pjsip-template,ltq-tapi,$(LTQ_TAPI_DEPENDS)) - -USE_LOCAL=$(shell ls ./src/ 2>/dev/null >/dev/null && echo 1) -ifneq ($(USE_LOCAL),) -define Build/Prepare - $(CP) ./src/* $(PKG_BUILD_DIR) -endef -endif - -define Build/Configure - (cd $(PKG_BUILD_DIR); autoconf aconfigure.ac > aconfigure) - $(call Build/Configure/Default) -endef - -define Build/Compile - +CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \ - CXXFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \ - LDFLAGS="$(TARGET_LDFLAGS) -lc $(LIBGCC_S) -lm" \ - $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(MAKE_PATH) -endef - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr - $(CP) $(PKG_INSTALL_DIR)/usr/pjsip-$(BUILD_VARIANT) $(1)/usr -endef - -$(eval $(call BuildPackage,pjsip-oss)) -$(eval $(call BuildPackage,pjsip-ltq-tapi)) diff --git a/extra/pjsip/patches/0001-configure-fixup.patch b/extra/pjsip/patches/0001-configure-fixup.patch deleted file mode 100644 index 5fcf911c3..000000000 --- a/extra/pjsip/patches/0001-configure-fixup.patch +++ /dev/null @@ -1,78 +0,0 @@ -Index: pjproject-1.14.2/aconfigure.ac -=================================================================== ---- pjproject-1.14.2.orig/aconfigure.ac 2012-04-27 03:22:15.000000000 +0200 -+++ pjproject-1.14.2/aconfigure.ac 2012-08-13 14:42:33.204641678 +0200 -@@ -48,9 +48,8 @@ - CROSS_COMPILE=`echo ${CC} | sed 's/gcc//'` - fi - --if test "$AR" = ""; then AR="${CROSS_COMPILE}ar rv"; fi -+AR="${AR} rv" - AC_SUBST(AR) --if test "$LD" = ""; then LD="$CC"; fi - AC_SUBST(LD) - if test "$LDOUT" = ""; then LDOUT="-o "; fi - AC_SUBST(LDOUT) -@@ -584,13 +583,7 @@ - ;; - *) - dnl # Check if ALSA is available -- ac_pjmedia_snd=pa_unix -- AC_CHECK_HEADER(alsa/version.h, -- [AC_SUBST(ac_pa_use_alsa,1) -- LIBS="$LIBS -lasound" -- ], -- [AC_SUBST(ac_pa_use_alsa,0)]) -- AC_MSG_RESULT([Checking sound device backend... unix]) -+ AC_SUBST(ac_pa_use_alsa,0) - - dnl # Check if OSS is disabled - AC_SUBST(ac_pa_use_oss,1) -@@ -617,6 +610,15 @@ - fi] - ) - -+AC_ARG_ENABLE(ltq_tapi, -+ AC_HELP_STRING([--enable-ltq-tapi], -+ [PJMEDIA will use ltq tapi backend]), -+ [if test "$enable_ltq_tapi" = "yes"; then -+ [ac_pjmedia_snd=ltqtapi] -+ AC_MSG_RESULT([Checking if external sound is set... yes]) -+ fi] -+ ) -+ - dnl # Include resampling small filter - AC_SUBST(ac_no_small_filter) - AC_ARG_ENABLE(small-filter, -@@ -737,14 +739,6 @@ - AC_MSG_RESULT([Checking if iLBC codec is disabled...no])) - - dnl # Include libsamplerate --AC_ARG_ENABLE(libsamplerate, -- AC_HELP_STRING([--enable-libsamplerate], -- [Link with libsamplerate when available. Note that PJMEDIA_RESAMPLE_IMP must also be configured]), -- [ AC_CHECK_LIB(samplerate,src_new) ], -- AC_MSG_RESULT([Skipping libsamplerate detection]) -- ) -- --dnl # Include libsamplerate - AC_SUBST(ac_resample_dll) - AC_ARG_ENABLE(resample_dll, - AC_HELP_STRING([--enable-resample-dll], -Index: pjproject-1.14.2/pjmedia/build/os-auto.mak.in -=================================================================== ---- pjproject-1.14.2.orig/pjmedia/build/os-auto.mak.in 2011-10-14 06:15:15.000000000 +0200 -+++ pjproject-1.14.2/pjmedia/build/os-auto.mak.in 2012-08-13 14:40:47.680637171 +0200 -@@ -125,4 +125,11 @@ - export CFLAGS += -DPJMEDIA_AUDIO_DEV_HAS_PORTAUDIO=0 -DPJMEDIA_AUDIO_DEV_HAS_WMME=0 - endif - -- -+# -+# Lantiq tapi backend -+# -+ifeq ($(AC_PJMEDIA_SND),ltqtapi) -+export CFLAGS += -DPJMEDIA_AUDIO_DEV_HAS_PORTAUDIO=0 -DPJMEDIA_AUDIO_DEV_HAS_WMME=0 -+export PJMEDIA_AUDIODEV_OBJS += tapi_dev.o -+export CFLAGS += -DPJMEDIA_AUDIO_DEV_HAS_TAPI_DEVICE=1 -+endif diff --git a/extra/pjsip/patches/0002-register-tapi.patch b/extra/pjsip/patches/0002-register-tapi.patch deleted file mode 100644 index 4363bc7ff..000000000 --- a/extra/pjsip/patches/0002-register-tapi.patch +++ /dev/null @@ -1,1333 +0,0 @@ ---- a/pjmedia/src/pjmedia-audiodev/audiodev.c -+++ b/pjmedia/src/pjmedia-audiodev/audiodev.c -@@ -98,6 +98,10 @@ pjmedia_aud_dev_factory* pjmedia_symb_md - pjmedia_aud_dev_factory* pjmedia_null_audio_factory(pj_pool_factory *pf); - #endif - -+#if PJMEDIA_AUDIO_DEV_HAS_TAPI_DEVICE -+pjmedia_aud_dev_factory* pjmedia_tapi_factory(pj_pool_factory *pf); -+#endif -+ - #define MAX_DRIVERS 16 - #define MAX_DEVS 64 - -@@ -409,6 +413,9 @@ PJ_DEF(pj_status_t) pjmedia_aud_subsys_i - #if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO - aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_null_audio_factory; - #endif -+#if PJMEDIA_AUDIO_DEV_HAS_TAPI_DEVICE -+ aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_tapi_factory; -+#endif - - /* Initialize each factory and build the device ID list */ - for (i=0; i -+#include -+#include -+#include -+#include -+#include -+ -+#if defined(PJMEDIA_AUDIO_DEV_HAS_TAPI_DEVICE) && PJMEDIA_AUDIO_DEV_HAS_TAPI_DEVICE -+ -+/* Linux includes */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* TAPI includes */ -+#include "drv_tapi_io.h" -+#include "vmmc_io.h" -+ -+/* Maximum 2 devices */ -+#define TAPI_AUDIO_PORT_NUM 2 -+#define TAPI_BASE_NAME "TAPI" -+#define TAPI_LL_DEV_BASE_PATH "/dev/vmmc" -+#define TAPI_LL_DEV_FIRMWARE_NAME "/lib/firmware/danube_firmware.bin" -+#define TAPI_LL_BBD_NAME "/lib/firmware/danube_bbd_fxs.bin" -+ -+#define TAPI_LL_DEV_SELECT_TIMEOUT_MS 2000 -+#define TAPI_LL_DEV_MAX_PACKET_SIZE 800 -+#define TAPI_LL_DEV_RTP_HEADER_SIZE_BYTE 12 -+#define TAPI_LL_DEV_ENC_FRAME_LEN_MS 20 -+#define TAPI_LL_DEV_ENC_SMPL_PER_SEC 8000 -+#define TAPI_LL_DEV_ENC_BITS_PER_SMPLS 16 -+#define TAPI_LL_DEV_ENC_SMPL_PER_FRAME 160 -+#define TAPI_LL_DEV_ENC_BYTES_PER_FRAME (TAPI_LL_DEV_ENC_SMPL_PER_FRAME * (TAPI_LL_DEV_ENC_BITS_PER_SMPLS / 8)) -+ -+#define THIS_FILE "tapi_dev.c" -+ -+/* Set to 1 to enable tracing */ -+#if 1 -+# define TRACE_(expr) PJ_LOG(1,expr) -+#else -+# define TRACE_(expr) -+#endif -+ -+pj_int32_t ch_fd[TAPI_AUDIO_PORT_NUM]; -+ -+typedef struct -+{ -+ pj_int32_t dev_fd; -+ pj_int32_t ch_fd[TAPI_AUDIO_PORT_NUM]; -+ pj_int8_t data2phone_map[TAPI_AUDIO_PORT_NUM]; -+} tapi_ctx; -+ -+struct tapi_aud_factory -+{ -+ pjmedia_aud_dev_factory base; -+ pj_pool_t *pool; -+ pj_pool_factory *pf; -+ pj_uint32_t dev_count; -+ pjmedia_aud_dev_info *dev_info; -+ tapi_ctx dev_ctx; -+}; -+ -+typedef struct tapi_aud_factory tapi_aud_factory_t; -+ -+struct tapi_aud_stream -+{ -+ pjmedia_aud_stream base; -+ pj_pool_t *pool; -+ pjmedia_aud_param param; -+ pjmedia_aud_rec_cb rec_cb; -+ pjmedia_aud_play_cb play_cb; -+ void *user_data; -+ -+ pj_thread_desc thread_desc; -+ pj_thread_t *thread; -+ tapi_ctx *dev_ctx; -+ pj_uint8_t run_flag; -+ pj_timestamp timestamp; -+}; -+ -+typedef struct tapi_aud_stream tapi_aud_stream_t; -+ -+/* Factory prototypes */ -+static pj_status_t factory_init(pjmedia_aud_dev_factory *f); -+static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f); -+static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f); -+static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, -+ unsigned index, -+ pjmedia_aud_dev_info *info); -+static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f, -+ unsigned index, -+ pjmedia_aud_param *param); -+static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f, -+ const pjmedia_aud_param *param, -+ pjmedia_aud_rec_cb rec_cb, -+ pjmedia_aud_play_cb play_cb, -+ void *user_data, -+ pjmedia_aud_stream **p_aud_strm); -+ -+/* Stream prototypes */ -+static pj_status_t stream_get_param(pjmedia_aud_stream *strm, -+ pjmedia_aud_param *param); -+static pj_status_t stream_get_cap(pjmedia_aud_stream *strm, -+ pjmedia_aud_dev_cap cap, -+ void *value); -+static pj_status_t stream_set_cap(pjmedia_aud_stream *strm, -+ pjmedia_aud_dev_cap cap, -+ const void *value); -+static pj_status_t stream_start(pjmedia_aud_stream *strm); -+static pj_status_t stream_stop(pjmedia_aud_stream *strm); -+static pj_status_t stream_destroy(pjmedia_aud_stream *strm); -+ -+static pjmedia_aud_dev_factory_op tapi_fact_op = -+{ -+ &factory_init, -+ &factory_destroy, -+ &factory_get_dev_count, -+ &factory_get_dev_info, -+ &factory_default_param, -+ &factory_create_stream -+}; -+ -+static pjmedia_aud_stream_op tapi_strm_op = -+{ -+ &stream_get_param, -+ &stream_get_cap, -+ &stream_set_cap, -+ &stream_start, -+ &stream_stop, -+ &stream_destroy -+}; -+ -+/* TAPI configuration */ -+static struct tapi_aud_stream streams[TAPI_AUDIO_PORT_NUM]; -+ -+void (*tapi_digit_callback)(pj_uint8_t port, pj_uint8_t digit) = NULL; -+void (*tapi_hook_callback)(pj_uint8_t port, pj_uint8_t event) = NULL; -+ -+#define TAPI_TONE_LOCALE_NONE 32 -+#define TAPI_TONE_LOCALE_BUSY_CODE 33 -+#define TAPI_TONE_LOCALE_CONGESTION_CODE 34 -+#define TAPI_TONE_LOCALE_DIAL_CODE 35 -+#define TAPI_TONE_LOCALE_RING_CODE 36 -+#define TAPI_TONE_LOCALE_WAITING_CODE 37 -+ -+static pj_uint8_t tapi_channel_revert = 0; -+static pj_uint8_t tapi_cid_type = 0; -+static pj_uint8_t tapi_locale = 0; -+ -+void tapi_revert_channels(void) -+{ -+ tapi_channel_revert = 1; -+ PJ_LOG(3, (THIS_FILE, "using reverted configuration for TAPI channels")); -+} -+ -+void tapi_cid_select(char *cid) -+{ -+ if (!stricmp(cid, "telecordia")) { -+ tapi_cid_type = IFX_TAPI_CID_STD_TELCORDIA; -+ PJ_LOG(3, (THIS_FILE, "using TELECORDIA configuration for TAPI CID")); -+ } else if (!stricmp(cid, "etsi_fsk")) { -+ tapi_cid_type = IFX_TAPI_CID_STD_ETSI_FSK; -+ PJ_LOG(3, (THIS_FILE, "using ETSI FSK configuration for TAPI CID")); -+ } else if (!stricmp(cid, "etsi_dtmf")) { -+ tapi_cid_type = IFX_TAPI_CID_STD_ETSI_DTMF; -+ PJ_LOG(3, (THIS_FILE, "using ETSI DTMF configuration for TAPI CID")); -+ } else if (!stricmp(cid, "sin")) { -+ tapi_cid_type = IFX_TAPI_CID_STD_SIN; -+ PJ_LOG(3, (THIS_FILE, "using SIN CID configuration for TAPI CID")); -+ } else if (!stricmp(cid, "ntt")) { -+ tapi_cid_type = IFX_TAPI_CID_STD_NTT; -+ PJ_LOG(3, (THIS_FILE, "using NTT configuration for TAPI CID")); -+ } else if (!stricmp(cid, "kpn_dtmf")) { -+ tapi_cid_type = IFX_TAPI_CID_STD_KPN_DTMF; -+ PJ_LOG(3, (THIS_FILE, "using KPN DTMF configuration for TAPI CID")); -+ } else if (!stricmp(cid, "kpn_dtmf_fsk")) { -+ tapi_cid_type = IFX_TAPI_CID_STD_KPN_DTMF_FSK; -+ PJ_LOG(3, (THIS_FILE, "using KPN DTMF FSK configuration for TAPI CID")); -+ } -+} -+ -+void tapi_locale_select(char *country) -+{ -+ IFX_TAPI_TONE_t tone; -+ pj_status_t status; -+ pj_uint8_t c; -+ -+ tapi_locale = 1; -+ -+ if (!stricmp(country, "croatia")) { -+ PJ_LOG(3, (THIS_FILE, "using localized tones for Croatia")); -+ -+ memset(&tone, 0, sizeof(IFX_TAPI_TONE_t)); -+ tone.simple.format = IFX_TAPI_TONE_TYPE_SIMPLE; -+ tone.simple.index = TAPI_TONE_LOCALE_BUSY_CODE; -+ tone.simple.freqA = 425; -+ tone.simple.levelA = 0; -+ tone.simple.cadence[0] = 500; -+ tone.simple.cadence[1] = 500; -+ tone.simple.frequencies[0] = IFX_TAPI_TONE_FREQA; -+ tone.simple.frequencies[1] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.loop = 0; -+ tone.simple.pause = 0; -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ status = ioctl(ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "IFX_TAPI_TONE_TABLE_CFG_SET failed!\n")); -+ } -+ -+ memset(&tone, 0, sizeof(IFX_TAPI_TONE_t)); -+ tone.simple.format = IFX_TAPI_TONE_TYPE_SIMPLE; -+ tone.simple.index = TAPI_TONE_LOCALE_CONGESTION_CODE; -+ tone.simple.freqA = 425; -+ tone.simple.levelA = 0; -+ tone.simple.cadence[0] = 250; -+ tone.simple.cadence[1] = 250; -+ tone.simple.frequencies[0] = IFX_TAPI_TONE_FREQA; -+ tone.simple.frequencies[1] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.loop = 0; -+ tone.simple.pause = 0; -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ status = ioctl(ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "IFX_TAPI_TONE_TABLE_CFG_SET failed!\n")); -+ } -+ -+ memset(&tone, 0, sizeof(IFX_TAPI_TONE_t)); -+ tone.simple.format = IFX_TAPI_TONE_TYPE_SIMPLE; -+ tone.simple.index = TAPI_TONE_LOCALE_DIAL_CODE; -+ tone.simple.freqA = 425; -+ tone.simple.levelA = 0; -+ tone.simple.cadence[0] = 200; -+ tone.simple.cadence[1] = 300; -+ tone.simple.cadence[2] = 700; -+ tone.simple.cadence[3] = 800; -+ tone.simple.frequencies[0] = IFX_TAPI_TONE_FREQA; -+ tone.simple.frequencies[1] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.frequencies[2] = IFX_TAPI_TONE_FREQA; -+ tone.simple.frequencies[3] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.loop = 0; -+ tone.simple.pause = 0; -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ status = ioctl(ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "IFX_TAPI_TONE_TABLE_CFG_SET failed!\n")); -+ } -+ -+ memset(&tone, 0, sizeof(IFX_TAPI_TONE_t)); -+ tone.simple.format = IFX_TAPI_TONE_TYPE_SIMPLE; -+ tone.simple.index = TAPI_TONE_LOCALE_RING_CODE; -+ tone.simple.freqA = 425; -+ tone.simple.levelA = 0; -+ tone.simple.cadence[0] = 1000; -+ tone.simple.cadence[1] = 4000; -+ tone.simple.frequencies[0] = IFX_TAPI_TONE_FREQA; -+ tone.simple.frequencies[1] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.loop = 0; -+ tone.simple.pause = 0; -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ status = ioctl(ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "IFX_TAPI_TONE_TABLE_CFG_SET failed!\n")); -+ } -+ -+ memset(&tone, 0, sizeof(IFX_TAPI_TONE_t)); -+ tone.simple.format = IFX_TAPI_TONE_TYPE_SIMPLE; -+ tone.simple.index = TAPI_TONE_LOCALE_WAITING_CODE; -+ tone.simple.freqA = 425; -+ tone.simple.levelA = 0; -+ tone.simple.cadence[0] = 300; -+ tone.simple.cadence[1] = 8000; -+ tone.simple.frequencies[0] = IFX_TAPI_TONE_FREQA; -+ tone.simple.frequencies[1] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.loop = 0; -+ tone.simple.pause = 0; -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ status = ioctl(ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "IFX_TAPI_TONE_TABLE_CFG_SET failed!\n")); -+ } -+ } else if (!stricmp(country, "germany")) { -+ PJ_LOG(3, (THIS_FILE, "using localized tones for Germany")); -+ -+ memset(&tone, 0, sizeof(IFX_TAPI_TONE_t)); -+ tone.simple.format = IFX_TAPI_TONE_TYPE_SIMPLE; -+ tone.simple.index = TAPI_TONE_LOCALE_BUSY_CODE; -+ tone.simple.freqA = 425; -+ tone.simple.levelA = 0; -+ tone.simple.cadence[0] = 480; -+ tone.simple.cadence[1] = 480; -+ tone.simple.frequencies[0] = IFX_TAPI_TONE_FREQA; -+ tone.simple.frequencies[1] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.loop = 0; -+ tone.simple.pause = 0; -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ status = ioctl(ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "IFX_TAPI_TONE_TABLE_CFG_SET failed!\n")); -+ } -+ -+ memset(&tone, 0, sizeof(IFX_TAPI_TONE_t)); -+ tone.simple.format = IFX_TAPI_TONE_TYPE_SIMPLE; -+ tone.simple.index = TAPI_TONE_LOCALE_CONGESTION_CODE; -+ tone.simple.freqA = 425; -+ tone.simple.levelA = 0; -+ tone.simple.cadence[0] = 240; -+ tone.simple.cadence[1] = 240; -+ tone.simple.frequencies[0] = IFX_TAPI_TONE_FREQA; -+ tone.simple.frequencies[1] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.loop = 0; -+ tone.simple.pause = 0; -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ status = ioctl(ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "IFX_TAPI_TONE_TABLE_CFG_SET failed!\n")); -+ } -+ -+ memset(&tone, 0, sizeof(IFX_TAPI_TONE_t)); -+ tone.simple.format = IFX_TAPI_TONE_TYPE_SIMPLE; -+ tone.simple.index = TAPI_TONE_LOCALE_DIAL_CODE; -+ tone.simple.freqA = 425; -+ tone.simple.levelA = 0; -+ tone.simple.cadence[0] = 1000; -+ tone.simple.frequencies[0] = IFX_TAPI_TONE_FREQA; -+ tone.simple.loop = 0; -+ tone.simple.pause = 0; -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ status = ioctl(ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "IFX_TAPI_TONE_TABLE_CFG_SET failed!\n")); -+ } -+ -+ memset(&tone, 0, sizeof(IFX_TAPI_TONE_t)); -+ tone.simple.format = IFX_TAPI_TONE_TYPE_SIMPLE; -+ tone.simple.index = TAPI_TONE_LOCALE_RING_CODE; -+ tone.simple.freqA = 425; -+ tone.simple.levelA = 0; -+ tone.simple.cadence[0] = 1000; -+ tone.simple.cadence[1] = 4000; -+ tone.simple.frequencies[0] = IFX_TAPI_TONE_FREQA; -+ tone.simple.frequencies[1] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.loop = 0; -+ tone.simple.pause = 0; -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ status = ioctl(ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "IFX_TAPI_TONE_TABLE_CFG_SET failed!\n")); -+ } -+ -+ memset(&tone, 0, sizeof(IFX_TAPI_TONE_t)); -+ tone.simple.format = IFX_TAPI_TONE_TYPE_SIMPLE; -+ tone.simple.index = TAPI_TONE_LOCALE_WAITING_CODE; -+ tone.simple.freqA = 425; -+ tone.simple.levelA = 0; -+ tone.simple.cadence[0] = 200; -+ tone.simple.cadence[1] = 200; -+ tone.simple.cadence[2] = 200; -+ tone.simple.cadence[3] = 5000; -+ tone.simple.frequencies[0] = IFX_TAPI_TONE_FREQA; -+ tone.simple.frequencies[1] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.frequencies[2] = IFX_TAPI_TONE_FREQA; -+ tone.simple.frequencies[3] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.loop = 0; -+ tone.simple.pause = 0; -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ status = ioctl(ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "IFX_TAPI_TONE_TABLE_CFG_SET failed!\n")); -+ } -+ } -+} -+ -+static pj_int32_t -+tapi_dev_open(char* dev_path, const pj_int32_t ch_num) -+{ -+ char devname[128] = { 0 }; -+ pj_ansi_sprintf(devname,"%s%u%u", dev_path, 1, ch_num); -+ return open((const char*)devname, O_RDWR, 0644); -+} -+ -+static pj_status_t -+tapi_dev_binary_buffer_create(const char *pPath, pj_uint8_t **ppBuf, pj_uint32_t *pBufSz) -+{ -+ pj_status_t status = PJ_SUCCESS; -+ FILE *fd; -+ struct stat file_stat; -+ -+ fd = fopen(pPath, "rb"); -+ if (fd == NULL) { -+ TRACE_((THIS_FILE, "ERROR - binary file %s open failed!\n", pPath)); -+ return PJ_EUNKNOWN; -+ } -+ -+ if (stat(pPath, &file_stat) != 0) { -+ TRACE_((THIS_FILE, "ERROR - file %s statistics get failed!\n", pPath)); -+ return PJ_EUNKNOWN; -+ } -+ -+ *ppBuf = malloc(file_stat.st_size); -+ if (*ppBuf == NULL) { -+ TRACE_((THIS_FILE, "ERROR - binary file %s memory allocation failed!\n", pPath)); -+ status = PJ_EUNKNOWN; -+ goto on_exit; -+ } -+ -+ if (fread (*ppBuf, sizeof(pj_uint8_t), file_stat.st_size, fd) <= 0) { -+ TRACE_((THIS_FILE, "ERROR - file %s read failed!\n", pPath)); -+ status = PJ_EUNKNOWN; -+ goto on_exit; -+ } -+ -+ *pBufSz = file_stat.st_size; -+ -+on_exit: -+ if (fd != NULL) -+ fclose(fd); -+ -+ if (*ppBuf != NULL && status != PJ_SUCCESS) -+ free(*ppBuf); -+ -+ return status; -+} -+ -+static void -+tapi_dev_binary_buffer_delete(pj_uint8_t *pBuf) -+{ -+ if (pBuf != NULL) -+ free(pBuf); -+} -+ -+static pj_status_t -+tapi_dev_firmware_download(pj_int32_t fd, const char *pPath) -+{ -+ pj_status_t status = PJ_SUCCESS; -+ pj_uint8_t *pFirmware = NULL; -+ pj_uint32_t binSz = 0; -+ VMMC_IO_INIT vmmc_io_init; -+ -+ status = tapi_dev_binary_buffer_create(pPath, &pFirmware, &binSz); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - binary buffer create failed!\n")); -+ return PJ_EUNKNOWN; -+ } -+ -+ memset(&vmmc_io_init, 0, sizeof(VMMC_IO_INIT)); -+ vmmc_io_init.pPRAMfw = pFirmware; -+ vmmc_io_init.pram_size = binSz; -+ -+ status = ioctl(fd, FIO_FW_DOWNLOAD, &vmmc_io_init); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "ERROR - FIO_FW_DOWNLOAD ioctl failed!")); -+ -+ tapi_dev_binary_buffer_delete(pFirmware); -+ -+ return status; -+} -+ -+/* NOT USED */ -+#if 0 -+static int -+tapi_dev_bbd_download(int fd, const char *pPath) -+{ -+ int status = PJ_SUCCESS; -+ unsigned char *pFirmware = NULL; -+ unsigned int binSz = 0; -+ VMMC_DWLD_t bbd_data; -+ -+ -+ /* Create binary buffer */ -+ status = tapi_dev_binary_buffer_create(pPath, &pFirmware, &binSz); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - binary buffer create failed!\n")); -+ return status; -+ } -+ -+ /* Download Voice Firmware */ -+ memset(&bbd_data, 0, sizeof(VMMC_DWLD_t)); -+ bbd_data.buf = pFirmware; -+ bbd_data.size = binSz; -+ -+ status = ioctl(fd, FIO_BBD_DOWNLOAD, &bbd_data); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - FIO_BBD_DOWNLOAD failed!\n")); -+ } -+ -+ /* Delete binary buffer */ -+ tapi_dev_binary_buffer_delete(pFirmware); -+ -+ return status; -+} -+#endif -+ -+static pj_status_t tapi_dev_start(tapi_aud_factory_t *f) -+{ -+ pj_uint8_t c, hook_status; -+ IFX_TAPI_TONE_t tone; -+ IFX_TAPI_DEV_START_CFG_t tapistart; -+ IFX_TAPI_MAP_DATA_t datamap; -+ IFX_TAPI_ENC_CFG_t enc_cfg; -+ IFX_TAPI_LINE_VOLUME_t line_vol; -+ IFX_TAPI_WLEC_CFG_t lec_cfg; -+ IFX_TAPI_JB_CFG_t jb_cfg; -+ IFX_TAPI_CID_CFG_t cid_cfg; -+ pj_status_t status; -+ -+ /* Open device */ -+ f->dev_ctx.dev_fd = tapi_dev_open(TAPI_LL_DEV_BASE_PATH, 0); -+ -+ if (f->dev_ctx.dev_fd < 0) { -+ TRACE_((THIS_FILE, "ERROR - TAPI device open failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ if (tapi_channel_revert) -+ ch_fd[c] = f->dev_ctx.ch_fd[c] = tapi_dev_open(TAPI_LL_DEV_BASE_PATH, c + 1); -+ else -+ ch_fd[c] = f->dev_ctx.ch_fd[c] = tapi_dev_open(TAPI_LL_DEV_BASE_PATH, TAPI_AUDIO_PORT_NUM - c); -+ -+ if (f->dev_ctx.dev_fd < 0) { -+ TRACE_((THIS_FILE, "ERROR - TAPI channel%d open failed!", c)); -+ return PJ_EUNKNOWN; -+ } -+ if (tapi_channel_revert) -+ f->dev_ctx.data2phone_map[c] = c & 0x1 ? 1 : 0; -+ else -+ f->dev_ctx.data2phone_map[c] = c & 0x1 ? 0 : 1; -+ } -+ -+ status = tapi_dev_firmware_download(f->dev_ctx.dev_fd, TAPI_LL_DEV_FIRMWARE_NAME); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - Voice Firmware Download failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ /* Download coefficients */ -+ /* -+ status = tapi_dev_bbd_download(f->dev_ctx.dev_fd, TAPI_LL_BBD_NAME); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - Voice Coefficients Download failed!")); -+ return PJ_EUNKNOWN; -+ } -+ */ -+ -+ memset(&tapistart, 0x0, sizeof(IFX_TAPI_DEV_START_CFG_t)); -+ tapistart.nMode = IFX_TAPI_INIT_MODE_VOICE_CODER; -+ -+ /* Start TAPI */ -+ status = ioctl(f->dev_ctx.dev_fd, IFX_TAPI_DEV_START, &tapistart); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEV_START ioctl failed")); -+ return PJ_EUNKNOWN; -+ } -+ -+ -+ /* OpenWrt default tone */ -+ memset(&tone, 0, sizeof(IFX_TAPI_TONE_t)); -+ tone.simple.format = IFX_TAPI_TONE_TYPE_SIMPLE; -+ tone.simple.index = TAPI_TONE_LOCALE_NONE; -+ tone.simple.freqA = 400; -+ tone.simple.levelA = 0; -+ tone.simple.freqB = 450; -+ tone.simple.levelB = 0; -+ tone.simple.freqC = 550; -+ tone.simple.levelC = 0; -+ tone.simple.freqD = 600; -+ tone.simple.levelD = 0; -+ tone.simple.cadence[0] = 100; -+ tone.simple.cadence[1] = 150; -+ tone.simple.cadence[2] = 100; -+ tone.simple.cadence[3] = 150; -+ tone.simple.frequencies[0] = IFX_TAPI_TONE_FREQA | IFX_TAPI_TONE_FREQB; -+ tone.simple.frequencies[1] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.frequencies[2] = IFX_TAPI_TONE_FREQC | IFX_TAPI_TONE_FREQD; -+ tone.simple.frequencies[3] = IFX_TAPI_TONE_FREQNONE; -+ tone.simple.loop = 0; -+ tone.simple.pause = 0; -+ for (c = 0; c < TAPI_AUDIO_PORT_NUM; c++) { -+ /* OpenWrt default tone */ -+ status = ioctl(ch_fd[c], IFX_TAPI_TONE_TABLE_CFG_SET, &tone); -+ if (status != PJ_SUCCESS) -+ TRACE_((THIS_FILE, "IFX_TAPI_TONE_TABLE_CFG_SET failed!\n")); -+ -+ /* Perform mapping */ -+ memset(&datamap, 0x0, sizeof(IFX_TAPI_MAP_DATA_t)); -+ datamap.nDstCh = f->dev_ctx.data2phone_map[c]; -+ datamap.nChType = IFX_TAPI_MAP_TYPE_PHONE; -+ -+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_MAP_DATA_ADD, &datamap); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_MAP_DATA_ADD ioctl failed")); -+ return PJ_EUNKNOWN; -+ } -+ -+ /* Set Line feed */ -+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_STANDBY); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed")); -+ return PJ_EUNKNOWN; -+ } -+ -+ /* Configure encoder for linear stream */ -+ memset(&enc_cfg, 0x0, sizeof(IFX_TAPI_ENC_CFG_t)); -+ enc_cfg.nFrameLen = IFX_TAPI_COD_LENGTH_20; -+ enc_cfg.nEncType = IFX_TAPI_COD_TYPE_LIN16_8; -+ -+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_ENC_CFG_SET, &enc_cfg); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_ENC_CFG_SET ioctl failed")); -+ return PJ_EUNKNOWN; -+ } -+ -+ /* Suppress TAPI volume, otherwise PJSIP starts autogeneration */ -+ memset(&line_vol, 0, sizeof(line_vol)); -+ line_vol.nGainRx = -8; -+ line_vol.nGainTx = -8; -+ -+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_PHONE_VOLUME_SET, &line_vol); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_PHONE_VOLUME_SET ioctl failed")); -+ return PJ_EUNKNOWN; -+ } -+ -+ /* Configure line echo canceller */ -+ memset(&lec_cfg, 0, sizeof(lec_cfg)); -+ lec_cfg.nType = IFX_TAPI_WLEC_TYPE_NFE; -+ lec_cfg.bNlp = IFX_TAPI_LEC_NLP_OFF; -+ -+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_WLEC_PHONE_CFG_SET, &lec_cfg); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_WLEC_PHONE_CFG_SET ioctl failed")); -+ return PJ_EUNKNOWN; -+ } -+ -+ /* Configure jitter buffer */ -+ memset(&jb_cfg, 0, sizeof(jb_cfg)); -+ jb_cfg.nJbType = IFX_TAPI_JB_TYPE_ADAPTIVE; -+ jb_cfg.nPckAdpt = IFX_TAPI_JB_PKT_ADAPT_VOICE; -+ jb_cfg.nLocalAdpt = IFX_TAPI_JB_LOCAL_ADAPT_ON; -+ jb_cfg.nScaling = 0x10; -+ jb_cfg.nInitialSize = 0x2d0; -+ jb_cfg.nMinSize = 0x50; -+ jb_cfg.nMaxSize = 0x5a0; -+ -+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_JB_CFG_SET, &jb_cfg); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_JB_CFG_SET ioctl failed")); -+ return PJ_EUNKNOWN; -+ } -+ -+ /* Configure Caller ID type */ -+ if (tapi_cid_type) { -+ memset(&cid_cfg, 0, sizeof(cid_cfg)); -+ cid_cfg.nStandard = tapi_cid_type; -+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_CID_CFG_SET, &cid_cfg); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_CID_CFG_SET ioctl failed")); -+ return PJ_EUNKNOWN; -+ } -+ } -+ -+ /* check hook status */ -+ hook_status = 0; -+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_LINE_HOOK_STATUS_GET, &hook_status); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_HOOK_STATUS_GET ioctl failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ /* if off hook do initialization */ -+ if (hook_status) { -+ status = ioctl(f->dev_ctx.ch_fd[c], IFX_TAPI_LINE_FEED_SET, IFX_TAPI_LINE_FEED_ACTIVE); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed!")); -+ return PJ_EUNKNOWN; -+ } -+ status = ioctl(c, IFX_TAPI_ENC_START, 0); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_ENC_START ioctl failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ status = ioctl(c, IFX_TAPI_DEC_START, 0); -+ if (status != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEC_START ioctl failed!")); -+ return PJ_EUNKNOWN; -+ } -+ } -+ } -+ -+ return status; -+} -+ -+static pj_status_t -+tapi_dev_stop(tapi_aud_factory_t *f) -+{ -+ pj_status_t status = PJ_SUCCESS; -+ pj_uint8_t c; -+ -+ if (ioctl(f->dev_ctx.dev_fd, IFX_TAPI_DEV_STOP, 0) != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEV_STOP ioctl failed")); -+ status = PJ_EUNKNOWN; -+ } -+ -+ close(f->dev_ctx.dev_fd); -+ for (c = TAPI_AUDIO_PORT_NUM; c > 0; c--) -+ close(f->dev_ctx.ch_fd[TAPI_AUDIO_PORT_NUM-c]); -+ -+ return status; -+} -+ -+static pj_status_t -+tapi_dev_codec_control(pj_int32_t fd, pj_uint8_t start) -+{ -+ if (ioctl(fd, start ? IFX_TAPI_ENC_START : IFX_TAPI_ENC_STOP, 0) != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_ENC_%s ioctl failed!", -+ start ? "START" : "STOP")); -+ return PJ_EUNKNOWN; -+ } -+ -+ if (ioctl(fd, start ? IFX_TAPI_DEC_START : IFX_TAPI_DEC_STOP, 0) != IFX_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_DEC_%s ioctl failed!", -+ start ? "START" : "STOP")); -+ return PJ_EUNKNOWN; -+ } -+ -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t tapi_dev_event_on_hook(tapi_ctx *dev_ctx, pj_uint32_t dev_idx) -+{ -+ PJ_LOG(1,(THIS_FILE, "TAPI: ONHOOK")); -+ -+ if (ioctl(dev_ctx->ch_fd[dev_idx], IFX_TAPI_LINE_FEED_SET, -+ IFX_TAPI_LINE_FEED_STANDBY) != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ /* enc/dec stop */ -+ if (tapi_dev_codec_control(dev_ctx->ch_fd[dev_idx], 0) != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - codec start failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t tapi_dev_event_off_hook(tapi_ctx *dev_ctx, pj_uint32_t dev_idx) -+{ -+ PJ_LOG(1,(THIS_FILE, "TAPI: OFFHOOK")); -+ -+ if (ioctl(dev_ctx->ch_fd[dev_idx], IFX_TAPI_LINE_FEED_SET, -+ IFX_TAPI_LINE_FEED_ACTIVE) != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ /* enc/dec stop */ -+ if (tapi_dev_codec_control(dev_ctx->ch_fd[dev_idx], 1) != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - codec start failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t -+tapi_dev_event_digit(tapi_ctx *dev_ctx, pj_uint32_t dev_idx) -+{ -+ PJ_LOG(1,(THIS_FILE, "TAPI: OFFHOOK")); -+ -+ if (ioctl(dev_ctx->ch_fd[dev_idx], IFX_TAPI_LINE_FEED_SET, -+ IFX_TAPI_LINE_FEED_ACTIVE) != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_FEED_SET ioctl failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ /* enc/dec stop */ -+ if (tapi_dev_codec_control(dev_ctx->ch_fd[dev_idx], 1) != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - codec start failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t -+tapi_dev_event_handler(tapi_aud_stream_t *stream) -+{ -+ IFX_TAPI_EVENT_t tapiEvent; -+ tapi_ctx *dev_ctx = stream->dev_ctx; -+ pj_status_t status = PJ_SUCCESS; -+ unsigned int i; -+ -+ for (i = 0; i < TAPI_AUDIO_PORT_NUM; i++) { -+ memset (&tapiEvent, 0, sizeof(tapiEvent)); -+ tapiEvent.ch = dev_ctx->data2phone_map[i]; -+ status = ioctl(dev_ctx->dev_fd, IFX_TAPI_EVENT_GET, &tapiEvent); -+ -+ if ((status == PJ_SUCCESS) && (tapiEvent.id != IFX_TAPI_EVENT_NONE)) { -+ switch(tapiEvent.id) { -+ case IFX_TAPI_EVENT_FXS_ONHOOK: -+ status = tapi_dev_event_on_hook(dev_ctx, i); -+ if(tapi_hook_callback) -+ tapi_hook_callback(i, 0); -+ break; -+ case IFX_TAPI_EVENT_FXS_OFFHOOK: -+ status = tapi_dev_event_off_hook(dev_ctx, i); -+ if(tapi_hook_callback) -+ tapi_hook_callback(i, 1); -+ break; -+ case IFX_TAPI_EVENT_DTMF_DIGIT: -+ if(tapi_digit_callback) -+ tapi_digit_callback(i, tapiEvent.data.dtmf.ascii); -+ break; -+ case IFX_TAPI_EVENT_PULSE_DIGIT: -+ if(tapi_digit_callback) -+ if(tapiEvent.data.pulse.digit == 0xB) -+ tapi_digit_callback(i, '0'); -+ else -+ tapi_digit_callback(i, '0' + tapiEvent.data.pulse.digit); -+ break; -+ case IFX_TAPI_EVENT_COD_DEC_CHG: -+ case IFX_TAPI_EVENT_TONE_GEN_END: -+ case IFX_TAPI_EVENT_CID_TX_SEQ_END: -+ break; -+ default: -+ PJ_LOG(1,(THIS_FILE, "unknown tapi event %08X", tapiEvent.id)); -+ break; -+ } -+ } -+ } -+ -+ return status; -+} -+ -+static pj_status_t -+tapi_dev_data_handler(tapi_aud_stream_t *stream) { -+ pj_status_t status = PJ_SUCCESS; -+ tapi_ctx *dev_ctx = stream->dev_ctx; -+ pj_uint32_t dev_idx = stream->param.rec_id; -+ pj_uint8_t buf_rec[TAPI_LL_DEV_ENC_BYTES_PER_FRAME + TAPI_LL_DEV_RTP_HEADER_SIZE_BYTE]={0}; -+ pj_uint8_t buf_play[TAPI_LL_DEV_ENC_BYTES_PER_FRAME + TAPI_LL_DEV_RTP_HEADER_SIZE_BYTE]={0}; -+ pjmedia_frame frame_rec, frame_play; -+ pj_int32_t ret; -+ -+ /* Get data from driver */ -+ ret = read(dev_ctx->ch_fd[dev_idx], buf_rec, sizeof(buf_rec)); -+ if (ret < 0) { -+ TRACE_((THIS_FILE, "ERROR - no data available from device!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ if (ret > 0) { -+ frame_rec.type = PJMEDIA_FRAME_TYPE_AUDIO; -+ frame_rec.buf = buf_rec + TAPI_LL_DEV_RTP_HEADER_SIZE_BYTE; -+ frame_rec.size = ret - TAPI_LL_DEV_RTP_HEADER_SIZE_BYTE; -+ frame_rec.timestamp.u64 = stream->timestamp.u64; -+ -+ status = stream->rec_cb(stream->user_data, &frame_rec); -+ if (status != PJ_SUCCESS) -+ PJ_LOG(1, (THIS_FILE, "rec_cb() failed %d", status)); -+ -+ frame_play.type = PJMEDIA_FRAME_TYPE_AUDIO; -+ frame_play.buf = buf_play + TAPI_LL_DEV_RTP_HEADER_SIZE_BYTE; -+ frame_play.size = TAPI_LL_DEV_ENC_BYTES_PER_FRAME; -+ frame_play.timestamp.u64 = stream->timestamp.u64; -+ -+ status = (*stream->play_cb)(stream->user_data, &frame_play); -+ if (status != PJ_SUCCESS) { -+ PJ_LOG(1, (THIS_FILE, "play_cb() failed %d", status)); -+ } else { -+ memcpy(buf_play, buf_rec, TAPI_LL_DEV_RTP_HEADER_SIZE_BYTE); -+ -+ ret = write(dev_ctx->ch_fd[dev_idx], buf_play, sizeof(buf_play)); -+ -+ if (ret < 0) { -+ PJ_LOG(1, (THIS_FILE, "ERROR - device data writing failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ if (ret == 0) { -+ PJ_LOG(1, (THIS_FILE, "ERROR - no data written to device!")); -+ return PJ_EUNKNOWN; -+ } -+ } -+ -+ stream->timestamp.u64 += TAPI_LL_DEV_ENC_SMPL_PER_FRAME; -+ } -+ -+ return PJ_SUCCESS; -+} -+ -+static int -+PJ_THREAD_FUNC tapi_dev_thread(void *arg) { -+ tapi_ctx *dev_ctx = streams[0].dev_ctx; -+ pj_uint32_t sretval; -+ struct pollfd fds[3]; -+ -+ PJ_LOG(1,(THIS_FILE, "TAPI: thread starting...")); -+ -+ streams[0].run_flag = 1; -+ streams[1].run_flag = 1; -+ -+ fds[0].fd = dev_ctx->dev_fd; -+ fds[0].events = POLLIN; -+ fds[1].fd = dev_ctx->ch_fd[0]; -+ fds[1].events = POLLIN; -+ fds[2].fd = dev_ctx->ch_fd[1]; -+ fds[2].events = POLLIN; -+ -+ while(1) -+ { -+ sretval = poll(fds, TAPI_AUDIO_PORT_NUM + 1, TAPI_LL_DEV_SELECT_TIMEOUT_MS); -+ -+ if (!streams[0].run_flag && !streams[0].run_flag) -+ break; -+ if (sretval <= 0) -+ continue; -+ -+ if (fds[0].revents == POLLIN) { -+ if (tapi_dev_event_handler(&streams[0]) != PJ_SUCCESS) { -+ PJ_LOG(1, (THIS_FILE, "TAPI: event hanldler failed")); -+ break; -+ } -+ } -+ -+ if (fds[1].revents == POLLIN) { -+ if (tapi_dev_data_handler(&streams[0]) != PJ_SUCCESS) { -+ PJ_LOG(1, (THIS_FILE, "TAPI: data hanldler failed")); -+ break; -+ } -+ } -+ -+ if (fds[2].revents == POLLIN) { -+ if (tapi_dev_data_handler(&streams[1]) != PJ_SUCCESS) { -+ PJ_LOG(1, (THIS_FILE, "TAPI: data hanldler failed")); -+ break; -+ } -+ } -+ } -+ PJ_LOG(1, (THIS_FILE, "TAPI: thread stopping...")); -+ -+ return 0; -+} -+ -+/* Factory operations */ -+ -+pjmedia_aud_dev_factory* -+pjmedia_tapi_factory(pj_pool_factory *pf) { -+ struct tapi_aud_factory *f; -+ pj_pool_t *pool; -+ -+ TRACE_((THIS_FILE, "pjmedia_tapi_factory()")); -+ -+ pool = pj_pool_create(pf, "tapi", 512, 512, NULL); -+ f = PJ_POOL_ZALLOC_T(pool, struct tapi_aud_factory); -+ f->pf = pf; -+ f->pool = pool; -+ f->base.op = &tapi_fact_op; -+ -+ return &f->base; -+} -+ -+static pj_status_t -+factory_init(pjmedia_aud_dev_factory *f) -+{ -+ struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; -+ pj_uint8_t i; -+ -+ TRACE_((THIS_FILE, "factory_init()")); -+ -+ af->dev_count = TAPI_AUDIO_PORT_NUM; -+ af->dev_info = (pjmedia_aud_dev_info*) -+ pj_pool_calloc(af->pool, af->dev_count, sizeof(pjmedia_aud_dev_info)); -+ for (i = 0; i < TAPI_AUDIO_PORT_NUM; i++) { -+ pj_ansi_sprintf(af->dev_info[i].name,"%s_%02d", TAPI_BASE_NAME, i); -+ af->dev_info[i].input_count = af->dev_info[i].output_count = 1; -+ af->dev_info[i].default_samples_per_sec = TAPI_LL_DEV_ENC_SMPL_PER_SEC; -+ pj_ansi_strcpy(af->dev_info[i].driver, "/dev/vmmc"); -+ af->dev_info[i].caps = PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING | -+ PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY | -+ PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY; -+ af->dev_info[i].routes = PJMEDIA_AUD_DEV_ROUTE_DEFAULT ; -+ } -+ if (tapi_dev_start(af) != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - TAPI device init failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t -+factory_destroy(pjmedia_aud_dev_factory *f) -+{ -+ struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; -+ pj_pool_t *pool; -+ pj_status_t status = PJ_SUCCESS; -+ -+ TRACE_((THIS_FILE, "factory_destroy()")); -+ -+ if (tapi_dev_stop(af) != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - TAPI device stop failed!")); -+ status = PJ_EUNKNOWN; -+ } -+ pool = af->pool; -+ af->pool = NULL; -+ pj_pool_release(pool); -+ -+ return status; -+} -+ -+static unsigned -+factory_get_dev_count(pjmedia_aud_dev_factory *f) -+{ -+ struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; -+ TRACE_((THIS_FILE, "factory_get_dev_count()")); -+ -+ return af->dev_count; -+} -+ -+static pj_status_t -+factory_get_dev_info(pjmedia_aud_dev_factory *f, unsigned index, pjmedia_aud_dev_info *info) -+{ -+ struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; -+ -+ TRACE_((THIS_FILE, "factory_get_dev_info()")); -+ PJ_ASSERT_RETURN(index < af->dev_count, PJMEDIA_EAUD_INVDEV); -+ -+ pj_memcpy(info, &af->dev_info[index], sizeof(*info)); -+ -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t -+factory_default_param(pjmedia_aud_dev_factory *f, unsigned index, pjmedia_aud_param *param) -+{ -+ struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; -+ struct pjmedia_aud_dev_info *di = &af->dev_info[index]; -+ -+ TRACE_((THIS_FILE, "factory_default_param.")); -+ PJ_ASSERT_RETURN(index < af->dev_count, PJMEDIA_EAUD_INVDEV); -+ -+ pj_bzero(param, sizeof(*param)); -+ if (di->input_count && di->output_count) { -+ param->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK; -+ param->rec_id = index; -+ param->play_id = index; -+ } else if (di->input_count) { -+ param->dir = PJMEDIA_DIR_CAPTURE; -+ param->rec_id = index; -+ param->play_id = PJMEDIA_AUD_INVALID_DEV; -+ } else if (di->output_count) { -+ param->dir = PJMEDIA_DIR_PLAYBACK; -+ param->play_id = index; -+ param->rec_id = PJMEDIA_AUD_INVALID_DEV; -+ } else { -+ return PJMEDIA_EAUD_INVDEV; -+ } -+ -+ param->clock_rate = TAPI_LL_DEV_ENC_SMPL_PER_SEC; //di->default_samples_per_sec; -+ param->channel_count = 1; -+ param->samples_per_frame = TAPI_LL_DEV_ENC_SMPL_PER_FRAME; -+ param->bits_per_sample = TAPI_LL_DEV_ENC_BITS_PER_SMPLS; -+ param->flags = PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE | di->caps; -+ param->output_route = PJMEDIA_AUD_DEV_ROUTE_DEFAULT; -+ -+ return PJ_SUCCESS; -+} -+ -+ -+static pj_status_t -+factory_create_stream(pjmedia_aud_dev_factory *f, const pjmedia_aud_param *param, -+ pjmedia_aud_rec_cb rec_cb, pjmedia_aud_play_cb play_cb, -+ void *user_data, pjmedia_aud_stream **p_aud_strm) -+{ -+ struct tapi_aud_factory *af = (struct tapi_aud_factory*)f; -+ pj_pool_t *pool; -+ pj_status_t status; -+ int id = param->rec_id; -+ struct tapi_aud_stream *strm = &streams[param->rec_id]; -+ TRACE_((THIS_FILE, "factory_create_stream() rec_id:%d play_id:%d", param->rec_id, param->play_id)); -+ -+ /* Can only support 16bits per sample */ -+ PJ_ASSERT_RETURN(param->bits_per_sample == TAPI_LL_DEV_ENC_BITS_PER_SMPLS, PJ_EINVAL); -+ PJ_ASSERT_RETURN(param->clock_rate == TAPI_LL_DEV_ENC_SMPL_PER_SEC, PJ_EINVAL); -+ PJ_ASSERT_RETURN(param->samples_per_frame == TAPI_LL_DEV_ENC_SMPL_PER_FRAME, PJ_EINVAL); -+ -+ /* Can only support bidirectional stream */ -+ PJ_ASSERT_RETURN(param->dir & PJMEDIA_DIR_CAPTURE_PLAYBACK, PJ_EINVAL); -+ -+ if (id == 0) { -+ /* Initialize our stream data */ -+ pool = pj_pool_create(af->pf, "tapi-dev", 1000, 1000, NULL); -+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM); -+ -+ strm->pool = pool; -+ } else { -+ pool = strm->pool = streams[0].pool; -+ } -+ -+ strm->rec_cb = rec_cb; -+ strm->play_cb = play_cb; -+ strm->user_data = user_data; -+ -+ pj_memcpy(&strm->param, param, sizeof(*param)); -+ -+ if ((strm->param.flags & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT) == 0) { -+ strm->param.ext_fmt.id = PJMEDIA_FORMAT_L16; -+ } -+ -+ strm->timestamp.u64 = 0; -+ strm->dev_ctx = &(af->dev_ctx); -+ -+ /* Create and start the thread */ -+ if (id == 1) { -+ status = pj_thread_create(pool, "tapi", &tapi_dev_thread, strm, 0, 0, &streams[0].thread); -+ if (status != PJ_SUCCESS) { -+ stream_destroy(&strm->base); -+ return status; -+ } -+ } -+ -+ /* Done */ -+ strm->base.op = &tapi_strm_op; -+ *p_aud_strm = &strm->base; -+ -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t -+stream_get_param(pjmedia_aud_stream *s, pjmedia_aud_param *pi) -+{ -+ struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; -+ -+ PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL); -+ pj_memcpy(pi, &strm->param, sizeof(*pi)); -+ -+ if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, -+ &pi->output_vol) == PJ_SUCCESS) -+ pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING; -+ -+ if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY, -+ &pi->output_latency_ms) == PJ_SUCCESS) -+ pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY; -+ -+ if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY, -+ &pi->input_latency_ms) == PJ_SUCCESS) -+ pi->flags |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY; -+ -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t -+stream_get_cap(pjmedia_aud_stream *s, pjmedia_aud_dev_cap cap, void *pval) -+{ -+ // struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t -+stream_set_cap(pjmedia_aud_stream *s, pjmedia_aud_dev_cap cap, const void *pval) -+{ -+ // struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t -+stream_start(pjmedia_aud_stream *s) -+{ -+ struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; -+ pj_uint32_t dev_idx; -+ -+ TRACE_((THIS_FILE, "stream_start()")); -+ -+ dev_idx = strm->param.rec_id; -+ -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t -+stream_stop(pjmedia_aud_stream *s) -+{ -+ struct tapi_aud_stream *strm = (struct tapi_aud_stream*)s; -+ tapi_ctx *dev_ctx = strm->dev_ctx; -+ pj_uint32_t dev_idx; -+ -+ TRACE_((THIS_FILE, "stream_stop()")); -+ dev_idx = strm->param.rec_id; -+ -+ if (tapi_dev_codec_control(dev_ctx->ch_fd[dev_idx], 0) != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - codec start failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ return PJ_SUCCESS; -+} -+ -+static pj_status_t -+stream_destroy(pjmedia_aud_stream *s) -+{ -+ pj_status_t state = PJ_SUCCESS; -+ struct tapi_aud_stream *stream = (struct tapi_aud_stream*)s; -+ pj_pool_t *pool; -+ -+ PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); -+ TRACE_((THIS_FILE, "stream_destroy()")); -+ -+ stream_stop(&stream->base); -+ stream->run_flag = 0; -+ -+ if (stream->thread) -+ { -+ pj_thread_join(stream->thread); -+ pj_thread_destroy(stream->thread); -+ stream->thread = NULL; -+ } -+ -+ pool = stream->pool; -+ pj_bzero(stream, sizeof(stream)); -+ pj_pool_release(pool); -+ -+ return state; -+} -+ -+pj_status_t -+tapi_hook_status(pj_uint8_t port, pj_int32_t *status) -+{ -+ PJ_ASSERT_RETURN(port < TAPI_AUDIO_PORT_NUM, PJ_EINVAL); -+ -+ if (ioctl(ch_fd[port], IFX_TAPI_LINE_HOOK_STATUS_GET, status) -+ != PJ_SUCCESS) { -+ TRACE_((THIS_FILE, "ERROR - IFX_TAPI_LINE_HOOK_STATUS_GET ioctl failed!")); -+ return PJ_EUNKNOWN; -+ } -+ -+ return PJ_SUCCESS; -+} -+ -+pj_status_t -+tapi_ring(pj_uint8_t port, pj_uint8_t state, char *caller_number) -+{ -+ PJ_ASSERT_RETURN(port < TAPI_AUDIO_PORT_NUM, PJ_EINVAL); -+ -+ if (state) { -+ if (tapi_cid_type && caller_number) { -+ IFX_TAPI_CID_MSG_t cid_msg; -+ IFX_TAPI_CID_MSG_ELEMENT_t cid_msg_el[1]; -+ memset(&cid_msg, 0, sizeof(cid_msg)); -+ memset(&cid_msg_el, 0, sizeof(cid_msg_el)); -+ -+ cid_msg_el[0].string.elementType = IFX_TAPI_CID_ST_CLI; -+ cid_msg_el[0].string.len = strlen(caller_number); -+ strncpy(cid_msg_el[0].string.element, caller_number, sizeof(cid_msg_el[0].string.element)); -+ -+ cid_msg.txMode = IFX_TAPI_CID_HM_ONHOOK; -+ cid_msg.messageType = IFX_TAPI_CID_MT_CSUP; -+ cid_msg.nMsgElements = 1; -+ cid_msg.message = cid_msg_el; -+ ioctl(ch_fd[port], IFX_TAPI_CID_TX_SEQ_START, &cid_msg); -+ } else { -+ ioctl(ch_fd[port], IFX_TAPI_RING_START, 0); -+ } -+ } else { -+ ioctl(ch_fd[port], IFX_TAPI_RING_STOP, 0); -+ } -+ -+ return PJ_SUCCESS; -+} -+ -+pj_status_t -+tapi_tone(pj_uint8_t port, pj_uint8_t code) -+{ -+ PJ_ASSERT_RETURN(port < TAPI_AUDIO_PORT_NUM, PJ_EINVAL); -+ -+ if (tapi_locale && code) -+ ioctl(ch_fd[port], IFX_TAPI_TONE_LOCAL_PLAY, code); -+ else if (code) -+ ioctl(ch_fd[port], IFX_TAPI_TONE_LOCAL_PLAY, TAPI_TONE_LOCALE_NONE); -+ else -+ ioctl(ch_fd[port], IFX_TAPI_TONE_LOCAL_PLAY, 0); -+ -+ return PJ_SUCCESS; -+} -+ -+#endif /* PJMEDIA_AUDIO_DEV_HAS_TAPI_DEVICE */ diff --git a/extra/pjsip/patches/0003-adds-PJ_DEF-pj_status_t-pjsua_add_snd_port-int-id.patch b/extra/pjsip/patches/0003-adds-PJ_DEF-pj_status_t-pjsua_add_snd_port-int-id.patch deleted file mode 100644 index 3331c8482..000000000 --- a/extra/pjsip/patches/0003-adds-PJ_DEF-pj_status_t-pjsua_add_snd_port-int-id.patch +++ /dev/null @@ -1,207 +0,0 @@ ---- a/pjsip/include/pjsua-lib/pjsua.h -+++ b/pjsip/include/pjsua-lib/pjsua.h -@@ -1543,6 +1543,8 @@ PJ_DECL(pjmedia_endpt*) pjsua_get_pjmedi - PJ_DECL(pj_pool_factory*) pjsua_get_pool_factory(void); - - -+PJ_DECL(pj_status_t) pjsua_add_snd_port(int id, pjsua_conf_port_id *p_id); -+ - - /***************************************************************************** - * Utilities. ---- a/pjsip/include/pjsua-lib/pjsua_internal.h -+++ b/pjsip/include/pjsua-lib/pjsua_internal.h -@@ -261,6 +261,8 @@ typedef struct pjsua_stun_resolve - } pjsua_stun_resolve; - - -+#define MAX_PORT 2 -+ - /** - * Global pjsua application data. - */ -@@ -336,7 +338,7 @@ struct pjsua_data - pj_bool_t aud_open_cnt;/**< How many # device is opened */ - pj_bool_t no_snd; /**< No sound (app will manage it) */ - pj_pool_t *snd_pool; /**< Sound's private pool. */ -- pjmedia_snd_port *snd_port; /**< Sound port. */ -+ pjmedia_snd_port *snd_port[MAX_PORT]; /**< Sound port. */ - pj_timer_entry snd_idle_timer;/**< Sound device idle timer. */ - pjmedia_master_port *null_snd; /**< Master port for null sound. */ - pjmedia_port *null_port; /**< Null port. */ ---- a/pjsip/src/pjsua-lib/pjsua_media.c -+++ b/pjsip/src/pjsua-lib/pjsua_media.c -@@ -588,7 +588,7 @@ static void check_snd_dev_idle() - * It is idle when there is no port connection in the bridge and - * there is no active call. - */ -- if ((pjsua_var.snd_port!=NULL || pjsua_var.null_snd!=NULL) && -+ if ((pjsua_var.snd_port[0]!=NULL || pjsua_var.null_snd!=NULL) && - pjsua_var.snd_idle_timer.id == PJ_FALSE && - pjmedia_conf_get_connect_count(pjsua_var.mconf) == 0 && - call_cnt == 0 && -@@ -2008,7 +2008,7 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( - pj_assert(status == PJ_SUCCESS); - - /* Check if sound device is instantiated. */ -- need_reopen = (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL && -+ need_reopen = (pjsua_var.snd_port[0]==NULL && pjsua_var.null_snd==NULL && - !pjsua_var.no_snd); - - /* Check if sound device need to reopen because it needs to modify -@@ -2072,7 +2072,7 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( - /* The bridge version */ - - /* Create sound port if none is instantiated */ -- if (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL && -+ if (pjsua_var.snd_port[0]==NULL && pjsua_var.null_snd==NULL && - !pjsua_var.no_snd) - { - pj_status_t status; -@@ -2686,9 +2686,9 @@ static pj_status_t update_initial_aud_pa - pjmedia_aud_param param; - pj_status_t status; - -- PJ_ASSERT_RETURN(pjsua_var.snd_port != NULL, PJ_EBUG); -+ PJ_ASSERT_RETURN(pjsua_var.snd_port[0] != NULL, PJ_EBUG); - -- strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port); -+ strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port[0]); - - status = pjmedia_aud_stream_get_param(strm, ¶m); - if (status != PJ_SUCCESS) { -@@ -2754,7 +2754,7 @@ static pj_status_t open_snd_dev(pjmedia_ - 1000 / param->base.clock_rate)); - - status = pjmedia_snd_port_create2( pjsua_var.snd_pool, -- param, &pjsua_var.snd_port); -+ param, &pjsua_var.snd_port[0]); - if (status != PJ_SUCCESS) - return status; - -@@ -2812,13 +2812,13 @@ static pj_status_t open_snd_dev(pjmedia_ - } - - /* Connect sound port to the bridge */ -- status = pjmedia_snd_port_connect(pjsua_var.snd_port, -+ status = pjmedia_snd_port_connect(pjsua_var.snd_port[0], - conf_port ); - if (status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "Unable to connect conference port to " - "sound device", status); -- pjmedia_snd_port_destroy(pjsua_var.snd_port); -- pjsua_var.snd_port = NULL; -+ pjmedia_snd_port_destroy(pjsua_var.snd_port[0]); -+ pjsua_var.snd_port[0] = NULL; - return status; - } - -@@ -2833,7 +2833,7 @@ static pj_status_t open_snd_dev(pjmedia_ - pjmedia_aud_param si; - pj_str_t tmp; - -- strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port); -+ strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port[0]); - status = pjmedia_aud_stream_get_param(strm, &si); - if (status == PJ_SUCCESS) - status = pjmedia_aud_dev_get_info(si.rec_id, &rec_info); -@@ -2876,12 +2876,12 @@ static pj_status_t open_snd_dev(pjmedia_ - static void close_snd_dev(void) - { - /* Close sound device */ -- if (pjsua_var.snd_port) { -+ if (pjsua_var.snd_port[0]) { - pjmedia_aud_dev_info cap_info, play_info; - pjmedia_aud_stream *strm; - pjmedia_aud_param param; - -- strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port); -+ strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port[0]); - pjmedia_aud_stream_get_param(strm, ¶m); - - if (pjmedia_aud_dev_get_info(param.rec_id, &cap_info) != PJ_SUCCESS) -@@ -2893,9 +2893,9 @@ static void close_snd_dev(void) - "%s sound capture device", - play_info.name, cap_info.name)); - -- pjmedia_snd_port_disconnect(pjsua_var.snd_port); -- pjmedia_snd_port_destroy(pjsua_var.snd_port); -- pjsua_var.snd_port = NULL; -+ pjmedia_snd_port_disconnect(pjsua_var.snd_port[0]); -+ pjmedia_snd_port_destroy(pjsua_var.snd_port[0]); -+ pjsua_var.snd_port[0] = NULL; - } - - /* Close null sound device */ -@@ -2984,6 +2984,35 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( i - return PJ_SUCCESS; - } - -+PJ_DEF(pj_status_t) pjsua_add_snd_port(int id, pjsua_conf_port_id *p_id) -+{ -+ unsigned alt_cr_cnt = 1; -+ unsigned alt_cr = 0; -+ pj_status_t status = -1; -+ pjmedia_snd_port_param param; -+ unsigned samples_per_frame; -+ pjmedia_port *port; -+ const pj_str_t name = pj_str("tapi2"); -+ alt_cr = pjsua_var.media_cfg.clock_rate; -+ samples_per_frame = alt_cr * -+ pjsua_var.media_cfg.audio_frame_ptime * -+ pjsua_var.media_cfg.channel_count / 1000; -+ status = create_aud_param(¶m.base, -+ pjsua_var.play_dev, -+ pjsua_var.cap_dev, -+ alt_cr, -+ pjsua_var.media_cfg.channel_count, -+ samples_per_frame, 16); -+ if (status != PJ_SUCCESS) -+ return status; -+ param.base.rec_id = id; -+ param.base.play_id = id; -+ param.options = 0; -+ status = pjmedia_snd_port_create2(pjsua_var.snd_pool, -+ ¶m, &pjsua_var.snd_port[id]); -+ return PJ_SUCCESS; -+} -+ - - /* - * Get currently active sound devices. If sound devices has not been created -@@ -3088,7 +3117,7 @@ PJ_DEF(pj_status_t) pjsua_set_ec(unsigne - pjsua_var.media_cfg.ec_options = options; - - if (pjsua_var.snd_port) -- status = pjmedia_snd_port_set_ec(pjsua_var.snd_port, pjsua_var.pool, -+ status = pjmedia_snd_port_set_ec(pjsua_var.snd_port[0], pjsua_var.pool, - tail_ms, options); - - PJSUA_UNLOCK(); -@@ -3111,7 +3140,7 @@ PJ_DEF(pj_status_t) pjsua_get_ec_tail(un - */ - PJ_DEF(pj_bool_t) pjsua_snd_is_active(void) - { -- return pjsua_var.snd_port != NULL; -+ return pjsua_var.snd_port[0] != NULL; - } - - -@@ -3135,7 +3164,7 @@ PJ_DEF(pj_status_t) pjsua_snd_set_settin - if (pjsua_snd_is_active()) { - pjmedia_aud_stream *strm; - -- strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port); -+ strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port[0]); - status = pjmedia_aud_stream_set_cap(strm, cap, pval); - } else { - status = PJ_SUCCESS; -@@ -3181,7 +3210,7 @@ PJ_DEF(pj_status_t) pjsua_snd_get_settin - /* Sound is active, retrieve from device directly */ - pjmedia_aud_stream *strm; - -- strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port); -+ strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port[0]); - status = pjmedia_aud_stream_get_cap(strm, cap, pval); - } else { - /* Otherwise retrieve from internal param */ diff --git a/extra/ps3-utils/Makefile b/extra/ps3-utils/Makefile deleted file mode 100644 index 042eb0e2f..000000000 --- a/extra/ps3-utils/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (C) 2008-2010 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=ps3-utils -PKG_REV:=6488134e48cf2d6f2d6471ced8346ac8cb1b855a -PKG_VERSION:=20090320 -PKG_RELEASE:=1 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.bz2 -PKG_SOURCE_URL:=git://git.kernel.org/pub/scm/linux/kernel/git/geoff/ps3-utils.git -PKG_SOURCE_PROTO:=git -PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE_VERSION:=$(PKG_REV) - -PKG_FIXUP:=autoreconf -PKG_INSTALL=1 - -include $(INCLUDE_DIR)/package.mk - -define Package/ps3-utils - SECTION:=utils - CATEGORY:=Utilities - TITLE:=PS3 Linux Utilities - URL:=http://kernel.org/pub/linux/kernel/people/geoff/cell/ps3-utils/ - MAINTAINER:=Geoff Levand - DEPENDS:=@TARGET_ps3||TARGET_ps3chk||TARGET_powerpc -endef - -define Package/ps3-utils/description - The ps3-utils package is a set of system administration utilites for the - PS3 game console. -endef - -define Build/Configure - (cd $(PKG_BUILD_DIR) && $(BASH) -x ./bootstrap) - $(call Build/Configure/Default) -endef - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/include - $(INSTALL_DATA) \ - $(PKG_INSTALL_DIR)/usr/include/ps3*.h \ - $(1)/usr/include - - $(INSTALL_DIR) $(1)/usr/lib - $(INSTALL_BIN) \ - $(PKG_INSTALL_DIR)/usr/lib/libps3-utils.{la,a,so*} \ - $(1)/usr/lib/ -endef - -define Package/ps3-utils/install - $(INSTALL_DIR) $(1)/usr/sbin - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_DIR) $(1)/usr/lib - - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ps3-boot-game-os $(1)/usr/sbin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ps3-dump-bootloader $(1)/usr/sbin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ps3-flash-util $(1)/usr/sbin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ps3-video-mode $(1)/usr/bin - - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libps3-utils.so.* $(1)/usr/lib -endef - -$(eval $(call BuildPackage,ps3-utils)) diff --git a/extra/sierra-directip/Makefile b/extra/sierra-directip/Makefile deleted file mode 100644 index fc0e4ea52..000000000 --- a/extra/sierra-directip/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright (C) 2006-2010 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=sierra-directip -PKG_RELEASE:=10 - -include $(INCLUDE_DIR)/package.mk - -define KernelPackage/usb-sierrawireless-directip - SUBMENU:=USB Support - DEPENDS:=+kmod-usb-serial +kmod-usb-net - TITLE:=Updated Sierra Wireless drivers for DirectIP - FILES:= \ - $(PKG_BUILD_DIR)/sierra.ko \ - $(PKG_BUILD_DIR)/sierra_net.ko - AUTOLOAD:=$(call AutoLoad,60,sierra sierra_net) -endef - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) - $(CP) ./src/* $(PKG_BUILD_DIR)/ - $(Build/Patch) -endef - -define Build/Compile - $(MAKE) -C "$(LINUX_DIR)" \ - CROSS_COMPILE="$(TARGET_CROSS)" \ - ARCH="$(LINUX_KARCH)" \ - SUBDIRS="$(PKG_BUILD_DIR)" \ - EXTRA_CFLAGS="$(BUILDFLAGS)" \ - modules -endef - -$(eval $(call KernelPackage,usb-sierrawireless-directip)) diff --git a/extra/sierra-directip/patches/100-sierra_net_endian.patch b/extra/sierra-directip/patches/100-sierra_net_endian.patch deleted file mode 100644 index 196d77d49..000000000 --- a/extra/sierra-directip/patches/100-sierra_net_endian.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/sierra_net.c -+++ b/sierra_net.c -@@ -840,8 +840,8 @@ static int sierra_net_bind(struct usbnet - init_timer(&priv->sync_timer); - /* verify fw attributes */ - status = sierra_net_get_fw_attr(dev, &fwattr); -- dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr); -- if (status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_APM)) { -+ dev_dbg(&dev->udev->dev, "Fw attr: %x\n", cpu_to_le16(fwattr)); -+ if (status == sizeof(fwattr) && (cpu_to_le16(fwattr) & SWI_GET_FW_ATTR_APM)) { - /******************************************************************************* - * If you want the default /sys/bus/usb/devices/.../.../power/level to be forced - * to auto, the following needs to be compiled in. -@@ -856,7 +856,7 @@ static int sierra_net_bind(struct usbnet - usb_disable_autosuspend(dev->udev); - } - /* test whether firmware supports DHCP */ -- if (!(status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_MASK))) { -+ if (!(status == sizeof(fwattr) && (cpu_to_le16(fwattr) & SWI_GET_FW_ATTR_MASK))) { - /* found incompatible firmware version */ - dev_err(&dev->udev->dev, "Incompatible driver and firmware" - " versions\n"); diff --git a/extra/sierra-directip/patches/110-drop_dhcp_requirement.patch b/extra/sierra-directip/patches/110-drop_dhcp_requirement.patch deleted file mode 100644 index 4c4d0ba65..000000000 --- a/extra/sierra-directip/patches/110-drop_dhcp_requirement.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/sierra_net.c -+++ b/sierra_net.c -@@ -858,10 +858,7 @@ static int sierra_net_bind(struct usbnet - /* test whether firmware supports DHCP */ - if (!(status == sizeof(fwattr) && (cpu_to_le16(fwattr) & SWI_GET_FW_ATTR_MASK))) { - /* found incompatible firmware version */ -- dev_err(&dev->udev->dev, "Incompatible driver and firmware" -- " versions\n"); -- kfree(priv); -- return -ENODEV; -+ dev_err(&dev->udev->dev, "Warning: Firmware does not have DHCP support\n"); - } - /* prepare sync message from template */ - memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg)); diff --git a/extra/sierra-directip/src/Makefile b/extra/sierra-directip/src/Makefile deleted file mode 100644 index 7ceb03b58..000000000 --- a/extra/sierra-directip/src/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-m := sierra.o sierra_net.o diff --git a/extra/sierra-directip/src/sierra.c b/extra/sierra-directip/src/sierra.c deleted file mode 100644 index 9752d1142..000000000 --- a/extra/sierra-directip/src/sierra.c +++ /dev/null @@ -1,1409 +0,0 @@ -/* - USB Driver for Sierra Wireless - - Copyright (C) 2006, 2007, 2008 Kevin Lloyd , - - Copyright (C) 2008 - 2011 Elina Pasheva, Matthew Safar, Rory Filer - - - IMPORTANT DISCLAIMER: This driver is not commercially supported by - Sierra Wireless. Use at your own risk. - - This driver is free software; you can redistribute it and/or modify - it under the terms of Version 2 of the GNU General Public License as - published by the Free Software Foundation. - - Portions based on the option driver by Matthias Urlichs - Whom based his on the Keyspan driver by Hugh Blemings -*/ -/* Uncomment to log function calls */ -/*#define DEBUG*/ -/* Uncomment to force power level set to auto when attaching a device */ -/*#define POWER_LEVEL_AUTO*/ - -/* Sierra driver - kernel 3.0 */ -#define DRIVER_VERSION "v.1.7.40" -#define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" -#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SWIMS_USB_REQUEST_SetPower 0x00 -#define SWIMS_USB_REQUEST_GetFwAttr 0x06 -#define SWIMS_USB_REQUEST_SetNmea 0x07 -#define USB_REQUEST_TYPE_CLASS 0xA1 -#define USB_REQUEST_IFACE 0x20 - -#define N_IN_URB_HM 8 -#define N_OUT_URB_HM 64 -#define N_IN_URB 4 -#define N_OUT_URB 4 -#define IN_BUFLEN 4096 - -#define MAX_TRANSFER (PAGE_SIZE - 512) -/* MAX_TRANSFER is chosen so that the VM is not stressed by - allocations > PAGE_SIZE and the number of packets in a page - is an integer 512 is the largest possible packet on EHCI */ - -#define SWI_FW_ATTR_PM_MASK 0x02 -/* PORTION_LEN defines the length of device attribute buffer */ -#define PORTION_LEN 4096 - -static int debug; -static int nmea; - -/* sysfs attributes */ -static int sierra_create_sysfs_attrs(struct usb_serial_port *port); -static int sierra_remove_sysfs_attrs(struct usb_serial_port *port); - -/* Used in interface blacklisting */ -struct sierra_iface_info { - const u32 infolen; /* number of interface numbers on blacklist */ - const u8 *ifaceinfo; /* pointer to the array holding the numbers */ -}; - -/* per interface statistics */ -struct sierra_intf_stats { - atomic_t rx_bytes; /* received bytes */ - atomic_t indat_cb_cnt; /* indat callback count */ - atomic_t indat_cb_fail; /* indat cb with error */ - - atomic_t tx_bytes; /* transmitted bytes */ - atomic_t write_cnt; /* no. of writes */ - atomic_t write_err; /* no. of failed writes */ - - atomic_t delayed_writes; /* no. of delayed writes */ - atomic_t delayed_write_err; /* no. of delayed write errs */ - - atomic_t outdat_cb_cnt; /* outdat callback count */ - atomic_t outdat_cb_fail; /* outdat cb with error */ - -}; - -struct sierra_intf_private { - spinlock_t susp_lock; - unsigned int suspended:1; - int in_flight; - - struct sierra_intf_stats stats; -}; - -static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) -{ - int result; - dev_dbg(&udev->dev, "%s\n", __func__); - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - SWIMS_USB_REQUEST_SetPower, /* __u8 request */ - USB_TYPE_VENDOR, /* __u8 request type */ - swiState, /* __u16 value */ - 0, /* __u16 index */ - NULL, /* void *data */ - 0, /* __u16 size */ - USB_CTRL_SET_TIMEOUT); /* int timeout */ - return result; -} - -static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) -{ - int result; - dev_dbg(&udev->dev, "%s\n", __func__); - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - SWIMS_USB_REQUEST_SetNmea, /* __u8 request */ - USB_TYPE_VENDOR, /* __u8 request type */ - enable, /* __u16 value */ - 0x0000, /* __u16 index */ - NULL, /* void *data */ - 0, /* __u16 size */ - USB_CTRL_SET_TIMEOUT); /* int timeout */ - return result; -} - -static int sierra_get_fw_attr(struct usb_device *udev, u16 *data) -{ - int result; - u16 *attrdata; - - dev_dbg(&udev->dev, "%s\n", __func__); - - attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL); - if (!attrdata) - return -ENOMEM; - - result = usb_control_msg(udev, - usb_rcvctrlpipe(udev, 0), - SWIMS_USB_REQUEST_GetFwAttr, /* __u8 request*/ - USB_TYPE_VENDOR | USB_DIR_IN, /* request type*/ - 0x0000, /* __u16 value */ - 0x0000, /* __u16 index */ - attrdata, /* void *data */ - sizeof(*attrdata), /* _u16 size */ - USB_CTRL_SET_TIMEOUT); /* in timeout */ - - if (result < 0) { - kfree(attrdata); - return -EIO; - } - - *data = *attrdata; - - kfree(attrdata); - return result; -} - -static int sierra_calc_num_ports(struct usb_serial *serial) -{ - int num_ports = 0; - u8 ifnum, numendpoints; - - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; - numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints; - - /* Dummy interface present on some SKUs should be ignored */ - if (ifnum == 0x99) - num_ports = 0; - else if (numendpoints <= 3) - num_ports = 1; - else - num_ports = (numendpoints-1)/2; - return num_ports; -} - -static int is_blacklisted(const u8 ifnum, - const struct sierra_iface_info *blacklist) -{ - const u8 *info; - int i; - - if (blacklist) { - info = blacklist->ifaceinfo; - - for (i = 0; i < blacklist->infolen; i++) { - if (info[i] == ifnum) - return 1; - } - } - return 0; -} - -static int is_himemory(const u8 ifnum, - const struct sierra_iface_info *himemorylist) -{ - const u8 *info; - int i; - - if (himemorylist) { - info = himemorylist->ifaceinfo; - - for (i=0; i < himemorylist->infolen; i++) { - if (info[i] == ifnum) - return 1; - } - } - return 0; -} - -static int sierra_calc_interface(struct usb_serial *serial) -{ - int interface; - struct usb_interface *p_interface; - struct usb_host_interface *p_host_interface; - - /* Get the interface structure pointer from the serial struct */ - p_interface = serial->interface; - - /* Get a pointer to the host interface structure */ - p_host_interface = p_interface->cur_altsetting; - - /* read the interface descriptor for this active altsetting - * to find out the interface number we are on */ - interface = p_host_interface->desc.bInterfaceNumber; - - return interface; -} - -static int sierra_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - int result = 0; - struct usb_device *udev; - struct sierra_intf_private *intfdata; - u8 ifnum; - - udev = serial->dev; - dev_dbg(&udev->dev, "%s\n", __func__); - - ifnum = sierra_calc_interface(serial); - /* - * If this interface supports more than 1 alternate - * select the 2nd one - */ - if (serial->interface->num_altsetting == 2) { - dev_dbg(&udev->dev, "Selecting alt setting for interface %d\n", - ifnum); - /* We know the alternate setting is for composite USB interface - * modems - */ - usb_set_interface(udev, ifnum, 1); - } - - /* ifnum could have changed - by calling usb_set_interface */ - ifnum = sierra_calc_interface(serial); - - if (is_blacklisted(ifnum, - (struct sierra_iface_info *)id->driver_info)) { - dev_dbg(&serial->dev->dev, - "Ignoring blacklisted interface #%d\n", ifnum); - return -ENODEV; - } - - intfdata = serial->private = kzalloc(sizeof(struct sierra_intf_private), - GFP_KERNEL); - if (!intfdata) - return -ENOMEM; - spin_lock_init(&intfdata->susp_lock); - - return result; -} - -/* interfaces with higher memory requirements */ -static const u8 hi_memory_typeA_ifaces[] = { 0, 2 }; -static const struct sierra_iface_info typeA_interface_list = { - .infolen = ARRAY_SIZE(hi_memory_typeA_ifaces), - .ifaceinfo = hi_memory_typeA_ifaces, -}; - -static const u8 hi_memory_typeB_ifaces[] = { 3, 4, 5, 6 }; -static const struct sierra_iface_info typeB_interface_list = { - .infolen = ARRAY_SIZE(hi_memory_typeB_ifaces), - .ifaceinfo = hi_memory_typeB_ifaces, -}; - -/* 'blacklist' of interfaces not served by this driver */ -static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; -static const struct sierra_iface_info direct_ip_interface_blacklist = { - .infolen = ARRAY_SIZE( direct_ip_non_serial_ifaces ), - .ifaceinfo = direct_ip_non_serial_ifaces, -}; - -static const struct usb_device_id id_table [] = { - { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ - { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */ - { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */ - { USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */ - - { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ - { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ - { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ - { USB_DEVICE(0x1199, 0x0022) }, /* Sierra Wireless EM5725 */ - { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */ - { USB_DEVICE(0x1199, 0x0224) }, /* Sierra Wireless MC5727 */ - { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ - { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ - { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ - { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ - { USB_DEVICE(0x1199, 0x0301) }, /* Sierra Wireless USB Dongle 250U/3G */ - /* Sierra Wireless MC5728 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0400, 0xFF, 0xFF, 0xFF) }, - - /* Sierra Wireless C597 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, - /* Sierra Wireless T598 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) }, - { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */ - { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */ - { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */ - { USB_DEVICE(0x114F, 0x6000) }, /* Sierra Wireless Q26 Elite */ - - { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ - { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ - { USB_DEVICE(0x1199, 0x6805) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6808) }, /* Sierra Wireless MC8755 */ - { USB_DEVICE(0x1199, 0x6809) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ - { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */ - { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ - { USB_DEVICE(0x1199, 0x6816) }, /* Sierra Wireless MC8775 */ - { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ - { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ - { USB_DEVICE(0x1199, 0x6822) }, /* Sierra Wireless AirCard 875E */ - { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ - { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ - { USB_DEVICE(0x1199, 0x6834) }, /* Sierra Wireless MC8780 */ - { USB_DEVICE(0x1199, 0x6835) }, /* Sierra Wireless MC8781 */ - { USB_DEVICE(0x1199, 0x6838) }, /* Sierra Wireless MC8780 */ - { USB_DEVICE(0x1199, 0x6839) }, /* Sierra Wireless MC8781 */ - { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ - { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ - /* Sierra Wireless MC8790, MC8791, MC8792 Composite */ - { USB_DEVICE(0x1199, 0x683C) }, - { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8791 Composite */ - /* Sierra Wireless MC8790, MC8791, MC8792 */ - { USB_DEVICE(0x1199, 0x683E) }, - { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ - { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ - { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ - { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ - { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */ - { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ - { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */ - { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ - /* Sierra Wireless C885 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, - /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)}, - /* Sierra Wireless C22/C33 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)}, - /* Sierra Wireless HSPA Non-Composite Device */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, - { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ - /* Sierra Wireless Direct IP modems */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68A3, 0xFF, 0xFF, 0xFF), - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, - /* AT&T Direct IP modems */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68A3, 0xFF, 0xFF, 0xFF), - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, - /* Sierra Wireless Direct IP LTE modems */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68AA, 0xFF, 0xFF, 0xFF), - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, - /* AT&T Direct IP LTE modems */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, - /* Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */ - { USB_DEVICE(0x413C, 0x8133) }, - - { } -}; -MODULE_DEVICE_TABLE(usb, id_table); - -/* per port private data */ -struct sierra_port_private { - spinlock_t lock; /* lock the structure */ - int outstanding_urbs; /* number of out urbs in flight */ - - struct usb_anchor active; - struct usb_anchor delayed; - - int num_out_urbs; - int num_in_urbs; - /* Input endpoints and buffers for this port */ - struct urb *in_urbs[N_IN_URB_HM]; - - /* Settings for the port */ - int rts_state; /* Handshaking pins (outputs) */ - int dtr_state; - int cts_state; /* Handshaking pins (inputs) */ - int dsr_state; - int dcd_state; - int ri_state; - unsigned int opened:1; -}; - -static int sierra_send_setup(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - __u16 interface = 0; - int val = 0; - int do_send = 0; - int retval; - - dev_dbg(&port->dev, "%s\n", __func__); - - if (portdata->dtr_state) - val |= 0x01; - if (portdata->rts_state) - val |= 0x02; - - /* If composite device then properly report interface */ - if (serial->num_ports == 1) { - interface = sierra_calc_interface(serial); - /* Control message is sent only to interfaces with - * interrupt_in endpoints - */ - if (port->interrupt_in_urb) { - /* send control message */ - do_send = 1; - } - } - - /* Otherwise the need to do non-composite mapping */ - else { - if (port->bulk_out_endpointAddress == 2) - interface = 0; - else if (port->bulk_out_endpointAddress == 4) - interface = 1; - else if (port->bulk_out_endpointAddress == 5) - interface = 2; - - do_send = 1; - } - if (!do_send) - return 0; - - usb_autopm_get_interface(serial->interface); - retval = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - 0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT); - usb_autopm_put_interface(serial->interface); - - return retval; -} - -static void sierra_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - dev_dbg(&port->dev, "%s\n", __func__); - tty_termios_copy_hw(tty->termios, old_termios); - sierra_send_setup(port); -} - -static int sierra_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned int value; - struct sierra_port_private *portdata; - - dev_dbg(&port->dev, "%s\n", __func__); - portdata = usb_get_serial_port_data(port); - - value = ((portdata->rts_state) ? TIOCM_RTS : 0) | - ((portdata->dtr_state) ? TIOCM_DTR : 0) | - ((portdata->cts_state) ? TIOCM_CTS : 0) | - ((portdata->dsr_state) ? TIOCM_DSR : 0) | - ((portdata->dcd_state) ? TIOCM_CAR : 0) | - ((portdata->ri_state) ? TIOCM_RNG : 0); - - return value; -} - -static int sierra_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct sierra_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - - if (set & TIOCM_RTS) - portdata->rts_state = 1; - if (set & TIOCM_DTR) - portdata->dtr_state = 1; - - if (clear & TIOCM_RTS) - portdata->rts_state = 0; - if (clear & TIOCM_DTR) - portdata->dtr_state = 0; - return sierra_send_setup(port); -} - -static void sierra_release_urb(struct urb *urb) -{ - struct usb_serial_port *port; - if (urb) { - port = urb->context; - dev_dbg(&port->dev, "%s: %p\n", __func__, urb); - usb_free_urb(urb); - } -} - -/* Sysfs Attributes */ - -static ssize_t show_suspend_status(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct usb_serial_port *port; - struct sierra_port_private *portdata; - struct sierra_intf_private *intfdata; - unsigned long flags; - unsigned int flag_suspended = 0; - - port = to_usb_serial_port(dev); - portdata = usb_get_serial_port_data(port); - intfdata = port->serial->private; - - spin_lock_irqsave(&intfdata->susp_lock, flags); - flag_suspended = intfdata->suspended; - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - - return snprintf(buf, PORTION_LEN, "%i\n", flag_suspended); -} - -static ssize_t show_stats(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct usb_serial_port *port; - struct sierra_intf_private *intfdata; - - port = to_usb_serial_port(dev); - intfdata = port->serial->private; - - return snprintf(buf, PORTION_LEN, - "rx: %i B\tindat: %i\tindat err: %i\n" - "tx: %i B\toutdat: %i\toutdat err: %i\n" - "writes: %i\t\twrite err: %i\n" - "delayed writes: %i\tdelayed write err: %i\n", - atomic_read(&intfdata->stats.rx_bytes), atomic_read(&intfdata->stats.indat_cb_cnt), atomic_read(&intfdata->stats.indat_cb_fail), - atomic_read(&intfdata->stats.tx_bytes), atomic_read(&intfdata->stats.outdat_cb_cnt), atomic_read(&intfdata->stats.outdat_cb_fail), - atomic_read(&intfdata->stats.write_cnt), atomic_read(&intfdata->stats.write_err), - atomic_read(&intfdata->stats.delayed_writes), atomic_read(&intfdata->stats.delayed_write_err) - ); -} - -/* Read only suspend status */ -static DEVICE_ATTR(suspend_status, S_IWUSR | S_IRUGO, show_suspend_status, - NULL); - -/* Read only statistics */ -static DEVICE_ATTR(stats, S_IWUSR | S_IRUGO, show_stats, NULL); - -static int sierra_create_sysfs_attrs(struct usb_serial_port *port) -{ - int result = 0; - - result = device_create_file(&port->dev, &dev_attr_stats); - if (unlikely (result < 0)) - return result; - return device_create_file(&port->dev, &dev_attr_suspend_status); -} - -static int sierra_remove_sysfs_attrs(struct usb_serial_port *port) -{ - device_remove_file(&port->dev, &dev_attr_stats); - device_remove_file(&port->dev, &dev_attr_suspend_status); - return 0; -} - -static void sierra_outdat_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - struct sierra_intf_private *intfdata; - int status = urb->status; - - dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); - intfdata = port->serial->private; - - usb_autopm_put_interface_async(port->serial->interface); - - atomic_inc(&intfdata->stats.outdat_cb_cnt); - - if (status) { - dev_dbg(&port->dev, "%s - nonzero write bulk status " - "received: %d\n", __func__, status); - atomic_inc(&intfdata->stats.outdat_cb_fail); - } - - spin_lock(&portdata->lock); - --portdata->outstanding_urbs; - spin_unlock(&portdata->lock); - - spin_lock(&intfdata->susp_lock); - --intfdata->in_flight; - spin_unlock(&intfdata->susp_lock); - - usb_serial_port_softint(port); -} - -/* Write */ -static int sierra_write(struct tty_struct *tty, - struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - struct sierra_intf_private *intfdata; - struct usb_serial *serial = port->serial; - unsigned long flags; - unsigned char *buffer; - struct urb *urb; - size_t writesize = min((size_t)count, (size_t)MAX_TRANSFER); - int retval = 0; - - /* verify that we actually have some data to write */ - if (count == 0) - return 0; - - dev_dbg(&port->dev, "%s: write (%zu bytes)\n", __func__, writesize); - - intfdata = serial->private; - - spin_lock_irqsave(&portdata->lock, flags); - if (portdata->outstanding_urbs > portdata->num_out_urbs) { - spin_unlock_irqrestore(&portdata->lock, flags); - dev_dbg(&port->dev, "%s - write limit hit\n", __func__); - return 0; - } - portdata->outstanding_urbs++; - spin_unlock_irqrestore(&portdata->lock, flags); - - retval = usb_autopm_get_interface_async(serial->interface); - if (unlikely(retval < 0)) { - spin_lock_irqsave(&portdata->lock, flags); - portdata->outstanding_urbs--; - spin_unlock_irqrestore(&portdata->lock, flags); - return retval; - } - - buffer = kmalloc(writesize, GFP_ATOMIC); - if (!buffer) { - dev_err(&port->dev, "out of memory\n"); - spin_lock_irqsave(&portdata->lock, flags); - --portdata->outstanding_urbs; - spin_unlock_irqrestore(&portdata->lock, flags); - usb_autopm_put_interface_async(serial->interface); - return -ENOMEM; - } - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - dev_err(&port->dev, "no more free urbs\n"); - kfree(buffer); - spin_lock_irqsave(&portdata->lock, flags); - --portdata->outstanding_urbs; - spin_unlock_irqrestore(&portdata->lock, flags); - usb_autopm_put_interface_async(serial->interface); - return -ENOMEM; - } - - memcpy(buffer, buf, writesize); - - usb_serial_debug_data(debug, &port->dev, __func__, writesize, buffer); - - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - buffer, writesize, sierra_outdat_callback, port); - - /* Handle the need to send a zero length packet and release the - * transfer buffer - */ - urb->transfer_flags |= (URB_ZERO_PACKET | URB_FREE_BUFFER); - - spin_lock_irqsave(&intfdata->susp_lock, flags); - - if (intfdata->suspended) { - usb_anchor_urb(urb, &portdata->delayed); - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - /* release our reference to this urb, the USB core will - * eventually free it entirely */ - usb_free_urb(urb); - return writesize; - } - usb_anchor_urb(urb, &portdata->active); - - /* send it down the pipe */ - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) { - usb_unanchor_urb(urb); - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - - dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " - "with status = %d\n", __func__, retval); - usb_free_urb(urb); - spin_lock_irqsave(&portdata->lock, flags); - --portdata->outstanding_urbs; - spin_unlock_irqrestore(&portdata->lock, flags); - usb_autopm_put_interface_async(serial->interface); - atomic_inc(&intfdata->stats.write_err); - return retval; - } else { - intfdata->in_flight++; - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - atomic_inc(&intfdata->stats.write_cnt); - atomic_add(writesize, &intfdata->stats.tx_bytes); - } - /* release our reference to this urb, the USB core will eventually - * free it entirely */ - usb_free_urb(urb); - - return writesize; -} - -static void sierra_indat_callback(struct urb *urb) -{ - int err; - int endpoint; - struct usb_serial_port *port = urb->context; - struct tty_struct *tty; - struct sierra_intf_private *intfdata; - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - - endpoint = usb_pipeendpoint(urb->pipe); - - dev_dbg(&port->dev, "%s: %p\n", __func__, urb); - - intfdata = port->serial->private; - - atomic_inc(&intfdata->stats.indat_cb_cnt); /* indat calls */ - - if (status) { - dev_dbg(&port->dev, "%s: nonzero status: %d on" - " endpoint %02x\n", __func__, status, endpoint); - atomic_inc(&intfdata->stats.indat_cb_fail); /* indat fails */ - } else { - if (urb->actual_length) { - tty = tty_port_tty_get(&port->port); - if (tty) { - tty_insert_flip_string(tty, data, - urb->actual_length); - tty_flip_buffer_push(tty); - - tty_kref_put(tty); - /* tty invalid after this point */ - /* rx'd bytes */ - atomic_add(urb->actual_length, - &intfdata->stats.rx_bytes); - usb_serial_debug_data(debug, &port->dev, - __func__, urb->actual_length, data); - } - } else { - dev_dbg(&port->dev, "%s: empty read urb" - " received\n", __func__); - } - } - - /* Resubmit urb so we continue receiving */ - if (status != -ESHUTDOWN && status != -ENOENT && status != -ENODEV) { - usb_mark_last_busy(port->serial->dev); - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err && err != -ENODEV) - dev_err(&port->dev, "resubmit read urb failed." - "(%d)\n", err); - } - - return; -} - -static void sierra_instat_callback(struct urb *urb) -{ - int err; - int status = urb->status; - struct usb_serial_port *port = urb->context; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - struct usb_serial *serial = port->serial; - - dev_dbg(&port->dev, "%s: %p\n", __func__, urb); - - if (status == 0) { - struct usb_ctrlrequest *req_pkt = - (struct usb_ctrlrequest *)urb->transfer_buffer; - - const u16 *sigp = (u16 *)(req_pkt + 1); - /* usb_ctrlrequest we parsed is followed by two bytes of data - * make sure we received that many bytes - */ - if (urb->actual_length >= sizeof(*req_pkt) + sizeof(*sigp) && - req_pkt->bRequestType == USB_REQUEST_TYPE_CLASS && - req_pkt->bRequest == USB_REQUEST_IFACE) { - int old_dcd_state; - const u16 signals = get_unaligned_le16(sigp); - struct tty_struct *tty; - - dev_dbg(&port->dev, "%s: signal 0x%x\n", __func__, - signals); - - old_dcd_state = portdata->dcd_state; - /* Note: CTS from modem is in reverse logic! */ - portdata->cts_state = ((signals & 0x100) ? 0 : 1); - portdata->dcd_state = ((signals & 0x01) ? 1 : 0); - portdata->dsr_state = ((signals & 0x02) ? 1 : 0); - portdata->ri_state = ((signals & 0x08) ? 1 : 0); - - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty) && - old_dcd_state && !portdata->dcd_state) - tty_hangup(tty); - tty_kref_put(tty); - } else { - /* dump the data we don't understand to log */ - usb_serial_debug_data(1, &port->dev, __func__, - urb->actual_length, urb->transfer_buffer); - } - } else - dev_dbg(&port->dev, "%s: error %d\n", __func__, status); - - /* Resubmit urb so we continue receiving IRQ data */ - if (status != -ESHUTDOWN && status != -ENOENT && status != -ENODEV) { - usb_mark_last_busy(serial->dev); - urb->dev = serial->dev; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err && err != -ENODEV) - dev_err(&port->dev, "%s: resubmit intr urb " - "failed. (%d)\n", __func__, err); - } -} - -static int sierra_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - unsigned long flags; - int retval; - - dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); - - /* try to give a good number back based on if we have any free urbs at - * this point in time */ - retval = MAX_TRANSFER; - - spin_lock_irqsave(&portdata->lock, flags); - if (portdata->outstanding_urbs >= portdata->num_out_urbs) { - retval = 0; - } - spin_unlock_irqrestore(&portdata->lock, flags); - - return retval; -} - -static void sierra_stop_rx_urbs(struct usb_serial_port *port) -{ - int i; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - - for (i = 0; i < portdata->num_in_urbs; i++) - usb_kill_urb(portdata->in_urbs[i]); - - usb_kill_urb(port->interrupt_in_urb); -} - -static int sierra_submit_rx_urbs(struct usb_serial_port *port, gfp_t mem_flags) -{ - int ok_cnt; - int err = -EINVAL; - int i; - struct urb *urb; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - - ok_cnt = 0; - for (i = 0; i < portdata->num_in_urbs; i++) { - urb = portdata->in_urbs[i]; - if (!urb) - continue; - urb->transfer_flags |= URB_FREE_BUFFER; - err = usb_submit_urb(urb, mem_flags); - if (err) { - dev_err(&port->dev, "%s: submit urb failed: %d\n", - __func__, err); - } else { - ok_cnt++; - } - } - - if (ok_cnt && port->interrupt_in_urb) { - err = usb_submit_urb(port->interrupt_in_urb, mem_flags); - if (err) { - dev_err(&port->dev, "%s: submit intr urb failed: %d\n", - __func__, err); - } - } - - if (ok_cnt > 0) /* at least one rx urb submitted */ - return 0; - else - return err; -} - -static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint, - int dir, void *ctx, int len, - gfp_t mem_flags, - usb_complete_t callback) -{ - struct urb *urb; - u8 *buf; - - if (endpoint == -1) - return NULL; - - urb = usb_alloc_urb(0, mem_flags); - if (urb == NULL) { - dev_dbg(&serial->dev->dev, "%s: alloc for endpoint %d failed\n", - __func__, endpoint); - return NULL; - } - - buf = kmalloc(len, mem_flags); - if (buf) { - /* Fill URB using supplied data */ - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, endpoint) | dir, - buf, len, callback, ctx); - - /* debug */ - dev_dbg(&serial->dev->dev, "%s %c u : %p d:%p\n", __func__, - dir == USB_DIR_IN ? 'i' : 'o', urb, buf); - } else { - dev_dbg(&serial->dev->dev, "%s %c u:%p d:%p\n", __func__, - dir == USB_DIR_IN ? 'i' : 'o', urb, buf); - - sierra_release_urb(urb); - urb = NULL; - } - - return urb; -} -static void sierra_close(struct usb_serial_port *port) -{ - int i; - struct urb *urb; - struct usb_serial *serial = port->serial; - struct sierra_port_private *portdata; - struct sierra_intf_private *intfdata = port->serial->private; - - dev_dbg(&port->dev, "%s\n", __func__); - portdata = usb_get_serial_port_data(port); - - portdata->rts_state = 0; - portdata->dtr_state = 0; - - usb_autopm_get_interface(serial->interface); - - if (serial->dev) { - mutex_lock(&serial->disc_mutex); - if (!serial->disconnected) - sierra_send_setup(port); - mutex_unlock(&serial->disc_mutex); - spin_lock_irq(&intfdata->susp_lock); - portdata->opened = 0; - spin_unlock_irq(&intfdata->susp_lock); - - /* Stop reading urbs */ - sierra_stop_rx_urbs(port); - /* .. and release them */ - for (i = 0; i < portdata->num_in_urbs; i++) { - sierra_release_urb(portdata->in_urbs[i]); - portdata->in_urbs[i] = NULL; - } - while((urb = usb_get_from_anchor(&portdata->delayed))) { - sierra_release_urb(urb); - usb_autopm_put_interface(serial->interface); - } - /* wait for active to finish */ - usb_wait_anchor_empty_timeout(&portdata->active, 500); - usb_kill_anchored_urbs(&portdata->active); - - } -} - -static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct sierra_port_private *portdata; - struct usb_serial *serial = port->serial; - struct sierra_intf_private *intfdata = serial->private; - int i; - int err; - int endpoint; - struct urb *urb; - - portdata = usb_get_serial_port_data(port); - - dev_dbg(&port->dev, "%s\n", __func__); - - /* Set some sane defaults */ - portdata->rts_state = 1; - portdata->dtr_state = 1; - - - endpoint = port->bulk_in_endpointAddress; - for (i = 0; i < portdata->num_in_urbs; i++) { - urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port, - IN_BUFLEN, GFP_KERNEL, - sierra_indat_callback); - portdata->in_urbs[i] = urb; - } - /* clear halt condition */ - usb_clear_halt(serial->dev, - usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN); - - /* reset outstanding out urbs counter */ - spin_lock_irq(&portdata->lock); - portdata->outstanding_urbs = 0; - spin_unlock_irq(&portdata->lock); - - err = sierra_submit_rx_urbs(port, GFP_KERNEL); - if (err) { - /* do everything as in close() but do not call close() because - * usbserial calls sierra_open() with mutex taken; - * then if we call sierra_close() inside sierra_open() we - * violate 'no nested mutexes' kernel condition - */ - portdata->rts_state = 0; - portdata->dtr_state = 0; - usb_autopm_get_interface(serial->interface); - /* Stop reading urbs */ - sierra_stop_rx_urbs(port); - /* .. and release them */ - for (i = 0; i < portdata->num_in_urbs; i++) { - sierra_release_urb(portdata->in_urbs[i]); - portdata->in_urbs[i] = NULL; - } - while((urb = usb_get_from_anchor(&portdata->delayed))) { - sierra_release_urb(urb); - usb_autopm_put_interface(serial->interface); - } - /* wait for active to finish */ - usb_wait_anchor_empty_timeout(&portdata->active, 500); - usb_kill_anchored_urbs(&portdata->active); - /* restore balance for autopm */ - usb_autopm_put_interface(serial->interface); - return err; - } - sierra_send_setup(port); - - spin_lock_irq(&intfdata->susp_lock); - portdata->opened = 1; - spin_unlock_irq(&intfdata->susp_lock); - usb_autopm_put_interface(serial->interface); - - return 0; -} - -static void sierra_dtr_rts(struct usb_serial_port *port, int on) -{ - struct usb_serial *serial = port->serial; - struct sierra_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - portdata->rts_state = on; - portdata->dtr_state = on; - - if (serial->dev) { - mutex_lock(&serial->disc_mutex); - if (!serial->disconnected) - sierra_send_setup(port); - mutex_unlock(&serial->disc_mutex); - } -} - -static int sierra_startup(struct usb_serial *serial) -{ - struct usb_serial_port *port = NULL; - struct sierra_port_private *portdata = NULL; - struct sierra_iface_info *himemoryp = NULL; - int i; - u8 ifnum; - u16 fw_attr; - int result; - - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - /* Set Device mode to D0 */ - sierra_set_power_state(serial->dev, 0x0000); - - /* Check NMEA and set */ - if (nmea) - sierra_vsc_set_nmea(serial->dev, 1); - - if (serial->num_ports) { - /* Note: One big piece of memory is allocated for all ports - * private data in one shot. This memory is split into equal - * pieces for each port. - */ - portdata = (struct sierra_port_private *)kzalloc - (sizeof(*portdata) * serial->num_ports, GFP_KERNEL); - if (!portdata) { - dev_dbg(&serial->dev->dev, "%s: No memory!\n", __func__); - return -ENOMEM; - } - } - - /* Now setup per port private data */ - for (i = 0; i < serial->num_ports; i++, portdata++) { - port = serial->port[i]; - /* Initialize selected members of private data because these - * may be referred to right away */ - spin_lock_init(&portdata->lock); - init_usb_anchor(&portdata->active); - init_usb_anchor(&portdata->delayed); - - portdata->cts_state = 1; - - ifnum = i; - /* Assume low memory requirements */ - portdata->num_out_urbs = N_OUT_URB; - portdata->num_in_urbs = N_IN_URB; - - /* Determine actual memory requirements */ - if (serial->num_ports == 1) { - /* Get interface number for composite device */ - ifnum = sierra_calc_interface(serial); - himemoryp = - (struct sierra_iface_info *)&typeB_interface_list; - if (is_himemory(ifnum, himemoryp)) { - portdata->num_out_urbs = N_OUT_URB_HM; - portdata->num_in_urbs = N_IN_URB_HM; - } - } - else { - himemoryp = - (struct sierra_iface_info *)&typeA_interface_list; - if (is_himemory(i, himemoryp)) { - portdata->num_out_urbs = N_OUT_URB_HM; - portdata->num_in_urbs = N_IN_URB_HM; - } - } - dev_dbg(&serial->dev->dev, - "Memory usage (urbs) interface #%d, in=%d, out=%d\n", - ifnum,portdata->num_in_urbs, portdata->num_out_urbs ); - /* Set the port private data pointer */ - usb_set_serial_port_data(port, portdata); - } - serial->interface->needs_remote_wakeup = 1; - - result = sierra_get_fw_attr(serial->dev, &fw_attr); - if (result == sizeof(fw_attr) && (fw_attr & SWI_FW_ATTR_PM_MASK) ) { - dev_info(&serial->dev->dev, - "APM supported, enabling autosuspend.\n"); -/******************************************************************************* - * If you want the default /sys/bus/usb/devices/.../.../power/level to be forced - * to auto, the following needs to be compiled in. - */ -#ifdef POWER_LEVEL_AUTO - /* make power level default be 'auto' */ - usb_enable_autosuspend(serial->dev); -#endif - } else { - usb_disable_autosuspend(serial->dev); - } - - return 0; -} - -static void sierra_release(struct usb_serial *serial) -{ - int i; - struct usb_serial_port *port; - struct sierra_intf_private *intfdata = serial->private; - - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - if (serial->num_ports > 0) { - port = serial->port[0]; - if (port) - /* Note: The entire piece of memory that was allocated - * in the startup routine can be released by passing - * a pointer to the beginning of the piece. - * This address corresponds to the address of the chunk - * that was given to port 0. - */ - kfree(usb_get_serial_port_data(port)); - } - - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - if (!port) - continue; - usb_set_serial_port_data(port, NULL); - } - kfree(intfdata); -} - -#ifdef CONFIG_PM -static void stop_read_write_urbs(struct usb_serial *serial) -{ - int i; - struct usb_serial_port *port; - struct sierra_port_private *portdata; - - /* Stop reading/writing urbs */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - sierra_stop_rx_urbs(port); - usb_kill_anchored_urbs(&portdata->active); - } -} - -static int sierra_suspend(struct usb_serial *serial, pm_message_t message) -{ - struct sierra_intf_private *intfdata; - - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - intfdata = serial->private; - spin_lock_irq(&intfdata->susp_lock); - - if (message.event & PM_EVENT_AUTO) { - if (intfdata->in_flight) { - spin_unlock_irq(&intfdata->susp_lock); - return -EBUSY; - } - } - intfdata->suspended = 1; - spin_unlock_irq(&intfdata->susp_lock); - - stop_read_write_urbs(serial); - - return 0; -} - -static int sierra_resume(struct usb_serial *serial) -{ - struct usb_serial_port *port; - struct sierra_intf_private *intfdata = serial->private; - struct sierra_port_private *portdata; - struct urb *urb; - int ec = 0; - int i, err; - int len; - int failed_submits; - - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - spin_lock_irq(&intfdata->susp_lock); - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - failed_submits = 0; - while ((urb = usb_get_from_anchor(&portdata->delayed))) { - usb_anchor_urb(urb, &portdata->active); - intfdata->in_flight++; - len = urb->transfer_buffer_length; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - intfdata->in_flight--; - usb_unanchor_urb(urb); - failed_submits++; - atomic_inc(&intfdata->stats.delayed_write_err); - /* fix pm_usage_cnt */ - usb_autopm_put_interface_async( - port->serial->interface); - } else { - atomic_inc(&intfdata->stats.delayed_writes); - atomic_add(len, &intfdata->stats.tx_bytes); - } - /* release urb - usb_get_from_anchor increased kref */ - usb_free_urb(urb); - } - - if (portdata->opened) { - err = sierra_submit_rx_urbs(port, GFP_ATOMIC); - if (err) - ec++; - } - if (failed_submits) { - /* fix outstanding_urbs counter */ - spin_lock(&portdata->lock); /* assuming irq disabled */ - portdata->outstanding_urbs -= failed_submits; - spin_unlock(&portdata->lock); - /* unblock a writer */ - usb_serial_port_softint(port); - } - } - intfdata->suspended = 0; - spin_unlock_irq(&intfdata->susp_lock); - - return ec ? -EIO : 0; -} -#else -#define sierra_suspend NULL -#define sierra_resume NULL -#endif - -static int sierra_reset_resume(struct usb_interface *intf) -{ - struct usb_serial *serial = usb_get_intfdata(intf); - dev_err(&serial->dev->dev, "%s\n", __func__); - return usb_serial_resume(intf); -} - -static struct usb_driver sierra_driver = { - .name = "sierra", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .suspend = usb_serial_suspend, - .resume = usb_serial_resume, - .reset_resume = sierra_reset_resume, - .id_table = id_table, - - .no_dynamic_id = 1, - .supports_autosuspend = 1, -}; - - -static struct usb_serial_driver sierra_device = { - .driver = { - .owner = THIS_MODULE, - .name = "sierra", - }, - .description = "Sierra USB modem", - .id_table = id_table, - .usb_driver = &sierra_driver, - .calc_num_ports = sierra_calc_num_ports, - .probe = sierra_probe, - .open = sierra_open, - .close = sierra_close, - .dtr_rts = sierra_dtr_rts, - .write = sierra_write, - .write_room = sierra_write_room, - .set_termios = sierra_set_termios, - .tiocmget = sierra_tiocmget, - .tiocmset = sierra_tiocmset, - .attach = sierra_startup, - .release = sierra_release, - .port_probe = sierra_create_sysfs_attrs, - .port_remove = sierra_remove_sysfs_attrs, - .suspend = sierra_suspend, - .resume = sierra_resume, - .read_int_callback = sierra_instat_callback, - -}; - -/* Functions used by new usb-serial code. */ -static int __init sierra_init(void) -{ - int retval; - retval = usb_serial_register(&sierra_device); - if (retval) - goto failed_device_register; - - retval = usb_register(&sierra_driver); - if (retval) - goto failed_driver_register; - - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); - - return 0; - -failed_driver_register: - usb_serial_deregister(&sierra_device); -failed_device_register: - return retval; -} - -static void __exit sierra_exit(void) -{ - usb_deregister(&sierra_driver); - usb_serial_deregister(&sierra_device); -} - -module_init(sierra_init); -module_exit(sierra_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(nmea, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(nmea, "NMEA streaming"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug messages"); diff --git a/extra/sierra-directip/src/sierra_net.c b/extra/sierra-directip/src/sierra_net.c deleted file mode 100644 index f6057d918..000000000 --- a/extra/sierra-directip/src/sierra_net.c +++ /dev/null @@ -1,1123 +0,0 @@ -/* - * USB-to-WWAN Driver for Sierra Wireless modems - * - * Copyright (C) 2008 - 2011 Paxton Smith, Matthew Safar, Rory Filer - * - * - * Portions of this based on the cdc_ether driver by David Brownell (2003-2005) - * and Ole Andre Vadla Ravnas (ActiveSync) (2006). - * - * IMPORTANT DISCLAIMER: This driver is not commercially supported by - * Sierra Wireless. Use at your own risk. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define DRIVER_VERSION "v.3.2" -#define DRIVER_AUTHOR "Paxton Smith, Matthew Safar, Rory Filer" -#define DRIVER_DESC "USB-to-WWAN Driver for Sierra Wireless modems" -static const char driver_name[] = "sierra_net"; - -/* if defined debug messages enabled */ -/*#define DEBUG*/ -/* more debug messages */ -/*#define VERBOSE*/ -/* Uncomment to force power level set to auto when attaching a device */ -/*#define POWER_LEVEL_AUTO*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SWI_USB_REQUEST_GET_FW_ATTR 0x06 -#define SWI_GET_FW_ATTR_MASK 0x08 -#define SWI_GET_FW_ATTR_APM 0x2 - -/* atomic counter partially included in MAC address to make sure 2 devices - * do not end up with the same MAC - concept breaks in case of > 255 ifaces - */ -static atomic_t iface_counter = ATOMIC_INIT(0); - -/* - * SYNC Timer Delay definition used to set the expiry time - */ -#define SIERRA_NET_SYNCDELAY (2*HZ) - -/* Max. MTU supported. The modem buffers are limited to 1500 */ -#define SIERRA_NET_MAX_SUPPORTED_MTU 1500 - -/* The SIERRA_NET_USBCTL_BUF_LEN defines a buffer size allocated for control - * message reception ... and thus the max. received packet. - * (May be the cause for parse_hip returning -EINVAL) - */ -#define SIERRA_NET_USBCTL_BUF_LEN 1024 - -/* The SIERRA_NET_RX_URB_SZ defines the receive urb size - * for optimal throughput. - */ -#define SIERRA_NET_RX_URB_SZ 1540 - -/* list of interface numbers - used for constructing interface lists */ -struct sierra_net_iface_info { - const u32 infolen; /* number of interface numbers on list */ - const u8 *ifaceinfo; /* pointer to the array holding the numbers */ -}; - -struct sierra_net_info_data { - u16 rx_urb_size; - struct sierra_net_iface_info whitelist; -}; - -/* Private data structure */ -struct sierra_net_data { - - u8 ethr_hdr_tmpl[ETH_HLEN]; /* ethernet header template for rx'd pkts */ - - u16 link_up; /* air link up or down */ - u8 tx_hdr_template[4]; /* part of HIP hdr for tx'd packets */ - - u8 sync_msg[4]; /* SYNC message */ - u8 shdwn_msg[4]; /* Shutdown message */ - - /* Backpointer to the container */ - struct usbnet *usbnet; - - u8 ifnum; /* interface number */ - -/* Bit masks, must be a power of 2 */ -#define SIERRA_NET_EVENT_RESP_AVAIL 0x01 -#define SIERRA_NET_TIMER_EXPIRY 0x02 - unsigned long kevent_flags; - struct work_struct sierra_net_kevent; - struct timer_list sync_timer; /* For retrying SYNC sequence */ -}; - -struct param { - int is_present; - union { - void *ptr; - u32 dword; - u16 word; - u8 byte; - }; -}; - -/* HIP message type */ -#define SIERRA_NET_HIP_EXTENDEDID 0x7F -#define SIERRA_NET_HIP_HSYNC_ID 0x60 /* Modem -> host */ -#define SIERRA_NET_HIP_RESTART_ID 0x62 /* Modem -> host */ -#define SIERRA_NET_HIP_MSYNC_ID 0x20 /* Host -> modem */ -#define SIERRA_NET_HIP_SHUTD_ID 0x26 /* Host -> modem */ - -#define SIERRA_NET_HIP_EXT_IP_IN_ID 0x0202 -#define SIERRA_NET_HIP_EXT_IP_OUT_ID 0x0002 - -/* 3G UMTS Link Sense Indication definitions */ -#define SIERRA_NET_HIP_LSI_UMTSID 0x78 - -/* Reverse Channel Grant Indication HIP message */ -#define SIERRA_NET_HIP_RCGI 0x64 - -/* LSI Protocol types */ -#define SIERRA_NET_PROTOCOL_UMTS 0x01 -/* LSI Coverage */ -#define SIERRA_NET_COVERAGE_NONE 0x00 -#define SIERRA_NET_COVERAGE_NOPACKET 0x01 - -/* LSI Session */ -#define SIERRA_NET_SESSION_IDLE 0x00 -/* LSI Link types */ -#define SIERRA_NET_AS_LINK_TYPE_IPv4 0x00 -#define SIERRA_NET_AS_LINK_TYPE_IPv6 0x02 - -struct lsi_umts { - u8 protocol; - u8 unused1; - __be16 length; - /* eventually use a union for the rest - assume umts for now */ - u8 coverage; - u8 unused2[41]; - u8 session_state; - u8 unused3[33]; - u8 link_type; - u8 pdp_addr_len; /* NW-supplied PDP address len */ - u8 pdp_addr[16]; /* NW-supplied PDP address (bigendian)) */ - u8 unused4[23]; - u8 dns1_addr_len; /* NW-supplied 1st DNS address len (bigendian) */ - u8 dns1_addr[16]; /* NW-supplied 1st DNS address */ - u8 dns2_addr_len; /* NW-supplied 2nd DNS address len */ - u8 dns2_addr[16]; /* NW-supplied 2nd DNS address (bigendian)*/ - u8 wins1_addr_len; /* NW-supplied 1st Wins address len */ - u8 wins1_addr[16]; /* NW-supplied 1st Wins address (bigendian)*/ - u8 wins2_addr_len; /* NW-supplied 2nd Wins address len */ - u8 wins2_addr[16]; /* NW-supplied 2nd Wins address (bigendian) */ - u8 unused5[4]; - u8 gw_addr_len; /* NW-supplied GW address len */ - u8 gw_addr[16]; /* NW-supplied GW address (bigendian) */ - u8 reserved[8]; -} __packed; - -#define SIERRA_NET_LSI_COMMON_LEN 4 -#define SIERRA_NET_LSI_UMTS_LEN (sizeof(struct lsi_umts)) -#define SIERRA_NET_LSI_UMTS_STATUS_LEN \ - (SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN) - -/* Forward definitions */ -static void sierra_sync_timer(unsigned long syncdata); -static int sierra_net_change_mtu(struct net_device *net, int new_mtu); - -/* Our own net device operations structure */ -static const struct net_device_ops sierra_net_device_ops = { - .ndo_open = usbnet_open, - .ndo_stop = usbnet_stop, - .ndo_start_xmit = usbnet_start_xmit, - .ndo_tx_timeout = usbnet_tx_timeout, - .ndo_change_mtu = sierra_net_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -/* get private data associated with passed in usbnet device */ -static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev) -{ - return (struct sierra_net_data *)dev->data[0]; -} - -/* set private data associated with passed in usbnet device */ -static inline void sierra_net_set_private(struct usbnet *dev, - struct sierra_net_data *priv) -{ - dev->data[0] = (unsigned long)priv; -} - -/* is packet IP */ -static inline int is_ip(struct sk_buff *skb) -{ - return ((skb->protocol == cpu_to_be16(ETH_P_IP)) || - (skb->protocol == cpu_to_be16(ETH_P_IPV6))); -} - -/* - * check passed in packet and make sure that: - * - it is linear (no scatter/gather) - * - it is ethernet (mac_header properly set) - */ -static int check_ethip_packet(struct sk_buff *skb, struct usbnet *dev) -{ - skb_reset_mac_header(skb); /* ethernet header */ - - if (skb_is_nonlinear(skb)) { - netdev_err(dev->net, "Non linear buffer-dropping\n"); - return 0; - } - - if (!pskb_may_pull(skb, ETH_HLEN)) - return 0; - skb->protocol = eth_hdr(skb)->h_proto; - - return 1; -} - -static const u8 *save16bit(struct param *p, const u8 *datap) -{ - p->is_present = 1; - p->word = get_unaligned_be16(datap); - return datap + sizeof(p->word); -} - -static const u8 *save8bit(struct param *p, const u8 *datap) -{ - p->is_present = 1; - p->byte = *datap; - return datap + sizeof(p->byte); -} - -/*----------------------------------------------------------------------------* - * BEGIN HIP * - *----------------------------------------------------------------------------*/ -/* HIP header */ -#define SIERRA_NET_HIP_HDR_LEN 4 -/* Extended HIP header */ -#define SIERRA_NET_HIP_EXT_HDR_LEN 6 - -struct hip_hdr { - int hdrlen; - struct param payload_len; - struct param msgid; - struct param msgspecific; - struct param extmsgid; -}; - -static int parse_hip(const u8 *buf, const u32 buflen, struct hip_hdr *hh) -{ - const u8 *curp = buf; - int padded; - - if (buflen < SIERRA_NET_HIP_HDR_LEN) - return -EPROTO; - - curp = save16bit(&hh->payload_len, curp); - curp = save8bit(&hh->msgid, curp); - curp = save8bit(&hh->msgspecific, curp); - - padded = hh->msgid.byte & 0x80; - hh->msgid.byte &= 0x7F; /* 7 bits */ - - hh->extmsgid.is_present = (hh->msgid.byte == SIERRA_NET_HIP_EXTENDEDID); - if (hh->extmsgid.is_present) { - if (buflen < SIERRA_NET_HIP_EXT_HDR_LEN) - return -EPROTO; - - hh->payload_len.word &= 0x3FFF; /* 14 bits */ - - curp = save16bit(&hh->extmsgid, curp); - hh->extmsgid.word &= 0x03FF; /* 10 bits */ - - hh->hdrlen = SIERRA_NET_HIP_EXT_HDR_LEN; - } else { - hh->payload_len.word &= 0x07FF; /* 11 bits */ - hh->hdrlen = SIERRA_NET_HIP_HDR_LEN; - } - - if (padded) { - hh->hdrlen++; - hh->payload_len.word--; - } - - /* if real packet shorter than the claimed length */ - if (buflen < (hh->hdrlen + hh->payload_len.word)) - return -EINVAL; - - return 0; -} - -static void build_hip(u8 *buf, const u16 payloadlen, - struct sierra_net_data *priv) -{ - /* the following doesn't have the full functionality. We - * currently build only one kind of header, so it is faster this way - */ - put_unaligned_be16(payloadlen, buf); - memcpy(buf+2, priv->tx_hdr_template, sizeof(priv->tx_hdr_template)); -} -/*----------------------------------------------------------------------------* - * END HIP * - *----------------------------------------------------------------------------*/ -/* This should come out before going to kernel.org */ -static void sierra_net_printk_buf(u8 *buf, u16 len) -{ -#ifdef VERBOSE - u16 i; - u16 k; - - for (i = k = 0; i < len / 4; i++, k += 4) { - printk(KERN_DEBUG "%02x%02x%02x%02x ", - buf[k+0], buf[k+1], buf[k+2], buf[k+3]); - } - - for (; k < len; k++) - printk(KERN_DEBUG "%02x", buf[k]); - - printk("\n"); -#endif -} - -static int sierra_net_send_cmd(struct usbnet *dev, - u8 *cmd, int cmdlen, const char * cmd_name) -{ - struct sierra_net_data *priv = sierra_net_get_private(dev); - int status; - - usb_autopm_get_interface(dev->intf); - status = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), - USB_CDC_SEND_ENCAPSULATED_COMMAND, - USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE, 0, - priv->ifnum, cmd, cmdlen, USB_CTRL_SET_TIMEOUT); - usb_autopm_put_interface(dev->intf); - - if (status != cmdlen && status != -ENODEV) - netdev_err(dev->net, "Submit %s failed %d\n", cmd_name, status); - - return status; -} - -static int sierra_net_send_sync(struct usbnet *dev) -{ - int status; - struct sierra_net_data *priv = sierra_net_get_private(dev); - - dev_dbg(&dev->udev->dev, "%s", __func__); - - status = sierra_net_send_cmd(dev, priv->sync_msg, - sizeof(priv->sync_msg), "SYNC"); - return status; -} - -static void sierra_net_send_shutdown(struct usbnet *dev) -{ - struct sierra_net_data *priv = sierra_net_get_private(dev); - - dev_dbg(&dev->udev->dev, "%s", __func__); - - sierra_net_send_cmd(dev, priv->shdwn_msg, - sizeof(priv->shdwn_msg), "Shutdown"); -} - -static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix) -{ - dev_dbg(&(priv->usbnet->udev->dev), "%s %d", __func__, ctx_ix); - priv->tx_hdr_template[0] = 0x3F; - priv->tx_hdr_template[1] = ctx_ix; - *((u16 *)&priv->tx_hdr_template[2]) = - cpu_to_be16(SIERRA_NET_HIP_EXT_IP_OUT_ID); -} - -static inline int sierra_net_is_valid_addrlen(u8 len) -{ - return (len == sizeof(struct in_addr)); -} - -static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen) -{ - struct lsi_umts *lsi = (struct lsi_umts *)data; - - if (datalen < sizeof(struct lsi_umts)) { - netdev_err(dev->net, "%s: Data length %d, exp %Zu\n", - __func__, datalen, - sizeof(struct lsi_umts)); - return -1; - } - - if (lsi->length != cpu_to_be16(SIERRA_NET_LSI_UMTS_STATUS_LEN)) { - netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, exp %u\n", - __func__, be16_to_cpu(lsi->length), - (u32)SIERRA_NET_LSI_UMTS_STATUS_LEN); - return -1; - } - - /* Validate the protocol - only support UMTS for now */ - if (lsi->protocol != SIERRA_NET_PROTOCOL_UMTS) { - netdev_err(dev->net, "Protocol unsupported, 0x%02x\n", - lsi->protocol); - return -1; - } - - /* Validate the link type */ - if ((lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) && - (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv6)) { - netdev_err(dev->net, "Link unavailable: 0x%02x", - lsi->link_type); - return 0; - } - - /* Validate the coverage */ - if (lsi->coverage == SIERRA_NET_COVERAGE_NONE - || lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) { - netdev_err(dev->net, "No coverage, 0x%02x\n", lsi->coverage); - return 0; - } - - /* Validate the session state */ - if (lsi->session_state == SIERRA_NET_SESSION_IDLE) { - netdev_err(dev->net, "Session idle, 0x%02x\n", - lsi->session_state); - return 0; - } - - /* Set link_sense true */ - return 1; -} - -static void sierra_net_handle_lsi(struct usbnet *dev, char *data, - struct hip_hdr *hh) -{ - struct sierra_net_data *priv = sierra_net_get_private(dev); - int link_up; - - link_up = sierra_net_parse_lsi(dev, data + hh->hdrlen, - hh->payload_len.word); - if (link_up < 0) { - netdev_err(dev->net, "Invalid LSI\n"); - return; - } - if (link_up) { - sierra_net_set_ctx_index(priv, hh->msgspecific.byte); - priv->link_up = 1; - netif_carrier_on(dev->net); - } else { - priv->link_up = 0; - netif_carrier_off(dev->net); - } -} - -static void sierra_net_dosync(struct usbnet *dev) -{ - int status; - struct sierra_net_data *priv = sierra_net_get_private(dev); - - dev_dbg(&dev->udev->dev, "%s", __func__); - - /* tell modem we are ready */ - status = sierra_net_send_sync(dev); - if (status < 0) - netdev_err(dev->net, - "Send SYNC failed, status %d\n", status); - status = sierra_net_send_sync(dev); - if (status < 0) - netdev_err(dev->net, - "Send SYNC failed, status %d\n", status); - - /* Now, start a timer and make sure we get the Restart Indication */ - priv->sync_timer.function = sierra_sync_timer; - priv->sync_timer.data = (unsigned long) dev; - priv->sync_timer.expires = jiffies + SIERRA_NET_SYNCDELAY; - add_timer(&priv->sync_timer); -} - -static void sierra_net_kevent(struct work_struct *work) -{ - struct sierra_net_data *priv = - container_of(work, struct sierra_net_data, sierra_net_kevent); - struct usbnet *dev = priv->usbnet; - int len; - int err; - u8 *buf; - u8 ifnum; - - if (test_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags)) { - clear_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags); - - /* Query the modem for the LSI message */ - buf = kzalloc(SIERRA_NET_USBCTL_BUF_LEN, GFP_KERNEL); - if (!buf) { - netdev_err(dev->net, - "failed to allocate buf for LS msg\n"); - return; - } - ifnum = priv->ifnum; - usb_autopm_get_interface(dev->intf); - len = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), - USB_CDC_GET_ENCAPSULATED_RESPONSE, - USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE, - 0, ifnum, buf, SIERRA_NET_USBCTL_BUF_LEN, - USB_CTRL_SET_TIMEOUT); - usb_autopm_put_interface(dev->intf); - - if (unlikely(len < 0)) { - netdev_err(dev->net, - "usb_control_msg failed, status %d\n", len); - } else { - struct hip_hdr hh; - - dev_dbg(&dev->udev->dev, "%s: Received status message," - " %04x bytes", __func__, len); - sierra_net_printk_buf(buf, len); - - err = parse_hip(buf, len, &hh); - if (err) { - netdev_err(dev->net, "%s: Bad packet," - " parse result %d\n", __func__, err); - kfree(buf); - return; - } - - /* Validate packet length */ - if (len != hh.hdrlen + hh.payload_len.word) { - netdev_err(dev->net, "%s: Bad packet, received" - " %d, expected %d\n", __func__, len, - hh.hdrlen + hh.payload_len.word); - kfree(buf); - return; - } - - /* Switch on received message types */ - switch (hh.msgid.byte) { - case SIERRA_NET_HIP_LSI_UMTSID: - dev_dbg(&dev->udev->dev, "LSI for ctx:%d", - hh.msgspecific.byte); - sierra_net_handle_lsi(dev, buf, &hh); - break; - case SIERRA_NET_HIP_RESTART_ID: - dev_dbg(&dev->udev->dev, "Restart reported: %d," - " stopping sync timer", - hh.msgspecific.byte); - /* Got sync resp - stop timer & clear mask */ - del_timer_sync(&priv->sync_timer); - clear_bit(SIERRA_NET_TIMER_EXPIRY, - &priv->kevent_flags); - break; - case SIERRA_NET_HIP_HSYNC_ID: - dev_dbg(&dev->udev->dev, "SYNC received"); - err = sierra_net_send_sync(dev); - if (err < 0) - netdev_err(dev->net, - "Send SYNC failed %d\n", err); - break; - case SIERRA_NET_HIP_EXTENDEDID: - netdev_err(dev->net, "Unrecognized HIP msg, " - "extmsgid 0x%04x\n", hh.extmsgid.word); - break; - case SIERRA_NET_HIP_RCGI: - /* Ignored. It is a firmware - * workaround to solve a Windows driver bug and - * may be removed in the future. - */ - break; - default: - netdev_err(dev->net, "Unrecognized HIP msg, " - "msgid 0x%02x\n", hh.msgid.byte); - break; - } - } - kfree(buf); - } - /* The sync timer bit might be set */ - if (test_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags)) { - clear_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags); - dev_dbg(&dev->udev->dev, "Deferred sync timer expiry"); - sierra_net_dosync(priv->usbnet); - } - - if (priv->kevent_flags) - dev_dbg(&dev->udev->dev, "sierra_net_kevent done, " - "kevent_flags = 0x%lx", priv->kevent_flags); -} - -static void sierra_net_defer_kevent(struct usbnet *dev, int work) -{ - struct sierra_net_data *priv = sierra_net_get_private(dev); - - set_bit(work, &priv->kevent_flags); - if (!schedule_work(&priv->sierra_net_kevent)) - dev_dbg(&dev->udev->dev, "sierra_net_kevent %d may have been dropped", work); - else - dev_dbg(&dev->udev->dev, "sierra_net_kevent %d scheduled", work); -} - -/* - * Sync Retransmit Timer Handler. On expiry, kick the work queue - */ -void sierra_sync_timer(unsigned long syncdata) -{ - struct usbnet *dev = (struct usbnet *)syncdata; - - dev_dbg(&dev->udev->dev, "%s", __func__); - /* Kick the tasklet */ - sierra_net_defer_kevent(dev, SIERRA_NET_TIMER_EXPIRY); -} - -static void sierra_net_status(struct usbnet *dev, struct urb *urb) -{ - struct usb_cdc_notification *event; - - dev_dbg(&dev->udev->dev, "%s", __func__); - sierra_net_printk_buf(urb->transfer_buffer, urb->actual_length); - - if (urb->actual_length < sizeof *event) - return; - - /* Add cases to handle other standard notifications. */ - event = urb->transfer_buffer; - switch (event->bNotificationType) { - case USB_CDC_NOTIFY_NETWORK_CONNECTION: - case USB_CDC_NOTIFY_SPEED_CHANGE: - /* USB 305 sends those */ - break; - case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: - sierra_net_defer_kevent(dev, SIERRA_NET_EVENT_RESP_AVAIL); - break; - default: - netdev_err(dev->net, ": unexpected notification %02x!\n", - event->bNotificationType); - break; - } -} - -static void sierra_net_get_drvinfo(struct net_device *net, - struct ethtool_drvinfo *info) -{ - /* Inherit standard device info */ - usbnet_get_drvinfo(net, info); - strncpy(info->driver, driver_name, sizeof info->driver); - strncpy(info->version, DRIVER_VERSION, sizeof info->version); -} - -static u32 sierra_net_get_link(struct net_device *net) -{ - struct usbnet *dev = netdev_priv(net); - /* Report link is down whenever the interface is down */ - return sierra_net_get_private(dev)->link_up && netif_running(net); -} - -static struct ethtool_ops sierra_net_ethtool_ops = { - .get_drvinfo = sierra_net_get_drvinfo, - .get_link = sierra_net_get_link, - .get_msglevel = usbnet_get_msglevel, - .set_msglevel = usbnet_set_msglevel, - .get_settings = usbnet_get_settings, - .set_settings = usbnet_set_settings, - .nway_reset = usbnet_nway_reset, -}; - -/* MTU can not be more than 1500 bytes, enforce it. */ -static int sierra_net_change_mtu(struct net_device *net, int new_mtu) -{ - if (new_mtu > SIERRA_NET_MAX_SUPPORTED_MTU) - return -EINVAL; - - return usbnet_change_mtu(net, new_mtu); -} - -static int is_whitelisted(const u8 ifnum, - const struct sierra_net_iface_info *whitelist) -{ - if (whitelist) { - const u8 *list = whitelist->ifaceinfo; - int i; - - for (i = 0; i < whitelist->infolen; i++) { - if (list[i] == ifnum) - return 1; - } - } - return 0; -} - -static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) -{ - int result = 0; - u16 *attrdata; - - attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL); - if (!attrdata) - return -ENOMEM; - - usb_autopm_get_interface(dev->intf); - result = usb_control_msg( - dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - /* _u8 vendor specific request */ - SWI_USB_REQUEST_GET_FW_ATTR, - USB_DIR_IN | USB_TYPE_VENDOR, /* __u8 request type */ - 0x0000, /* __u16 value not used */ - 0x0000, /* __u16 index not used */ - attrdata, /* char *data */ - sizeof(*attrdata), /* __u16 size */ - USB_CTRL_SET_TIMEOUT); /* int timeout */ - usb_autopm_put_interface(dev->intf); - - if (result < 0) { - kfree(attrdata); - return -EIO; - } - - *datap = *attrdata; - - kfree(attrdata); - return result; -} - -static int sierra_net_manage_power(struct usbnet *dev, int on) -{ - dev->intf->needs_remote_wakeup = on; - return 0; -} - -/* - * collects the bulk endpoints, the status endpoint. - */ -static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) -{ - u8 ifacenum; - u8 numendpoints; - u16 fwattr = 0; - int status; - struct ethhdr *eth; - struct sierra_net_data *priv; - static const u8 sync_tmplate[sizeof(priv->sync_msg)] = { - 0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00}; - static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = { - 0x00, 0x00, SIERRA_NET_HIP_SHUTD_ID, 0x00}; - - struct sierra_net_info_data *data = - (struct sierra_net_info_data *)dev->driver_info->data; - - dev_dbg(&dev->udev->dev, "%s", __func__); - - ifacenum = intf->cur_altsetting->desc.bInterfaceNumber; - /* We only accept certain interfaces */ - if (!is_whitelisted(ifacenum, &data->whitelist)) { - dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum); - return -ENODEV; - } - numendpoints = intf->cur_altsetting->desc.bNumEndpoints; - /* We have three endpoints, bulk in and out, and a status */ - if (numendpoints != 3) { - dev_err(&dev->udev->dev, "Expected 3 endpoints, found: %d", - numendpoints); - return -ENODEV; - } - /* Status endpoint set in usbnet_get_endpoints() */ - dev->status = NULL; - status = usbnet_get_endpoints(dev, intf); - if (status < 0) { - dev_err(&dev->udev->dev, "Error in usbnet_get_endpoints (%d)", - status); - return -ENODEV; - } - /* Initialize sierra private data */ - priv = kzalloc(sizeof *priv, GFP_KERNEL); - if (!priv) { - dev_err(&dev->udev->dev, "No memory"); - return -ENOMEM; - } - - priv->usbnet = dev; - priv->ifnum = ifacenum; - /* override change_mtu with our own routine - need to bound check */ - /* replace structure to our own structure where we have our own - * routine - need to bound check - */ - dev->net->netdev_ops = &sierra_net_device_ops; - - /* change MAC addr to include, ifacenum, and to be unique */ - dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter); - dev->net->dev_addr[ETH_ALEN-1] = ifacenum; - - /* we will have to manufacture ethernet headers, prepare template */ - eth = (struct ethhdr *)priv->ethr_hdr_tmpl; - memcpy(ð->h_dest, dev->net->dev_addr, ETH_ALEN); - eth->h_proto = cpu_to_be16(ETH_P_IP); - - /* prepare shutdown message template */ - memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg)); - /* set context index initially to 0 - prepares tx hdr template */ - sierra_net_set_ctx_index(priv, 0); - - /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */ - dev->rx_urb_size = data->rx_urb_size; - if (dev->udev->speed != USB_SPEED_HIGH) - dev->rx_urb_size = min_t(size_t, 4096, data->rx_urb_size); - - dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN; - dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; - - /* Set up the netdev */ - dev->net->flags |= IFF_NOARP; - dev->net->flags |= IFF_MULTICAST; - dev->net->ethtool_ops = &sierra_net_ethtool_ops; - netif_carrier_off(dev->net); - - sierra_net_set_private(dev, priv); - - priv->kevent_flags = 0; - - /* Use the shared workqueue */ - INIT_WORK(&priv->sierra_net_kevent, sierra_net_kevent); - - /* Only need to do this once */ - init_timer(&priv->sync_timer); - /* verify fw attributes */ - status = sierra_net_get_fw_attr(dev, &fwattr); - dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr); - if (status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_APM)) { -/******************************************************************************* - * If you want the default /sys/bus/usb/devices/.../.../power/level to be forced - * to auto, the following needs to be compiled in. - */ -#ifdef POWER_LEVEL_AUTO - /* make power level default be 'auto' */ - dev_dbg(&dev->udev->dev, "Enabling APM"); - usb_enable_autosuspend(dev->udev); -#endif - } else { - dev_info(&intf->dev, "Disabling APM - not supported"); - usb_disable_autosuspend(dev->udev); - } - /* test whether firmware supports DHCP */ - if (!(status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_MASK))) { - /* found incompatible firmware version */ - dev_err(&dev->udev->dev, "Incompatible driver and firmware" - " versions\n"); - kfree(priv); - return -ENODEV; - } - /* prepare sync message from template */ - memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg)); - - return 0; -} - -static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf) -{ - struct sierra_net_data *priv = sierra_net_get_private(dev); - - dev_dbg(&dev->udev->dev, "%s", __func__); - - sierra_net_set_private(dev, NULL); - - kfree(priv); -} - -static int sierra_net_open(struct usbnet *dev) -{ - dev_dbg(&dev->udev->dev, "%s", __func__); - - /* initiate the sync sequence */ - sierra_net_dosync(dev); - - return 0; -} - -static int sierra_net_stop(struct usbnet *dev) -{ - struct sierra_net_data *priv = sierra_net_get_private(dev); - - dev_dbg(&dev->udev->dev, "%s", __func__); - - /* Kill the timer then flush the work queue */ - del_timer_sync(&priv->sync_timer); - - cancel_work_sync(&priv->sierra_net_kevent); - - /* tell modem we are going away */ - sierra_net_send_shutdown(dev); - - return 0; -} - -static struct sk_buff *sierra_net_skb_clone(struct usbnet *dev, - struct sk_buff *skb, int len) -{ - struct sk_buff *new_skb; - - /* clone skb */ - new_skb = skb_clone(skb, GFP_ATOMIC); - - /* remove len bytes from original */ - skb_pull(skb, len); - - /* trim next packet to it's length */ - if (new_skb) { - skb_trim(new_skb, len); - } else { - if (netif_msg_rx_err(dev)) - netdev_err(dev->net, "failed to get skb\n"); - dev->net->stats.rx_dropped++; - } - - return new_skb; -} - -/* ---------------------------- Receive data path ----------------------*/ -static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb) -{ - int err; - struct hip_hdr hh; - struct sk_buff *new_skb; - struct ethhdr *eth; - struct iphdr *ip; - - dev_dbg(&dev->udev->dev, "%s", __func__); - - sierra_net_printk_buf(skb->data, skb->len); - - /* could contain multiple packets */ - while (likely(skb->len)) { - err = parse_hip(skb->data, skb->len, &hh); - if (err) { - if (netif_msg_rx_err(dev)) - netdev_err(dev->net, "Invalid HIP header %d\n", - err); - /* dev->net->stats.rx_errors incremented by caller */ - dev->net->stats.rx_length_errors++; - return 0; - } - - /* Validate Extended HIP header */ - if (!hh.extmsgid.is_present - || hh.extmsgid.word != SIERRA_NET_HIP_EXT_IP_IN_ID) { - if (netif_msg_rx_err(dev)) - netdev_err(dev->net, "HIP/ETH: Invalid pkt\n"); - - dev->net->stats.rx_frame_errors++; - /* dev->net->stats.rx_errors incremented by caller */; - return 0; - } - - skb_pull(skb, hh.hdrlen); - - /* We are going to accept this packet, prepare it */ - memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl, - ETH_HLEN); - - ip = (struct iphdr *)((char *)skb->data + ETH_HLEN); - if(ip->version == 6) { - eth = (struct ethhdr *)skb->data; - eth->h_proto = cpu_to_be16(ETH_P_IPV6); - } - - /* Last packet in batch handled by usbnet */ - if (hh.payload_len.word == skb->len) - return 1; - - new_skb = sierra_net_skb_clone(dev, skb, hh.payload_len.word); - if (new_skb) - usbnet_skb_return(dev, new_skb); - - } /* while */ - - return 0; -} - -/* ---------------------------- Transmit data path ----------------------*/ -struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb, - gfp_t flags) -{ - struct sierra_net_data *priv = sierra_net_get_private(dev); - u16 len; - bool need_tail; - - dev_dbg(&dev->udev->dev, "%s", __func__); - if (priv->link_up && check_ethip_packet(skb, dev) && is_ip(skb)) { - /* enough head room as is? */ - if (SIERRA_NET_HIP_EXT_HDR_LEN <= skb_headroom(skb)) { - /* Save the Eth/IP length and set up HIP hdr */ - len = skb->len; - skb_push(skb, SIERRA_NET_HIP_EXT_HDR_LEN); - /* Handle ZLP issue */ - need_tail = ((len + SIERRA_NET_HIP_EXT_HDR_LEN) - % dev->maxpacket == 0); - if (need_tail) { - if (unlikely(skb_tailroom(skb) == 0)) { - netdev_err(dev->net, "tx_fixup:" - "no room for packet\n"); - dev_kfree_skb_any(skb); - return NULL; - } else { - skb->data[skb->len] = 0; - __skb_put(skb, 1); - len = len + 1; - } - } - build_hip(skb->data, len, priv); - - sierra_net_printk_buf(skb->data, skb->len); - return skb; - } else { - /* - * compensate in the future if necessary - */ - netdev_err(dev->net, "tx_fixup: no room for HIP\n"); - } /* headroom */ - } - - if (!priv->link_up) - dev->net->stats.tx_carrier_errors++; - - /* tx_dropped incremented by usbnet */ - - /* filter the packet out, release it */ - dev_kfree_skb_any(skb); - return NULL; -} - -static int sierra_net_reset_resume(struct usb_interface *intf) -{ - struct usbnet *dev = usb_get_intfdata(intf); - netdev_err(dev->net, "%s\n", __func__); - return usbnet_resume(intf); -} - -static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 }; -static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { - /* .rx_urb_size = 8 * 1024, */ - .rx_urb_size = SIERRA_NET_RX_URB_SZ, - .whitelist = { - .infolen = ARRAY_SIZE(sierra_net_ifnum_list), - .ifaceinfo = sierra_net_ifnum_list - } -}; - -static const struct driver_info sierra_net_info_direct_ip = { - .description = "Sierra Wireless USB-to-WWAN Modem", - .flags = FLAG_WWAN | FLAG_SEND_ZLP, - .bind = sierra_net_bind, - .unbind = sierra_net_unbind, - .status = sierra_net_status, - .rx_fixup = sierra_net_rx_fixup, - .tx_fixup = sierra_net_tx_fixup, - .manage_power = sierra_net_manage_power, - .stop = sierra_net_stop, - .check_connect = sierra_net_open, - .data = (unsigned long)&sierra_net_info_data_direct_ip, -}; - -static const struct usb_device_id products[] = { - {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, - {USB_DEVICE(0xF3D, 0x68A3), /* AT&T Direct IP modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, - {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, - {USB_DEVICE(0xF3D, 0x68AA), /* AT&T Direct IP LTE modem */ - .driver_info = (unsigned long) &sierra_net_info_direct_ip}, - - {}, /* last item */ -}; -MODULE_DEVICE_TABLE(usb, products); - -/* We are based on usbnet, so let it handle the USB driver specifics */ -static struct usb_driver sierra_net_driver = { - .name = "sierra_net", - .id_table = products, - .probe = usbnet_probe, - .disconnect = usbnet_disconnect, - .suspend = usbnet_suspend, - .resume = usbnet_resume, - .reset_resume = sierra_net_reset_resume, - .no_dynamic_id = 1, - .supports_autosuspend = 1, -}; - -static int __init sierra_net_init(void) -{ - BUILD_BUG_ON(FIELD_SIZEOF(struct usbnet, data) - < sizeof(struct cdc_state)); - - return usb_register(&sierra_net_driver); -} - -static void __exit sierra_net_exit(void) -{ - usb_deregister(&sierra_net_driver); -} - -module_exit(sierra_net_exit); -module_init(sierra_net_init); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); diff --git a/extra/wprobe/Makefile b/extra/wprobe/Makefile deleted file mode 100644 index de1ba6d63..000000000 --- a/extra/wprobe/Makefile +++ /dev/null @@ -1,143 +0,0 @@ -# -# Copyright (C) 2008-2010 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. - -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/kernel.mk - -PKG_NAME:=wprobe -PKG_VERSION:=1 -PKG_RELEASE:=1 - -PKG_BUILD_DEPENDS:=PACKAGE_wprobe-export:libipfix - -PKG_CONFIG_DEPENDS = \ - CONFIG_PACKAGE_kmod-wprobe \ - CONFIG_PACKAGE_wprobe-export \ - -include $(INCLUDE_DIR)/package.mk - -# XXX: build failure on cris -# wprobe-lib.c:145: error: 'packed' attribute ignored for field of type 'struct ' -# wprobe-lib.c:149: error: 'packed' attribute ignored for field of type 'struct ' - -define Package/wprobe/Default - DEPENDS:=@(!(TARGET_ps3||TARGET_pxcab||cris)||BROKEN) -endef - -define KernelPackage/wprobe -$(call Package/wprobe/Default) - SUBMENU:=Network Support - TITLE:=Wireless driver probe infrastructure - MAINTAINER:=Felix Fietkau - FILES:= \ - $(PKG_BUILD_DIR)/kernel/wprobe.ko - AUTOLOAD:=$(call AutoLoad,01,wprobe) -endef - -define KernelPackage/wprobe/description - A module that exports measurement data from wireless driver to user space -endef - -define Package/wprobe-util -$(call Package/wprobe/Default) - SECTION:=net - CATEGORY:=Network - DEPENDS+=+kmod-wprobe +libnl-tiny - TITLE:=Wireless measurement utility -endef - -define Package/wprobe-util/description - wprobe-util uses the wprobe kernel module to query - wireless driver measurement data from an interface -endef - -define Package/wprobe-export -$(call Package/wprobe/Default) - SECTION:=net - CATEGORY:=Network - DEPENDS+=+wprobe-util - TITLE:=Wireless measurement data exporter -endef - -define Package/wprobe-export/description - wprobe-export uses the wprobe kernel module to export - wireless driver measurement data via the IPFIX protocol -endef - -define Package/wprobe-export/conffiles -/etc/config/wprobe -endef - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) - $(CP) src/* $(PKG_BUILD_DIR)/ -endef - -TARGET_CPPFLAGS := \ - -D_GNU_SOURCE \ - -I$(STAGING_DIR)/usr/include/libnl-tiny \ - $(TARGET_CPPFLAGS) - -ifdef CONFIG_PACKAGE_kmod-wprobe - define Build/Compile/kmod - $(MAKE) -C $(LINUX_DIR) \ - CROSS_COMPILE="$(KERNEL_CROSS)" \ - ARCH="$(LINUX_KARCH)" \ - SUBDIRS="$(PKG_BUILD_DIR)/kernel" \ - KERNELDIR=$(LINUX_DIR) \ - CC="$(TARGET_CC)" \ - EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/kernel" \ - modules - endef -endif - -define Build/Compile/lib - $(MAKE) -C $(PKG_BUILD_DIR)/user \ - $(TARGET_CONFIGURE_OPTS) \ - CFLAGS="$(TARGET_CFLAGS)" \ - CPPFLAGS="$(TARGET_CPPFLAGS) -I$(PKG_BUILD_DIR)/kernel" \ - LDFLAGS="$(TARGET_LDFLAGS)" \ - HOST_OS=Linux \ - LIBNL="-lnl-tiny" -endef - -ifdef CONFIG_PACKAGE_wprobe-export - define Build/Compile/exporter - $(MAKE) -C $(PKG_BUILD_DIR)/exporter \ - $(TARGET_CONFIGURE_OPTS) \ - CFLAGS="$(TARGET_CFLAGS)" \ - CPPFLAGS="$(TARGET_CPPFLAGS) -I$(PKG_BUILD_DIR)/kernel -I$(PKG_BUILD_DIR)/user" \ - LDFLAGS="$(TARGET_LDFLAGS)" \ - LIBS="$(PKG_BUILD_DIR)/user/libwprobe.a $(STAGING_DIR)/usr/lib/libipfix.a $(STAGING_DIR)/usr/lib/libipfixmisc.a -lnl-tiny -lm" - endef -endif - -define Build/Compile - $(Build/Compile/kmod) - $(Build/Compile/lib) - $(Build/Compile/exporter) -endef - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/include/wprobe - $(CP) $(PKG_BUILD_DIR)/kernel/linux $(1)/usr/include/wprobe -endef - -define Package/wprobe-util/install - $(INSTALL_DIR) $(1)/sbin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/user/wprobe-util $(1)/sbin/ -endef - -define Package/wprobe-export/install - $(INSTALL_DIR) $(1)/sbin $(1)/etc/init.d $(1)/etc/config - $(INSTALL_BIN) ./files/wprobe.init $(1)/etc/init.d/wprobe - $(INSTALL_BIN) ./files/wprobe.config $(1)/etc/config/wprobe - $(INSTALL_BIN) $(PKG_BUILD_DIR)/exporter/wprobe-export $(1)/sbin/ -endef - -$(eval $(call KernelPackage,wprobe)) -$(eval $(call BuildPackage,wprobe-util)) -$(eval $(call BuildPackage,wprobe-export)) diff --git a/extra/wprobe/files/wprobe.config b/extra/wprobe/files/wprobe.config deleted file mode 100644 index 63518ef6e..000000000 --- a/extra/wprobe/files/wprobe.config +++ /dev/null @@ -1,10 +0,0 @@ -config export - # uncomment this line to enable ipfix export: - # option type ipfix - option ifname ath0 - option host ipfix-col - option proto tcp - -# enable public wprobe protocol access -config export - option type wprobe diff --git a/extra/wprobe/files/wprobe.init b/extra/wprobe/files/wprobe.init deleted file mode 100755 index b35246d42..000000000 --- a/extra/wprobe/files/wprobe.init +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh /etc/rc.common -START=90 -EXPORTER=/sbin/wprobe-export -UTIL=/sbin/wprobe-util - -wprobe_ssd() { - local cmd="$1"; shift - local type="$1"; shift - local app="$1"; shift - start-stop-daemon "$cmd" -p "/var/run/wprobe-$type.pid" -b ${app:+-x "$app"} -m -- "$@" -} - -stop_wprobe() { - local type="$1" - [ -f "/var/run/wprobe-$type.pid" ] && wprobe_ssd -K "$type" - rm -f "/var/run/wprobe-$type.pid" -} - -config_wprobe() { - config_get ifname "$cfg" ifname - config_get interval "$cfg" interval - [ -n "$interval" ] || interval=100 - $UTIL "$ifname" -i "$interval" 2>/dev/null >/dev/null -} - -start_proxy() { - config_get port "$cfg" port - wprobe_ssd -S proxy "$UTIL" -P -p "${port:-17990}" -} - -start_ipfix() { - local cfg="$1" - config_get ifname "$cfg" ifname - config_get host "$cfg" host - config_get port "$cfg" port - config_get proto "$cfg" proto - case "$proto" in - sctp) proto="-s";; - tcp) proto="-t";; - udp) proto="-u";; - *) proto="-t";; - esac - [ -z "$ifname" -o -z "$host" ] && { - echo "wprobe-export: missing host or interface name in config $cfg" - return - } - config_wprobe "$cfg" - wprobe_ssd -S "export-$cfg" "$EXPORTER" "$proto" -i "$ifname" -c "$host" -p "${port:-4739}" -} - -start_export() { - local cfg="$1" - config_get export_type "$cfg" type - case "$export_type" in - ipfix) [ -x "$EXPORTER" ] && start_ipfix "$cfg";; - wprobe) start_proxy "$cfg";; - esac -} - -stop() { - for f in /var/run/wprobe-*.pid; do - CFG="${f%%.pid}" - CFG="${CFG##/var/run/wprobe-}" - stop_wprobe "$CFG" - done -} - -start() { - config_load wprobe - config_foreach config_wprobe interface - config_foreach start_export export -} diff --git a/extra/wprobe/src/Makefile.inc b/extra/wprobe/src/Makefile.inc deleted file mode 100644 index 5044c0a55..000000000 --- a/extra/wprobe/src/Makefile.inc +++ /dev/null @@ -1,12 +0,0 @@ -HOST_OS=$(shell uname) - -CC=gcc -AR=ar -RANLIB=ranlib - -WFLAGS = -Wall -Werror -Wno-format -CFLAGS?=-O2 -CPPFLAGS= -LDFLAGS= -LIBS= - diff --git a/extra/wprobe/src/exporter/Makefile b/extra/wprobe/src/exporter/Makefile deleted file mode 100644 index 9f8150729..000000000 --- a/extra/wprobe/src/exporter/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -include ../Makefile.inc -CPPFLAGS += -I../kernel -I../user - -wprobe-export: wprobe-export.c - $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS) diff --git a/extra/wprobe/src/exporter/wprobe-export.c b/extra/wprobe/src/exporter/wprobe-export.c deleted file mode 100644 index a0e52e2f4..000000000 --- a/extra/wprobe/src/exporter/wprobe-export.c +++ /dev/null @@ -1,304 +0,0 @@ -/* -** exporter.c - example exporter -** -** Copyright Fraunhofer FOKUS -** -*/ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -static ipfix_datarecord_t g_data = { NULL, NULL, 0 }; -static int do_close = 0; - -struct wprobe_mapping { - int id; - bool counter; - const char *wprobe_id; - struct wprobe_value *val; -}; - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(_array) (sizeof(_array) / sizeof((_array)[0])) -#endif - -#define WMAP(_id, _name, ...) \ - { \ - .counter = false, \ - .id = IPFIX_FT_WPROBE_##_id##_N, \ - .wprobe_id = _name \ - , ## __VA_ARGS__ \ - } - -#define WMAP_COUNTER(_id, _name, ...) \ - { \ - .counter = true, \ - .id = IPFIX_FT_WPROBE_##_id, \ - .wprobe_id = _name \ - , ## __VA_ARGS__ \ - } - - -#define WPROBE_OFFSET 2 - -static struct wprobe_mapping map_globals[] = { - WMAP(NOISE, "noise"), - WMAP(PHY_BUSY, "phy_busy"), - WMAP(PHY_RX, "phy_rx"), - WMAP(PHY_TX, "phy_tx"), - WMAP_COUNTER(FRAMES, "frames"), - WMAP_COUNTER(PROBEREQ, "probereq"), -}; - -static struct wprobe_mapping map_perlink[] = { - WMAP(IEEE_TX_RATE, "tx_rate"), - WMAP(IEEE_RX_RATE, "rx_rate"), - WMAP(RSSI, "rssi"), - WMAP(SIGNAL, "signal"), - WMAP(RETRANSMIT_200, "retransmit_200"), - WMAP(RETRANSMIT_400, "retransmit_400"), - WMAP(RETRANSMIT_800, "retransmit_800"), - WMAP(RETRANSMIT_1600, "retransmit_1600"), -}; - -static unsigned char link_local[6]; -static char link_default[6]; -static int nfields = 0; - -#define FOKUS_USERID 12325 - -static void -match_template(struct wprobe_mapping *map, int n, struct list_head *list) -{ - struct wprobe_attribute *attr; - int i, j, last = -1; - - list_for_each_entry(attr, list, list) { - for (i = 0; i < n; i++) { - j = (last + 1 + i) % n; - if (!strcmp(attr->name, map[j].wprobe_id)) - goto found; - } - continue; -found: - last = j; - map[j].val = &attr->val; - memset(&attr->val, 0, sizeof(attr->val)); - nfields++; - } -} - -/* name: export_ipfix_get_template() - */ -static ipfix_template_t * -prepare_template(ipfix_t *handle) -{ - ipfix_template_t *t = NULL; - int size = 3 * nfields + WPROBE_OFFSET; - int i; - - if (ipfix_new_data_template( handle, &t, size) < 0) { - mlogf( 0, "ipfix_new_template() failed: %s\n", strerror(errno) ); - exit(1); - } - - ipfix_add_field(handle, t, 0, IPFIX_FT_SOURCEMACADDRESS, 6); - ipfix_add_field(handle, t, 0, IPFIX_FT_DESTINATIONMACADDRESS, 6); - - g_data.lens = calloc(size, sizeof(g_data.lens[0])); - g_data.lens[0] = 6; - g_data.lens[1] = 6; - for (i = WPROBE_OFFSET; i < size; i++) - g_data.lens[i] = 4; - - g_data.addrs = calloc(size, sizeof(g_data.addrs[0])); - g_data.addrs[0] = link_local; - g_data.maxfields = WPROBE_OFFSET; - return t; -} - -static void -add_template_fields(ipfix_t *handle, ipfix_template_t *t, struct wprobe_mapping *map, int n) -{ - int f = g_data.maxfields; - int i; - - for (i = 0; i < n; i++) { - if (!map[i].val) - continue; - - if (map[i].counter) - g_data.addrs[f++] = &map[i].val->U32; - else - g_data.addrs[f++] = &map[i].val->n; - - if (ipfix_add_field( handle, t, FOKUS_USERID, map[i].id + 0, 4) < 0) - exit(1); - - if (map[i].counter) - continue; - - g_data.lens[f] = 8; - g_data.addrs[f++] = &map[i].val->s; - - g_data.lens[f] = 8; - g_data.addrs[f++] = &map[i].val->ss; - if (ipfix_add_field( handle, t, FOKUS_USERID, map[i].id + 1, 8) < 0) - exit(1); - if (ipfix_add_field( handle, t, FOKUS_USERID, map[i].id + 2, 8) < 0) - exit(1); - } - g_data.maxfields = f; -} - -static void -wprobe_dump_data(ipfix_t *ipfixh, ipfix_template_t *ipfixt, struct wprobe_iface *dev) -{ - struct wprobe_link *link; - - wprobe_update_links(dev); - wprobe_request_data(dev, NULL); - if (list_empty(&dev->links)) { - g_data.addrs[1] = link_default; - ipfix_export_array(ipfixh, ipfixt, g_data.maxfields, g_data.addrs, g_data.lens); - ipfix_export_flush(ipfixh); - } - list_for_each_entry(link, &dev->links, list) { - g_data.addrs[1] = link->addr; - wprobe_request_data(dev, link->addr); - ipfix_export_array(ipfixh, ipfixt, g_data.maxfields, g_data.addrs, g_data.lens); - ipfix_export_flush(ipfixh); - } -} - -int main ( int argc, char **argv ) -{ - struct wprobe_iface *dev = NULL; - ipfix_template_t *ipfixt = NULL; - ipfix_t *ipfixh = NULL; - int protocol = IPFIX_PROTO_TCP; - char *chost = NULL; - char *ifname = NULL; - int sourceid = 12345; - int port = IPFIX_PORTNO; - int verbose_level = 0; - int opt, i = 10; - char *err = NULL; - - while ((opt = getopt(argc, argv, "hi:c:p:vstu")) != EOF) { - switch (opt) { - case 'p': - if ((port=atoi(optarg)) <0) { - fprintf( stderr, "Invalid -p argument!\n" ); - exit(1); - } - break; - case 'i': - ifname = optarg; - break; - case 'c': - chost = optarg; - break; - - case 's': - protocol = IPFIX_PROTO_SCTP; - break; - - case 't': - protocol = IPFIX_PROTO_TCP; - break; - - case 'u': - protocol = IPFIX_PROTO_UDP; - break; - - case 'v': - verbose_level ++; - break; - - case 'h': - default: - fprintf(stderr, "usage: %s [-hstuv] -i -c [-p portno]\n" - " -h this help\n" - " -i wprobe interface\n" - " -c collector address\n" - " -p collector port number (default=%d)\n" - " -s send data via SCTP\n" - " -t send data via TCP (default)\n" - " -u send data via UDP\n" - " -v increase verbose level\n\n", - argv[0], IPFIX_PORTNO ); - exit(1); - } - } - - if (!ifname) { - fprintf(stderr, "No interface specified\n"); - return -1; - } - - if (!chost) { - fprintf(stderr, "No collector specified\n"); - return -1; - } - - dev = wprobe_get_auto(ifname, &err); - if (!dev || (list_empty(&dev->global_attr) && list_empty(&dev->link_attr))) { - fprintf(stderr, "Cannot connect to wprobe on interface '%s': %s\n", ifname, (err ? err : "Unknown error")); - return -1; - } - - match_template(map_globals, ARRAY_SIZE(map_globals), &dev->global_attr); - match_template(map_perlink, ARRAY_SIZE(map_perlink), &dev->link_attr); - if (nfields == 0) { - fprintf(stderr, "No usable attributes found\n"); - return -1; - } - - mlog_set_vlevel( verbose_level ); - if (ipfix_init() < 0) { - fprintf( stderr, "cannot init ipfix module: %s\n", strerror(errno) ); - exit(1); - } - - ipfix_add_vendor_information_elements(ipfix_ft_fokus); - if (ipfix_open(&ipfixh, sourceid, IPFIX_VERSION) < 0) { - fprintf( stderr, "ipfix_open() failed: %s\n", strerror(errno) ); - exit(1); - } - - if (ipfix_add_collector( ipfixh, chost, port, protocol ) < 0) { - fprintf( stderr, "ipfix_add_collector(%s,%d) failed: %s\n", - chost, port, strerror(errno)); - exit(1); - } - - fprintf(stderr, "Local link address: %02x:%02x:%02x:%02x:%02x:%02x\n", - link_local[0], link_local[1], link_local[2], - link_local[3], link_local[4], link_local[5]); - - ipfixt = prepare_template(ipfixh); - add_template_fields(ipfixh, ipfixt, map_globals, ARRAY_SIZE(map_globals)); - add_template_fields(ipfixh, ipfixt, map_perlink, ARRAY_SIZE(map_perlink)); - - while (!do_close) { - sleep(1); - wprobe_dump_data(ipfixh, ipfixt, dev); - } - - ipfix_delete_template( ipfixh, ipfixt ); - ipfix_close( ipfixh ); - ipfix_cleanup(); - exit(0); -} diff --git a/extra/wprobe/src/exporter/wprobe-export.h b/extra/wprobe/src/exporter/wprobe-export.h deleted file mode 100644 index 89da9e86e..000000000 --- a/extra/wprobe/src/exporter/wprobe-export.h +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include - -/** - * struct wprobe_value: data structure for attribute values - * see kernel api netlink attributes for more information - */ -struct wprobe_value { - /* attribute value */ - union data { - const char *STRING; - uint8_t U8; - uint16_t U16; - uint32_t U32; - uint64_t U64; - int8_t S8; - int16_t S16; - int32_t S32; - int64_t S64; - } data; - /* statistics */ - int64_t s, ss; - double avg, stdev; - unsigned int n; - void *usedata; /* Pointer to used data.something */ -}; - -struct exporter_data { - int id; /* ipfix id */ - int userid; /* focus or global */ - int size; /* size in byte*/ - struct wprobe_value val; -}; diff --git a/extra/wprobe/src/filter/README.txt b/extra/wprobe/src/filter/README.txt deleted file mode 100644 index 6fa265e4f..000000000 --- a/extra/wprobe/src/filter/README.txt +++ /dev/null @@ -1 +0,0 @@ -To compile pfc you need at least libpcap version 1.0, as it requires proper radiotap header support diff --git a/extra/wprobe/src/filter/gen_filter.pl b/extra/wprobe/src/filter/gen_filter.pl deleted file mode 100755 index f03f477a4..000000000 --- a/extra/wprobe/src/filter/gen_filter.pl +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/perl -use strict; - -# helpers for custom packet format -# bytes 0-7 are used by a dummy radiotap header -my $WLAN_LEN = "radio[8:2]"; -my $SNR = "radio[10:1]"; -my $DEFAULT = undef; - -my $MAGIC = "WPFF"; -my $VERSION = 1; # filter binary format version -my $HDRLEN = 3; # assumed storage space for custom fields - -my $output = "filter.bin"; -my $config = { - "packetsize" => [ - [ "small", "$WLAN_LEN < 250" ], - [ "medium", "$WLAN_LEN < 800" ], - [ "big", $DEFAULT ], - ], - "snr" => [ - [ "low", "$SNR < 10" ], - [ "medium", "$SNR < 20" ], - [ "high", $DEFAULT ], - ], - "type" => [ - [ "beacon", "type mgt subtype beacon" ], - [ "data", "type data subtype data" ], - [ "qosdata", "type data subtype qos-data" ], - [ "other", "$DEFAULT" ] - ] -}; - -sub escape_q($) { - my $str = shift; - $str =~ s/'/'\\''/g; - return $str; -} - -my $GROUPS = scalar(keys %$config); -open OUTPUT, ">$output" or die "Cannot open output file: $!\n"; -print OUTPUT pack("a4CCn", $MAGIC, $VERSION, $HDRLEN, $GROUPS); - -foreach my $groupname (keys %$config) { - my $default = 0; - my $group = $config->{$groupname}; - print OUTPUT pack("a32N", $groupname, scalar(@$group)); - foreach my $filter (@$group) { - if (!$filter->[1]) { - $default > 0 and print "Cannot add more than one default filter per group: $groupname -> ".$filter->[0]."\n"; - print OUTPUT pack("a32N", $filter->[0], 0); - $default++; - } else { - open FILTER, "./pfc '".escape_q($filter->[0])."' '".escape_q($filter->[1])."' |" - or die "Failed to run filter command for '".$filter->[0]."': $!\n"; - while () { - print OUTPUT $_; - } - close FILTER; - $? and die "Filter '".$filter->[0]."' did not compile.\n"; - } - } -} diff --git a/extra/wprobe/src/filter/pfc.c b/extra/wprobe/src/filter/pfc.c deleted file mode 100644 index 76fb1412a..000000000 --- a/extra/wprobe/src/filter/pfc.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include - -struct wprobe_filter_hdr { - char name[32]; - uint32_t len; -} hdr; - -int main (int argc, char ** argv) -{ - struct bpf_program filter; - pcap_t *pc; - int i; - - if (argc != 3) - { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - pc = pcap_open_dead(DLT_IEEE802_11_RADIO, 256); - if (pcap_compile(pc, &filter, argv[2], 1, 0) != 0) - { - pcap_perror(pc, argv[0]); - exit(1); - } - - /* fix up for linux */ - for (i = 0; i < filter.bf_len; i++) { - struct bpf_insn *bi = &filter.bf_insns[i]; - switch(BPF_CLASS(bi->code)) { - case BPF_RET: - if (BPF_MODE(bi->code) == BPF_K) { - if (bi->k != 0) - bi->k = 65535; - } - break; - } - bi->code = ntohs(bi->code); - bi->k = ntohl(bi->k); - } - - memset(&hdr, 0, sizeof(hdr)); - strncpy(hdr.name, argv[1], sizeof(hdr.name)); - hdr.len = htonl(filter.bf_len); - fwrite(&hdr, sizeof(hdr), 1, stdout); - fwrite(filter.bf_insns, 8, filter.bf_len, stdout); - fflush(stdout); - - return 0; -} diff --git a/extra/wprobe/src/kernel/Makefile b/extra/wprobe/src/kernel/Makefile deleted file mode 100644 index 2a9875311..000000000 --- a/extra/wprobe/src/kernel/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -EXTRA_CFLAGS += -I. - -obj-m := wprobe.o wprobe-dummy.o - -wprobe-objs := wprobe-core.o diff --git a/extra/wprobe/src/kernel/linux/wprobe.h b/extra/wprobe/src/kernel/linux/wprobe.h deleted file mode 100644 index 901daf3d1..000000000 --- a/extra/wprobe/src/kernel/linux/wprobe.h +++ /dev/null @@ -1,397 +0,0 @@ -/* - * wprobe.h: API for the wireless probe interface - * Copyright (C) 2008-2009 Felix Fietkau - * - * 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. - */ - -#ifndef __WPROBE_H -#define __WPROBE_H - -#ifdef __KERNEL__ -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -/** - * enum wprobe_attr: netlink attribute list - * - * @WPROBE_ATTR_UNSPEC: unused - * - * @WPROBE_ATTR_INTERFACE: interface name to process query on (NLA_STRING) - * @WPROBE_ATTR_MAC: mac address (used for wireless links) (NLA_STRING) - * @WPROBE_ATTR_FLAGS: interface/link/attribute flags (see enum wprobe_flags) (NLA_U32)a - * @WPROBE_ATTR_DURATION: sampling duration (in milliseconds) (NLA_MSECS) - * - * @WPROBE_ATTR_ID: attribute id (NLA_U32) - * @WPROBE_ATTR_NAME: attribute name (NLA_STRING) - * @WPROBE_ATTR_TYPE: attribute type (NLA_U8) - * - * attribute values: - * - * @WPROBE_VAL_STRING: string value (NLA_STRING) - * @WPROBE_VAL_S8: signed 8-bit integer (NLA_U8) - * @WPROBE_VAL_S16: signed 16-bit integer (NLA_U16) - * @WPROBE_VAL_S32: signed 32-bit integer (NLA_U32) - * @WPROBE_VAL_S64: signed 64-bit integer (NLA_U64) - * @WPROBE_VAL_U8: unsigned 8-bit integer (NLA_U8) - * @WPROBE_VAL_U16: unsigned 16-bit integer (NLA_U16) - * @WPROBE_VAL_U32: unsigned 32-bit integer (NLA_U32) - * @WPROBE_VAL_U64: unsigned 64-bit integer (NLA_U64) - * - * statistics: - * @WPROBE_VAL_SUM: sum of all samples - * @WPROBE_VAL_SUM_SQ: sum of all samples^2 - * @WPROBE_VAL_SAMPLES: number of samples - * @WPROBE_VAL_SCALE_TIME: last time the samples were scaled down - * - * configuration: - * @WPROBE_ATTR_INTERVAL: (measurement interval in milliseconds) (NLA_MSECS) - * @WPROBE_ATTR_SAMPLES_MIN: minimum samples to keep during inactivity (NLA_U32) - * @WPROBE_ATTR_SAMPLES_MAX: maximum samples to keep before scaling down (NLA_U32) - * @WPROBE_ATTR_SAMPLES_SCALE_M: multiplier for scaling down samples (NLA_U32) - * @WPROBE_ATTR_SAMPLES_SCALE_D: divisor for scaling down samples (NLA_U32) - * - * @WPROBE_ATTR_LAST: unused - */ -enum wprobe_attr { - /* query attributes */ - WPROBE_ATTR_UNSPEC, - WPROBE_ATTR_INTERFACE, - WPROBE_ATTR_MAC, - WPROBE_ATTR_FLAGS, - - /* response data */ - WPROBE_ATTR_ID, - WPROBE_ATTR_NAME, - WPROBE_ATTR_TYPE, - WPROBE_ATTR_DURATION, - - /* value type attributes */ - WPROBE_VAL_STRING, - WPROBE_VAL_S8, - WPROBE_VAL_S16, - WPROBE_VAL_S32, - WPROBE_VAL_S64, - WPROBE_VAL_U8, - WPROBE_VAL_U16, - WPROBE_VAL_U32, - WPROBE_VAL_U64, - - /* aggregates for statistics */ - WPROBE_VAL_SUM, - WPROBE_VAL_SUM_SQ, - WPROBE_VAL_SAMPLES, - WPROBE_VAL_SCALE_TIME, - - /* config attributes */ - WPROBE_ATTR_INTERVAL, - WPROBE_ATTR_SAMPLES_MIN, - WPROBE_ATTR_SAMPLES_MAX, - WPROBE_ATTR_SAMPLES_SCALE_M, - WPROBE_ATTR_SAMPLES_SCALE_D, - WPROBE_ATTR_FILTER, - - WPROBE_ATTR_FILTER_GROUP, - WPROBE_ATTR_RXCOUNT, - WPROBE_ATTR_TXCOUNT, - - WPROBE_ATTR_LAST -}; - - -/** - * enum wprobe_cmd: netlink commands for interacting with wprobe - * - * @WPROBE_CMD_UNSPEC: unused - * - * @WPROBE_CMD_GET_LIST: get global/link property list - * @WPROBE_CMD_GET_INFO: get global/link properties - * @WPROBE_CMD_SET_FLAGS: set global/link flags - * @WPROBE_CMD_MEASURE: take a snapshot of the current data - * @WPROBE_CMD_GET_LINKS: get a list of links - * @WPROBE_CMD_CONFIG: set config options - * @WPROBE_CMD_GET_FILTER: get counters for active filters - * - * @WPROBE_CMD_LAST: unused - * - * options for GET_INFO and SET_FLAGS: - * - mac address set: per-link - * - mac address unset: globalsa - */ -enum wprobe_cmd { - WPROBE_CMD_UNSPEC, - WPROBE_CMD_GET_LIST, - WPROBE_CMD_GET_INFO, - WPROBE_CMD_SET_FLAGS, - WPROBE_CMD_MEASURE, - WPROBE_CMD_GET_LINKS, - WPROBE_CMD_CONFIG, - WPROBE_CMD_GET_FILTER, - WPROBE_CMD_LAST -}; - -/** - * enum wprobe_flags: flags for wprobe links and items - * @WPROBE_F_KEEPSTAT: keep statistics for this link/device - * @WPROBE_F_RESET: reset statistics now - * @WPROBE_F_NEWDATA: used to indicate that a value has been updated - */ -enum wprobe_flags { - WPROBE_F_KEEPSTAT = (1 << 0), - WPROBE_F_RESET = (1 << 1), - WPROBE_F_NEWDATA = (1 << 2), -}; - -#ifdef __KERNEL__ - -struct wprobe_link; -struct wprobe_item; -struct wprobe_source; -struct wprobe_value; - -/** - * struct wprobe_link - data structure describing a wireless link - * @iface: pointer to the wprobe_iface that this link belongs to - * @addr: BSSID of the remote link partner - * @flags: link flags (see wprobe_flags) - * @priv: user pointer - * - * @list: for internal use - * @val: for internal use - */ -struct wprobe_link { - struct list_head list; - struct wprobe_iface *iface; - char addr[ETH_ALEN]; - u32 flags; - void *priv; - struct wprobe_value *val; -}; - -/** - * struct wprobe_item - data structure describing the format of wprobe_link::data or wprobe_iface::data - * @name: name of the field - * @type: data type of this field - * @flags: measurement item flags (see wprobe_flags) - */ -struct wprobe_item { - const char *name; - enum wprobe_attr type; - u32 flags; -}; - -struct wprobe_value { - bool pending; - union { - /* - * the following are kept uppercase to allow - * for automated checking against WPROBE_VAL_* - * via BUG_ON() - */ - const char *STRING; - u8 U8; - u16 U16; - u32 U32; - u64 U64; - s8 S8; - s16 S16; - s32 S32; - s64 S64; - }; - s64 s, ss; - unsigned int n; - - /* timestamps */ - u64 first, last; - u64 scale_timestamp; -}; - -struct wprobe_filter_item_hdr { - char name[32]; - __be32 n_items; -} __attribute__((packed)); - -struct wprobe_filter_item { - struct wprobe_filter_item_hdr hdr; - struct sock_filter filter[]; -} __attribute__((packed)); - -struct wprobe_filter_counter { - u64 tx; - u64 rx; -}; - -struct wprobe_filter_group { - const char *name; - int n_items; - struct wprobe_filter_item **items; - struct wprobe_filter_counter *counters; -}; - -struct wprobe_filter_hdr { - __u8 magic[4]; - __u8 version; - __u8 hdrlen; - __u16 n_groups; -} __attribute__((packed)); - -struct wprobe_filter { - spinlock_t lock; - struct sk_buff *skb; - void *data; - int n_groups; - int hdrlen; - struct wprobe_filter_item **items; - struct wprobe_filter_counter *counters; - struct wprobe_filter_group groups[]; -}; - -enum { - WPROBE_PKT_RX = 0x00, - WPROBE_PKT_TX = 0x10, -}; - -struct wprobe_wlan_hdr { - u16 len; - u8 snr; - u8 type; -} __attribute__((packed)); - - -/** - * struct wprobe_source - data structure describing a wireless interface - * - * @name: name of the interface - * @addr: local mac address of the interface - * @links: list of wireless links to poll - * @link_items: description of the per-link data structure - * @n_link_items: number of link description items - * @global_items: description of the per-interface data structure - * @n_global_items: number of per-interface description items - * @sync_data: callback allowing the driver to prepare data for the wprobe poll - * - * @list: head for the list of interfaces - * @priv: user pointer - * @lock: spinlock protecting value data access - * @val: internal use - * @query_val: internal use - * - * if sync_data is NULL, wprobe assumes that it can access the data structure - * at any time (in atomic context). if sync_data returns a negative error code, - * the poll request will not be handled for the given link - */ -struct wprobe_iface { - /* to be filled in by wprobe source drivers */ - const char *name; - const char *addr; - const struct wprobe_item *link_items; - int n_link_items; - const struct wprobe_item *global_items; - int n_global_items; - - int (*sync_data)(struct wprobe_iface *dev, struct wprobe_link *l, - struct wprobe_value *val, bool measure); - void *priv; - - /* handled by the wprobe core */ - struct list_head list; - struct list_head links; - spinlock_t lock; - struct wprobe_value *val; - struct wprobe_value *query_val; - struct wprobe_filter *active_filter; - - u32 measure_interval; - struct timer_list measure_timer; - - u32 scale_min; - u32 scale_max; - u32 scale_m; - u32 scale_d; -}; - - -#define WPROBE_FILL_BEGIN(_ptr, _list) do { \ - struct wprobe_value *__val = (_ptr); \ - const struct wprobe_item *__item = _list; \ - u64 __msecs = jiffies_to_msecs(jiffies) - -#define WPROBE_SET(_idx, _type, _value) \ - if (__item[_idx].type != WPROBE_VAL_##_type) { \ - printk("ERROR: invalid data type at %s:%d\n", __FILE__, __LINE__); \ - break; \ - } \ - __val[_idx].pending = true; \ - __val[_idx]._type = _value; \ - if (!__val[_idx].first) \ - __val[_idx].first = __msecs; \ - __val[_idx].first = __msecs - -#define WPROBE_FILL_END() \ -} while(0) - -/** - * wprobe_add_iface: register an interface with the wireless probe subsystem - * @dev: wprobe_iface structure describing the interface - */ -extern int __weak wprobe_add_iface(struct wprobe_iface *dev); - -/** - * wprobe_remove_iface: deregister an interface from the wireless probe subsystem - * @dev: wprobe_iface structure describing the interface - */ -extern void __weak wprobe_remove_iface(struct wprobe_iface *dev); - -/** - * wprobe_add_link: register a new wireless link - * @dev: wprobe_iface structure describing the interface - * @l: storage space for the wprobe_link structure - * @addr: mac address of the new link - * - * the entire wprobe_link structure is overwritten by this function call - */ -extern int __weak wprobe_add_link(struct wprobe_iface *dev, struct wprobe_link *l, const char *addr); - -/** - * wprobe_remove_link: deregister a previously registered wireless link - * @dev: wprobe_iface structure describing the interface - * @l: wprobe_link data structure - */ -extern void __weak wprobe_remove_link(struct wprobe_iface *dev, struct wprobe_link *l); - -/** - * wprobe_update_stats: update statistics after sampling values - * @dev: wprobe_iface structure describing the interface - * @l: wprobe_link data structure - * - * if l == NULL, then the stats for globals are updated - */ -extern void __weak wprobe_update_stats(struct wprobe_iface *dev, struct wprobe_link *l); - -/** - * wprobe_add_frame: add frame for layer 2 analysis - * @dev: wprobe_iface structure describing the interface - * @hdr: metadata for the frame - * @data: 802.11 header pointer - * @len: length of the 802.11 header - */ -extern int __weak wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, void *data, int len); - -#endif /* __KERNEL__ */ - -#endif diff --git a/extra/wprobe/src/kernel/wprobe-core.c b/extra/wprobe/src/kernel/wprobe-core.c deleted file mode 100644 index 6ec847a7a..000000000 --- a/extra/wprobe/src/kernel/wprobe-core.c +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * wprobe-core.c: Wireless probe interface core - * Copyright (C) 2008-2009 Felix Fietkau - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -#include -#else -#include -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) -#include -#endif -#include -#include -#include - -#define static - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) -#define list_for_each_rcu(pos, head) \ -for (pos = rcu_dereference((head)->next); \ -prefetch(pos->next), pos != (head); \ -pos = rcu_dereference(pos->next)) -#endif - -#define WPROBE_MIN_INTERVAL 100 /* minimum measurement interval in msecs */ -#define WPROBE_MAX_FILTER_SIZE 1024 -#define WPROBE_MAX_FRAME_SIZE 1900 - -static struct list_head wprobe_if; -static spinlock_t wprobe_lock; - -static struct genl_family wprobe_fam = { - .id = GENL_ID_GENERATE, - .name = "wprobe", - .hdrsize = 0, - .version = 1, - /* only the first set of attributes is used for queries */ - .maxattr = WPROBE_ATTR_LAST, -}; - -/* fake radiotap header */ -struct wprobe_rtap_hdr { - __u8 version; - __u8 padding; - __le16 len; - __le32 present; -}; - -static void wprobe_update_stats(struct wprobe_iface *dev, struct wprobe_link *l); -static int wprobe_sync_data(struct wprobe_iface *dev, struct wprobe_link *l, bool query); -static void wprobe_free_filter(struct wprobe_filter *f); - -int -wprobe_add_link(struct wprobe_iface *s, struct wprobe_link *l, const char *addr) -{ - unsigned long flags; - - INIT_LIST_HEAD(&l->list); - l->val = kzalloc(sizeof(struct wprobe_value) * s->n_link_items, GFP_ATOMIC); - if (!l->val) - return -ENOMEM; - - l->iface = s; - memcpy(&l->addr, addr, ETH_ALEN); - spin_lock_irqsave(&wprobe_lock, flags); - list_add_tail_rcu(&l->list, &s->links); - spin_unlock_irqrestore(&wprobe_lock, flags); - - return 0; -} -EXPORT_SYMBOL(wprobe_add_link); - -void -wprobe_remove_link(struct wprobe_iface *s, struct wprobe_link *l) -{ - unsigned long flags; - - spin_lock_irqsave(&wprobe_lock, flags); - list_del_rcu(&l->list); - spin_unlock_irqrestore(&wprobe_lock, flags); - synchronize_rcu(); - kfree(l->val); -} -EXPORT_SYMBOL(wprobe_remove_link); - -static void -wprobe_measure_timer(unsigned long data) -{ - struct wprobe_iface *dev = (struct wprobe_iface *) data; - - /* set next measurement interval */ - mod_timer(&dev->measure_timer, jiffies + - msecs_to_jiffies(dev->measure_interval)); - - /* perform measurement */ - wprobe_sync_data(dev, NULL, false); -} - -int -wprobe_add_iface(struct wprobe_iface *s) -{ - unsigned long flags; - int vsize; - - /* reset only wprobe private area */ - memset(&s->list, 0, sizeof(struct wprobe_iface) - offsetof(struct wprobe_iface, list)); - - BUG_ON(!s->name); - INIT_LIST_HEAD(&s->list); - INIT_LIST_HEAD(&s->links); - setup_timer(&s->measure_timer, wprobe_measure_timer, (unsigned long) s); - - s->val = kzalloc(sizeof(struct wprobe_value) * s->n_global_items, GFP_ATOMIC); - if (!s->val) - goto error; - - vsize = max(s->n_link_items, s->n_global_items); - s->query_val = kzalloc(sizeof(struct wprobe_value) * vsize, GFP_ATOMIC); - if (!s->query_val) - goto error; - - /* initialize defaults to be able to handle overflow, - * user space will need to handle this if it keeps an - * internal histogram */ - s->scale_min = 20; - s->scale_max = (1 << 31); - - s->scale_m = 1; - s->scale_d = 10; - - spin_lock_irqsave(&wprobe_lock, flags); - list_add_rcu(&s->list, &wprobe_if); - spin_unlock_irqrestore(&wprobe_lock, flags); - - return 0; - -error: - if (s->val) - kfree(s->val); - return -ENOMEM; -} -EXPORT_SYMBOL(wprobe_add_iface); - -void -wprobe_remove_iface(struct wprobe_iface *s) -{ - unsigned long flags; - - BUG_ON(!list_empty(&s->links)); - - del_timer_sync(&s->measure_timer); - spin_lock_irqsave(&wprobe_lock, flags); - list_del_rcu(&s->list); - spin_unlock_irqrestore(&wprobe_lock, flags); - - /* wait for all queries to finish before freeing the - * temporary value storage buffer */ - synchronize_rcu(); - - kfree(s->val); - kfree(s->query_val); - if (s->active_filter) - wprobe_free_filter(s->active_filter); -} -EXPORT_SYMBOL(wprobe_remove_iface); - -static struct wprobe_iface * -wprobe_get_dev(struct nlattr *attr) -{ - struct wprobe_iface *dev = NULL; - struct wprobe_iface *p; - const char *name; - int i = 0; - - if (!attr) - return NULL; - - name = nla_data(attr); - list_for_each_entry_rcu(p, &wprobe_if, list) { - i++; - if (strcmp(name, p->name) != 0) - continue; - - dev = p; - break; - } - - return dev; -} - -int -wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, void *data, int len) -{ - struct wprobe_wlan_hdr *new_hdr; - struct wprobe_filter *f; - struct sk_buff *skb; - unsigned long flags; - int i, j; - - rcu_read_lock(); - f = rcu_dereference(dev->active_filter); - if (!f) - goto out; - - spin_lock_irqsave(&f->lock, flags); - - skb = f->skb; - skb->len = sizeof(struct wprobe_rtap_hdr); - skb->tail = skb->data + skb->len; - if (len + skb->len > WPROBE_MAX_FRAME_SIZE) - len = WPROBE_MAX_FRAME_SIZE - skb->len; - - new_hdr = (struct wprobe_wlan_hdr *) skb_put(skb, f->hdrlen); - memcpy(new_hdr, hdr, sizeof(struct wprobe_wlan_hdr)); - new_hdr->len = cpu_to_be16(new_hdr->len); - - memcpy(skb_put(skb, len), data, len); - - for(i = 0; i < f->n_groups; i++) { - struct wprobe_filter_group *fg = &f->groups[i]; - bool found = false; - int def = -1; - - for (j = 0; j < fg->n_items; j++) { - struct wprobe_filter_item *fi = fg->items[j]; - - if (!fi->hdr.n_items) { - def = j; - continue; - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) - if (sk_run_filter(skb, fi->filter) == 0) - continue; -#else - if (sk_run_filter(skb, fi->filter, fi->hdr.n_items) == 0) - continue; -#endif - - found = true; - break; - } - if (!found && def >= 0) { - j = def; - found = true; - } - if (found) { - struct wprobe_filter_counter *c = &fg->counters[j]; - - if (hdr->type >= WPROBE_PKT_TX) - c->tx++; - else - c->rx++; - } - } - - spin_unlock_irqrestore(&f->lock, flags); -out: - rcu_read_unlock(); - return 0; -} -EXPORT_SYMBOL(wprobe_add_frame); - -static int -wprobe_sync_data(struct wprobe_iface *dev, struct wprobe_link *l, bool query) -{ - struct wprobe_value *val; - unsigned long flags; - int n, err; - - if (l) { - n = dev->n_link_items; - val = l->val; - } else { - n = dev->n_global_items; - val = dev->val; - } - - spin_lock_irqsave(&dev->lock, flags); - err = dev->sync_data(dev, l, val, !query); - if (err) - goto done; - - if (query) - memcpy(dev->query_val, val, sizeof(struct wprobe_value) * n); - - wprobe_update_stats(dev, l); -done: - spin_unlock_irqrestore(&dev->lock, flags); - return 0; -} -EXPORT_SYMBOL(wprobe_sync_data); - -static void -wprobe_scale_stats(struct wprobe_iface *dev, const struct wprobe_item *item, - struct wprobe_value *val, int n) -{ - u64 scale_ts = jiffies_64; - int i; - - for (i = 0; i < n; i++) { - if (!(item[i].flags & WPROBE_F_KEEPSTAT)) - continue; - - if (val[i].n <= dev->scale_min) - continue; - - /* FIXME: div_s64 seems to be very imprecise here, even when - * the values are scaled up */ - val[i].s *= dev->scale_m; - val[i].s = div_s64(val[i].s, dev->scale_d); - - val[i].ss *= dev->scale_m; - val[i].ss = div_s64(val[i].ss, dev->scale_d); - - val[i].n = (val[i].n * dev->scale_m) / dev->scale_d; - val[i].scale_timestamp = scale_ts; - } -} - - -void -wprobe_update_stats(struct wprobe_iface *dev, struct wprobe_link *l) -{ - const struct wprobe_item *item; - struct wprobe_value *val; - bool scale_stats = false; - int i, n; - - if (l) { - n = dev->n_link_items; - item = dev->link_items; - val = l->val; - } else { - n = dev->n_global_items; - item = dev->global_items; - val = dev->val; - } - - /* process statistics */ - for (i = 0; i < n; i++) { - s64 v; - - if (!val[i].pending) - continue; - - val[i].n++; - if ((item[i].flags & WPROBE_F_KEEPSTAT) && - (dev->scale_max > 0) && (val[i].n > dev->scale_max)) { - scale_stats = true; - } - - switch(item[i].type) { - case WPROBE_VAL_S8: - v = val[i].S8; - break; - case WPROBE_VAL_S16: - v = val[i].S16; - break; - case WPROBE_VAL_S32: - v = val[i].S32; - break; - case WPROBE_VAL_S64: - v = val[i].S64; - break; - case WPROBE_VAL_U8: - v = val[i].U8; - break; - case WPROBE_VAL_U16: - v = val[i].U16; - break; - case WPROBE_VAL_U32: - v = val[i].U32; - break; - case WPROBE_VAL_U64: - v = val[i].U64; - break; - default: - continue; - } - - val[i].s += v; - val[i].ss += v * v; - val[i].pending = false; - } - if (scale_stats) - wprobe_scale_stats(dev, item, val, n); -} -EXPORT_SYMBOL(wprobe_update_stats); - -static const struct nla_policy wprobe_policy[WPROBE_ATTR_LAST+1] = { - [WPROBE_ATTR_INTERFACE] = { .type = NLA_NUL_STRING }, - [WPROBE_ATTR_MAC] = { .type = NLA_STRING }, - [WPROBE_ATTR_FLAGS] = { .type = NLA_U32 }, - - /* config */ - [WPROBE_ATTR_INTERVAL] = { .type = NLA_MSECS }, - [WPROBE_ATTR_SAMPLES_MIN] = { .type = NLA_U32 }, - [WPROBE_ATTR_SAMPLES_MAX] = { .type = NLA_U32 }, - [WPROBE_ATTR_SAMPLES_SCALE_M] = { .type = NLA_U32 }, - [WPROBE_ATTR_SAMPLES_SCALE_D] = { .type = NLA_U32 }, - [WPROBE_ATTR_FILTER] = { .type = NLA_BINARY, .len = 32768 }, -}; - -static bool -wprobe_check_ptr(struct list_head *list, struct list_head *ptr) -{ - struct list_head *p; - - list_for_each_rcu(p, list) { - if (ptr == p) - return true; - } - return false; -} - -static bool -wprobe_send_item_value(struct sk_buff *msg, struct netlink_callback *cb, - struct wprobe_iface *dev, struct wprobe_link *l, - const struct wprobe_item *item, - int i, u32 flags) -{ - struct genlmsghdr *hdr; - struct wprobe_value *val = dev->query_val; - u64 time = val[i].last - val[i].first; - - hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, - &wprobe_fam, NLM_F_MULTI, WPROBE_CMD_GET_INFO); - - NLA_PUT_U32(msg, WPROBE_ATTR_ID, i); - NLA_PUT_U32(msg, WPROBE_ATTR_FLAGS, flags); - NLA_PUT_U8(msg, WPROBE_ATTR_TYPE, item[i].type); - NLA_PUT_U64(msg, WPROBE_ATTR_DURATION, time); - - switch(item[i].type) { - case WPROBE_VAL_S8: - case WPROBE_VAL_U8: - NLA_PUT_U8(msg, item[i].type, val[i].U8); - break; - case WPROBE_VAL_S16: - case WPROBE_VAL_U16: - NLA_PUT_U16(msg, item[i].type, val[i].U16); - break; - case WPROBE_VAL_S32: - case WPROBE_VAL_U32: - NLA_PUT_U32(msg, item[i].type, val[i].U32); - break; - case WPROBE_VAL_S64: - case WPROBE_VAL_U64: - NLA_PUT_U64(msg, item[i].type, val[i].U64); - break; - case WPROBE_VAL_STRING: - if (val[i].STRING) - NLA_PUT_STRING(msg, item[i].type, val[i].STRING); - else - NLA_PUT_STRING(msg, item[i].type, ""); - /* bypass avg/stdev */ - goto done; - default: - /* skip unknown values */ - goto done; - } - if (item[i].flags & WPROBE_F_KEEPSTAT) { - NLA_PUT_U64(msg, WPROBE_VAL_SUM, val[i].s); - NLA_PUT_U64(msg, WPROBE_VAL_SUM_SQ, val[i].ss); - NLA_PUT_U32(msg, WPROBE_VAL_SAMPLES, (u32) val[i].n); - NLA_PUT_MSECS(msg, WPROBE_VAL_SCALE_TIME, val[i].scale_timestamp); - } -done: - genlmsg_end(msg, hdr); - return true; - -nla_put_failure: - genlmsg_cancel(msg, hdr); - return false; -} - -static bool -wprobe_send_item_info(struct sk_buff *msg, struct netlink_callback *cb, - struct wprobe_iface *dev, - const struct wprobe_item *item, int i) -{ - struct genlmsghdr *hdr; - - hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, - &wprobe_fam, NLM_F_MULTI, WPROBE_CMD_GET_LIST); - - if ((i == 0) && (dev->addr != NULL)) - NLA_PUT(msg, WPROBE_ATTR_MAC, 6, dev->addr); - NLA_PUT_U32(msg, WPROBE_ATTR_ID, (u32) i); - NLA_PUT_STRING(msg, WPROBE_ATTR_NAME, item[i].name); - NLA_PUT_U8(msg, WPROBE_ATTR_TYPE, item[i].type); - NLA_PUT_U32(msg, WPROBE_ATTR_FLAGS, item[i].flags); - genlmsg_end(msg, hdr); - return true; - -nla_put_failure: - genlmsg_cancel(msg, hdr); - return false; -} - - -static struct wprobe_link * -wprobe_find_link(struct wprobe_iface *dev, const char *mac) -{ - struct wprobe_link *l; - - list_for_each_entry_rcu(l, &dev->links, list) { - if (!memcmp(l->addr, mac, 6)) - return l; - } - return NULL; -} - -static bool -wprobe_dump_filter_group(struct sk_buff *msg, struct wprobe_filter_group *fg, struct netlink_callback *cb) -{ - struct genlmsghdr *hdr; - struct nlattr *group, *item; - int i; - - hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, - &wprobe_fam, NLM_F_MULTI, WPROBE_CMD_GET_FILTER); - if (!hdr) - return false; - - NLA_PUT_STRING(msg, WPROBE_ATTR_NAME, fg->name); - group = nla_nest_start(msg, WPROBE_ATTR_FILTER_GROUP); - for (i = 0; i < fg->n_items; i++) { - struct wprobe_filter_item *fi = fg->items[i]; - struct wprobe_filter_counter *fc = &fg->counters[i]; - - item = nla_nest_start(msg, WPROBE_ATTR_FILTER_GROUP); - NLA_PUT_STRING(msg, WPROBE_ATTR_NAME, fi->hdr.name); - NLA_PUT_U64(msg, WPROBE_ATTR_RXCOUNT, fc->rx); - NLA_PUT_U64(msg, WPROBE_ATTR_TXCOUNT, fc->tx); - nla_nest_end(msg, item); - } - - nla_nest_end(msg, group); - genlmsg_end(msg, hdr); - return true; - -nla_put_failure: - genlmsg_cancel(msg, hdr); - return false; -} - -static int -wprobe_dump_filters(struct sk_buff *skb, struct netlink_callback *cb) -{ - struct wprobe_iface *dev = (struct wprobe_iface *)cb->args[0]; - struct wprobe_filter *f; - int err = 0; - int i = 0; - - if (!dev) { - err = nlmsg_parse(cb->nlh, GENL_HDRLEN + wprobe_fam.hdrsize, - wprobe_fam.attrbuf, wprobe_fam.maxattr, wprobe_policy); - if (err) - goto done; - - dev = wprobe_get_dev(wprobe_fam.attrbuf[WPROBE_ATTR_INTERFACE]); - if (!dev) { - err = -ENODEV; - goto done; - } - - cb->args[0] = (long) dev; - cb->args[1] = 0; - } else { - if (!wprobe_check_ptr(&wprobe_if, &dev->list)) { - err = -ENODEV; - goto done; - } - } - - rcu_read_lock(); - f = rcu_dereference(dev->active_filter); - if (!f) - goto abort; - - for (i = cb->args[1]; i < f->n_groups; i++) { - if (unlikely(!wprobe_dump_filter_group(skb, &f->groups[i], cb))) - break; - } - cb->args[1] = i; -abort: - rcu_read_unlock(); - err = skb->len; -done: - return err; -} - -static bool -wprobe_dump_link(struct sk_buff *msg, struct wprobe_link *l, struct netlink_callback *cb) -{ - struct genlmsghdr *hdr; - - hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, - &wprobe_fam, NLM_F_MULTI, WPROBE_CMD_GET_LINKS); - if (!hdr) - return false; - - NLA_PUT(msg, WPROBE_ATTR_MAC, 6, l->addr); - genlmsg_end(msg, hdr); - return true; - -nla_put_failure: - genlmsg_cancel(msg, hdr); - return false; -} - -static int -wprobe_dump_links(struct sk_buff *skb, struct netlink_callback *cb) -{ - struct wprobe_iface *dev = (struct wprobe_iface *)cb->args[0]; - struct wprobe_link *l; - int err = 0; - int i = 0; - - if (!dev) { - err = nlmsg_parse(cb->nlh, GENL_HDRLEN + wprobe_fam.hdrsize, - wprobe_fam.attrbuf, wprobe_fam.maxattr, wprobe_policy); - if (err) - goto done; - - dev = wprobe_get_dev(wprobe_fam.attrbuf[WPROBE_ATTR_INTERFACE]); - if (!dev) { - err = -ENODEV; - goto done; - } - - cb->args[0] = (long) dev; - } else { - if (!wprobe_check_ptr(&wprobe_if, &dev->list)) { - err = -ENODEV; - goto done; - } - } - - rcu_read_lock(); - list_for_each_entry_rcu(l, &dev->links, list) { - if (i < cb->args[1]) - continue; - - if (unlikely(!wprobe_dump_link(skb, l, cb))) - break; - - i++; - } - cb->args[1] = i; - rcu_read_unlock(); - err = skb->len; -done: - return err; -} - -#define WPROBE_F_LINK (1 << 31) /* for internal use */ -static int -wprobe_dump_info(struct sk_buff *skb, struct netlink_callback *cb) -{ - struct wprobe_iface *dev = (struct wprobe_iface *)cb->args[0]; - struct wprobe_link *l = (struct wprobe_link *)cb->args[1]; - struct wprobe_value *val; - const struct wprobe_item *item; - struct genlmsghdr *hdr; - unsigned long flags; - int cmd, n, i = cb->args[3]; - u32 vflags = cb->args[2]; - int err = 0; - - hdr = (struct genlmsghdr *)nlmsg_data(cb->nlh); - cmd = hdr->cmd; - - /* since the attribute value list might be too big for a single netlink - * message, the device, link and offset get stored in the netlink callback. - * if this is the first request, we need to do the full lookup for the device. - * - * access to the device and link structure is synchronized through rcu. - */ - rcu_read_lock(); - if (!dev) { - err = nlmsg_parse(cb->nlh, GENL_HDRLEN + wprobe_fam.hdrsize, - wprobe_fam.attrbuf, wprobe_fam.maxattr, wprobe_policy); - if (err) - goto done; - - err = -ENOENT; - dev = wprobe_get_dev(wprobe_fam.attrbuf[WPROBE_ATTR_INTERFACE]); - if (!dev) - goto done; - - if (cmd == WPROBE_CMD_GET_INFO) { - if (wprobe_fam.attrbuf[WPROBE_ATTR_MAC]) { - l = wprobe_find_link(dev, nla_data(wprobe_fam.attrbuf[WPROBE_ATTR_MAC])); - if (!l) - goto done; - - vflags = l->flags; - } - - if (l) { - item = dev->link_items; - n = dev->n_link_items; - val = l->val; - } else { - item = dev->global_items; - n = dev->n_global_items; - val = dev->val; - } - - /* sync data and move to temp storage for the query */ - spin_lock_irqsave(&dev->lock, flags); - err = wprobe_sync_data(dev, l, true); - if (!err) - memcpy(dev->query_val, val, n * sizeof(struct wprobe_value)); - spin_unlock_irqrestore(&dev->lock, flags); - - if (err) - goto done; - } - - if (wprobe_fam.attrbuf[WPROBE_ATTR_FLAGS]) - vflags |= nla_get_u32(wprobe_fam.attrbuf[WPROBE_ATTR_FLAGS]); - - if (wprobe_fam.attrbuf[WPROBE_ATTR_MAC]) - vflags |= WPROBE_F_LINK; - - cb->args[0] = (long) dev; - cb->args[1] = (long) l; - cb->args[2] = vflags; - cb->args[3] = 0; - } else { - /* when pulling pointers from the callback, validate them - * against the list using rcu to make sure that we won't - * dereference pointers to free'd memory after the last - * grace period */ - err = -ENOENT; - if (!wprobe_check_ptr(&wprobe_if, &dev->list)) - goto done; - - if (l && !wprobe_check_ptr(&dev->links, &l->list)) - goto done; - } - - if (vflags & WPROBE_F_LINK) { - item = dev->link_items; - n = dev->n_link_items; - } else { - item = dev->global_items; - n = dev->n_global_items; - } - - err = 0; - switch(cmd) { - case WPROBE_CMD_GET_INFO: - while (i < n) { - if (!wprobe_send_item_value(skb, cb, dev, l, item, i, vflags)) - break; - i++; - } - break; - case WPROBE_CMD_GET_LIST: - while (i < n) { - if (!wprobe_send_item_info(skb, cb, dev, item, i)) - break; - i++; - } - break; - default: - err = -EINVAL; - goto done; - } - cb->args[3] = i; - err = skb->len; - -done: - rcu_read_unlock(); - return err; -} -#undef WPROBE_F_LINK - -static int -wprobe_update_auto_measurement(struct wprobe_iface *dev, u32 interval) -{ - if (interval && (interval < WPROBE_MIN_INTERVAL)) - return -EINVAL; - - if (!interval && dev->measure_interval) - del_timer_sync(&dev->measure_timer); - - dev->measure_interval = interval; - if (!interval) - return 0; - - /* kick of a new measurement immediately */ - mod_timer(&dev->measure_timer, jiffies + 1); - - return 0; -} - -static int -wprobe_measure(struct sk_buff *skb, struct genl_info *info) -{ - struct wprobe_iface *dev; - struct wprobe_link *l = NULL; - int err = -ENOENT; - - rcu_read_lock(); - dev = wprobe_get_dev(info->attrs[WPROBE_ATTR_INTERFACE]); - if (!dev) - goto done; - - if (info->attrs[WPROBE_ATTR_MAC]) { - l = wprobe_find_link(dev, nla_data(wprobe_fam.attrbuf[WPROBE_ATTR_MAC])); - if (!l) - goto done; - } - - err = wprobe_sync_data(dev, l, false); - -done: - rcu_read_unlock(); - return err; -} - -static int -wprobe_check_filter(void *data, int datalen, int gs) -{ - struct wprobe_filter_item_hdr *hdr; - void *orig_data = data; - void *end = data + datalen; - int i, j, k, is, cur_is; - - for (i = j = is = 0; i < gs; i++) { - hdr = data; - data += sizeof(*hdr); - - if (data > end) - goto overrun; - - hdr->name[31] = 0; - cur_is = be32_to_cpu(hdr->n_items); - hdr->n_items = cur_is; - is += cur_is; - for (j = 0; j < cur_is; j++) { - struct sock_filter *sf; - int n_items; - - hdr = data; - data += sizeof(*hdr); - if (data > end) - goto overrun; - - hdr->name[31] = 0; - n_items = be32_to_cpu(hdr->n_items); - hdr->n_items = n_items; - - if (n_items > 1024) - goto overrun; - - sf = data; - if (n_items > 0) { - for (k = 0; k < n_items; k++) { - sf->code = be16_to_cpu(sf->code); - sf->k = be32_to_cpu(sf->k); - sf++; - } - if (sk_chk_filter(data, n_items) != 0) { - printk("%s: filter check failed at group %d, item %d\n", __func__, i, j); - return 0; - } - } - data += n_items * sizeof(struct sock_filter); - } - } - return is; - -overrun: - printk(KERN_ERR "%s: overrun during filter check at group %d, item %d, offset=%d, len=%d\n", __func__, i, j, (data - orig_data), datalen); - return 0; -} - -static void -wprobe_free_filter(struct wprobe_filter *f) -{ - if (f->skb) - kfree_skb(f->skb); - if (f->data) - kfree(f->data); - if (f->items) - kfree(f->items); - if (f->counters) - kfree(f->counters); - kfree(f); -} - - -static int -wprobe_set_filter(struct wprobe_iface *dev, void *data, int len) -{ - struct wprobe_filter_hdr *fhdr; - struct wprobe_rtap_hdr *rtap; - struct wprobe_filter *f; - int i, j, cur_is, is, gs; - - if (len < sizeof(*fhdr)) - return -EINVAL; - - fhdr = data; - data += sizeof(*fhdr); - len -= sizeof(*fhdr); - - if (memcmp(fhdr->magic, "WPFF", 4) != 0) { - printk(KERN_ERR "%s: filter rejected (invalid magic)\n", __func__); - return -EINVAL; - } - - gs = be16_to_cpu(fhdr->n_groups); - is = wprobe_check_filter(data, len, gs); - if (is == 0) - return -EINVAL; - - f = kzalloc(sizeof(struct wprobe_filter) + - gs * sizeof(struct wprobe_filter_group), GFP_ATOMIC); - if (!f) - return -ENOMEM; - - f->skb = alloc_skb(WPROBE_MAX_FRAME_SIZE, GFP_ATOMIC); - if (!f->skb) - goto error; - - f->data = kmalloc(len, GFP_ATOMIC); - if (!f->data) - goto error; - - f->items = kzalloc(sizeof(struct wprobe_filter_item *) * is, GFP_ATOMIC); - if (!f->items) - goto error; - - f->counters = kzalloc(sizeof(struct wprobe_filter_counter) * is, GFP_ATOMIC); - if (!f->counters) - goto error; - - spin_lock_init(&f->lock); - memcpy(f->data, data, len); - f->n_groups = gs; - - if (f->hdrlen < sizeof(struct wprobe_wlan_hdr)) - f->hdrlen = sizeof(struct wprobe_wlan_hdr); - - rtap = (struct wprobe_rtap_hdr *)skb_put(f->skb, sizeof(*rtap)); - memset(rtap, 0, sizeof(*rtap)); - rtap->len = cpu_to_le16(sizeof(struct wprobe_rtap_hdr) + f->hdrlen); - data = f->data; - - cur_is = 0; - for (i = 0; i < gs; i++) { - struct wprobe_filter_item_hdr *hdr = data; - struct wprobe_filter_group *g = &f->groups[i]; - - data += sizeof(*hdr); - g->name = hdr->name; - g->items = &f->items[cur_is]; - g->counters = &f->counters[cur_is]; - g->n_items = hdr->n_items; - - for (j = 0; j < g->n_items; j++) { - hdr = data; - f->items[cur_is++] = data; - data += sizeof(*hdr) + hdr->n_items * sizeof(struct sock_filter); - } - } - rcu_assign_pointer(dev->active_filter, f); - return 0; - -error: - wprobe_free_filter(f); - return -ENOMEM; -} - -static int -wprobe_set_config(struct sk_buff *skb, struct genl_info *info) -{ - struct wprobe_iface *dev; - unsigned long flags; - int err = -ENOENT; - u32 scale_min, scale_max; - u32 scale_m, scale_d; - struct nlattr *attr; - struct wprobe_filter *filter_free = NULL; - - rcu_read_lock(); - dev = wprobe_get_dev(info->attrs[WPROBE_ATTR_INTERFACE]); - if (!dev) - goto done_unlocked; - - err = -EINVAL; - spin_lock_irqsave(&dev->lock, flags); - if (info->attrs[WPROBE_ATTR_MAC]) { - /* not supported yet */ - goto done; - } - - if (info->attrs[WPROBE_ATTR_FLAGS]) { - u32 flags = nla_get_u32(info->attrs[WPROBE_ATTR_FLAGS]); - - if (flags & BIT(WPROBE_F_RESET)) { - struct wprobe_link *l; - - memset(dev->val, 0, sizeof(struct wprobe_value) * dev->n_global_items); - list_for_each_entry_rcu(l, &dev->links, list) { - memset(l->val, 0, sizeof(struct wprobe_value) * dev->n_link_items); - } - } - } - - if (info->attrs[WPROBE_ATTR_SAMPLES_MIN] || - info->attrs[WPROBE_ATTR_SAMPLES_MAX]) { - if ((attr = info->attrs[WPROBE_ATTR_SAMPLES_MIN])) - scale_min = nla_get_u32(attr); - else - scale_min = dev->scale_min; - - if ((attr = info->attrs[WPROBE_ATTR_SAMPLES_MAX])) - scale_max = nla_get_u32(attr); - else - scale_max = dev->scale_max; - - if ((!scale_min && !scale_max) || - (scale_min && scale_max && (scale_min < scale_max))) { - dev->scale_min = scale_min; - dev->scale_max = scale_max; - } else { - goto done; - } - } - - if (info->attrs[WPROBE_ATTR_SAMPLES_SCALE_M] && - info->attrs[WPROBE_ATTR_SAMPLES_SCALE_D]) { - - scale_m = nla_get_u32(info->attrs[WPROBE_ATTR_SAMPLES_SCALE_M]); - scale_d = nla_get_u32(info->attrs[WPROBE_ATTR_SAMPLES_SCALE_D]); - - if (!scale_d || (scale_m > scale_d)) - goto done; - - dev->scale_m = scale_m; - dev->scale_d = scale_d; - } - - if ((attr = info->attrs[WPROBE_ATTR_FILTER])) { - filter_free = rcu_dereference(dev->active_filter); - rcu_assign_pointer(dev->active_filter, NULL); - if (nla_len(attr) > 0) - wprobe_set_filter(dev, nla_data(attr), nla_len(attr)); - } - - err = 0; - if (info->attrs[WPROBE_ATTR_INTERVAL]) { - /* change of measurement interval requested */ - err = wprobe_update_auto_measurement(dev, - (u32) nla_get_u64(info->attrs[WPROBE_ATTR_INTERVAL])); - } - -done: - spin_unlock_irqrestore(&dev->lock, flags); -done_unlocked: - rcu_read_unlock(); - if (filter_free) { - synchronize_rcu(); - wprobe_free_filter(filter_free); - } - return err; -} - -static struct genl_ops wprobe_ops[] = { - { - .cmd = WPROBE_CMD_GET_INFO, - .dumpit = wprobe_dump_info, - .policy = wprobe_policy, - }, - { - .cmd = WPROBE_CMD_GET_LIST, - .dumpit = wprobe_dump_info, - .policy = wprobe_policy, - }, - { - .cmd = WPROBE_CMD_MEASURE, - .doit = wprobe_measure, - .policy = wprobe_policy, - }, - { - .cmd = WPROBE_CMD_GET_LINKS, - .dumpit = wprobe_dump_links, - .policy = wprobe_policy, - }, - { - .cmd = WPROBE_CMD_CONFIG, - .doit = wprobe_set_config, - .policy = wprobe_policy, - }, - { - .cmd = WPROBE_CMD_GET_FILTER, - .dumpit = wprobe_dump_filters, - .policy = wprobe_policy, - }, -}; - -static void __exit -wprobe_exit(void) -{ - BUG_ON(!list_empty(&wprobe_if)); - genl_unregister_family(&wprobe_fam); -} - - -static int __init -wprobe_init(void) -{ - int i, err; - - spin_lock_init(&wprobe_lock); - INIT_LIST_HEAD(&wprobe_if); - - err = genl_register_family(&wprobe_fam); - if (err) - return err; - - for (i = 0; i < ARRAY_SIZE(wprobe_ops); i++) { - err = genl_register_ops(&wprobe_fam, &wprobe_ops[i]); - if (err) - goto error; - } - - return 0; - -error: - genl_unregister_family(&wprobe_fam); - return err; -} - -module_init(wprobe_init); -module_exit(wprobe_exit); -MODULE_LICENSE("GPL"); - diff --git a/extra/wprobe/src/kernel/wprobe-dummy.c b/extra/wprobe/src/kernel/wprobe-dummy.c deleted file mode 100644 index 4231223e0..000000000 --- a/extra/wprobe/src/kernel/wprobe-dummy.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * wprobe-core.c: Wireless probe interface dummy driver - * Copyright (C) 2008-2009 Felix Fietkau - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include - -static const char local_addr[] = "\x00\x13\x37\xba\xbe\x00"; - -enum dummy_global_values { - DUMMY_GLOBAL_MEDIUM_BUSY -}; -enum dummy_link_values { - DUMMY_LINK_SNR -}; - -struct wprobe_item dummy_perlink[] = { - [DUMMY_LINK_SNR] = { - .name = "snr", - .type = WPROBE_VAL_U8, - .flags = WPROBE_F_KEEPSTAT, - }, -}; - -struct wprobe_item dummy_globals[] = { - [DUMMY_GLOBAL_MEDIUM_BUSY] = { - .name = "medium_busy", - .type = WPROBE_VAL_U8, - .flags = WPROBE_F_KEEPSTAT, - } -}; - -int dummy_sync(struct wprobe_iface *dev, struct wprobe_link *l, struct wprobe_value *val, bool measure) -{ - u8 intval = 0; - - get_random_bytes(&intval, 1); - if (l) { - WPROBE_FILL_BEGIN(val, dummy_perlink); - WPROBE_SET(DUMMY_LINK_SNR, U8, (intval % 40)); - WPROBE_FILL_END(); - } else { - WPROBE_FILL_BEGIN(val, dummy_globals); - WPROBE_SET(DUMMY_GLOBAL_MEDIUM_BUSY, U8, (intval % 100)); - WPROBE_FILL_END(); - } - return 0; -} - -static struct wprobe_iface dummy_dev = { - .name = "dummy", - .addr = local_addr, - .link_items = dummy_perlink, - .n_link_items = ARRAY_SIZE(dummy_perlink), - .global_items = dummy_globals, - .n_global_items = ARRAY_SIZE(dummy_globals), - .sync_data = dummy_sync, -}; - -static struct wprobe_link dummy_link; - -static int __init -wprobe_dummy_init(void) -{ - wprobe_add_iface(&dummy_dev); - wprobe_add_link(&dummy_dev, &dummy_link, "\x00\x13\x37\xda\xda\x00"); - return 0; -} - -static void __exit -wprobe_dummy_exit(void) -{ - wprobe_remove_link(&dummy_dev, &dummy_link); - wprobe_remove_iface(&dummy_dev); -} - -module_init(wprobe_dummy_init); -module_exit(wprobe_dummy_exit); - -MODULE_LICENSE("GPL"); diff --git a/extra/wprobe/src/user/Makefile b/extra/wprobe/src/user/Makefile deleted file mode 100644 index 01e83da3e..000000000 --- a/extra/wprobe/src/user/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -include ../Makefile.inc - -CPPFLAGS += -I../kernel -LDFLAGS = - -ifneq ($(HOST_OS),Linux) -USE_LIBNL_MICRO=1 -else -USE_LIBNL_MICRO= -endif - -ifeq ($(USE_LIBNL_MICRO),1) -LIBNL_PREFIX = /usr/local -LIBNL = $(LIBNL_PREFIX)/lib/libnl-micro.a -CPPFLAGS += -I$(LIBNL_PREFIX)/include/libnl-micro -EXTRA_CFLAGS += -DNO_LOCAL_ACCESS -else -LIBNL = -lnl -endif - -LIBM = -lm -LIBS = $(LIBNL) $(LIBM) - -all: libwprobe.a wprobe-util - -libwprobe.a: wprobe-lib.o - rm -f $@ - $(AR) rcu $@ $^ - $(RANLIB) $@ - -%.o: %.c - $(CC) $(WFLAGS) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) $< - -wprobe-util: wprobe-util.o wprobe-lib.o - $(CC) -o $@ $^ $(LDFLAGS) $(LIBS) - -clean: - rm -f *.o *.a wprobe-util diff --git a/extra/wprobe/src/user/list.h b/extra/wprobe/src/user/list.h deleted file mode 100644 index 2959a061d..000000000 --- a/extra/wprobe/src/user/list.h +++ /dev/null @@ -1,601 +0,0 @@ -#ifndef _LINUX_LIST_H -#define _LINUX_LIST_H - -#include -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#ifndef container_of -#define container_of(ptr, type, member) ( \ - (type *)( (char *)ptr - offsetof(type,member) )) -#endif - - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -static inline void INIT_LIST_HEAD(struct list_head *list) -{ - list->next = list; - list->prev = list; -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head * prev, struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty() on entry does not return true after this, the entry is - * in an undefined state. - */ -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = NULL; - entry->prev = NULL; -} - -/** - * list_replace - replace old entry by new one - * @old : the element to be replaced - * @new : the new element to insert - * - * If @old was empty, it will be overwritten. - */ -static inline void list_replace(struct list_head *old, - struct list_head *new) -{ - new->next = old->next; - new->next->prev = new; - new->prev = old->prev; - new->prev->next = new; -} - -static inline void list_replace_init(struct list_head *old, - struct list_head *new) -{ - list_replace(old, new); - INIT_LIST_HEAD(old); -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static inline void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_move - delete from one list and add as another's head - * @list: the entry to move - * @head: the head that will precede our entry - */ -static inline void list_move(struct list_head *list, struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add(list, head); -} - -/** - * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move - * @head: the head that will follow our entry - */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add_tail(list, head); -} - -/** - * list_is_last - tests whether @list is the last entry in list @head - * @list: the entry to test - * @head: the head of the list - */ -static inline int list_is_last(const struct list_head *list, - const struct list_head *head) -{ - return list->next == head; -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/** - * list_empty_careful - tests whether a list is empty and not being modified - * @head: the list to test - * - * Description: - * tests whether a list is empty _and_ checks that no other CPU might be - * in the process of modifying either member (next or prev) - * - * NOTE: using list_empty_careful() without synchronization - * can only be safe if the only activity that can happen - * to the list entry is list_del_init(). Eg. it cannot be used - * if another CPU could re-list_add() it. - */ -static inline int list_empty_careful(const struct list_head *head) -{ - struct list_head *next = head->next; - return (next == head) && (next == head->prev); -} - -static inline void __list_splice(struct list_head *list, - struct list_head *head) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice(struct list_head *list, struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head); -} - -/** - * list_splice_init - join two lists and reinitialise the emptied list. - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * The list at @list is reinitialised - */ -static inline void list_splice_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head); - INIT_LIST_HEAD(list); - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_first_entry - get the first element from a list - * @ptr: the list head to take the element from. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - * - * Note, that list is expected to be not empty. - */ -#define list_first_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); \ - pos = pos->next) - -/** - * __list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - * - * This variant differs from list_for_each() in that it's the - * simplest possible list iteration code, no prefetching is done. - * Use this for code that knows the list to be very short (empty - * or 1 entry) most of the time. - */ -#define __list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_prev - iterate over a list backwards - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; pos != (head); \ - pos = pos->prev) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_prev_safe(pos, n, head) \ - for (pos = (head)->prev, n = pos->prev; \ - pos != (head); \ - pos = n, n = pos->prev) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_reverse - iterate backwards over list of given type. - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() - * @pos: the type * to use as a start point - * @head: the head of the list - * @member: the name of the list_struct within the struct. - * - * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). - */ -#define list_prepare_entry(pos, head, member) \ - ((pos) ? : list_entry(head, typeof(*pos), member)) - -/** - * list_for_each_entry_continue - continue iteration over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Continue to iterate over list of given type, continuing after - * the current position. - */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_continue_reverse - iterate backwards from the given point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Start to iterate over list of given type backwards, continuing after - * the current position. - */ -#define list_for_each_entry_continue_reverse(pos, head, member) \ - for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_for_each_entry_from - iterate over list of given type from the current point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing from current position. - */ -#define list_for_each_entry_from(pos, head, member) \ - for (; &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_continue - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing after current point, - * safe against removal of list entry. - */ -#define list_for_each_entry_safe_continue(pos, n, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_from - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type from current point, safe against - * removal of list entry. - */ -#define list_for_each_entry_safe_from(pos, n, head, member) \ - for (n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_reverse - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate backwards over list of given type, safe against removal - * of list entry. - */ -#define list_for_each_entry_safe_reverse(pos, n, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member), \ - n = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.prev, typeof(*n), member)) - -/* - * Double linked lists with a single pointer list head. - * Mostly useful for hash tables where the two pointer list head is - * too wasteful. - * You lose the ability to access the tail in O(1). - */ - -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **pprev; -}; - -#define HLIST_HEAD_INIT { .first = NULL } -#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } -#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) -static inline void INIT_HLIST_NODE(struct hlist_node *h) -{ - h->next = NULL; - h->pprev = NULL; -} - -static inline int hlist_unhashed(const struct hlist_node *h) -{ - return !h->pprev; -} - -static inline int hlist_empty(const struct hlist_head *h) -{ - return !h->first; -} - -static inline void __hlist_del(struct hlist_node *n) -{ - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next) - next->pprev = pprev; -} - -static inline void hlist_del(struct hlist_node *n) -{ - __hlist_del(n); - n->next = NULL; - n->pprev = NULL; -} - -static inline void hlist_del_init(struct hlist_node *n) -{ - if (!hlist_unhashed(n)) { - __hlist_del(n); - INIT_HLIST_NODE(n); - } -} - - -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - struct hlist_node *first = h->first; - n->next = first; - if (first) - first->pprev = &n->next; - h->first = n; - n->pprev = &h->first; -} - - -/* next must be != NULL */ -static inline void hlist_add_before(struct hlist_node *n, - struct hlist_node *next) -{ - n->pprev = next->pprev; - n->next = next; - next->pprev = &n->next; - *(n->pprev) = n; -} - -static inline void hlist_add_after(struct hlist_node *n, - struct hlist_node *next) -{ - next->next = n->next; - n->next = next; - next->pprev = &n->next; - - if(next->next) - next->next->pprev = &next->next; -} - -#define hlist_entry(ptr, type, member) container_of(ptr,type,member) - -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos; pos = pos->next) - -#define hlist_for_each_safe(pos, n, head) \ - for (pos = (head)->first; pos; pos = n) - -/** - * hlist_for_each_entry - iterate over list of given type - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry(tpos, pos, head, member) \ - for (pos = (head)->first; pos && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_continue - iterate over a hlist continuing after current point - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_continue(tpos, pos, member) \ - for (pos = (pos)->next; pos && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_from - iterate over a hlist continuing from current point - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_from(tpos, pos, member) \ - for (; pos && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @n: another &struct hlist_node to use as temporary storage - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ - for (pos = (head)->first; \ - pos && ({ n = pos->next; 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = n) - -#endif diff --git a/extra/wprobe/src/user/wprobe-lib.c b/extra/wprobe/src/user/wprobe-lib.c deleted file mode 100644 index 7a5460bb0..000000000 --- a/extra/wprobe/src/user/wprobe-lib.c +++ /dev/null @@ -1,1210 +0,0 @@ -/* - * wprobe.c: Wireless probe user space library - * Copyright (C) 2008-2009 Felix Fietkau - * - * 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. - */ - -#define _ISOC99_SOURCE -#define _BSD_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef NO_LOCAL_ACCESS -#include -#include -#include -#endif -#include "wprobe.h" - -#define DEBUG 1 -#ifdef DEBUG -#define DPRINTF(fmt, ...) fprintf(stderr, "%s(%d): " fmt, __func__, __LINE__, ##__VA_ARGS__) -#else -#define DPRINTF(fmt, ...) do {} while (0) -#endif - -#if defined(BYTE_ORDER) && !defined(__BYTE_ORDER) -#define __LITTLE_ENDIAN LITTLE_ENDIAN -#define __BIG_ENDIAN BIG_ENDIAN -#define __BYTE_ORDER BYTE_ORDER -#endif - -#ifndef __BYTE_ORDER -#error Unknown endian type -#endif - -#define WPROBE_MAX_MSGLEN 65536 - -static inline __u16 __swab16(__u16 x) -{ - return x<<8 | x>>8; -} - -static inline __u32 __swab32(__u32 x) -{ - return x<<24 | x>>24 | - (x & (__u32)0x0000ff00UL)<<8 | - (x & (__u32)0x00ff0000UL)>>8; -} - -static inline __u64 __swab64(__u64 x) -{ - return x<<56 | x>>56 | - (x & (__u64)0x000000000000ff00ULL)<<40 | - (x & (__u64)0x0000000000ff0000ULL)<<24 | - (x & (__u64)0x00000000ff000000ULL)<< 8 | - (x & (__u64)0x000000ff00000000ULL)>> 8 | - (x & (__u64)0x0000ff0000000000ULL)>>24 | - (x & (__u64)0x00ff000000000000ULL)>>40; -} - - -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define SWAP16(var) var = __swab16(var) -#define SWAP32(var) var = __swab32(var) -#define SWAP64(var) var = __swab64(var) -#else -#define SWAP16(var) do {} while(0) -#define SWAP32(var) do {} while(0) -#define SWAP64(var) do {} while(0) -#endif - -int wprobe_port = 17990; -static struct nlattr *tb[WPROBE_ATTR_LAST+1]; -static struct nla_policy attribute_policy[WPROBE_ATTR_LAST+1] = { - [WPROBE_ATTR_ID] = { .type = NLA_U32 }, - [WPROBE_ATTR_MAC] = { .type = NLA_UNSPEC, .minlen = 6, .maxlen = 6 }, - [WPROBE_ATTR_NAME] = { .type = NLA_STRING }, - [WPROBE_ATTR_FLAGS] = { .type = NLA_U32 }, - [WPROBE_ATTR_TYPE] = { .type = NLA_U8 }, - [WPROBE_ATTR_FLAGS] = { .type = NLA_U32 }, - [WPROBE_VAL_S8] = { .type = NLA_U8 }, - [WPROBE_VAL_S16] = { .type = NLA_U16 }, - [WPROBE_VAL_S32] = { .type = NLA_U32 }, - [WPROBE_VAL_S64] = { .type = NLA_U64 }, - [WPROBE_VAL_U8] = { .type = NLA_U8 }, - [WPROBE_VAL_U16] = { .type = NLA_U16 }, - [WPROBE_VAL_U32] = { .type = NLA_U32 }, - [WPROBE_VAL_U64] = { .type = NLA_U64 }, - [WPROBE_VAL_SUM] = { .type = NLA_U64 }, - [WPROBE_VAL_SUM_SQ] = { .type = NLA_U64 }, - [WPROBE_VAL_SAMPLES] = { .type = NLA_U32 }, - [WPROBE_VAL_SCALE_TIME] = { .type = NLA_U64 }, - [WPROBE_ATTR_INTERVAL] = { .type = NLA_U64 }, - [WPROBE_ATTR_SAMPLES_MIN] = { .type = NLA_U32 }, - [WPROBE_ATTR_SAMPLES_MAX] = { .type = NLA_U32 }, - [WPROBE_ATTR_SAMPLES_SCALE_M] = { .type = NLA_U32 }, - [WPROBE_ATTR_SAMPLES_SCALE_D] = { .type = NLA_U32 }, - [WPROBE_ATTR_FILTER_GROUP] = { .type = NLA_NESTED }, - [WPROBE_ATTR_RXCOUNT] = { .type = NLA_U64 }, - [WPROBE_ATTR_TXCOUNT] = { .type = NLA_U64 }, -}; - -typedef int (*wprobe_cb_t)(struct nl_msg *, void *); - -struct wprobe_iface_ops { - int (*send_msg)(struct wprobe_iface *dev, struct nl_msg *msg, wprobe_cb_t cb, void *arg); - void (*free)(struct wprobe_iface *dev); -}; - -struct wprobe_attr_cb { - struct list_head *list; - char *addr; -}; - -#define WPROBE_MAGIC_STR "WPROBE" -struct wprobe_init_hdr { - struct { - char magic[sizeof(WPROBE_MAGIC_STR)]; - - /* protocol version */ - uint8_t version; - - /* extra header length (unused for now) */ - uint16_t extra; - } pre __attribute__((packed)); - union { - struct { - uint16_t genl_family; - } v0 __attribute__((packed)); - }; -} __attribute__((packed)); - -struct wprobe_msg_hdr { - __u16 status; - __u16 error; - __u32 len; -}; - -enum wprobe_resp_status { - WPROBE_MSG_DONE = 0, - WPROBE_MSG_DATA = 1, -}; - -static inline void -wprobe_swap_msg_hdr(struct wprobe_msg_hdr *mhdr) -{ - SWAP16(mhdr->status); - SWAP16(mhdr->error); - SWAP32(mhdr->len); -} - -static int -save_attribute_handler(struct nl_msg *msg, void *arg) -{ - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - const char *name = "N/A"; - struct wprobe_attribute *attr; - int type = 0; - struct wprobe_attr_cb *cb = arg; - - nla_parse(tb, WPROBE_ATTR_LAST, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), attribute_policy); - - if (tb[WPROBE_ATTR_NAME]) - name = nla_data(tb[WPROBE_ATTR_NAME]); - - attr = malloc(sizeof(struct wprobe_attribute) + strlen(name) + 1); - if (!attr) - return -1; - - memset(attr, 0, sizeof(struct wprobe_attribute)); - - if (tb[WPROBE_ATTR_ID]) - attr->id = nla_get_u32(tb[WPROBE_ATTR_ID]); - - if (tb[WPROBE_ATTR_MAC] && cb->addr) - memcpy(cb->addr, nla_data(tb[WPROBE_ATTR_MAC]), 6); - - if (tb[WPROBE_ATTR_FLAGS]) - attr->flags = nla_get_u32(tb[WPROBE_ATTR_FLAGS]); - - if (tb[WPROBE_ATTR_TYPE]) - type = nla_get_u8(tb[WPROBE_ATTR_TYPE]); - - if ((type < WPROBE_VAL_STRING) || - (type > WPROBE_VAL_U64)) - type = 0; - - attr->type = type; - strcpy(attr->name, name); - INIT_LIST_HEAD(&attr->list); - list_add(&attr->list, cb->list); - return 0; -} - -static struct nl_msg * -wprobe_new_msg(struct wprobe_iface *dev, int cmd, bool dump) -{ - struct nl_msg *msg; - uint32_t flags = 0; - - msg = nlmsg_alloc_size(65536); - if (!msg) - return NULL; - - if (dump) - flags |= NLM_F_DUMP; - - genlmsg_put(msg, 0, 0, dev->genl_family, - 0, flags, cmd, 0); - - NLA_PUT_STRING(msg, WPROBE_ATTR_INTERFACE, dev->ifname); -nla_put_failure: - return msg; -} - - -static int -dump_attributes(struct wprobe_iface *dev, bool link, struct list_head *list, char *addr) -{ - struct nl_msg *msg; - struct wprobe_attr_cb cb; - - cb.list = list; - cb.addr = addr; - msg = wprobe_new_msg(dev, WPROBE_CMD_GET_LIST, true); - if (!msg) - return -ENOMEM; - - if (link) - NLA_PUT(msg, WPROBE_ATTR_MAC, 6, "\x00\x00\x00\x00\x00\x00"); - - return dev->ops->send_msg(dev, msg, save_attribute_handler, &cb); - -nla_put_failure: - nlmsg_free(msg); - return -EINVAL; -} - -static struct wprobe_iface * -wprobe_alloc_dev(void) -{ - struct wprobe_iface *dev; - - dev = malloc(sizeof(struct wprobe_iface)); - if (!dev) - return NULL; - - memset(dev, 0, sizeof(struct wprobe_iface)); - - dev->interval = -1; - dev->scale_min = -1; - dev->scale_max = -1; - dev->scale_m = -1; - dev->scale_d = -1; - dev->sockfd = -1; - - INIT_LIST_HEAD(&dev->global_attr); - INIT_LIST_HEAD(&dev->link_attr); - INIT_LIST_HEAD(&dev->links); - return dev; -} - -static int -wprobe_init_dev(struct wprobe_iface *dev) -{ - dump_attributes(dev, false, &dev->global_attr, NULL); - dump_attributes(dev, true, &dev->link_attr, NULL); - return 0; -} - -#ifndef NO_LOCAL_ACCESS -static int n_devs = 0; -static struct nl_sock *handle = NULL; -static struct nl_cache *cache = NULL; -static struct genl_family *family = NULL; - -static int -error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) -{ - int *ret = arg; - *ret = err->error; - return NL_STOP; -} - -static int -finish_handler(struct nl_msg *msg, void *arg) -{ - int *ret = arg; - *ret = 0; - return NL_SKIP; -} - -static int -ack_handler(struct nl_msg *msg, void *arg) -{ - int *ret = arg; - *ret = 0; - return NL_STOP; -} - -static void -wprobe_local_free(struct wprobe_iface *dev) -{ - /* should not happen */ - if (n_devs == 0) - return; - - if (--n_devs != 0) - return; - - if (cache) - nl_cache_free(cache); - if (handle) - nl_socket_free(handle); - handle = NULL; - cache = NULL; -} - -static int -wprobe_local_init(void) -{ - int ret; - - if (n_devs++ > 0) - return 0; - - handle = nl_socket_alloc(); - if (!handle) { - DPRINTF("Failed to create handle\n"); - goto err; - } - - if (genl_connect(handle)) { - DPRINTF("Failed to connect to generic netlink\n"); - goto err; - } - - ret = genl_ctrl_alloc_cache(handle, &cache); - if (ret < 0) { - DPRINTF("Failed to allocate netlink cache\n"); - goto err; - } - - family = genl_ctrl_search_by_name(cache, "wprobe"); - if (!family) { - DPRINTF("wprobe API not present\n"); - goto err; - } - return 0; - -err: - wprobe_local_free(NULL); - return -EINVAL; -} - - -static int -wprobe_local_send_msg(struct wprobe_iface *dev, struct nl_msg *msg, wprobe_cb_t callback, void *arg) -{ - struct nl_cb *cb; - int err = 0; - - cb = nl_cb_alloc(NL_CB_DEFAULT); - if (!cb) - goto out_no_cb; - - if (callback) - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, callback, arg); - - err = nl_send_auto_complete(handle, msg); - if (err < 0) - goto out; - - err = 1; - - nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); - nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); - nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); - - while (err > 0) - nl_recvmsgs(handle, cb); - -out: - nl_cb_put(cb); -out_no_cb: - nlmsg_free(msg); - return err; -} - -static const struct wprobe_iface_ops wprobe_local_ops = { - .send_msg = wprobe_local_send_msg, - .free = wprobe_local_free, -}; - -struct wprobe_iface * -wprobe_get_dev(const char *ifname) -{ - struct wprobe_iface *dev; - - if (wprobe_local_init() != 0) - return NULL; - - dev = wprobe_alloc_dev(); - if (!dev) - goto error_alloc; - - dev->ifname = strdup(ifname); - dev->ops = &wprobe_local_ops; - dev->genl_family = genl_family_get_id(family); - - if (wprobe_init_dev(dev) < 0) - goto error; - - return dev; - -error: - free(dev); -error_alloc: - wprobe_local_free(NULL); - return NULL; -} - -#endif - -static void swap_nlmsghdr(struct nlmsghdr *nlh) -{ - SWAP32(nlh->nlmsg_len); - SWAP16(nlh->nlmsg_type); - SWAP16(nlh->nlmsg_flags); - SWAP32(nlh->nlmsg_seq); - SWAP32(nlh->nlmsg_pid); -} - -static void swap_genlmsghdr(struct genlmsghdr *gnlh) -{ -#if 0 /* probably unnecessary */ - SWAP16(gnlh->reserved); -#endif -} - -static void -wprobe_swap_nested(void *data, int len, bool outgoing) -{ - void *end = data + len; - - while (data < end) { - struct nlattr *nla = data; - unsigned int type, len; - - if (!outgoing) { - SWAP16(nla->nla_len); - SWAP16(nla->nla_type); - - /* required for further sanity checks */ - if (data + nla->nla_len > end) - nla->nla_len = end - data; - } - - len = NLA_ALIGN(nla->nla_len); - type = nla->nla_type & NLA_TYPE_MASK; - - if (type <= WPROBE_ATTR_LAST) { -#if __BYTE_ORDER == __LITTLE_ENDIAN - switch(attribute_policy[type].type) { - case NLA_U16: - SWAP16(*(__u16 *)nla_data(nla)); - break; - case NLA_U32: - SWAP32(*(__u32 *)nla_data(nla)); - break; - case NLA_U64: - SWAP64(*(__u64 *)nla_data(nla)); - break; - case NLA_NESTED: - wprobe_swap_nested(nla_data(nla), nla_len(nla), outgoing); - break; - } -#endif - } - data += len; - - if (outgoing) { - SWAP16(nla->nla_len); - SWAP16(nla->nla_type); - } - if (!nla->nla_len) - break; - } -} - -static struct nl_msg * -wprobe_msg_from_network(int socket, int len) -{ - struct genlmsghdr *gnlh; - struct nlmsghdr *nlh; - struct nl_msg *msg; - void *data; - - msg = nlmsg_alloc_size(len + 32); - if (!msg) - return NULL; - - nlh = nlmsg_hdr(msg); - if (read(socket, nlh, len) != len) - goto free; - - swap_nlmsghdr(nlh); - if (nlh->nlmsg_len > len) - goto free; - - gnlh = nlmsg_data(nlh); - swap_genlmsghdr(gnlh); - - data = genlmsg_data(gnlh); - wprobe_swap_nested(data, genlmsg_len(gnlh), false); - - return msg; -free: - nlmsg_free(msg); - return NULL; -} - -static int -wprobe_msg_to_network(int socket, struct nl_msg *msg) -{ - struct nlmsghdr *nlh = nlmsg_hdr(msg); - struct wprobe_msg_hdr mhdr; - struct genlmsghdr *gnlh; - void *buf, *data; - int buflen, datalen; - int ret; - - buflen = nlh->nlmsg_len; - buf = malloc(buflen); - if (!buf) - return -ENOMEM; - - memset(&mhdr, 0, sizeof(mhdr)); - mhdr.status = WPROBE_MSG_DATA; - mhdr.len = buflen; - wprobe_swap_msg_hdr(&mhdr); - ret = write(socket, &mhdr, sizeof(mhdr)); - if (ret < 0) - goto out; - - memcpy(buf, nlh, buflen); - nlh = buf; - gnlh = nlmsg_data(nlh); - data = genlmsg_data(gnlh); - datalen = genlmsg_len(gnlh); - - wprobe_swap_nested(data, datalen, true); - swap_genlmsghdr(gnlh); - swap_nlmsghdr(nlh); - ret = write(socket, buf, buflen); - -out: - free(buf); - - return ret; -} - -static int -wprobe_remote_send_msg(struct wprobe_iface *dev, struct nl_msg *msg, wprobe_cb_t callback, void *arg) -{ - struct wprobe_msg_hdr mhdr; - int msgs = 0; - - wprobe_msg_to_network(dev->sockfd, msg); - nlmsg_free(msg); - do { - if (read(dev->sockfd, &mhdr, sizeof(mhdr)) != sizeof(mhdr)) { - DPRINTF("Failed to read response header\n"); - return -1; - } - wprobe_swap_msg_hdr(&mhdr); - - switch(mhdr.status) { - case WPROBE_MSG_DATA: - if (mhdr.len > WPROBE_MAX_MSGLEN) { - fprintf(stderr, "Invalid length in received response message.\n"); - exit(1); - } - - msg = wprobe_msg_from_network(dev->sockfd, mhdr.len); - if (!msg) - return -EINVAL; - - msgs++; - callback(msg, arg); - nlmsg_free(msg); - break; - } - } while (mhdr.status != WPROBE_MSG_DONE); - - if (mhdr.error) - return -mhdr.error; - else - return msgs; -} - - -static void -wprobe_socket_dev_free(struct wprobe_iface *dev) -{ - if (dev->sockfd >= 0) - close(dev->sockfd); -} - -static const struct wprobe_iface_ops wprobe_remote_ops = { - .send_msg = wprobe_remote_send_msg, - .free = wprobe_socket_dev_free, -}; - - -#ifndef NO_LOCAL_ACCESS -int -wprobe_server_init(int socket) -{ - struct wprobe_init_hdr hdr; - int ret; - - ret = wprobe_local_init(); - if (ret != 0) - return ret; - - memset(&hdr, 0, sizeof(hdr)); - memcpy(hdr.pre.magic, WPROBE_MAGIC_STR, sizeof(WPROBE_MAGIC_STR)); - hdr.pre.version = 0; - hdr.v0.genl_family = genl_family_get_id(family); - SWAP16(hdr.v0.genl_family); - write(socket, (unsigned char *)&hdr, sizeof(hdr)); - - return 0; -} - -static int -wprobe_server_cb(struct nl_msg *msg, void *arg) -{ - int *socket = arg; - int ret; - - ret = wprobe_msg_to_network(*socket, msg); - if (ret > 0) - ret = 0; - - return ret; -} - - -int -wprobe_server_handle(int socket) -{ - struct wprobe_msg_hdr mhdr; - struct nl_msg *msg; - int ret; - - ret = read(socket, &mhdr, sizeof(mhdr)); - if (ret != sizeof(mhdr)) { - if (ret <= 0) - return -1; - - DPRINTF("Failed to read request header\n"); - return -EINVAL; - } - wprobe_swap_msg_hdr(&mhdr); - - switch(mhdr.status) { - case WPROBE_MSG_DATA: - if (mhdr.len > WPROBE_MAX_MSGLEN) { - DPRINTF("Invalid length in received response message.\n"); - return -EINVAL; - } - msg = wprobe_msg_from_network(socket, mhdr.len); - break; - default: - DPRINTF("Invalid request header type\n"); - return -ENOENT; - } - - if (!msg) { - DPRINTF("Failed to get message\n"); - return -EINVAL; - } - - ret = wprobe_local_send_msg(NULL, msg, wprobe_server_cb, &socket); - - memset(&mhdr, 0, sizeof(mhdr)); - mhdr.status = WPROBE_MSG_DONE; - if (ret < 0) - mhdr.error = (uint16_t) -ret; - - ret = write(socket, (unsigned char *)&mhdr, sizeof(mhdr)); - if (ret > 0) - ret = 0; - - return ret; -} - -void -wprobe_server_done(void) -{ - wprobe_local_free(NULL); -} -#endif - -struct wprobe_iface * -wprobe_get_from_socket(int socket, const char *name) -{ - struct wprobe_iface *dev; - struct wprobe_init_hdr hdr; - - dev = wprobe_alloc_dev(); - if (!dev) - goto out; - - dev->ops = &wprobe_remote_ops; - dev->sockfd = socket; - dev->ifname = strdup(name); - - /* read version and header length */ - if (read(socket, &hdr.pre, sizeof(hdr.pre)) != sizeof(hdr.pre)) { - DPRINTF("Could not read header\n"); - goto error; - } - - /* magic not found */ - if (memcmp(hdr.pre.magic, WPROBE_MAGIC_STR, sizeof(hdr.pre.magic)) != 0) { - DPRINTF("Magic does not match\n"); - goto error; - } - - /* unsupported version */ - if (hdr.pre.version != 0) { - DPRINTF("Protocol version does not match\n"); - goto error; - } - - if (read(socket, &hdr.v0, sizeof(hdr.v0)) != sizeof(hdr.v0)) { - DPRINTF("Could not read header data\n"); - goto error; - } - - SWAP16(hdr.pre.extra); - SWAP16(hdr.v0.genl_family); - dev->genl_family = hdr.v0.genl_family; - - if (wprobe_init_dev(dev) < 0) { - DPRINTF("Could not initialize device\n"); - goto error; - } - -out: - return dev; - -error: - wprobe_free_dev(dev); - return NULL; -} - -struct wprobe_iface * -wprobe_get_auto(const char *arg, char **err) -{ - static struct sockaddr_in sa; - static char errbuf[512]; - - struct wprobe_iface *dev = NULL; - struct hostent *h; - char *devstr = strdup(arg); - char *sep = NULL; - int sock = -1; - int len; - - if (err) - *err = NULL; - - sep = strchr(devstr, ':'); - if (!sep) { -#ifndef NO_LOCAL_ACCESS - free(devstr); - return wprobe_get_dev(arg); -#else - if (err) - *err = "Invalid argument"; - goto out; -#endif - } - - *sep = 0; - sep++; - - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) - goto syserr; - - h = gethostbyname(devstr); - if (!h) { - sprintf(errbuf, "Host not found"); - goto out_err; - } - - memcpy(&sa.sin_addr, h->h_addr, h->h_length); - sa.sin_family = AF_INET; - sa.sin_port = htons(wprobe_port); - if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) - goto syserr; - - dev = wprobe_get_from_socket(sock, sep); - if (!dev) { - sprintf(errbuf, "wprobe connection initialization failed"); - goto out_err; - } - goto out; - -syserr: - if (err) { - strcpy(errbuf, "Connection failed: "); - len = strlen(errbuf); - strerror_r(errno, errbuf + len, sizeof(errbuf) - len - 1); - } -out_err: - if (err) - *err = errbuf; - if (sock >= 0) - close(sock); -out: - if (devstr) - free(devstr); - return dev; -} - -static void -free_attr_list(struct list_head *list) -{ - struct wprobe_attribute *attr, *tmp; - - list_for_each_entry_safe(attr, tmp, list, list) { - list_del(&attr->list); - free(attr); - } -} - -void -wprobe_free_dev(struct wprobe_iface *dev) -{ - if (dev->ops->free) - dev->ops->free(dev); - free_attr_list(&dev->global_attr); - free_attr_list(&dev->link_attr); - free((void *)dev->ifname); - free(dev); -} - -static struct wprobe_link * -get_link(struct list_head *list, const char *addr) -{ - struct wprobe_link *l; - - list_for_each_entry(l, list, list) { - if (!memcmp(l->addr, addr, 6)) { - list_del_init(&l->list); - goto out; - } - } - - /* no previous link found, allocate a new one */ - l = malloc(sizeof(struct wprobe_link)); - if (!l) - goto out; - - memset(l, 0, sizeof(struct wprobe_link)); - memcpy(l->addr, addr, sizeof(l->addr)); - INIT_LIST_HEAD(&l->list); - -out: - return l; -} - -struct wprobe_save_cb { - struct list_head *list; - struct list_head old_list; -}; - -static int -save_link_handler(struct nl_msg *msg, void *arg) -{ - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - struct wprobe_link *link; - struct wprobe_save_cb *cb = arg; - const char *addr; - - nla_parse(tb, WPROBE_ATTR_LAST, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), attribute_policy); - - if (!tb[WPROBE_ATTR_MAC] || (nla_len(tb[WPROBE_ATTR_MAC]) != 6)) - return -1; - - addr = nla_data(tb[WPROBE_ATTR_MAC]); - link = get_link(&cb->old_list, addr); - if (!link) - return -1; - - if (tb[WPROBE_ATTR_FLAGS]) - link->flags = nla_get_u32(tb[WPROBE_ATTR_FLAGS]); - - list_add_tail(&link->list, cb->list); - return 0; -} - - -int -wprobe_update_links(struct wprobe_iface *dev) -{ - struct wprobe_link *l, *tmp; - struct nl_msg *msg; - struct wprobe_save_cb cb; - int err; - - INIT_LIST_HEAD(&cb.old_list); - list_splice_init(&dev->links, &cb.old_list); - cb.list = &dev->links; - - msg = wprobe_new_msg(dev, WPROBE_CMD_GET_LINKS, true); - if (!msg) - return -ENOMEM; - - err = dev->ops->send_msg(dev, msg, save_link_handler, &cb); - if (err < 0) - return err; - - list_for_each_entry_safe(l, tmp, &cb.old_list, list) { - list_del(&l->list); - free(l); - } - - return 0; -} - - -struct wprobe_filter_data -{ - wprobe_filter_cb cb; - void *arg; - struct wprobe_filter_item *buf; - int buflen; -}; - -static int -dump_filter_handler(struct nl_msg *msg, void *arg) -{ - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - struct wprobe_filter_data *data = arg; - struct nlattr *p; - const char *name; - int count = 0; - int len; - - nla_parse(tb, WPROBE_ATTR_LAST, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), attribute_policy); - - if (!tb[WPROBE_ATTR_NAME] || !tb[WPROBE_ATTR_FILTER_GROUP]) - return -1; - - name = nla_data(tb[WPROBE_ATTR_NAME]); - nla_for_each_nested(p, tb[WPROBE_ATTR_FILTER_GROUP], len) { - count++; - } - - if (data->buflen < count) { - if (data->buf) - free(data->buf); - data->buflen = count; - data->buf = malloc(sizeof(struct wprobe_filter_item) * count); - memset(data->buf, 0, sizeof(struct wprobe_filter_item) * count); - } - - count = 0; - nla_for_each_nested(p, tb[WPROBE_ATTR_FILTER_GROUP], len) { - struct wprobe_filter_item *fi; - - nla_parse(tb, WPROBE_ATTR_LAST, nla_data(p), - nla_len(p), attribute_policy); - - if (!tb[WPROBE_ATTR_NAME] || !tb[WPROBE_ATTR_RXCOUNT] - || !tb[WPROBE_ATTR_TXCOUNT]) - continue; - - fi = &data->buf[count++]; - strncpy(fi->name, nla_data(tb[WPROBE_ATTR_NAME]), sizeof(fi->name) - 1); - fi->name[sizeof(fi->name) - 1] = 0; - fi->rx = nla_get_u64(tb[WPROBE_ATTR_RXCOUNT]); - fi->tx = nla_get_u64(tb[WPROBE_ATTR_TXCOUNT]); - } - data->cb(data->arg, name, data->buf, count); - - return 0; -} - -int -wprobe_dump_filters(struct wprobe_iface *dev, wprobe_filter_cb cb, void *arg) -{ - struct wprobe_filter_data data; - struct nl_msg *msg; - int err; - - data.buf = 0; - data.buflen = 0; - data.cb = cb; - data.arg = arg; - - msg = wprobe_new_msg(dev, WPROBE_CMD_GET_FILTER, true); - if (!msg) - return -ENOMEM; - - err = dev->ops->send_msg(dev, msg, dump_filter_handler, &data); - if (err < 0) - return err; - - return 0; -} - -int -wprobe_apply_config(struct wprobe_iface *dev) -{ - struct nl_msg *msg; - - msg = wprobe_new_msg(dev, WPROBE_CMD_CONFIG, false); - if (!msg) - return -ENOMEM; - - if (dev->interval >= 0) - NLA_PUT_MSECS(msg, WPROBE_ATTR_INTERVAL, dev->interval); - - if (dev->filter_len < 0) { - NLA_PUT(msg, WPROBE_ATTR_FILTER, 0, NULL); - dev->filter_len = 0; - } else if (dev->filter && dev->filter_len > 0) { - NLA_PUT(msg, WPROBE_ATTR_FILTER, dev->filter_len, dev->filter); - } - dev->filter = NULL; - - dev->ops->send_msg(dev, msg, NULL, NULL); - return 0; - -nla_put_failure: - nlmsg_free(msg); - return -ENOMEM; -} - -int -wprobe_measure(struct wprobe_iface *dev) -{ - struct nl_msg *msg; - - msg = wprobe_new_msg(dev, WPROBE_CMD_MEASURE, false); - if (!msg) - return -ENOMEM; - - dev->ops->send_msg(dev, msg, NULL, NULL); - return 0; -} - -struct wprobe_request_cb { - struct list_head *list; - struct list_head old_list; - char *addr; -}; - -static int -save_attrdata_handler(struct nl_msg *msg, void *arg) -{ - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - struct wprobe_request_cb *cb = arg; - struct wprobe_attribute *attr; - int type, id; - - nla_parse(tb, WPROBE_ATTR_LAST, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), attribute_policy); - - if (!tb[WPROBE_ATTR_ID]) - return -1; - - if (!tb[WPROBE_ATTR_TYPE]) - return -1; - - id = nla_get_u32(tb[WPROBE_ATTR_ID]); - list_for_each_entry(attr, &cb->old_list, list) { - if (attr->id == id) - goto found; - } - /* not found */ - return -1; - -found: - list_del_init(&attr->list); - - type = nla_get_u8(tb[WPROBE_ATTR_TYPE]); - if (type != attr->type) { - DPRINTF("WARNING: type mismatch for %s attribute '%s' (%d != %d)\n", - (cb->addr ? "link" : "global"), - attr->name, - type, attr->type); - goto out; - } - - if ((type < WPROBE_VAL_STRING) || - (type > WPROBE_VAL_U64)) - goto out; - - memset(&attr->val, 0, sizeof(attr->val)); - -#define HANDLE_INT_TYPE(_idx, _type) \ - case WPROBE_VAL_S##_type: \ - case WPROBE_VAL_U##_type: \ - attr->val.U##_type = nla_get_u##_type(tb[_idx]); \ - break - - switch(type) { - HANDLE_INT_TYPE(type, 8); - HANDLE_INT_TYPE(type, 16); - HANDLE_INT_TYPE(type, 32); - HANDLE_INT_TYPE(type, 64); - case WPROBE_VAL_STRING: - /* unimplemented */ - break; - } -#undef HANDLE_TYPE - - if (attr->flags & WPROBE_F_KEEPSTAT) { - if (tb[WPROBE_VAL_SUM]) - attr->val.s = nla_get_u64(tb[WPROBE_VAL_SUM]); - - if (tb[WPROBE_VAL_SUM_SQ]) - attr->val.ss = nla_get_u64(tb[WPROBE_VAL_SUM_SQ]); - - if (tb[WPROBE_VAL_SAMPLES]) - attr->val.n = nla_get_u32(tb[WPROBE_VAL_SAMPLES]); - - if (attr->val.n > 0) { - float avg = ((float) attr->val.s) / attr->val.n; - float stdev = sqrt((((float) attr->val.ss) / attr->val.n) - (avg * avg)); - if (isnan(stdev)) - stdev = 0.0f; - if (isnan(avg)) - avg = 0.0f; - attr->val.avg = avg; - attr->val.stdev = stdev; - } - } - -out: - list_add_tail(&attr->list, cb->list); - return 0; -} - - -int -wprobe_request_data(struct wprobe_iface *dev, const unsigned char *addr) -{ - struct wprobe_request_cb cb; - struct list_head *attrs; - struct nl_msg *msg; - int err; - - msg = wprobe_new_msg(dev, WPROBE_CMD_GET_INFO, true); - if (!msg) - return -ENOMEM; - - if (addr) { - attrs = &dev->link_attr; - NLA_PUT(msg, WPROBE_ATTR_MAC, 6, addr); - } else { - attrs = &dev->global_attr; - } - - INIT_LIST_HEAD(&cb.old_list); - list_splice_init(attrs, &cb.old_list); - cb.list = attrs; - - err = dev->ops->send_msg(dev, msg, save_attrdata_handler, &cb); - list_splice(&cb.old_list, attrs->prev); - return err; - -nla_put_failure: - nlmsg_free(msg); - return -ENOMEM; -} - - diff --git a/extra/wprobe/src/user/wprobe-util.c b/extra/wprobe/src/user/wprobe-util.c deleted file mode 100644 index 654442f9c..000000000 --- a/extra/wprobe/src/user/wprobe-util.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * wprobe-test.c: Wireless probe user space test code - * Copyright (C) 2008-2009 Felix Fietkau - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "wprobe.h" - -static bool simple_mode = false; - -static const char * -wprobe_dump_value(struct wprobe_attribute *attr) -{ - static char buf[128]; - -#define HANDLE_TYPE(_type, _format) \ - case WPROBE_VAL_##_type: \ - snprintf(buf, sizeof(buf), _format, attr->val._type); \ - break - - switch(attr->type) { - HANDLE_TYPE(S8, "%d"); - HANDLE_TYPE(S16, "%d"); - HANDLE_TYPE(S32, "%d"); - HANDLE_TYPE(S64, "%lld"); - HANDLE_TYPE(U8, "%d"); - HANDLE_TYPE(U16, "%d"); - HANDLE_TYPE(U32, "%d"); - HANDLE_TYPE(U64, "%lld"); - case WPROBE_VAL_STRING: - /* FIXME: implement this */ - default: - strncpy(buf, "", sizeof(buf)); - break; - } - if ((attr->flags & WPROBE_F_KEEPSTAT) && - (attr->val.n > 0)) { - int len = strlen(buf); - if (simple_mode) - snprintf(buf + len, sizeof(buf) - len, ";%.02f;%.02f;%d;%lld;%lld", attr->val.avg, attr->val.stdev, attr->val.n, attr->val.s, attr->val.ss); - else - snprintf(buf + len, sizeof(buf) - len, " (avg: %.02f; stdev: %.02f, n=%d)", attr->val.avg, attr->val.stdev, attr->val.n); - } -#undef HANDLE_TYPE - - return buf; -} - - -static void -wprobe_dump_data(struct wprobe_iface *dev) -{ - struct wprobe_attribute *attr; - struct wprobe_link *link; - bool first = true; - - if (!simple_mode) - fprintf(stdout, "\n"); - wprobe_request_data(dev, NULL); - list_for_each_entry(attr, &dev->global_attr, list) { - if (simple_mode) { - if (first) - fprintf(stdout, "[global]\n"); - fprintf(stdout, "%s=%s\n", attr->name, wprobe_dump_value(attr)); - } else { - fprintf(stdout, (first ? - "Global: %s=%s\n" : - " %s=%s\n"), - attr->name, - wprobe_dump_value(attr) - ); - } - first = false; - } - - list_for_each_entry(link, &dev->links, list) { - first = true; - wprobe_request_data(dev, link->addr); - list_for_each_entry(attr, &dev->link_attr, list) { - if (first) { - fprintf(stdout, - (simple_mode ? - "[%02x:%02x:%02x:%02x:%02x:%02x]\n%s=%s\n" : - "%02x:%02x:%02x:%02x:%02x:%02x: %s=%s\n"), - link->addr[0], link->addr[1], link->addr[2], - link->addr[3], link->addr[4], link->addr[5], - attr->name, - wprobe_dump_value(attr)); - first = false; - } else { - fprintf(stdout, - (simple_mode ? "%s=%s\n" : - " %s=%s\n"), - attr->name, - wprobe_dump_value(attr)); - } - } - } - fflush(stdout); -} - -static const char *attr_typestr[] = { - [0] = "Unknown", - [WPROBE_VAL_STRING] = "String", - [WPROBE_VAL_U8] = "Unsigned 8 bit", - [WPROBE_VAL_U16] = "Unsigned 16 bit", - [WPROBE_VAL_U32] = "Unsigned 32 bit", - [WPROBE_VAL_U64] = "Unsigned 64 bit", - [WPROBE_VAL_S8] = "Signed 8 bit", - [WPROBE_VAL_S16] = "Signed 16 bit", - [WPROBE_VAL_S32] = "Signed 32 bit", - [WPROBE_VAL_S64] = "Signed 64 bit", -}; - -static int usage(const char *prog) -{ - fprintf(stderr, -#ifndef NO_LOCAL_ACCESS - "Usage: %s |:|-P [options]\n" -#else - "Usage: %s : [options]\n" -#endif - "\n" - "Options:\n" - " -a: Print attributes\n" - " -c: Only apply configuration\n" - " -d: Delay between measurement dumps (in milliseconds, default: 1000)\n" - " A value of 0 (zero) prints once and exits; useful for scripts\n" - " -f: Dump contents of layer 2 filter counters during measurement\n" - " -F : Apply layer 2 filters from \n" - " -h: This help text\n" - " -i : Set measurement interval\n" - " -m: Run measurement loop\n" - " -p: Set the TCP port for server/client (default: 17990)\n" -#ifndef NO_LOCAL_ACCESS - " -P: Run in proxy mode (listen on network)\n" -#endif - "\n" - , prog); - exit(1); -} - -static void show_attributes(struct wprobe_iface *dev) -{ - struct wprobe_attribute *attr; - if (simple_mode) - return; - list_for_each_entry(attr, &dev->global_attr, list) { - fprintf(stdout, "Global attribute: '%s' (%s)\n", - attr->name, attr_typestr[attr->type]); - } - list_for_each_entry(attr, &dev->link_attr, list) { - fprintf(stdout, "Link attribute: '%s' (%s)\n", - attr->name, attr_typestr[attr->type]); - } -} - -static void show_filter_simple(void *arg, const char *group, struct wprobe_filter_item *items, int n_items) -{ - int i; - - fprintf(stdout, "[filter:%s]\n", group); - for (i = 0; i < n_items; i++) { - fprintf(stdout, "%s=%lld;%lld\n", - items[i].name, items[i].tx, items[i].rx); - } - fflush(stdout); -} - - -static void show_filter(void *arg, const char *group, struct wprobe_filter_item *items, int n_items) -{ - int i; - fprintf(stdout, "Filter group: '%s' (tx/rx)\n", group); - for (i = 0; i < n_items; i++) { - fprintf(stdout, " - %s (%lld/%lld)\n", - items[i].name, items[i].tx, items[i].rx); - } -} - -static void loop_measurement(struct wprobe_iface *dev, bool print_filters, unsigned long delay) -{ - do { - wprobe_update_links(dev); - wprobe_dump_data(dev); - if (print_filters) - wprobe_dump_filters(dev, simple_mode ? show_filter_simple : show_filter, NULL); - usleep(delay * 1000); - } - while (delay); -} - -static void set_filter(struct wprobe_iface *dev, const char *filename) -{ - unsigned char *buf = NULL; - unsigned int buflen = 0; - unsigned int len = 0; - int fd; - - /* clear filter */ - if (filename[0] == 0) { - dev->filter_len = -1; - return; - } - - fd = open(filename, O_RDONLY); - if (fd < 0) { - perror("open filter"); - return; - } - - do { - int rlen; - - if (!buf) { - len = 0; - buflen = 1024; - buf = malloc(1024); - } else { - buflen *= 2; - buf = realloc(buf, buflen); - } - rlen = read(fd, buf + len, buflen - len); - if (rlen < 0) - break; - - len += rlen; - } while (len == buflen); - - dev->filter = buf; - dev->filter_len = len; - close(fd); -} - -#ifndef NO_LOCAL_ACCESS - -static void sigchld_handler(int s) -{ - while (waitpid(-1, NULL, WNOHANG) > 0); -} - -static int run_proxy(int port) -{ - struct sockaddr_in sa; - struct sigaction sig; - int v = 1; - int s; - - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) { - perror("socket"); - return 1; - } - - sig.sa_handler = sigchld_handler; // Signal Handler fuer Zombie Prozesse - sigemptyset(&sig.sa_mask); - sig.sa_flags = SA_RESTART; - sigaction(SIGCHLD, &sig, NULL); - - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - sa.sin_addr.s_addr = htonl(INADDR_ANY); - sa.sin_port = htons(wprobe_port); - - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v)); - if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) { - perror("bind"); - return 1; - } - if (listen(s, 10)) { - perror("listen"); - return 1; - } - while(1) { - unsigned int addrlen = sizeof(struct sockaddr_in); - int ret, c; - - c = accept(s, (struct sockaddr *)&sa, &addrlen); - if (c < 0) { - if (errno == EINTR) - continue; - - perror("accept"); - return 1; - } - if (fork() == 0) { - /* close server socket, stdin, stdout, stderr */ - close(s); - close(0); - close(1); - close(2); - - wprobe_server_init(c); - do { - ret = wprobe_server_handle(c); - } while (ret >= 0); - wprobe_server_done(); - close(c); - exit(0); - } - close(c); - } - - return 0; -} -#endif - -int main(int argc, char **argv) -{ - struct wprobe_iface *dev = NULL; - const char *ifname; - const char *prog = argv[0]; - char *err = NULL; - enum { - CMD_NONE, - CMD_CONFIG, - CMD_MEASURE, - CMD_PROXY, - } cmd = CMD_NONE; - const char *filter = NULL; - bool print_attributes = false; - bool print_filters = false; - unsigned long delay = 1000; - int interval = -1; - int ch; - - if (argc < 2) - return usage(prog); - -#ifndef NO_LOCAL_ACCESS - if (!strcmp(argv[1], "-P")) { - while ((ch = getopt(argc - 1, argv + 1, "p:")) != -1) { - switch(ch) { - case 'p': - /* set port */ - wprobe_port = strtoul(optarg, NULL, 0); - break; - default: - return usage(prog); - } - } - return run_proxy(wprobe_port); - } -#endif - - if (argv[1][0] == '-') - return usage(prog); - - ifname = argv[1]; - argv++; - argc--; - - while ((ch = getopt(argc, argv, "acd:fF:hi:msp:")) != -1) { - switch(ch) { - case 'a': - print_attributes = true; - break; - case 'c': - cmd = CMD_CONFIG; - break; - case 'd': - delay = strtoul(optarg, NULL, 10); - break; - case 'm': - cmd = CMD_MEASURE; - break; - case 'i': - interval = strtoul(optarg, NULL, 10); - break; - case 'f': - print_filters = true; - break; - case 'F': - if (filter) { - fprintf(stderr, "Cannot set multiple filters\n"); - return usage(prog); - } - filter = optarg; - break; - case 's': - simple_mode = true; - break; - case 'p': - /* set port */ - wprobe_port = strtoul(optarg, NULL, 0); - break; - case 'h': - default: - usage(prog); - break; - } - } - - dev = wprobe_get_auto(ifname, &err); - if (!dev || (list_empty(&dev->global_attr) && - list_empty(&dev->link_attr))) { - if (err) - fprintf(stdout, "%s\n", err); - else - fprintf(stderr, "Interface '%s' not found\n", ifname); - return 1; - } - - if (filter || interval >= 0) { - if (filter) - set_filter(dev, filter); - if (interval >= 0) - dev->interval = interval; - - wprobe_apply_config(dev); - } - - if (cmd != CMD_CONFIG) { - if (print_attributes) - show_attributes(dev); - } - if (cmd == CMD_MEASURE) - loop_measurement(dev, print_filters, delay); - - wprobe_free_dev(dev); - - return 0; -} diff --git a/extra/wprobe/src/user/wprobe.h b/extra/wprobe/src/user/wprobe.h deleted file mode 100644 index 706facc80..000000000 --- a/extra/wprobe/src/user/wprobe.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * wprobe.h: Wireless probe user space library - * Copyright (C) 2008-2009 Felix Fietkau - * - * 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. - */ - -#ifndef __WPROBE_USER_H -#define __WPROBE_USER_H -#include -#include -#include -#include "list.h" - -/** - * struct wprobe_value: data structure for attribute values - * @STRING: string value (currently unsupported) - * @U8: unsigned 8-bit integer value - * @U16: unsigned 16-bit integer value - * @U32: unsigned 32-bit integer value - * @U64: unsigned 64-bit integer value - * @S8: signed 8-bit integer value - * @S16: signed 16-bit integer value - * @S32: signed 32-bit integer value - * @S64: signed 64-bit integer value - * - * @n: number of sample values - * @avg: average value - * @stdev: standard deviation - * @s: sum of all sample values (internal use) - * @ss: sum of all sample values squared (internal use) - */ -struct wprobe_value { - /* attribute value */ - union { - const char *STRING; - uint8_t U8; - uint16_t U16; - uint32_t U32; - uint64_t U64; - int8_t S8; - int16_t S16; - int32_t S32; - int64_t S64; - }; - /* statistics */ - int64_t s, ss; - float avg, stdev; - unsigned int n; -}; - -/** - * struct wprobe_attribute: data structures for attribute descriptions - * @list: linked list data structure for a list of attributes - * @id: attribute id - * @type: netlink type for the attribute (see kernel api documentation) - * @flags: attribute flags (see kernel api documentation) - * @val: cached version of the last netlink query, will be overwritten on each request - * @name: attribute name - */ -struct wprobe_attribute { - struct list_head list; - int id; - int type; - uint32_t flags; - struct wprobe_value val; - char name[]; -}; - -/** - * struct wprobe_link: data structure for the link description - * @list: linked list data structure for a list of links - * @flags: link flags (see kernel api documentation) - * @addr: mac address of the remote link partner - */ -struct wprobe_link { - struct list_head list; - uint32_t flags; - unsigned char addr[6]; -}; - -struct wprobe_filter_item { - char name[32]; - uint64_t rx; - uint64_t tx; -}; - -struct wprobe_iface_ops; -struct wprobe_iface { - const struct wprobe_iface_ops *ops; - - int sockfd; - const char *ifname; - unsigned int genl_family; - char addr[6]; - - struct list_head global_attr; - struct list_head link_attr; - struct list_head links; - - /* config */ - int interval; - int scale_min; - int scale_max; - int scale_m; - int scale_d; - - /* filter */ - void *filter; - - /* filter_len: - * set to -1 to drop the current filter - * automatically reset to 0 after config apply - */ - int filter_len; -}; - -typedef void (*wprobe_filter_cb)(void *arg, const char *group, struct wprobe_filter_item *items, int n_items); -extern int wprobe_port; - -/** - * wprobe_update_links: get a list of all link partners - * @dev: wprobe device structure - * @list: linked list for storing link descriptions - * - * when wprobe_update_links is called multiple times, the linked list - * is updated with new link partners, old entries are automatically expired - */ -extern int wprobe_update_links(struct wprobe_iface *dev); - -/** - * wprobe_dump_filters: dump all layer 2 filter counters - * @dev: wprobe device structure - * @cb: callback (called once per filter group) - * @arg: user argument for the callback - */ -extern int wprobe_dump_filters(struct wprobe_iface *dev, wprobe_filter_cb cb, void *arg); - -/** - * wprobe_measure: start a measurement request for all global attributes - * @dev: wprobe device structure - * - * not all attributes are automatically filled with data, since for some - * it may be desirable to control the sampling interval from user space - * you can use this function to do that. - */ -extern int wprobe_measure(struct wprobe_iface *dev); - -/** - * wprobe_get_dev: get a handle to a local wprobe device - * @ifname: name of the wprobe interface - * - * queries the wprobe interface for all attributes - * must be freed with wprobe_free_dev - */ -extern struct wprobe_iface *wprobe_get_dev(const char *ifname); - -/** - * wprobe_get_auto: get a handle to a local or remote wprobe device - * @arg: pointer to the wprobe device, either (local) or : (remote) - */ -extern struct wprobe_iface *wprobe_get_auto(const char *arg, char **err); - -/** - * wprobe_get_dev: free all device information - * @dev: wprobe device structure - */ -extern void wprobe_free_dev(struct wprobe_iface *dev); - -/** - * wprobe_apply_config: apply configuration data - * @dev: wprobe device structure - * - * uploads all configuration values from @dev that are not set to -1 - */ -extern int wprobe_apply_config(struct wprobe_iface *dev); - -/** - * wprobe_request_data: request new sampling values for the given list of attributes - * @dev: wprobe device structure - * @addr: (optional) mac address of the link partner - * - * if addr is unset, global values are stored in the global attributes list - * if addr is set, per-link values for the given address are stored in the link attributes list - */ -extern int wprobe_request_data(struct wprobe_iface *dev, const unsigned char *addr); - -/** - * wprobe_server_init: send a wprobe server init message to a server's client socket - * @socket: socket of the connection to the client - */ -extern int wprobe_server_init(int socket); - -/** - * wprobe_server_handle: read a request from the client socket, process it, send the response - * @socket: socket of the connection to the client - */ -extern int wprobe_server_handle(int socket); - -/** - * wprobe_server_done: release memory allocated for the server connection - */ -extern void wprobe_server_done(void); - -#endif