mirror of
https://github.com/hak5/wifipineapple-openwrt.git
synced 2025-10-29 16:57:19 +00:00
strip the kernel version suffix from target directories, except for brcm-2.4 (the -2.4 will be included in the board name here). CONFIG_LINUX_<ver>_<board> becomes CONFIG_TARGET_<board>, same for profiles.
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@8653 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
44
target/linux/etrax/Makefile
Normal file
44
target/linux/etrax/Makefile
Normal file
@@ -0,0 +1,44 @@
|
||||
#
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
ARCH:=cris
|
||||
BOARD:=etrax
|
||||
BOARDNAME:=Foxboard (ETRAX 100LX)
|
||||
FEATURES:=squashfs jffs2
|
||||
LINUX_VERSION:=2.6.19.2
|
||||
|
||||
include $(INCLUDE_DIR)/kernel-build.mk
|
||||
|
||||
define Target/Description
|
||||
Build fimware images for the FOXBOARD made by acmesystems.it
|
||||
endef
|
||||
|
||||
define Kernel/Prepare/Fox
|
||||
bzcat $(DL_DIR)/$(LINUX_SOURCE) | tar -C $(KERNEL_BUILD_DIR) $(TAR_OPTIONS)
|
||||
if [ -d ./files ]; then $(CP) ./files/* $(LINUX_DIR)/; fi
|
||||
if [ -d ./patches/generic_2.6 ]; then $(PATCH) $(LINUX_DIR) ./patches/generic_2.6; fi
|
||||
if [ -d ./patches/cris ]; then $(PATCH) $(LINUX_DIR) ./patches/cris; fi
|
||||
ln -sf $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/include/asm-cris/arch-v10 $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/include/asm-cris/arch
|
||||
ln -sf $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/arch/cris/arch-v10 $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/arch/cris/arch
|
||||
endef
|
||||
|
||||
define Kernel/Prepare
|
||||
$(call Kernel/Prepare/Fox)
|
||||
endef
|
||||
|
||||
DEFAULT_PACKAGES += foxboard-utils
|
||||
|
||||
$(eval $(call RequireCommand,/usr/local/cris/gcc-cris, \
|
||||
Please install the binary cris toolchain. \
|
||||
))
|
||||
|
||||
#include the profiles
|
||||
-include profiles/*.mk
|
||||
|
||||
KERNELNAME:="zImage"
|
||||
$(eval $(call BuildKernel))
|
||||
5
target/linux/etrax/base-files.mk
Normal file
5
target/linux/etrax/base-files.mk
Normal file
@@ -0,0 +1,5 @@
|
||||
define Package/base-files/install-target
|
||||
mkdir -p $(1)/root
|
||||
endef
|
||||
|
||||
|
||||
15
target/linux/etrax/base-files/default/etc/config/network
Normal file
15
target/linux/etrax/base-files/default/etc/config/network
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
|
||||
config interface loopback
|
||||
option ifname lo
|
||||
option proto static
|
||||
option ipaddr 127.0.0.1
|
||||
option netmask 255.0.0.0
|
||||
|
||||
config interface lan
|
||||
option ifname eth0
|
||||
option proto static
|
||||
option ipaddr 192.168.0.90
|
||||
option netmask 255.255.255.0
|
||||
#option dns 192.168.0.1
|
||||
#option gateway 192.168.0.1
|
||||
3
target/linux/etrax/base-files/default/etc/ipkg.conf
Normal file
3
target/linux/etrax/base-files/default/etc/ipkg.conf
Normal file
@@ -0,0 +1,3 @@
|
||||
src snapshots http://www.acmesystems.it/download/owrt/packages
|
||||
dest root /
|
||||
dest ram /tmp
|
||||
2
target/linux/etrax/base-files/default/etc/passwd
Normal file
2
target/linux/etrax/base-files/default/etc/passwd
Normal file
@@ -0,0 +1,2 @@
|
||||
root:$1$6upaSrHM$W/0IQ8kf7IYxCxEkJQ2D60:0:0:root:/root:/bin/ash
|
||||
nobody:*:65534:65534:nobody:/var:/bin/false
|
||||
237
target/linux/etrax/config/default
Normal file
237
target/linux/etrax/config/default
Normal file
@@ -0,0 +1,237 @@
|
||||
CONFIG_BASE_SMALL=0
|
||||
# CONFIG_BLK_DEV_INITRD is not set
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CRIS=y
|
||||
CONFIG_CRYPTO_ARC4=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
# CONFIG_ETRAX100LX is not set
|
||||
CONFIG_ETRAX100LX_V2=y
|
||||
# CONFIG_ETRAXFS is not set
|
||||
# CONFIG_ETRAXFS_SIM is not set
|
||||
CONFIG_ETRAX_ARCH_V10=y
|
||||
# CONFIG_ETRAX_ARCH_V32 is not set
|
||||
CONFIG_ETRAX_AXISFLASHMAP=y
|
||||
# CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE is not set
|
||||
CONFIG_ETRAX_CMDLINE="root=/dev/mtdblock1 rootfstype=squashfs,jffs2 init=/etc/preinit noinitrd console=ttyS0,115200"
|
||||
# CONFIG_ETRAX_CSP0_LEDS is not set
|
||||
# CONFIG_ETRAX_DEBUG_PORT0 is not set
|
||||
# CONFIG_ETRAX_DEBUG_PORT1 is not set
|
||||
# CONFIG_ETRAX_DEBUG_PORT2 is not set
|
||||
# CONFIG_ETRAX_DEBUG_PORT3 is not set
|
||||
CONFIG_ETRAX_DEBUG_PORT_NULL=y
|
||||
CONFIG_ETRAX_DEF_R_BUS_CONFIG=0x4
|
||||
# CONFIG_ETRAX_DEF_R_PORT_G_DIR is not set
|
||||
CONFIG_ETRAX_DEF_R_PORT_PA_DATA=0xf0
|
||||
CONFIG_ETRAX_DEF_R_PORT_PA_DIR=0x1c
|
||||
CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG=0x00
|
||||
CONFIG_ETRAX_DEF_R_PORT_PB_DATA=0x03
|
||||
CONFIG_ETRAX_DEF_R_PORT_PB_DIR=0xce
|
||||
CONFIG_ETRAX_DEF_R_SDRAM_CONFIG=0x09603737
|
||||
CONFIG_ETRAX_DEF_R_SDRAM_TIMING=0x80008002
|
||||
CONFIG_ETRAX_DEF_R_WAITSTATES=0x95f8
|
||||
CONFIG_ETRAX_DRAM_SIZE=32
|
||||
CONFIG_ETRAX_DRAM_VIRTUAL_BASE=c0000000
|
||||
CONFIG_ETRAX_DS1302=y
|
||||
CONFIG_ETRAX_DS1302_RSTBIT=2
|
||||
CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT=y
|
||||
CONFIG_ETRAX_DS1302_SCLBIT=1
|
||||
CONFIG_ETRAX_DS1302_SDABIT=0
|
||||
CONFIG_ETRAX_DS1302_TRICKLE_CHARGE=0
|
||||
CONFIG_ETRAX_ETHERNET=y
|
||||
CONFIG_ETRAX_FAST_TIMER=y
|
||||
CONFIG_ETRAX_FLASH1_SIZE=0
|
||||
CONFIG_ETRAX_FLASH_BUSWIDTH=2
|
||||
CONFIG_ETRAX_GPIO=y
|
||||
CONFIG_ETRAX_I2C=y
|
||||
CONFIG_ETRAX_I2C_CLK_PORT=1
|
||||
CONFIG_ETRAX_I2C_DATA_PORT=0
|
||||
# CONFIG_ETRAX_I2C_EEPROM is not set
|
||||
CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C=y
|
||||
# CONFIG_ETRAX_IDE is not set
|
||||
CONFIG_ETRAX_LED1G=2
|
||||
CONFIG_ETRAX_LED1R=2
|
||||
CONFIG_ETRAX_LED2G=3
|
||||
CONFIG_ETRAX_LED2R=3
|
||||
CONFIG_ETRAX_LED3G=2
|
||||
CONFIG_ETRAX_LED3R=2
|
||||
CONFIG_ETRAX_NANDFLASH_BUSWIDTH=1
|
||||
CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY=y
|
||||
# CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK is not set
|
||||
# CONFIG_ETRAX_NO_LEDS is not set
|
||||
# CONFIG_ETRAX_NO_PHY is not set
|
||||
CONFIG_ETRAX_PA_CHANGEABLE_BITS=0xFF
|
||||
CONFIG_ETRAX_PA_CHANGEABLE_DIR=0xFF
|
||||
CONFIG_ETRAX_PA_LEDS=y
|
||||
CONFIG_ETRAX_PB_CHANGEABLE_BITS=0xFF
|
||||
CONFIG_ETRAX_PB_CHANGEABLE_DIR=0xFF
|
||||
# CONFIG_ETRAX_PB_LEDS is not set
|
||||
# CONFIG_ETRAX_PCF8563 is not set
|
||||
CONFIG_ETRAX_PTABLE_SECTOR=0
|
||||
CONFIG_ETRAX_RESCUE_SER0=y
|
||||
# CONFIG_ETRAX_RESCUE_SER1 is not set
|
||||
# CONFIG_ETRAX_RESCUE_SER2 is not set
|
||||
# CONFIG_ETRAX_RESCUE_SER3 is not set
|
||||
# CONFIG_ETRAX_RS485 is not set
|
||||
CONFIG_ETRAX_RTC=y
|
||||
CONFIG_ETRAX_SDRAM=y
|
||||
CONFIG_ETRAX_SER0_CD_ON_PA_BIT=-1
|
||||
CONFIG_ETRAX_SER0_CD_ON_PB_BIT=-1
|
||||
CONFIG_ETRAX_SER0_DSR_ON_PA_BIT=-1
|
||||
CONFIG_ETRAX_SER0_DSR_ON_PB_BIT=-1
|
||||
CONFIG_ETRAX_SER0_DTR_ON_PA_BIT=-1
|
||||
CONFIG_ETRAX_SER0_DTR_ON_PB_BIT=-1
|
||||
# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED is not set
|
||||
CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE=y
|
||||
# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PA is not set
|
||||
# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB is not set
|
||||
CONFIG_ETRAX_SER0_RI_ON_PA_BIT=-1
|
||||
CONFIG_ETRAX_SER0_RI_ON_PB_BIT=-1
|
||||
CONFIG_ETRAX_SER2_CD_ON_PA_BIT=7
|
||||
CONFIG_ETRAX_SER2_CD_ON_PB_BIT=-1
|
||||
CONFIG_ETRAX_SER2_DSR_ON_PA_BIT=6
|
||||
CONFIG_ETRAX_SER2_DSR_ON_PB_BIT=-1
|
||||
CONFIG_ETRAX_SER2_DTR_ON_PA_BIT=4
|
||||
CONFIG_ETRAX_SER2_DTR_ON_PB_BIT=-1
|
||||
# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED is not set
|
||||
# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE is not set
|
||||
CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA=y
|
||||
# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PB is not set
|
||||
CONFIG_ETRAX_SER2_RI_ON_PA_BIT=5
|
||||
CONFIG_ETRAX_SER2_RI_ON_PB_BIT=-1
|
||||
CONFIG_ETRAX_SER3_CD_ON_PA_BIT=-1
|
||||
CONFIG_ETRAX_SER3_CD_ON_PB_BIT=-1
|
||||
CONFIG_ETRAX_SER3_DSR_ON_PA_BIT=-1
|
||||
CONFIG_ETRAX_SER3_DSR_ON_PB_BIT=-1
|
||||
CONFIG_ETRAX_SER3_DTR_ON_PA_BIT=-1
|
||||
CONFIG_ETRAX_SER3_DTR_ON_PB_BIT=-1
|
||||
# CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED is not set
|
||||
CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_NONE=y
|
||||
# CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_PA is not set
|
||||
# CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_PB is not set
|
||||
CONFIG_ETRAX_SER3_RI_ON_PA_BIT=-1
|
||||
CONFIG_ETRAX_SER3_RI_ON_PB_BIT=-1
|
||||
CONFIG_ETRAX_SERIAL=y
|
||||
# CONFIG_ETRAX_SERIAL_FAST_TIMER is not set
|
||||
# CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST is not set
|
||||
CONFIG_ETRAX_SERIAL_PORT0=y
|
||||
# CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT is not set
|
||||
# CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN is not set
|
||||
CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN=y
|
||||
CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT=y
|
||||
# CONFIG_ETRAX_SERIAL_PORT1 is not set
|
||||
CONFIG_ETRAX_SERIAL_PORT2=y
|
||||
CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT=y
|
||||
CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN=y
|
||||
# CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN is not set
|
||||
# CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT is not set
|
||||
CONFIG_ETRAX_SERIAL_PORT3=y
|
||||
CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT=y
|
||||
CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN=y
|
||||
# CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_IN is not set
|
||||
# CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_OUT is not set
|
||||
CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS=1
|
||||
# CONFIG_ETRAX_SOFT_SHUTDOWN is not set
|
||||
# CONFIG_ETRAX_SYNCHRONOUS_SERIAL is not set
|
||||
CONFIG_ETRAX_SYSFS_NODES=y
|
||||
CONFIG_ETRAX_USB_HOST=y
|
||||
CONFIG_ETRAX_USB_HOST_PORT1=y
|
||||
CONFIG_ETRAX_USB_HOST_PORT2=y
|
||||
# CONFIG_ETRAX_WATCHDOG is not set
|
||||
CONFIG_FAT_FS=y
|
||||
CONFIG_FS_POSIX_ACL=y
|
||||
CONFIG_GENERIC_FIND_NEXT_BIT=y
|
||||
CONFIG_GENERIC_IOMAP=y
|
||||
# CONFIG_GEN_RTC is not set
|
||||
# CONFIG_HOSTAP is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_IDE is not set
|
||||
CONFIG_IEEE80211=y
|
||||
# CONFIG_IEEE80211_CRYPT_CCMP is not set
|
||||
# CONFIG_IEEE80211_CRYPT_TKIP is not set
|
||||
CONFIG_IEEE80211_CRYPT_WEP=y
|
||||
CONFIG_IEEE80211_DEBUG=y
|
||||
CONFIG_IEEE80211_SOFTMAC=y
|
||||
CONFIG_IEEE80211_SOFTMAC_DEBUG=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IRQ_PER_CPU=y
|
||||
CONFIG_JFFS2_FS_DEBUG=0
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTDRAM_ABS_POS=0x0
|
||||
CONFIG_MTDRAM_ERASE_SIZE=128
|
||||
CONFIG_MTDRAM_TOTAL_SIZE=0
|
||||
# CONFIG_MTD_ABSENT is not set
|
||||
CONFIG_MTD_BLOCK=y
|
||||
# CONFIG_MTD_BLOCK2MTD is not set
|
||||
CONFIG_MTD_CFI=y
|
||||
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||
CONFIG_MTD_CFI_AMDSTD=y
|
||||
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
|
||||
# CONFIG_MTD_CFI_GEOMETRY is not set
|
||||
CONFIG_MTD_CFI_I1=y
|
||||
CONFIG_MTD_CFI_I2=y
|
||||
# CONFIG_MTD_CFI_I4 is not set
|
||||
# CONFIG_MTD_CFI_I8 is not set
|
||||
# CONFIG_MTD_CFI_INTELEXT is not set
|
||||
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
|
||||
CONFIG_MTD_CFI_NOSWAP=y
|
||||
# CONFIG_MTD_CFI_STAA is not set
|
||||
CONFIG_MTD_CFI_UTIL=y
|
||||
CONFIG_MTD_CHAR=y
|
||||
# CONFIG_MTD_CMDLINE_PARTS is not set
|
||||
CONFIG_MTD_COMPLEX_MAPPINGS=y
|
||||
CONFIG_MTD_CONCAT=y
|
||||
# CONFIG_MTD_DEBUG is not set
|
||||
# CONFIG_MTD_DOC2000 is not set
|
||||
# CONFIG_MTD_DOC2001 is not set
|
||||
# CONFIG_MTD_DOC2001PLUS is not set
|
||||
CONFIG_MTD_GEN_PROBE=y
|
||||
CONFIG_MTD_JEDECPROBE=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_1=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_2=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_4=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
|
||||
CONFIG_MTD_MTDRAM=y
|
||||
# CONFIG_MTD_OBSOLETE_CHIPS is not set
|
||||
# CONFIG_MTD_ONENAND is not set
|
||||
# CONFIG_MTD_OTP is not set
|
||||
CONFIG_MTD_PARTITIONS=y
|
||||
# CONFIG_MTD_PHRAM is not set
|
||||
# CONFIG_MTD_PHYSMAP is not set
|
||||
# CONFIG_MTD_PLATRAM is not set
|
||||
# CONFIG_MTD_RAM is not set
|
||||
# CONFIG_MTD_REDBOOT_PARTS is not set
|
||||
# CONFIG_MTD_ROM is not set
|
||||
# CONFIG_MTD_SLRAM is not set
|
||||
CONFIG_MTD_SPLIT_ROOTFS=y
|
||||
# CONFIG_NET_WIRELESS_RTNETLINK is not set
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
# CONFIG_OOM_REBOOT is not set
|
||||
# CONFIG_OVERRIDE_SCHED_STARVATION_LIMIT is not set
|
||||
# CONFIG_RTC is not set
|
||||
CONFIG_RWSEM_GENERIC_SPINLOCK=y
|
||||
CONFIG_SCSI=y
|
||||
# CONFIG_SERIAL_8250 is not set
|
||||
# CONFIG_SMP is not set
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
# CONFIG_SPARSEMEM_STATIC is not set
|
||||
# CONFIG_SVINTO_SIM is not set
|
||||
# CONFIG_SYSTEM_PROFILER is not set
|
||||
CONFIG_UID16=y
|
||||
# CONFIG_UNUSED_SYMBOLS is not set
|
||||
# CONFIG_UNWIND_INFO is not set
|
||||
CONFIG_USB=y
|
||||
# CONFIG_USBPCWATCHDOG is not set
|
||||
# CONFIG_USB_ARCH_HAS_EHCI is not set
|
||||
# CONFIG_USB_ARCH_HAS_HCD is not set
|
||||
# CONFIG_USB_ARCH_HAS_OHCI is not set
|
||||
# CONFIG_USB_SERIAL_IR is not set
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_ZD1201=y
|
||||
CONFIG_VFAT_FS=y
|
||||
# CONFIG_VLAN_8021Q is not set
|
||||
# CONFIG_ZD1211RW is not set
|
||||
0
target/linux/etrax/config/profile-vhdl_no_fb
Normal file
0
target/linux/etrax/config/profile-vhdl_no_fb
Normal file
@@ -0,0 +1,191 @@
|
||||
#include <linux/autoconf.h>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/gpio_syscalls.h>
|
||||
|
||||
#include <asm/etraxgpio.h>
|
||||
#include <asm/arch/svinto.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/arch/io_interface_mux.h>
|
||||
|
||||
#include <asm/unistd.h>
|
||||
|
||||
|
||||
extern int errno;
|
||||
|
||||
|
||||
asmlinkage void sys_gpiosetbits(unsigned char port, unsigned int bits){
|
||||
switch(port){
|
||||
case 'G':
|
||||
case 'g':
|
||||
*R_PORT_G_DATA = port_g_data_shadow |= bits;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
case 'a':
|
||||
*R_PORT_PA_DATA = port_pa_data_shadow |= bits;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
case 'b':
|
||||
*R_PORT_PB_DATA = port_pb_data_shadow |= bits;
|
||||
break;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
asmlinkage void sys_gpioclearbits(unsigned char port, unsigned int bits){
|
||||
switch(port){
|
||||
case 'G':
|
||||
case 'g':
|
||||
*R_PORT_G_DATA = port_g_data_shadow &= ~bits;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
case 'a':
|
||||
*R_PORT_PA_DATA = port_pa_data_shadow &= ~bits;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
case 'b':
|
||||
*R_PORT_PB_DATA = port_pb_data_shadow &= ~bits;
|
||||
break;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
asmlinkage void sys_gpiosetdir(unsigned char port, unsigned char dir, unsigned int bits){
|
||||
if((dir=='I' )||(dir=='i')){
|
||||
switch(port){
|
||||
case 'G':
|
||||
case 'g':
|
||||
if(bits & (1<<0)){
|
||||
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g0dir);
|
||||
};
|
||||
if((bits & 0x0000FF00)==0x0000FF00){
|
||||
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g8_15dir);
|
||||
};
|
||||
if((bits & 0x00FF0000)==0x00FF0000){
|
||||
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g16_23dir);
|
||||
};
|
||||
if(bits & (1<<24)){
|
||||
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g24dir);
|
||||
};
|
||||
*R_GEN_CONFIG = genconfig_shadow;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
case 'a':
|
||||
*R_PORT_PA_DIR = port_pa_dir_shadow &= ~(bits & 0xff);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
case 'b':
|
||||
*R_PORT_PB_DIR = port_pb_dir_shadow &= ~(bits & 0xff);
|
||||
break;
|
||||
};
|
||||
} else if((dir=='O' )||(dir=='o')){
|
||||
switch(port){
|
||||
case 'G':
|
||||
case 'g':
|
||||
if(bits & (1<<0)){
|
||||
genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g0dir);
|
||||
};
|
||||
if((bits & 0x0000FF00)==0x0000FF00){
|
||||
genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g8_15dir);
|
||||
};
|
||||
if((bits & 0x00FF0000)==0x00FF0000){
|
||||
genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g8_15dir);
|
||||
};
|
||||
if(bits & (1<<24)){
|
||||
genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g24dir);
|
||||
};
|
||||
*R_GEN_CONFIG = genconfig_shadow;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
case 'a':
|
||||
*R_PORT_PA_DIR = port_pa_dir_shadow |= (bits & 0xff);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
case 'b':
|
||||
*R_PORT_PB_DIR = port_pb_dir_shadow |= (bits & 0xff);
|
||||
break;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
asmlinkage void sys_gpiotogglebit(unsigned char port, unsigned int bits){
|
||||
switch(port){
|
||||
case 'G':
|
||||
case 'g':
|
||||
if(port_g_data_shadow & bits){
|
||||
*R_PORT_G_DATA = port_g_data_shadow &= ~bits;
|
||||
} else {
|
||||
*R_PORT_G_DATA = port_g_data_shadow |= bits;
|
||||
};
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
case 'a':
|
||||
if(*R_PORT_PA_DATA & bits){
|
||||
*R_PORT_PA_DATA = port_pa_data_shadow &= ~(bits & 0xff);
|
||||
} else {
|
||||
*R_PORT_PA_DATA = port_pa_data_shadow |= (bits & 0xff);
|
||||
};
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
case 'b':
|
||||
if(*R_PORT_PB_DATA & bits){
|
||||
*R_PORT_PB_DATA = port_pb_data_shadow &= ~(bits & 0xff);
|
||||
} else {
|
||||
*R_PORT_PB_DATA = port_pb_data_shadow |= (bits & 0xff);
|
||||
};
|
||||
break;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
asmlinkage unsigned int sys_gpiogetbits(unsigned char port, unsigned int bits){
|
||||
unsigned int data = 0;
|
||||
switch(port){
|
||||
case 'G':
|
||||
case 'g':
|
||||
data = *R_PORT_G_DATA;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
case 'a':
|
||||
data = *R_PORT_PA_DATA;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
case 'b':
|
||||
data = *R_PORT_PB_DATA;
|
||||
break;
|
||||
|
||||
};
|
||||
data &= bits;
|
||||
return data;
|
||||
};
|
||||
|
||||
|
||||
262
target/linux/etrax/files/drivers/spi/spi_crisv32_gpio.c
Normal file
262
target/linux/etrax/files/drivers/spi/spi_crisv32_gpio.c
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Simple bitbanged-GPIO SPI driver for ETRAX FS et al.
|
||||
*
|
||||
* Copyright (c) 2007 Axis Communications AB
|
||||
*
|
||||
* Author: Hans-Peter Nilsson, inspired by earlier work by
|
||||
* Andre Spanberg but mostly by copying large parts of
|
||||
* spi_s3c24xx_gpio.c, hence also:
|
||||
* Copyright (c) 2006 Ben Dooks
|
||||
* Copyright (c) 2006 Simtec Electronics
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spi_bitbang.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/board.h>
|
||||
|
||||
/* Our main driver state. */
|
||||
|
||||
struct crisv32_spi_hw_info {
|
||||
struct crisv32_iopin sclk;
|
||||
struct crisv32_iopin mosi;
|
||||
struct crisv32_iopin miso;
|
||||
struct crisv32_iopin cs;
|
||||
};
|
||||
|
||||
/*
|
||||
* The driver state hides behind the spi_bitbang state. We're
|
||||
* responsible for allocating that, so we can get a little something
|
||||
* for ourselves.
|
||||
*/
|
||||
|
||||
struct crisv32_spi_gpio_devdata {
|
||||
struct spi_bitbang bitbang;
|
||||
struct crisv32_spi_hw_info pins;
|
||||
};
|
||||
|
||||
/* Helper function getting the driver state from a spi_device. */
|
||||
|
||||
static inline struct crisv32_spi_hw_info *spidev_to_hw(struct spi_device *spi)
|
||||
{
|
||||
struct crisv32_spi_gpio_devdata *dd = spi_master_get_devdata(spi->master);
|
||||
return &dd->pins;
|
||||
}
|
||||
|
||||
/* The SPI-bitbang functions: see spi_bitbang.h at EXPAND_BITBANG_TXRX. */
|
||||
|
||||
static inline void setsck(struct spi_device *spi, int is_on)
|
||||
{
|
||||
crisv32_io_set(&spidev_to_hw(spi)->sclk, is_on != 0);
|
||||
}
|
||||
|
||||
static inline void setmosi(struct spi_device *spi, int is_on)
|
||||
{
|
||||
crisv32_io_set(&spidev_to_hw(spi)->mosi, is_on != 0);
|
||||
}
|
||||
|
||||
static inline u32 getmiso(struct spi_device *spi)
|
||||
{
|
||||
return crisv32_io_rd(&spidev_to_hw(spi)->miso) != 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
#define spidelay(x) ndelay(x)
|
||||
|
||||
#define EXPAND_BITBANG_TXRX
|
||||
#include <linux/spi/spi_bitbang.h>
|
||||
|
||||
/*
|
||||
* SPI-bitbang word transmit-functions for the four SPI modes,
|
||||
* dispatching to the inlined functions we just included.
|
||||
*/
|
||||
|
||||
static u32 crisv32_spi_gpio_txrx_mode0(struct spi_device *spi,
|
||||
unsigned nsecs, u32 word, u8 bits)
|
||||
{
|
||||
return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
|
||||
}
|
||||
|
||||
static u32 crisv32_spi_gpio_txrx_mode1(struct spi_device *spi,
|
||||
unsigned nsecs, u32 word, u8 bits)
|
||||
{
|
||||
return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
|
||||
}
|
||||
|
||||
static u32 crisv32_spi_gpio_txrx_mode2(struct spi_device *spi,
|
||||
unsigned nsecs, u32 word, u8 bits)
|
||||
{
|
||||
return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
|
||||
}
|
||||
|
||||
static u32 crisv32_spi_gpio_txrx_mode3(struct spi_device *spi,
|
||||
unsigned nsecs, u32 word, u8 bits)
|
||||
{
|
||||
return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
|
||||
}
|
||||
|
||||
/* SPI-bitbang chip-select function. */
|
||||
|
||||
static void crisv32_spi_gpio_chipselect(struct spi_device *spi, int value)
|
||||
{
|
||||
if (spi->mode & SPI_CS_HIGH)
|
||||
crisv32_io_set(&spidev_to_hw(spi)->cs,
|
||||
value == BITBANG_CS_ACTIVE ? 1 : 0);
|
||||
else
|
||||
crisv32_io_set(&spidev_to_hw(spi)->cs,
|
||||
value == BITBANG_CS_ACTIVE ? 0 : 1);
|
||||
}
|
||||
|
||||
/* Platform-device probe function. */
|
||||
|
||||
static int __devinit crisv32_spi_gpio_probe(struct platform_device *dev)
|
||||
{
|
||||
struct spi_master *master;
|
||||
struct crisv32_spi_gpio_devdata *dd;
|
||||
struct resource *res;
|
||||
struct crisv32_spi_gpio_controller_data *gc;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* We need to get the controller data as a hardware resource,
|
||||
* or else it wouldn't be available until *after* the
|
||||
* spi_bitbang_start call!
|
||||
*/
|
||||
res = platform_get_resource_byname(dev, 0, "controller_data_ptr");
|
||||
if (res == NULL) {
|
||||
dev_err(&dev->dev, "can't get controller_data resource\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
gc = (struct crisv32_spi_gpio_controller_data *) res->start;
|
||||
|
||||
master = spi_alloc_master(&dev->dev, sizeof *dd);
|
||||
if (master == NULL) {
|
||||
dev_err(&dev->dev, "failed to allocate spi master\n");
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
dd = spi_master_get_devdata(master);
|
||||
platform_set_drvdata(dev, dd);
|
||||
|
||||
/*
|
||||
* The device data asks for this driver, and holds the id
|
||||
* number, which must be unique among the same-type devices.
|
||||
* We use this as the number of this SPI bus.
|
||||
*/
|
||||
master->bus_num = dev->id;
|
||||
|
||||
/*
|
||||
* Allocate pins. Note that thus being allocated as GPIO, we
|
||||
* don't have to deconfigure them at the end or if something
|
||||
* fails.
|
||||
*/
|
||||
if ((ret = crisv32_io_get_name(&dd->pins.cs, gc->cs)) != 0
|
||||
|| (ret = crisv32_io_get_name(&dd->pins.miso, gc->miso)) != 0
|
||||
|| (ret = crisv32_io_get_name(&dd->pins.mosi, gc->mosi)) != 0
|
||||
|| (ret = crisv32_io_get_name(&dd->pins.sclk, gc->sclk)) != 0)
|
||||
goto err_no_pins;
|
||||
|
||||
/* Set directions of the SPI pins. */
|
||||
crisv32_io_set_dir(&dd->pins.cs, crisv32_io_dir_out);
|
||||
crisv32_io_set_dir(&dd->pins.sclk, crisv32_io_dir_out);
|
||||
crisv32_io_set_dir(&dd->pins.miso, crisv32_io_dir_in);
|
||||
crisv32_io_set_dir(&dd->pins.mosi, crisv32_io_dir_out);
|
||||
|
||||
/* Set state of the SPI pins. */
|
||||
dev_dbg(&dev->dev, "cs.port 0x%x, pin: %d\n"
|
||||
dd->pins.cs.port, dd->pins.cs.bit);
|
||||
|
||||
/*
|
||||
* Can't use crisv32_spi_gpio_chipselect(spi, 1) here; we
|
||||
* don't have a proper "spi" until after spi_bitbang_start.
|
||||
*/
|
||||
crisv32_io_set(&dd->pins.cs, 1);
|
||||
crisv32_io_set(&dd->pins.sclk, 0);
|
||||
crisv32_io_set(&dd->pins.mosi, 0);
|
||||
|
||||
/* Setup SPI bitbang adapter hooks. */
|
||||
dd->bitbang.master = spi_master_get(master);
|
||||
dd->bitbang.chipselect = crisv32_spi_gpio_chipselect;
|
||||
|
||||
dd->bitbang.txrx_word[SPI_MODE_0] = crisv32_spi_gpio_txrx_mode0;
|
||||
dd->bitbang.txrx_word[SPI_MODE_1] = crisv32_spi_gpio_txrx_mode1;
|
||||
dd->bitbang.txrx_word[SPI_MODE_2] = crisv32_spi_gpio_txrx_mode2;
|
||||
dd->bitbang.txrx_word[SPI_MODE_3] = crisv32_spi_gpio_txrx_mode3;
|
||||
|
||||
ret = spi_bitbang_start(&dd->bitbang);
|
||||
if (ret)
|
||||
goto err_no_bitbang;
|
||||
|
||||
printk (KERN_INFO "CRIS v32 SPI driver for GPIO"
|
||||
" (cs: %s, miso: %s, mosi: %s, sclk: %s)\n",
|
||||
gc->cs, gc->miso, gc->mosi, gc->sclk);
|
||||
|
||||
return 0;
|
||||
|
||||
err_no_bitbang:
|
||||
spi_master_put(dd->bitbang.master);
|
||||
err_no_pins:
|
||||
platform_set_drvdata(dev, NULL);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Platform-device remove-function. */
|
||||
|
||||
static int __devexit crisv32_spi_gpio_remove(struct platform_device *dev)
|
||||
{
|
||||
struct crisv32_spi_gpio_devdata *dd = platform_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = spi_bitbang_stop(&dd->bitbang);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
spi_master_put(dd->bitbang.master);
|
||||
platform_set_drvdata(dev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* For the time being, there's no suspend/resume support to care
|
||||
* about, so we let those handlers default to NULL.
|
||||
*/
|
||||
static struct platform_driver crisv32_spi_gpio_drv = {
|
||||
.probe = crisv32_spi_gpio_probe,
|
||||
.remove = __devexit_p(crisv32_spi_gpio_remove),
|
||||
.driver = {
|
||||
.name = "spi_crisv32_gpio",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
/* Module init function. */
|
||||
|
||||
static int __devinit crisv32_spi_gpio_init(void)
|
||||
{
|
||||
return platform_driver_register(&crisv32_spi_gpio_drv);
|
||||
}
|
||||
|
||||
/* Module exit function. */
|
||||
|
||||
static void __devexit crisv32_spi_gpio_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&crisv32_spi_gpio_drv);
|
||||
}
|
||||
|
||||
module_init(crisv32_spi_gpio_init);
|
||||
module_exit(crisv32_spi_gpio_exit);
|
||||
|
||||
MODULE_DESCRIPTION("CRIS v32 SPI-GPIO Driver");
|
||||
MODULE_AUTHOR("Hans-Peter Nilsson, <hp@axis.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
1566
target/linux/etrax/files/drivers/spi/spi_crisv32_sser.c
Normal file
1566
target/linux/etrax/files/drivers/spi/spi_crisv32_sser.c
Normal file
File diff suppressed because it is too large
Load Diff
141
target/linux/etrax/files/drivers/usb/host/hc-cris-dbg.h
Normal file
141
target/linux/etrax/files/drivers/usb/host/hc-cris-dbg.h
Normal file
@@ -0,0 +1,141 @@
|
||||
|
||||
/* macros for debug output */
|
||||
|
||||
#define hcd_dbg(hcd, fmt, args...) \
|
||||
dev_info(hcd->self.controller, fmt, ## args)
|
||||
#define hcd_err(hcd, fmt, args...) \
|
||||
dev_err(hcd->self.controller, fmt, ## args)
|
||||
#define hcd_info(hcd, fmt, args...) \
|
||||
dev_info(hcd->self.controller, fmt, ## args)
|
||||
#define hcd_warn(hcd, fmt, args...) \
|
||||
dev_warn(hcd->self.controller, fmt, ## args)
|
||||
|
||||
/*
|
||||
#define devdrv_dbg(fmt, args...) \
|
||||
printk(KERN_INFO "usb_devdrv dbg: ");printk(fmt, ## args)
|
||||
*/
|
||||
#define devdrv_dbg(fmt, args...) {}
|
||||
|
||||
#define devdrv_err(fmt, args...) \
|
||||
printk(KERN_ERR "usb_devdrv error: ");printk(fmt, ## args)
|
||||
#define devdrv_info(fmt, args...) \
|
||||
printk(KERN_INFO "usb_devdrv: ");printk(fmt, ## args)
|
||||
|
||||
#define irq_dbg(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_irq dbg: ");printk(fmt, ## args)
|
||||
#define irq_err(fmt, args...) \
|
||||
printk(KERN_ERR "crisv10_irq error: ");printk(fmt, ## args)
|
||||
#define irq_warn(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_irq warn: ");printk(fmt, ## args)
|
||||
#define irq_info(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_hcd: ");printk(fmt, ## args)
|
||||
|
||||
/*
|
||||
#define rh_dbg(fmt, args...) \
|
||||
printk(KERN_DEBUG "crisv10_rh dbg: ");printk(fmt, ## args)
|
||||
*/
|
||||
#define rh_dbg(fmt, args...) {}
|
||||
|
||||
#define rh_err(fmt, args...) \
|
||||
printk(KERN_ERR "crisv10_rh error: ");printk(fmt, ## args)
|
||||
#define rh_warn(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_rh warning: ");printk(fmt, ## args)
|
||||
#define rh_info(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_rh: ");printk(fmt, ## args)
|
||||
|
||||
/*
|
||||
#define tc_dbg(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_tc dbg: ");printk(fmt, ## args)
|
||||
*/
|
||||
#define tc_dbg(fmt, args...) {while(0){}}
|
||||
|
||||
#define tc_err(fmt, args...) \
|
||||
printk(KERN_ERR "crisv10_tc error: ");printk(fmt, ## args)
|
||||
/*
|
||||
#define tc_warn(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_tc warning: ");printk(fmt, ## args)
|
||||
*/
|
||||
#define tc_warn(fmt, args...) {while(0){}}
|
||||
|
||||
#define tc_info(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_tc: ");printk(fmt, ## args)
|
||||
|
||||
|
||||
/* Debug print-outs for various traffic types */
|
||||
|
||||
#define intr_warn(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_intr warning: ");printk(fmt, ## args)
|
||||
/*
|
||||
#define intr_dbg(fmt, args...) \
|
||||
printk(KERN_DEBUG "crisv10_intr dbg: ");printk(fmt, ## args)
|
||||
*/
|
||||
#define intr_dbg(fmt, args...) {while(0){}}
|
||||
|
||||
|
||||
#define isoc_err(fmt, args...) \
|
||||
printk(KERN_ERR "crisv10_isoc error: ");printk(fmt, ## args)
|
||||
/*
|
||||
#define isoc_warn(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_isoc warning: ");printk(fmt, ## args)
|
||||
*/
|
||||
#define isoc_warn(fmt, args...) {while(0){}}
|
||||
|
||||
/*
|
||||
#define isoc_dbg(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_isoc dbg: ");printk(fmt, ## args)
|
||||
*/
|
||||
#define isoc_dbg(fmt, args...) {while(0){}}
|
||||
|
||||
/*
|
||||
#define timer_warn(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_timer warning: ");printk(fmt, ## args)
|
||||
*/
|
||||
#define timer_warn(fmt, args...) {while(0){}}
|
||||
|
||||
/*
|
||||
#define timer_dbg(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_timer dbg: ");printk(fmt, ## args)
|
||||
*/
|
||||
#define timer_dbg(fmt, args...) {while(0){}}
|
||||
|
||||
|
||||
/* Debug printouts for events related to late finishing of URBs */
|
||||
/*
|
||||
#define late_dbg(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_late dbg: ");printk(fmt, ## args)
|
||||
*/
|
||||
#define late_dbg(fmt, args...) {while(0){}}
|
||||
|
||||
#define late_warn(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_late warning: ");printk(fmt, ## args)
|
||||
/*
|
||||
#define errno_dbg(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_errno dbg: ");printk(fmt, ## args)
|
||||
*/
|
||||
#define errno_dbg(fmt, args...) {while(0){}}
|
||||
|
||||
|
||||
#define dma_dbg(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_dma dbg: ");printk(fmt, ## args)
|
||||
#define dma_err(fmt, args...) \
|
||||
printk(KERN_ERR "crisv10_dma error: ");printk(fmt, ## args)
|
||||
#define dma_warn(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_dma warning: ");printk(fmt, ## args)
|
||||
#define dma_info(fmt, args...) \
|
||||
printk(KERN_INFO "crisv10_dma: ");printk(fmt, ## args)
|
||||
|
||||
|
||||
|
||||
#define str_dir(pipe) \
|
||||
(usb_pipeout(pipe) ? "out" : "in")
|
||||
#define str_type(pipe) \
|
||||
({ \
|
||||
char *s = "?"; \
|
||||
switch (usb_pipetype(pipe)) { \
|
||||
case PIPE_ISOCHRONOUS: s = "iso"; break; \
|
||||
case PIPE_INTERRUPT: s = "intr"; break; \
|
||||
case PIPE_CONTROL: s = "ctrl"; break; \
|
||||
case PIPE_BULK: s = "bulk"; break; \
|
||||
}; \
|
||||
s; \
|
||||
})
|
||||
10
target/linux/etrax/files/include/linux/mtd/mtdram.h
Normal file
10
target/linux/etrax/files/include/linux/mtd/mtdram.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef __MTD_MTDRAM_H__
|
||||
#define __MTD_MTDRAM_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/mtd/mtd.h>
|
||||
int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
|
||||
unsigned long size, char *name);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __MTD_MTDRAM_H__ */
|
||||
5
target/linux/etrax/image/Config.in
Normal file
5
target/linux/etrax/image/Config.in
Normal file
@@ -0,0 +1,5 @@
|
||||
config AXIS_FIMAGE
|
||||
bool "Build fimage"
|
||||
depends LINUX_2_6_ETRAX
|
||||
default y
|
||||
|
||||
55
target/linux/etrax/image/Makefile
Normal file
55
target/linux/etrax/image/Makefile
Normal file
@@ -0,0 +1,55 @@
|
||||
#
|
||||
# Copyright (C) 2006 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)/image.mk
|
||||
|
||||
FOXBOARD:=custom MCM 416 816 832
|
||||
FOXBOARD_4MB:=MCM 416
|
||||
FOXBOARD_8MB:=custom 816 832
|
||||
|
||||
define Image/BuildKernel
|
||||
for f in $(FOXBOARD); do \
|
||||
cp $(KDIR)/vmlinuz_$$$$f $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-zImage_$$$$f; \
|
||||
done
|
||||
endef
|
||||
|
||||
define Image/Prepare
|
||||
for f in $(FOXBOARD); do \
|
||||
cp $(LINUX_DIR)/arch/cris/boot/zImage_$$$$f $(KDIR)/vmlinuz_$$$$f; \
|
||||
done
|
||||
$(MAKE) -C e100boot compile
|
||||
$(MAKE) -C mkfimage compile
|
||||
$(INSTALL_BIN) ./boot_linux $(BIN_DIR)
|
||||
endef
|
||||
|
||||
define Image/Build/generic
|
||||
for f in $(2); do \
|
||||
mkfimage $(KDIR)/vmlinuz_$$$$f $(KDIR)/vmlinuz_$$$$f.tmp ; \
|
||||
cat $(KDIR)/vmlinuz_$$$$f.tmp $(KDIR)/root.$(1) > $(KDIR)/fimage.$(1)_$$$$f.tmp; \
|
||||
dd if=$(KDIR)/fimage.$(1)_$$$$f.tmp of=$(KDIR)/fimage.$(1)_$$$$f bs=$(3) conv=sync; \
|
||||
cp $(KDIR)/fimage.$(1)_$$$$f $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1)-fimage_$$$$f; \
|
||||
done
|
||||
endef
|
||||
|
||||
define Image/Build/jffs2-64k
|
||||
$(call prepare_generic_jffs-64k,$(KDIR)/root.jff2-64k)
|
||||
$(call Image/Build/generic,$(1),$(FOXBOARD_4MB),4194304)
|
||||
$(call Image/Build/generic,$(1),$(FOXBOARD_8MB),8388608)
|
||||
endef
|
||||
|
||||
define Image/Build/squashfs
|
||||
$(call prepare_generic_squashfs,$(KDIR)/root.squashfs)
|
||||
$(call Image/Build/generic,$(1),$(FOXBOARD_4MB),4194304)
|
||||
$(call Image/Build/generic,$(1),$(FOXBOARD_8MB),8388608)
|
||||
endef
|
||||
|
||||
define Image/Build
|
||||
$(call Image/Build/$(1),$(1))
|
||||
endef
|
||||
|
||||
$(eval $(call BuildImage))
|
||||
512
target/linux/etrax/image/boot_linux
Executable file
512
target/linux/etrax/image/boot_linux
Executable file
@@ -0,0 +1,512 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#*****************************************************************************
|
||||
#!
|
||||
#! FILE NAME : boot_linux
|
||||
#!
|
||||
#! PARAMETERS : -b <bootimage> the name of the boot image to use
|
||||
#! -d <device> the interface to use, e.g., eth1
|
||||
#! (defaults is eth0)
|
||||
#! -f save it in flash memory at address 0x10000
|
||||
#! -F save it in flash memory at address 0
|
||||
#! -h show some help
|
||||
#! -i <image> name of the image to use (default is fimage)
|
||||
#! -o <offset> the offset in the flash where the flashing
|
||||
#! starts
|
||||
#! -O <offset> the offset in the image file where the
|
||||
#! flashing starts from
|
||||
#! -p print the resulting etrax100boot command
|
||||
#! instead of executing it
|
||||
#! -s <size> how much to flash (default is the size of
|
||||
#! the flash minus the offset specified using
|
||||
#! -o or -f)
|
||||
#! -S <size> the size of the flash
|
||||
#!
|
||||
#! All sizes and offsets above can be specified as decimal
|
||||
#! numbers, or as hexadecimal numbers by prefixing them with 0x.
|
||||
#! It is also possible to use the suffixes k and M to specify
|
||||
#! kilo (1024) or mega (1048576).
|
||||
#!
|
||||
#! DESCRIPTION: Extract the start of the image and any registers that should
|
||||
#! be set from the kimage or fimage file, and then boot it.
|
||||
#!
|
||||
#! FUNCTIONS : convert_size
|
||||
#! extract_hw_settings
|
||||
#! get_dword
|
||||
#! calculate_sdram_init
|
||||
#! sdram_command
|
||||
#! print_help
|
||||
#!
|
||||
#!----------------------------------------------------------------------------
|
||||
#! HISTORY
|
||||
#!
|
||||
#! $Log: boot_linux,v $
|
||||
#! Revision 1.16 2004/11/01 16:32:27 starvik
|
||||
#! Corrected help text to avoid confusion
|
||||
#!
|
||||
#! Revision 1.15 2003/01/29 11:48:57 pkj
|
||||
#! Calculate a flash size large enough for the given image if the
|
||||
#! -S option is not specified.
|
||||
#!
|
||||
#! Revision 1.14 2002/11/18 14:40:09 pkj
|
||||
#! Make use of the --loop option to etrax100boot when initialising
|
||||
#! SDRAM memories. This requires a lot fewer options to be passed
|
||||
#! to the boot loader.
|
||||
#!
|
||||
#! Revision 1.13 2002/08/15 16:29:02 pkj
|
||||
#! * The -S option now accepts the size in bytes (just like the -s option).
|
||||
#! For backwards compatibility it still assumes sizes of 16 and less to
|
||||
#! be specified in MB.
|
||||
#! * The suffixes k and M can now be used with all sizes and offsets to
|
||||
#! specify them in kilo or mega.
|
||||
#!
|
||||
#! Revision 1.12 2002/08/15 15:27:34 pkj
|
||||
#! Use $opts{'x'} instead of $opt_x.
|
||||
#!
|
||||
#! Revision 1.11 2002/07/04 17:06:39 pkj
|
||||
#! * No longer specifies a bootfile by default (not needed any longer).
|
||||
#! * Implemented option -b to specify a bootfile.
|
||||
#! * Removed references to option -l (it was never implemented).
|
||||
#!
|
||||
#! Revision 1.10 2002/06/04 11:50:23 starvik
|
||||
#! Check if mrs_data is specified in kernelconfig (necessary for MCM)
|
||||
#!
|
||||
#! Revision 1.9 2002/01/29 10:38:26 pkj
|
||||
#! Change illegal to invalid.
|
||||
#!
|
||||
#! Revision 1.8 2001/09/13 12:32:10 pkj
|
||||
#! * Added option -S to specify the size of the flash (in MB), as -s
|
||||
#! is used to specify how much to flash nowadays.
|
||||
#! * Made the default size of the flash depend on the size of the image
|
||||
#! file. If it is bigger than 0x200100 then the flash is assumed to
|
||||
#! be 4 MB, otherwise it is assumed to be 2 MB.
|
||||
#! * Added verification of various options.
|
||||
#!
|
||||
#! Revision 1.7 2001/09/13 10:25:11 pkj
|
||||
#! Minor clean-up.
|
||||
#!
|
||||
#! Revision 1.6 2001/06/29 10:05:16 pkj
|
||||
#! Corrected check for SDRAM.
|
||||
#!
|
||||
#! Revision 1.5 2001/06/29 09:11:55 pkj
|
||||
#! Synchronised boot_elinux and boot_linux.
|
||||
#!
|
||||
#!----------------------------------------------------------------------------
|
||||
#! (C) Copyright 2001, Axis Communications AB, LUND, SWEDEN
|
||||
#!****************************************************************************
|
||||
# $Id: boot_linux,v 1.16 2004/11/01 16:32:27 starvik Exp $
|
||||
|
||||
#****************** INCLUDE FILES SECTION ************************************
|
||||
|
||||
use strict;
|
||||
|
||||
use Getopt::Std;
|
||||
use File::Basename;
|
||||
|
||||
#****************** VARIABLE DECLARATION SECTION *****************************
|
||||
|
||||
use vars qw($my_name %opts);
|
||||
use vars qw($text_start $cmd);
|
||||
use vars qw($image_name $image_size);
|
||||
use vars qw($offset $source_offset $flash_size $flashing_size);
|
||||
use vars qw($sdram_timing_address $sdram_config_address);
|
||||
use vars qw($sdram_precharge $sdram_nop $sdram_refresh $sdram_mrs);
|
||||
|
||||
#****************** CONSTANT SECTION *****************************************
|
||||
|
||||
# Register addresses
|
||||
$sdram_timing_address = "b0000008";
|
||||
$sdram_config_address = "b000000c";
|
||||
|
||||
# SDRAM commands
|
||||
$sdram_precharge = 3;
|
||||
$sdram_nop = 0;
|
||||
$sdram_refresh = 2;
|
||||
$sdram_mrs = 1;
|
||||
|
||||
#****************** MAIN PROGRAM SECTION *************************************
|
||||
|
||||
# The name of this program.
|
||||
$my_name = basename($0);
|
||||
|
||||
# Get options
|
||||
getopts('b:d:fFhi:o:O:ps:S:', \%opts);
|
||||
|
||||
&print_help if ($opts{'h'});
|
||||
|
||||
# Name and existance of the image
|
||||
$image_name = ($opts{'i'} ? $opts{'i'} : 'fimage');
|
||||
die "Could not find the image $image_name!\n" unless (-s $image_name);
|
||||
|
||||
if ($opts{'f'} || $opts{'F'})
|
||||
{
|
||||
$image_size = -s $image_name;
|
||||
|
||||
$offset = ($opts{'f'} ? 0x10000 : 0);
|
||||
|
||||
$offset = &convert_size($opts{'o'}) if (defined($opts{'o'}));
|
||||
|
||||
die("$my_name: Invalid destination offset\n") if ($offset !~ /^\d+$/);
|
||||
|
||||
my $base_name = basename($image_name);
|
||||
if ($base_name eq 'timage' || $base_name eq 'flash1.img')
|
||||
{
|
||||
$source_offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$source_offset = $offset;
|
||||
}
|
||||
|
||||
$source_offset = &convert_size($opts{'O'}) if (defined($opts{'O'}));
|
||||
|
||||
die("$my_name: Invalid source offset\n") if ($source_offset !~ /^\d+$/);
|
||||
die("$my_name: Source offset > image size\n") if ($source_offset > $image_size);
|
||||
|
||||
if (defined($opts{'S'}))
|
||||
{
|
||||
# Backwards compatibility to allow specifying the flash size in MB
|
||||
# without using an M suffix
|
||||
$opts{'S'} .= 'M' if ($opts{'S'} =~ /^\d+$/ && $opts{'S'} <= 16);
|
||||
|
||||
$flash_size = &convert_size($opts{'S'});
|
||||
}
|
||||
else
|
||||
{
|
||||
# Calculate a flash size large enough for the image without the checksum
|
||||
# and HWID.
|
||||
$flash_size = ($image_size - $source_offset + $offset) & 0xFFFF0000;
|
||||
}
|
||||
|
||||
die("$my_name: Invalid flash size\n") if ($flash_size !~ /^\d+$/);
|
||||
die("$my_name: Destination offset > flash size\n") if ($offset > $flash_size);
|
||||
if (defined($opts{'s'}))
|
||||
{
|
||||
$flashing_size = &convert_size($opts{'s'});
|
||||
}
|
||||
else
|
||||
{
|
||||
$flashing_size = $flash_size - $offset;
|
||||
}
|
||||
|
||||
die("$my_name: Invalid size to flash\n") if ($flashing_size !~ /^\d+$/);
|
||||
|
||||
if ($flashing_size > $flash_size - $offset)
|
||||
{
|
||||
$flashing_size = $flash_size - $offset;
|
||||
printf("Warning: Flashing size limited to 0x%lx due to the offset (0x%lx) and flash size (0x%lx).\n", $flashing_size, $offset, $flash_size);
|
||||
}
|
||||
|
||||
if ($flashing_size > $image_size - $source_offset)
|
||||
{
|
||||
$flashing_size = $image_size - $source_offset;
|
||||
printf("Warning: Flashing size limited to 0x%lx due to the offset (0x%lx) and image size (0x%lx).\n", $flashing_size, $source_offset, $image_size);
|
||||
}
|
||||
}
|
||||
|
||||
# Create the command line to boot the image
|
||||
if (system('./etrax100boot --help > /dev/null') == 0)
|
||||
{
|
||||
$cmd = './etrax100boot';
|
||||
}
|
||||
elsif (system('svinto_boot --help > /dev/null') == 0)
|
||||
{
|
||||
$cmd = 'svinto_boot';
|
||||
}
|
||||
else
|
||||
{
|
||||
die("Cannot find e100boot program in your PATH!\n");
|
||||
}
|
||||
|
||||
$cmd .= " --device $opts{'d'}" if ($opts{'d'});
|
||||
|
||||
$cmd .= &extract_hw_settings;
|
||||
|
||||
$cmd .= " --bootfile $opts{'b'}" if ($opts{'b'});
|
||||
$cmd .= " --file $image_name $text_start";
|
||||
|
||||
if ($opts{'f'} || $opts{'F'})
|
||||
{
|
||||
$cmd .= sprintf(" --flash %lx %lx %lx --jump 0",
|
||||
hex($text_start) + $source_offset, $offset, $flashing_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
$cmd .= " --jump $text_start";
|
||||
}
|
||||
|
||||
if ($opts{'p'})
|
||||
{
|
||||
print "Command:\n$cmd\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
system($cmd);
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
#****************** FUNCTION DEFINITION SECTION ******************************
|
||||
|
||||
#*****************************************************************************
|
||||
##
|
||||
## FUNCTION NAME: convert_size
|
||||
##
|
||||
##****************************************************************************
|
||||
|
||||
sub convert_size
|
||||
{
|
||||
my($arg) = @_;
|
||||
my $size;
|
||||
|
||||
if ($arg =~ /^0x([\da-fA-F]+)([kM])?$/)
|
||||
{
|
||||
$size = hex($1);
|
||||
}
|
||||
elsif ($arg =~ /^(\d+)([kM])?$/)
|
||||
{
|
||||
$size = $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!defined($2))
|
||||
{
|
||||
return $size;
|
||||
}
|
||||
elsif ($2 eq 'k')
|
||||
{
|
||||
return $size * 1024;
|
||||
}
|
||||
elsif ($2 eq 'M')
|
||||
{
|
||||
return $size * 1048576;
|
||||
}
|
||||
}
|
||||
|
||||
#*****************************************************************************
|
||||
##
|
||||
## FUNCTION NAME: extract_hw_settings
|
||||
##
|
||||
##****************************************************************************
|
||||
|
||||
sub extract_hw_settings
|
||||
{
|
||||
my $data;
|
||||
my $dbg_port;
|
||||
my $sdram_enabled;
|
||||
my $return_value = "";
|
||||
my $sdram_config;
|
||||
|
||||
# The hw information table has the following format
|
||||
#
|
||||
# "HW_PARAM_MAGIC"
|
||||
# text_start (dword)
|
||||
# serial debg port (dword)
|
||||
# sdram enabled (dword)
|
||||
# register address (dword)
|
||||
# register value (dword)
|
||||
# ...
|
||||
# 0
|
||||
|
||||
open(FILE, "$image_name") || die("Could not open '$image_name'");
|
||||
|
||||
while (<FILE>)
|
||||
{
|
||||
if (m/HW_PARAM_MAGIC/g)
|
||||
{
|
||||
# Seek to first byte after magic
|
||||
seek(FILE, -length($_) + pos($_), 1);
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
$text_start = &get_dword;
|
||||
$dbg_port = &get_dword;
|
||||
$sdram_enabled = int(&get_dword);
|
||||
|
||||
while (1)
|
||||
{
|
||||
my $register = &get_dword;
|
||||
my $value = &get_dword;
|
||||
|
||||
last if ($register eq "00000000");
|
||||
|
||||
if ($sdram_enabled)
|
||||
{
|
||||
if ($register eq $sdram_config_address)
|
||||
{
|
||||
$sdram_config = $value;
|
||||
}
|
||||
elsif ($register eq $sdram_timing_address)
|
||||
{
|
||||
$return_value .= &calculate_sdram_init($value, $sdram_config);
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
$return_value .= " --setreg $register $value";
|
||||
}
|
||||
|
||||
close(FILE);
|
||||
|
||||
return $return_value;
|
||||
}
|
||||
|
||||
#*****************************************************************************
|
||||
##
|
||||
## FUNCTION NAME: get_dword
|
||||
##
|
||||
##****************************************************************************
|
||||
|
||||
sub get_dword
|
||||
{
|
||||
my $data;
|
||||
|
||||
read(FILE, $data, 4);
|
||||
return unpack("H8", pack("V", unpack("N", $data)));
|
||||
}
|
||||
|
||||
#*****************************************************************************
|
||||
##
|
||||
## FUNCTION NAME: calculate_sdram_init
|
||||
##
|
||||
##****************************************************************************
|
||||
|
||||
sub calculate_sdram_init
|
||||
{
|
||||
# Refer to ETRAX 100LX Designers Reference for a description of SDRAM
|
||||
# initialization
|
||||
my $sdram_init_val = hex($_[0]);
|
||||
my $sdram_config_val = hex($_[1]);
|
||||
my $bus_width = $sdram_config_val & 0x00800000;
|
||||
my $speed;
|
||||
my $cas_latency;
|
||||
my $mrs_data;
|
||||
my $temp;
|
||||
my $return_value;
|
||||
my $value;
|
||||
|
||||
$mrs_data = ($sdram_init_val & 0x00ff0000) >> 16;
|
||||
$sdram_init_val &= 0x8000ffff; # Make sure mrs data is 0
|
||||
$sdram_init_val |= 0x80000000; # Make sure sdram is enabled
|
||||
$speed = $sdram_init_val & 0x1000;
|
||||
$cas_latency = $sdram_init_val & 0x3;
|
||||
if ($speed) # 100 MHz
|
||||
{
|
||||
$cas_latency += 2;
|
||||
}
|
||||
else # 50 MHz
|
||||
{
|
||||
$cas_latency += 1;
|
||||
}
|
||||
|
||||
# Calculate value of mrs_data
|
||||
# CAS latency = 2 && bus_width = 32 => 0x40
|
||||
# CAS latency = 3 && bus_width = 32 => 0x60
|
||||
# CAS latency = 2 && bus_width = 16 => 0x20
|
||||
# CAS latency = 3 && bus_width = 16 => 0x30
|
||||
if ($mrs_data == 0)
|
||||
{
|
||||
if ($bus_width == 0) # 16 bits
|
||||
{
|
||||
$mrs_data = $cas_latency == 2 ? 0x20 : 0x30;
|
||||
}
|
||||
else # 32 bits
|
||||
{
|
||||
$mrs_data = $cas_latency == 2 ? 0x40 : 0x60;
|
||||
}
|
||||
}
|
||||
|
||||
$temp = $sdram_init_val | 0x0000c000; # Disable refresh
|
||||
$return_value .= &sdram_command($temp);
|
||||
$return_value .= " --pause 20000";
|
||||
|
||||
$return_value .= &sdram_command($temp, $sdram_precharge);
|
||||
$return_value .= &sdram_command($temp, $sdram_nop);
|
||||
|
||||
$return_value .= " --setreg +0 7";
|
||||
$return_value .= " --label label1";
|
||||
$return_value .= &sdram_command($temp, $sdram_refresh);
|
||||
$return_value .= &sdram_command($temp, $sdram_nop);
|
||||
$return_value .= " --loop +0 label1";
|
||||
|
||||
$return_value .= &sdram_command($temp, $sdram_mrs, $mrs_data);
|
||||
$return_value .= &sdram_command($temp, $sdram_nop);
|
||||
|
||||
$return_value .= &sdram_command($sdram_init_val);
|
||||
|
||||
return $return_value;
|
||||
}
|
||||
|
||||
#*****************************************************************************
|
||||
##
|
||||
## FUNCTION NAME: sdram_command
|
||||
##
|
||||
##****************************************************************************
|
||||
|
||||
sub sdram_command
|
||||
{
|
||||
my($temp, $value, $mrs_data) = @_;
|
||||
|
||||
$value ||= 0;
|
||||
if ($value == $sdram_mrs)
|
||||
{
|
||||
$value = sprintf("%lx", $temp | ($value << 9) | ($mrs_data << 16));
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = sprintf("%lx", $temp | ($value << 9));
|
||||
}
|
||||
|
||||
return " --setreg $sdram_timing_address $value";
|
||||
}
|
||||
|
||||
#*****************************************************************************
|
||||
##
|
||||
## FUNCTION NAME: print_help
|
||||
##
|
||||
##****************************************************************************
|
||||
|
||||
sub print_help
|
||||
{
|
||||
print "\nAXIS $my_name, ", '$Revision: 1.16 $ $Date: 2004/11/01 16:32:27 $ ', "\n";
|
||||
die <<EOT;
|
||||
Copyright (C) 2001-2002 Axis Communications AB
|
||||
|
||||
DESCRIPTION:
|
||||
This program is used to boot (and flash) a linux image to a box.
|
||||
It tries to extract the required ETRAX 100 settings from the image file.
|
||||
|
||||
SYNTAX:
|
||||
$my_name [options]
|
||||
|
||||
OPTIONS:
|
||||
-b <bootfile> : The boot image to use.
|
||||
-d <device> : The network interface to use, default is eth0.
|
||||
-f : Save the image in the flash memory starting at
|
||||
address 0x10000.
|
||||
-F : Save the image in the flash memory starting at
|
||||
address 0.
|
||||
-h : Print this help text.
|
||||
-i <image> : The path and name of the image to use, default
|
||||
is fimage.
|
||||
-o <offset> : The offset in the flash where the flashing starts.
|
||||
-O <offset> : The offset in the image file where the flashing
|
||||
starts from.
|
||||
-p : Print the resulting etrax100boot command instead
|
||||
of executing it.
|
||||
-s <size> : How much to flash (default is the size of the
|
||||
flash minus the offset specified using -o or -f).
|
||||
-S <size> : The size of the flash.
|
||||
|
||||
All sizes and offsets above can be specified as decimal numbers, or as
|
||||
hexadecimal numbers by prefixing them with 0x. It is also possible to use
|
||||
the suffixes k and M to specify kilo (1024) or mega (1048576).
|
||||
|
||||
EOT
|
||||
}
|
||||
|
||||
#****************** END OF FILE boot_linux ***********************************
|
||||
34
target/linux/etrax/image/e100boot/Makefile
Normal file
34
target/linux/etrax/image/e100boot/Makefile
Normal file
@@ -0,0 +1,34 @@
|
||||
#
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
# $Id$
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=e100boot
|
||||
PKG_VERSION:=0.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=e100boot.tar.bz2
|
||||
PKG_SOURCE_URL:=http://www.acmesystems.it/download/owrt
|
||||
PKG_MD5SUM:=
|
||||
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
CRLF_WORKAROUND=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Build/Compile
|
||||
make -C $(PKG_BUILD_DIR) STRIP=true
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/sbl/e100boot $(BIN_DIR)/etrax100boot
|
||||
endef
|
||||
|
||||
$(eval $(call Build/DefaultTargets))
|
||||
30
target/linux/etrax/image/mkfimage/Makefile
Normal file
30
target/linux/etrax/image/mkfimage/Makefile
Normal file
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
# $Id$
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=mkfimage
|
||||
PKG_VERSION:=0.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Build/Compile
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
cp -r ./src/* $(PKG_BUILD_DIR)
|
||||
make -C $(PKG_BUILD_DIR)
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mkfimage $(STAGING_DIR)/bin/mkfimage
|
||||
endef
|
||||
|
||||
$(eval $(call Build/DefaultTargets))
|
||||
4
target/linux/etrax/image/mkfimage/src/Makefile
Normal file
4
target/linux/etrax/image/mkfimage/src/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
all: mkfimage
|
||||
gcc mkfimage.c -o mkfimage
|
||||
|
||||
72
target/linux/etrax/image/mkfimage/src/mkfimage.c
Normal file
72
target/linux/etrax/image/mkfimage/src/mkfimage.c
Normal file
@@ -0,0 +1,72 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char **argv){
|
||||
unsigned char *buffer = malloc(64 * 1024);
|
||||
struct stat s;
|
||||
unsigned int size_vmlinux = 0, real_size_vmlinux = 0;
|
||||
const unsigned char *magic_str = "ACME_PART_MAGIC";
|
||||
unsigned int loop;
|
||||
unsigned char *magic;
|
||||
|
||||
if(argc != 3){
|
||||
printf("%s in out\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Generating image\n");
|
||||
|
||||
FILE *vmlinux = fopen(argv[1], "r");
|
||||
FILE *vmlinux_out = fopen(argv[2], "w");
|
||||
if((!vmlinux) || (!vmlinux_out)){
|
||||
printf("Error opening a file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
stat(argv[1], &s);
|
||||
size_vmlinux = s.st_size;
|
||||
real_size_vmlinux = (size_vmlinux & 0xffff0000) + 0x10000;
|
||||
|
||||
printf("vmlinux = 0x%.08X / 0x%.08X\n", size_vmlinux, real_size_vmlinux);
|
||||
|
||||
unsigned int t = fread(buffer, 1, 64 * 1024, vmlinux);
|
||||
for(loop = 0; loop < (64 * 1024) - sizeof(magic_str); loop++){
|
||||
if(buffer[loop] == magic_str[0]){
|
||||
if((magic = strstr(&buffer[loop], magic_str))){
|
||||
printf("Magic at 0x%.08X %p %p\n", magic - buffer, magic, buffer);
|
||||
printf("Found Magic %X%X%X%X\n",
|
||||
buffer[loop + strlen(magic_str)],
|
||||
buffer[loop + strlen(magic_str) + 2],
|
||||
buffer[loop + strlen(magic_str) + 1],
|
||||
buffer[loop + strlen(magic_str) + 3]);
|
||||
|
||||
buffer[loop + strlen(magic_str)] = real_size_vmlinux >> 24;
|
||||
buffer[loop + strlen(magic_str) + 2] = (real_size_vmlinux >> 16) & 0xff;
|
||||
buffer[loop + strlen(magic_str) + 1] = (real_size_vmlinux >> 8) & 0xff;
|
||||
buffer[loop + strlen(magic_str) + 3] = (real_size_vmlinux) & 0xff;
|
||||
|
||||
printf("Replaced with %.02X%.02X%.02X%.02X\n",
|
||||
buffer[loop + strlen(magic_str)],
|
||||
buffer[loop + strlen(magic_str) + 2],
|
||||
buffer[loop + strlen(magic_str) + 1],
|
||||
buffer[loop + strlen(magic_str) + 3]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(buffer, 1, 64 * 1024, vmlinux_out);
|
||||
real_size_vmlinux -= 64 * 1024;
|
||||
do {
|
||||
real_size_vmlinux -= 64 * 1024;
|
||||
memset(buffer, 0, 64 * 1024);
|
||||
fread(buffer, 1, 64 * 1024, vmlinux);
|
||||
fwrite(buffer, 1, 64 * 1024, vmlinux_out);
|
||||
} while (real_size_vmlinux);
|
||||
|
||||
return 0;
|
||||
}
|
||||
4551
target/linux/etrax/patches/cris/001-include-cris.patch
Normal file
4551
target/linux/etrax/patches/cris/001-include-cris.patch
Normal file
File diff suppressed because it is too large
Load Diff
24914
target/linux/etrax/patches/cris/002-arch-cris.patch
Normal file
24914
target/linux/etrax/patches/cris/002-arch-cris.patch
Normal file
File diff suppressed because it is too large
Load Diff
22601
target/linux/etrax/patches/cris/003-drivers-cris.patch
Normal file
22601
target/linux/etrax/patches/cris/003-drivers-cris.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
||||
--- linux-2.6.19.2.old/kernel/Kconfig.sched 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.2.dev/kernel/Kconfig.sched 2007-02-05 12:22:39.000000000 +0100
|
||||
@@ -0,0 +1,18 @@
|
||||
+#
|
||||
+# Scheduler tuning
|
||||
+#
|
||||
+
|
||||
+config OVERRIDE_SCHED_STARVATION_LIMIT
|
||||
+ bool "Override scheduler STARVATION_LIMIT"
|
||||
+ help
|
||||
+ This threshold sets the maximum time a task may wait in the
|
||||
+ expired runqueue when deciding to re-insert interactive tasks
|
||||
+ into the active runqueue. The time-limit is in ms but scales with
|
||||
+ the number of running tasks in the system.
|
||||
+
|
||||
+config SCHED_STARVATION_LIMIT
|
||||
+ int "Scheduler Starvation Limit"
|
||||
+ depends on OVERRIDE_SCHED_STARVATION_LIMIT
|
||||
+ default 10
|
||||
+ help
|
||||
+ Starvation limit in milliseconds per running task.
|
||||
60
target/linux/etrax/patches/cris/005-loader.patch
Normal file
60
target/linux/etrax/patches/cris/005-loader.patch
Normal file
@@ -0,0 +1,60 @@
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/boot/Makefile linux-2.6.19.2/arch/cris/arch-v10/boot/Makefile
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/boot/Makefile 2007-05-19 14:31:06.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/boot/Makefile 2007-05-19 14:32:24.000000000 +0200
|
||||
@@ -2,7 +2,7 @@
|
||||
# arch/cris/arch-v10/boot/Makefile
|
||||
#
|
||||
|
||||
-OBJCOPY = objcopy-cris
|
||||
+OBJCOPY = /usr/local/cris/objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
|
||||
subdir- := compressed rescue
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/Makefile linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/Makefile
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/Makefile 2007-05-19 14:31:06.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/Makefile 2007-05-19 14:33:45.000000000 +0200
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
CC = gcc-cris -melf $(LINUXINCLUDE)
|
||||
CFLAGS = -O2
|
||||
-LD = ld-cris
|
||||
+LD = /usr/local/cris/ld-cris
|
||||
LDFLAGS = -T $(obj)/decompress.ld
|
||||
OBJECTS = $(obj)/head.o $(obj)/misc.o
|
||||
-OBJCOPY = objcopy-cris
|
||||
+OBJCOPY = /usr/local/cris/objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
|
||||
quiet_cmd_image = BUILD $@
|
||||
@@ -22,10 +22,10 @@
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
$(obj)/head.o: $(obj)/head.S .config
|
||||
- @$(CC) -D__ASSEMBLY__ -traditional -c $< -o $@
|
||||
+ /usr/local/cris/gcc-cris -melf $(LINUXINCLUDE) -D__ASSEMBLY__ -traditional -c $< -o $@
|
||||
|
||||
$(obj)/misc.o: $(obj)/misc.c .config
|
||||
- @$(CC) -D__KERNEL__ -c $< -o $@
|
||||
+ /usr/local/cris/gcc-cris -melf $(LINUXINCLUDE) -D__KERNEL__ -c $< -o $@
|
||||
|
||||
$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
|
||||
$(call if_changed,image)
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/boot/rescue/Makefile linux-2.6.19.2/arch/cris/arch-v10/boot/rescue/Makefile
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/boot/rescue/Makefile 2007-05-19 14:31:06.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/boot/rescue/Makefile 2007-05-19 14:34:25.000000000 +0200
|
||||
@@ -2,12 +2,12 @@
|
||||
# Makefile for rescue (bootstrap) code
|
||||
#
|
||||
|
||||
-CC = gcc-cris -mlinux $(LINUXINCLUDE)
|
||||
+CC = /usr/local/cris/gcc-cris -mlinux $(LINUXINCLUDE)
|
||||
CFLAGS = -O2
|
||||
AFLAGS = -traditional
|
||||
-LD = gcc-cris -mlinux -nostdlib
|
||||
+LD = /usr/local/cris/gcc-cris -mlinux -nostdlib
|
||||
LDFLAGS = -T $(obj)/rescue.ld
|
||||
-OBJCOPY = objcopy-cris
|
||||
+OBJCOPY = /usr/local/cris/objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
obj-y = head.o
|
||||
OBJECT = $(obj)/$(obj-y)
|
||||
705
target/linux/etrax/patches/cris/006-gcc-4.patch
Normal file
705
target/linux/etrax/patches/cris/006-gcc-4.patch
Normal file
@@ -0,0 +1,705 @@
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/lib/memset.c linux-2.6.19.2/arch/cris/arch-v10/lib/memset.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/lib/memset.c 2007-06-03 13:59:39.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/lib/memset.c 2007-06-03 14:11:43.000000000 +0200
|
||||
@@ -110,45 +110,28 @@
|
||||
If you want to check that the allocation was right; then
|
||||
check the equalities in the first comment. It should say
|
||||
"r13=r13, r12=r12, r11=r11" */
|
||||
- __asm__ volatile ("
|
||||
- ;; Check that the following is true (same register names on
|
||||
- ;; both sides of equal sign, as in r8=r8):
|
||||
- ;; %0=r13, %1=r12, %4=r11
|
||||
- ;;
|
||||
- ;; Save the registers we'll clobber in the movem process
|
||||
- ;; on the stack. Don't mention them to gcc, it will only be
|
||||
- ;; upset.
|
||||
- subq 11*4,$sp
|
||||
- movem $r10,[$sp]
|
||||
-
|
||||
- move.d $r11,$r0
|
||||
- move.d $r11,$r1
|
||||
- move.d $r11,$r2
|
||||
- move.d $r11,$r3
|
||||
- move.d $r11,$r4
|
||||
- move.d $r11,$r5
|
||||
- move.d $r11,$r6
|
||||
- move.d $r11,$r7
|
||||
- move.d $r11,$r8
|
||||
- move.d $r11,$r9
|
||||
- move.d $r11,$r10
|
||||
-
|
||||
- ;; Now we've got this:
|
||||
- ;; r13 - dst
|
||||
- ;; r12 - n
|
||||
+ __asm__ volatile (
|
||||
+ "subq 11*4,$sp\n\t"
|
||||
+ "movem $r10,[$sp]\n\t"
|
||||
+ "move.d $r11,$r0\n\t"
|
||||
+ "move.d $r11,$r1\n\t"
|
||||
+ "move.d $r11,$r2\n\t"
|
||||
+ "move.d $r11,$r3\n\t"
|
||||
+ "move.d $r11,$r4\n\t"
|
||||
+ "move.d $r11,$r5\n\t"
|
||||
+ "move.d $r11,$r6\n\t"
|
||||
+ "move.d $r11,$r7\n\t"
|
||||
+ "move.d $r11,$r8\n\t"
|
||||
+ "move.d $r11,$r9\n\t"
|
||||
+ "move.d $r11,$r10\n\t"
|
||||
+ "subq 12*4,$r12\n\t"
|
||||
+"0:\n\t"
|
||||
+ "subq 12*4,$r12\n\t"
|
||||
+ "bge 0b\n\t"
|
||||
+ "movem $r11,[$r13+]\n\t"
|
||||
+ "addq 12*4,$r12\n\t"
|
||||
+ "movem [$sp+],$r10"
|
||||
|
||||
- ;; Update n for the first loop
|
||||
- subq 12*4,$r12
|
||||
-0:
|
||||
- subq 12*4,$r12
|
||||
- bge 0b
|
||||
- movem $r11,[$r13+]
|
||||
-
|
||||
- addq 12*4,$r12 ;; compensate for last loop underflowing n
|
||||
-
|
||||
- ;; Restore registers from stack
|
||||
- movem [$sp+],$r10"
|
||||
-
|
||||
/* Outputs */ : "=r" (dst), "=r" (n)
|
||||
/* Inputs */ : "0" (dst), "1" (n), "r" (lc));
|
||||
|
||||
@@ -161,10 +144,14 @@
|
||||
|
||||
while ( n >= 16 )
|
||||
{
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
n -= 16;
|
||||
}
|
||||
|
||||
@@ -182,67 +169,95 @@
|
||||
*(short*)dst = (short) lc;
|
||||
break;
|
||||
case 3:
|
||||
- *((short*)dst)++ = (short) lc;
|
||||
+ *((short*)dst) = (short) lc;
|
||||
+ dst+=2;
|
||||
*(char*)dst = (char) lc;
|
||||
break;
|
||||
case 4:
|
||||
- *((long*)dst)++ = lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
break;
|
||||
case 5:
|
||||
- *((long*)dst)++ = lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
*(char*)dst = (char) lc;
|
||||
break;
|
||||
case 6:
|
||||
- *((long*)dst)++ = lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
*(short*)dst = (short) lc;
|
||||
break;
|
||||
case 7:
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((short*)dst)++ = (short) lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((short*)dst) = (short) lc;
|
||||
+ dst+=2;
|
||||
*(char*)dst = (char) lc;
|
||||
break;
|
||||
case 8:
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
break;
|
||||
case 9:
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
*(char*)dst = (char) lc;
|
||||
break;
|
||||
case 10:
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
*(short*)dst = (short) lc;
|
||||
break;
|
||||
case 11:
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((short*)dst)++ = (short) lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((short*)dst) = (short) lc;
|
||||
+ dst+=2;
|
||||
*(char*)dst = (char) lc;
|
||||
break;
|
||||
case 12:
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
break;
|
||||
case 13:
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
*(char*)dst = (char) lc;
|
||||
break;
|
||||
case 14:
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
*(short*)dst = (short) lc;
|
||||
break;
|
||||
case 15:
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((long*)dst)++ = lc;
|
||||
- *((short*)dst)++ = (short) lc;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((long*)dst) = lc;
|
||||
+ dst+=4;
|
||||
+ *((short*)dst) = (short) lc;
|
||||
+ dst+=2;
|
||||
*(char*)dst = (char) lc;
|
||||
break;
|
||||
}
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/lib/string.c linux-2.6.19.2/arch/cris/arch-v10/lib/string.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/lib/string.c 2007-06-03 13:59:39.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/lib/string.c 2007-06-03 14:21:02.000000000 +0200
|
||||
@@ -95,37 +95,19 @@
|
||||
If you want to check that the allocation was right; then
|
||||
check the equalities in the first comment. It should say
|
||||
"r13=r13, r11=r11, r12=r12" */
|
||||
- __asm__ volatile ("
|
||||
- ;; Check that the following is true (same register names on
|
||||
- ;; both sides of equal sign, as in r8=r8):
|
||||
- ;; %0=r13, %1=r11, %2=r12
|
||||
- ;;
|
||||
- ;; Save the registers we'll use in the movem process
|
||||
- ;; on the stack.
|
||||
- subq 11*4,$sp
|
||||
- movem $r10,[$sp]
|
||||
-
|
||||
- ;; Now we've got this:
|
||||
- ;; r11 - src
|
||||
- ;; r13 - dst
|
||||
- ;; r12 - n
|
||||
-
|
||||
- ;; Update n for the first loop
|
||||
- subq 44,$r12
|
||||
-0:
|
||||
- movem [$r11+],$r10
|
||||
- subq 44,$r12
|
||||
- bge 0b
|
||||
- movem $r10,[$r13+]
|
||||
-
|
||||
- addq 44,$r12 ;; compensate for last loop underflowing n
|
||||
-
|
||||
- ;; Restore registers from stack
|
||||
- movem [$sp+],$r10"
|
||||
-
|
||||
+ __asm__ volatile (
|
||||
+ "subq 11*4,$sp\n\t"
|
||||
+ "movem $r10,[$sp]\n\t"
|
||||
+ "subq 44,$r12\n\t"
|
||||
+"0:\n\t"
|
||||
+ "movem [$r11+],$r10\n\t"
|
||||
+ "subq 44,$r12\n\t"
|
||||
+ "bge 0b\n\t"
|
||||
+ "movem $r10,[$r13+]\n\t"
|
||||
+ "addq 44,$r12\n\t"
|
||||
+ "movem [$sp+],$r10\n\t"
|
||||
/* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
|
||||
/* Inputs */ : "0" (dst), "1" (src), "2" (n));
|
||||
-
|
||||
}
|
||||
|
||||
/* Either we directly starts copying, using dword copying
|
||||
@@ -135,10 +117,14 @@
|
||||
|
||||
while ( n >= 16 )
|
||||
{
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
n -= 16;
|
||||
}
|
||||
|
||||
@@ -156,67 +142,95 @@
|
||||
*(short*)dst = *(short*)src;
|
||||
break;
|
||||
case 3:
|
||||
- *((short*)dst)++ = *((short*)src)++;
|
||||
+ *((short*)dst) = *((short*)src);
|
||||
+ src+=2;dst+=2;
|
||||
*(char*)dst = *(char*)src;
|
||||
break;
|
||||
case 4:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
break;
|
||||
case 5:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
*(char*)dst = *(char*)src;
|
||||
break;
|
||||
case 6:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
*(short*)dst = *(short*)src;
|
||||
break;
|
||||
case 7:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((short*)dst)++ = *((short*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((short*)dst) = *((short*)src);
|
||||
+ src+=2;dst+=2;
|
||||
*(char*)dst = *(char*)src;
|
||||
break;
|
||||
case 8:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
break;
|
||||
case 9:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
*(char*)dst = *(char*)src;
|
||||
break;
|
||||
case 10:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
*(short*)dst = *(short*)src;
|
||||
break;
|
||||
case 11:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((short*)dst)++ = *((short*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((short*)dst) = *((short*)src);
|
||||
+ src+=2;dst+=2;
|
||||
*(char*)dst = *(char*)src;
|
||||
break;
|
||||
case 12:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
break;
|
||||
case 13:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
*(char*)dst = *(char*)src;
|
||||
break;
|
||||
case 14:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
*(short*)dst = *(short*)src;
|
||||
break;
|
||||
case 15:
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((long*)dst)++ = *((long*)src)++;
|
||||
- *((short*)dst)++ = *((short*)src)++;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((long*)dst) = *((long*)src);
|
||||
+ src+=4;dst+=4;
|
||||
+ *((short*)dst) = *((short*)src);
|
||||
+ src+=2;dst+=2;
|
||||
*(char*)dst = *(char*)src;
|
||||
break;
|
||||
}
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/lib/usercopy.c linux-2.6.19.2/arch/cris/arch-v10/lib/usercopy.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/lib/usercopy.c 2007-06-03 13:59:39.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/lib/usercopy.c 2007-06-03 14:25:55.000000000 +0200
|
||||
@@ -88,63 +88,38 @@
|
||||
If you want to check that the allocation was right; then
|
||||
check the equalities in the first comment. It should say
|
||||
"r13=r13, r11=r11, r12=r12". */
|
||||
- __asm__ volatile ("\
|
||||
- .ifnc %0%1%2%3,$r13$r11$r12$r10 \n\
|
||||
- .err \n\
|
||||
- .endif \n\
|
||||
-
|
||||
- ;; Save the registers we'll use in the movem process
|
||||
- ;; on the stack.
|
||||
- subq 11*4,$sp
|
||||
- movem $r10,[$sp]
|
||||
-
|
||||
- ;; Now we've got this:
|
||||
- ;; r11 - src
|
||||
- ;; r13 - dst
|
||||
- ;; r12 - n
|
||||
-
|
||||
- ;; Update n for the first loop
|
||||
- subq 44,$r12
|
||||
-
|
||||
-; Since the noted PC of a faulting instruction in a delay-slot of a taken
|
||||
-; branch, is that of the branch target, we actually point at the from-movem
|
||||
-; for this case. There is no ambiguity here; if there was a fault in that
|
||||
-; instruction (meaning a kernel oops), the faulted PC would be the address
|
||||
-; after *that* movem.
|
||||
-
|
||||
-0:
|
||||
- movem [$r11+],$r10
|
||||
- subq 44,$r12
|
||||
- bge 0b
|
||||
- movem $r10,[$r13+]
|
||||
-1:
|
||||
- addq 44,$r12 ;; compensate for last loop underflowing n
|
||||
-
|
||||
- ;; Restore registers from stack
|
||||
- movem [$sp+],$r10
|
||||
-2:
|
||||
- .section .fixup,\"ax\"
|
||||
-
|
||||
-; To provide a correct count in r10 of bytes that failed to be copied,
|
||||
-; we jump back into the loop if the loop-branch was taken. There is no
|
||||
-; performance penalty for sany use; the program will segfault soon enough.
|
||||
-
|
||||
-3:
|
||||
- move.d [$sp],$r10
|
||||
- addq 44,$r10
|
||||
- move.d $r10,[$sp]
|
||||
- jump 0b
|
||||
-4:
|
||||
- movem [$sp+],$r10
|
||||
- addq 44,$r10
|
||||
- addq 44,$r12
|
||||
- jump 2b
|
||||
-
|
||||
- .previous
|
||||
- .section __ex_table,\"a\"
|
||||
- .dword 0b,3b
|
||||
- .dword 1b,4b
|
||||
- .previous"
|
||||
+ __asm__ volatile (
|
||||
+ ".ifnc %0%1%2%3,$r13$r11$r12$r10 \n\t"
|
||||
+ ".err \n\t"
|
||||
+ ".endif \n\t"
|
||||
+ "subq 11*4,$sp\n\t"
|
||||
+ "movem $r10,[$sp]\n\t"
|
||||
+ "subq 44,$r12\n\t"
|
||||
+ "0:\n\t"
|
||||
+ "movem [$r11+],$r10\n\t"
|
||||
+ "subq 44,$r12\n\t"
|
||||
+ "bge 0b\n\t"
|
||||
+ "movem $r10,[$r13+]\n\t"
|
||||
+ "1:\n\t"
|
||||
+ "addq 44,$r12 \n\t"
|
||||
+ "movem [$sp+],$r10\n\t"
|
||||
+ "2:\n\t"
|
||||
+ ".section .fixup,\"ax\"\n\t"
|
||||
+ "3:\n\t"
|
||||
+ "move.d [$sp],$r10\n\t"
|
||||
+ "addq 44,$r10\n\t"
|
||||
+ "move.d $r10,[$sp]\n\t"
|
||||
+ "jump 0b\n\t"
|
||||
+ "4:\n\t"
|
||||
+ "movem [$sp+],$r10\n\t"
|
||||
+ "addq 44,$r10\n\t"
|
||||
+ "addq 44,$r12\n\t"
|
||||
+ "jump 2b\n\t"
|
||||
+ ".previous\n\t"
|
||||
+ ".section __ex_table,\"a\"\n\t"
|
||||
+ ".dword 0b,3b\n\t"
|
||||
+ ".dword 1b,4b\n\t"
|
||||
+ ".previous\n\t"
|
||||
|
||||
/* Outputs */ : "=r" (dst), "=r" (src), "=r" (n), "=r" (retn)
|
||||
/* Inputs */ : "0" (dst), "1" (src), "2" (n), "3" (retn));
|
||||
@@ -253,60 +228,32 @@
|
||||
If you want to check that the allocation was right; then
|
||||
check the equalities in the first comment. It should say
|
||||
"r13=r13, r11=r11, r12=r12" */
|
||||
- __asm__ volatile ("
|
||||
- .ifnc %0%1%2%3,$r13$r11$r12$r10 \n\
|
||||
- .err \n\
|
||||
- .endif \n\
|
||||
-
|
||||
- ;; Save the registers we'll use in the movem process
|
||||
- ;; on the stack.
|
||||
- subq 11*4,$sp
|
||||
- movem $r10,[$sp]
|
||||
-
|
||||
- ;; Now we've got this:
|
||||
- ;; r11 - src
|
||||
- ;; r13 - dst
|
||||
- ;; r12 - n
|
||||
-
|
||||
- ;; Update n for the first loop
|
||||
- subq 44,$r12
|
||||
-0:
|
||||
- movem [$r11+],$r10
|
||||
-1:
|
||||
- subq 44,$r12
|
||||
- bge 0b
|
||||
- movem $r10,[$r13+]
|
||||
-
|
||||
- addq 44,$r12 ;; compensate for last loop underflowing n
|
||||
-
|
||||
- ;; Restore registers from stack
|
||||
- movem [$sp+],$r10
|
||||
-4:
|
||||
- .section .fixup,\"ax\"
|
||||
-
|
||||
-;; Do not jump back into the loop if we fail. For some uses, we get a
|
||||
-;; page fault somewhere on the line. Without checking for page limits,
|
||||
-;; we don't know where, but we need to copy accurately and keep an
|
||||
-;; accurate count; not just clear the whole line. To do that, we fall
|
||||
-;; down in the code below, proceeding with smaller amounts. It should
|
||||
-;; be kept in mind that we have to cater to code like what at one time
|
||||
-;; was in fs/super.c:
|
||||
-;; i = size - copy_from_user((void *)page, data, size);
|
||||
-;; which would cause repeated faults while clearing the remainder of
|
||||
-;; the SIZE bytes at PAGE after the first fault.
|
||||
-;; A caveat here is that we must not fall through from a failing page
|
||||
-;; to a valid page.
|
||||
-
|
||||
-3:
|
||||
- movem [$sp+],$r10
|
||||
- addq 44,$r12 ;; Get back count before faulting point.
|
||||
- subq 44,$r11 ;; Get back pointer to faulting movem-line.
|
||||
- jump 4b ;; Fall through, pretending the fault didn't happen.
|
||||
-
|
||||
- .previous
|
||||
- .section __ex_table,\"a\"
|
||||
- .dword 1b,3b
|
||||
- .previous"
|
||||
+ __asm__ volatile (
|
||||
+ ".ifnc %0%1%2%3,$r13$r11$r12$r10 \n\t"
|
||||
+ ".err \n\t"
|
||||
+ ".endif \n\t"
|
||||
+ "subq 11*4,$sp\n\t"
|
||||
+ "movem $r10,[$sp]\n\t"
|
||||
+ "subq 44,$r12\n\t"
|
||||
+ "0:\n\t"
|
||||
+ "movem [$r11+],$r10\n\t"
|
||||
+ "1:\n\t"
|
||||
+ "subq 44,$r12\n\t"
|
||||
+ "bge 0b\n\t"
|
||||
+ "movem $r10,[$r13+]\n\t"
|
||||
+ "addq 44,$r12 \n\t"
|
||||
+ "movem [$sp+],$r10\n\t"
|
||||
+ "4:\n\t"
|
||||
+ ".section .fixup,\"ax\"\n\t"
|
||||
+ "3:\n\t"
|
||||
+ "movem [$sp+],$r10\n\t"
|
||||
+ "addq 44,$r12\n\t"
|
||||
+ "subq 44,$r11\n\t"
|
||||
+ "jump 4b \n\t"
|
||||
+ ".previous\n\t"
|
||||
+ ".section __ex_table,\"a\"\n\t"
|
||||
+ ".dword 1b,3b\n\t"
|
||||
+ ".previous\n\t"
|
||||
|
||||
/* Outputs */ : "=r" (dst), "=r" (src), "=r" (n), "=r" (retn)
|
||||
/* Inputs */ : "0" (dst), "1" (src), "2" (n), "3" (retn));
|
||||
@@ -425,66 +372,50 @@
|
||||
If you want to check that the allocation was right; then
|
||||
check the equalities in the first comment. It should say
|
||||
something like "r13=r13, r11=r11, r12=r12". */
|
||||
- __asm__ volatile ("
|
||||
- .ifnc %0%1%2,$r13$r12$r10 \n\
|
||||
- .err \n\
|
||||
- .endif \n\
|
||||
-
|
||||
- ;; Save the registers we'll clobber in the movem process
|
||||
- ;; on the stack. Don't mention them to gcc, it will only be
|
||||
- ;; upset.
|
||||
- subq 11*4,$sp
|
||||
- movem $r10,[$sp]
|
||||
-
|
||||
- clear.d $r0
|
||||
- clear.d $r1
|
||||
- clear.d $r2
|
||||
- clear.d $r3
|
||||
- clear.d $r4
|
||||
- clear.d $r5
|
||||
- clear.d $r6
|
||||
- clear.d $r7
|
||||
- clear.d $r8
|
||||
- clear.d $r9
|
||||
- clear.d $r10
|
||||
- clear.d $r11
|
||||
-
|
||||
- ;; Now we've got this:
|
||||
- ;; r13 - dst
|
||||
- ;; r12 - n
|
||||
-
|
||||
- ;; Update n for the first loop
|
||||
- subq 12*4,$r12
|
||||
-0:
|
||||
- subq 12*4,$r12
|
||||
- bge 0b
|
||||
- movem $r11,[$r13+]
|
||||
-1:
|
||||
- addq 12*4,$r12 ;; compensate for last loop underflowing n
|
||||
-
|
||||
- ;; Restore registers from stack
|
||||
- movem [$sp+],$r10
|
||||
-2:
|
||||
- .section .fixup,\"ax\"
|
||||
-3:
|
||||
- move.d [$sp],$r10
|
||||
- addq 12*4,$r10
|
||||
- move.d $r10,[$sp]
|
||||
- clear.d $r10
|
||||
- jump 0b
|
||||
-
|
||||
-4:
|
||||
- movem [$sp+],$r10
|
||||
- addq 12*4,$r10
|
||||
- addq 12*4,$r12
|
||||
- jump 2b
|
||||
-
|
||||
- .previous
|
||||
- .section __ex_table,\"a\"
|
||||
- .dword 0b,3b
|
||||
- .dword 1b,4b
|
||||
- .previous"
|
||||
-
|
||||
+ __asm__ volatile (
|
||||
+ ".ifnc %0%1%2,$r13$r12$r10\n\t"
|
||||
+ ".err \n\t"
|
||||
+ ".endif\n\t"
|
||||
+ "subq 11*4,$sp\n\t"
|
||||
+ "movem $r10,[$sp]\n\t"
|
||||
+ "clear.d $r0\n\t"
|
||||
+ "clear.d $r1\n\t"
|
||||
+ "clear.d $r2\n\t"
|
||||
+ "clear.d $r3\n\t"
|
||||
+ "clear.d $r4\n\t"
|
||||
+ "clear.d $r5\n\t"
|
||||
+ "clear.d $r6\n\t"
|
||||
+ "clear.d $r7\n\t"
|
||||
+ "clear.d $r8\n\t"
|
||||
+ "clear.d $r9\n\t"
|
||||
+ "clear.d $r10\n\t"
|
||||
+ "clear.d $r11\n\t"
|
||||
+ "subq 12*4,$r12\n\t"
|
||||
+ "0:\n\t"
|
||||
+ "subq 12*4,$r12\n\t"
|
||||
+ "bge 0b\n\t"
|
||||
+ "movem $r11,[$r13+]\n\t"
|
||||
+ "1: \n\t"
|
||||
+ "addq 12*4,$r12 \n\t"
|
||||
+ "movem [$sp+],$r10\n\t"
|
||||
+ "2:\n\t"
|
||||
+ ".section .fixup,\"ax\"\n\t"
|
||||
+ "3:\n\t"
|
||||
+ "move.d [$sp],$r10\n\t"
|
||||
+ "addq 12*4,$r10\n\t"
|
||||
+ "move.d $r10,[$sp]\n\t"
|
||||
+ "clear.d $r10\n\t"
|
||||
+ "jump 0b\n\t"
|
||||
+ "4:\n\t"
|
||||
+ "movem [$sp+],$r10\n\t"
|
||||
+ "addq 12*4,$r10\n\t"
|
||||
+ "addq 12*4,$r12\n\t"
|
||||
+ "jump 2b\n\t"
|
||||
+ ".previous\n\t"
|
||||
+ ".section __ex_table,\"a\"\n\t"
|
||||
+ ".dword 0b,3b\n\t"
|
||||
+ ".dword 1b,4b\n\t"
|
||||
+ ".previous\n\t"
|
||||
/* Outputs */ : "=r" (dst), "=r" (n), "=r" (retn)
|
||||
/* Inputs */ : "0" (dst), "1" (n), "2" (retn)
|
||||
/* Clobber */ : "r11");
|
||||
12
target/linux/etrax/patches/cris/007-nr_free_pages.patch
Normal file
12
target/linux/etrax/patches/cris/007-nr_free_pages.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff -urN linux-2.6.19.2.orig/mm/page_alloc.c linux-2.6.19.2/mm/page_alloc.c
|
||||
--- linux-2.6.19.2.orig/mm/page_alloc.c 2007-05-20 03:26:41.000000000 +0200
|
||||
+++ linux-2.6.19.2/mm/page_alloc.c 2007-05-20 03:28:22.000000000 +0200
|
||||
@@ -1200,7 +1200,7 @@
|
||||
unsigned int nr_free_pages(void)
|
||||
{
|
||||
unsigned int sum = 0;
|
||||
- struct zone *zone;
|
||||
+ volatile struct zone *zone;
|
||||
|
||||
for_each_zone(zone)
|
||||
sum += zone->free_pages;
|
||||
41
target/linux/etrax/patches/cris/008-flashmap.patch
Normal file
41
target/linux/etrax/patches/cris/008-flashmap.patch
Normal file
@@ -0,0 +1,41 @@
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/axisflashmap.c linux-2.6.19.2/arch/cris/arch-v10/drivers/axisflashmap.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/axisflashmap.c 2007-05-21 23:12:27.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/drivers/axisflashmap.c 2007-05-21 23:13:09.000000000 +0200
|
||||
@@ -256,7 +256,7 @@
|
||||
|
||||
/* If no partition-table was found, we use this default-set. */
|
||||
#define MAX_PARTITIONS 7
|
||||
-#define NUM_DEFAULT_PARTITIONS 3
|
||||
+#define NUM_DEFAULT_PARTITIONS 3
|
||||
|
||||
/*
|
||||
* Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the
|
||||
@@ -265,19 +265,19 @@
|
||||
*/
|
||||
static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
|
||||
{
|
||||
- .name = "boot firmware",
|
||||
- .size = CONFIG_ETRAX_PTABLE_SECTOR,
|
||||
+ .name = "kernel",
|
||||
+ .size = 0x200000,
|
||||
.offset = 0
|
||||
},
|
||||
{
|
||||
- .name = "kernel",
|
||||
- .size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
|
||||
- .offset = CONFIG_ETRAX_PTABLE_SECTOR
|
||||
+ .name = "filesystem",
|
||||
+ .size = 0x200000,
|
||||
+ .offset = 0x200000
|
||||
},
|
||||
{
|
||||
- .name = "filesystem",
|
||||
- .size = 5 * CONFIG_ETRAX_PTABLE_SECTOR,
|
||||
- .offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
|
||||
+ .name = "filesystem2",
|
||||
+ .size = 0x400000,
|
||||
+ .offset = 0x400000
|
||||
}
|
||||
};
|
||||
|
||||
009-flashmap.patch
|
||||
33
target/linux/etrax/patches/cris/008a-flashmap.patch
Normal file
33
target/linux/etrax/patches/cris/008a-flashmap.patch
Normal file
@@ -0,0 +1,33 @@
|
||||
Binary files linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/.axisflashmap.c.swp and linux-2.6.19.2/arch/cris/arch-v10/drivers/.axisflashmap.c.swp differ
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/axisflashmap.c linux-2.6.19.2/arch/cris/arch-v10/drivers/axisflashmap.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/axisflashmap.c 2007-05-28 01:40:09.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/drivers/axisflashmap.c 2007-05-28 01:41:29.000000000 +0200
|
||||
@@ -256,7 +256,7 @@
|
||||
|
||||
/* If no partition-table was found, we use this default-set. */
|
||||
#define MAX_PARTITIONS 7
|
||||
-#define NUM_DEFAULT_PARTITIONS 3
|
||||
+#define NUM_DEFAULT_PARTITIONS 2
|
||||
|
||||
/*
|
||||
* Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the
|
||||
@@ -270,15 +270,10 @@
|
||||
.offset = 0
|
||||
},
|
||||
{
|
||||
- .name = "filesystem",
|
||||
- .size = 0x200000,
|
||||
+ .name = "rootfs",
|
||||
+ .size = 0x600000,
|
||||
.offset = 0x200000
|
||||
},
|
||||
- {
|
||||
- .name = "filesystem2",
|
||||
- .size = 0x400000,
|
||||
- .offset = 0x400000
|
||||
- }
|
||||
};
|
||||
|
||||
/* Initialize the ones normally used. */
|
||||
Binary files linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/axisflashmap.o and linux-2.6.19.2/arch/cris/arch-v10/drivers/axisflashmap.o differ
|
||||
Binary files linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/built-in.o and linux-2.6.19.2/arch/cris/arch-v10/drivers/built-in.o differ
|
||||
83
target/linux/etrax/patches/cris/009-sysfs.patch
Normal file
83
target/linux/etrax/patches/cris/009-sysfs.patch
Normal file
@@ -0,0 +1,83 @@
|
||||
--- linux-2.6.19.2.orig/drivers/serial/crisv10.c 2007-05-26 18:12:33.000000000 +0200
|
||||
+++ linux-2.6.19.2/drivers/serial/crisv10.c 2007-05-26 19:24:56.000000000 +0200
|
||||
@@ -442,6 +442,7 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mutex.h>
|
||||
+#include <linux/miscdevice.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
@@ -4822,6 +4823,12 @@
|
||||
.tiocmset = rs_tiocmset
|
||||
};
|
||||
|
||||
+#define CONFIG_ETRAX_SYSFS_NODES
|
||||
+#ifdef CONFIG_ETRAX_SYSFS_NODES
|
||||
+static struct class *mem_class;
|
||||
+#endif
|
||||
+
|
||||
+static struct class *rs_class;
|
||||
static int __init
|
||||
rs_init(void)
|
||||
{
|
||||
@@ -4948,6 +4955,30 @@
|
||||
#endif
|
||||
#endif /* CONFIG_SVINTO_SIM */
|
||||
|
||||
+#ifdef CONFIG_ETRAX_SYSFS_NODES
|
||||
+
|
||||
+ rs_class = class_create(THIS_MODULE, "rs_tty");
|
||||
+#ifdef CONFIG_ETRAX_SERIAL_PORT0
|
||||
+ class_device_create(rs_class, NULL,
|
||||
+ MKDEV(TTY_MAJOR, 64),
|
||||
+ NULL, "ttyS0");
|
||||
+#endif
|
||||
+#ifdef CONFIG_ETRAX_SERIAL_PORT1
|
||||
+ class_device_create(rs_class, NULL,
|
||||
+ MKDEV(TTY_MAJOR, 65),
|
||||
+ NULL, "ttyS1");
|
||||
+#endif
|
||||
+#ifdef CONFIG_ETRAX_SERIAL_PORT2
|
||||
+ class_device_create(rs_class, NULL,
|
||||
+ MKDEV(TTY_MAJOR, 66),
|
||||
+ NULL, "ttyS2");
|
||||
+#endif
|
||||
+#ifdef CONFIG_ETRAX_SERIAL_PORT3
|
||||
+ class_device_create(rs_class, NULL,
|
||||
+ MKDEV(TTY_MAJOR, 67),
|
||||
+ NULL, "ttyS3");
|
||||
+#endif
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/Kconfig 2007-05-26 18:12:22.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/drivers/Kconfig 2007-05-26 19:26:06.000000000 +0200
|
||||
@@ -900,3 +900,9 @@
|
||||
1 = 2kohm, 2 = 4kohm, 3 = 4kohm
|
||||
4 = 1 diode, 8 = 2 diodes
|
||||
Allowed values are (increasing current): 0, 11, 10, 9, 7, 6, 5
|
||||
+
|
||||
+config ETRAX_SYSFS_NODES
|
||||
+ bool "Create device nodes using sysfs for builtin devices"
|
||||
+ default n
|
||||
+ help
|
||||
+ Creates device nodes inside the rootfs dynamically for all the builtin devices
|
||||
--- linux-2.6.19.2.orig/drivers/serial/crisv10.c 2007-05-28 20:37:56.000000000 +0200
|
||||
+++ linux-2.6.19.2/drivers/serial/crisv10.c 2007-05-28 20:39:07.000000000 +0200
|
||||
@@ -4823,12 +4823,11 @@
|
||||
.tiocmset = rs_tiocmset
|
||||
};
|
||||
|
||||
-#define CONFIG_ETRAX_SYSFS_NODES
|
||||
#ifdef CONFIG_ETRAX_SYSFS_NODES
|
||||
-static struct class *mem_class;
|
||||
+static struct class *rs_class;
|
||||
#endif
|
||||
|
||||
-static struct class *rs_class;
|
||||
+
|
||||
static int __init
|
||||
rs_init(void)
|
||||
{
|
||||
1973
target/linux/etrax/patches/cris/010-multi-target-build.patch
Normal file
1973
target/linux/etrax/patches/cris/010-multi-target-build.patch
Normal file
File diff suppressed because it is too large
Load Diff
26
target/linux/etrax/patches/cris/011-debug-port
Normal file
26
target/linux/etrax/patches/cris/011-debug-port
Normal file
@@ -0,0 +1,26 @@
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/misc.c linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/misc.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/misc.c 2007-05-28 21:53:52.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/misc.c 2007-05-28 22:23:16.000000000 +0200
|
||||
@@ -143,9 +143,10 @@
|
||||
static void
|
||||
puts(const char *s)
|
||||
{
|
||||
-#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
|
||||
- while(*s) {
|
||||
-#ifdef CONFIG_ETRAX_DEBUG_PORT0
|
||||
+#if defined(CONFIG_ETRAX_DEBUG_PORT0) || defined(CONFIG_ETRAX_DEBUG_PORT1) || defined(CONFIG_ETRAX_DEBUG_PORT2) || defined(CONFIG_ETRAX_DEBUG_PORT3) || defined(CONFIG_ETRAX_SERIAL_PORT0)
|
||||
+
|
||||
+while(*s) {
|
||||
+#if defined(CONFIG_ETRAX_DEBUG_PORT0) || defined(CONFIG_ETRAX_SERIAL_PORT0)
|
||||
while(!(*R_SERIAL0_STATUS & (1 << 5))) ;
|
||||
*R_SERIAL0_TR_DATA = *s++;
|
||||
#endif
|
||||
@@ -232,7 +233,7 @@
|
||||
/* input_data is set in head.S */
|
||||
inbuf = input_data;
|
||||
|
||||
-#ifdef CONFIG_ETRAX_DEBUG_PORT0
|
||||
+#if defined(CONFIG_ETRAX_DEBUG_PORT0) || defined(CONFIG_ETRAX_SERIAL_PORT0)
|
||||
*R_SERIAL0_XOFF = 0;
|
||||
*R_SERIAL0_BAUD = 0x99;
|
||||
*R_SERIAL0_TR_CTRL = 0x40;
|
||||
22
target/linux/etrax/patches/cris/012-splash.patch
Normal file
22
target/linux/etrax/patches/cris/012-splash.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/misc.c linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/misc.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/misc.c 2007-05-28 22:35:23.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/misc.c 2007-05-28 22:40:43.000000000 +0200
|
||||
@@ -266,8 +266,16 @@
|
||||
puts("You need an ETRAX 100LX to run linux 2.6\n");
|
||||
while(1);
|
||||
}
|
||||
+ puts("\r\n _ _ _ \r\n");
|
||||
+ puts(" | | (_) | \r\n");
|
||||
+ puts(" __ _ ___ _ __ ___ ___ ___ _ _ ___| |_ ___ _ __ ___ ___ _| |_\r\n");
|
||||
+ puts(" / _` |/ __| '_ ` _ \\ / _ \\/ __| | | / __| __/ _ \\ '_ ` _ \\/ __| | | __|\r\n");
|
||||
+ puts(" | (_| | (__| | | | | | __/\\__ \\ |_| \\__ \\ || __/ | | | | \\__ \\_| | |_ \r\n");
|
||||
+ puts(" \\__,_|\\___|_| |_| |_|\\___||___/\\__, |___/\\__\\___|_| |_| |_|___(_)_|\\__|\r\n");
|
||||
+ puts(" __/ | \r\n");
|
||||
+ puts(" |___/ FOXBOARD @ www.acmesystems.it \r\n");
|
||||
|
||||
- puts("Uncompressing Linux...\n");
|
||||
+ puts("Uncompressing Linux...\r\n");
|
||||
gunzip();
|
||||
- puts("Done. Now booting the kernel.\n");
|
||||
+ puts("Done. Now booting the kernel.\r\n");
|
||||
}
|
||||
180
target/linux/etrax/patches/cris/013-crisdriver-sysfs.patch
Normal file
180
target/linux/etrax/patches/cris/013-crisdriver-sysfs.patch
Normal file
@@ -0,0 +1,180 @@
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/ds1302.c linux-2.6.19.2/arch/cris/arch-v10/drivers/ds1302.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/ds1302.c 2007-05-28 22:35:23.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/drivers/ds1302.c 2007-05-28 22:55:40.000000000 +0200
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/capability.h>
|
||||
-
|
||||
+#include <linux/device.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/arch/svinto.h>
|
||||
@@ -480,6 +480,10 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SYSFS
|
||||
+static struct class *rtc_class;
|
||||
+#endif
|
||||
+
|
||||
static int __init ds1302_register(void)
|
||||
{
|
||||
ds1302_init();
|
||||
@@ -488,7 +492,15 @@
|
||||
ds1302_name, RTC_MAJOR_NR);
|
||||
return -1;
|
||||
}
|
||||
- return 0;
|
||||
+
|
||||
+ #ifdef CONFIG_SYSFS
|
||||
+ rtc_class = class_create(THIS_MODULE, "rtc");
|
||||
+ class_device_create(rtc_class, NULL,
|
||||
+ MKDEV(RTC_MAJOR_NR, 0),
|
||||
+ NULL, "rtc");
|
||||
+ #endif
|
||||
+
|
||||
+ return 0;
|
||||
|
||||
}
|
||||
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/eeprom.c linux-2.6.19.2/arch/cris/arch-v10/drivers/eeprom.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/eeprom.c 2007-05-28 22:35:23.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/drivers/eeprom.c 2007-05-28 23:03:45.000000000 +0200
|
||||
@@ -103,6 +103,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/wait.h>
|
||||
+#include <linux/device.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include "i2c.h"
|
||||
|
||||
@@ -185,6 +186,9 @@
|
||||
};
|
||||
|
||||
/* eeprom init call. Probes for different eeprom models. */
|
||||
+#ifdef CONFIG_SYSFS
|
||||
+static struct class *eep_class;
|
||||
+#endif
|
||||
|
||||
int __init eeprom_init(void)
|
||||
{
|
||||
@@ -202,7 +206,13 @@
|
||||
eeprom_name, EEPROM_MAJOR_NR);
|
||||
return -1;
|
||||
}
|
||||
-
|
||||
+
|
||||
+#ifdef CONFIG_SYSFS
|
||||
+ eep_class = class_create(THIS_MODULE, "eep");
|
||||
+ class_device_create(eep_class, NULL, MKDEV(EEPROM_MAJOR, 0), NULL, "eeprom");
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
printk("EEPROM char device v0.3, (c) 2000 Axis Communications AB\n");
|
||||
|
||||
/*
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/gpio.c linux-2.6.19.2/arch/cris/arch-v10/drivers/gpio.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/gpio.c 2007-05-28 22:35:23.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/drivers/gpio.c 2007-05-28 22:59:27.000000000 +0200
|
||||
@@ -181,6 +181,7 @@
|
||||
#include <linux/poll.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
+#include <linux/device.h>
|
||||
|
||||
#include <asm/etraxgpio.h>
|
||||
#include <asm/arch/svinto.h>
|
||||
@@ -938,6 +939,10 @@
|
||||
|
||||
/* main driver initialization routine, called from mem.c */
|
||||
|
||||
+#ifdef CONFIG_SYSFS
|
||||
+static struct class *gpio_class;
|
||||
+#endif
|
||||
+
|
||||
static __init int
|
||||
gpio_init(void)
|
||||
{
|
||||
@@ -955,6 +960,14 @@
|
||||
return res;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SYSFS
|
||||
+ gpio_class = class_create(THIS_MODULE, "gpio");
|
||||
+ class_device_create(gpio_class, NULL, MKDEV(GPIO_MAJOR, 0), NULL, "gpioa");
|
||||
+ class_device_create(gpio_class, NULL, MKDEV(GPIO_MAJOR, 1), NULL, "gpiob");
|
||||
+ class_device_create(gpio_class, NULL, MKDEV(GPIO_MAJOR, 2), NULL, "leds");
|
||||
+ class_device_create(gpio_class, NULL, MKDEV(GPIO_MAJOR, 3), NULL, "gpiog");
|
||||
+#endif
|
||||
+
|
||||
/* Clear all leds */
|
||||
#if defined (CONFIG_ETRAX_CSP0_LEDS) || defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
|
||||
LED_NETWORK_SET(0);
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/pcf8563.c linux-2.6.19.2/arch/cris/arch-v10/drivers/pcf8563.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/pcf8563.c 2007-05-28 22:35:23.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/drivers/pcf8563.c 2007-05-28 23:09:02.000000000 +0200
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/bcd.h>
|
||||
+#include <linux/device.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/system.h>
|
||||
@@ -344,6 +345,10 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SYSFS
|
||||
+static struct class *pcf8563_class;
|
||||
+#endif
|
||||
+
|
||||
static int __init
|
||||
pcf8563_register(void)
|
||||
{
|
||||
@@ -358,6 +363,10 @@
|
||||
"device.\n", PCF8563_NAME, PCF8563_MAJOR);
|
||||
return -1;
|
||||
}
|
||||
+#ifdef CONFIG_SYSFS
|
||||
+ pcf8563_class = class_create(THIS_MODULE, "pcf8563");
|
||||
+ class_device_create(pcf8563_class, NULL, MKDEV(PCF8563_MAJOR, 0), NULL, "rtc");
|
||||
+#endif
|
||||
|
||||
printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
|
||||
DRIVER_VERSION);
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/sync_serial.c linux-2.6.19.2/arch/cris/arch-v10/drivers/sync_serial.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/sync_serial.c 2007-05-28 22:35:23.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/drivers/sync_serial.c 2007-05-28 23:06:41.000000000 +0200
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/sync_serial.h>
|
||||
+#include <linux/device.h>
|
||||
+
|
||||
#include <asm/arch/io_interface_mux.h>
|
||||
|
||||
/* The receiver is a bit tricky beacuse of the continuous stream of data.*/
|
||||
@@ -241,6 +243,9 @@
|
||||
.open = sync_serial_open,
|
||||
.release = sync_serial_release
|
||||
};
|
||||
+#ifdef CONFIG_SYSFS
|
||||
+static struct class *syncser_class;
|
||||
+#endif
|
||||
|
||||
static int __init etrax_sync_serial_init(void)
|
||||
{
|
||||
@@ -274,6 +279,11 @@
|
||||
printk("unable to get major for synchronous serial port\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
+#ifdef CONFIG_SYSFS
|
||||
+ syncser_class = class_create(THIS_MODULE, "syncser");
|
||||
+ class_device_create(syncser_class, NULL, MKDEV(SYNC_SERIAL_MAJOR, 0), NULL, "syncser0");
|
||||
+ class_device_create(syncser_class, NULL, MKDEV(SYNC_SERIAL_MAJOR, 1), NULL, "syncser1");
|
||||
+#endif
|
||||
|
||||
/* Deselect synchronous serial ports while configuring. */
|
||||
SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
|
||||
102
target/linux/etrax/patches/cris/014-partition-tables.patch
Normal file
102
target/linux/etrax/patches/cris/014-partition-tables.patch
Normal file
@@ -0,0 +1,102 @@
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/hw_settings.S linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings.S
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/hw_settings.S 2007-05-29 23:30:35.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings.S 2007-05-29 23:33:44.000000000 +0200
|
||||
@@ -60,3 +60,5 @@
|
||||
.dword R_PORT_PB_SET
|
||||
.dword PB_SET_VALUE
|
||||
.dword 0 ; No more register values
|
||||
+ .ascii "ACME_PART_MAGIC" ; Magic number
|
||||
+ .dword 0xdeadc0de
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/hw_settings_416.S linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_416.S
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/hw_settings_416.S 2007-05-29 23:30:35.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_416.S 2007-05-29 23:33:44.000000000 +0200
|
||||
@@ -60,3 +60,5 @@
|
||||
.dword R_PORT_PB_SET
|
||||
.dword PB_SET_VALUE
|
||||
.dword 0 ; No more register values
|
||||
+ .ascii "ACME_PART_MAGIC" ; Magic number
|
||||
+ .dword 0xdeadc0de
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/hw_settings_816.S linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_816.S
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/hw_settings_816.S 2007-05-29 23:30:35.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_816.S 2007-05-29 23:33:44.000000000 +0200
|
||||
@@ -60,3 +60,5 @@
|
||||
.dword R_PORT_PB_SET
|
||||
.dword PB_SET_VALUE
|
||||
.dword 0 ; No more register values
|
||||
+ .ascii "ACME_PART_MAGIC" ; Magic number
|
||||
+ .dword 0xdeadc0de
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/hw_settings_832.S linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_832.S
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/hw_settings_832.S 2007-05-29 23:30:35.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_832.S 2007-05-29 23:33:44.000000000 +0200
|
||||
@@ -60,3 +60,5 @@
|
||||
.dword R_PORT_PB_SET
|
||||
.dword PB_SET_VALUE
|
||||
.dword 0 ; No more register values
|
||||
+ .ascii "ACME_PART_MAGIC" ; Magic number
|
||||
+ .dword 0xdeadc0de
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/hw_settings_MCM.S linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_MCM.S
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/boot/compressed/hw_settings_MCM.S 2007-05-29 23:30:35.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_MCM.S 2007-05-29 23:33:44.000000000 +0200
|
||||
@@ -60,3 +60,5 @@
|
||||
.dword R_PORT_PB_SET
|
||||
.dword PB_SET_VALUE
|
||||
.dword 0 ; No more register values
|
||||
+ .ascii "ACME_PART_MAGIC" ; Magic number
|
||||
+ .dword 0xdeadc0de
|
||||
diff -urN linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/axisflashmap.c linux-2.6.19.2/arch/cris/arch-v10/drivers/axisflashmap.c
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/axisflashmap.c 2007-05-29 23:30:36.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/drivers/axisflashmap.c 2007-05-29 23:36:31.000000000 +0200
|
||||
@@ -421,6 +421,11 @@
|
||||
struct partitiontable_entry *ptable;
|
||||
int use_default_ptable = 1; /* Until proven otherwise. */
|
||||
const char pmsg[] = " /dev/flash%d at 0x%08x, size 0x%08x\n";
|
||||
+ unsigned int kernel_part_size = 0;
|
||||
+ unsigned char *flash_mem = (unsigned char*)(FLASH_CACHED_ADDR);
|
||||
+ unsigned int flash_scan_count = 0;
|
||||
+ const char *part_magic = "ACME_PART_MAGIC";
|
||||
+ unsigned int magic_len = strlen(part_magic);
|
||||
|
||||
if (!(mymtd = flash_probe())) {
|
||||
/* There's no reason to use this module if no flash chip can
|
||||
@@ -432,6 +437,32 @@
|
||||
mymtd->name, mymtd->size);
|
||||
axisflash_mtd = mymtd;
|
||||
}
|
||||
+ /* scan flash to findout where out partition starts */
|
||||
+
|
||||
+ printk(KERN_INFO "Scanning flash for end of kernel magic\n");
|
||||
+ for(flash_scan_count = 0; flash_scan_count < 100000; flash_scan_count++){
|
||||
+ if(strncmp(&flash_mem[flash_scan_count], part_magic, magic_len - 1) == 0){
|
||||
+ //printk(KERN_INFO "Found end of kernel magic at 0x%.08X\n", flash_scan_count);
|
||||
+ kernel_part_size = flash_mem[flash_scan_count + magic_len ];
|
||||
+ kernel_part_size <<= 8;
|
||||
+ kernel_part_size += flash_mem[flash_scan_count + magic_len + 2];
|
||||
+ kernel_part_size <<= 8;
|
||||
+ kernel_part_size += flash_mem[flash_scan_count + magic_len + 1];
|
||||
+ kernel_part_size <<= 8;
|
||||
+ kernel_part_size += flash_mem[flash_scan_count + magic_len + 3];
|
||||
+ printk(KERN_INFO "Kernel ends at 0x%.08X\n", kernel_part_size);
|
||||
+ flash_scan_count = 1100000;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if(kernel_part_size){
|
||||
+ kernel_part_size = (kernel_part_size & 0xffff0000);
|
||||
+ //printk(KERN_INFO "Configuring partition sizes total flash 0x%.08X - kernel 0x%.08X - rootfs 0x%.08X\n", mymtd->size, kernel_part_size, mymtd->size - kernel_part_size);
|
||||
+ axis_default_partitions[0].size = kernel_part_size;
|
||||
+ axis_default_partitions[1].size = mymtd->size - axis_default_partitions[0].size;
|
||||
+ axis_default_partitions[1].offset = axis_default_partitions[0].size;
|
||||
+ }
|
||||
|
||||
if (mymtd) {
|
||||
mymtd->owner = THIS_MODULE;
|
||||
@@ -527,7 +558,7 @@
|
||||
|
||||
if (mymtd) {
|
||||
if (use_default_ptable) {
|
||||
- printk(KERN_INFO " Using default partition table.\n");
|
||||
+ printk(KERN_INFO " Using ACME partition table.\n");
|
||||
err = add_mtd_partitions(mymtd, axis_default_partitions,
|
||||
NUM_DEFAULT_PARTITIONS);
|
||||
} else {
|
||||
13
target/linux/etrax/patches/cris/015-samsung-flash-chip.patch
Normal file
13
target/linux/etrax/patches/cris/015-samsung-flash-chip.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff -urN linux-2.6.19.2.orig/drivers/mtd/chips/cfi_cmdset_0002.c linux-2.6.19.2/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
--- linux-2.6.19.2.orig/drivers/mtd/chips/cfi_cmdset_0002.c 2007-05-30 21:23:01.000000000 +0200
|
||||
+++ linux-2.6.19.2/drivers/mtd/chips/cfi_cmdset_0002.c 2007-05-30 21:38:13.000000000 +0200
|
||||
@@ -291,8 +291,7 @@
|
||||
kfree(mtd);
|
||||
return NULL;
|
||||
}
|
||||
-
|
||||
- if (extp->MajorVersion != '1' ||
|
||||
+ if (extp->MajorVersion < '0' || extp->MajorVersion > '3' ||
|
||||
(extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
|
||||
if (cfi->mfr == MANUFACTURER_SAMSUNG &&
|
||||
(extp->MajorVersion == '3' && extp->MinorVersion == '3')) {
|
||||
101
target/linux/etrax/patches/cris/016-auto-detect-ram.patch
Normal file
101
target/linux/etrax/patches/cris/016-auto-detect-ram.patch
Normal file
@@ -0,0 +1,101 @@
|
||||
diff -urN linux-2.6.19.2//arch/cris/arch-v10/boot/compressed/hw_settings.S /tmp/linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings.S
|
||||
--- linux-2.6.19.2//arch/cris/arch-v10/boot/compressed/hw_settings.S 2007-06-01 00:37:57.000000000 +0200
|
||||
+++ /tmp/linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings.S 2007-06-01 00:34:55.000000000 +0200
|
||||
@@ -62,3 +62,5 @@
|
||||
.dword 0 ; No more register values
|
||||
.ascii "ACME_PART_MAGIC" ; Magic number
|
||||
.dword 0xdeadc0de
|
||||
+ .ascii "ACME_RAM_MAGIC" ; Magic number
|
||||
+ .dword 0x2000000
|
||||
diff -urN linux-2.6.19.2//arch/cris/arch-v10/boot/compressed/hw_settings_416.S /tmp/linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_416.S
|
||||
--- linux-2.6.19.2//arch/cris/arch-v10/boot/compressed/hw_settings_416.S 2007-06-01 00:37:57.000000000 +0200
|
||||
+++ /tmp/linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_416.S 2007-06-01 00:34:55.000000000 +0200
|
||||
@@ -62,3 +62,5 @@
|
||||
.dword 0 ; No more register values
|
||||
.ascii "ACME_PART_MAGIC" ; Magic number
|
||||
.dword 0xdeadc0de
|
||||
+ .ascii "ACME_RAM_MAGIC" ; Magic number
|
||||
+ .dword 0x1000000
|
||||
diff -urN linux-2.6.19.2//arch/cris/arch-v10/boot/compressed/hw_settings_816.S /tmp/linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_816.S
|
||||
--- linux-2.6.19.2//arch/cris/arch-v10/boot/compressed/hw_settings_816.S 2007-06-01 00:37:57.000000000 +0200
|
||||
+++ /tmp/linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_816.S 2007-06-01 00:34:55.000000000 +0200
|
||||
@@ -62,3 +62,5 @@
|
||||
.dword 0 ; No more register values
|
||||
.ascii "ACME_PART_MAGIC" ; Magic number
|
||||
.dword 0xdeadc0de
|
||||
+ .ascii "ACME_RAM_MAGIC" ; Magic number
|
||||
+ .dword 0x1000000
|
||||
diff -urN linux-2.6.19.2//arch/cris/arch-v10/boot/compressed/hw_settings_832.S /tmp/linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_832.S
|
||||
--- linux-2.6.19.2//arch/cris/arch-v10/boot/compressed/hw_settings_832.S 2007-06-01 00:37:57.000000000 +0200
|
||||
+++ /tmp/linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_832.S 2007-06-01 00:34:55.000000000 +0200
|
||||
@@ -62,3 +62,5 @@
|
||||
.dword 0 ; No more register values
|
||||
.ascii "ACME_PART_MAGIC" ; Magic number
|
||||
.dword 0xdeadc0de
|
||||
+ .ascii "ACME_RAM_MAGIC" ; Magic number
|
||||
+ .dword 0x2000000
|
||||
diff -urN linux-2.6.19.2//arch/cris/arch-v10/boot/compressed/hw_settings_MCM.S /tmp/linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_MCM.S
|
||||
--- linux-2.6.19.2//arch/cris/arch-v10/boot/compressed/hw_settings_MCM.S 2007-06-01 00:37:57.000000000 +0200
|
||||
+++ /tmp/linux-2.6.19.2/arch/cris/arch-v10/boot/compressed/hw_settings_MCM.S 2007-06-01 00:34:55.000000000 +0200
|
||||
@@ -62,3 +62,5 @@
|
||||
.dword 0 ; No more register values
|
||||
.ascii "ACME_PART_MAGIC" ; Magic number
|
||||
.dword 0xdeadc0de
|
||||
+ .ascii "ACME_RAM_MAGIC" ; Magic number
|
||||
+ .dword 0x1000000
|
||||
--- linux-2.6.19.2//arch/cris/kernel/setup.c 2007-06-01 00:37:55.000000000 +0200
|
||||
+++ /tmp/linux-2.6.19.2/arch/cris/kernel/setup.c 2007-06-01 00:34:55.000000000 +0200
|
||||
@@ -55,6 +55,13 @@
|
||||
* boot code and the system.
|
||||
*
|
||||
*/
|
||||
+#ifdef CONFIG_CRIS_LOW_MAP
|
||||
+#define FLASH_UNCACHED_ADDR KSEG_8
|
||||
+#define FLASH_CACHED_ADDR KSEG_5
|
||||
+#else
|
||||
+#define FLASH_UNCACHED_ADDR KSEG_E
|
||||
+#define FLASH_CACHED_ADDR KSEG_F
|
||||
+#endif
|
||||
|
||||
void __init
|
||||
setup_arch(char **cmdline_p)
|
||||
@@ -63,15 +70,37 @@
|
||||
unsigned long bootmap_size;
|
||||
unsigned long start_pfn, max_pfn;
|
||||
unsigned long memory_start;
|
||||
-
|
||||
+ unsigned int ram_size = 0;
|
||||
+ unsigned char *flash_mem = (unsigned char*)(FLASH_CACHED_ADDR);
|
||||
+ unsigned int ram_scan_count = 0;
|
||||
+ const char *ram_magic = "ACME_RAM_MAGIC";
|
||||
+ unsigned int magic_len = strlen(ram_magic);
|
||||
+ unsigned long dend;
|
||||
/* register an initial console printing routine for printk's */
|
||||
|
||||
init_etrax_debug();
|
||||
|
||||
/* we should really poll for DRAM size! */
|
||||
+ printk(KERN_INFO "Determinig RAM size\n");
|
||||
+ for(ram_scan_count = 0; ram_scan_count < 100000; ram_scan_count++){
|
||||
+ if(strncmp(&flash_mem[ram_scan_count], ram_magic, magic_len - 1) == 0){
|
||||
+ ram_size = flash_mem[ram_scan_count + magic_len ];
|
||||
+ ram_size <<= 8;
|
||||
+ ram_size += flash_mem[ram_scan_count + magic_len + 2];
|
||||
+ ram_size <<= 8;
|
||||
+ ram_size += flash_mem[ram_scan_count + magic_len + 1];
|
||||
+ ram_size <<= 8;
|
||||
+ ram_size += flash_mem[ram_scan_count + magic_len + 3];
|
||||
+ printk(KERN_INFO "RAM size is %uMB\n", 16 * ram_size);
|
||||
+ ram_scan_count = 1100000;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
high_memory = &dram_end;
|
||||
-
|
||||
+ dend = dram_start + 16 * 1024 * 1024 * ram_size;
|
||||
+ if(ram_size == 1){
|
||||
+ high_memory = 0xc1000000;
|
||||
+ }
|
||||
if(romfs_in_flash || !romfs_length) {
|
||||
/* if we have the romfs in flash, or if there is no rom filesystem,
|
||||
* our free area starts directly after the BSS
|
||||
50
target/linux/etrax/patches/cris/017-uclibc-swab.patch
Normal file
50
target/linux/etrax/patches/cris/017-uclibc-swab.patch
Normal file
@@ -0,0 +1,50 @@
|
||||
Binary files linux-2.6.19.2.orig/include/linux/byteorder/.swab.h.swp and linux-2.6.19.2/include/linux/byteorder/.swab.h.swp differ
|
||||
diff -urN linux-2.6.19.2.orig/include/linux/byteorder/swab.h linux-2.6.19.2/include/linux/byteorder/swab.h
|
||||
--- linux-2.6.19.2.orig/include/linux/byteorder/swab.h 2007-06-02 03:13:27.000000000 +0200
|
||||
+++ linux-2.6.19.2/include/linux/byteorder/swab.h 2007-06-02 03:14:52.000000000 +0200
|
||||
@@ -20,6 +20,8 @@
|
||||
/* casts are necessary for constants, because we never know how for sure
|
||||
* how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
|
||||
*/
|
||||
+
|
||||
+#ifndef _BITS_BYTESWAP_H
|
||||
#define ___swab16(x) \
|
||||
({ \
|
||||
__u16 __x = (x); \
|
||||
@@ -37,6 +39,8 @@
|
||||
(((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
|
||||
(((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
|
||||
})
|
||||
+#endif
|
||||
+
|
||||
|
||||
#define ___swab64(x) \
|
||||
({ \
|
||||
@@ -129,11 +133,13 @@
|
||||
# define __swab64(x) __fswab64(x)
|
||||
#endif /* OPTIMIZE */
|
||||
|
||||
-
|
||||
+#ifndef _BITS_BYTESWAP_H
|
||||
static __inline__ __attribute_const__ __u16 __fswab16(__u16 x)
|
||||
{
|
||||
return __arch__swab16(x);
|
||||
}
|
||||
+#endif
|
||||
+
|
||||
static __inline__ __u16 __swab16p(const __u16 *x)
|
||||
{
|
||||
return __arch__swab16p(x);
|
||||
@@ -143,10 +149,12 @@
|
||||
__arch__swab16s(addr);
|
||||
}
|
||||
|
||||
+#ifndef _BITS_BYTESWAP_H
|
||||
static __inline__ __attribute_const__ __u32 __fswab32(__u32 x)
|
||||
{
|
||||
return __arch__swab32(x);
|
||||
}
|
||||
+#endif
|
||||
static __inline__ __u32 __swab32p(const __u32 *x)
|
||||
{
|
||||
return __arch__swab32p(x);
|
||||
10
target/linux/etrax/patches/cris/018-reboot.patch
Normal file
10
target/linux/etrax/patches/cris/018-reboot.patch
Normal file
@@ -0,0 +1,10 @@
|
||||
--- linux-2.6.19.2.orig/kernel/sys.c 2007-06-04 22:00:44.000000000 +0200
|
||||
+++ linux-2.6.19.2/kernel/sys.c 2007-06-04 22:02:06.000000000 +0200
|
||||
@@ -829,6 +829,7 @@
|
||||
break;
|
||||
|
||||
case LINUX_REBOOT_CMD_CAD_ON:
|
||||
+ kernel_restart(NULL);
|
||||
C_A_D = 1;
|
||||
break;
|
||||
|
||||
166
target/linux/etrax/patches/cris/020-syscalls.patch
Normal file
166
target/linux/etrax/patches/cris/020-syscalls.patch
Normal file
@@ -0,0 +1,166 @@
|
||||
diff -urN linux-2.6.19.2.orig/include/asm-cris/unistd.h linux-2.6.19.2/include/asm/unistd.h
|
||||
--- linux-2.6.19.2.orig/include/asm-cris/unistd.h 2007-06-16 23:59:11.000000000 +0200
|
||||
+++ linux-2.6.19.2/include/asm/unistd.h 2007-06-17 03:43:10.000000000 +0200
|
||||
@@ -325,9 +325,52 @@
|
||||
#define __NR_getcpu 318
|
||||
#define __NR_epoll_pwait 319
|
||||
|
||||
+#ifdef CONFIG_ETRAX_GPIO
|
||||
+ #ifdef CONFIG_FOXBONE
|
||||
+ #define __NR_gpiosetbits 320
|
||||
+ #define __NR_gpioclearbits 321
|
||||
+ #define __NR_gpiosetdir 322
|
||||
+ #define __NR_gpiotogglebit 323
|
||||
+ #define __NR_gpiogetbits 324
|
||||
+ #define __NR_foxboneread 325
|
||||
+ #define __NR_foxbonewrite 326
|
||||
+ #define __NR_foxbonebulkread 327
|
||||
+ #define __NR_foxbonebulkwrite 328
|
||||
+ #define __NR_foxbonereset 329
|
||||
+ #define __NR_foxboneintreg 330
|
||||
+ #define __NR_foxboneintcheck 331
|
||||
+ #define __NR_foxboneintwait 332
|
||||
+ #define NR_syscalls 333
|
||||
+
|
||||
+ #else
|
||||
+ #define __NR_gpiosetbits 320
|
||||
+ #define __NR_gpioclearbits 321
|
||||
+ #define __NR_gpiosetdir 322
|
||||
+ #define __NR_gpiotogglebit 323
|
||||
+ #define __NR_gpiogetbits 324
|
||||
+
|
||||
+ #define NR_syscalls 325
|
||||
+ #endif
|
||||
+#else
|
||||
+ #ifdef CONFIG_FOXBONE
|
||||
+ #define __NR_foxboneread 320
|
||||
+ #define __NR_foxbonewrite 321
|
||||
+ #define __NR_foxbonebulkread 322
|
||||
+ #define __NR_foxbonebulkwrite 323
|
||||
+ #define __NR_foxboneintreg 324
|
||||
+ #define __NR_foxboneintcheck 325
|
||||
+ #define __NR_foxboneintwait 326
|
||||
+
|
||||
+ #define NR_syscalls 327
|
||||
+
|
||||
+ #else
|
||||
+
|
||||
+ #define NR_syscalls 320
|
||||
+ #endif
|
||||
+#endif
|
||||
+
|
||||
#ifdef __KERNEL__
|
||||
|
||||
-#define NR_syscalls 320
|
||||
|
||||
#include <asm/arch/unistd.h>
|
||||
|
||||
--- linux-2.6.19.2.orig/include/linux/gpio_syscalls.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.2/include/linux/gpio_syscalls.h 2007-06-17 03:44:49.000000000 +0200
|
||||
@@ -0,0 +1,75 @@
|
||||
+#ifndef __LINUX_SYSCALL_GPIO
|
||||
+#define __LINUX_SYSCALL_GPIO
|
||||
+#include <linux/autoconf.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <asm/unistd.h>
|
||||
+
|
||||
+// port defines
|
||||
+#define PORTA 'A'
|
||||
+#define PORTB 'B'
|
||||
+#define PORTG 'G'
|
||||
+
|
||||
+//direction defines
|
||||
+#define DIRIN 'I'
|
||||
+#define DIROUT 'O'
|
||||
+
|
||||
+// pin defines for PORTG
|
||||
+#define PG0 (1<<0)
|
||||
+#define PG1 (1<<1)
|
||||
+#define PG2 (1<<2)
|
||||
+#define PG3 (1<<3)
|
||||
+#define PG4 (1<<4)
|
||||
+#define PG5 (1<<5)
|
||||
+#define PG6 (1<<6)
|
||||
+#define PG7 (1<<7)
|
||||
+#define PG8 (1<<8)
|
||||
+#define PG9 (1<<9)
|
||||
+#define PG10 (1<<10)
|
||||
+#define PG11 (1<<11)
|
||||
+#define PG12 (1<<12)
|
||||
+#define PG13 (1<<13)
|
||||
+#define PG14 (1<<14)
|
||||
+#define PG15 (1<<15)
|
||||
+#define PG16 (1<<16)
|
||||
+#define PG17 (1<<17)
|
||||
+#define PG18 (1<<18)
|
||||
+#define PG19 (1<<19)
|
||||
+#define PG20 (1<<20)
|
||||
+#define PG21 (1<<21)
|
||||
+#define PG22 (1<<22)
|
||||
+#define PG23 (1<<23)
|
||||
+#define PG24 (1<<24)
|
||||
+
|
||||
+#define PG8_15 0x00ff00
|
||||
+#define PG16_23 0xff0000
|
||||
+
|
||||
+
|
||||
+// pin defines for PORTA
|
||||
+#define PA0 (1<<0)
|
||||
+#define PA1 (1<<1)
|
||||
+#define PA2 (1<<2)
|
||||
+#define PA3 (1<<3)
|
||||
+#define PA4 (1<<4)
|
||||
+#define PA5 (1<<5)
|
||||
+#define PA6 (1<<6)
|
||||
+#define PA7 (1<<7)
|
||||
+
|
||||
+// pin defines for PORTB
|
||||
+#define PB0 (1<<0)
|
||||
+#define PB1 (1<<1)
|
||||
+#define PB2 (1<<2)
|
||||
+#define PB3 (1<<3)
|
||||
+#define PB4 (1<<4)
|
||||
+#define PB5 (1<<5)
|
||||
+#define PB6 (1<<6)
|
||||
+#define PB7 (1<<7)
|
||||
+
|
||||
+int errno;
|
||||
+_syscall2(void, gpiosetbits, unsigned char, port, unsigned int, bits);
|
||||
+_syscall2(void, gpioclearbits, unsigned char, port, unsigned int, bits);
|
||||
+_syscall3(void, gpiosetdir, unsigned char, port, unsigned char, dir, unsigned int, bits);
|
||||
+_syscall2(void, gpiotogglebit, unsigned char, port, unsigned int, bits);
|
||||
+_syscall2(unsigned int, gpiogetbits, unsigned char, port, unsigned int, bits);
|
||||
+
|
||||
+#endif
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/kernel/entry.S 2007-06-16 23:58:14.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/kernel/entry.S 2007-06-17 03:48:21.000000000 +0200
|
||||
@@ -1200,6 +1200,23 @@
|
||||
.long sys_move_pages
|
||||
.long sys_getcpu
|
||||
.long sys_epoll_pwait
|
||||
+#ifdef CONFIG_ETRAX_GPIO
|
||||
+ .long sys_gpiosetbits
|
||||
+ .long sys_gpioclearbits
|
||||
+ .long sys_gpiosetdir
|
||||
+ .long sys_gpiotogglebit
|
||||
+ .long sys_gpiogetbits
|
||||
+#endif
|
||||
+#ifdef CONFIG_FOXBONE
|
||||
+ .long sys_foxboneread
|
||||
+ .long sys_foxbonewrite
|
||||
+ .long sys_foxbonebulkread
|
||||
+ .long sys_foxbonebulkwrite
|
||||
+ .long sys_foxbonereset
|
||||
+ .long sys_foxboneintreg
|
||||
+ .long sys_foxboneintcheck
|
||||
+ .long sys_foxboneintwait
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* NOTE!! This doesn't have to be exact - we just have
|
||||
diff linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/Makefile linux-2.6.19.2/arch/cris/arch-v10/drivers/Makefile
|
||||
--- linux-2.6.19.2.orig/arch/cris/arch-v10/drivers/Makefile 2007-06-16 23:58:14.000000000 +0200
|
||||
+++ linux-2.6.19.2/arch/cris/arch-v10/drivers/Makefile 2007-06-17 03:48:21.000000000 +0200
|
||||
8a9
|
||||
> obj-$(CONFIG_ETRAX_GPIO) += gpio_syscalls.o
|
||||
4170
target/linux/etrax/patches/generic_2.6/001-squashfs.patch
Normal file
4170
target/linux/etrax/patches/generic_2.6/001-squashfs.patch
Normal file
File diff suppressed because it is too large
Load Diff
780
target/linux/etrax/patches/generic_2.6/002-lzma_decompress.patch
Normal file
780
target/linux/etrax/patches/generic_2.6/002-lzma_decompress.patch
Normal file
@@ -0,0 +1,780 @@
|
||||
--- linux-2.6.19.old/lib/Makefile 2007-04-18 17:41:22.679403384 +0200
|
||||
+++ linux-2.6.19.dev/lib/Makefile 2007-04-18 17:41:43.303268080 +0200
|
||||
@@ -54,6 +54,7 @@
|
||||
obj-$(CONFIG_AUDIT_GENERIC) += audit.o
|
||||
|
||||
obj-$(CONFIG_SWIOTLB) += swiotlb.o
|
||||
+obj-y += LzmaDecode.o
|
||||
|
||||
hostprogs-y := gen_crc32table
|
||||
clean-files := crc32table.h
|
||||
--- linux-2.6.19.old/lib/LzmaDecode.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/lib/LzmaDecode.c 2006-12-14 03:13:20.000000000 +0100
|
||||
@@ -0,0 +1,663 @@
|
||||
+/*
|
||||
+ LzmaDecode.c
|
||||
+ LZMA Decoder
|
||||
+
|
||||
+ LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25)
|
||||
+ http://www.7-zip.org/
|
||||
+
|
||||
+ LZMA SDK is licensed under two licenses:
|
||||
+ 1) GNU Lesser General Public License (GNU LGPL)
|
||||
+ 2) Common Public License (CPL)
|
||||
+ It means that you can select one of these two licenses and
|
||||
+ follow rules of that license.
|
||||
+
|
||||
+ SPECIAL EXCEPTION:
|
||||
+ Igor Pavlov, as the author of this code, expressly permits you to
|
||||
+ statically or dynamically link your code (or bind by name) to the
|
||||
+ interfaces of this file without subjecting your linked code to the
|
||||
+ terms of the CPL or GNU LGPL. Any modifications or additions
|
||||
+ to this file, however, are subject to the LGPL or CPL terms.
|
||||
+*/
|
||||
+
|
||||
+#include <linux/LzmaDecode.h>
|
||||
+
|
||||
+#ifndef Byte
|
||||
+#define Byte unsigned char
|
||||
+#endif
|
||||
+
|
||||
+#define kNumTopBits 24
|
||||
+#define kTopValue ((UInt32)1 << kNumTopBits)
|
||||
+
|
||||
+#define kNumBitModelTotalBits 11
|
||||
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||
+#define kNumMoveBits 5
|
||||
+
|
||||
+typedef struct _CRangeDecoder
|
||||
+{
|
||||
+ Byte *Buffer;
|
||||
+ Byte *BufferLim;
|
||||
+ UInt32 Range;
|
||||
+ UInt32 Code;
|
||||
+ #ifdef _LZMA_IN_CB
|
||||
+ ILzmaInCallback *InCallback;
|
||||
+ int Result;
|
||||
+ #endif
|
||||
+ int ExtraBytes;
|
||||
+} CRangeDecoder;
|
||||
+
|
||||
+Byte RangeDecoderReadByte(CRangeDecoder *rd)
|
||||
+{
|
||||
+ if (rd->Buffer == rd->BufferLim)
|
||||
+ {
|
||||
+ #ifdef _LZMA_IN_CB
|
||||
+ UInt32 size;
|
||||
+ rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
|
||||
+ rd->BufferLim = rd->Buffer + size;
|
||||
+ if (size == 0)
|
||||
+ #endif
|
||||
+ {
|
||||
+ rd->ExtraBytes = 1;
|
||||
+ return 0xFF;
|
||||
+ }
|
||||
+ }
|
||||
+ return (*rd->Buffer++);
|
||||
+}
|
||||
+
|
||||
+/* #define ReadByte (*rd->Buffer++) */
|
||||
+#define ReadByte (RangeDecoderReadByte(rd))
|
||||
+
|
||||
+void RangeDecoderInit(CRangeDecoder *rd,
|
||||
+ #ifdef _LZMA_IN_CB
|
||||
+ ILzmaInCallback *inCallback
|
||||
+ #else
|
||||
+ Byte *stream, UInt32 bufferSize
|
||||
+ #endif
|
||||
+ )
|
||||
+{
|
||||
+ int i;
|
||||
+ #ifdef _LZMA_IN_CB
|
||||
+ rd->InCallback = inCallback;
|
||||
+ rd->Buffer = rd->BufferLim = 0;
|
||||
+ #else
|
||||
+ rd->Buffer = stream;
|
||||
+ rd->BufferLim = stream + bufferSize;
|
||||
+ #endif
|
||||
+ rd->ExtraBytes = 0;
|
||||
+ rd->Code = 0;
|
||||
+ rd->Range = (0xFFFFFFFF);
|
||||
+ for(i = 0; i < 5; i++)
|
||||
+ rd->Code = (rd->Code << 8) | ReadByte;
|
||||
+}
|
||||
+
|
||||
+#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;
|
||||
+#define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
|
||||
+#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }
|
||||
+
|
||||
+UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits)
|
||||
+{
|
||||
+ RC_INIT_VAR
|
||||
+ UInt32 result = 0;
|
||||
+ int i;
|
||||
+ for (i = numTotalBits; i > 0; i--)
|
||||
+ {
|
||||
+ /* UInt32 t; */
|
||||
+ range >>= 1;
|
||||
+
|
||||
+ result <<= 1;
|
||||
+ if (code >= range)
|
||||
+ {
|
||||
+ code -= range;
|
||||
+ result |= 1;
|
||||
+ }
|
||||
+ /*
|
||||
+ t = (code - range) >> 31;
|
||||
+ t &= 1;
|
||||
+ code -= range & (t - 1);
|
||||
+ result = (result + result) | (1 - t);
|
||||
+ */
|
||||
+ RC_NORMALIZE
|
||||
+ }
|
||||
+ RC_FLUSH_VAR
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd)
|
||||
+{
|
||||
+ UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob;
|
||||
+ if (rd->Code < bound)
|
||||
+ {
|
||||
+ rd->Range = bound;
|
||||
+ *prob += (kBitModelTotal - *prob) >> kNumMoveBits;
|
||||
+ if (rd->Range < kTopValue)
|
||||
+ {
|
||||
+ rd->Code = (rd->Code << 8) | ReadByte;
|
||||
+ rd->Range <<= 8;
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ rd->Range -= bound;
|
||||
+ rd->Code -= bound;
|
||||
+ *prob -= (*prob) >> kNumMoveBits;
|
||||
+ if (rd->Range < kTopValue)
|
||||
+ {
|
||||
+ rd->Code = (rd->Code << 8) | ReadByte;
|
||||
+ rd->Range <<= 8;
|
||||
+ }
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#define RC_GET_BIT2(prob, mi, A0, A1) \
|
||||
+ UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
|
||||
+ if (code < bound) \
|
||||
+ { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
|
||||
+ else \
|
||||
+ { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
|
||||
+ RC_NORMALIZE
|
||||
+
|
||||
+#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)
|
||||
+
|
||||
+int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
|
||||
+{
|
||||
+ int mi = 1;
|
||||
+ int i;
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ RC_INIT_VAR
|
||||
+ #endif
|
||||
+ for(i = numLevels; i > 0; i--)
|
||||
+ {
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ CProb *prob = probs + mi;
|
||||
+ RC_GET_BIT(prob, mi)
|
||||
+ #else
|
||||
+ mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd);
|
||||
+ #endif
|
||||
+ }
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ RC_FLUSH_VAR
|
||||
+ #endif
|
||||
+ return mi - (1 << numLevels);
|
||||
+}
|
||||
+
|
||||
+int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
|
||||
+{
|
||||
+ int mi = 1;
|
||||
+ int i;
|
||||
+ int symbol = 0;
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ RC_INIT_VAR
|
||||
+ #endif
|
||||
+ for(i = 0; i < numLevels; i++)
|
||||
+ {
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ CProb *prob = probs + mi;
|
||||
+ RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i))
|
||||
+ #else
|
||||
+ int bit = RangeDecoderBitDecode(probs + mi, rd);
|
||||
+ mi = mi + mi + bit;
|
||||
+ symbol |= (bit << i);
|
||||
+ #endif
|
||||
+ }
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ RC_FLUSH_VAR
|
||||
+ #endif
|
||||
+ return symbol;
|
||||
+}
|
||||
+
|
||||
+Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd)
|
||||
+{
|
||||
+ int symbol = 1;
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ RC_INIT_VAR
|
||||
+ #endif
|
||||
+ do
|
||||
+ {
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ CProb *prob = probs + symbol;
|
||||
+ RC_GET_BIT(prob, symbol)
|
||||
+ #else
|
||||
+ symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
|
||||
+ #endif
|
||||
+ }
|
||||
+ while (symbol < 0x100);
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ RC_FLUSH_VAR
|
||||
+ #endif
|
||||
+ return symbol;
|
||||
+}
|
||||
+
|
||||
+Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte)
|
||||
+{
|
||||
+ int symbol = 1;
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ RC_INIT_VAR
|
||||
+ #endif
|
||||
+ do
|
||||
+ {
|
||||
+ int bit;
|
||||
+ int matchBit = (matchByte >> 7) & 1;
|
||||
+ matchByte <<= 1;
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ {
|
||||
+ CProb *prob = probs + ((1 + matchBit) << 8) + symbol;
|
||||
+ RC_GET_BIT2(prob, symbol, bit = 0, bit = 1)
|
||||
+ }
|
||||
+ #else
|
||||
+ bit = RangeDecoderBitDecode(probs + ((1 + matchBit) << 8) + symbol, rd);
|
||||
+ symbol = (symbol << 1) | bit;
|
||||
+ #endif
|
||||
+ if (matchBit != bit)
|
||||
+ {
|
||||
+ while (symbol < 0x100)
|
||||
+ {
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ CProb *prob = probs + symbol;
|
||||
+ RC_GET_BIT(prob, symbol)
|
||||
+ #else
|
||||
+ symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
|
||||
+ #endif
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ while (symbol < 0x100);
|
||||
+ #ifdef _LZMA_LOC_OPT
|
||||
+ RC_FLUSH_VAR
|
||||
+ #endif
|
||||
+ return symbol;
|
||||
+}
|
||||
+
|
||||
+#define kNumPosBitsMax 4
|
||||
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
|
||||
+
|
||||
+#define kLenNumLowBits 3
|
||||
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
|
||||
+#define kLenNumMidBits 3
|
||||
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
|
||||
+#define kLenNumHighBits 8
|
||||
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
|
||||
+
|
||||
+#define LenChoice 0
|
||||
+#define LenChoice2 (LenChoice + 1)
|
||||
+#define LenLow (LenChoice2 + 1)
|
||||
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
|
||||
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
|
||||
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
|
||||
+
|
||||
+int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState)
|
||||
+{
|
||||
+ if(RangeDecoderBitDecode(p + LenChoice, rd) == 0)
|
||||
+ return RangeDecoderBitTreeDecode(p + LenLow +
|
||||
+ (posState << kLenNumLowBits), kLenNumLowBits, rd);
|
||||
+ if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0)
|
||||
+ return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid +
|
||||
+ (posState << kLenNumMidBits), kLenNumMidBits, rd);
|
||||
+ return kLenNumLowSymbols + kLenNumMidSymbols +
|
||||
+ RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd);
|
||||
+}
|
||||
+
|
||||
+#define kNumStates 12
|
||||
+
|
||||
+#define kStartPosModelIndex 4
|
||||
+#define kEndPosModelIndex 14
|
||||
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
|
||||
+
|
||||
+#define kNumPosSlotBits 6
|
||||
+#define kNumLenToPosStates 4
|
||||
+
|
||||
+#define kNumAlignBits 4
|
||||
+#define kAlignTableSize (1 << kNumAlignBits)
|
||||
+
|
||||
+#define kMatchMinLen 2
|
||||
+
|
||||
+#define IsMatch 0
|
||||
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
|
||||
+#define IsRepG0 (IsRep + kNumStates)
|
||||
+#define IsRepG1 (IsRepG0 + kNumStates)
|
||||
+#define IsRepG2 (IsRepG1 + kNumStates)
|
||||
+#define IsRep0Long (IsRepG2 + kNumStates)
|
||||
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
|
||||
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
|
||||
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
|
||||
+#define LenCoder (Align + kAlignTableSize)
|
||||
+#define RepLenCoder (LenCoder + kNumLenProbs)
|
||||
+#define Literal (RepLenCoder + kNumLenProbs)
|
||||
+
|
||||
+#if Literal != LZMA_BASE_SIZE
|
||||
+StopCompilingDueBUG
|
||||
+#endif
|
||||
+
|
||||
+#ifdef _LZMA_OUT_READ
|
||||
+
|
||||
+typedef struct _LzmaVarState
|
||||
+{
|
||||
+ CRangeDecoder RangeDecoder;
|
||||
+ Byte *Dictionary;
|
||||
+ UInt32 DictionarySize;
|
||||
+ UInt32 DictionaryPos;
|
||||
+ UInt32 GlobalPos;
|
||||
+ UInt32 Reps[4];
|
||||
+ int lc;
|
||||
+ int lp;
|
||||
+ int pb;
|
||||
+ int State;
|
||||
+ int PreviousIsMatch;
|
||||
+ int RemainLen;
|
||||
+} LzmaVarState;
|
||||
+
|
||||
+int LzmaDecoderInit(
|
||||
+ unsigned char *buffer, UInt32 bufferSize,
|
||||
+ int lc, int lp, int pb,
|
||||
+ unsigned char *dictionary, UInt32 dictionarySize,
|
||||
+ #ifdef _LZMA_IN_CB
|
||||
+ ILzmaInCallback *inCallback
|
||||
+ #else
|
||||
+ unsigned char *inStream, UInt32 inSize
|
||||
+ #endif
|
||||
+ )
|
||||
+{
|
||||
+ LzmaVarState *vs = (LzmaVarState *)buffer;
|
||||
+ CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
|
||||
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
|
||||
+ UInt32 i;
|
||||
+ if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState))
|
||||
+ return LZMA_RESULT_NOT_ENOUGH_MEM;
|
||||
+ vs->Dictionary = dictionary;
|
||||
+ vs->DictionarySize = dictionarySize;
|
||||
+ vs->DictionaryPos = 0;
|
||||
+ vs->GlobalPos = 0;
|
||||
+ vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1;
|
||||
+ vs->lc = lc;
|
||||
+ vs->lp = lp;
|
||||
+ vs->pb = pb;
|
||||
+ vs->State = 0;
|
||||
+ vs->PreviousIsMatch = 0;
|
||||
+ vs->RemainLen = 0;
|
||||
+ dictionary[dictionarySize - 1] = 0;
|
||||
+ for (i = 0; i < numProbs; i++)
|
||||
+ p[i] = kBitModelTotal >> 1;
|
||||
+ RangeDecoderInit(&vs->RangeDecoder,
|
||||
+ #ifdef _LZMA_IN_CB
|
||||
+ inCallback
|
||||
+ #else
|
||||
+ inStream, inSize
|
||||
+ #endif
|
||||
+ );
|
||||
+ return LZMA_RESULT_OK;
|
||||
+}
|
||||
+
|
||||
+int LzmaDecode(unsigned char *buffer,
|
||||
+ unsigned char *outStream, UInt32 outSize,
|
||||
+ UInt32 *outSizeProcessed)
|
||||
+{
|
||||
+ LzmaVarState *vs = (LzmaVarState *)buffer;
|
||||
+ CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
|
||||
+ CRangeDecoder rd = vs->RangeDecoder;
|
||||
+ int state = vs->State;
|
||||
+ int previousIsMatch = vs->PreviousIsMatch;
|
||||
+ Byte previousByte;
|
||||
+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
|
||||
+ UInt32 nowPos = 0;
|
||||
+ UInt32 posStateMask = (1 << (vs->pb)) - 1;
|
||||
+ UInt32 literalPosMask = (1 << (vs->lp)) - 1;
|
||||
+ int lc = vs->lc;
|
||||
+ int len = vs->RemainLen;
|
||||
+ UInt32 globalPos = vs->GlobalPos;
|
||||
+
|
||||
+ Byte *dictionary = vs->Dictionary;
|
||||
+ UInt32 dictionarySize = vs->DictionarySize;
|
||||
+ UInt32 dictionaryPos = vs->DictionaryPos;
|
||||
+
|
||||
+ if (len == -1)
|
||||
+ {
|
||||
+ *outSizeProcessed = 0;
|
||||
+ return LZMA_RESULT_OK;
|
||||
+ }
|
||||
+
|
||||
+ while(len > 0 && nowPos < outSize)
|
||||
+ {
|
||||
+ UInt32 pos = dictionaryPos - rep0;
|
||||
+ if (pos >= dictionarySize)
|
||||
+ pos += dictionarySize;
|
||||
+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
|
||||
+ if (++dictionaryPos == dictionarySize)
|
||||
+ dictionaryPos = 0;
|
||||
+ len--;
|
||||
+ }
|
||||
+ if (dictionaryPos == 0)
|
||||
+ previousByte = dictionary[dictionarySize - 1];
|
||||
+ else
|
||||
+ previousByte = dictionary[dictionaryPos - 1];
|
||||
+#else
|
||||
+
|
||||
+int LzmaDecode(
|
||||
+ Byte *buffer, UInt32 bufferSize,
|
||||
+ int lc, int lp, int pb,
|
||||
+ #ifdef _LZMA_IN_CB
|
||||
+ ILzmaInCallback *inCallback,
|
||||
+ #else
|
||||
+ unsigned char *inStream, UInt32 inSize,
|
||||
+ #endif
|
||||
+ unsigned char *outStream, UInt32 outSize,
|
||||
+ UInt32 *outSizeProcessed)
|
||||
+{
|
||||
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
|
||||
+ CProb *p = (CProb *)buffer;
|
||||
+ CRangeDecoder rd;
|
||||
+ UInt32 i;
|
||||
+ int state = 0;
|
||||
+ int previousIsMatch = 0;
|
||||
+ Byte previousByte = 0;
|
||||
+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
|
||||
+ UInt32 nowPos = 0;
|
||||
+ UInt32 posStateMask = (1 << pb) - 1;
|
||||
+ UInt32 literalPosMask = (1 << lp) - 1;
|
||||
+ int len = 0;
|
||||
+ if (bufferSize < numProbs * sizeof(CProb))
|
||||
+ return LZMA_RESULT_NOT_ENOUGH_MEM;
|
||||
+ for (i = 0; i < numProbs; i++)
|
||||
+ p[i] = kBitModelTotal >> 1;
|
||||
+ RangeDecoderInit(&rd,
|
||||
+ #ifdef _LZMA_IN_CB
|
||||
+ inCallback
|
||||
+ #else
|
||||
+ inStream, inSize
|
||||
+ #endif
|
||||
+ );
|
||||
+#endif
|
||||
+
|
||||
+ *outSizeProcessed = 0;
|
||||
+ while(nowPos < outSize)
|
||||
+ {
|
||||
+ int posState = (int)(
|
||||
+ (nowPos
|
||||
+ #ifdef _LZMA_OUT_READ
|
||||
+ + globalPos
|
||||
+ #endif
|
||||
+ )
|
||||
+ & posStateMask);
|
||||
+ #ifdef _LZMA_IN_CB
|
||||
+ if (rd.Result != LZMA_RESULT_OK)
|
||||
+ return rd.Result;
|
||||
+ #endif
|
||||
+ if (rd.ExtraBytes != 0)
|
||||
+ return LZMA_RESULT_DATA_ERROR;
|
||||
+ if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0)
|
||||
+ {
|
||||
+ CProb *probs = p + Literal + (LZMA_LIT_SIZE *
|
||||
+ (((
|
||||
+ (nowPos
|
||||
+ #ifdef _LZMA_OUT_READ
|
||||
+ + globalPos
|
||||
+ #endif
|
||||
+ )
|
||||
+ & literalPosMask) << lc) + (previousByte >> (8 - lc))));
|
||||
+
|
||||
+ if (state < 4) state = 0;
|
||||
+ else if (state < 10) state -= 3;
|
||||
+ else state -= 6;
|
||||
+ if (previousIsMatch)
|
||||
+ {
|
||||
+ Byte matchByte;
|
||||
+ #ifdef _LZMA_OUT_READ
|
||||
+ UInt32 pos = dictionaryPos - rep0;
|
||||
+ if (pos >= dictionarySize)
|
||||
+ pos += dictionarySize;
|
||||
+ matchByte = dictionary[pos];
|
||||
+ #else
|
||||
+ matchByte = outStream[nowPos - rep0];
|
||||
+ #endif
|
||||
+ previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte);
|
||||
+ previousIsMatch = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ previousByte = LzmaLiteralDecode(probs, &rd);
|
||||
+ outStream[nowPos++] = previousByte;
|
||||
+ #ifdef _LZMA_OUT_READ
|
||||
+ dictionary[dictionaryPos] = previousByte;
|
||||
+ if (++dictionaryPos == dictionarySize)
|
||||
+ dictionaryPos = 0;
|
||||
+ #endif
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ previousIsMatch = 1;
|
||||
+ if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1)
|
||||
+ {
|
||||
+ if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0)
|
||||
+ {
|
||||
+ if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0)
|
||||
+ {
|
||||
+ #ifdef _LZMA_OUT_READ
|
||||
+ UInt32 pos;
|
||||
+ #endif
|
||||
+ if (
|
||||
+ (nowPos
|
||||
+ #ifdef _LZMA_OUT_READ
|
||||
+ + globalPos
|
||||
+ #endif
|
||||
+ )
|
||||
+ == 0)
|
||||
+ return LZMA_RESULT_DATA_ERROR;
|
||||
+ state = state < 7 ? 9 : 11;
|
||||
+ #ifdef _LZMA_OUT_READ
|
||||
+ pos = dictionaryPos - rep0;
|
||||
+ if (pos >= dictionarySize)
|
||||
+ pos += dictionarySize;
|
||||
+ previousByte = dictionary[pos];
|
||||
+ dictionary[dictionaryPos] = previousByte;
|
||||
+ if (++dictionaryPos == dictionarySize)
|
||||
+ dictionaryPos = 0;
|
||||
+ #else
|
||||
+ previousByte = outStream[nowPos - rep0];
|
||||
+ #endif
|
||||
+ outStream[nowPos++] = previousByte;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ UInt32 distance;
|
||||
+ if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0)
|
||||
+ distance = rep1;
|
||||
+ else
|
||||
+ {
|
||||
+ if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0)
|
||||
+ distance = rep2;
|
||||
+ else
|
||||
+ {
|
||||
+ distance = rep3;
|
||||
+ rep3 = rep2;
|
||||
+ }
|
||||
+ rep2 = rep1;
|
||||
+ }
|
||||
+ rep1 = rep0;
|
||||
+ rep0 = distance;
|
||||
+ }
|
||||
+ len = LzmaLenDecode(p + RepLenCoder, &rd, posState);
|
||||
+ state = state < 7 ? 8 : 11;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ int posSlot;
|
||||
+ rep3 = rep2;
|
||||
+ rep2 = rep1;
|
||||
+ rep1 = rep0;
|
||||
+ state = state < 7 ? 7 : 10;
|
||||
+ len = LzmaLenDecode(p + LenCoder, &rd, posState);
|
||||
+ posSlot = RangeDecoderBitTreeDecode(p + PosSlot +
|
||||
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
|
||||
+ kNumPosSlotBits), kNumPosSlotBits, &rd);
|
||||
+ if (posSlot >= kStartPosModelIndex)
|
||||
+ {
|
||||
+ int numDirectBits = ((posSlot >> 1) - 1);
|
||||
+ rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
|
||||
+ if (posSlot < kEndPosModelIndex)
|
||||
+ {
|
||||
+ rep0 += RangeDecoderReverseBitTreeDecode(
|
||||
+ p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ rep0 += RangeDecoderDecodeDirectBits(&rd,
|
||||
+ numDirectBits - kNumAlignBits) << kNumAlignBits;
|
||||
+ rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ rep0 = posSlot;
|
||||
+ rep0++;
|
||||
+ }
|
||||
+ if (rep0 == (UInt32)(0))
|
||||
+ {
|
||||
+ /* it's for stream version */
|
||||
+ len = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (rep0 > nowPos
|
||||
+ #ifdef _LZMA_OUT_READ
|
||||
+ + globalPos
|
||||
+ #endif
|
||||
+ )
|
||||
+ {
|
||||
+ return LZMA_RESULT_DATA_ERROR;
|
||||
+ }
|
||||
+ len += kMatchMinLen;
|
||||
+ do
|
||||
+ {
|
||||
+ #ifdef _LZMA_OUT_READ
|
||||
+ UInt32 pos = dictionaryPos - rep0;
|
||||
+ if (pos >= dictionarySize)
|
||||
+ pos += dictionarySize;
|
||||
+ previousByte = dictionary[pos];
|
||||
+ dictionary[dictionaryPos] = previousByte;
|
||||
+ if (++dictionaryPos == dictionarySize)
|
||||
+ dictionaryPos = 0;
|
||||
+ #else
|
||||
+ previousByte = outStream[nowPos - rep0];
|
||||
+ #endif
|
||||
+ outStream[nowPos++] = previousByte;
|
||||
+ len--;
|
||||
+ }
|
||||
+ while(len > 0 && nowPos < outSize);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ #ifdef _LZMA_OUT_READ
|
||||
+ vs->RangeDecoder = rd;
|
||||
+ vs->DictionaryPos = dictionaryPos;
|
||||
+ vs->GlobalPos = globalPos + nowPos;
|
||||
+ vs->Reps[0] = rep0;
|
||||
+ vs->Reps[1] = rep1;
|
||||
+ vs->Reps[2] = rep2;
|
||||
+ vs->Reps[3] = rep3;
|
||||
+ vs->State = state;
|
||||
+ vs->PreviousIsMatch = previousIsMatch;
|
||||
+ vs->RemainLen = len;
|
||||
+ #endif
|
||||
+
|
||||
+ *outSizeProcessed = nowPos;
|
||||
+ return LZMA_RESULT_OK;
|
||||
+}
|
||||
--- linux-2.6.19.old/include/linux/LzmaDecode.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/include/linux/LzmaDecode.h 2006-12-14 03:13:20.000000000 +0100
|
||||
@@ -0,0 +1,100 @@
|
||||
+/*
|
||||
+ LzmaDecode.h
|
||||
+ LZMA Decoder interface
|
||||
+
|
||||
+ LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25)
|
||||
+ http://www.7-zip.org/
|
||||
+
|
||||
+ LZMA SDK is licensed under two licenses:
|
||||
+ 1) GNU Lesser General Public License (GNU LGPL)
|
||||
+ 2) Common Public License (CPL)
|
||||
+ It means that you can select one of these two licenses and
|
||||
+ follow rules of that license.
|
||||
+
|
||||
+ SPECIAL EXCEPTION:
|
||||
+ Igor Pavlov, as the author of this code, expressly permits you to
|
||||
+ statically or dynamically link your code (or bind by name) to the
|
||||
+ interfaces of this file without subjecting your linked code to the
|
||||
+ terms of the CPL or GNU LGPL. Any modifications or additions
|
||||
+ to this file, however, are subject to the LGPL or CPL terms.
|
||||
+*/
|
||||
+
|
||||
+#ifndef __LZMADECODE_H
|
||||
+#define __LZMADECODE_H
|
||||
+
|
||||
+/* #define _LZMA_IN_CB */
|
||||
+/* Use callback for input data */
|
||||
+
|
||||
+/* #define _LZMA_OUT_READ */
|
||||
+/* Use read function for output data */
|
||||
+
|
||||
+/* #define _LZMA_PROB32 */
|
||||
+/* It can increase speed on some 32-bit CPUs,
|
||||
+ but memory usage will be doubled in that case */
|
||||
+
|
||||
+/* #define _LZMA_LOC_OPT */
|
||||
+/* Enable local speed optimizations inside code */
|
||||
+
|
||||
+#ifndef UInt32
|
||||
+#ifdef _LZMA_UINT32_IS_ULONG
|
||||
+#define UInt32 unsigned long
|
||||
+#else
|
||||
+#define UInt32 unsigned int
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
+#ifdef _LZMA_PROB32
|
||||
+#define CProb UInt32
|
||||
+#else
|
||||
+#define CProb unsigned short
|
||||
+#endif
|
||||
+
|
||||
+#define LZMA_RESULT_OK 0
|
||||
+#define LZMA_RESULT_DATA_ERROR 1
|
||||
+#define LZMA_RESULT_NOT_ENOUGH_MEM 2
|
||||
+
|
||||
+#ifdef _LZMA_IN_CB
|
||||
+typedef struct _ILzmaInCallback
|
||||
+{
|
||||
+ int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize);
|
||||
+} ILzmaInCallback;
|
||||
+#endif
|
||||
+
|
||||
+#define LZMA_BASE_SIZE 1846
|
||||
+#define LZMA_LIT_SIZE 768
|
||||
+
|
||||
+/*
|
||||
+bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb)
|
||||
+bufferSize += 100 in case of _LZMA_OUT_READ
|
||||
+by default CProb is unsigned short,
|
||||
+but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int)
|
||||
+*/
|
||||
+
|
||||
+#ifdef _LZMA_OUT_READ
|
||||
+int LzmaDecoderInit(
|
||||
+ unsigned char *buffer, UInt32 bufferSize,
|
||||
+ int lc, int lp, int pb,
|
||||
+ unsigned char *dictionary, UInt32 dictionarySize,
|
||||
+ #ifdef _LZMA_IN_CB
|
||||
+ ILzmaInCallback *inCallback
|
||||
+ #else
|
||||
+ unsigned char *inStream, UInt32 inSize
|
||||
+ #endif
|
||||
+);
|
||||
+#endif
|
||||
+
|
||||
+int LzmaDecode(
|
||||
+ unsigned char *buffer,
|
||||
+ #ifndef _LZMA_OUT_READ
|
||||
+ UInt32 bufferSize,
|
||||
+ int lc, int lp, int pb,
|
||||
+ #ifdef _LZMA_IN_CB
|
||||
+ ILzmaInCallback *inCallback,
|
||||
+ #else
|
||||
+ unsigned char *inStream, UInt32 inSize,
|
||||
+ #endif
|
||||
+ #endif
|
||||
+ unsigned char *outStream, UInt32 outSize,
|
||||
+ UInt32 *outSizeProcessed);
|
||||
+
|
||||
+#endif
|
||||
|
||||
109
target/linux/etrax/patches/generic_2.6/003-squashfs_lzma.patch
Normal file
109
target/linux/etrax/patches/generic_2.6/003-squashfs_lzma.patch
Normal file
@@ -0,0 +1,109 @@
|
||||
diff -urN linux-2.6.19.old/fs/squashfs/inode.c linux-2.6.19.dev/fs/squashfs/inode.c
|
||||
--- linux-2.6.19.old/fs/squashfs/inode.c 2006-12-14 03:13:20.000000000 +0100
|
||||
+++ linux-2.6.19.dev/fs/squashfs/inode.c 2006-12-14 03:13:20.000000000 +0100
|
||||
@@ -4,6 +4,9 @@
|
||||
* Copyright (c) 2002, 2003, 2004, 2005, 2006
|
||||
* Phillip Lougher <phillip@lougher.org.uk>
|
||||
*
|
||||
+ * LZMA decompressor support added by Oleg I. Vdovikin
|
||||
+ * Copyright (c) 2005 Oleg I.Vdovikin <oleg@cs.msu.su>
|
||||
+ *
|
||||
* 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,
|
||||
@@ -21,6 +24,7 @@
|
||||
* inode.c
|
||||
*/
|
||||
|
||||
+#define SQUASHFS_LZMA
|
||||
#include <linux/types.h>
|
||||
#include <linux/squashfs_fs.h>
|
||||
#include <linux/module.h>
|
||||
@@ -44,6 +48,19 @@
|
||||
|
||||
#include "squashfs.h"
|
||||
|
||||
+#ifdef SQUASHFS_LZMA
|
||||
+#include <linux/LzmaDecode.h>
|
||||
+
|
||||
+/* default LZMA settings, should be in sync with mksquashfs */
|
||||
+#define LZMA_LC 3
|
||||
+#define LZMA_LP 0
|
||||
+#define LZMA_PB 2
|
||||
+
|
||||
+#define LZMA_WORKSPACE_SIZE ((LZMA_BASE_SIZE + \
|
||||
+ (LZMA_LIT_SIZE << (LZMA_LC + LZMA_LP))) * sizeof(CProb))
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
static void squashfs_put_super(struct super_block *);
|
||||
static int squashfs_statfs(struct dentry *, struct kstatfs *);
|
||||
static int squashfs_symlink_readpage(struct file *file, struct page *page);
|
||||
@@ -64,7 +81,11 @@
|
||||
const char *, void *, struct vfsmount *);
|
||||
|
||||
|
||||
+#ifdef SQUASHFS_LZMA
|
||||
+static unsigned char lzma_workspace[LZMA_WORKSPACE_SIZE];
|
||||
+#else
|
||||
static z_stream stream;
|
||||
+#endif
|
||||
|
||||
static struct file_system_type squashfs_fs_type = {
|
||||
.owner = THIS_MODULE,
|
||||
@@ -249,6 +270,15 @@
|
||||
if (compressed) {
|
||||
int zlib_err;
|
||||
|
||||
+#ifdef SQUASHFS_LZMA
|
||||
+ if ((zlib_err = LzmaDecode(lzma_workspace,
|
||||
+ LZMA_WORKSPACE_SIZE, LZMA_LC, LZMA_LP, LZMA_PB,
|
||||
+ c_buffer, c_byte, buffer, msblk->read_size, &bytes)) != LZMA_RESULT_OK)
|
||||
+ {
|
||||
+ ERROR("lzma returned unexpected result 0x%x\n", zlib_err);
|
||||
+ bytes = 0;
|
||||
+ }
|
||||
+#else
|
||||
stream.next_in = c_buffer;
|
||||
stream.avail_in = c_byte;
|
||||
stream.next_out = buffer;
|
||||
@@ -263,7 +293,7 @@
|
||||
bytes = 0;
|
||||
} else
|
||||
bytes = stream.total_out;
|
||||
-
|
||||
+#endif
|
||||
up(&msblk->read_data_mutex);
|
||||
}
|
||||
|
||||
@@ -2045,15 +2075,19 @@
|
||||
printk(KERN_INFO "squashfs: version 3.0 (2006/03/15) "
|
||||
"Phillip Lougher\n");
|
||||
|
||||
+#ifndef SQUASHFS_LZMA
|
||||
if (!(stream.workspace = vmalloc(zlib_inflate_workspacesize()))) {
|
||||
ERROR("Failed to allocate zlib workspace\n");
|
||||
destroy_inodecache();
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
+#endif
|
||||
|
||||
if ((err = register_filesystem(&squashfs_fs_type))) {
|
||||
+#ifndef SQUASHFS_LZMA
|
||||
vfree(stream.workspace);
|
||||
+#endif
|
||||
destroy_inodecache();
|
||||
}
|
||||
|
||||
@@ -2064,7 +2098,9 @@
|
||||
|
||||
static void __exit exit_squashfs_fs(void)
|
||||
{
|
||||
+#ifndef SQUASHFS_LZMA
|
||||
vfree(stream.workspace);
|
||||
+#endif
|
||||
unregister_filesystem(&squashfs_fs_type);
|
||||
destroy_inodecache();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
diff -urN linux-2.6.19.old/Makefile linux-2.6.19.dev/Makefile
|
||||
--- linux-2.6.19.old/Makefile 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/Makefile 2006-12-14 03:13:23.000000000 +0100
|
||||
@@ -513,6 +513,9 @@
|
||||
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
|
||||
CHECKFLAGS += $(NOSTDINC_FLAGS)
|
||||
|
||||
+# improve gcc optimization
|
||||
+CFLAGS += $(call cc-option,-funit-at-a-time,)
|
||||
+
|
||||
# warn about C99 declaration after statement
|
||||
CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
diff -urN linux-2.6.19.old/include/asm-mips/system.h linux-2.6.19.dev/include/asm-mips/system.h
|
||||
--- linux-2.6.19.old/include/asm-mips/system.h 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/include/asm-mips/system.h 2006-12-14 03:13:28.000000000 +0100
|
||||
@@ -311,7 +311,7 @@
|
||||
if something tries to do an invalid xchg(). */
|
||||
extern void __xchg_called_with_bad_pointer(void);
|
||||
|
||||
-static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
|
||||
+static __always_inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 4:
|
||||
@@ -0,0 +1,37 @@
|
||||
diff -urN linux-2.6.19.old/drivers/mtd/chips/cfi_cmdset_0002.c linux-2.6.19.dev/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
--- linux-2.6.19.old/drivers/mtd/chips/cfi_cmdset_0002.c 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/drivers/mtd/chips/cfi_cmdset_0002.c 2006-12-14 03:13:30.000000000 +0100
|
||||
@@ -50,6 +50,7 @@
|
||||
#define SST49LF004B 0x0060
|
||||
#define SST49LF008A 0x005a
|
||||
#define AT49BV6416 0x00d6
|
||||
+#define MANUFACTURER_SAMSUNG 0x00ec
|
||||
|
||||
static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
|
||||
static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
|
||||
@@ -293,12 +294,19 @@
|
||||
|
||||
if (extp->MajorVersion != '1' ||
|
||||
(extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
|
||||
- printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
|
||||
- "version %c.%c.\n", extp->MajorVersion,
|
||||
- extp->MinorVersion);
|
||||
- kfree(extp);
|
||||
- kfree(mtd);
|
||||
- return NULL;
|
||||
+ if (cfi->mfr == MANUFACTURER_SAMSUNG &&
|
||||
+ (extp->MajorVersion == '3' && extp->MinorVersion == '3')) {
|
||||
+ printk(KERN_NOTICE " Newer Samsung flash detected, "
|
||||
+ "should be compatibile with Amd/Fujitsu.\n");
|
||||
+ }
|
||||
+ else {
|
||||
+ printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
|
||||
+ "version %c.%c.\n", extp->MajorVersion,
|
||||
+ extp->MinorVersion);
|
||||
+ kfree(extp);
|
||||
+ kfree(mtd);
|
||||
+ return NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Install our own private info structure */
|
||||
@@ -0,0 +1,169 @@
|
||||
--- linux.old/drivers/mtd/chips/cfi_cmdset_0001.c 2007-02-13 02:41:50.816650352 +0100
|
||||
+++ linux.dev/drivers/mtd/chips/cfi_cmdset_0001.c 2007-02-13 02:42:13.782159064 +0100
|
||||
@@ -908,7 +908,7 @@
|
||||
|
||||
static int __xipram xip_wait_for_operation(
|
||||
struct map_info *map, struct flchip *chip,
|
||||
- unsigned long adr, unsigned int chip_op_time )
|
||||
+ unsigned long adr, int *chip_op_time )
|
||||
{
|
||||
struct cfi_private *cfi = map->fldrv_priv;
|
||||
struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
|
||||
@@ -917,7 +917,7 @@
|
||||
flstate_t oldstate, newstate;
|
||||
|
||||
start = xip_currtime();
|
||||
- usec = chip_op_time * 8;
|
||||
+ usec = *chip_op_time * 8;
|
||||
if (usec == 0)
|
||||
usec = 500000;
|
||||
done = 0;
|
||||
@@ -1027,8 +1027,8 @@
|
||||
#define XIP_INVAL_CACHED_RANGE(map, from, size) \
|
||||
INVALIDATE_CACHED_RANGE(map, from, size)
|
||||
|
||||
-#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \
|
||||
- xip_wait_for_operation(map, chip, cmd_adr, usec)
|
||||
+#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, p_usec) \
|
||||
+ xip_wait_for_operation(map, chip, cmd_adr, p_usec)
|
||||
|
||||
#else
|
||||
|
||||
@@ -1040,65 +1040,65 @@
|
||||
static int inval_cache_and_wait_for_operation(
|
||||
struct map_info *map, struct flchip *chip,
|
||||
unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
|
||||
- unsigned int chip_op_time)
|
||||
+ int *chip_op_time )
|
||||
{
|
||||
struct cfi_private *cfi = map->fldrv_priv;
|
||||
map_word status, status_OK = CMD(0x80);
|
||||
- int chip_state = chip->state;
|
||||
- unsigned int timeo, sleep_time;
|
||||
+ int z, chip_state = chip->state;
|
||||
+ unsigned long timeo;
|
||||
|
||||
spin_unlock(chip->mutex);
|
||||
if (inval_len)
|
||||
INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
|
||||
+ if (*chip_op_time)
|
||||
+ cfi_udelay(*chip_op_time);
|
||||
spin_lock(chip->mutex);
|
||||
|
||||
- /* set our timeout to 8 times the expected delay */
|
||||
- timeo = chip_op_time * 8;
|
||||
- if (!timeo)
|
||||
- timeo = 500000;
|
||||
- sleep_time = chip_op_time / 2;
|
||||
+ timeo = *chip_op_time * 8 * HZ / 1000000;
|
||||
+ if (timeo < HZ/2)
|
||||
+ timeo = HZ/2;
|
||||
+ timeo += jiffies;
|
||||
|
||||
+ z = 0;
|
||||
for (;;) {
|
||||
+ if (chip->state != chip_state) {
|
||||
+ /* Someone's suspended the operation: sleep */
|
||||
+ DECLARE_WAITQUEUE(wait, current);
|
||||
+
|
||||
+ set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
+ add_wait_queue(&chip->wq, &wait);
|
||||
+ spin_unlock(chip->mutex);
|
||||
+ schedule();
|
||||
+ remove_wait_queue(&chip->wq, &wait);
|
||||
+ timeo = jiffies + (HZ / 2); /* FIXME */
|
||||
+ spin_lock(chip->mutex);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
status = map_read(map, cmd_adr);
|
||||
if (map_word_andequal(map, status, status_OK, status_OK))
|
||||
break;
|
||||
|
||||
- if (!timeo) {
|
||||
+ /* OK Still waiting */
|
||||
+ if (time_after(jiffies, timeo)) {
|
||||
map_write(map, CMD(0x70), cmd_adr);
|
||||
chip->state = FL_STATUS;
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
- /* OK Still waiting. Drop the lock, wait a while and retry. */
|
||||
+ /* Latency issues. Drop the lock, wait a while and retry */
|
||||
+ z++;
|
||||
spin_unlock(chip->mutex);
|
||||
- if (sleep_time >= 1000000/HZ) {
|
||||
- /*
|
||||
- * Half of the normal delay still remaining
|
||||
- * can be performed with a sleeping delay instead
|
||||
- * of busy waiting.
|
||||
- */
|
||||
- msleep(sleep_time/1000);
|
||||
- timeo -= sleep_time;
|
||||
- sleep_time = 1000000/HZ;
|
||||
- } else {
|
||||
- udelay(1);
|
||||
- cond_resched();
|
||||
- timeo--;
|
||||
- }
|
||||
+ cfi_udelay(1);
|
||||
spin_lock(chip->mutex);
|
||||
-
|
||||
- while (chip->state != chip_state) {
|
||||
- /* Someone's suspended the operation: sleep */
|
||||
- DECLARE_WAITQUEUE(wait, current);
|
||||
- set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
- add_wait_queue(&chip->wq, &wait);
|
||||
- spin_unlock(chip->mutex);
|
||||
- schedule();
|
||||
- remove_wait_queue(&chip->wq, &wait);
|
||||
- spin_lock(chip->mutex);
|
||||
- }
|
||||
}
|
||||
|
||||
+ if (!z) {
|
||||
+ if (!--(*chip_op_time))
|
||||
+ *chip_op_time = 1;
|
||||
+ } else if (z > 1)
|
||||
+ ++(*chip_op_time);
|
||||
+
|
||||
/* Done and happy. */
|
||||
chip->state = FL_STATUS;
|
||||
return 0;
|
||||
@@ -1107,7 +1107,8 @@
|
||||
#endif
|
||||
|
||||
#define WAIT_TIMEOUT(map, chip, adr, udelay) \
|
||||
- INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay);
|
||||
+ ({ int __udelay = (udelay); \
|
||||
+ INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, &__udelay); })
|
||||
|
||||
|
||||
static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
|
||||
@@ -1331,7 +1332,7 @@
|
||||
|
||||
ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
|
||||
adr, map_bankwidth(map),
|
||||
- chip->word_write_time);
|
||||
+ &chip->word_write_time);
|
||||
if (ret) {
|
||||
xip_enable(map, chip, adr);
|
||||
printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
|
||||
@@ -1568,7 +1569,7 @@
|
||||
|
||||
ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
|
||||
adr, len,
|
||||
- chip->buffer_write_time);
|
||||
+ &chip->buffer_write_time);
|
||||
if (ret) {
|
||||
map_write(map, CMD(0x70), cmd_adr);
|
||||
chip->state = FL_STATUS;
|
||||
@@ -1703,7 +1704,7 @@
|
||||
|
||||
ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
|
||||
adr, len,
|
||||
- chip->erase_time);
|
||||
+ &chip->erase_time);
|
||||
if (ret) {
|
||||
map_write(map, CMD(0x70), adr);
|
||||
chip->state = FL_STATUS;
|
||||
@@ -0,0 +1,21 @@
|
||||
diff -urN linux-2.6.19.old/fs/squashfs/Makefile linux-2.6.19.dev/fs/squashfs/Makefile
|
||||
--- linux-2.6.19.old/fs/squashfs/Makefile 2006-12-14 03:13:22.000000000 +0100
|
||||
+++ linux-2.6.19.dev/fs/squashfs/Makefile 2006-12-14 03:13:31.000000000 +0100
|
||||
@@ -4,4 +4,3 @@
|
||||
|
||||
obj-$(CONFIG_SQUASHFS) += squashfs.o
|
||||
squashfs-y += inode.o
|
||||
-squashfs-y += squashfs2_0.o
|
||||
diff -urN linux-2.6.19.old/fs/squashfs/squashfs.h linux-2.6.19.dev/fs/squashfs/squashfs.h
|
||||
--- linux-2.6.19.old/fs/squashfs/squashfs.h 2006-12-14 03:13:20.000000000 +0100
|
||||
+++ linux-2.6.19.dev/fs/squashfs/squashfs.h 2006-12-14 03:13:31.000000000 +0100
|
||||
@@ -24,6 +24,9 @@
|
||||
#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
|
||||
#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
|
||||
#endif
|
||||
+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
|
||||
+#undef CONFIG_SQUASHFS_2_0_COMPATIBILITY
|
||||
+#endif
|
||||
|
||||
#ifdef SQUASHFS_TRACE
|
||||
#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args)
|
||||
414
target/linux/etrax/patches/generic_2.6/060-rootfs_split.patch
Normal file
414
target/linux/etrax/patches/generic_2.6/060-rootfs_split.patch
Normal file
@@ -0,0 +1,414 @@
|
||||
diff -ur linux.old/drivers/mtd/Kconfig linux.dev/drivers/mtd/Kconfig
|
||||
--- linux.old/drivers/mtd/Kconfig 2007-01-10 20:10:37.000000000 +0100
|
||||
+++ linux.dev/drivers/mtd/Kconfig 2007-02-19 23:00:53.739457000 +0100
|
||||
@@ -49,6 +49,11 @@
|
||||
devices. Partitioning on NFTL 'devices' is a different - that's the
|
||||
'normal' form of partitioning used on a block device.
|
||||
|
||||
+config MTD_SPLIT_ROOTFS
|
||||
+ bool "Automatically split rootfs partition for squashfs"
|
||||
+ depends on MTD_PARTITIONS
|
||||
+ default y
|
||||
+
|
||||
config MTD_REDBOOT_PARTS
|
||||
tristate "RedBoot partition table parsing"
|
||||
depends on MTD_PARTITIONS
|
||||
diff -ur linux.old/drivers/mtd/mtdpart.c linux.dev/drivers/mtd/mtdpart.c
|
||||
--- linux.old/drivers/mtd/mtdpart.c 2007-01-10 20:10:37.000000000 +0100
|
||||
+++ linux.dev/drivers/mtd/mtdpart.c 2007-02-20 00:01:38.587355896 +0100
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
+#include <linux/squashfs_fs.h>
|
||||
+#include <linux/root_dev.h>
|
||||
|
||||
/* Our partition linked list */
|
||||
static LIST_HEAD(mtd_partitions);
|
||||
@@ -303,6 +305,173 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static u_int32_t cur_offset = 0;
|
||||
+static int add_mtd_partition(struct mtd_info *master, const struct mtd_partition *part, int i)
|
||||
+{
|
||||
+ struct mtd_part *slave;
|
||||
+
|
||||
+ /* allocate the partition structure */
|
||||
+ slave = kmalloc (sizeof(*slave), GFP_KERNEL);
|
||||
+ if (!slave) {
|
||||
+ printk ("memory allocation error while creating partitions for \"%s\"\n",
|
||||
+ master->name);
|
||||
+ del_mtd_partitions(master);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ memset(slave, 0, sizeof(*slave));
|
||||
+ list_add(&slave->list, &mtd_partitions);
|
||||
+
|
||||
+ /* set up the MTD object for this partition */
|
||||
+ slave->mtd.type = master->type;
|
||||
+ slave->mtd.flags = master->flags & ~part->mask_flags;
|
||||
+ slave->mtd.size = part->size;
|
||||
+ slave->mtd.writesize = master->writesize;
|
||||
+ slave->mtd.oobsize = master->oobsize;
|
||||
+ slave->mtd.ecctype = master->ecctype;
|
||||
+ slave->mtd.eccsize = master->eccsize;
|
||||
+
|
||||
+ slave->mtd.name = part->name;
|
||||
+ slave->mtd.bank_size = master->bank_size;
|
||||
+ slave->mtd.owner = master->owner;
|
||||
+
|
||||
+ slave->mtd.read = part_read;
|
||||
+ slave->mtd.write = part_write;
|
||||
+
|
||||
+ if(master->point && master->unpoint){
|
||||
+ slave->mtd.point = part_point;
|
||||
+ slave->mtd.unpoint = part_unpoint;
|
||||
+ }
|
||||
+
|
||||
+ if (master->read_oob)
|
||||
+ slave->mtd.read_oob = part_read_oob;
|
||||
+ if (master->write_oob)
|
||||
+ slave->mtd.write_oob = part_write_oob;
|
||||
+ if(master->read_user_prot_reg)
|
||||
+ slave->mtd.read_user_prot_reg = part_read_user_prot_reg;
|
||||
+ if(master->read_fact_prot_reg)
|
||||
+ slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
|
||||
+ if(master->write_user_prot_reg)
|
||||
+ slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
|
||||
+ if(master->lock_user_prot_reg)
|
||||
+ slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
|
||||
+ if(master->get_user_prot_info)
|
||||
+ slave->mtd.get_user_prot_info = part_get_user_prot_info;
|
||||
+ if(master->get_fact_prot_info)
|
||||
+ slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
|
||||
+ if (master->sync)
|
||||
+ slave->mtd.sync = part_sync;
|
||||
+ if (!i && master->suspend && master->resume) {
|
||||
+ slave->mtd.suspend = part_suspend;
|
||||
+ slave->mtd.resume = part_resume;
|
||||
+ }
|
||||
+ if (master->writev)
|
||||
+ slave->mtd.writev = part_writev;
|
||||
+ if (master->lock)
|
||||
+ slave->mtd.lock = part_lock;
|
||||
+ if (master->unlock)
|
||||
+ slave->mtd.unlock = part_unlock;
|
||||
+ if (master->block_isbad)
|
||||
+ slave->mtd.block_isbad = part_block_isbad;
|
||||
+ if (master->block_markbad)
|
||||
+ slave->mtd.block_markbad = part_block_markbad;
|
||||
+ slave->mtd.erase = part_erase;
|
||||
+ slave->master = master;
|
||||
+ slave->offset = part->offset;
|
||||
+ slave->index = i;
|
||||
+
|
||||
+ if (slave->offset == MTDPART_OFS_APPEND)
|
||||
+ slave->offset = cur_offset;
|
||||
+ if (slave->offset == MTDPART_OFS_NXTBLK) {
|
||||
+ slave->offset = cur_offset;
|
||||
+ if ((cur_offset % master->erasesize) != 0) {
|
||||
+ /* Round up to next erasesize */
|
||||
+ slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize;
|
||||
+ printk(KERN_NOTICE "Moving partition %d: "
|
||||
+ "0x%08x -> 0x%08x\n", i,
|
||||
+ cur_offset, slave->offset);
|
||||
+ }
|
||||
+ }
|
||||
+ if (slave->mtd.size == MTDPART_SIZ_FULL)
|
||||
+ slave->mtd.size = master->size - slave->offset;
|
||||
+ cur_offset = slave->offset + slave->mtd.size;
|
||||
+
|
||||
+ printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
|
||||
+ slave->offset + slave->mtd.size, slave->mtd.name);
|
||||
+
|
||||
+ /* let's do some sanity checks */
|
||||
+ if (slave->offset >= master->size) {
|
||||
+ /* let's register it anyway to preserve ordering */
|
||||
+ slave->offset = 0;
|
||||
+ slave->mtd.size = 0;
|
||||
+ printk ("mtd: partition \"%s\" is out of reach -- disabled\n",
|
||||
+ part->name);
|
||||
+ }
|
||||
+ if (slave->offset + slave->mtd.size > master->size) {
|
||||
+ slave->mtd.size = master->size - slave->offset;
|
||||
+ printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n",
|
||||
+ part->name, master->name, slave->mtd.size);
|
||||
+ }
|
||||
+ if (master->numeraseregions>1) {
|
||||
+ /* Deal with variable erase size stuff */
|
||||
+ int i;
|
||||
+ struct mtd_erase_region_info *regions = master->eraseregions;
|
||||
+
|
||||
+ /* Find the first erase regions which is part of this partition. */
|
||||
+ for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
|
||||
+ ;
|
||||
+
|
||||
+ for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) {
|
||||
+ if (slave->mtd.erasesize < regions[i].erasesize) {
|
||||
+ slave->mtd.erasesize = regions[i].erasesize;
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* Single erase size */
|
||||
+ slave->mtd.erasesize = master->erasesize;
|
||||
+ }
|
||||
+
|
||||
+ if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||
+ (slave->offset % slave->mtd.erasesize)) {
|
||||
+ /* Doesn't start on a boundary of major erase size */
|
||||
+ /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */
|
||||
+ slave->mtd.flags &= ~MTD_WRITEABLE;
|
||||
+ printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
|
||||
+ part->name);
|
||||
+ }
|
||||
+ if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||
+ (slave->mtd.size % slave->mtd.erasesize)) {
|
||||
+ slave->mtd.flags &= ~MTD_WRITEABLE;
|
||||
+ printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
|
||||
+ part->name);
|
||||
+ }
|
||||
+
|
||||
+ slave->mtd.ecclayout = master->ecclayout;
|
||||
+ if (master->block_isbad) {
|
||||
+ uint32_t offs = 0;
|
||||
+
|
||||
+ while(offs < slave->mtd.size) {
|
||||
+ if (master->block_isbad(master,
|
||||
+ offs + slave->offset))
|
||||
+ slave->mtd.ecc_stats.badblocks++;
|
||||
+ offs += slave->mtd.erasesize;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if(part->mtdp)
|
||||
+ { /* store the object pointer (caller may or may not register it */
|
||||
+ *part->mtdp = &slave->mtd;
|
||||
+ slave->registered = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* register our partition */
|
||||
+ add_mtd_device(&slave->mtd);
|
||||
+ slave->registered = 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* This function, given a master MTD object and a partition table, creates
|
||||
* and registers slave MTD objects which are bound to the master according to
|
||||
@@ -314,171 +483,53 @@
|
||||
const struct mtd_partition *parts,
|
||||
int nbparts)
|
||||
{
|
||||
- struct mtd_part *slave;
|
||||
- u_int32_t cur_offset = 0;
|
||||
- int i;
|
||||
+ struct mtd_partition *part;
|
||||
+ int i, ret = 0;
|
||||
|
||||
printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
|
||||
|
||||
for (i = 0; i < nbparts; i++) {
|
||||
+ part = (struct mtd_partition *) &parts[i];
|
||||
+ ret = add_mtd_partition(master, part, i);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (strcmp(part->name, "rootfs") == 0) {
|
||||
+#ifdef CONFIG_MTD_SPLIT_ROOTFS
|
||||
+ int len;
|
||||
+ char buf[512];
|
||||
+ struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
|
||||
+#define ROOTFS_SPLIT_NAME "rootfs_data"
|
||||
+ if ((master->read(master, part->offset, sizeof(struct squashfs_super_block), &len, buf) == 0) &&
|
||||
+ (len == sizeof(struct squashfs_super_block)) &&
|
||||
+ (*((u32 *) buf) == SQUASHFS_MAGIC) &&
|
||||
+ (sb->bytes_used > 0)) {
|
||||
+
|
||||
+
|
||||
+ part = kmalloc(sizeof(struct mtd_partition), GFP_KERNEL);
|
||||
+ memcpy(part, &parts[i], sizeof(struct mtd_partition));
|
||||
+
|
||||
+ part->name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL);
|
||||
+ strcpy(part->name, ROOTFS_SPLIT_NAME);
|
||||
+
|
||||
+ len = (u32) sb->bytes_used;
|
||||
+ len += (part->offset & 0x000fffff);
|
||||
+ len += (master->erasesize - 1);
|
||||
+ len &= ~(master->erasesize - 1);
|
||||
+ len -= (part->offset & 0x000fffff);
|
||||
+ part->offset += len;
|
||||
+ part->size -= len;
|
||||
+
|
||||
+ if (master->erasesize <= part->size)
|
||||
+ ret = add_mtd_partition(master, part, i + 1);
|
||||
+ else
|
||||
+ kfree(part->name);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
- /* allocate the partition structure */
|
||||
- slave = kmalloc (sizeof(*slave), GFP_KERNEL);
|
||||
- if (!slave) {
|
||||
- printk ("memory allocation error while creating partitions for \"%s\"\n",
|
||||
- master->name);
|
||||
- del_mtd_partitions(master);
|
||||
- return -ENOMEM;
|
||||
- }
|
||||
- memset(slave, 0, sizeof(*slave));
|
||||
- list_add(&slave->list, &mtd_partitions);
|
||||
-
|
||||
- /* set up the MTD object for this partition */
|
||||
- slave->mtd.type = master->type;
|
||||
- slave->mtd.flags = master->flags & ~parts[i].mask_flags;
|
||||
- slave->mtd.size = parts[i].size;
|
||||
- slave->mtd.writesize = master->writesize;
|
||||
- slave->mtd.oobsize = master->oobsize;
|
||||
- slave->mtd.ecctype = master->ecctype;
|
||||
- slave->mtd.eccsize = master->eccsize;
|
||||
-
|
||||
- slave->mtd.name = parts[i].name;
|
||||
- slave->mtd.bank_size = master->bank_size;
|
||||
- slave->mtd.owner = master->owner;
|
||||
-
|
||||
- slave->mtd.read = part_read;
|
||||
- slave->mtd.write = part_write;
|
||||
-
|
||||
- if(master->point && master->unpoint){
|
||||
- slave->mtd.point = part_point;
|
||||
- slave->mtd.unpoint = part_unpoint;
|
||||
- }
|
||||
-
|
||||
- if (master->read_oob)
|
||||
- slave->mtd.read_oob = part_read_oob;
|
||||
- if (master->write_oob)
|
||||
- slave->mtd.write_oob = part_write_oob;
|
||||
- if(master->read_user_prot_reg)
|
||||
- slave->mtd.read_user_prot_reg = part_read_user_prot_reg;
|
||||
- if(master->read_fact_prot_reg)
|
||||
- slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
|
||||
- if(master->write_user_prot_reg)
|
||||
- slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
|
||||
- if(master->lock_user_prot_reg)
|
||||
- slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
|
||||
- if(master->get_user_prot_info)
|
||||
- slave->mtd.get_user_prot_info = part_get_user_prot_info;
|
||||
- if(master->get_fact_prot_info)
|
||||
- slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
|
||||
- if (master->sync)
|
||||
- slave->mtd.sync = part_sync;
|
||||
- if (!i && master->suspend && master->resume) {
|
||||
- slave->mtd.suspend = part_suspend;
|
||||
- slave->mtd.resume = part_resume;
|
||||
- }
|
||||
- if (master->writev)
|
||||
- slave->mtd.writev = part_writev;
|
||||
- if (master->lock)
|
||||
- slave->mtd.lock = part_lock;
|
||||
- if (master->unlock)
|
||||
- slave->mtd.unlock = part_unlock;
|
||||
- if (master->block_isbad)
|
||||
- slave->mtd.block_isbad = part_block_isbad;
|
||||
- if (master->block_markbad)
|
||||
- slave->mtd.block_markbad = part_block_markbad;
|
||||
- slave->mtd.erase = part_erase;
|
||||
- slave->master = master;
|
||||
- slave->offset = parts[i].offset;
|
||||
- slave->index = i;
|
||||
-
|
||||
- if (slave->offset == MTDPART_OFS_APPEND)
|
||||
- slave->offset = cur_offset;
|
||||
- if (slave->offset == MTDPART_OFS_NXTBLK) {
|
||||
- slave->offset = cur_offset;
|
||||
- if ((cur_offset % master->erasesize) != 0) {
|
||||
- /* Round up to next erasesize */
|
||||
- slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize;
|
||||
- printk(KERN_NOTICE "Moving partition %d: "
|
||||
- "0x%08x -> 0x%08x\n", i,
|
||||
- cur_offset, slave->offset);
|
||||
+ kfree(part);
|
||||
}
|
||||
- }
|
||||
- if (slave->mtd.size == MTDPART_SIZ_FULL)
|
||||
- slave->mtd.size = master->size - slave->offset;
|
||||
- cur_offset = slave->offset + slave->mtd.size;
|
||||
-
|
||||
- printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
|
||||
- slave->offset + slave->mtd.size, slave->mtd.name);
|
||||
-
|
||||
- /* let's do some sanity checks */
|
||||
- if (slave->offset >= master->size) {
|
||||
- /* let's register it anyway to preserve ordering */
|
||||
- slave->offset = 0;
|
||||
- slave->mtd.size = 0;
|
||||
- printk ("mtd: partition \"%s\" is out of reach -- disabled\n",
|
||||
- parts[i].name);
|
||||
- }
|
||||
- if (slave->offset + slave->mtd.size > master->size) {
|
||||
- slave->mtd.size = master->size - slave->offset;
|
||||
- printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n",
|
||||
- parts[i].name, master->name, slave->mtd.size);
|
||||
- }
|
||||
- if (master->numeraseregions>1) {
|
||||
- /* Deal with variable erase size stuff */
|
||||
- int i;
|
||||
- struct mtd_erase_region_info *regions = master->eraseregions;
|
||||
-
|
||||
- /* Find the first erase regions which is part of this partition. */
|
||||
- for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
|
||||
- ;
|
||||
-
|
||||
- for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) {
|
||||
- if (slave->mtd.erasesize < regions[i].erasesize) {
|
||||
- slave->mtd.erasesize = regions[i].erasesize;
|
||||
- }
|
||||
- }
|
||||
- } else {
|
||||
- /* Single erase size */
|
||||
- slave->mtd.erasesize = master->erasesize;
|
||||
- }
|
||||
-
|
||||
- if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||
- (slave->offset % slave->mtd.erasesize)) {
|
||||
- /* Doesn't start on a boundary of major erase size */
|
||||
- /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */
|
||||
- slave->mtd.flags &= ~MTD_WRITEABLE;
|
||||
- printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
|
||||
- parts[i].name);
|
||||
- }
|
||||
- if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||
- (slave->mtd.size % slave->mtd.erasesize)) {
|
||||
- slave->mtd.flags &= ~MTD_WRITEABLE;
|
||||
- printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
|
||||
- parts[i].name);
|
||||
- }
|
||||
-
|
||||
- slave->mtd.ecclayout = master->ecclayout;
|
||||
- if (master->block_isbad) {
|
||||
- uint32_t offs = 0;
|
||||
-
|
||||
- while(offs < slave->mtd.size) {
|
||||
- if (master->block_isbad(master,
|
||||
- offs + slave->offset))
|
||||
- slave->mtd.ecc_stats.badblocks++;
|
||||
- offs += slave->mtd.erasesize;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if(parts[i].mtdp)
|
||||
- { /* store the object pointer (caller may or may not register it */
|
||||
- *parts[i].mtdp = &slave->mtd;
|
||||
- slave->registered = 0;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- /* register our partition */
|
||||
- add_mtd_device(&slave->mtd);
|
||||
- slave->registered = 1;
|
||||
+#endif /* CONFIG_MTD_SPLIT_ROOTFS */
|
||||
+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, i);
|
||||
}
|
||||
}
|
||||
|
||||
112
target/linux/etrax/patches/generic_2.6/065-block2mtd_init.patch
Normal file
112
target/linux/etrax/patches/generic_2.6/065-block2mtd_init.patch
Normal file
@@ -0,0 +1,112 @@
|
||||
--- linux.old/drivers/mtd/devices/block2mtd.c 2007-03-02 01:00:13.866987272 +0100
|
||||
+++ linux.dev/drivers/mtd/devices/block2mtd.c 2007-03-02 02:03:45.558522080 +0100
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mount.h>
|
||||
@@ -287,10 +288,11 @@
|
||||
|
||||
|
||||
/* FIXME: ensure that mtd->size % erase_size == 0 */
|
||||
-static struct block2mtd_dev *add_device(char *devname, int erase_size)
|
||||
+static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname)
|
||||
{
|
||||
struct block_device *bdev;
|
||||
struct block2mtd_dev *dev;
|
||||
+ struct mtd_partition *part;
|
||||
|
||||
if (!devname)
|
||||
return NULL;
|
||||
@@ -330,14 +332,18 @@
|
||||
|
||||
/* Setup the MTD structure */
|
||||
/* make the name contain the block device in */
|
||||
- dev->mtd.name = kmalloc(sizeof("block2mtd: ") + strlen(devname),
|
||||
- GFP_KERNEL);
|
||||
+
|
||||
+ if (!mtdname)
|
||||
+ mtdname = devname;
|
||||
+
|
||||
+ dev->mtd.name = kmalloc(strlen(mtdname), GFP_KERNEL);
|
||||
+
|
||||
if (!dev->mtd.name)
|
||||
goto devinit_err;
|
||||
+
|
||||
+ strcpy(dev->mtd.name, mtdname);
|
||||
|
||||
- sprintf(dev->mtd.name, "block2mtd: %s", devname);
|
||||
-
|
||||
- dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
|
||||
+ dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK & ~(erase_size - 1);
|
||||
dev->mtd.erasesize = erase_size;
|
||||
dev->mtd.writesize = 1;
|
||||
dev->mtd.type = MTD_RAM;
|
||||
@@ -349,15 +355,18 @@
|
||||
dev->mtd.read = block2mtd_read;
|
||||
dev->mtd.priv = dev;
|
||||
dev->mtd.owner = THIS_MODULE;
|
||||
-
|
||||
- if (add_mtd_device(&dev->mtd)) {
|
||||
+
|
||||
+ part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
|
||||
+ part->name = dev->mtd.name;
|
||||
+ part->offset = 0;
|
||||
+ part->size = dev->mtd.size;
|
||||
+ if (add_mtd_partitions(&dev->mtd, part, 1)) {
|
||||
/* Device didnt get added, so free the entry */
|
||||
goto devinit_err;
|
||||
}
|
||||
list_add(&dev->list, &blkmtd_device_list);
|
||||
INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index,
|
||||
- dev->mtd.name + strlen("blkmtd: "),
|
||||
- dev->mtd.erasesize >> 10, dev->mtd.erasesize);
|
||||
+ mtdname, dev->mtd.erasesize >> 10, dev->mtd.erasesize);
|
||||
return dev;
|
||||
|
||||
devinit_err:
|
||||
@@ -430,9 +439,9 @@
|
||||
|
||||
static int block2mtd_setup2(const char *val)
|
||||
{
|
||||
- char buf[80 + 12]; /* 80 for device, 12 for erase size */
|
||||
+ char buf[80 + 12 + 80]; /* 80 for device, 12 for erase size, 80 for name */
|
||||
char *str = buf;
|
||||
- char *token[2];
|
||||
+ char *token[3];
|
||||
char *name;
|
||||
size_t erase_size = PAGE_SIZE;
|
||||
int i, ret;
|
||||
@@ -443,7 +452,7 @@
|
||||
strcpy(str, val);
|
||||
kill_final_newline(str);
|
||||
|
||||
- for (i = 0; i < 2; i++)
|
||||
+ for (i = 0; i < 3; i++)
|
||||
token[i] = strsep(&str, ",");
|
||||
|
||||
if (str)
|
||||
@@ -463,8 +472,10 @@
|
||||
parse_err("illegal erase size");
|
||||
}
|
||||
}
|
||||
+ if (token[2] && (strlen(token[2]) + 1 > 80))
|
||||
+ parse_err("mtd device name too long");
|
||||
|
||||
- add_device(name, erase_size);
|
||||
+ add_device(name, erase_size, token[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -498,7 +509,7 @@
|
||||
|
||||
|
||||
module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200);
|
||||
-MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\"");
|
||||
+MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>]]\"");
|
||||
|
||||
static int __init block2mtd_init(void)
|
||||
{
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,108 @@
|
||||
diff -ur linux.dev/include/linux/netfilter_ipv4/ipt_layer7.h linux.dev2/include/linux/netfilter_ipv4/ipt_layer7.h
|
||||
--- linux.dev/include/linux/netfilter_ipv4/ipt_layer7.h 2007-01-01 05:18:48.000000000 +0100
|
||||
+++ linux.dev2/include/linux/netfilter_ipv4/ipt_layer7.h 2007-01-01 05:30:46.000000000 +0100
|
||||
@@ -21,6 +21,7 @@
|
||||
char protocol[MAX_PROTOCOL_LEN];
|
||||
char invert:1;
|
||||
char pattern[MAX_PATTERN_LEN];
|
||||
+ char pkt;
|
||||
};
|
||||
|
||||
#endif /* _IPT_LAYER7_H */
|
||||
diff -ur linux.dev/net/ipv4/netfilter/ipt_layer7.c linux.dev2/net/ipv4/netfilter/ipt_layer7.c
|
||||
--- linux.dev/net/ipv4/netfilter/ipt_layer7.c 2007-01-01 05:18:48.000000000 +0100
|
||||
+++ linux.dev2/net/ipv4/netfilter/ipt_layer7.c 2007-01-01 05:30:46.000000000 +0100
|
||||
@@ -296,33 +296,34 @@
|
||||
}
|
||||
}
|
||||
|
||||
-/* add the new app data to the conntrack. Return number of bytes added. */
|
||||
-static int add_data(struct ip_conntrack * master_conntrack,
|
||||
- char * app_data, int appdatalen)
|
||||
+static int add_datastr(char *target, int offset, char *app_data, int len)
|
||||
{
|
||||
int length = 0, i;
|
||||
- int oldlength = master_conntrack->layer7.app_data_len;
|
||||
-
|
||||
- // This is a fix for a race condition by Deti Fliegl. However, I'm not
|
||||
- // clear on whether the race condition exists or whether this really
|
||||
- // fixes it. I might just be being dense... Anyway, if it's not really
|
||||
- // a fix, all it does is waste a very small amount of time.
|
||||
- if(!master_conntrack->layer7.app_data) return 0;
|
||||
+ if(!target) return 0;
|
||||
|
||||
/* Strip nulls. Make everything lower case (our regex lib doesn't
|
||||
do case insensitivity). Add it to the end of the current data. */
|
||||
- for(i = 0; i < maxdatalen-oldlength-1 &&
|
||||
- i < appdatalen; i++) {
|
||||
+ for(i = 0; i < maxdatalen-offset-1 && i < len; i++) {
|
||||
if(app_data[i] != '\0') {
|
||||
- master_conntrack->layer7.app_data[length+oldlength] =
|
||||
+ target[length+offset] =
|
||||
/* the kernel version of tolower mungs 'upper ascii' */
|
||||
isascii(app_data[i])? tolower(app_data[i]) : app_data[i];
|
||||
length++;
|
||||
}
|
||||
}
|
||||
+ target[length+offset] = '\0';
|
||||
|
||||
- master_conntrack->layer7.app_data[length+oldlength] = '\0';
|
||||
- master_conntrack->layer7.app_data_len = length + oldlength;
|
||||
+ return length;
|
||||
+}
|
||||
+
|
||||
+/* add the new app data to the conntrack. Return number of bytes added. */
|
||||
+static int add_data(struct ip_conntrack * master_conntrack,
|
||||
+ char * app_data, int appdatalen)
|
||||
+{
|
||||
+ int length;
|
||||
+
|
||||
+ length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen);
|
||||
+ master_conntrack->layer7.app_data_len += length;
|
||||
|
||||
return length;
|
||||
}
|
||||
@@ -339,7 +340,7 @@
|
||||
struct ipt_layer7_info * info = (struct ipt_layer7_info *)matchinfo;
|
||||
enum ip_conntrack_info master_ctinfo, ctinfo;
|
||||
struct ip_conntrack *master_conntrack, *conntrack;
|
||||
- unsigned char * app_data;
|
||||
+ unsigned char *app_data, *tmp_data;
|
||||
unsigned int pattern_result, appdatalen;
|
||||
regexp * comppattern;
|
||||
|
||||
@@ -362,8 +363,8 @@
|
||||
master_conntrack = master_ct(master_conntrack);
|
||||
|
||||
/* if we've classified it or seen too many packets */
|
||||
- if(TOTAL_PACKETS > num_packets ||
|
||||
- master_conntrack->layer7.app_proto) {
|
||||
+ if(!info->pkt && (TOTAL_PACKETS > num_packets ||
|
||||
+ master_conntrack->layer7.app_proto)) {
|
||||
|
||||
pattern_result = match_no_append(conntrack, master_conntrack, ctinfo, master_ctinfo, info);
|
||||
|
||||
@@ -394,6 +395,23 @@
|
||||
comppattern = compile_and_cache(info->pattern, info->protocol);
|
||||
spin_unlock_bh(&list_lock);
|
||||
|
||||
+ if (info->pkt) {
|
||||
+ tmp_data = kmalloc(maxdatalen, GFP_ATOMIC);
|
||||
+ if(!tmp_data){
|
||||
+ if (net_ratelimit())
|
||||
+ printk(KERN_ERR "layer7: out of memory in match, bailing.\n");
|
||||
+ return info->invert;
|
||||
+ }
|
||||
+
|
||||
+ tmp_data[0] = '\0';
|
||||
+ add_datastr(tmp_data, 0, app_data, appdatalen);
|
||||
+ pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0);
|
||||
+ kfree(tmp_data);
|
||||
+ tmp_data = NULL;
|
||||
+
|
||||
+ return (pattern_result ^ info->invert);
|
||||
+ }
|
||||
+
|
||||
/* On the first packet of a connection, allocate space for app data */
|
||||
write_lock(&ct_lock);
|
||||
if(TOTAL_PACKETS == 1 && !skb->cb[0] && !master_conntrack->layer7.app_data) {
|
||||
948
target/linux/etrax/patches/generic_2.6/110-ipp2p_0.8.1rc1.patch
Normal file
948
target/linux/etrax/patches/generic_2.6/110-ipp2p_0.8.1rc1.patch
Normal file
@@ -0,0 +1,948 @@
|
||||
diff -urN linux-2.6.19.old/include/linux/netfilter_ipv4/ipt_ipp2p.h linux-2.6.19.dev/include/linux/netfilter_ipv4/ipt_ipp2p.h
|
||||
--- linux-2.6.19.old/include/linux/netfilter_ipv4/ipt_ipp2p.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/include/linux/netfilter_ipv4/ipt_ipp2p.h 2006-12-14 03:13:39.000000000 +0100
|
||||
@@ -0,0 +1,31 @@
|
||||
+#ifndef __IPT_IPP2P_H
|
||||
+#define __IPT_IPP2P_H
|
||||
+#define IPP2P_VERSION "0.8.1_rc1"
|
||||
+
|
||||
+struct ipt_p2p_info {
|
||||
+ int cmd;
|
||||
+ int debug;
|
||||
+};
|
||||
+
|
||||
+#endif //__IPT_IPP2P_H
|
||||
+
|
||||
+#define SHORT_HAND_IPP2P 1 /* --ipp2p switch*/
|
||||
+//#define SHORT_HAND_DATA 4 /* --ipp2p-data switch*/
|
||||
+#define SHORT_HAND_NONE 5 /* no short hand*/
|
||||
+
|
||||
+#define IPP2P_EDK (1 << 1)
|
||||
+#define IPP2P_DATA_KAZAA (1 << 2)
|
||||
+#define IPP2P_DATA_EDK (1 << 3)
|
||||
+#define IPP2P_DATA_DC (1 << 4)
|
||||
+#define IPP2P_DC (1 << 5)
|
||||
+#define IPP2P_DATA_GNU (1 << 6)
|
||||
+#define IPP2P_GNU (1 << 7)
|
||||
+#define IPP2P_KAZAA (1 << 8)
|
||||
+#define IPP2P_BIT (1 << 9)
|
||||
+#define IPP2P_APPLE (1 << 10)
|
||||
+#define IPP2P_SOUL (1 << 11)
|
||||
+#define IPP2P_WINMX (1 << 12)
|
||||
+#define IPP2P_ARES (1 << 13)
|
||||
+#define IPP2P_MUTE (1 << 14)
|
||||
+#define IPP2P_WASTE (1 << 15)
|
||||
+#define IPP2P_XDCC (1 << 16)
|
||||
diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_ipp2p.c linux-2.6.19.dev/net/ipv4/netfilter/ipt_ipp2p.c
|
||||
--- linux-2.6.19.old/net/ipv4/netfilter/ipt_ipp2p.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv4/netfilter/ipt_ipp2p.c 2006-12-14 03:13:39.000000000 +0100
|
||||
@@ -0,0 +1,881 @@
|
||||
+#if defined(MODVERSIONS)
|
||||
+#include <linux/modversions.h>
|
||||
+#endif
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
+#include <linux/version.h>
|
||||
+#include <linux/netfilter_ipv4/ipt_ipp2p.h>
|
||||
+#include <net/tcp.h>
|
||||
+#include <net/udp.h>
|
||||
+
|
||||
+#define get_u8(X,O) (*(__u8 *)(X + O))
|
||||
+#define get_u16(X,O) (*(__u16 *)(X + O))
|
||||
+#define get_u32(X,O) (*(__u32 *)(X + O))
|
||||
+
|
||||
+MODULE_AUTHOR("Eicke Friedrich/Klaus Degner <ipp2p@ipp2p.org>");
|
||||
+MODULE_DESCRIPTION("An extension to iptables to identify P2P traffic.");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+
|
||||
+/*Search for UDP eDonkey/eMule/Kad commands*/
|
||||
+int
|
||||
+udp_search_edk (unsigned char *haystack, int packet_len)
|
||||
+{
|
||||
+ unsigned char *t = haystack;
|
||||
+ t += 8;
|
||||
+
|
||||
+ switch (t[0]) {
|
||||
+ case 0xe3:
|
||||
+ { /*edonkey*/
|
||||
+ switch (t[1])
|
||||
+ {
|
||||
+ /* client -> server status request */
|
||||
+ case 0x96:
|
||||
+ if (packet_len == 14) return ((IPP2P_EDK * 100) + 50);
|
||||
+ break;
|
||||
+ /* server -> client status request */
|
||||
+ case 0x97: if (packet_len == 42) return ((IPP2P_EDK * 100) + 51);
|
||||
+ break;
|
||||
+ /* server description request */
|
||||
+ /* e3 2a ff f0 .. | size == 6 */
|
||||
+ case 0xa2: if ( (packet_len == 14) && ( get_u16(t,2) == __constant_htons(0xfff0) ) ) return ((IPP2P_EDK * 100) + 52);
|
||||
+ break;
|
||||
+ /* server description response */
|
||||
+ /* e3 a3 ff f0 .. | size > 40 && size < 200 */
|
||||
+ //case 0xa3: return ((IPP2P_EDK * 100) + 53);
|
||||
+ // break;
|
||||
+ case 0x9a: if (packet_len==26) return ((IPP2P_EDK * 100) + 54);
|
||||
+ break;
|
||||
+
|
||||
+ case 0x92: if (packet_len==18) return ((IPP2P_EDK * 100) + 55);
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ case 0xe4:
|
||||
+ {
|
||||
+ switch (t[1])
|
||||
+ {
|
||||
+ /* e4 20 .. | size == 43 */
|
||||
+ case 0x20: if ((packet_len == 43) && (t[2] != 0x00) && (t[34] != 0x00)) return ((IPP2P_EDK * 100) + 60);
|
||||
+ break;
|
||||
+ /* e4 00 .. 00 | size == 35 ? */
|
||||
+ case 0x00: if ((packet_len == 35) && (t[26] == 0x00)) return ((IPP2P_EDK * 100) + 61);
|
||||
+ break;
|
||||
+ /* e4 10 .. 00 | size == 35 ? */
|
||||
+ case 0x10: if ((packet_len == 35) && (t[26] == 0x00)) return ((IPP2P_EDK * 100) + 62);
|
||||
+ break;
|
||||
+ /* e4 18 .. 00 | size == 35 ? */
|
||||
+ case 0x18: if ((packet_len == 35) && (t[26] == 0x00)) return ((IPP2P_EDK * 100) + 63);
|
||||
+ break;
|
||||
+ /* e4 52 .. | size = 44 */
|
||||
+ case 0x52: if (packet_len == 44 ) return ((IPP2P_EDK * 100) + 64);
|
||||
+ break;
|
||||
+ /* e4 58 .. | size == 6 */
|
||||
+ case 0x58: if (packet_len == 14 ) return ((IPP2P_EDK * 100) + 65);
|
||||
+ break;
|
||||
+ /* e4 59 .. | size == 2 */
|
||||
+ case 0x59: if (packet_len == 10 )return ((IPP2P_EDK * 100) + 66);
|
||||
+ break;
|
||||
+ /* e4 28 .. | packet_len == 52,77,102,127... */
|
||||
+ case 0x28: if (((packet_len-52) % 25) == 0) return ((IPP2P_EDK * 100) + 67);
|
||||
+ break;
|
||||
+ /* e4 50 xx xx | size == 4 */
|
||||
+ case 0x50: if (packet_len == 12) return ((IPP2P_EDK * 100) + 68);
|
||||
+ break;
|
||||
+ /* e4 40 xx xx | size == 48 */
|
||||
+ case 0x40: if (packet_len == 56) return ((IPP2P_EDK * 100) + 69);
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ } /* end of switch (t[0]) */
|
||||
+ return 0;
|
||||
+}/*udp_search_edk*/
|
||||
+
|
||||
+
|
||||
+/*Search for UDP Gnutella commands*/
|
||||
+int
|
||||
+udp_search_gnu (unsigned char *haystack, int packet_len)
|
||||
+{
|
||||
+ unsigned char *t = haystack;
|
||||
+ t += 8;
|
||||
+
|
||||
+ if (memcmp(t, "GND", 3) == 0) return ((IPP2P_GNU * 100) + 51);
|
||||
+ if (memcmp(t, "GNUTELLA ", 9) == 0) return ((IPP2P_GNU * 100) + 52);
|
||||
+ return 0;
|
||||
+}/*udp_search_gnu*/
|
||||
+
|
||||
+
|
||||
+/*Search for UDP KaZaA commands*/
|
||||
+int
|
||||
+udp_search_kazaa (unsigned char *haystack, int packet_len)
|
||||
+{
|
||||
+ unsigned char *t = haystack;
|
||||
+
|
||||
+ if (t[packet_len-1] == 0x00){
|
||||
+ t += (packet_len - 6);
|
||||
+ if (memcmp(t, "KaZaA", 5) == 0) return (IPP2P_KAZAA * 100 +50);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}/*udp_search_kazaa*/
|
||||
+
|
||||
+/*Search for UDP DirectConnect commands*/
|
||||
+int
|
||||
+udp_search_directconnect (unsigned char *haystack, int packet_len)
|
||||
+{
|
||||
+ unsigned char *t = haystack;
|
||||
+ if ((*(t + 8) == 0x24) && (*(t + packet_len - 1) == 0x7c)) {
|
||||
+ t+=8;
|
||||
+ if (memcmp(t, "SR ", 3) == 0) return ((IPP2P_DC * 100) + 60);
|
||||
+ if (memcmp(t, "Ping ", 5) == 0) return ((IPP2P_DC * 100) + 61);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}/*udp_search_directconnect*/
|
||||
+
|
||||
+
|
||||
+
|
||||
+/*Search for UDP BitTorrent commands*/
|
||||
+int
|
||||
+udp_search_bit (unsigned char *haystack, int packet_len)
|
||||
+{
|
||||
+ switch(packet_len)
|
||||
+ {
|
||||
+ case 24:
|
||||
+ /* ^ 00 00 04 17 27 10 19 80 */
|
||||
+ if ((ntohl(get_u32(haystack, 8)) == 0x00000417) && (ntohl(get_u32(haystack, 12)) == 0x27101980))
|
||||
+ return (IPP2P_BIT * 100 + 50);
|
||||
+ break;
|
||||
+ case 44:
|
||||
+ if (get_u32(haystack, 16) == __constant_htonl(0x00000400) && get_u32(haystack, 36) == __constant_htonl(0x00000104))
|
||||
+ return (IPP2P_BIT * 100 + 51);
|
||||
+ if (get_u32(haystack, 16) == __constant_htonl(0x00000400))
|
||||
+ return (IPP2P_BIT * 100 + 61);
|
||||
+ break;
|
||||
+ case 65:
|
||||
+ if (get_u32(haystack, 16) == __constant_htonl(0x00000404) && get_u32(haystack, 36) == __constant_htonl(0x00000104))
|
||||
+ return (IPP2P_BIT * 100 + 52);
|
||||
+ if (get_u32(haystack, 16) == __constant_htonl(0x00000404))
|
||||
+ return (IPP2P_BIT * 100 + 62);
|
||||
+ break;
|
||||
+ case 67:
|
||||
+ if (get_u32(haystack, 16) == __constant_htonl(0x00000406) && get_u32(haystack, 36) == __constant_htonl(0x00000104))
|
||||
+ return (IPP2P_BIT * 100 + 53);
|
||||
+ if (get_u32(haystack, 16) == __constant_htonl(0x00000406))
|
||||
+ return (IPP2P_BIT * 100 + 63);
|
||||
+ break;
|
||||
+ case 211:
|
||||
+ if (get_u32(haystack, 8) == __constant_htonl(0x00000405))
|
||||
+ return (IPP2P_BIT * 100 + 54);
|
||||
+ break;
|
||||
+ case 29:
|
||||
+ if ((get_u32(haystack, 8) == __constant_htonl(0x00000401)))
|
||||
+ return (IPP2P_BIT * 100 + 55);
|
||||
+ break;
|
||||
+ case 52:
|
||||
+ if (get_u32(haystack,8) == __constant_htonl(0x00000827) &&
|
||||
+ get_u32(haystack,12) == __constant_htonl(0x37502950))
|
||||
+ return (IPP2P_BIT * 100 + 80);
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* this packet does not have a constant size */
|
||||
+ if (packet_len >= 40 && get_u32(haystack, 16) == __constant_htonl(0x00000402) && get_u32(haystack, 36) == __constant_htonl(0x00000104))
|
||||
+ return (IPP2P_BIT * 100 + 56);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* some extra-bitcomet rules:
|
||||
+ * "d1:" [a|r] "d2:id20:"
|
||||
+ */
|
||||
+ if (packet_len > 30 && get_u8(haystack, 8) == 'd' && get_u8(haystack, 9) == '1' && get_u8(haystack, 10) == ':' )
|
||||
+ {
|
||||
+ if (get_u8(haystack, 11) == 'a' || get_u8(haystack, 11) == 'r')
|
||||
+ {
|
||||
+ if (memcmp(haystack+12,"d2:id20:",8)==0)
|
||||
+ return (IPP2P_BIT * 100 + 57);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+#if 0
|
||||
+ /* bitlord rules */
|
||||
+ /* packetlen must be bigger than 40 */
|
||||
+ /* first 4 bytes are zero */
|
||||
+ if (packet_len > 40 && get_u32(haystack, 8) == 0x00000000)
|
||||
+ {
|
||||
+ /* first rule: 00 00 00 00 01 00 00 xx xx xx xx 00 00 00 00*/
|
||||
+ if (get_u32(haystack, 12) == 0x00000000 &&
|
||||
+ get_u32(haystack, 16) == 0x00010000 &&
|
||||
+ get_u32(haystack, 24) == 0x00000000 )
|
||||
+ return (IPP2P_BIT * 100 + 71);
|
||||
+
|
||||
+ /* 00 01 00 00 0d 00 00 xx xx xx xx 00 00 00 00*/
|
||||
+ if (get_u32(haystack, 12) == 0x00000001 &&
|
||||
+ get_u32(haystack, 16) == 0x000d0000 &&
|
||||
+ get_u32(haystack, 24) == 0x00000000 )
|
||||
+ return (IPP2P_BIT * 100 + 71);
|
||||
+
|
||||
+
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ return 0;
|
||||
+}/*udp_search_bit*/
|
||||
+
|
||||
+
|
||||
+
|
||||
+/*Search for Ares commands*/
|
||||
+//#define IPP2P_DEBUG_ARES
|
||||
+int
|
||||
+search_ares (const unsigned char *payload, const u16 plen)
|
||||
+//int search_ares (unsigned char *haystack, int packet_len, int head_len)
|
||||
+{
|
||||
+// const unsigned char *t = haystack + head_len;
|
||||
+
|
||||
+ /* all ares packets start with */
|
||||
+ if (payload[1] == 0 && (plen - payload[0]) == 3)
|
||||
+ {
|
||||
+ switch (payload[2])
|
||||
+ {
|
||||
+ case 0x5a:
|
||||
+ /* ares connect */
|
||||
+ if ( plen == 6 && payload[5] == 0x05 ) return ((IPP2P_ARES * 100) + 1);
|
||||
+ break;
|
||||
+ case 0x09:
|
||||
+ /* ares search, min 3 chars --> 14 bytes
|
||||
+ * lets define a search can be up to 30 chars --> max 34 bytes
|
||||
+ */
|
||||
+ if ( plen >= 14 && plen <= 34 ) return ((IPP2P_ARES * 100) + 1);
|
||||
+ break;
|
||||
+#ifdef IPP2P_DEBUG_ARES
|
||||
+ default:
|
||||
+ printk(KERN_DEBUG "Unknown Ares command %x recognized, len: %u \n", (unsigned int) payload[2],plen);
|
||||
+#endif /* IPP2P_DEBUG_ARES */
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+#if 0
|
||||
+ /* found connect packet: 03 00 5a 04 03 05 */
|
||||
+ /* new version ares 1.8: 03 00 5a xx xx 05 */
|
||||
+ if ((plen) == 6){ /* possible connect command*/
|
||||
+ if ((payload[0] == 0x03) && (payload[1] == 0x00) && (payload[2] == 0x5a) && (payload[5] == 0x05))
|
||||
+ return ((IPP2P_ARES * 100) + 1);
|
||||
+ }
|
||||
+ if ((plen) == 60){ /* possible download command*/
|
||||
+ if ((payload[59] == 0x0a) && (payload[58] == 0x0a)){
|
||||
+ if (memcmp(t, "PUSH SHA1:", 10) == 0) /* found download command */
|
||||
+ return ((IPP2P_ARES * 100) + 2);
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ return 0;
|
||||
+} /*search_ares*/
|
||||
+
|
||||
+/*Search for SoulSeek commands*/
|
||||
+int
|
||||
+search_soul (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+//#define IPP2P_DEBUG_SOUL
|
||||
+ /* match: xx xx xx xx | xx = sizeof(payload) - 4 */
|
||||
+ if (get_u32(payload, 0) == (plen - 4)){
|
||||
+ const __u32 m=get_u32(payload, 4);
|
||||
+ /* match 00 yy yy 00, yy can be everything */
|
||||
+ if ( get_u8(payload, 4) == 0x00 && get_u8(payload, 7) == 0x00 )
|
||||
+ {
|
||||
+#ifdef IPP2P_DEBUG_SOUL
|
||||
+ printk(KERN_DEBUG "0: Soulseek command 0x%x recognized\n",get_u32(payload, 4));
|
||||
+#endif /* IPP2P_DEBUG_SOUL */
|
||||
+ return ((IPP2P_SOUL * 100) + 1);
|
||||
+ }
|
||||
+
|
||||
+ /* next match: 01 yy 00 00 | yy can be everything */
|
||||
+ if ( get_u8(payload, 4) == 0x01 && get_u16(payload, 6) == 0x0000 )
|
||||
+ {
|
||||
+#ifdef IPP2P_DEBUG_SOUL
|
||||
+ printk(KERN_DEBUG "1: Soulseek command 0x%x recognized\n",get_u16(payload, 4));
|
||||
+#endif /* IPP2P_DEBUG_SOUL */
|
||||
+ return ((IPP2P_SOUL * 100) + 2);
|
||||
+ }
|
||||
+
|
||||
+ /* other soulseek commandos are: 1-5,7,9,13-18,22,23,26,28,35-37,40-46,50,51,60,62-69,91,92,1001 */
|
||||
+ /* try to do this in an intelligent way */
|
||||
+ /* get all small commandos */
|
||||
+ switch(m)
|
||||
+ {
|
||||
+ case 7:
|
||||
+ case 9:
|
||||
+ case 22:
|
||||
+ case 23:
|
||||
+ case 26:
|
||||
+ case 28:
|
||||
+ case 50:
|
||||
+ case 51:
|
||||
+ case 60:
|
||||
+ case 91:
|
||||
+ case 92:
|
||||
+ case 1001:
|
||||
+#ifdef IPP2P_DEBUG_SOUL
|
||||
+ printk(KERN_DEBUG "2: Soulseek command 0x%x recognized\n",get_u16(payload, 4));
|
||||
+#endif /* IPP2P_DEBUG_SOUL */
|
||||
+ return ((IPP2P_SOUL * 100) + 3);
|
||||
+ }
|
||||
+
|
||||
+ if (m > 0 && m < 6 )
|
||||
+ {
|
||||
+#ifdef IPP2P_DEBUG_SOUL
|
||||
+ printk(KERN_DEBUG "3: Soulseek command 0x%x recognized\n",get_u16(payload, 4));
|
||||
+#endif /* IPP2P_DEBUG_SOUL */
|
||||
+ return ((IPP2P_SOUL * 100) + 4);
|
||||
+ }
|
||||
+ if (m > 12 && m < 19 )
|
||||
+ {
|
||||
+#ifdef IPP2P_DEBUG_SOUL
|
||||
+ printk(KERN_DEBUG "4: Soulseek command 0x%x recognized\n",get_u16(payload, 4));
|
||||
+#endif /* IPP2P_DEBUG_SOUL */
|
||||
+ return ((IPP2P_SOUL * 100) + 5);
|
||||
+ }
|
||||
+
|
||||
+ if (m > 34 && m < 38 )
|
||||
+ {
|
||||
+#ifdef IPP2P_DEBUG_SOUL
|
||||
+ printk(KERN_DEBUG "5: Soulseek command 0x%x recognized\n",get_u16(payload, 4));
|
||||
+#endif /* IPP2P_DEBUG_SOUL */
|
||||
+ return ((IPP2P_SOUL * 100) + 6);
|
||||
+ }
|
||||
+
|
||||
+ if (m > 39 && m < 47 )
|
||||
+ {
|
||||
+#ifdef IPP2P_DEBUG_SOUL
|
||||
+ printk(KERN_DEBUG "6: Soulseek command 0x%x recognized\n",get_u16(payload, 4));
|
||||
+#endif /* IPP2P_DEBUG_SOUL */
|
||||
+ return ((IPP2P_SOUL * 100) + 7);
|
||||
+ }
|
||||
+
|
||||
+ if (m > 61 && m < 70 )
|
||||
+ {
|
||||
+#ifdef IPP2P_DEBUG_SOUL
|
||||
+ printk(KERN_DEBUG "7: Soulseek command 0x%x recognized\n",get_u16(payload, 4));
|
||||
+#endif /* IPP2P_DEBUG_SOUL */
|
||||
+ return ((IPP2P_SOUL * 100) + 8);
|
||||
+ }
|
||||
+
|
||||
+#ifdef IPP2P_DEBUG_SOUL
|
||||
+ printk(KERN_DEBUG "unknown SOULSEEK command: 0x%x, first 16 bit: 0x%x, first 8 bit: 0x%x ,soulseek ???\n",get_u32(payload, 4),get_u16(payload, 4) >> 16,get_u8(payload, 4) >> 24);
|
||||
+#endif /* IPP2P_DEBUG_SOUL */
|
||||
+ }
|
||||
+
|
||||
+ /* match 14 00 00 00 01 yy 00 00 00 STRING(YY) 01 00 00 00 00 46|50 00 00 00 00 */
|
||||
+ /* without size at the beginning !!! */
|
||||
+ if ( get_u32(payload, 0) == 0x14 && get_u8(payload, 4) == 0x01 )
|
||||
+ {
|
||||
+ __u32 y=get_u32(payload, 5);
|
||||
+ /* we need 19 chars + string */
|
||||
+ if ( (y + 19) <= (plen) )
|
||||
+ {
|
||||
+ const unsigned char *w=payload+9+y;
|
||||
+ if (get_u32(w, 0) == 0x01 && ( get_u16(w, 4) == 0x4600 || get_u16(w, 4) == 0x5000) && get_u32(w, 6) == 0x00);
|
||||
+#ifdef IPP2P_DEBUG_SOUL
|
||||
+ printk(KERN_DEBUG "Soulssek special client command recognized\n");
|
||||
+#endif /* IPP2P_DEBUG_SOUL */
|
||||
+ return ((IPP2P_SOUL * 100) + 9);
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*Search for WinMX commands*/
|
||||
+int
|
||||
+search_winmx (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+//#define IPP2P_DEBUG_WINMX
|
||||
+ if (((plen) == 4) && (memcmp(payload, "SEND", 4) == 0)) return ((IPP2P_WINMX * 100) + 1);
|
||||
+ if (((plen) == 3) && (memcmp(payload, "GET", 3) == 0)) return ((IPP2P_WINMX * 100) + 2);
|
||||
+ //if (packet_len < (head_len + 10)) return 0;
|
||||
+ if (plen < 10) return 0;
|
||||
+
|
||||
+ if ((memcmp(payload, "SEND", 4) == 0) || (memcmp(payload, "GET", 3) == 0)){
|
||||
+ u16 c=4;
|
||||
+ const u16 end=plen-2;
|
||||
+ u8 count=0;
|
||||
+ while (c < end)
|
||||
+ {
|
||||
+ if (payload[c]== 0x20 && payload[c+1] == 0x22)
|
||||
+ {
|
||||
+ c++;
|
||||
+ count++;
|
||||
+ if (count>=2) return ((IPP2P_WINMX * 100) + 3);
|
||||
+ }
|
||||
+ c++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ( plen == 149 && payload[0] == '8' )
|
||||
+ {
|
||||
+#ifdef IPP2P_DEBUG_WINMX
|
||||
+ printk(KERN_INFO "maybe WinMX\n");
|
||||
+#endif
|
||||
+ if (get_u32(payload,17) == 0 && get_u32(payload,21) == 0 && get_u32(payload,25) == 0 &&
|
||||
+// get_u32(payload,33) == __constant_htonl(0x71182b1a) && get_u32(payload,37) == __constant_htonl(0x05050000) &&
|
||||
+// get_u32(payload,133) == __constant_htonl(0x31097edf) && get_u32(payload,145) == __constant_htonl(0xdcb8f792))
|
||||
+ get_u16(payload,39) == 0 && get_u16(payload,135) == __constant_htons(0x7edf) && get_u16(payload,147) == __constant_htons(0xf792))
|
||||
+
|
||||
+ {
|
||||
+#ifdef IPP2P_DEBUG_WINMX
|
||||
+ printk(KERN_INFO "got WinMX\n");
|
||||
+#endif
|
||||
+ return ((IPP2P_WINMX * 100) + 4);
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+} /*search_winmx*/
|
||||
+
|
||||
+
|
||||
+/*Search for appleJuice commands*/
|
||||
+int
|
||||
+search_apple (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+ if ( (plen > 7) && (payload[6] == 0x0d) && (payload[7] == 0x0a) && (memcmp(payload, "ajprot", 6) == 0)) return (IPP2P_APPLE * 100);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*Search for BitTorrent commands*/
|
||||
+int
|
||||
+search_bittorrent (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+ if (plen > 20)
|
||||
+ {
|
||||
+ /* test for match 0x13+"BitTorrent protocol" */
|
||||
+ if (payload[0] == 0x13)
|
||||
+ {
|
||||
+ if (memcmp(payload+1, "BitTorrent protocol", 19) == 0) return (IPP2P_BIT * 100);
|
||||
+ }
|
||||
+
|
||||
+ /* get tracker commandos, all starts with GET /
|
||||
+ * then it can follow: scrape| announce
|
||||
+ * and then ?hash_info=
|
||||
+ */
|
||||
+ if (memcmp(payload,"GET /",5) == 0)
|
||||
+ {
|
||||
+ /* message scrape */
|
||||
+ if ( memcmp(payload+5,"scrape?info_hash=",17)==0 ) return (IPP2P_BIT * 100 + 1);
|
||||
+ /* message announce */
|
||||
+ if ( memcmp(payload+5,"announce?info_hash=",19)==0 ) return (IPP2P_BIT * 100 + 2);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* bitcomet encryptes the first packet, so we have to detect another
|
||||
+ * one later in the flow */
|
||||
+ /* first try failed, too many missdetections */
|
||||
+ //if ( size == 5 && get_u32(t,0) == __constant_htonl(1) && t[4] < 3) return (IPP2P_BIT * 100 + 3);
|
||||
+
|
||||
+ /* second try: block request packets */
|
||||
+ if ( plen == 17 && get_u32(payload,0) == __constant_htonl(0x0d) && payload[4] == 0x06 && get_u32(payload,13) == __constant_htonl(0x4000) ) return (IPP2P_BIT * 100 + 3);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
+/*check for Kazaa get command*/
|
||||
+int
|
||||
+search_kazaa (const unsigned char *payload, const u16 plen)
|
||||
+
|
||||
+{
|
||||
+ if ((payload[plen-2] == 0x0d) && (payload[plen-1] == 0x0a) && memcmp(payload, "GET /.hash=", 11) == 0)
|
||||
+ return (IPP2P_DATA_KAZAA * 100);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*check for gnutella get command*/
|
||||
+int
|
||||
+search_gnu (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+ if ((payload[plen-2] == 0x0d) && (payload[plen-1] == 0x0a))
|
||||
+ {
|
||||
+ if (memcmp(payload, "GET /get/", 9) == 0) return ((IPP2P_DATA_GNU * 100) + 1);
|
||||
+ if (memcmp(payload, "GET /uri-res/", 13) == 0) return ((IPP2P_DATA_GNU * 100) + 2);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*check for gnutella get commands and other typical data*/
|
||||
+int
|
||||
+search_all_gnu (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+
|
||||
+ if ((payload[plen-2] == 0x0d) && (payload[plen-1] == 0x0a))
|
||||
+ {
|
||||
+
|
||||
+ if (memcmp(payload, "GNUTELLA CONNECT/", 17) == 0) return ((IPP2P_GNU * 100) + 1);
|
||||
+ if (memcmp(payload, "GNUTELLA/", 9) == 0) return ((IPP2P_GNU * 100) + 2);
|
||||
+
|
||||
+
|
||||
+ if ((memcmp(payload, "GET /get/", 9) == 0) || (memcmp(payload, "GET /uri-res/", 13) == 0))
|
||||
+ {
|
||||
+ u16 c=8;
|
||||
+ const u16 end=plen-22;
|
||||
+ while (c < end) {
|
||||
+ if ( payload[c] == 0x0a && payload[c+1] == 0x0d && ((memcmp(&payload[c+2], "X-Gnutella-", 11) == 0) || (memcmp(&payload[c+2], "X-Queue:", 8) == 0)))
|
||||
+ return ((IPP2P_GNU * 100) + 3);
|
||||
+ c++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*check for KaZaA download commands and other typical data*/
|
||||
+int
|
||||
+search_all_kazaa (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+ if ((payload[plen-2] == 0x0d) && (payload[plen-1] == 0x0a))
|
||||
+ {
|
||||
+
|
||||
+ if (memcmp(payload, "GIVE ", 5) == 0) return ((IPP2P_KAZAA * 100) + 1);
|
||||
+
|
||||
+ if (memcmp(payload, "GET /", 5) == 0) {
|
||||
+ u16 c = 8;
|
||||
+ const u16 end=plen-22;
|
||||
+ while (c < end) {
|
||||
+ if ( payload[c] == 0x0a && payload[c+1] == 0x0d && ((memcmp(&payload[c+2], "X-Kazaa-Username: ", 18) == 0) || (memcmp(&payload[c+2], "User-Agent: PeerEnabler/", 24) == 0)))
|
||||
+ return ((IPP2P_KAZAA * 100) + 2);
|
||||
+ c++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*fast check for edonkey file segment transfer command*/
|
||||
+int
|
||||
+search_edk (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+ if (payload[0] != 0xe3)
|
||||
+ return 0;
|
||||
+ else {
|
||||
+ if (payload[5] == 0x47)
|
||||
+ return (IPP2P_DATA_EDK * 100);
|
||||
+ else
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
+/*intensive but slower search for some edonkey packets including size-check*/
|
||||
+int
|
||||
+search_all_edk (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+ if (payload[0] != 0xe3)
|
||||
+ return 0;
|
||||
+ else {
|
||||
+ //t += head_len;
|
||||
+ const u16 cmd = get_u16(payload, 1);
|
||||
+ if (cmd == (plen - 5)) {
|
||||
+ switch (payload[5]) {
|
||||
+ case 0x01: return ((IPP2P_EDK * 100) + 1); /*Client: hello or Server:hello*/
|
||||
+ case 0x4c: return ((IPP2P_EDK * 100) + 9); /*Client: Hello-Answer*/
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*fast check for Direct Connect send command*/
|
||||
+int
|
||||
+search_dc (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+
|
||||
+ if (payload[0] != 0x24 )
|
||||
+ return 0;
|
||||
+ else {
|
||||
+ if (memcmp(&payload[1], "Send|", 5) == 0)
|
||||
+ return (IPP2P_DATA_DC * 100);
|
||||
+ else
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*intensive but slower check for all direct connect packets*/
|
||||
+int
|
||||
+search_all_dc (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+// unsigned char *t = haystack;
|
||||
+
|
||||
+ if (payload[0] == 0x24 && payload[plen-1] == 0x7c)
|
||||
+ {
|
||||
+ const unsigned char *t=&payload[1];
|
||||
+ /* Client-Hub-Protocol */
|
||||
+ if (memcmp(t, "Lock ", 5) == 0) return ((IPP2P_DC * 100) + 1);
|
||||
+ /* Client-Client-Protocol, some are already recognized by client-hub (like lock) */
|
||||
+ if (memcmp(t, "MyNick ", 7) == 0) return ((IPP2P_DC * 100) + 38);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*check for mute*/
|
||||
+int
|
||||
+search_mute (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+ if ( plen == 209 || plen == 345 || plen == 473 || plen == 609 || plen == 1121 )
|
||||
+ {
|
||||
+ //printk(KERN_DEBUG "size hit: %u",size);
|
||||
+ if (memcmp(payload,"PublicKey: ",11) == 0 )
|
||||
+ {
|
||||
+ return ((IPP2P_MUTE * 100) + 0);
|
||||
+
|
||||
+/* if (memcmp(t+size-14,"\x0aEndPublicKey\x0a",14) == 0)
|
||||
+ {
|
||||
+ printk(KERN_DEBUG "end pubic key hit: %u",size);
|
||||
+
|
||||
+ }*/
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* check for xdcc */
|
||||
+int
|
||||
+search_xdcc (const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+ /* search in small packets only */
|
||||
+ if (plen > 20 && plen < 200 && payload[plen-1] == 0x0a && payload[plen-2] == 0x0d && memcmp(payload,"PRIVMSG ",8) == 0)
|
||||
+ {
|
||||
+
|
||||
+ u16 x=10;
|
||||
+ const u16 end=plen - 13;
|
||||
+
|
||||
+ /* is seems to be a irc private massage, chedck for xdcc command */
|
||||
+ while (x < end)
|
||||
+ {
|
||||
+ if (payload[x] == ':')
|
||||
+ {
|
||||
+ if ( memcmp(&payload[x+1],"xdcc send #",11) == 0 )
|
||||
+ return ((IPP2P_XDCC * 100) + 0);
|
||||
+ }
|
||||
+ x++;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* search for waste */
|
||||
+int search_waste(const unsigned char *payload, const u16 plen)
|
||||
+{
|
||||
+ if ( plen >= 8 && memcmp(payload,"GET.sha1:",9) == 0)
|
||||
+ return ((IPP2P_WASTE * 100) + 0);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static struct {
|
||||
+ int command;
|
||||
+ __u8 short_hand; /*for fucntions included in short hands*/
|
||||
+ int packet_len;
|
||||
+ int (*function_name) (const unsigned char *, const u16);
|
||||
+} matchlist[] = {
|
||||
+ {IPP2P_EDK,SHORT_HAND_IPP2P,20, &search_all_edk},
|
||||
+// {IPP2P_DATA_KAZAA,SHORT_HAND_DATA,200, &search_kazaa},
|
||||
+// {IPP2P_DATA_EDK,SHORT_HAND_DATA,60, &search_edk},
|
||||
+// {IPP2P_DATA_DC,SHORT_HAND_DATA,26, &search_dc},
|
||||
+ {IPP2P_DC,SHORT_HAND_IPP2P,5, search_all_dc},
|
||||
+// {IPP2P_DATA_GNU,SHORT_HAND_DATA,40, &search_gnu},
|
||||
+ {IPP2P_GNU,SHORT_HAND_IPP2P,5, &search_all_gnu},
|
||||
+ {IPP2P_KAZAA,SHORT_HAND_IPP2P,5, &search_all_kazaa},
|
||||
+ {IPP2P_BIT,SHORT_HAND_IPP2P,20, &search_bittorrent},
|
||||
+ {IPP2P_APPLE,SHORT_HAND_IPP2P,5, &search_apple},
|
||||
+ {IPP2P_SOUL,SHORT_HAND_IPP2P,5, &search_soul},
|
||||
+ {IPP2P_WINMX,SHORT_HAND_IPP2P,2, &search_winmx},
|
||||
+ {IPP2P_ARES,SHORT_HAND_IPP2P,5, &search_ares},
|
||||
+ {IPP2P_MUTE,SHORT_HAND_NONE,200, &search_mute},
|
||||
+ {IPP2P_WASTE,SHORT_HAND_NONE,5, &search_waste},
|
||||
+ {IPP2P_XDCC,SHORT_HAND_NONE,5, &search_xdcc},
|
||||
+ {0,0,0,NULL}
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static struct {
|
||||
+ int command;
|
||||
+ __u8 short_hand; /*for fucntions included in short hands*/
|
||||
+ int packet_len;
|
||||
+ int (*function_name) (unsigned char *, int);
|
||||
+} udp_list[] = {
|
||||
+ {IPP2P_KAZAA,SHORT_HAND_IPP2P,14, &udp_search_kazaa},
|
||||
+ {IPP2P_BIT,SHORT_HAND_IPP2P,23, &udp_search_bit},
|
||||
+ {IPP2P_GNU,SHORT_HAND_IPP2P,11, &udp_search_gnu},
|
||||
+ {IPP2P_EDK,SHORT_HAND_IPP2P,9, &udp_search_edk},
|
||||
+ {IPP2P_DC,SHORT_HAND_IPP2P,12, &udp_search_directconnect},
|
||||
+ {0,0,0,NULL}
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+match(const struct sk_buff *skb,
|
||||
+ const struct net_device *in,
|
||||
+ const struct net_device *out,
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
|
||||
+ const struct xt_match *match,
|
||||
+#endif
|
||||
+ const void *matchinfo,
|
||||
+ int offset,
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
|
||||
+ unsigned int protoff,
|
||||
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
|
||||
+ const void *hdr,
|
||||
+ u_int16_t datalen,
|
||||
+#endif
|
||||
+ int *hotdrop)
|
||||
+{
|
||||
+ const struct ipt_p2p_info *info = matchinfo;
|
||||
+ unsigned char *haystack;
|
||||
+ struct iphdr *ip = skb->nh.iph;
|
||||
+ int p2p_result = 0, i = 0;
|
||||
+// int head_len;
|
||||
+ int hlen = ntohs(ip->tot_len)-(ip->ihl*4); /*hlen = packet-data length*/
|
||||
+
|
||||
+ /*must not be a fragment*/
|
||||
+ if (offset) {
|
||||
+ if (info->debug) printk("IPP2P.match: offset found %i \n",offset);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /*make sure that skb is linear*/
|
||||
+ if(skb_is_nonlinear(skb)){
|
||||
+ if (info->debug) printk("IPP2P.match: nonlinear skb found\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ haystack=(char *)ip+(ip->ihl*4); /*haystack = packet data*/
|
||||
+
|
||||
+ switch (ip->protocol){
|
||||
+ case IPPROTO_TCP: /*what to do with a TCP packet*/
|
||||
+ {
|
||||
+ struct tcphdr *tcph = (void *) ip + ip->ihl * 4;
|
||||
+
|
||||
+ if (tcph->fin) return 0; /*if FIN bit is set bail out*/
|
||||
+ if (tcph->syn) return 0; /*if SYN bit is set bail out*/
|
||||
+ if (tcph->rst) return 0; /*if RST bit is set bail out*/
|
||||
+
|
||||
+ haystack += tcph->doff * 4; /*get TCP-Header-Size*/
|
||||
+ hlen -= tcph->doff * 4;
|
||||
+ while (matchlist[i].command) {
|
||||
+ if ((((info->cmd & matchlist[i].command) == matchlist[i].command) ||
|
||||
+ ((info->cmd & matchlist[i].short_hand) == matchlist[i].short_hand)) &&
|
||||
+ (hlen > matchlist[i].packet_len)) {
|
||||
+ p2p_result = matchlist[i].function_name(haystack, hlen);
|
||||
+ if (p2p_result)
|
||||
+ {
|
||||
+ if (info->debug) printk("IPP2P.debug:TCP-match: %i from: %u.%u.%u.%u:%i to: %u.%u.%u.%u:%i Length: %i\n",
|
||||
+ p2p_result, NIPQUAD(ip->saddr),ntohs(tcph->source), NIPQUAD(ip->daddr),ntohs(tcph->dest),hlen);
|
||||
+ return p2p_result;
|
||||
+ }
|
||||
+ }
|
||||
+ i++;
|
||||
+ }
|
||||
+ return p2p_result;
|
||||
+ }
|
||||
+
|
||||
+ case IPPROTO_UDP: /*what to do with an UDP packet*/
|
||||
+ {
|
||||
+ struct udphdr *udph = (void *) ip + ip->ihl * 4;
|
||||
+
|
||||
+ while (udp_list[i].command){
|
||||
+ if ((((info->cmd & udp_list[i].command) == udp_list[i].command) ||
|
||||
+ ((info->cmd & udp_list[i].short_hand) == udp_list[i].short_hand)) &&
|
||||
+ (hlen > udp_list[i].packet_len)) {
|
||||
+ p2p_result = udp_list[i].function_name(haystack, hlen);
|
||||
+ if (p2p_result){
|
||||
+ if (info->debug) printk("IPP2P.debug:UDP-match: %i from: %u.%u.%u.%u:%i to: %u.%u.%u.%u:%i Length: %i\n",
|
||||
+ p2p_result, NIPQUAD(ip->saddr),ntohs(udph->source), NIPQUAD(ip->daddr),ntohs(udph->dest),hlen);
|
||||
+ return p2p_result;
|
||||
+ }
|
||||
+ }
|
||||
+ i++;
|
||||
+ }
|
||||
+ return p2p_result;
|
||||
+ }
|
||||
+
|
||||
+ default: return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+checkentry(const char *tablename,
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
|
||||
+ const void *ip,
|
||||
+ const struct xt_match *match,
|
||||
+#else
|
||||
+ const struct ipt_ip *ip,
|
||||
+#endif
|
||||
+ void *matchinfo,
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
|
||||
+ unsigned int matchsize,
|
||||
+#endif
|
||||
+ unsigned int hook_mask)
|
||||
+{
|
||||
+ /* Must specify -p tcp */
|
||||
+/* if (ip->proto != IPPROTO_TCP || (ip->invflags & IPT_INV_PROTO)) {
|
||||
+ * printk("ipp2p: Only works on TCP packets, use -p tcp\n");
|
||||
+ * return 0;
|
||||
+ * }*/
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+static struct ipt_match ipp2p_match = {
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
|
||||
+ { NULL, NULL },
|
||||
+ "ipp2p",
|
||||
+ &match,
|
||||
+ &checkentry,
|
||||
+ NULL,
|
||||
+ THIS_MODULE
|
||||
+#endif
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
+ .name = "ipp2p",
|
||||
+ .match = &match,
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
|
||||
+ .matchsize = sizeof(struct ipt_p2p_info),
|
||||
+#endif
|
||||
+ .checkentry = &checkentry,
|
||||
+ .me = THIS_MODULE,
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static int __init init(void)
|
||||
+{
|
||||
+ printk(KERN_INFO "IPP2P v%s loading\n", IPP2P_VERSION);
|
||||
+ return ipt_register_match(&ipp2p_match);
|
||||
+}
|
||||
+
|
||||
+static void __exit fini(void)
|
||||
+{
|
||||
+ ipt_unregister_match(&ipp2p_match);
|
||||
+ printk(KERN_INFO "IPP2P v%s unloaded\n", IPP2P_VERSION);
|
||||
+}
|
||||
+
|
||||
+module_init(init);
|
||||
+module_exit(fini);
|
||||
+
|
||||
+
|
||||
diff -urN linux-2.6.19.old/net/ipv4/netfilter/Kconfig linux-2.6.19.dev/net/ipv4/netfilter/Kconfig
|
||||
--- linux-2.6.19.old/net/ipv4/netfilter/Kconfig 2006-12-14 03:13:39.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv4/netfilter/Kconfig 2006-12-14 03:13:39.000000000 +0100
|
||||
@@ -248,6 +248,12 @@
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
+config IP_NF_MATCH_IPP2P
|
||||
+ tristate "IPP2P"
|
||||
+ depends on IP_NF_IPTABLES
|
||||
+ help
|
||||
+ Module for matching traffic of various Peer-to-Peer applications
|
||||
+
|
||||
config IP_NF_MATCH_TOS
|
||||
tristate "TOS match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
diff -urN linux-2.6.19.old/net/ipv4/netfilter/Makefile linux-2.6.19.dev/net/ipv4/netfilter/Makefile
|
||||
--- linux-2.6.19.old/net/ipv4/netfilter/Makefile 2006-12-14 03:13:39.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv4/netfilter/Makefile 2006-12-14 03:13:39.000000000 +0100
|
||||
@@ -62,7 +62,7 @@
|
||||
obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
|
||||
-
|
||||
+obj-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_LAYER7) += ipt_layer7.o
|
||||
|
||||
# targets
|
||||
@@ -0,0 +1,171 @@
|
||||
diff -urN linux-2.6.19.old/include/net/xfrmudp.h linux-2.6.19.dev/include/net/xfrmudp.h
|
||||
--- linux-2.6.19.old/include/net/xfrmudp.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/include/net/xfrmudp.h 2006-12-14 03:13:41.000000000 +0100
|
||||
@@ -0,0 +1,10 @@
|
||||
+/*
|
||||
+ * pointer to function for type that xfrm4_input wants, to permit
|
||||
+ * decoupling of XFRM from udp.c
|
||||
+ */
|
||||
+#define HAVE_XFRM4_UDP_REGISTER
|
||||
+
|
||||
+typedef int (*xfrm4_rcv_encap_t)(struct sk_buff *skb, __u16 encap_type);
|
||||
+extern int udp4_register_esp_rcvencap(xfrm4_rcv_encap_t func
|
||||
+ , xfrm4_rcv_encap_t *oldfunc);
|
||||
+extern int udp4_unregister_esp_rcvencap(xfrm4_rcv_encap_t func);
|
||||
diff -urN linux-2.6.19.old/net/ipv4/Kconfig linux-2.6.19.dev/net/ipv4/Kconfig
|
||||
--- linux-2.6.19.old/net/ipv4/Kconfig 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv4/Kconfig 2006-12-14 03:13:41.000000000 +0100
|
||||
@@ -273,6 +273,12 @@
|
||||
Network), but can be distributed all over the Internet. If you want
|
||||
to do that, say Y here and to "IP multicast routing" below.
|
||||
|
||||
+config IPSEC_NAT_TRAVERSAL
|
||||
+ bool "IPSEC NAT-Traversal (KLIPS compatible)"
|
||||
+ depends on INET
|
||||
+ ---help---
|
||||
+ Includes support for RFC3947/RFC3948 NAT-Traversal of ESP over UDP.
|
||||
+
|
||||
config IP_MROUTE
|
||||
bool "IP: multicast routing"
|
||||
depends on IP_MULTICAST
|
||||
diff -urN linux-2.6.19.old/net/ipv4/udp.c linux-2.6.19.dev/net/ipv4/udp.c
|
||||
--- linux-2.6.19.old/net/ipv4/udp.c 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv4/udp.c 2006-12-14 03:13:41.000000000 +0100
|
||||
@@ -108,11 +108,14 @@
|
||||
#include <net/inet_common.h>
|
||||
#include <net/checksum.h>
|
||||
#include <net/xfrm.h>
|
||||
+#include <net/xfrmudp.h>
|
||||
|
||||
/*
|
||||
* Snmp MIB for the UDP layer
|
||||
*/
|
||||
|
||||
+static xfrm4_rcv_encap_t xfrm4_rcv_encap_func;
|
||||
+
|
||||
DEFINE_SNMP_STAT(struct udp_mib, udp_statistics) __read_mostly;
|
||||
|
||||
struct hlist_head udp_hash[UDP_HTABLE_SIZE];
|
||||
@@ -917,6 +920,42 @@
|
||||
sk_common_release(sk);
|
||||
}
|
||||
|
||||
+#if defined(CONFIG_XFRM) || defined(CONFIG_IPSEC_NAT_TRAVERSAL)
|
||||
+
|
||||
+/* if XFRM isn't a module, then register it directly. */
|
||||
+#if 0 && !defined(CONFIG_XFRM_MODULE) && !defined(CONFIG_IPSEC_NAT_TRAVERSAL)
|
||||
+static xfrm4_rcv_encap_t xfrm4_rcv_encap_func = xfrm4_rcv_encap;
|
||||
+#else
|
||||
+static xfrm4_rcv_encap_t xfrm4_rcv_encap_func = NULL;
|
||||
+#endif
|
||||
+
|
||||
+int udp4_register_esp_rcvencap(xfrm4_rcv_encap_t func
|
||||
+ , xfrm4_rcv_encap_t *oldfunc)
|
||||
+{
|
||||
+ if(oldfunc != NULL) {
|
||||
+ *oldfunc = xfrm4_rcv_encap_func;
|
||||
+ }
|
||||
+
|
||||
+#if 0
|
||||
+ if(xfrm4_rcv_encap_func != NULL)
|
||||
+ return -1;
|
||||
+#endif
|
||||
+
|
||||
+ xfrm4_rcv_encap_func = func;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int udp4_unregister_esp_rcvencap(xfrm4_rcv_encap_t func)
|
||||
+{
|
||||
+ if(xfrm4_rcv_encap_func != func)
|
||||
+ return -1;
|
||||
+
|
||||
+ xfrm4_rcv_encap_func = NULL;
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif /* CONFIG_XFRM_MODULE || CONFIG_IPSEC_NAT_TRAVERSAL */
|
||||
+
|
||||
+
|
||||
/* return:
|
||||
* 1 if the the UDP system should process it
|
||||
* 0 if we should drop this packet
|
||||
@@ -924,9 +963,9 @@
|
||||
*/
|
||||
static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
|
||||
{
|
||||
-#ifndef CONFIG_XFRM
|
||||
+#if !defined(CONFIG_XFRM) && !defined(CONFIG_IPSEC_NAT_TRAVERSAL)
|
||||
return 1;
|
||||
-#else
|
||||
+#else /* either CONFIG_XFRM or CONFIG_IPSEC_NAT_TRAVERSAL */
|
||||
struct udp_sock *up = udp_sk(sk);
|
||||
struct udphdr *uh;
|
||||
struct iphdr *iph;
|
||||
@@ -939,11 +978,11 @@
|
||||
/* if we're overly short, let UDP handle it */
|
||||
len = skb->len - sizeof(struct udphdr);
|
||||
if (len <= 0)
|
||||
- return 1;
|
||||
+ return 2;
|
||||
|
||||
/* if this is not encapsulated socket, then just return now */
|
||||
if (!encap_type)
|
||||
- return 1;
|
||||
+ return 3;
|
||||
|
||||
/* If this is a paged skb, make sure we pull up
|
||||
* whatever data we need to look at. */
|
||||
@@ -966,7 +1005,7 @@
|
||||
len = sizeof(struct udphdr);
|
||||
} else
|
||||
/* Must be an IKE packet.. pass it through */
|
||||
- return 1;
|
||||
+ return 4;
|
||||
break;
|
||||
case UDP_ENCAP_ESPINUDP_NON_IKE:
|
||||
/* Check if this is a keepalive packet. If so, eat it. */
|
||||
@@ -979,7 +1018,7 @@
|
||||
len = sizeof(struct udphdr) + 2 * sizeof(u32);
|
||||
} else
|
||||
/* Must be an IKE packet.. pass it through */
|
||||
- return 1;
|
||||
+ return 5;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -990,6 +1029,8 @@
|
||||
*/
|
||||
if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
|
||||
return 0;
|
||||
+ if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
|
||||
+ return 0;
|
||||
|
||||
/* Now we can update and verify the packet length... */
|
||||
iph = skb->nh.iph;
|
||||
@@ -1055,9 +1096,13 @@
|
||||
return 0;
|
||||
}
|
||||
if (ret < 0) {
|
||||
- /* process the ESP packet */
|
||||
- ret = xfrm4_rcv_encap(skb, up->encap_type);
|
||||
- UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS);
|
||||
+ if(xfrm4_rcv_encap_func != NULL) {
|
||||
+ ret = (*xfrm4_rcv_encap_func)(skb, up->encap_type);
|
||||
+ UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS);
|
||||
+ } else {
|
||||
+ UDP_INC_STATS_BH(UDP_MIB_INERRORS);
|
||||
+ ret = 1;
|
||||
+ }
|
||||
return -ret;
|
||||
}
|
||||
/* FALLTHROUGH -- it's a UDP Packet */
|
||||
@@ -1639,3 +1684,9 @@
|
||||
EXPORT_SYMBOL(udp_proc_register);
|
||||
EXPORT_SYMBOL(udp_proc_unregister);
|
||||
#endif
|
||||
+
|
||||
+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL)
|
||||
+EXPORT_SYMBOL(udp4_register_esp_rcvencap);
|
||||
+EXPORT_SYMBOL(udp4_unregister_esp_rcvencap);
|
||||
+#endif
|
||||
+
|
||||
5851
target/linux/etrax/patches/generic_2.6/130-netfilter-ipset.patch
Normal file
5851
target/linux/etrax/patches/generic_2.6/130-netfilter-ipset.patch
Normal file
File diff suppressed because it is too large
Load Diff
241
target/linux/etrax/patches/generic_2.6/140-netfilter_time.patch
Normal file
241
target/linux/etrax/patches/generic_2.6/140-netfilter_time.patch
Normal file
@@ -0,0 +1,241 @@
|
||||
diff -urN linux-2.6.19.old/include/linux/netfilter_ipv4/ipt_time.h linux-2.6.19.dev/include/linux/netfilter_ipv4/ipt_time.h
|
||||
--- linux-2.6.19.old/include/linux/netfilter_ipv4/ipt_time.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/include/linux/netfilter_ipv4/ipt_time.h 2006-12-14 03:13:45.000000000 +0100
|
||||
@@ -0,0 +1,18 @@
|
||||
+#ifndef __ipt_time_h_included__
|
||||
+#define __ipt_time_h_included__
|
||||
+
|
||||
+
|
||||
+struct ipt_time_info {
|
||||
+ u_int8_t days_match; /* 1 bit per day. -SMTWTFS */
|
||||
+ u_int16_t time_start; /* 0 < time_start < 23*60+59 = 1439 */
|
||||
+ u_int16_t time_stop; /* 0:0 < time_stat < 23:59 */
|
||||
+
|
||||
+ /* FIXME: Keep this one for userspace iptables binary compability: */
|
||||
+ u_int8_t kerneltime; /* ignore skb time (and use kerneltime) or not. */
|
||||
+
|
||||
+ time_t date_start;
|
||||
+ time_t date_stop;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#endif /* __ipt_time_h_included__ */
|
||||
diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_time.c linux-2.6.19.dev/net/ipv4/netfilter/ipt_time.c
|
||||
--- linux-2.6.19.old/net/ipv4/netfilter/ipt_time.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv4/netfilter/ipt_time.c 2006-12-14 03:13:45.000000000 +0100
|
||||
@@ -0,0 +1,178 @@
|
||||
+/*
|
||||
+ This is a module which is used for time matching
|
||||
+ It is using some modified code from dietlibc (localtime() function)
|
||||
+ that you can find at http://www.fefe.de/dietlibc/
|
||||
+ This file is distributed under the terms of the GNU General Public
|
||||
+ License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
|
||||
+ 2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development.
|
||||
+ 2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code,
|
||||
+ thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report.
|
||||
+ 2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only.
|
||||
+ 2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
|
||||
+ added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones.
|
||||
+ 2004-05-02 Fabrice : added support for date matching, from an idea of Fabien COELHO.
|
||||
+*/
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
+#include <linux/netfilter_ipv4/ipt_time.h>
|
||||
+#include <linux/time.h>
|
||||
+
|
||||
+MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
|
||||
+MODULE_DESCRIPTION("Match arrival timestamp/date");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+struct tm
|
||||
+{
|
||||
+ int tm_sec; /* Seconds. [0-60] (1 leap second) */
|
||||
+ int tm_min; /* Minutes. [0-59] */
|
||||
+ int tm_hour; /* Hours. [0-23] */
|
||||
+ int tm_mday; /* Day. [1-31] */
|
||||
+ int tm_mon; /* Month. [0-11] */
|
||||
+ int tm_year; /* Year - 1900. */
|
||||
+ int tm_wday; /* Day of week. [0-6] */
|
||||
+ int tm_yday; /* Days in year.[0-365] */
|
||||
+ int tm_isdst; /* DST. [-1/0/1]*/
|
||||
+
|
||||
+ long int tm_gmtoff; /* we don't care, we count from GMT */
|
||||
+ const char *tm_zone; /* we don't care, we count from GMT */
|
||||
+};
|
||||
+
|
||||
+void
|
||||
+localtime(const u32 time, struct tm *r);
|
||||
+
|
||||
+static int
|
||||
+match(const struct sk_buff *skb,
|
||||
+ const struct net_device *in,
|
||||
+ const struct net_device *out,
|
||||
+ const struct xt_match *match,
|
||||
+ const void *matchinfo,
|
||||
+ int offset,
|
||||
+ unsigned int protoff,
|
||||
+ int *hotdrop)
|
||||
+{
|
||||
+ const struct ipt_time_info *info = matchinfo; /* match info for rule */
|
||||
+ struct tm currenttime; /* time human readable */
|
||||
+ u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
|
||||
+ u_int16_t packet_time;
|
||||
+
|
||||
+ /* We might not have a timestamp, get one */
|
||||
+ if (skb->tstamp.off_sec == 0)
|
||||
+ __net_timestamp((struct sk_buff *)skb);
|
||||
+
|
||||
+ /* First we make sure we are in the date start-stop boundaries */
|
||||
+ if ((skb->tstamp.off_sec < info->date_start) || (skb->tstamp.off_sec > info->date_stop))
|
||||
+ return 0; /* We are outside the date boundaries */
|
||||
+
|
||||
+ /* Transform the timestamp of the packet, in a human readable form */
|
||||
+ localtime(skb->tstamp.off_sec, ¤ttime);
|
||||
+
|
||||
+ /* check if we match this timestamp, we start by the days... */
|
||||
+ if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
|
||||
+ return 0; /* the day doesn't match */
|
||||
+
|
||||
+ /* ... check the time now */
|
||||
+ packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
|
||||
+ if ((packet_time < info->time_start) || (packet_time > info->time_stop))
|
||||
+ return 0;
|
||||
+
|
||||
+ /* here we match ! */
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+checkentry(const char *tablename,
|
||||
+ const void *ip,
|
||||
+ const struct xt_match *match,
|
||||
+ void *matchinfo,
|
||||
+ unsigned int hook_mask)
|
||||
+{
|
||||
+ struct ipt_time_info *info = matchinfo; /* match info for rule */
|
||||
+
|
||||
+ /* First, check that we are in the correct hooks */
|
||||
+ if (hook_mask
|
||||
+ & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
|
||||
+ {
|
||||
+ printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Now check the coherence of the data ... */
|
||||
+ if ((info->time_start > 1439) || /* 23*60+59 = 1439*/
|
||||
+ (info->time_stop > 1439))
|
||||
+ {
|
||||
+ printk(KERN_WARNING "ipt_time: invalid argument\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static struct ipt_match time_match = {
|
||||
+ .name = "time",
|
||||
+ .match = &match,
|
||||
+ .matchsize = sizeof(struct ipt_time_info),
|
||||
+ .checkentry = &checkentry,
|
||||
+ .me = THIS_MODULE
|
||||
+};
|
||||
+
|
||||
+static int __init init(void)
|
||||
+{
|
||||
+ printk("ipt_time loading\n");
|
||||
+ return ipt_register_match(&time_match);
|
||||
+}
|
||||
+
|
||||
+static void __exit fini(void)
|
||||
+{
|
||||
+ ipt_unregister_match(&time_match);
|
||||
+ printk("ipt_time unloaded\n");
|
||||
+}
|
||||
+
|
||||
+module_init(init);
|
||||
+module_exit(fini);
|
||||
+
|
||||
+
|
||||
+/* The part below is borowed and modified from dietlibc */
|
||||
+
|
||||
+/* seconds per day */
|
||||
+#define SPD 24*60*60
|
||||
+
|
||||
+void
|
||||
+localtime(const u32 time, struct tm *r) {
|
||||
+ u32 i, timep;
|
||||
+ extern struct timezone sys_tz;
|
||||
+ const unsigned int __spm[12] =
|
||||
+ { 0,
|
||||
+ (31),
|
||||
+ (31+28),
|
||||
+ (31+28+31),
|
||||
+ (31+28+31+30),
|
||||
+ (31+28+31+30+31),
|
||||
+ (31+28+31+30+31+30),
|
||||
+ (31+28+31+30+31+30+31),
|
||||
+ (31+28+31+30+31+30+31+31),
|
||||
+ (31+28+31+30+31+30+31+31+30),
|
||||
+ (31+28+31+30+31+30+31+31+30+31),
|
||||
+ (31+28+31+30+31+30+31+31+30+31+30),
|
||||
+ };
|
||||
+ register u32 work;
|
||||
+
|
||||
+ timep = time - (sys_tz.tz_minuteswest * 60);
|
||||
+ work=timep%(SPD);
|
||||
+ r->tm_sec=work%60; work/=60;
|
||||
+ r->tm_min=work%60; r->tm_hour=work/60;
|
||||
+ work=timep/(SPD);
|
||||
+ r->tm_wday=(4+work)%7;
|
||||
+ for (i=1970; ; ++i) {
|
||||
+ register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
|
||||
+ if (work>k)
|
||||
+ work-=k;
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+ r->tm_year=i-1900;
|
||||
+ for (i=11; i && __spm[i]>work; --i) ;
|
||||
+ r->tm_mon=i;
|
||||
+ r->tm_mday=work-__spm[i]+1;
|
||||
+}
|
||||
diff -urN linux-2.6.19.old/net/ipv4/netfilter/Kconfig linux-2.6.19.dev/net/ipv4/netfilter/Kconfig
|
||||
--- linux-2.6.19.old/net/ipv4/netfilter/Kconfig 2006-12-14 03:13:45.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv4/netfilter/Kconfig 2006-12-14 03:13:45.000000000 +0100
|
||||
@@ -263,6 +263,22 @@
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
+
|
||||
+config IP_NF_MATCH_TIME
|
||||
+ tristate 'TIME match support'
|
||||
+ depends on IP_NF_IPTABLES
|
||||
+ help
|
||||
+ This option adds a `time' match, which allows you
|
||||
+ to match based on the packet arrival time/date
|
||||
+ (arrival time/date at the machine which netfilter is running on) or
|
||||
+ departure time/date (for locally generated packets).
|
||||
+
|
||||
+ If you say Y here, try iptables -m time --help for more information.
|
||||
+ If you want to compile it as a module, say M here and read
|
||||
+
|
||||
+ Documentation/modules.txt. If unsure, say `N'.
|
||||
+
|
||||
+
|
||||
config IP_NF_MATCH_RECENT
|
||||
tristate "recent match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
diff -urN linux-2.6.19.old/net/ipv4/netfilter/Makefile linux-2.6.19.dev/net/ipv4/netfilter/Makefile
|
||||
--- linux-2.6.19.old/net/ipv4/netfilter/Makefile 2006-12-14 03:13:45.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv4/netfilter/Makefile 2006-12-14 03:13:45.000000000 +0100
|
||||
@@ -58,6 +58,7 @@
|
||||
obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
|
||||
+obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
|
||||
892
target/linux/etrax/patches/generic_2.6/150-netfilter_imq.patch
Normal file
892
target/linux/etrax/patches/generic_2.6/150-netfilter_imq.patch
Normal file
@@ -0,0 +1,892 @@
|
||||
diff -urN linux-2.6.19/drivers/net/imq.c linux-2.6.19+imq/drivers/net/imq.c
|
||||
--- linux-2.6.19/drivers/net/imq.c 1970-01-01 09:30:00.000000000 +0930
|
||||
+++ linux-2.6.19+imq/drivers/net/imq.c 2006-12-05 23:01:02.000000000 +1030
|
||||
@@ -0,0 +1,402 @@
|
||||
+/*
|
||||
+ * Pseudo-driver for the intermediate queue device.
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Authors: Patrick McHardy, <kaber@trash.net>
|
||||
+ *
|
||||
+ * The first version was written by Martin Devera, <devik@cdi.cz>
|
||||
+ *
|
||||
+ * Credits: Jan Rafaj <imq2t@cedric.vabo.cz>
|
||||
+ * - Update patch to 2.4.21
|
||||
+ * Sebastian Strollo <sstrollo@nortelnetworks.com>
|
||||
+ * - Fix "Dead-loop on netdevice imq"-issue
|
||||
+ * Marcel Sebek <sebek64@post.cz>
|
||||
+ * - Update to 2.6.2-rc1
|
||||
+ *
|
||||
+ * After some time of inactivity there is a group taking care
|
||||
+ * of IMQ again: http://www.linuximq.net
|
||||
+ *
|
||||
+ *
|
||||
+ * 2004/06/30 - New version of IMQ patch to kernels <=2.6.7 including
|
||||
+ * the following changes:
|
||||
+ *
|
||||
+ * - Correction of ipv6 support "+"s issue (Hasso Tepper)
|
||||
+ * - Correction of imq_init_devs() issue that resulted in
|
||||
+ * kernel OOPS unloading IMQ as module (Norbert Buchmuller)
|
||||
+ * - Addition of functionality to choose number of IMQ devices
|
||||
+ * during kernel config (Andre Correa)
|
||||
+ * - Addition of functionality to choose how IMQ hooks on
|
||||
+ * PRE and POSTROUTING (after or before NAT) (Andre Correa)
|
||||
+ * - Cosmetic corrections (Norbert Buchmuller) (Andre Correa)
|
||||
+ *
|
||||
+ *
|
||||
+ * 2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were
|
||||
+ * released with almost no problems. 2.6.14-x was released
|
||||
+ * with some important changes: nfcache was removed; After
|
||||
+ * some weeks of trouble we figured out that some IMQ fields
|
||||
+ * in skb were missing in skbuff.c - skb_clone and copy_skb_header.
|
||||
+ * These functions are correctly patched by this new patch version.
|
||||
+ *
|
||||
+ * Thanks for all who helped to figure out all the problems with
|
||||
+ * 2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX,
|
||||
+ * Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully
|
||||
+ * I didn't forget anybody). I apologize again for my lack of time.
|
||||
+ *
|
||||
+ * More info at: http://www.linuximq.net/ (Andre Correa)
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/moduleparam.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/netdevice.h>
|
||||
+#include <linux/rtnetlink.h>
|
||||
+#include <linux/if_arp.h>
|
||||
+#include <linux/netfilter.h>
|
||||
+#include <linux/netfilter_ipv4.h>
|
||||
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
|
||||
+ #include <linux/netfilter_ipv6.h>
|
||||
+#endif
|
||||
+#include <linux/imq.h>
|
||||
+#include <net/pkt_sched.h>
|
||||
+
|
||||
+extern int qdisc_restart1(struct net_device *dev);
|
||||
+
|
||||
+static nf_hookfn imq_nf_hook;
|
||||
+
|
||||
+static struct nf_hook_ops imq_ingress_ipv4 = {
|
||||
+ .hook = imq_nf_hook,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .pf = PF_INET,
|
||||
+ .hooknum = NF_IP_PRE_ROUTING,
|
||||
+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
|
||||
+ .priority = NF_IP_PRI_MANGLE + 1
|
||||
+#else
|
||||
+ .priority = NF_IP_PRI_NAT_DST + 1
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+static struct nf_hook_ops imq_egress_ipv4 = {
|
||||
+ .hook = imq_nf_hook,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .pf = PF_INET,
|
||||
+ .hooknum = NF_IP_POST_ROUTING,
|
||||
+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
|
||||
+ .priority = NF_IP_PRI_LAST
|
||||
+#else
|
||||
+ .priority = NF_IP_PRI_NAT_SRC - 1
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
|
||||
+static struct nf_hook_ops imq_ingress_ipv6 = {
|
||||
+ .hook = imq_nf_hook,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .pf = PF_INET6,
|
||||
+ .hooknum = NF_IP6_PRE_ROUTING,
|
||||
+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
|
||||
+ .priority = NF_IP6_PRI_MANGLE + 1
|
||||
+#else
|
||||
+ .priority = NF_IP6_PRI_NAT_DST + 1
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+static struct nf_hook_ops imq_egress_ipv6 = {
|
||||
+ .hook = imq_nf_hook,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .pf = PF_INET6,
|
||||
+ .hooknum = NF_IP6_POST_ROUTING,
|
||||
+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA)
|
||||
+ .priority = NF_IP6_PRI_LAST
|
||||
+#else
|
||||
+ .priority = NF_IP6_PRI_NAT_SRC - 1
|
||||
+#endif
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+#if defined(CONFIG_IMQ_NUM_DEVS)
|
||||
+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS;
|
||||
+#else
|
||||
+static unsigned int numdevs = 2;
|
||||
+#endif
|
||||
+
|
||||
+static struct net_device *imq_devs;
|
||||
+
|
||||
+static struct net_device_stats *imq_get_stats(struct net_device *dev)
|
||||
+{
|
||||
+ return (struct net_device_stats *)dev->priv;
|
||||
+}
|
||||
+
|
||||
+/* called for packets kfree'd in qdiscs at places other than enqueue */
|
||||
+static void imq_skb_destructor(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct nf_info *info = skb->nf_info;
|
||||
+
|
||||
+ if (info) {
|
||||
+ if (info->indev)
|
||||
+ dev_put(info->indev);
|
||||
+ if (info->outdev)
|
||||
+ dev_put(info->outdev);
|
||||
+ kfree(info);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
+{
|
||||
+ struct net_device_stats *stats = (struct net_device_stats*) dev->priv;
|
||||
+
|
||||
+ stats->tx_bytes += skb->len;
|
||||
+ stats->tx_packets++;
|
||||
+
|
||||
+ skb->imq_flags = 0;
|
||||
+ skb->destructor = NULL;
|
||||
+
|
||||
+ dev->trans_start = jiffies;
|
||||
+ nf_reinject(skb, skb->nf_info, NF_ACCEPT);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int imq_nf_queue(struct sk_buff *skb, struct nf_info *info, unsigned queue_num, void *data)
|
||||
+{
|
||||
+ struct net_device *dev;
|
||||
+ struct net_device_stats *stats;
|
||||
+ struct sk_buff *skb2 = NULL;
|
||||
+ struct Qdisc *q;
|
||||
+ unsigned int index = skb->imq_flags&IMQ_F_IFMASK;
|
||||
+ int ret = -1;
|
||||
+
|
||||
+ if (index > numdevs)
|
||||
+ return -1;
|
||||
+
|
||||
+ dev = imq_devs + index;
|
||||
+ if (!(dev->flags & IFF_UP)) {
|
||||
+ skb->imq_flags = 0;
|
||||
+ nf_reinject(skb, info, NF_ACCEPT);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ dev->last_rx = jiffies;
|
||||
+
|
||||
+ if (skb->destructor) {
|
||||
+ skb2 = skb;
|
||||
+ skb = skb_clone(skb, GFP_ATOMIC);
|
||||
+ if (!skb)
|
||||
+ return -1;
|
||||
+ }
|
||||
+ skb->nf_info = info;
|
||||
+
|
||||
+ stats = (struct net_device_stats *)dev->priv;
|
||||
+ stats->rx_bytes+= skb->len;
|
||||
+ stats->rx_packets++;
|
||||
+
|
||||
+ spin_lock_bh(&dev->queue_lock);
|
||||
+ q = dev->qdisc;
|
||||
+ if (q->enqueue) {
|
||||
+ q->enqueue(skb_get(skb), q);
|
||||
+ if (skb_shared(skb)) {
|
||||
+ skb->destructor = imq_skb_destructor;
|
||||
+ kfree_skb(skb);
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ if (spin_is_locked(&dev->_xmit_lock))
|
||||
+ netif_schedule(dev);
|
||||
+ else
|
||||
+ while (!netif_queue_stopped(dev) && qdisc_restart1(dev) < 0)
|
||||
+ /* NOTHING */;
|
||||
+
|
||||
+ spin_unlock_bh(&dev->queue_lock);
|
||||
+
|
||||
+ if (skb2)
|
||||
+ kfree_skb(ret ? skb : skb2);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct nf_queue_handler nfqh = {
|
||||
+ .name = "imq",
|
||||
+ .outfn = imq_nf_queue,
|
||||
+};
|
||||
+
|
||||
+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff **pskb,
|
||||
+ const struct net_device *indev,
|
||||
+ const struct net_device *outdev,
|
||||
+ int (*okfn)(struct sk_buff *))
|
||||
+{
|
||||
+ if ((*pskb)->imq_flags & IMQ_F_ENQUEUE)
|
||||
+ return NF_QUEUE;
|
||||
+
|
||||
+ return NF_ACCEPT;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int __init imq_init_hooks(void)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ err = nf_register_queue_handler(PF_INET, &nfqh);
|
||||
+ if (err > 0)
|
||||
+ goto err1;
|
||||
+ if ((err = nf_register_hook(&imq_ingress_ipv4)))
|
||||
+ goto err2;
|
||||
+ if ((err = nf_register_hook(&imq_egress_ipv4)))
|
||||
+ goto err3;
|
||||
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
|
||||
+ if ((err = nf_register_queue_handler(PF_INET6, &nfqh)))
|
||||
+ goto err4;
|
||||
+ if ((err = nf_register_hook(&imq_ingress_ipv6)))
|
||||
+ goto err5;
|
||||
+ if ((err = nf_register_hook(&imq_egress_ipv6)))
|
||||
+ goto err6;
|
||||
+#endif
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
|
||||
+err6:
|
||||
+ nf_unregister_hook(&imq_ingress_ipv6);
|
||||
+err5:
|
||||
+ nf_unregister_queue_handler(PF_INET6);
|
||||
+err4:
|
||||
+ nf_unregister_hook(&imq_egress_ipv6);
|
||||
+#endif
|
||||
+err3:
|
||||
+ nf_unregister_hook(&imq_ingress_ipv4);
|
||||
+err2:
|
||||
+ nf_unregister_queue_handler(PF_INET);
|
||||
+err1:
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void __exit imq_unhook(void)
|
||||
+{
|
||||
+ nf_unregister_hook(&imq_ingress_ipv4);
|
||||
+ nf_unregister_hook(&imq_egress_ipv4);
|
||||
+ nf_unregister_queue_handler(PF_INET);
|
||||
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
|
||||
+ nf_unregister_hook(&imq_ingress_ipv6);
|
||||
+ nf_unregister_hook(&imq_egress_ipv6);
|
||||
+ nf_unregister_queue_handler(PF_INET6);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+static int __init imq_dev_init(struct net_device *dev)
|
||||
+{
|
||||
+ dev->hard_start_xmit = imq_dev_xmit;
|
||||
+ dev->type = ARPHRD_VOID;
|
||||
+ dev->mtu = 1500;
|
||||
+ dev->tx_queue_len = 30;
|
||||
+ dev->flags = IFF_NOARP;
|
||||
+ dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
|
||||
+ if (dev->priv == NULL)
|
||||
+ return -ENOMEM;
|
||||
+ memset(dev->priv, 0, sizeof(struct net_device_stats));
|
||||
+ dev->get_stats = imq_get_stats;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void imq_dev_uninit(struct net_device *dev)
|
||||
+{
|
||||
+ kfree(dev->priv);
|
||||
+}
|
||||
+
|
||||
+static int __init imq_init_devs(void)
|
||||
+{
|
||||
+ struct net_device *dev;
|
||||
+ int i,j;
|
||||
+ j = numdevs;
|
||||
+
|
||||
+ if (!numdevs || numdevs > IMQ_MAX_DEVS) {
|
||||
+ printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n",
|
||||
+ IMQ_MAX_DEVS);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ imq_devs = kmalloc(sizeof(struct net_device) * numdevs, GFP_KERNEL);
|
||||
+ if (!imq_devs)
|
||||
+ return -ENOMEM;
|
||||
+ memset(imq_devs, 0, sizeof(struct net_device) * numdevs);
|
||||
+
|
||||
+ /* we start counting at zero */
|
||||
+ numdevs--;
|
||||
+
|
||||
+ for (i = 0, dev = imq_devs; i <= numdevs; i++, dev++) {
|
||||
+ SET_MODULE_OWNER(dev);
|
||||
+ strcpy(dev->name, "imq%d");
|
||||
+ dev->init = imq_dev_init;
|
||||
+ dev->uninit = imq_dev_uninit;
|
||||
+
|
||||
+ if (register_netdev(dev) < 0)
|
||||
+ goto err_register;
|
||||
+ }
|
||||
+ printk(KERN_INFO "IMQ starting with %u devices...\n", j);
|
||||
+ return 0;
|
||||
+
|
||||
+err_register:
|
||||
+ for (; i; i--)
|
||||
+ unregister_netdev(--dev);
|
||||
+ kfree(imq_devs);
|
||||
+ return -EIO;
|
||||
+}
|
||||
+
|
||||
+static void imq_cleanup_devs(void)
|
||||
+{
|
||||
+ int i;
|
||||
+ struct net_device *dev = imq_devs;
|
||||
+
|
||||
+ for (i = 0; i <= numdevs; i++)
|
||||
+ unregister_netdev(dev++);
|
||||
+
|
||||
+ kfree(imq_devs);
|
||||
+}
|
||||
+
|
||||
+static int __init imq_init_module(void)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ if ((err = imq_init_devs())) {
|
||||
+ printk(KERN_ERR "IMQ: Error trying imq_init_devs()\n");
|
||||
+ return err;
|
||||
+ }
|
||||
+ if ((err = imq_init_hooks())) {
|
||||
+ printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n");
|
||||
+ imq_cleanup_devs();
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ printk(KERN_INFO "IMQ driver loaded successfully.\n");
|
||||
+
|
||||
+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB)
|
||||
+ printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n");
|
||||
+#else
|
||||
+ printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n");
|
||||
+#endif
|
||||
+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB)
|
||||
+ printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n");
|
||||
+#else
|
||||
+ printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n");
|
||||
+#endif
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __exit imq_cleanup_module(void)
|
||||
+{
|
||||
+ imq_unhook();
|
||||
+ imq_cleanup_devs();
|
||||
+ printk(KERN_INFO "IMQ driver unloaded successfully.\n");
|
||||
+}
|
||||
+
|
||||
+
|
||||
+module_init(imq_init_module);
|
||||
+module_exit(imq_cleanup_module);
|
||||
+
|
||||
+module_param(numdevs, int, 0);
|
||||
+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will be created)");
|
||||
+MODULE_AUTHOR("http://www.linuximq.net");
|
||||
+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff -urN linux-2.6.19/drivers/net/Kconfig linux-2.6.19+imq/drivers/net/Kconfig
|
||||
--- linux-2.6.19/drivers/net/Kconfig 2006-12-01 14:05:30.000000000 +1030
|
||||
+++ linux-2.6.19+imq/drivers/net/Kconfig 2006-12-05 23:03:52.000000000 +1030
|
||||
@@ -96,6 +96,129 @@
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called eql. If unsure, say N.
|
||||
|
||||
+config IMQ
|
||||
+ tristate "IMQ (intermediate queueing device) support"
|
||||
+ depends on NETDEVICES && NETFILTER
|
||||
+ ---help---
|
||||
+ The IMQ device(s) is used as placeholder for QoS queueing
|
||||
+ disciplines. Every packet entering/leaving the IP stack can be
|
||||
+ directed through the IMQ device where it's enqueued/dequeued to the
|
||||
+ attached qdisc. This allows you to treat network devices as classes
|
||||
+ and distribute bandwidth among them. Iptables is used to specify
|
||||
+ through which IMQ device, if any, packets travel.
|
||||
+
|
||||
+ More information at: http://www.linuximq.net/
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called imq. If unsure, say N.
|
||||
+
|
||||
+choice
|
||||
+ prompt "IMQ behavior (PRE/POSTROUTING)"
|
||||
+ depends on IMQ
|
||||
+ default IMQ_BEHAVIOR_BA
|
||||
+ help
|
||||
+
|
||||
+ This settings defines how IMQ behaves in respect to its
|
||||
+ hooking in PREROUTING and POSTROUTING.
|
||||
+
|
||||
+ IMQ can work in any of the following ways:
|
||||
+
|
||||
+ PREROUTING | POSTROUTING
|
||||
+ -----------------|-------------------
|
||||
+ #1 After NAT | After NAT
|
||||
+ #2 After NAT | Before NAT
|
||||
+ #3 Before NAT | After NAT
|
||||
+ #4 Before NAT | Before NAT
|
||||
+
|
||||
+ The default behavior is to hook before NAT on PREROUTING
|
||||
+ and after NAT on POSTROUTING (#3).
|
||||
+
|
||||
+ This settings are specially usefull when trying to use IMQ
|
||||
+ to shape NATed clients.
|
||||
+
|
||||
+ More information can be found at: www.linuximq.net
|
||||
+
|
||||
+ If not sure leave the default settings alone.
|
||||
+
|
||||
+config IMQ_BEHAVIOR_AA
|
||||
+ bool "IMQ AA"
|
||||
+ help
|
||||
+ This settings defines how IMQ behaves in respect to its
|
||||
+ hooking in PREROUTING and POSTROUTING.
|
||||
+
|
||||
+ Choosing this option will make IMQ hook like this:
|
||||
+
|
||||
+ PREROUTING: After NAT
|
||||
+ POSTROUTING: After NAT
|
||||
+
|
||||
+ More information can be found at: www.linuximq.net
|
||||
+
|
||||
+ If not sure leave the default settings alone.
|
||||
+
|
||||
+config IMQ_BEHAVIOR_AB
|
||||
+ bool "IMQ AB"
|
||||
+ help
|
||||
+ This settings defines how IMQ behaves in respect to its
|
||||
+ hooking in PREROUTING and POSTROUTING.
|
||||
+
|
||||
+ Choosing this option will make IMQ hook like this:
|
||||
+
|
||||
+ PREROUTING: After NAT
|
||||
+ POSTROUTING: Before NAT
|
||||
+
|
||||
+ More information can be found at: www.linuximq.net
|
||||
+
|
||||
+ If not sure leave the default settings alone.
|
||||
+
|
||||
+config IMQ_BEHAVIOR_BA
|
||||
+ bool "IMQ BA"
|
||||
+ help
|
||||
+ This settings defines how IMQ behaves in respect to its
|
||||
+ hooking in PREROUTING and POSTROUTING.
|
||||
+
|
||||
+ Choosing this option will make IMQ hook like this:
|
||||
+
|
||||
+ PREROUTING: Before NAT
|
||||
+ POSTROUTING: After NAT
|
||||
+
|
||||
+ More information can be found at: www.linuximq.net
|
||||
+
|
||||
+ If not sure leave the default settings alone.
|
||||
+
|
||||
+config IMQ_BEHAVIOR_BB
|
||||
+ bool "IMQ BB"
|
||||
+ help
|
||||
+ This settings defines how IMQ behaves in respect to its
|
||||
+ hooking in PREROUTING and POSTROUTING.
|
||||
+
|
||||
+ Choosing this option will make IMQ hook like this:
|
||||
+
|
||||
+ PREROUTING: Before NAT
|
||||
+ POSTROUTING: Before NAT
|
||||
+
|
||||
+ More information can be found at: www.linuximq.net
|
||||
+
|
||||
+ If not sure leave the default settings alone.
|
||||
+
|
||||
+endchoice
|
||||
+
|
||||
+config IMQ_NUM_DEVS
|
||||
+
|
||||
+ int "Number of IMQ devices"
|
||||
+ range 2 8
|
||||
+ depends on IMQ
|
||||
+ default "2"
|
||||
+ help
|
||||
+
|
||||
+ This settings defines how many IMQ devices will be
|
||||
+ created.
|
||||
+
|
||||
+ The default value is 2.
|
||||
+
|
||||
+ More information can be found at: www.linuximq.net
|
||||
+
|
||||
+ If not sure leave the default settings alone.
|
||||
+
|
||||
config TUN
|
||||
tristate "Universal TUN/TAP device driver support"
|
||||
select CRC32
|
||||
diff -urN linux-2.6.19/drivers/net/Makefile linux-2.6.19+imq/drivers/net/Makefile
|
||||
--- linux-2.6.19/drivers/net/Makefile 2006-12-01 14:05:30.000000000 +1030
|
||||
+++ linux-2.6.19+imq/drivers/net/Makefile 2006-12-04 12:41:01.000000000 +1030
|
||||
@@ -124,6 +124,7 @@
|
||||
obj-$(CONFIG_SLHC) += slhc.o
|
||||
|
||||
obj-$(CONFIG_DUMMY) += dummy.o
|
||||
+obj-$(CONFIG_IMQ) += imq.o
|
||||
obj-$(CONFIG_IFB) += ifb.o
|
||||
obj-$(CONFIG_DE600) += de600.o
|
||||
obj-$(CONFIG_DE620) += de620.o
|
||||
diff -urN linux-2.6.19/include/linux/imq.h linux-2.6.19+imq/include/linux/imq.h
|
||||
--- linux-2.6.19/include/linux/imq.h 1970-01-01 09:30:00.000000000 +0930
|
||||
+++ linux-2.6.19+imq/include/linux/imq.h 2006-12-04 12:41:01.000000000 +1030
|
||||
@@ -0,0 +1,9 @@
|
||||
+#ifndef _IMQ_H
|
||||
+#define _IMQ_H
|
||||
+
|
||||
+#define IMQ_MAX_DEVS 16
|
||||
+
|
||||
+#define IMQ_F_IFMASK 0x7f
|
||||
+#define IMQ_F_ENQUEUE 0x80
|
||||
+
|
||||
+#endif /* _IMQ_H */
|
||||
diff -urN linux-2.6.19/include/linux/netfilter_ipv4/ipt_IMQ.h linux-2.6.19+imq/include/linux/netfilter_ipv4/ipt_IMQ.h
|
||||
--- linux-2.6.19/include/linux/netfilter_ipv4/ipt_IMQ.h 1970-01-01 09:30:00.000000000 +0930
|
||||
+++ linux-2.6.19+imq/include/linux/netfilter_ipv4/ipt_IMQ.h 2006-12-05 23:04:22.000000000 +1030
|
||||
@@ -0,0 +1,8 @@
|
||||
+#ifndef _IPT_IMQ_H
|
||||
+#define _IPT_IMQ_H
|
||||
+
|
||||
+struct ipt_imq_info {
|
||||
+ unsigned int todev; /* target imq device */
|
||||
+};
|
||||
+
|
||||
+#endif /* _IPT_IMQ_H */
|
||||
diff -urN linux-2.6.19/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-2.6.19+imq/include/linux/netfilter_ipv6/ip6t_IMQ.h
|
||||
--- linux-2.6.19/include/linux/netfilter_ipv6/ip6t_IMQ.h 1970-01-01 09:30:00.000000000 +0930
|
||||
+++ linux-2.6.19+imq/include/linux/netfilter_ipv6/ip6t_IMQ.h 2006-12-05 23:04:32.000000000 +1030
|
||||
@@ -0,0 +1,8 @@
|
||||
+#ifndef _IP6T_IMQ_H
|
||||
+#define _IP6T_IMQ_H
|
||||
+
|
||||
+struct ip6t_imq_info {
|
||||
+ unsigned int todev; /* target imq device */
|
||||
+};
|
||||
+
|
||||
+#endif /* _IP6T_IMQ_H */
|
||||
diff -urN linux-2.6.19/include/linux/skbuff.h linux-2.6.19+imq/include/linux/skbuff.h
|
||||
--- linux-2.6.19/include/linux/skbuff.h 2006-12-01 14:05:44.000000000 +1030
|
||||
+++ linux-2.6.19+imq/include/linux/skbuff.h 2006-12-05 23:05:06.000000000 +1030
|
||||
@@ -292,6 +292,10 @@
|
||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||
struct sk_buff *nfct_reasm;
|
||||
#endif
|
||||
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
|
||||
+ unsigned char imq_flags;
|
||||
+ struct nf_info *nf_info;
|
||||
+#endif
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
struct nf_bridge_info *nf_bridge;
|
||||
#endif
|
||||
diff -urN linux-2.6.19/net/core/dev.c linux-2.6.19+imq/net/core/dev.c
|
||||
--- linux-2.6.19/net/core/dev.c 2006-12-01 14:05:45.000000000 +1030
|
||||
+++ linux-2.6.19+imq/net/core/dev.c 2006-12-05 23:05:40.000000000 +1030
|
||||
@@ -94,6 +94,9 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/sock.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
|
||||
+#include <linux/imq.h>
|
||||
+#endif
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/stat.h>
|
||||
@@ -1344,7 +1347,11 @@
|
||||
int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
if (likely(!skb->next)) {
|
||||
- if (netdev_nit)
|
||||
+ if (netdev_nit
|
||||
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
|
||||
+ && !(skb->imq_flags & IMQ_F_ENQUEUE)
|
||||
+#endif
|
||||
+ )
|
||||
dev_queue_xmit_nit(skb, dev);
|
||||
|
||||
if (netif_needs_gso(dev, skb)) {
|
||||
diff -urN linux-2.6.19/net/core/skbuff.c linux-2.6.19+imq/net/core/skbuff.c
|
||||
--- linux-2.6.19/net/core/skbuff.c 2006-12-01 14:05:45.000000000 +1030
|
||||
+++ linux-2.6.19+imq/net/core/skbuff.c 2006-12-04 12:41:01.000000000 +1030
|
||||
@@ -482,6 +482,10 @@
|
||||
C(nfct_reasm);
|
||||
nf_conntrack_get_reasm(skb->nfct_reasm);
|
||||
#endif
|
||||
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
|
||||
+ C(imq_flags);
|
||||
+ C(nf_info);
|
||||
+#endif /*CONFIG_IMQ*/
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
C(nf_bridge);
|
||||
nf_bridge_get(skb->nf_bridge);
|
||||
@@ -546,6 +550,10 @@
|
||||
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
|
||||
new->ipvs_property = old->ipvs_property;
|
||||
#endif
|
||||
+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
|
||||
+ new->imq_flags = old->imq_flags;
|
||||
+ new->nf_info = old->nf_info;
|
||||
+#endif /*CONFIG_IMQ*/
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
new->nf_bridge = old->nf_bridge;
|
||||
nf_bridge_get(old->nf_bridge);
|
||||
diff -urN linux-2.6.19/net/ipv4/netfilter/ipt_IMQ.c linux-2.6.19+imq/net/ipv4/netfilter/ipt_IMQ.c
|
||||
--- linux-2.6.19/net/ipv4/netfilter/ipt_IMQ.c 1970-01-01 09:30:00.000000000 +0930
|
||||
+++ linux-2.6.19.2/net/ipv4/netfilter/ipt_IMQ.c 2007-01-25 09:59:34.000000000 +0100
|
||||
@@ -0,0 +1,71 @@
|
||||
+/*
|
||||
+ * This target marks packets to be enqueued to an imq device
|
||||
+ */
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
+#include <linux/netfilter_ipv4/ipt_IMQ.h>
|
||||
+#include <linux/imq.h>
|
||||
+
|
||||
+static unsigned int imq_target(struct sk_buff **pskb,
|
||||
+ const struct net_device *in,
|
||||
+ const struct net_device *out,
|
||||
+ unsigned int hooknum,
|
||||
+ const struct xt_target *target,
|
||||
+ const void *targinfo)
|
||||
+{
|
||||
+ struct ipt_imq_info *mr = (struct ipt_imq_info*)targinfo;
|
||||
+
|
||||
+ (*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE;
|
||||
+
|
||||
+ return IPT_CONTINUE;
|
||||
+}
|
||||
+
|
||||
+static int imq_checkentry(const char *tablename,
|
||||
+ const void *e,
|
||||
+ const struct xt_target *target,
|
||||
+ void *targinfo,
|
||||
+ unsigned int hook_mask)
|
||||
+{
|
||||
+ struct ipt_imq_info *mr;
|
||||
+
|
||||
+ mr = (struct ipt_imq_info*)targinfo;
|
||||
+
|
||||
+ if (mr->todev > IMQ_MAX_DEVS) {
|
||||
+ printk(KERN_WARNING
|
||||
+ "IMQ: invalid device specified, highest is %u\n",
|
||||
+ IMQ_MAX_DEVS);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static struct ipt_target ipt_imq_reg = {
|
||||
+ .name = "IMQ",
|
||||
+ .target = imq_target,
|
||||
+ .targetsize = sizeof(struct ipt_imq_info),
|
||||
+ .checkentry = imq_checkentry,
|
||||
+ .me = THIS_MODULE,
|
||||
+ .table = "mangle"
|
||||
+};
|
||||
+
|
||||
+static int __init init(void)
|
||||
+{
|
||||
+ if (ipt_register_target(&ipt_imq_reg))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __exit fini(void)
|
||||
+{
|
||||
+ ipt_unregister_target(&ipt_imq_reg);
|
||||
+}
|
||||
+
|
||||
+module_init(init);
|
||||
+module_exit(fini);
|
||||
+
|
||||
+MODULE_AUTHOR("http://www.linuximq.net");
|
||||
+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff -urN linux-2.6.19/net/ipv4/netfilter/Kconfig linux-2.6.19+imq/net/ipv4/netfilter/Kconfig
|
||||
--- linux-2.6.19/net/ipv4/netfilter/Kconfig 2006-12-01 14:05:45.000000000 +1030
|
||||
+++ linux-2.6.19+imq/net/ipv4/netfilter/Kconfig 2006-12-04 12:41:01.000000000 +1030
|
||||
@@ -533,6 +533,17 @@
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
+config IP_NF_TARGET_IMQ
|
||||
+ tristate "IMQ target support"
|
||||
+ depends on IP_NF_MANGLE
|
||||
+ help
|
||||
+ This option adds a `IMQ' target which is used to specify if and
|
||||
+ to which IMQ device packets should get enqueued/dequeued.
|
||||
+
|
||||
+ For more information visit: http://www.linuximq.net/
|
||||
+
|
||||
+ To compile it as a module, choose M here. If unsure, say N.
|
||||
+
|
||||
config IP_NF_TARGET_TOS
|
||||
tristate "TOS target support"
|
||||
depends on IP_NF_MANGLE
|
||||
diff -urN linux-2.6.19/net/ipv4/netfilter/Makefile linux-2.6.19+imq/net/ipv4/netfilter/Makefile
|
||||
--- linux-2.6.19/net/ipv4/netfilter/Makefile 2006-12-01 14:05:45.000000000 +1030
|
||||
+++ linux-2.6.19+imq/net/ipv4/netfilter/Makefile 2006-12-04 12:41:01.000000000 +1030
|
||||
@@ -67,6 +67,7 @@
|
||||
obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
|
||||
+obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
|
||||
diff -urN linux-2.6.19/net/ipv6/netfilter/ip6t_IMQ.c linux-2.6.19+imq/net/ipv6/netfilter/ip6t_IMQ.c
|
||||
--- linux-2.6.19/net/ipv6/netfilter/ip6t_IMQ.c 1970-01-01 09:30:00.000000000 +0930
|
||||
+++ linux-2.6.19.2/net/ipv6/netfilter/ip6t_IMQ.c 2007-01-25 10:06:41.000000000 +0100
|
||||
@@ -0,0 +1,71 @@
|
||||
+/*
|
||||
+ * This target marks packets to be enqueued to an imq device
|
||||
+ */
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
+#include <linux/netfilter_ipv6/ip6t_IMQ.h>
|
||||
+#include <linux/imq.h>
|
||||
+
|
||||
+static unsigned int imq_target(struct sk_buff **pskb,
|
||||
+ const struct net_device *in,
|
||||
+ const struct net_device *out,
|
||||
+ unsigned int hooknum,
|
||||
+ const struct xt_target *target,
|
||||
+ const void *targinfo)
|
||||
+{
|
||||
+ struct ip6t_imq_info *mr = (struct ip6t_imq_info*)targinfo;
|
||||
+
|
||||
+ (*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE;
|
||||
+
|
||||
+ return IP6T_CONTINUE;
|
||||
+}
|
||||
+
|
||||
+static int imq_checkentry(const char *tablename,
|
||||
+ const void *entry,
|
||||
+ const struct xt_target *target,
|
||||
+ void *targinfo,
|
||||
+ unsigned int hook_mask)
|
||||
+{
|
||||
+ struct ip6t_imq_info *mr;
|
||||
+
|
||||
+ mr = (struct ip6t_imq_info*)targinfo;
|
||||
+
|
||||
+ if (mr->todev > IMQ_MAX_DEVS) {
|
||||
+ printk(KERN_WARNING
|
||||
+ "IMQ: invalid device specified, highest is %u\n",
|
||||
+ IMQ_MAX_DEVS);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static struct ip6t_target ip6t_imq_reg = {
|
||||
+ .name = "IMQ",
|
||||
+ .target = imq_target,
|
||||
+ .targetsize = sizeof(struct ip6t_imq_info),
|
||||
+ .table = "mangle",
|
||||
+ .checkentry = imq_checkentry,
|
||||
+ .me = THIS_MODULE
|
||||
+};
|
||||
+
|
||||
+static int __init init(void)
|
||||
+{
|
||||
+ if (ip6t_register_target(&ip6t_imq_reg))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __exit fini(void)
|
||||
+{
|
||||
+ ip6t_unregister_target(&ip6t_imq_reg);
|
||||
+}
|
||||
+
|
||||
+module_init(init);
|
||||
+module_exit(fini);
|
||||
+
|
||||
+MODULE_AUTHOR("http://www.linuximq.net");
|
||||
+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information.");
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff -urN linux-2.6.19/net/ipv6/netfilter/Kconfig linux-2.6.19+imq/net/ipv6/netfilter/Kconfig
|
||||
--- linux-2.6.19/net/ipv6/netfilter/Kconfig 2006-12-01 14:05:46.000000000 +1030
|
||||
+++ linux-2.6.19+imq/net/ipv6/netfilter/Kconfig 2006-12-04 12:41:01.000000000 +1030
|
||||
@@ -163,6 +163,15 @@
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
+config IP6_NF_TARGET_IMQ
|
||||
+ tristate "IMQ target support"
|
||||
+ depends on IP6_NF_MANGLE
|
||||
+ help
|
||||
+ This option adds a `IMQ' target which is used to specify if and
|
||||
+ to which imq device packets should get enqueued/dequeued.
|
||||
+
|
||||
+ To compile it as a module, choose M here. If unsure, say N.
|
||||
+
|
||||
config IP6_NF_TARGET_HL
|
||||
tristate 'HL (hoplimit) target support'
|
||||
depends on IP6_NF_MANGLE
|
||||
diff -urN linux-2.6.19/net/ipv6/netfilter/Makefile linux-2.6.19+imq/net/ipv6/netfilter/Makefile
|
||||
--- linux-2.6.19/net/ipv6/netfilter/Makefile 2006-12-01 14:05:46.000000000 +1030
|
||||
+++ linux-2.6.19+imq/net/ipv6/netfilter/Makefile 2006-12-04 12:41:01.000000000 +1030
|
||||
@@ -13,6 +13,7 @@
|
||||
obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
|
||||
obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
|
||||
obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
|
||||
+obj-$(CONFIG_IP6_NF_TARGET_IMQ) += ip6t_IMQ.o
|
||||
obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
|
||||
obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
|
||||
obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
|
||||
diff -urN linux-2.6.19/net/sched/sch_generic.c linux-2.6.19+imq/net/sched/sch_generic.c
|
||||
--- linux-2.6.19/net/sched/sch_generic.c 2006-12-01 14:05:46.000000000 +1030
|
||||
+++ linux-2.6.19+imq/net/sched/sch_generic.c 2006-12-05 23:08:54.000000000 +1030
|
||||
@@ -87,7 +87,6 @@
|
||||
|
||||
NOTE: Called under dev->queue_lock with locally disabled BH.
|
||||
*/
|
||||
-
|
||||
static inline int qdisc_restart(struct net_device *dev)
|
||||
{
|
||||
struct Qdisc *q = dev->qdisc;
|
||||
@@ -181,6 +180,11 @@
|
||||
return q->q.qlen;
|
||||
}
|
||||
|
||||
+int qdisc_restart1(struct net_device *dev)
|
||||
+{
|
||||
+ return qdisc_restart(dev);
|
||||
+}
|
||||
+
|
||||
void __qdisc_run(struct net_device *dev)
|
||||
{
|
||||
if (unlikely(dev->qdisc == &noop_qdisc))
|
||||
@@ -617,3 +621,4 @@
|
||||
EXPORT_SYMBOL(qdisc_reset);
|
||||
EXPORT_SYMBOL(qdisc_lock_tree);
|
||||
EXPORT_SYMBOL(qdisc_unlock_tree);
|
||||
+EXPORT_SYMBOL(qdisc_restart1);
|
||||
902
target/linux/etrax/patches/generic_2.6/160-netfilter_route.patch
Normal file
902
target/linux/etrax/patches/generic_2.6/160-netfilter_route.patch
Normal file
@@ -0,0 +1,902 @@
|
||||
diff -urN linux-2.6.19.old/include/linux/netfilter_ipv4/ipt_ROUTE.h linux-2.6.19.dev/include/linux/netfilter_ipv4/ipt_ROUTE.h
|
||||
--- linux-2.6.19.old/include/linux/netfilter_ipv4/ipt_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/include/linux/netfilter_ipv4/ipt_ROUTE.h 2006-12-14 03:13:49.000000000 +0100
|
||||
@@ -0,0 +1,23 @@
|
||||
+/* Header file for iptables ipt_ROUTE target
|
||||
+ *
|
||||
+ * (C) 2002 by Cédric de Launois <delaunois@info.ucl.ac.be>
|
||||
+ *
|
||||
+ * This software is distributed under GNU GPL v2, 1991
|
||||
+ */
|
||||
+#ifndef _IPT_ROUTE_H_target
|
||||
+#define _IPT_ROUTE_H_target
|
||||
+
|
||||
+#define IPT_ROUTE_IFNAMSIZ 16
|
||||
+
|
||||
+struct ipt_route_target_info {
|
||||
+ char oif[IPT_ROUTE_IFNAMSIZ]; /* Output Interface Name */
|
||||
+ char iif[IPT_ROUTE_IFNAMSIZ]; /* Input Interface Name */
|
||||
+ u_int32_t gw; /* IP address of gateway */
|
||||
+ u_int8_t flags;
|
||||
+};
|
||||
+
|
||||
+/* Values for "flags" field */
|
||||
+#define IPT_ROUTE_CONTINUE 0x01
|
||||
+#define IPT_ROUTE_TEE 0x02
|
||||
+
|
||||
+#endif /*_IPT_ROUTE_H_target*/
|
||||
diff -urN linux-2.6.19.old/include/linux/netfilter_ipv6/ip6t_ROUTE.h linux-2.6.19.dev/include/linux/netfilter_ipv6/ip6t_ROUTE.h
|
||||
--- linux-2.6.19.old/include/linux/netfilter_ipv6/ip6t_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/include/linux/netfilter_ipv6/ip6t_ROUTE.h 2006-12-14 03:13:49.000000000 +0100
|
||||
@@ -0,0 +1,23 @@
|
||||
+/* Header file for iptables ip6t_ROUTE target
|
||||
+ *
|
||||
+ * (C) 2003 by Cédric de Launois <delaunois@info.ucl.ac.be>
|
||||
+ *
|
||||
+ * This software is distributed under GNU GPL v2, 1991
|
||||
+ */
|
||||
+#ifndef _IPT_ROUTE_H_target
|
||||
+#define _IPT_ROUTE_H_target
|
||||
+
|
||||
+#define IP6T_ROUTE_IFNAMSIZ 16
|
||||
+
|
||||
+struct ip6t_route_target_info {
|
||||
+ char oif[IP6T_ROUTE_IFNAMSIZ]; /* Output Interface Name */
|
||||
+ char iif[IP6T_ROUTE_IFNAMSIZ]; /* Input Interface Name */
|
||||
+ u_int32_t gw[4]; /* IPv6 address of gateway */
|
||||
+ u_int8_t flags;
|
||||
+};
|
||||
+
|
||||
+/* Values for "flags" field */
|
||||
+#define IP6T_ROUTE_CONTINUE 0x01
|
||||
+#define IP6T_ROUTE_TEE 0x02
|
||||
+
|
||||
+#endif /*_IP6T_ROUTE_H_target*/
|
||||
diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_ROUTE.c linux-2.6.19.dev/net/ipv4/netfilter/ipt_ROUTE.c
|
||||
--- linux-2.6.19.old/net/ipv4/netfilter/ipt_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv4/netfilter/ipt_ROUTE.c 2006-12-14 03:13:49.000000000 +0100
|
||||
@@ -0,0 +1,455 @@
|
||||
+/*
|
||||
+ * This implements the ROUTE target, which enables you to setup unusual
|
||||
+ * routes not supported by the standard kernel routing table.
|
||||
+ *
|
||||
+ * Copyright (C) 2002 Cedric de Launois <delaunois@info.ucl.ac.be>
|
||||
+ *
|
||||
+ * v 1.11 2004/11/23
|
||||
+ *
|
||||
+ * This software is distributed under GNU GPL v2, 1991
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/ip.h>
|
||||
+#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
+#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
+#include <linux/netfilter_ipv4/ipt_ROUTE.h>
|
||||
+#include <linux/netdevice.h>
|
||||
+#include <linux/route.h>
|
||||
+#include <linux/if_arp.h>
|
||||
+#include <net/ip.h>
|
||||
+#include <net/route.h>
|
||||
+#include <net/icmp.h>
|
||||
+#include <net/checksum.h>
|
||||
+
|
||||
+#if 0
|
||||
+#define DEBUGP printk
|
||||
+#else
|
||||
+#define DEBUGP(format, args...)
|
||||
+#endif
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("Cedric de Launois <delaunois@info.ucl.ac.be>");
|
||||
+MODULE_DESCRIPTION("iptables ROUTE target module");
|
||||
+
|
||||
+/* Try to route the packet according to the routing keys specified in
|
||||
+ * route_info. Keys are :
|
||||
+ * - ifindex :
|
||||
+ * 0 if no oif preferred,
|
||||
+ * otherwise set to the index of the desired oif
|
||||
+ * - route_info->gw :
|
||||
+ * 0 if no gateway specified,
|
||||
+ * otherwise set to the next host to which the pkt must be routed
|
||||
+ * If success, skb->dev is the output device to which the packet must
|
||||
+ * be sent and skb->dst is not NULL
|
||||
+ *
|
||||
+ * RETURN: -1 if an error occured
|
||||
+ * 1 if the packet was succesfully routed to the
|
||||
+ * destination desired
|
||||
+ * 0 if the kernel routing table could not route the packet
|
||||
+ * according to the keys specified
|
||||
+ */
|
||||
+static int route(struct sk_buff *skb,
|
||||
+ unsigned int ifindex,
|
||||
+ const struct ipt_route_target_info *route_info)
|
||||
+{
|
||||
+ int err;
|
||||
+ struct rtable *rt;
|
||||
+ struct iphdr *iph = skb->nh.iph;
|
||||
+ struct flowi fl = {
|
||||
+ .oif = ifindex,
|
||||
+ .nl_u = {
|
||||
+ .ip4_u = {
|
||||
+ .daddr = iph->daddr,
|
||||
+ .saddr = 0,
|
||||
+ .tos = RT_TOS(iph->tos),
|
||||
+ .scope = RT_SCOPE_UNIVERSE,
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ /* The destination address may be overloaded by the target */
|
||||
+ if (route_info->gw)
|
||||
+ fl.fl4_dst = route_info->gw;
|
||||
+
|
||||
+ /* Trying to route the packet using the standard routing table. */
|
||||
+ if ((err = ip_route_output_key(&rt, &fl))) {
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /* Drop old route. */
|
||||
+ dst_release(skb->dst);
|
||||
+ skb->dst = NULL;
|
||||
+
|
||||
+ /* Success if no oif specified or if the oif correspond to the
|
||||
+ * one desired */
|
||||
+ if (!ifindex || rt->u.dst.dev->ifindex == ifindex) {
|
||||
+ skb->dst = &rt->u.dst;
|
||||
+ skb->dev = skb->dst->dev;
|
||||
+ skb->protocol = htons(ETH_P_IP);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ /* The interface selected by the routing table is not the one
|
||||
+ * specified by the user. This may happen because the dst address
|
||||
+ * is one of our own addresses.
|
||||
+ */
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP("ipt_ROUTE: failed to route as desired gw=%u.%u.%u.%u oif=%i (got oif=%i)\n",
|
||||
+ NIPQUAD(route_info->gw), ifindex, rt->u.dst.dev->ifindex);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Stolen from ip_finish_output2
|
||||
+ * PRE : skb->dev is set to the device we are leaving by
|
||||
+ * skb->dst is not NULL
|
||||
+ * POST: the packet is sent with the link layer header pushed
|
||||
+ * the packet is destroyed
|
||||
+ */
|
||||
+static void ip_direct_send(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct dst_entry *dst = skb->dst;
|
||||
+ struct hh_cache *hh = dst->hh;
|
||||
+ struct net_device *dev = dst->dev;
|
||||
+ int hh_len = LL_RESERVED_SPACE(dev);
|
||||
+
|
||||
+ /* Be paranoid, rather than too clever. */
|
||||
+ if (unlikely(skb_headroom(skb) < hh_len && dev->hard_header)) {
|
||||
+ struct sk_buff *skb2;
|
||||
+
|
||||
+ skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
|
||||
+ if (skb2 == NULL) {
|
||||
+ kfree_skb(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+ if (skb->sk)
|
||||
+ skb_set_owner_w(skb2, skb->sk);
|
||||
+ kfree_skb(skb);
|
||||
+ skb = skb2;
|
||||
+ }
|
||||
+
|
||||
+ if (hh) {
|
||||
+ int hh_alen;
|
||||
+
|
||||
+ read_lock_bh(&hh->hh_lock);
|
||||
+ hh_alen = HH_DATA_ALIGN(hh->hh_len);
|
||||
+ memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
|
||||
+ read_unlock_bh(&hh->hh_lock);
|
||||
+ skb_push(skb, hh->hh_len);
|
||||
+ hh->hh_output(skb);
|
||||
+ } else if (dst->neighbour)
|
||||
+ dst->neighbour->output(skb);
|
||||
+ else {
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n");
|
||||
+ kfree_skb(skb);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* PRE : skb->dev is set to the device we are leaving by
|
||||
+ * POST: - the packet is directly sent to the skb->dev device, without
|
||||
+ * pushing the link layer header.
|
||||
+ * - the packet is destroyed
|
||||
+ */
|
||||
+static inline int dev_direct_send(struct sk_buff *skb)
|
||||
+{
|
||||
+ return dev_queue_xmit(skb);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static unsigned int route_oif(const struct ipt_route_target_info *route_info,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ unsigned int ifindex = 0;
|
||||
+ struct net_device *dev_out = NULL;
|
||||
+
|
||||
+ /* The user set the interface name to use.
|
||||
+ * Getting the current interface index.
|
||||
+ */
|
||||
+ if ((dev_out = dev_get_by_name(route_info->oif))) {
|
||||
+ ifindex = dev_out->ifindex;
|
||||
+ } else {
|
||||
+ /* Unknown interface name : packet dropped */
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif);
|
||||
+ return NF_DROP;
|
||||
+ }
|
||||
+
|
||||
+ /* Trying the standard way of routing packets */
|
||||
+ switch (route(skb, ifindex, route_info)) {
|
||||
+ case 1:
|
||||
+ dev_put(dev_out);
|
||||
+ if (route_info->flags & IPT_ROUTE_CONTINUE)
|
||||
+ return IPT_CONTINUE;
|
||||
+
|
||||
+ ip_direct_send(skb);
|
||||
+ return NF_STOLEN;
|
||||
+
|
||||
+ case 0:
|
||||
+ /* Failed to send to oif. Trying the hard way */
|
||||
+ if (route_info->flags & IPT_ROUTE_CONTINUE)
|
||||
+ return NF_DROP;
|
||||
+
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP("ipt_ROUTE: forcing the use of %i\n",
|
||||
+ ifindex);
|
||||
+
|
||||
+ /* We have to force the use of an interface.
|
||||
+ * This interface must be a tunnel interface since
|
||||
+ * otherwise we can't guess the hw address for
|
||||
+ * the packet. For a tunnel interface, no hw address
|
||||
+ * is needed.
|
||||
+ */
|
||||
+ if ((dev_out->type != ARPHRD_TUNNEL)
|
||||
+ && (dev_out->type != ARPHRD_IPGRE)) {
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP("ipt_ROUTE: can't guess the hw addr !\n");
|
||||
+ dev_put(dev_out);
|
||||
+ return NF_DROP;
|
||||
+ }
|
||||
+
|
||||
+ /* Send the packet. This will also free skb
|
||||
+ * Do not go through the POST_ROUTING hook because
|
||||
+ * skb->dst is not set and because it will probably
|
||||
+ * get confused by the destination IP address.
|
||||
+ */
|
||||
+ skb->dev = dev_out;
|
||||
+ dev_direct_send(skb);
|
||||
+ dev_put(dev_out);
|
||||
+ return NF_STOLEN;
|
||||
+
|
||||
+ default:
|
||||
+ /* Unexpected error */
|
||||
+ dev_put(dev_out);
|
||||
+ return NF_DROP;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static unsigned int route_iif(const struct ipt_route_target_info *route_info,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct net_device *dev_in = NULL;
|
||||
+
|
||||
+ /* Getting the current interface index. */
|
||||
+ if (!(dev_in = dev_get_by_name(route_info->iif))) {
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->iif);
|
||||
+ return NF_DROP;
|
||||
+ }
|
||||
+
|
||||
+ skb->dev = dev_in;
|
||||
+ dst_release(skb->dst);
|
||||
+ skb->dst = NULL;
|
||||
+
|
||||
+ netif_rx(skb);
|
||||
+ dev_put(dev_in);
|
||||
+ return NF_STOLEN;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static unsigned int route_gw(const struct ipt_route_target_info *route_info,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ if (route(skb, 0, route_info)!=1)
|
||||
+ return NF_DROP;
|
||||
+
|
||||
+ if (route_info->flags & IPT_ROUTE_CONTINUE)
|
||||
+ return IPT_CONTINUE;
|
||||
+
|
||||
+ ip_direct_send(skb);
|
||||
+ return NF_STOLEN;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* To detect and deter routed packet loopback when using the --tee option,
|
||||
+ * we take a page out of the raw.patch book: on the copied skb, we set up
|
||||
+ * a fake ->nfct entry, pointing to the local &route_tee_track. We skip
|
||||
+ * routing packets when we see they already have that ->nfct.
|
||||
+ */
|
||||
+
|
||||
+static struct ip_conntrack route_tee_track;
|
||||
+
|
||||
+static unsigned int ipt_route_target(struct sk_buff **pskb,
|
||||
+ const struct net_device *in,
|
||||
+ const struct net_device *out,
|
||||
+ unsigned int hooknum,
|
||||
+ const struct xt_target *target,
|
||||
+ const void *targinfo)
|
||||
+{
|
||||
+ const struct ipt_route_target_info *route_info = targinfo;
|
||||
+ struct sk_buff *skb = *pskb;
|
||||
+ unsigned int res;
|
||||
+
|
||||
+ if (skb->nfct == &route_tee_track.ct_general) {
|
||||
+ /* Loopback - a packet we already routed, is to be
|
||||
+ * routed another time. Avoid that, now.
|
||||
+ */
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP(KERN_DEBUG "ipt_ROUTE: loopback - DROP!\n");
|
||||
+ return NF_DROP;
|
||||
+ }
|
||||
+
|
||||
+ /* If we are at PREROUTING or INPUT hook
|
||||
+ * the TTL isn't decreased by the IP stack
|
||||
+ */
|
||||
+ if (hooknum == NF_IP_PRE_ROUTING ||
|
||||
+ hooknum == NF_IP_LOCAL_IN) {
|
||||
+
|
||||
+ struct iphdr *iph = skb->nh.iph;
|
||||
+
|
||||
+ if (iph->ttl <= 1) {
|
||||
+ struct rtable *rt;
|
||||
+ struct flowi fl = {
|
||||
+ .oif = 0,
|
||||
+ .nl_u = {
|
||||
+ .ip4_u = {
|
||||
+ .daddr = iph->daddr,
|
||||
+ .saddr = iph->saddr,
|
||||
+ .tos = RT_TOS(iph->tos),
|
||||
+ .scope = ((iph->tos & RTO_ONLINK) ?
|
||||
+ RT_SCOPE_LINK :
|
||||
+ RT_SCOPE_UNIVERSE)
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ if (ip_route_output_key(&rt, &fl)) {
|
||||
+ return NF_DROP;
|
||||
+ }
|
||||
+
|
||||
+ if (skb->dev == rt->u.dst.dev) {
|
||||
+ /* Drop old route. */
|
||||
+ dst_release(skb->dst);
|
||||
+ skb->dst = &rt->u.dst;
|
||||
+
|
||||
+ /* this will traverse normal stack, and
|
||||
+ * thus call conntrack on the icmp packet */
|
||||
+ icmp_send(skb, ICMP_TIME_EXCEEDED,
|
||||
+ ICMP_EXC_TTL, 0);
|
||||
+ }
|
||||
+
|
||||
+ return NF_DROP;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * If we are at INPUT the checksum must be recalculated since
|
||||
+ * the length could change as the result of a defragmentation.
|
||||
+ */
|
||||
+ if(hooknum == NF_IP_LOCAL_IN) {
|
||||
+ iph->ttl = iph->ttl - 1;
|
||||
+ iph->check = 0;
|
||||
+ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
|
||||
+ } else {
|
||||
+ ip_decrease_ttl(iph);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((route_info->flags & IPT_ROUTE_TEE)) {
|
||||
+ /*
|
||||
+ * Copy the *pskb, and route the copy. Will later return
|
||||
+ * IPT_CONTINUE for the original skb, which should continue
|
||||
+ * on its way as if nothing happened. The copy should be
|
||||
+ * independantly delivered to the ROUTE --gw.
|
||||
+ */
|
||||
+ skb = skb_copy(*pskb, GFP_ATOMIC);
|
||||
+ if (!skb) {
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP(KERN_DEBUG "ipt_ROUTE: copy failed!\n");
|
||||
+ return IPT_CONTINUE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Tell conntrack to forget this packet since it may get confused
|
||||
+ * when a packet is leaving with dst address == our address.
|
||||
+ * Good idea ? Dunno. Need advice.
|
||||
+ *
|
||||
+ * NEW: mark the skb with our &route_tee_track, so we avoid looping
|
||||
+ * on any already routed packet.
|
||||
+ */
|
||||
+ if (!(route_info->flags & IPT_ROUTE_CONTINUE)) {
|
||||
+ nf_conntrack_put(skb->nfct);
|
||||
+ skb->nfct = &route_tee_track.ct_general;
|
||||
+ skb->nfctinfo = IP_CT_NEW;
|
||||
+ nf_conntrack_get(skb->nfct);
|
||||
+ }
|
||||
+
|
||||
+ if (route_info->oif[0] != '\0') {
|
||||
+ res = route_oif(route_info, skb);
|
||||
+ } else if (route_info->iif[0] != '\0') {
|
||||
+ res = route_iif(route_info, skb);
|
||||
+ } else if (route_info->gw) {
|
||||
+ res = route_gw(route_info, skb);
|
||||
+ } else {
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n");
|
||||
+ res = IPT_CONTINUE;
|
||||
+ }
|
||||
+
|
||||
+ if ((route_info->flags & IPT_ROUTE_TEE))
|
||||
+ res = IPT_CONTINUE;
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int ipt_route_checkentry(const char *tablename,
|
||||
+ const void *e,
|
||||
+ const struct xt_target *target,
|
||||
+ void *targinfo,
|
||||
+ unsigned int hook_mask)
|
||||
+{
|
||||
+ if (strcmp(tablename, "mangle") != 0) {
|
||||
+ printk("ipt_ROUTE: bad table `%s', use the `mangle' table.\n",
|
||||
+ tablename);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (hook_mask & ~( (1 << NF_IP_PRE_ROUTING)
|
||||
+ | (1 << NF_IP_LOCAL_IN)
|
||||
+ | (1 << NF_IP_FORWARD)
|
||||
+ | (1 << NF_IP_LOCAL_OUT)
|
||||
+ | (1 << NF_IP_POST_ROUTING))) {
|
||||
+ printk("ipt_ROUTE: bad hook\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static struct ipt_target ipt_route_reg = {
|
||||
+ .name = "ROUTE",
|
||||
+ .target = ipt_route_target,
|
||||
+ .targetsize = sizeof(struct ipt_route_target_info),
|
||||
+ .checkentry = ipt_route_checkentry,
|
||||
+ .me = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int __init init(void)
|
||||
+{
|
||||
+ /* Set up fake conntrack (stolen from raw.patch):
|
||||
+ - to never be deleted, not in any hashes */
|
||||
+ atomic_set(&route_tee_track.ct_general.use, 1);
|
||||
+ /* - and look it like as a confirmed connection */
|
||||
+ set_bit(IPS_CONFIRMED_BIT, &route_tee_track.status);
|
||||
+ /* Initialize fake conntrack so that NAT will skip it */
|
||||
+ route_tee_track.status |= IPS_NAT_DONE_MASK;
|
||||
+
|
||||
+ return ipt_register_target(&ipt_route_reg);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void __exit fini(void)
|
||||
+{
|
||||
+ ipt_unregister_target(&ipt_route_reg);
|
||||
+}
|
||||
+
|
||||
+module_init(init);
|
||||
+module_exit(fini);
|
||||
diff -urN linux-2.6.19.old/net/ipv4/netfilter/Kconfig linux-2.6.19.dev/net/ipv4/netfilter/Kconfig
|
||||
--- linux-2.6.19.old/net/ipv4/netfilter/Kconfig 2006-12-14 03:13:49.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv4/netfilter/Kconfig 2006-12-14 03:13:49.000000000 +0100
|
||||
@@ -494,6 +494,23 @@
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
+config IP_NF_TARGET_ROUTE
|
||||
+ tristate 'ROUTE target support'
|
||||
+ depends on IP_NF_MANGLE
|
||||
+ help
|
||||
+ This option adds a `ROUTE' target, which enables you to setup unusual
|
||||
+ routes. For example, the ROUTE lets you route a received packet through
|
||||
+ an interface or towards a host, even if the regular destination of the
|
||||
+ packet is the router itself. The ROUTE target is also able to change the
|
||||
+ incoming interface of a packet.
|
||||
+
|
||||
+ The target can be or not a final target. It has to be used inside the
|
||||
+ mangle table.
|
||||
+
|
||||
+ If you want to compile it as a module, say M here and read
|
||||
+ Documentation/modules.txt. The module will be called ipt_ROUTE.o.
|
||||
+ If unsure, say `N'.
|
||||
+
|
||||
config IP_NF_TARGET_NETMAP
|
||||
tristate "NETMAP target support"
|
||||
depends on IP_NF_NAT
|
||||
diff -urN linux-2.6.19.old/net/ipv4/netfilter/Makefile linux-2.6.19.dev/net/ipv4/netfilter/Makefile
|
||||
--- linux-2.6.19.old/net/ipv4/netfilter/Makefile 2006-12-14 03:13:49.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv4/netfilter/Makefile 2006-12-14 03:13:49.000000000 +0100
|
||||
@@ -74,6 +74,7 @@
|
||||
obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
|
||||
+obj-$(CONFIG_IP_NF_TARGET_ROUTE) += ipt_ROUTE.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
|
||||
obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
|
||||
obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
|
||||
diff -urN linux-2.6.19.old/net/ipv6/ipv6_syms.c linux-2.6.19.dev/net/ipv6/ipv6_syms.c
|
||||
--- linux-2.6.19.old/net/ipv6/ipv6_syms.c 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv6/ipv6_syms.c 2006-12-14 03:13:49.000000000 +0100
|
||||
@@ -11,6 +11,7 @@
|
||||
EXPORT_SYMBOL(icmpv6_statistics);
|
||||
EXPORT_SYMBOL(icmpv6_err_convert);
|
||||
EXPORT_SYMBOL(ndisc_mc_map);
|
||||
+EXPORT_SYMBOL(nd_tbl);
|
||||
EXPORT_SYMBOL(register_inet6addr_notifier);
|
||||
EXPORT_SYMBOL(unregister_inet6addr_notifier);
|
||||
EXPORT_SYMBOL(ip6_route_output);
|
||||
diff -urN linux-2.6.19.old/net/ipv6/netfilter/ip6t_ROUTE.c linux-2.6.19.dev/net/ipv6/netfilter/ip6t_ROUTE.c
|
||||
--- linux-2.6.19.old/net/ipv6/netfilter/ip6t_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv6/netfilter/ip6t_ROUTE.c 2006-12-14 03:13:49.000000000 +0100
|
||||
@@ -0,0 +1,302 @@
|
||||
+/*
|
||||
+ * This implements the ROUTE v6 target, which enables you to setup unusual
|
||||
+ * routes not supported by the standard kernel routing table.
|
||||
+ *
|
||||
+ * Copyright (C) 2003 Cedric de Launois <delaunois@info.ucl.ac.be>
|
||||
+ *
|
||||
+ * v 1.1 2004/11/23
|
||||
+ *
|
||||
+ * This software is distributed under GNU GPL v2, 1991
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/ipv6.h>
|
||||
+#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
+#include <linux/netfilter_ipv6/ip6t_ROUTE.h>
|
||||
+#include <linux/netdevice.h>
|
||||
+#include <net/ipv6.h>
|
||||
+#include <net/ndisc.h>
|
||||
+#include <net/ip6_route.h>
|
||||
+#include <linux/icmpv6.h>
|
||||
+
|
||||
+#if 1
|
||||
+#define DEBUGP printk
|
||||
+#else
|
||||
+#define DEBUGP(format, args...)
|
||||
+#endif
|
||||
+
|
||||
+#define NIP6(addr) \
|
||||
+ ntohs((addr).s6_addr16[0]), \
|
||||
+ ntohs((addr).s6_addr16[1]), \
|
||||
+ ntohs((addr).s6_addr16[2]), \
|
||||
+ ntohs((addr).s6_addr16[3]), \
|
||||
+ ntohs((addr).s6_addr16[4]), \
|
||||
+ ntohs((addr).s6_addr16[5]), \
|
||||
+ ntohs((addr).s6_addr16[6]), \
|
||||
+ ntohs((addr).s6_addr16[7])
|
||||
+
|
||||
+/* Route the packet according to the routing keys specified in
|
||||
+ * route_info. Keys are :
|
||||
+ * - ifindex :
|
||||
+ * 0 if no oif preferred,
|
||||
+ * otherwise set to the index of the desired oif
|
||||
+ * - route_info->gw :
|
||||
+ * 0 if no gateway specified,
|
||||
+ * otherwise set to the next host to which the pkt must be routed
|
||||
+ * If success, skb->dev is the output device to which the packet must
|
||||
+ * be sent and skb->dst is not NULL
|
||||
+ *
|
||||
+ * RETURN: 1 if the packet was succesfully routed to the
|
||||
+ * destination desired
|
||||
+ * 0 if the kernel routing table could not route the packet
|
||||
+ * according to the keys specified
|
||||
+ */
|
||||
+static int
|
||||
+route6(struct sk_buff *skb,
|
||||
+ unsigned int ifindex,
|
||||
+ const struct ip6t_route_target_info *route_info)
|
||||
+{
|
||||
+ struct rt6_info *rt = NULL;
|
||||
+ struct ipv6hdr *ipv6h = skb->nh.ipv6h;
|
||||
+ struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
|
||||
+
|
||||
+ DEBUGP("ip6t_ROUTE: called with: ");
|
||||
+ DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ipv6h->daddr));
|
||||
+ DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(*gw));
|
||||
+ DEBUGP("OUT=%s\n", route_info->oif);
|
||||
+
|
||||
+ if (ipv6_addr_any(gw))
|
||||
+ rt = rt6_lookup(&ipv6h->daddr, &ipv6h->saddr, ifindex, 1);
|
||||
+ else
|
||||
+ rt = rt6_lookup(gw, &ipv6h->saddr, ifindex, 1);
|
||||
+
|
||||
+ if (!rt)
|
||||
+ goto no_route;
|
||||
+
|
||||
+ DEBUGP("ip6t_ROUTE: routing gives: ");
|
||||
+ DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_dst.addr));
|
||||
+ DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_gateway));
|
||||
+ DEBUGP("OUT=%s\n", rt->rt6i_dev->name);
|
||||
+
|
||||
+ if (ifindex && rt->rt6i_dev->ifindex!=ifindex)
|
||||
+ goto wrong_route;
|
||||
+
|
||||
+ if (!rt->rt6i_nexthop) {
|
||||
+ DEBUGP("ip6t_ROUTE: discovering neighbour\n");
|
||||
+ rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_dst.addr);
|
||||
+ }
|
||||
+
|
||||
+ /* Drop old route. */
|
||||
+ dst_release(skb->dst);
|
||||
+ skb->dst = &rt->u.dst;
|
||||
+ skb->dev = rt->rt6i_dev;
|
||||
+ return 1;
|
||||
+
|
||||
+ wrong_route:
|
||||
+ dst_release(&rt->u.dst);
|
||||
+ no_route:
|
||||
+ if (!net_ratelimit())
|
||||
+ return 0;
|
||||
+
|
||||
+ printk("ip6t_ROUTE: no explicit route found ");
|
||||
+ if (ifindex)
|
||||
+ printk("via interface %s ", route_info->oif);
|
||||
+ if (!ipv6_addr_any(gw))
|
||||
+ printk("via gateway %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", NIP6(*gw));
|
||||
+ printk("\n");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Stolen from ip6_output_finish
|
||||
+ * PRE : skb->dev is set to the device we are leaving by
|
||||
+ * skb->dst is not NULL
|
||||
+ * POST: the packet is sent with the link layer header pushed
|
||||
+ * the packet is destroyed
|
||||
+ */
|
||||
+static void ip_direct_send(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct dst_entry *dst = skb->dst;
|
||||
+ struct hh_cache *hh = dst->hh;
|
||||
+
|
||||
+ if (hh) {
|
||||
+ read_lock_bh(&hh->hh_lock);
|
||||
+ memcpy(skb->data - 16, hh->hh_data, 16);
|
||||
+ read_unlock_bh(&hh->hh_lock);
|
||||
+ skb_push(skb, hh->hh_len);
|
||||
+ hh->hh_output(skb);
|
||||
+ } else if (dst->neighbour)
|
||||
+ dst->neighbour->output(skb);
|
||||
+ else {
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP(KERN_DEBUG "ip6t_ROUTE: no hdr & no neighbour cache!\n");
|
||||
+ kfree_skb(skb);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static unsigned int
|
||||
+route6_oif(const struct ip6t_route_target_info *route_info,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ unsigned int ifindex = 0;
|
||||
+ struct net_device *dev_out = NULL;
|
||||
+
|
||||
+ /* The user set the interface name to use.
|
||||
+ * Getting the current interface index.
|
||||
+ */
|
||||
+ if ((dev_out = dev_get_by_name(route_info->oif))) {
|
||||
+ ifindex = dev_out->ifindex;
|
||||
+ } else {
|
||||
+ /* Unknown interface name : packet dropped */
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP("ip6t_ROUTE: oif interface %s not found\n", route_info->oif);
|
||||
+
|
||||
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
|
||||
+ return IP6T_CONTINUE;
|
||||
+ else
|
||||
+ return NF_DROP;
|
||||
+ }
|
||||
+
|
||||
+ /* Trying the standard way of routing packets */
|
||||
+ if (route6(skb, ifindex, route_info)) {
|
||||
+ dev_put(dev_out);
|
||||
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
|
||||
+ return IP6T_CONTINUE;
|
||||
+
|
||||
+ ip_direct_send(skb);
|
||||
+ return NF_STOLEN;
|
||||
+ } else
|
||||
+ return NF_DROP;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static unsigned int
|
||||
+route6_gw(const struct ip6t_route_target_info *route_info,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ if (route6(skb, 0, route_info)) {
|
||||
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
|
||||
+ return IP6T_CONTINUE;
|
||||
+
|
||||
+ ip_direct_send(skb);
|
||||
+ return NF_STOLEN;
|
||||
+ } else
|
||||
+ return NF_DROP;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static unsigned int
|
||||
+ip6t_route_target(struct sk_buff **pskb,
|
||||
+ const struct net_device *in,
|
||||
+ const struct net_device *out,
|
||||
+ unsigned int hooknum,
|
||||
+ const struct xt_target *target,
|
||||
+ const void *targinfo)
|
||||
+{
|
||||
+ const struct ip6t_route_target_info *route_info = targinfo;
|
||||
+ struct sk_buff *skb = *pskb;
|
||||
+ struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
|
||||
+ unsigned int res;
|
||||
+
|
||||
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
|
||||
+ goto do_it;
|
||||
+
|
||||
+ /* If we are at PREROUTING or INPUT hook
|
||||
+ * the TTL isn't decreased by the IP stack
|
||||
+ */
|
||||
+ if (hooknum == NF_IP6_PRE_ROUTING ||
|
||||
+ hooknum == NF_IP6_LOCAL_IN) {
|
||||
+
|
||||
+ struct ipv6hdr *ipv6h = skb->nh.ipv6h;
|
||||
+
|
||||
+ if (ipv6h->hop_limit <= 1) {
|
||||
+ /* Force OUTPUT device used as source address */
|
||||
+ skb->dev = skb->dst->dev;
|
||||
+
|
||||
+ icmpv6_send(skb, ICMPV6_TIME_EXCEED,
|
||||
+ ICMPV6_EXC_HOPLIMIT, 0, skb->dev);
|
||||
+
|
||||
+ return NF_DROP;
|
||||
+ }
|
||||
+
|
||||
+ ipv6h->hop_limit--;
|
||||
+ }
|
||||
+
|
||||
+ if ((route_info->flags & IP6T_ROUTE_TEE)) {
|
||||
+ /*
|
||||
+ * Copy the *pskb, and route the copy. Will later return
|
||||
+ * IP6T_CONTINUE for the original skb, which should continue
|
||||
+ * on its way as if nothing happened. The copy should be
|
||||
+ * independantly delivered to the ROUTE --gw.
|
||||
+ */
|
||||
+ skb = skb_copy(*pskb, GFP_ATOMIC);
|
||||
+ if (!skb) {
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP(KERN_DEBUG "ip6t_ROUTE: copy failed!\n");
|
||||
+ return IP6T_CONTINUE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+do_it:
|
||||
+ if (route_info->oif[0]) {
|
||||
+ res = route6_oif(route_info, skb);
|
||||
+ } else if (!ipv6_addr_any(gw)) {
|
||||
+ res = route6_gw(route_info, skb);
|
||||
+ } else {
|
||||
+ if (net_ratelimit())
|
||||
+ DEBUGP(KERN_DEBUG "ip6t_ROUTE: no parameter !\n");
|
||||
+ res = IP6T_CONTINUE;
|
||||
+ }
|
||||
+
|
||||
+ if ((route_info->flags & IP6T_ROUTE_TEE))
|
||||
+ res = IP6T_CONTINUE;
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+ip6t_route_checkentry(const char *tablename,
|
||||
+ const void *e,
|
||||
+ const struct xt_target *target,
|
||||
+ void *targinfo,
|
||||
+ unsigned int hook_mask)
|
||||
+{
|
||||
+ if (strcmp(tablename, "mangle") != 0) {
|
||||
+ printk("ip6t_ROUTE: can only be called from \"mangle\" table.\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static struct ip6t_target ip6t_route_reg = {
|
||||
+ .name = "ROUTE",
|
||||
+ .target = ip6t_route_target,
|
||||
+ .targetsize = sizeof(struct ip6t_route_target_info),
|
||||
+ .checkentry = ip6t_route_checkentry,
|
||||
+ .me = THIS_MODULE
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static int __init init(void)
|
||||
+{
|
||||
+ printk(KERN_DEBUG "registering ipv6 ROUTE target\n");
|
||||
+ if (ip6t_register_target(&ip6t_route_reg))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void __exit fini(void)
|
||||
+{
|
||||
+ ip6t_unregister_target(&ip6t_route_reg);
|
||||
+}
|
||||
+
|
||||
+module_init(init);
|
||||
+module_exit(fini);
|
||||
+MODULE_LICENSE("GPL");
|
||||
diff -urN linux-2.6.19.old/net/ipv6/netfilter/Kconfig linux-2.6.19.dev/net/ipv6/netfilter/Kconfig
|
||||
--- linux-2.6.19.old/net/ipv6/netfilter/Kconfig 2006-12-14 03:13:49.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv6/netfilter/Kconfig 2006-12-14 03:13:49.000000000 +0100
|
||||
@@ -162,6 +162,19 @@
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
+config IP6_NF_TARGET_ROUTE
|
||||
+ tristate "ROUTE target support"
|
||||
+ depends on IP6_NF_MANGLE
|
||||
+ help
|
||||
+ This option adds a `ROUTE' target, which enables you to setup unusual
|
||||
+ routes. The ROUTE target is also able to change the incoming interface
|
||||
+ of a packet.
|
||||
+
|
||||
+ The target can be or not a final target. It has to be used inside the
|
||||
+ mangle table.
|
||||
+
|
||||
+ Not working as a module.
|
||||
+
|
||||
config IP6_NF_MANGLE
|
||||
tristate "Packet mangling"
|
||||
depends on IP6_NF_IPTABLES
|
||||
diff -urN linux-2.6.19.old/net/ipv6/netfilter/Makefile linux-2.6.19.dev/net/ipv6/netfilter/Makefile
|
||||
--- linux-2.6.19.old/net/ipv6/netfilter/Makefile 2006-12-14 03:13:49.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/ipv6/netfilter/Makefile 2006-12-14 03:13:49.000000000 +0100
|
||||
@@ -20,6 +20,7 @@
|
||||
obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
|
||||
obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
|
||||
+obj-$(CONFIG_IP6_NF_TARGET_ROUTE) += ip6t_ROUTE.o
|
||||
|
||||
# objects for l3 independent conntrack
|
||||
nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
|
||||
@@ -0,0 +1,880 @@
|
||||
diff -ruN linux-2.6.19.1.orig/include/linux/netfilter/xt_CHAOS.h linux-2.6.19.1/include/linux/netfilter/xt_CHAOS.h
|
||||
--- linux-2.6.19.1.orig/include/linux/netfilter/xt_CHAOS.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.1/include/linux/netfilter/xt_CHAOS.h 2007-01-11 13:28:07.656144799 +0100
|
||||
@@ -0,0 +1,14 @@
|
||||
+#ifndef _LINUX_XT_CHAOS_H
|
||||
+#define _LINUX_XT_CHAOS_H 1
|
||||
+
|
||||
+enum xt_chaos_variant {
|
||||
+ XTCHAOS_NORMAL,
|
||||
+ XTCHAOS_TARPIT,
|
||||
+ XTCHAOS_DELUDE,
|
||||
+};
|
||||
+
|
||||
+struct xt_chaos_info {
|
||||
+ enum xt_chaos_variant variant;
|
||||
+};
|
||||
+
|
||||
+#endif /* _LINUX_XT_CHAOS_H */
|
||||
diff -ruN linux-2.6.19.1.orig/include/linux/netfilter/xt_portscan.h linux-2.6.19.1/include/linux/netfilter/xt_portscan.h
|
||||
--- linux-2.6.19.1.orig/include/linux/netfilter/xt_portscan.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.1/include/linux/netfilter/xt_portscan.h 2007-01-11 13:28:07.656144799 +0100
|
||||
@@ -0,0 +1,8 @@
|
||||
+#ifndef _LINUX_XT_PORTSCAN_H
|
||||
+#define _LINUX_XT_PORTSCAN_H 1
|
||||
+
|
||||
+struct xt_portscan_info {
|
||||
+ unsigned int match_stealth, match_syn, match_cn, match_gr;
|
||||
+};
|
||||
+
|
||||
+#endif /* _LINUX_XT_PORTSCAN_H */
|
||||
diff -ruN linux-2.6.19.1.orig/net/netfilter/find_match.c linux-2.6.19.1/net/netfilter/find_match.c
|
||||
--- linux-2.6.19.1.orig/net/netfilter/find_match.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.1/net/netfilter/find_match.c 2007-01-11 13:28:12.191994379 +0100
|
||||
@@ -0,0 +1,37 @@
|
||||
+/*
|
||||
+ xt_request_find_match
|
||||
+ by Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007
|
||||
+
|
||||
+ Based upon linux-2.6.18.5/net/netfilter/x_tables.c:
|
||||
+ Copyright (C) 2006-2006 Harald Welte <laforge@netfilter.org>
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License version 2 as
|
||||
+ published by the Free Software Foundation.
|
||||
+*/
|
||||
+
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/netfilter_arp.h>
|
||||
+#include <linux/socket.h>
|
||||
+#include <linux/netfilter/x_tables.h>
|
||||
+
|
||||
+/*
|
||||
+ * Yeah this code is sub-optimal, but the function is missing in
|
||||
+ * mainline so far. -jengelh
|
||||
+ */
|
||||
+static struct xt_match *xt_request_find_match(int af, const char *name,
|
||||
+ u8 revision)
|
||||
+{
|
||||
+ static const char *const xt_prefix[] = {
|
||||
+ [AF_INET] = "ip",
|
||||
+ [AF_INET6] = "ip6",
|
||||
+ [NF_ARP] = "arp",
|
||||
+ };
|
||||
+ struct xt_match *match;
|
||||
+
|
||||
+ match = try_then_request_module(xt_find_match(af, name, revision),
|
||||
+ "%st_%s", xt_prefix[af], name);
|
||||
+ if(IS_ERR(match) || match == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return match;
|
||||
+}
|
||||
diff -ruN linux-2.6.19.1.orig/net/netfilter/Kconfig linux-2.6.19.1/net/netfilter/Kconfig
|
||||
--- linux-2.6.19.1.orig/net/netfilter/Kconfig 2007-01-11 13:27:24.445577700 +0100
|
||||
+++ linux-2.6.19.1/net/netfilter/Kconfig 2007-01-11 13:28:09.092097179 +0100
|
||||
@@ -122,6 +122,14 @@
|
||||
|
||||
# alphabetically ordered list of targets
|
||||
|
||||
+config NETFILTER_XT_TARGET_CHAOS
|
||||
+ tristate '"CHAOS" target support'
|
||||
+ depends on NETFILTER_XTABLES
|
||||
+ help
|
||||
+ This option adds a `CHAOS' target.
|
||||
+
|
||||
+ To compile it as a module, choose M here. If unsure, say N.
|
||||
+
|
||||
config NETFILTER_XT_TARGET_CLASSIFY
|
||||
tristate '"CLASSIFY" target support'
|
||||
depends on NETFILTER_XTABLES
|
||||
@@ -148,6 +156,14 @@
|
||||
<file:Documentation/modules.txt>. The module will be called
|
||||
ipt_CONNMARK.o. If unsure, say `N'.
|
||||
|
||||
+config NETFILTER_XT_TARGET_DELUDE
|
||||
+ tristate '"DELUDE" target support'
|
||||
+ depends on NETFILTER_XTABLES
|
||||
+ help
|
||||
+ This option adds a `DELUDE' target.
|
||||
+
|
||||
+ To compile it as a module, choose M here. If unsure, say N.
|
||||
+
|
||||
config NETFILTER_XT_TARGET_DSCP
|
||||
tristate '"DSCP" target support'
|
||||
depends on NETFILTER_XTABLES
|
||||
@@ -355,6 +371,14 @@
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
+config NETFILTER_XT_MATCH_PORTSCAN
|
||||
+ tristate '"portscan" match support'
|
||||
+ depends on NETFILTER_XTABLES
|
||||
+ help
|
||||
+ This option adds a 'portscan' match support.
|
||||
+
|
||||
+ To compile it as a module, choose M here. If unsure, say N.
|
||||
+
|
||||
config NETFILTER_XT_MATCH_MULTIPORT
|
||||
tristate "Multiple port match support"
|
||||
depends on NETFILTER_XTABLES
|
||||
diff -ruN linux-2.6.19.1.orig/net/netfilter/Makefile linux-2.6.19.1/net/netfilter/Makefile
|
||||
--- linux-2.6.19.1.orig/net/netfilter/Makefile 2007-01-11 13:27:24.445577700 +0100
|
||||
+++ linux-2.6.19.1/net/netfilter/Makefile 2007-01-11 13:28:07.656144799 +0100
|
||||
@@ -23,8 +23,10 @@
|
||||
obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
|
||||
|
||||
# targets
|
||||
+obj-$(CONFIG_NETFILTER_XT_TARGET_CHAOS) += xt_CHAOS.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
|
||||
+obj-$(CONFIG_NETFILTER_XT_TARGET_DELUDE) += xt_DELUDE.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
|
||||
obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
|
||||
@@ -47,6 +49,7 @@
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
|
||||
+obj-$(CONFIG_NETFILTER_XT_MATCH_PORTSCAN) += xt_portscan.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
|
||||
diff -ruN linux-2.6.19.1.orig/net/netfilter/xt_CHAOS.c linux-2.6.19.1/net/netfilter/xt_CHAOS.c
|
||||
--- linux-2.6.19.1.orig/net/netfilter/xt_CHAOS.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.1/net/netfilter/xt_CHAOS.c 2007-01-11 13:28:14.407920893 +0100
|
||||
@@ -0,0 +1,180 @@
|
||||
+/*
|
||||
+ CHAOS target for netfilter
|
||||
+
|
||||
+ Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007
|
||||
+ released under the terms of the GNU General Public
|
||||
+ License version 2.x and only versions 2.x.
|
||||
+*/
|
||||
+#include <linux/icmp.h>
|
||||
+#include <linux/in.h>
|
||||
+#include <linux/ip.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/stat.h>
|
||||
+#include <linux/netfilter/x_tables.h>
|
||||
+#include <linux/netfilter/xt_tcpudp.h>
|
||||
+#include <linux/netfilter_ipv4/ipt_REJECT.h>
|
||||
+#include <net/ip.h>
|
||||
+#include <linux/netfilter/xt_CHAOS.h>
|
||||
+#include "find_match.c"
|
||||
+#define PFX KBUILD_MODNAME ": "
|
||||
+
|
||||
+/* Out of tree workarounds */
|
||||
+#include <linux/version.h>
|
||||
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
+# define HAVE_TARGUSERINFO 1
|
||||
+#endif
|
||||
+
|
||||
+/* Module parameters */
|
||||
+static unsigned int reject_percentage = ~0U * .01;
|
||||
+static unsigned int delude_percentage = ~0U * .0101;
|
||||
+module_param(reject_percentage, uint, S_IRUGO | S_IWUSR);
|
||||
+module_param(delude_percentage, uint, S_IRUGO | S_IWUSR);
|
||||
+
|
||||
+/* References to other matches/targets */
|
||||
+static struct xt_match *xm_tcp;
|
||||
+static struct xt_target *xt_delude, *xt_reject, *xt_tarpit;
|
||||
+
|
||||
+/* Static data for other matches/targets */
|
||||
+static const struct ipt_reject_info reject_params = {
|
||||
+ .with = ICMP_HOST_UNREACH,
|
||||
+};
|
||||
+
|
||||
+static const struct xt_tcp tcp_params = {
|
||||
+ .spts = {0, ~0},
|
||||
+ .dpts = {0, ~0},
|
||||
+};
|
||||
+
|
||||
+/* CHAOS functions */
|
||||
+static void xt_chaos_total(const struct xt_chaos_info *info,
|
||||
+ struct sk_buff **pskb, const struct net_device *in,
|
||||
+ const struct net_device *out, unsigned int hooknum)
|
||||
+{
|
||||
+ const int protoff = 4 * (*pskb)->nh.iph->ihl;
|
||||
+ const int offset = ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET;
|
||||
+ const struct xt_target *destiny;
|
||||
+ int hotdrop = 0, ret;
|
||||
+
|
||||
+ ret = xm_tcp->match(*pskb, in, out, xm_tcp, &tcp_params,
|
||||
+ offset, protoff, &hotdrop);
|
||||
+ if(!ret || hotdrop || (unsigned int)net_random() > delude_percentage)
|
||||
+ return;
|
||||
+
|
||||
+ destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude;
|
||||
+#ifdef HAVE_TARGUSERINFO
|
||||
+ destiny->target(pskb, in, out, hooknum, destiny, NULL, NULL);
|
||||
+#else
|
||||
+ destiny->target(pskb, in, out, hooknum, destiny, NULL);
|
||||
+#endif
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static unsigned int xt_chaos_target(struct sk_buff **pskb,
|
||||
+ const struct net_device *in, const struct net_device *out,
|
||||
+ unsigned int hooknum, const struct xt_target *target, const void *targinfo
|
||||
+#ifdef HAVE_TARGUSERINFO
|
||||
+ ,
|
||||
+ void *userinfo
|
||||
+#endif
|
||||
+ )
|
||||
+{
|
||||
+ /* Equivalent to:
|
||||
+ * -A chaos -m statistic --mode random --probability \
|
||||
+ * $reject_percentage -j REJECT --reject-with host-unreach;
|
||||
+ * -A chaos -m statistic --mode random --probability \
|
||||
+ * $delude_percentage -j DELUDE;
|
||||
+ * -A chaos -j DROP;
|
||||
+ */
|
||||
+ const struct xt_chaos_info *info = targinfo;
|
||||
+
|
||||
+ if((unsigned int)net_random() <= reject_percentage)
|
||||
+#ifdef HAVE_TARGUSERINFO
|
||||
+ return xt_reject->target(pskb, in, out, hooknum, target,
|
||||
+ &reject_params, userinfo);
|
||||
+#else
|
||||
+ return xt_reject->target(pskb, in, out, hooknum, target,
|
||||
+ &reject_params);
|
||||
+#endif
|
||||
+
|
||||
+ /* TARPIT/DELUDE may not be called from the OUTPUT chain */
|
||||
+ if((*pskb)->nh.iph->protocol == IPPROTO_TCP &&
|
||||
+ info->variant != XTCHAOS_NORMAL && hooknum != NF_IP_LOCAL_OUT)
|
||||
+ xt_chaos_total(info, pskb, in, out, hooknum);
|
||||
+
|
||||
+ return NF_DROP;
|
||||
+}
|
||||
+
|
||||
+static struct xt_target xt_chaos_info = {
|
||||
+ .name = "CHAOS",
|
||||
+ .target = xt_chaos_target,
|
||||
+ .table = "filter",
|
||||
+ .targetsize = sizeof(struct xt_chaos_info),
|
||||
+ .hooks = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) |
|
||||
+ (1 << NF_IP_LOCAL_OUT),
|
||||
+ .family = AF_INET,
|
||||
+ .me = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int __init xt_chaos_init(void)
|
||||
+{
|
||||
+ int ret = -EINVAL;
|
||||
+
|
||||
+ xm_tcp = xt_request_find_match(AF_INET, "tcp", 0);
|
||||
+ if(xm_tcp == NULL) {
|
||||
+ printk(KERN_WARNING PFX "Could not find \"tcp\" match\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ xt_reject = xt_request_find_target(AF_INET, "REJECT", 0);
|
||||
+ if(xt_reject == NULL) {
|
||||
+ printk(KERN_WARNING PFX "Could not find \"REJECT\" target\n");
|
||||
+ goto out2;
|
||||
+ }
|
||||
+
|
||||
+ xt_tarpit = xt_request_find_target(AF_INET, "TARPIT", 0);
|
||||
+ if(xt_tarpit == NULL) {
|
||||
+ printk(KERN_WARNING PFX "Could not find \"TARPIT\" target\n");
|
||||
+ goto out3;
|
||||
+ }
|
||||
+
|
||||
+ xt_delude = xt_request_find_target(AF_INET, "DELUDE", 0);
|
||||
+ if(xt_delude == NULL) {
|
||||
+ printk(KERN_WARNING PFX "Could not find \"DELUDE\" target\n");
|
||||
+ goto out4;
|
||||
+ }
|
||||
+
|
||||
+ if((ret = xt_register_target(&xt_chaos_info)) != 0) {
|
||||
+ printk(KERN_WARNING PFX "xt_register_target returned "
|
||||
+ "error %d\n", ret);
|
||||
+ goto out5;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+ out5:
|
||||
+ module_put(xt_delude->me);
|
||||
+ out4:
|
||||
+ module_put(xt_tarpit->me);
|
||||
+ out3:
|
||||
+ module_put(xt_reject->me);
|
||||
+ out2:
|
||||
+ module_put(xm_tcp->me);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void __exit xt_chaos_exit(void)
|
||||
+{
|
||||
+ xt_unregister_target(&xt_chaos_info);
|
||||
+ module_put(xm_tcp->me);
|
||||
+ module_put(xt_reject->me);
|
||||
+ module_put(xt_delude->me);
|
||||
+ module_put(xt_tarpit->me);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+module_init(xt_chaos_init);
|
||||
+module_exit(xt_chaos_exit);
|
||||
+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
|
||||
+MODULE_DESCRIPTION("netfilter CHAOS target");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_ALIAS("ipt_CHAOS");
|
||||
diff -ruN linux-2.6.19.1.orig/net/netfilter/xt_DELUDE.c linux-2.6.19.1/net/netfilter/xt_DELUDE.c
|
||||
--- linux-2.6.19.1.orig/net/netfilter/xt_DELUDE.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.1/net/netfilter/xt_DELUDE.c 2007-01-11 13:28:07.656144799 +0100
|
||||
@@ -0,0 +1,265 @@
|
||||
+/*
|
||||
+ DELUDE target
|
||||
+ Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2007
|
||||
+
|
||||
+ Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c:
|
||||
+ (C) 1999-2001 Paul `Rusty' Russell
|
||||
+ (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License version 2 as
|
||||
+ published by the Free Software Foundation.
|
||||
+*/
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/ip.h>
|
||||
+#include <linux/tcp.h>
|
||||
+#include <linux/udp.h>
|
||||
+#include <linux/icmp.h>
|
||||
+#include <net/icmp.h>
|
||||
+#include <net/ip.h>
|
||||
+#include <net/tcp.h>
|
||||
+#include <net/route.h>
|
||||
+#include <net/dst.h>
|
||||
+#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
+#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
+#include <linux/netfilter_bridge.h>
|
||||
+#endif
|
||||
+#define PFX KBUILD_MODNAME ": "
|
||||
+
|
||||
+/* Out of tree workarounds */
|
||||
+#include <linux/version.h>
|
||||
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
+# define HAVE_TARGINFOSIZE 1
|
||||
+# define HAVE_TARGUSERINFO 1
|
||||
+#endif
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
|
||||
+# define nfmark mark
|
||||
+#endif
|
||||
+
|
||||
+static inline struct rtable *route_reverse(struct sk_buff *skb,
|
||||
+ struct tcphdr *tcph, int hook)
|
||||
+{
|
||||
+ struct iphdr *iph = skb->nh.iph;
|
||||
+ struct dst_entry *odst;
|
||||
+ struct flowi fl = {};
|
||||
+ struct rtable *rt;
|
||||
+
|
||||
+ /* We don't require ip forwarding to be enabled to be able to
|
||||
+ * send a RST reply for bridged traffic. */
|
||||
+ if (hook != NF_IP_FORWARD
|
||||
+#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
+ || (skb->nf_bridge && skb->nf_bridge->mask & BRNF_BRIDGED)
|
||||
+#endif
|
||||
+ ) {
|
||||
+ fl.nl_u.ip4_u.daddr = iph->saddr;
|
||||
+ if (hook == NF_IP_LOCAL_IN)
|
||||
+ fl.nl_u.ip4_u.saddr = iph->daddr;
|
||||
+ fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
|
||||
+
|
||||
+ if (ip_route_output_key(&rt, &fl) != 0)
|
||||
+ return NULL;
|
||||
+ } else {
|
||||
+ /* non-local src, find valid iif to satisfy
|
||||
+ * rp-filter when calling ip_route_input. */
|
||||
+ fl.nl_u.ip4_u.daddr = iph->daddr;
|
||||
+ if (ip_route_output_key(&rt, &fl) != 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ odst = skb->dst;
|
||||
+ if (ip_route_input(skb, iph->saddr, iph->daddr,
|
||||
+ RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
|
||||
+ dst_release(&rt->u.dst);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ dst_release(&rt->u.dst);
|
||||
+ rt = (struct rtable *)skb->dst;
|
||||
+ skb->dst = odst;
|
||||
+
|
||||
+ fl.nl_u.ip4_u.daddr = iph->saddr;
|
||||
+ fl.nl_u.ip4_u.saddr = iph->daddr;
|
||||
+ fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
|
||||
+ }
|
||||
+
|
||||
+ if (rt->u.dst.error) {
|
||||
+ dst_release(&rt->u.dst);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ fl.proto = IPPROTO_TCP;
|
||||
+ fl.fl_ip_sport = tcph->dest;
|
||||
+ fl.fl_ip_dport = tcph->source;
|
||||
+
|
||||
+ xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
|
||||
+
|
||||
+ return rt;
|
||||
+}
|
||||
+
|
||||
+static void send_reset(struct sk_buff *oldskb, int hook)
|
||||
+{
|
||||
+ struct sk_buff *nskb;
|
||||
+ struct iphdr *iph = oldskb->nh.iph;
|
||||
+ struct tcphdr _otcph, *oth, *tcph;
|
||||
+ struct rtable *rt;
|
||||
+ u_int16_t tmp_port;
|
||||
+ u_int32_t tmp_addr;
|
||||
+ int hh_len;
|
||||
+
|
||||
+ /* IP header checks: fragment. */
|
||||
+ if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))
|
||||
+ return;
|
||||
+
|
||||
+ oth = skb_header_pointer(oldskb, oldskb->nh.iph->ihl * 4,
|
||||
+ sizeof(_otcph), &_otcph);
|
||||
+ if (oth == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ /* DELUDE only answers SYN. */
|
||||
+ if(!oth->syn || oth->ack || oth->fin || oth->rst)
|
||||
+ return;
|
||||
+
|
||||
+ /* Check checksum */
|
||||
+ if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP))
|
||||
+ return;
|
||||
+
|
||||
+ if ((rt = route_reverse(oldskb, oth, hook)) == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
|
||||
+
|
||||
+ /* We need a linear, writeable skb. We also need to expand
|
||||
+ headroom in case hh_len of incoming interface < hh_len of
|
||||
+ outgoing interface */
|
||||
+ nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
|
||||
+ GFP_ATOMIC);
|
||||
+ if (!nskb) {
|
||||
+ dst_release(&rt->u.dst);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ dst_release(nskb->dst);
|
||||
+ nskb->dst = &rt->u.dst;
|
||||
+
|
||||
+ /* This packet will not be the same as the other: clear nf fields */
|
||||
+ nf_reset(nskb);
|
||||
+ nskb->nfmark = 0;
|
||||
+ skb_init_secmark(nskb);
|
||||
+
|
||||
+ tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
|
||||
+
|
||||
+ /* Swap source and dest */
|
||||
+ tmp_addr = nskb->nh.iph->saddr;
|
||||
+ nskb->nh.iph->saddr = nskb->nh.iph->daddr;
|
||||
+ nskb->nh.iph->daddr = tmp_addr;
|
||||
+ tmp_port = tcph->source;
|
||||
+ tcph->source = tcph->dest;
|
||||
+ tcph->dest = tmp_port;
|
||||
+
|
||||
+ /* Truncate to length (no data) */
|
||||
+ tcph->doff = sizeof(struct tcphdr)/4;
|
||||
+ skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
|
||||
+ nskb->nh.iph->tot_len = htons(nskb->len);
|
||||
+
|
||||
+ tcph->seq = oth->ack_seq;
|
||||
+ tcph->ack_seq = 0;
|
||||
+
|
||||
+ /* Reset flags */
|
||||
+ ((u_int8_t *)tcph)[13] = 0;
|
||||
+ tcph->syn = tcph->ack = 1;
|
||||
+
|
||||
+ tcph->window = 0;
|
||||
+ tcph->urg_ptr = 0;
|
||||
+
|
||||
+ /* Adjust TCP checksum */
|
||||
+ tcph->check = 0;
|
||||
+ tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
|
||||
+ nskb->nh.iph->saddr,
|
||||
+ nskb->nh.iph->daddr,
|
||||
+ csum_partial((char *)tcph,
|
||||
+ sizeof(struct tcphdr), 0));
|
||||
+
|
||||
+ /* Adjust IP TTL, DF */
|
||||
+ nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
|
||||
+ /* Set DF, id = 0 */
|
||||
+ nskb->nh.iph->frag_off = htons(IP_DF);
|
||||
+ nskb->nh.iph->id = 0;
|
||||
+
|
||||
+ /* Adjust IP checksum */
|
||||
+ nskb->nh.iph->check = 0;
|
||||
+ nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
|
||||
+ nskb->nh.iph->ihl);
|
||||
+
|
||||
+ /* "Never happens" */
|
||||
+ if (nskb->len > dst_mtu(nskb->dst))
|
||||
+ goto free_nskb;
|
||||
+
|
||||
+ nf_ct_attach(nskb, oldskb);
|
||||
+
|
||||
+ NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
|
||||
+ dst_output);
|
||||
+ return;
|
||||
+
|
||||
+ free_nskb:
|
||||
+ kfree_skb(nskb);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static unsigned int xt_delude_target(struct sk_buff **pskb,
|
||||
+ const struct net_device *in, const struct net_device *out,
|
||||
+ unsigned int hooknum, const struct xt_target *target, const void *targinfo
|
||||
+#ifdef HAVE_TARGUSERINFO
|
||||
+ ,
|
||||
+ void *userinfo
|
||||
+#endif
|
||||
+ )
|
||||
+{
|
||||
+ /* WARNING: This code causes reentry within iptables.
|
||||
+ This means that the iptables jump stack is now crap. We
|
||||
+ must return an absolute verdict. --RR */
|
||||
+ send_reset(*pskb, hooknum);
|
||||
+ return NF_DROP;
|
||||
+}
|
||||
+
|
||||
+static int xt_delude_check(const char *tablename, const void *e_void,
|
||||
+ const struct xt_target *target, void *targinfo,
|
||||
+#ifdef HAVE_TARGINFOSIZE
|
||||
+ unsigned int targinfosize,
|
||||
+#endif
|
||||
+ unsigned int hook_mask)
|
||||
+{
|
||||
+ if(hook_mask & ~((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD))) {
|
||||
+ printk(KERN_WARNING PFX "DELUDE may not be used in chains "
|
||||
+ "other than INPUT and FORWARD\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static struct xt_target xt_delude_info = {
|
||||
+ .name = "DELUDE",
|
||||
+ .target = xt_delude_target,
|
||||
+ .checkentry = xt_delude_check,
|
||||
+ .table = "filter",
|
||||
+ .hooks = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) |
|
||||
+ (1 << NF_IP_LOCAL_OUT),
|
||||
+ .proto = IPPROTO_TCP,
|
||||
+ .family = AF_INET,
|
||||
+ .me = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int __init xt_delude_init(void)
|
||||
+{
|
||||
+ return xt_register_target(&xt_delude_info);
|
||||
+}
|
||||
+
|
||||
+static void __exit xt_delude_exit(void)
|
||||
+{
|
||||
+ xt_unregister_target(&xt_delude_info);
|
||||
+}
|
||||
+
|
||||
+module_init(xt_delude_init);
|
||||
+module_exit(xt_delude_exit);
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
|
||||
+MODULE_DESCRIPTION("netfilter DELUDE target");
|
||||
diff -ruN linux-2.6.19.1.orig/net/netfilter/xt_portscan.c linux-2.6.19.1/net/netfilter/xt_portscan.c
|
||||
--- linux-2.6.19.1.orig/net/netfilter/xt_portscan.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.1/net/netfilter/xt_portscan.c 2007-01-11 13:28:14.407920893 +0100
|
||||
@@ -0,0 +1,282 @@
|
||||
+/*
|
||||
+ portscan match for netfilter
|
||||
+
|
||||
+ Written by Jan Engelhardt, 2006 - 2007
|
||||
+ released under the terms of the GNU General Public
|
||||
+ License version 2.x and only versions 2.x.
|
||||
+*/
|
||||
+#include <linux/in.h>
|
||||
+#include <linux/ip.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/moduleparam.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/stat.h>
|
||||
+#include <linux/tcp.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/version.h>
|
||||
+#include <linux/netfilter/x_tables.h>
|
||||
+#include <linux/netfilter/xt_tcpudp.h>
|
||||
+#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
|
||||
+# include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
+#else /* linux-2.6.20+ */
|
||||
+# include <net/netfilter/nf_nat_rule.h>
|
||||
+#endif
|
||||
+#include <linux/netfilter/xt_portscan.h>
|
||||
+#define PFX KBUILD_MODNAME ": "
|
||||
+
|
||||
+/* Out of tree workarounds */
|
||||
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
+# define HAVE_MATCHINFOSIZE 1
|
||||
+#endif
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
|
||||
+# define nfmark mark
|
||||
+#endif
|
||||
+
|
||||
+enum {
|
||||
+ TCP_FLAGS_ALL3 = TCP_FLAG_FIN | TCP_FLAG_RST | TCP_FLAG_SYN,
|
||||
+ TCP_FLAGS_ALL4 = TCP_FLAGS_ALL3 | TCP_FLAG_ACK,
|
||||
+ TCP_FLAGS_ALL6 = TCP_FLAGS_ALL4 | TCP_FLAG_PSH | TCP_FLAG_URG,
|
||||
+};
|
||||
+
|
||||
+/* Module parameters */
|
||||
+static unsigned int
|
||||
+ connmark_mask = ~0,
|
||||
+ packet_mask = ~0,
|
||||
+ mark_seen = 0x9,
|
||||
+ mark_synrcv = 0x1,
|
||||
+ mark_closed = 0x2,
|
||||
+ mark_synscan = 0x3,
|
||||
+ mark_estab1 = 0x4,
|
||||
+ mark_estab2 = 0x5,
|
||||
+ mark_cnscan = 0x6,
|
||||
+ mark_grscan = 0x7,
|
||||
+ mark_valid = 0x8;
|
||||
+
|
||||
+module_param(connmark_mask, uint, S_IRUGO | S_IWUSR);
|
||||
+module_param(packet_mask, uint, S_IRUGO | S_IWUSR);
|
||||
+module_param(mark_seen, uint, S_IRUGO | S_IWUSR);
|
||||
+module_param(mark_synrcv, uint, S_IRUGO | S_IWUSR);
|
||||
+module_param(mark_closed, uint, S_IRUGO | S_IWUSR);
|
||||
+module_param(mark_synscan, uint, S_IRUGO | S_IWUSR);
|
||||
+module_param(mark_estab1, uint, S_IRUGO | S_IWUSR);
|
||||
+module_param(mark_estab2, uint, S_IRUGO | S_IWUSR);
|
||||
+module_param(mark_cnscan, uint, S_IRUGO | S_IWUSR);
|
||||
+module_param(mark_grscan, uint, S_IRUGO | S_IWUSR);
|
||||
+module_param(mark_valid, uint, S_IRUGO | S_IWUSR);
|
||||
+MODULE_PARM_DESC(connmark_mask, "only set specified bits in connection mark");
|
||||
+MODULE_PARM_DESC(packet_mask, "only set specified bits in packet mark");
|
||||
+MODULE_PARM_DESC(mark_seen, "nfmark value for packet-seen state");
|
||||
+MODULE_PARM_DESC(mark_synrcv, "connmark value for SYN Received state");
|
||||
+MODULE_PARM_DESC(mark_closed, "connmark value for closed state");
|
||||
+MODULE_PARM_DESC(mark_synscan, "connmark value for SYN Scan state");
|
||||
+MODULE_PARM_DESC(mark_estab1, "connmark value for Established-1 state");
|
||||
+MODULE_PARM_DESC(mark_estab2, "connmark value for Established-2 state");
|
||||
+MODULE_PARM_DESC(mark_cnscan, "connmark value for Connect Scan state");
|
||||
+MODULE_PARM_DESC(mark_grscan, "connmark value for Grab Scan state");
|
||||
+MODULE_PARM_DESC(mark_valid, "connmark value for Valid state");
|
||||
+
|
||||
+/* TCP flag functions */
|
||||
+static inline int tflg_ack4(const struct tcphdr *th)
|
||||
+{
|
||||
+ return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_ACK;
|
||||
+}
|
||||
+
|
||||
+static inline int tflg_ack6(const struct tcphdr *th)
|
||||
+{
|
||||
+ return (tcp_flag_word(th) & TCP_FLAGS_ALL6) == TCP_FLAG_ACK;
|
||||
+}
|
||||
+
|
||||
+static inline int tflg_fin(const struct tcphdr *th)
|
||||
+{
|
||||
+ return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_FIN;
|
||||
+}
|
||||
+
|
||||
+static inline int tflg_rst(const struct tcphdr *th)
|
||||
+{
|
||||
+ return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_RST;
|
||||
+}
|
||||
+
|
||||
+static inline int tflg_rstack(const struct tcphdr *th)
|
||||
+{
|
||||
+ return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==
|
||||
+ (TCP_FLAG_ACK | TCP_FLAG_RST);
|
||||
+}
|
||||
+
|
||||
+static inline int tflg_syn(const struct tcphdr *th)
|
||||
+{
|
||||
+ return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_SYN;
|
||||
+}
|
||||
+
|
||||
+static inline int tflg_synack(const struct tcphdr *th)
|
||||
+{
|
||||
+ return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==
|
||||
+ (TCP_FLAG_SYN | TCP_FLAG_ACK);
|
||||
+}
|
||||
+
|
||||
+/* portscan functions */
|
||||
+static inline int xt_portscan_stealth(const struct tcphdr *th)
|
||||
+{
|
||||
+ /*
|
||||
+ * "Connection refused" replies to our own probes must not be matched.
|
||||
+ */
|
||||
+ if(tflg_rstack(th))
|
||||
+ return 0;
|
||||
+
|
||||
+ if(tflg_rst(th) && printk_ratelimit()) {
|
||||
+ printk(KERN_WARNING PFX "Warning: Pure RST received\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * -p tcp ! --syn -m conntrack --ctstate INVALID: Looking for non-start
|
||||
+ * packets that are not associated with any connection -- this will
|
||||
+ * match most scan types (NULL, XMAS, FIN) and ridiculous flag
|
||||
+ * combinations (SYN-RST, SYN-FIN, SYN-FIN-RST, FIN-RST, etc.).
|
||||
+ */
|
||||
+ return !tflg_syn(th);
|
||||
+}
|
||||
+
|
||||
+static inline int xt_portscan_full(int mark, enum ip_conntrack_info ctstate,
|
||||
+ int loopback, const struct tcphdr *tcph, int payload_len)
|
||||
+{
|
||||
+ if(mark == mark_estab2) {
|
||||
+ /*
|
||||
+ * -m connmark --mark $ESTAB2
|
||||
+ */
|
||||
+ if(tflg_ack4(tcph) && payload_len == 0)
|
||||
+ return mark; /* keep mark */
|
||||
+ else if(tflg_rst(tcph) || tflg_fin(tcph))
|
||||
+ return mark_grscan;
|
||||
+ else
|
||||
+ return mark_valid;
|
||||
+ } else if(mark == mark_estab1) {
|
||||
+ /*
|
||||
+ * -m connmark --mark $ESTAB1
|
||||
+ */
|
||||
+ if(tflg_rst(tcph) || tflg_fin(tcph))
|
||||
+ return mark_cnscan;
|
||||
+ else if(!loopback && tflg_ack4(tcph) && payload_len == 0)
|
||||
+ return mark_estab2;
|
||||
+ else
|
||||
+ return mark_valid;
|
||||
+ } else if(mark == mark_synrcv) {
|
||||
+ /*
|
||||
+ * -m connmark --mark $SYN
|
||||
+ */
|
||||
+ if(loopback && tflg_synack(tcph))
|
||||
+ return mark; /* keep mark */
|
||||
+ else if(loopback && tflg_rstack(tcph))
|
||||
+ return mark_closed;
|
||||
+ else if(tflg_ack6(tcph))
|
||||
+ return mark_estab1;
|
||||
+ else
|
||||
+ return mark_synscan;
|
||||
+ } else if(ctstate == IP_CT_NEW && tflg_syn(tcph)) {
|
||||
+ /*
|
||||
+ * -p tcp --syn --ctstate NEW
|
||||
+ */
|
||||
+ return mark_synrcv;
|
||||
+ }
|
||||
+ return mark;
|
||||
+}
|
||||
+
|
||||
+static int xt_portscan_match(const struct sk_buff *skb,
|
||||
+ const struct net_device *in, const struct net_device *out,
|
||||
+ const struct xt_match *match, const void *matchinfo, int offset,
|
||||
+ unsigned int protoff, int *hotdrop)
|
||||
+{
|
||||
+ const struct xt_portscan_info *info = matchinfo;
|
||||
+ enum ip_conntrack_info ctstate;
|
||||
+ struct ip_conntrack *ctdata;
|
||||
+ const struct tcphdr *tcph;
|
||||
+ struct tcphdr tcph_buf;
|
||||
+
|
||||
+ tcph = skb_header_pointer(skb, protoff, sizeof(tcph_buf), &tcph_buf);
|
||||
+ if(tcph == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Check for invalid packets: -m conntrack --ctstate INVALID */
|
||||
+ if((ctdata = ip_conntrack_get(skb, &ctstate)) == NULL) {
|
||||
+ if(info->match_stealth)
|
||||
+ return xt_portscan_stealth(tcph);
|
||||
+ /*
|
||||
+ * If @ctdata is NULL, we cannot match the other scan
|
||||
+ * types, return.
|
||||
+ */
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * If -m portscan was previously applied to this packet, the rules we
|
||||
+ * simulate must not be run through again. And for speedup, do not call
|
||||
+ * it either when the connection is already VALID.
|
||||
+ */
|
||||
+ if((ctdata->mark & connmark_mask) == mark_valid ||
|
||||
+ (skb->nfmark & packet_mask) != mark_seen)
|
||||
+ {
|
||||
+ unsigned int n;
|
||||
+ n = xt_portscan_full(ctdata->mark & connmark_mask, ctstate,
|
||||
+ in == &loopback_dev, tcph,
|
||||
+ skb->len - protoff - 4 * tcph->doff);
|
||||
+
|
||||
+ ctdata->mark = (ctdata->mark & ~connmark_mask) | n;
|
||||
+ ((struct sk_buff *)skb)->nfmark =
|
||||
+ (skb->nfmark & ~packet_mask) | mark_seen;
|
||||
+ }
|
||||
+
|
||||
+ return (info->match_syn && ctdata->mark == mark_synscan) ||
|
||||
+ (info->match_cn && ctdata->mark == mark_cnscan) ||
|
||||
+ (info->match_gr && ctdata->mark == mark_grscan);
|
||||
+}
|
||||
+
|
||||
+static int xt_portscan_checkentry(const char *tablename, const void *entry,
|
||||
+ const struct xt_match *match, void *matchinfo,
|
||||
+#ifdef HAVE_MATCHINFOSIZE
|
||||
+ unsigned int matchinfosize,
|
||||
+#endif
|
||||
+ unsigned int hook_mask)
|
||||
+{
|
||||
+ const struct xt_portscan_info *info = matchinfo;
|
||||
+#ifdef HAVE_MATCHINFOSIZE
|
||||
+ if(matchinfosize != XT_ALIGN(sizeof(struct xt_portscan_info))) {
|
||||
+ printk(KERN_WARNING PFX "matchinfosize %u != %Zu\n",
|
||||
+ matchinfosize,
|
||||
+ XT_ALIGN(sizeof(struct xt_portscan_info)));
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif
|
||||
+ if((info->match_stealth & ~1) || (info->match_syn & ~1) ||
|
||||
+ (info->match_cn & ~1) || (info->match_gr & ~1)) {
|
||||
+ printk(KERN_WARNING PFX "Invalid flags\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static struct xt_match xt_portscan = {
|
||||
+ .name = "portscan",
|
||||
+ .match = xt_portscan_match,
|
||||
+ .checkentry = xt_portscan_checkentry,
|
||||
+ .matchsize = sizeof(struct xt_portscan_info),
|
||||
+ .proto = IPPROTO_TCP,
|
||||
+ .family = AF_INET,
|
||||
+ .me = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int __init xt_portscan_init(void)
|
||||
+{
|
||||
+ return xt_register_match(&xt_portscan);
|
||||
+}
|
||||
+
|
||||
+static void __exit xt_portscan_exit(void)
|
||||
+{
|
||||
+ xt_unregister_match(&xt_portscan);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+module_init(xt_portscan_init);
|
||||
+module_exit(xt_portscan_exit);
|
||||
+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
|
||||
+MODULE_DESCRIPTION("netfilter portscan match module");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_ALIAS("ipt_portscan");
|
||||
730
target/linux/etrax/patches/generic_2.6/200-sched_esfq.patch
Normal file
730
target/linux/etrax/patches/generic_2.6/200-sched_esfq.patch
Normal file
@@ -0,0 +1,730 @@
|
||||
diff -urN linux-2.6.19.old/include/linux/pkt_sched.h linux-2.6.19.dev/include/linux/pkt_sched.h
|
||||
--- linux-2.6.19.old/include/linux/pkt_sched.h 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/include/linux/pkt_sched.h 2006-12-14 03:13:51.000000000 +0100
|
||||
@@ -146,8 +146,35 @@
|
||||
*
|
||||
* The only reason for this is efficiency, it is possible
|
||||
* to change these parameters in compile time.
|
||||
+ *
|
||||
+ * If you need to play with these values use esfq instead.
|
||||
*/
|
||||
|
||||
+/* ESFQ section */
|
||||
+
|
||||
+enum
|
||||
+{
|
||||
+ /* traditional */
|
||||
+ TCA_SFQ_HASH_CLASSIC,
|
||||
+ TCA_SFQ_HASH_DST,
|
||||
+ TCA_SFQ_HASH_SRC,
|
||||
+ TCA_SFQ_HASH_FWMARK,
|
||||
+ /* direct */
|
||||
+ TCA_SFQ_HASH_DSTDIR,
|
||||
+ TCA_SFQ_HASH_SRCDIR,
|
||||
+ TCA_SFQ_HASH_FWMARKDIR,
|
||||
+};
|
||||
+
|
||||
+struct tc_esfq_qopt
|
||||
+{
|
||||
+ unsigned quantum; /* Bytes per round allocated to flow */
|
||||
+ int perturb_period; /* Period of hash perturbation */
|
||||
+ __u32 limit; /* Maximal packets in queue */
|
||||
+ unsigned divisor; /* Hash divisor */
|
||||
+ unsigned flows; /* Maximal number of flows */
|
||||
+ unsigned hash_kind; /* Hash function to use for flow identification */
|
||||
+};
|
||||
+
|
||||
/* RED section */
|
||||
|
||||
enum
|
||||
diff -urN linux-2.6.19.old/net/sched/Kconfig linux-2.6.19.dev/net/sched/Kconfig
|
||||
--- linux-2.6.19.old/net/sched/Kconfig 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/sched/Kconfig 2006-12-14 03:13:51.000000000 +0100
|
||||
@@ -185,6 +185,28 @@
|
||||
To compile this code as a module, choose M here: the
|
||||
module will be called sch_sfq.
|
||||
|
||||
+config NET_SCH_ESFQ
|
||||
+ tristate "ESFQ queue"
|
||||
+ depends on NET_SCHED
|
||||
+ ---help---
|
||||
+ Say Y here if you want to use the Enhanced Stochastic Fairness
|
||||
+ Queueing (ESFQ) packet scheduling algorithm for some of your network
|
||||
+ devices or as a leaf discipline for a classful qdisc such as HTB or
|
||||
+ CBQ (see the top of <file:net/sched/sch_esfq.c> for details and
|
||||
+ references to the SFQ algorithm).
|
||||
+
|
||||
+ This is an enchanced SFQ version which allows you to control some
|
||||
+ hardcoded values in the SFQ scheduler: queue depth, hash table size,
|
||||
+ and queues limit.
|
||||
+
|
||||
+ ESFQ also adds control to the hash function used to identify packet
|
||||
+ flows. The original SFQ hashes by individual flow (TCP session or UDP
|
||||
+ stream); ESFQ can hash by src or dst IP as well, which can be more
|
||||
+ fair to users in some networking situations.
|
||||
+
|
||||
+ To compile this code as a module, choose M here: the
|
||||
+ module will be called sch_esfq.
|
||||
+
|
||||
config NET_SCH_TEQL
|
||||
tristate "True Link Equalizer (TEQL)"
|
||||
---help---
|
||||
diff -urN linux-2.6.19.old/net/sched/Makefile linux-2.6.19.dev/net/sched/Makefile
|
||||
--- linux-2.6.19.old/net/sched/Makefile 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/sched/Makefile 2006-12-14 03:13:51.000000000 +0100
|
||||
@@ -23,6 +23,7 @@
|
||||
obj-$(CONFIG_NET_SCH_INGRESS) += sch_ingress.o
|
||||
obj-$(CONFIG_NET_SCH_DSMARK) += sch_dsmark.o
|
||||
obj-$(CONFIG_NET_SCH_SFQ) += sch_sfq.o
|
||||
+obj-$(CONFIG_NET_SCH_ESFQ) += sch_esfq.o
|
||||
obj-$(CONFIG_NET_SCH_TBF) += sch_tbf.o
|
||||
obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o
|
||||
obj-$(CONFIG_NET_SCH_PRIO) += sch_prio.o
|
||||
diff -urN linux-2.6.19.old/net/sched/sch_esfq.c linux-2.6.19.dev/net/sched/sch_esfq.c
|
||||
--- linux-2.6.19.old/net/sched/sch_esfq.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ linux-2.6.19.dev/net/sched/sch_esfq.c 2006-12-14 03:13:51.000000000 +0100
|
||||
@@ -0,0 +1,644 @@
|
||||
+/*
|
||||
+ * net/sched/sch_esfq.c Extended Stochastic Fairness Queueing discipline.
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
|
||||
+ *
|
||||
+ * Changes: Alexander Atanasov, <alex@ssi.bg>
|
||||
+ * Added dynamic depth,limit,divisor,hash_kind options.
|
||||
+ * Added dst and src hashes.
|
||||
+ *
|
||||
+ * Alexander Clouter, <alex@digriz.org.uk>
|
||||
+ * Ported ESFQ to Linux 2.6.
|
||||
+ *
|
||||
+ * Corey Hickey, <bugfood-c@fatooh.org>
|
||||
+ * Maintenance of the Linux 2.6 port.
|
||||
+ * Added fwmark hash (thanks to Robert Kurjata)
|
||||
+ * Added direct hashing for src, dst, and fwmark.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/autoconf.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <asm/uaccess.h>
|
||||
+#include <asm/system.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/jiffies.h>
|
||||
+#include <linux/string.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <linux/socket.h>
|
||||
+#include <linux/sockios.h>
|
||||
+#include <linux/in.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/if_ether.h>
|
||||
+#include <linux/inet.h>
|
||||
+#include <linux/netdevice.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
+#include <linux/notifier.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <net/ip.h>
|
||||
+#include <linux/ipv6.h>
|
||||
+#include <net/route.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <net/sock.h>
|
||||
+#include <net/pkt_sched.h>
|
||||
+
|
||||
+
|
||||
+/* Stochastic Fairness Queuing algorithm.
|
||||
+ For more comments look at sch_sfq.c.
|
||||
+ The difference is that you can change limit, depth,
|
||||
+ hash table size and choose 7 hash types.
|
||||
+
|
||||
+ classic: same as in sch_sfq.c
|
||||
+ dst: destination IP address
|
||||
+ src: source IP address
|
||||
+ fwmark: netfilter mark value
|
||||
+ dst_direct:
|
||||
+ src_direct:
|
||||
+ fwmark_direct: direct hashing of the above sources
|
||||
+
|
||||
+ TODO:
|
||||
+ make sfq_change work.
|
||||
+*/
|
||||
+
|
||||
+
|
||||
+/* This type should contain at least SFQ_DEPTH*2 values */
|
||||
+typedef unsigned int esfq_index;
|
||||
+
|
||||
+struct esfq_head
|
||||
+{
|
||||
+ esfq_index next;
|
||||
+ esfq_index prev;
|
||||
+};
|
||||
+
|
||||
+struct esfq_sched_data
|
||||
+{
|
||||
+/* Parameters */
|
||||
+ int perturb_period;
|
||||
+ unsigned quantum; /* Allotment per round: MUST BE >= MTU */
|
||||
+ int limit;
|
||||
+ unsigned depth;
|
||||
+ unsigned hash_divisor;
|
||||
+ unsigned hash_kind;
|
||||
+/* Variables */
|
||||
+ struct timer_list perturb_timer;
|
||||
+ int perturbation;
|
||||
+ esfq_index tail; /* Index of current slot in round */
|
||||
+ esfq_index max_depth; /* Maximal depth */
|
||||
+
|
||||
+ esfq_index *ht; /* Hash table */
|
||||
+ esfq_index *next; /* Active slots link */
|
||||
+ short *allot; /* Current allotment per slot */
|
||||
+ unsigned short *hash; /* Hash value indexed by slots */
|
||||
+ struct sk_buff_head *qs; /* Slot queue */
|
||||
+ struct esfq_head *dep; /* Linked list of slots, indexed by depth */
|
||||
+ unsigned dyn_min; /* For dynamic divisor adjustment; minimum value seen */
|
||||
+ unsigned dyn_max; /* maximum value seen */
|
||||
+ unsigned dyn_range; /* saved range */
|
||||
+};
|
||||
+
|
||||
+static __inline__ unsigned esfq_hash_u32(struct esfq_sched_data *q,u32 h)
|
||||
+{
|
||||
+ int pert = q->perturbation;
|
||||
+
|
||||
+ if (pert)
|
||||
+ h = (h<<pert) ^ (h>>(0x1F - pert));
|
||||
+
|
||||
+ h = ntohl(h) * 2654435761UL;
|
||||
+ return h & (q->hash_divisor-1);
|
||||
+}
|
||||
+
|
||||
+/* Hash input values directly into the "nearest" slot, taking into account the
|
||||
+ * range of input values seen. This is most useful when the hash table is at
|
||||
+ * least as large as the range of possible values. */
|
||||
+static __inline__ unsigned esfq_hash_direct(struct esfq_sched_data *q, u32 h)
|
||||
+{
|
||||
+ /* adjust minimum and maximum */
|
||||
+ if (h < q->dyn_min || h > q->dyn_max) {
|
||||
+ q->dyn_min = h < q->dyn_min ? h : q->dyn_min;
|
||||
+ q->dyn_max = h > q->dyn_max ? h : q->dyn_max;
|
||||
+
|
||||
+ /* find new range */
|
||||
+ if ((q->dyn_range = q->dyn_max - q->dyn_min) >= q->hash_divisor)
|
||||
+ printk(KERN_WARNING "ESFQ: (direct hash) Input range %u is larger than hash "
|
||||
+ "table. See ESFQ README for details.\n", q->dyn_range);
|
||||
+ }
|
||||
+
|
||||
+ /* hash input values into slot numbers */
|
||||
+ if (q->dyn_min == q->dyn_max)
|
||||
+ return 0; /* only one value seen; avoid division by 0 */
|
||||
+ else
|
||||
+ return (h - q->dyn_min) * (q->hash_divisor - 1) / q->dyn_range;
|
||||
+}
|
||||
+
|
||||
+static __inline__ unsigned esfq_fold_hash_classic(struct esfq_sched_data *q, u32 h, u32 h1)
|
||||
+{
|
||||
+ int pert = q->perturbation;
|
||||
+
|
||||
+ /* Have we any rotation primitives? If not, WHY? */
|
||||
+ h ^= (h1<<pert) ^ (h1>>(0x1F - pert));
|
||||
+ h ^= h>>10;
|
||||
+ return h & (q->hash_divisor-1);
|
||||
+}
|
||||
+
|
||||
+static unsigned esfq_hash(struct esfq_sched_data *q, struct sk_buff *skb)
|
||||
+{
|
||||
+ u32 h, h2;
|
||||
+ u32 hs;
|
||||
+ u32 nfm;
|
||||
+
|
||||
+ switch (skb->protocol) {
|
||||
+ case __constant_htons(ETH_P_IP):
|
||||
+ {
|
||||
+ struct iphdr *iph = skb->nh.iph;
|
||||
+ h = iph->daddr;
|
||||
+ hs = iph->saddr;
|
||||
+ nfm = skb->nfmark;
|
||||
+ h2 = hs^iph->protocol;
|
||||
+ if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
|
||||
+ (iph->protocol == IPPROTO_TCP ||
|
||||
+ iph->protocol == IPPROTO_UDP ||
|
||||
+ iph->protocol == IPPROTO_SCTP ||
|
||||
+ iph->protocol == IPPROTO_DCCP ||
|
||||
+ iph->protocol == IPPROTO_ESP))
|
||||
+ h2 ^= *(((u32*)iph) + iph->ihl);
|
||||
+ break;
|
||||
+ }
|
||||
+ case __constant_htons(ETH_P_IPV6):
|
||||
+ {
|
||||
+ struct ipv6hdr *iph = skb->nh.ipv6h;
|
||||
+ h = iph->daddr.s6_addr32[3];
|
||||
+ hs = iph->saddr.s6_addr32[3];
|
||||
+ nfm = skb->nfmark;
|
||||
+ h2 = hs^iph->nexthdr;
|
||||
+ if (iph->nexthdr == IPPROTO_TCP ||
|
||||
+ iph->nexthdr == IPPROTO_UDP ||
|
||||
+ iph->nexthdr == IPPROTO_SCTP ||
|
||||
+ iph->nexthdr == IPPROTO_DCCP ||
|
||||
+ iph->nexthdr == IPPROTO_ESP)
|
||||
+ h2 ^= *(u32*)&iph[1];
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ h = (u32)(unsigned long)skb->dst;
|
||||
+ hs = (u32)(unsigned long)skb->sk;
|
||||
+ nfm = skb->nfmark;
|
||||
+ h2 = hs^skb->protocol;
|
||||
+ }
|
||||
+ switch(q->hash_kind)
|
||||
+ {
|
||||
+ case TCA_SFQ_HASH_CLASSIC:
|
||||
+ return esfq_fold_hash_classic(q, h, h2);
|
||||
+ case TCA_SFQ_HASH_DST:
|
||||
+ return esfq_hash_u32(q,h);
|
||||
+ case TCA_SFQ_HASH_DSTDIR:
|
||||
+ return esfq_hash_direct(q, ntohl(h));
|
||||
+ case TCA_SFQ_HASH_SRC:
|
||||
+ return esfq_hash_u32(q,hs);
|
||||
+ case TCA_SFQ_HASH_SRCDIR:
|
||||
+ return esfq_hash_direct(q, ntohl(hs));
|
||||
+#ifdef CONFIG_NETFILTER
|
||||
+ case TCA_SFQ_HASH_FWMARK:
|
||||
+ return esfq_hash_u32(q,nfm);
|
||||
+ case TCA_SFQ_HASH_FWMARKDIR:
|
||||
+ return esfq_hash_direct(q,nfm);
|
||||
+#endif
|
||||
+ default:
|
||||
+ if (net_ratelimit())
|
||||
+ printk(KERN_WARNING "ESFQ: Unknown hash method. Falling back to classic.\n");
|
||||
+ }
|
||||
+ return esfq_fold_hash_classic(q, h, h2);
|
||||
+}
|
||||
+
|
||||
+static inline void esfq_link(struct esfq_sched_data *q, esfq_index x)
|
||||
+{
|
||||
+ esfq_index p, n;
|
||||
+ int d = q->qs[x].qlen + q->depth;
|
||||
+
|
||||
+ p = d;
|
||||
+ n = q->dep[d].next;
|
||||
+ q->dep[x].next = n;
|
||||
+ q->dep[x].prev = p;
|
||||
+ q->dep[p].next = q->dep[n].prev = x;
|
||||
+}
|
||||
+
|
||||
+static inline void esfq_dec(struct esfq_sched_data *q, esfq_index x)
|
||||
+{
|
||||
+ esfq_index p, n;
|
||||
+
|
||||
+ n = q->dep[x].next;
|
||||
+ p = q->dep[x].prev;
|
||||
+ q->dep[p].next = n;
|
||||
+ q->dep[n].prev = p;
|
||||
+
|
||||
+ if (n == p && q->max_depth == q->qs[x].qlen + 1)
|
||||
+ q->max_depth--;
|
||||
+
|
||||
+ esfq_link(q, x);
|
||||
+}
|
||||
+
|
||||
+static inline void esfq_inc(struct esfq_sched_data *q, esfq_index x)
|
||||
+{
|
||||
+ esfq_index p, n;
|
||||
+ int d;
|
||||
+
|
||||
+ n = q->dep[x].next;
|
||||
+ p = q->dep[x].prev;
|
||||
+ q->dep[p].next = n;
|
||||
+ q->dep[n].prev = p;
|
||||
+ d = q->qs[x].qlen;
|
||||
+ if (q->max_depth < d)
|
||||
+ q->max_depth = d;
|
||||
+
|
||||
+ esfq_link(q, x);
|
||||
+}
|
||||
+
|
||||
+static unsigned int esfq_drop(struct Qdisc *sch)
|
||||
+{
|
||||
+ struct esfq_sched_data *q = qdisc_priv(sch);
|
||||
+ esfq_index d = q->max_depth;
|
||||
+ struct sk_buff *skb;
|
||||
+ unsigned int len;
|
||||
+
|
||||
+ /* Queue is full! Find the longest slot and
|
||||
+ drop a packet from it */
|
||||
+
|
||||
+ if (d > 1) {
|
||||
+ esfq_index x = q->dep[d+q->depth].next;
|
||||
+ skb = q->qs[x].prev;
|
||||
+ len = skb->len;
|
||||
+ __skb_unlink(skb, &q->qs[x]);
|
||||
+ kfree_skb(skb);
|
||||
+ esfq_dec(q, x);
|
||||
+ sch->q.qlen--;
|
||||
+ sch->qstats.drops++;
|
||||
+ return len;
|
||||
+ }
|
||||
+
|
||||
+ if (d == 1) {
|
||||
+ /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
|
||||
+ d = q->next[q->tail];
|
||||
+ q->next[q->tail] = q->next[d];
|
||||
+ q->allot[q->next[d]] += q->quantum;
|
||||
+ skb = q->qs[d].prev;
|
||||
+ len = skb->len;
|
||||
+ __skb_unlink(skb, &q->qs[d]);
|
||||
+ kfree_skb(skb);
|
||||
+ esfq_dec(q, d);
|
||||
+ sch->q.qlen--;
|
||||
+ q->ht[q->hash[d]] = q->depth;
|
||||
+ sch->qstats.drops++;
|
||||
+ return len;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+esfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
|
||||
+{
|
||||
+ struct esfq_sched_data *q = qdisc_priv(sch);
|
||||
+ unsigned hash = esfq_hash(q, skb);
|
||||
+ unsigned depth = q->depth;
|
||||
+ esfq_index x;
|
||||
+
|
||||
+ x = q->ht[hash];
|
||||
+ if (x == depth) {
|
||||
+ q->ht[hash] = x = q->dep[depth].next;
|
||||
+ q->hash[x] = hash;
|
||||
+ }
|
||||
+ __skb_queue_tail(&q->qs[x], skb);
|
||||
+ esfq_inc(q, x);
|
||||
+ if (q->qs[x].qlen == 1) { /* The flow is new */
|
||||
+ if (q->tail == depth) { /* It is the first flow */
|
||||
+ q->tail = x;
|
||||
+ q->next[x] = x;
|
||||
+ q->allot[x] = q->quantum;
|
||||
+ } else {
|
||||
+ q->next[x] = q->next[q->tail];
|
||||
+ q->next[q->tail] = x;
|
||||
+ q->tail = x;
|
||||
+ }
|
||||
+ }
|
||||
+ if (++sch->q.qlen < q->limit-1) {
|
||||
+ sch->bstats.bytes += skb->len;
|
||||
+ sch->bstats.packets++;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ esfq_drop(sch);
|
||||
+ return NET_XMIT_CN;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+esfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
|
||||
+{
|
||||
+ struct esfq_sched_data *q = qdisc_priv(sch);
|
||||
+ unsigned hash = esfq_hash(q, skb);
|
||||
+ unsigned depth = q->depth;
|
||||
+ esfq_index x;
|
||||
+
|
||||
+ x = q->ht[hash];
|
||||
+ if (x == depth) {
|
||||
+ q->ht[hash] = x = q->dep[depth].next;
|
||||
+ q->hash[x] = hash;
|
||||
+ }
|
||||
+ __skb_queue_head(&q->qs[x], skb);
|
||||
+ esfq_inc(q, x);
|
||||
+ if (q->qs[x].qlen == 1) { /* The flow is new */
|
||||
+ if (q->tail == depth) { /* It is the first flow */
|
||||
+ q->tail = x;
|
||||
+ q->next[x] = x;
|
||||
+ q->allot[x] = q->quantum;
|
||||
+ } else {
|
||||
+ q->next[x] = q->next[q->tail];
|
||||
+ q->next[q->tail] = x;
|
||||
+ q->tail = x;
|
||||
+ }
|
||||
+ }
|
||||
+ if (++sch->q.qlen < q->limit - 1) {
|
||||
+ sch->qstats.requeues++;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ sch->qstats.drops++;
|
||||
+ esfq_drop(sch);
|
||||
+ return NET_XMIT_CN;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+static struct sk_buff *
|
||||
+esfq_dequeue(struct Qdisc* sch)
|
||||
+{
|
||||
+ struct esfq_sched_data *q = qdisc_priv(sch);
|
||||
+ struct sk_buff *skb;
|
||||
+ unsigned depth = q->depth;
|
||||
+ esfq_index a, old_a;
|
||||
+
|
||||
+ /* No active slots */
|
||||
+ if (q->tail == depth)
|
||||
+ return NULL;
|
||||
+
|
||||
+ a = old_a = q->next[q->tail];
|
||||
+
|
||||
+ /* Grab packet */
|
||||
+ skb = __skb_dequeue(&q->qs[a]);
|
||||
+ esfq_dec(q, a);
|
||||
+ sch->q.qlen--;
|
||||
+
|
||||
+ /* Is the slot empty? */
|
||||
+ if (q->qs[a].qlen == 0) {
|
||||
+ q->ht[q->hash[a]] = depth;
|
||||
+ a = q->next[a];
|
||||
+ if (a == old_a) {
|
||||
+ q->tail = depth;
|
||||
+ return skb;
|
||||
+ }
|
||||
+ q->next[q->tail] = a;
|
||||
+ q->allot[a] += q->quantum;
|
||||
+ } else if ((q->allot[a] -= skb->len) <= 0) {
|
||||
+ q->tail = a;
|
||||
+ a = q->next[a];
|
||||
+ q->allot[a] += q->quantum;
|
||||
+ }
|
||||
+
|
||||
+ return skb;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+esfq_reset(struct Qdisc* sch)
|
||||
+{
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ while ((skb = esfq_dequeue(sch)) != NULL)
|
||||
+ kfree_skb(skb);
|
||||
+}
|
||||
+
|
||||
+static void esfq_perturbation(unsigned long arg)
|
||||
+{
|
||||
+ struct Qdisc *sch = (struct Qdisc*)arg;
|
||||
+ struct esfq_sched_data *q = qdisc_priv(sch);
|
||||
+
|
||||
+ q->perturbation = net_random()&0x1F;
|
||||
+
|
||||
+ if (q->perturb_period) {
|
||||
+ q->perturb_timer.expires = jiffies + q->perturb_period;
|
||||
+ add_timer(&q->perturb_timer);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int esfq_change(struct Qdisc *sch, struct rtattr *opt)
|
||||
+{
|
||||
+ struct esfq_sched_data *q = qdisc_priv(sch);
|
||||
+ struct tc_esfq_qopt *ctl = RTA_DATA(opt);
|
||||
+ int old_perturb = q->perturb_period;
|
||||
+
|
||||
+ if (opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ sch_tree_lock(sch);
|
||||
+ q->quantum = ctl->quantum ? : psched_mtu(sch->dev);
|
||||
+ q->perturb_period = ctl->perturb_period*HZ;
|
||||
+// q->hash_divisor = ctl->divisor;
|
||||
+// q->tail = q->limit = q->depth = ctl->flows;
|
||||
+
|
||||
+ if (ctl->limit)
|
||||
+ q->limit = min_t(u32, ctl->limit, q->depth);
|
||||
+
|
||||
+ if (ctl->hash_kind) {
|
||||
+ q->hash_kind = ctl->hash_kind;
|
||||
+ if (q->hash_kind != TCA_SFQ_HASH_CLASSIC)
|
||||
+ q->perturb_period = 0;
|
||||
+ }
|
||||
+
|
||||
+ // is sch_tree_lock enough to do this ?
|
||||
+ while (sch->q.qlen >= q->limit-1)
|
||||
+ esfq_drop(sch);
|
||||
+
|
||||
+ if (old_perturb)
|
||||
+ del_timer(&q->perturb_timer);
|
||||
+ if (q->perturb_period) {
|
||||
+ q->perturb_timer.expires = jiffies + q->perturb_period;
|
||||
+ add_timer(&q->perturb_timer);
|
||||
+ } else {
|
||||
+ q->perturbation = 0;
|
||||
+ }
|
||||
+ sch_tree_unlock(sch);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int esfq_init(struct Qdisc *sch, struct rtattr *opt)
|
||||
+{
|
||||
+ struct esfq_sched_data *q = qdisc_priv(sch);
|
||||
+ struct tc_esfq_qopt *ctl;
|
||||
+ esfq_index p = ~0UL/2;
|
||||
+ int i;
|
||||
+
|
||||
+ if (opt && opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ init_timer(&q->perturb_timer);
|
||||
+ q->perturb_timer.data = (unsigned long)sch;
|
||||
+ q->perturb_timer.function = esfq_perturbation;
|
||||
+ q->perturbation = 0;
|
||||
+ q->hash_kind = TCA_SFQ_HASH_CLASSIC;
|
||||
+ q->max_depth = 0;
|
||||
+ q->dyn_min = ~0U; /* maximum value for this type */
|
||||
+ q->dyn_max = 0; /* dyn_min/dyn_max will be set properly upon first packet */
|
||||
+ if (opt == NULL) {
|
||||
+ q->quantum = psched_mtu(sch->dev);
|
||||
+ q->perturb_period = 0;
|
||||
+ q->hash_divisor = 1024;
|
||||
+ q->tail = q->limit = q->depth = 128;
|
||||
+
|
||||
+ } else {
|
||||
+ ctl = RTA_DATA(opt);
|
||||
+ q->quantum = ctl->quantum ? : psched_mtu(sch->dev);
|
||||
+ q->perturb_period = ctl->perturb_period*HZ;
|
||||
+ q->hash_divisor = ctl->divisor ? : 1024;
|
||||
+ q->tail = q->limit = q->depth = ctl->flows ? : 128;
|
||||
+
|
||||
+ if ( q->depth > p - 1 )
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (ctl->limit)
|
||||
+ q->limit = min_t(u32, ctl->limit, q->depth);
|
||||
+
|
||||
+ if (ctl->hash_kind) {
|
||||
+ q->hash_kind = ctl->hash_kind;
|
||||
+ }
|
||||
+
|
||||
+ if (q->perturb_period) {
|
||||
+ q->perturb_timer.expires = jiffies + q->perturb_period;
|
||||
+ add_timer(&q->perturb_timer);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ q->ht = kmalloc(q->hash_divisor*sizeof(esfq_index), GFP_KERNEL);
|
||||
+ if (!q->ht)
|
||||
+ goto err_case;
|
||||
+
|
||||
+ q->dep = kmalloc((1+q->depth*2)*sizeof(struct esfq_head), GFP_KERNEL);
|
||||
+ if (!q->dep)
|
||||
+ goto err_case;
|
||||
+ q->next = kmalloc(q->depth*sizeof(esfq_index), GFP_KERNEL);
|
||||
+ if (!q->next)
|
||||
+ goto err_case;
|
||||
+
|
||||
+ q->allot = kmalloc(q->depth*sizeof(short), GFP_KERNEL);
|
||||
+ if (!q->allot)
|
||||
+ goto err_case;
|
||||
+ q->hash = kmalloc(q->depth*sizeof(unsigned short), GFP_KERNEL);
|
||||
+ if (!q->hash)
|
||||
+ goto err_case;
|
||||
+ q->qs = kmalloc(q->depth*sizeof(struct sk_buff_head), GFP_KERNEL);
|
||||
+ if (!q->qs)
|
||||
+ goto err_case;
|
||||
+
|
||||
+ for (i=0; i< q->hash_divisor; i++)
|
||||
+ q->ht[i] = q->depth;
|
||||
+ for (i=0; i<q->depth; i++) {
|
||||
+ skb_queue_head_init(&q->qs[i]);
|
||||
+ q->dep[i+q->depth].next = i+q->depth;
|
||||
+ q->dep[i+q->depth].prev = i+q->depth;
|
||||
+ }
|
||||
+
|
||||
+ for (i=0; i<q->depth; i++)
|
||||
+ esfq_link(q, i);
|
||||
+ return 0;
|
||||
+err_case:
|
||||
+ del_timer(&q->perturb_timer);
|
||||
+ if (q->ht)
|
||||
+ kfree(q->ht);
|
||||
+ if (q->dep)
|
||||
+ kfree(q->dep);
|
||||
+ if (q->next)
|
||||
+ kfree(q->next);
|
||||
+ if (q->allot)
|
||||
+ kfree(q->allot);
|
||||
+ if (q->hash)
|
||||
+ kfree(q->hash);
|
||||
+ if (q->qs)
|
||||
+ kfree(q->qs);
|
||||
+ return -ENOBUFS;
|
||||
+}
|
||||
+
|
||||
+static void esfq_destroy(struct Qdisc *sch)
|
||||
+{
|
||||
+ struct esfq_sched_data *q = qdisc_priv(sch);
|
||||
+ del_timer(&q->perturb_timer);
|
||||
+ if(q->ht)
|
||||
+ kfree(q->ht);
|
||||
+ if(q->dep)
|
||||
+ kfree(q->dep);
|
||||
+ if(q->next)
|
||||
+ kfree(q->next);
|
||||
+ if(q->allot)
|
||||
+ kfree(q->allot);
|
||||
+ if(q->hash)
|
||||
+ kfree(q->hash);
|
||||
+ if(q->qs)
|
||||
+ kfree(q->qs);
|
||||
+}
|
||||
+
|
||||
+static int esfq_dump(struct Qdisc *sch, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct esfq_sched_data *q = qdisc_priv(sch);
|
||||
+ unsigned char *b = skb->tail;
|
||||
+ struct tc_esfq_qopt opt;
|
||||
+
|
||||
+ opt.quantum = q->quantum;
|
||||
+ opt.perturb_period = q->perturb_period/HZ;
|
||||
+
|
||||
+ opt.limit = q->limit;
|
||||
+ opt.divisor = q->hash_divisor;
|
||||
+ opt.flows = q->depth;
|
||||
+ opt.hash_kind = q->hash_kind;
|
||||
+
|
||||
+ RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
|
||||
+
|
||||
+ return skb->len;
|
||||
+
|
||||
+rtattr_failure:
|
||||
+ skb_trim(skb, b - skb->data);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static struct Qdisc_ops esfq_qdisc_ops =
|
||||
+{
|
||||
+ .next = NULL,
|
||||
+ .cl_ops = NULL,
|
||||
+ .id = "esfq",
|
||||
+ .priv_size = sizeof(struct esfq_sched_data),
|
||||
+ .enqueue = esfq_enqueue,
|
||||
+ .dequeue = esfq_dequeue,
|
||||
+ .requeue = esfq_requeue,
|
||||
+ .drop = esfq_drop,
|
||||
+ .init = esfq_init,
|
||||
+ .reset = esfq_reset,
|
||||
+ .destroy = esfq_destroy,
|
||||
+ .change = NULL, /* esfq_change - needs more work */
|
||||
+ .dump = esfq_dump,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int __init esfq_module_init(void)
|
||||
+{
|
||||
+ return register_qdisc(&esfq_qdisc_ops);
|
||||
+}
|
||||
+static void __exit esfq_module_exit(void)
|
||||
+{
|
||||
+ unregister_qdisc(&esfq_qdisc_ops);
|
||||
+}
|
||||
+module_init(esfq_module_init)
|
||||
+module_exit(esfq_module_exit)
|
||||
+MODULE_LICENSE("GPL");
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,58 @@
|
||||
diff -urN linux-2.6.19.old/fs/jffs2/build.c linux-2.6.19.dev/fs/jffs2/build.c
|
||||
--- linux-2.6.19.old/fs/jffs2/build.c 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/fs/jffs2/build.c 2006-12-14 03:13:57.000000000 +0100
|
||||
@@ -107,6 +107,17 @@
|
||||
dbg_fsbuild("scanned flash completely\n");
|
||||
jffs2_dbg_dump_block_lists_nolock(c);
|
||||
|
||||
+ if (c->flags & (1 << 7)) {
|
||||
+ printk("%s(): unlocking the mtd device... ", __func__);
|
||||
+ if (c->mtd->unlock)
|
||||
+ c->mtd->unlock(c->mtd, 0, c->mtd->size);
|
||||
+ printk("done.\n");
|
||||
+
|
||||
+ printk("%s(): erasing all blocks after the end marker... ", __func__);
|
||||
+ jffs2_erase_pending_blocks(c, -1);
|
||||
+ printk("done.\n");
|
||||
+ }
|
||||
+
|
||||
dbg_fsbuild("pass 1 starting\n");
|
||||
c->flags |= JFFS2_SB_FLAG_BUILDING;
|
||||
/* Now scan the directory tree, increasing nlink according to every dirent found. */
|
||||
diff -urN linux-2.6.19.old/fs/jffs2/scan.c linux-2.6.19.dev/fs/jffs2/scan.c
|
||||
--- linux-2.6.19.old/fs/jffs2/scan.c 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/fs/jffs2/scan.c 2006-12-14 03:13:57.000000000 +0100
|
||||
@@ -141,9 +141,12 @@
|
||||
|
||||
/* reset summary info for next eraseblock scan */
|
||||
jffs2_sum_reset_collected(s);
|
||||
-
|
||||
- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
|
||||
- buf_size, s);
|
||||
+
|
||||
+ if (c->flags & (1 << 7))
|
||||
+ ret = BLK_STATE_ALLFF;
|
||||
+ else
|
||||
+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
|
||||
+ buf_size, s);
|
||||
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@@ -540,6 +543,17 @@
|
||||
return err;
|
||||
}
|
||||
|
||||
+ if ((buf[0] == 0xde) &&
|
||||
+ (buf[1] == 0xad) &&
|
||||
+ (buf[2] == 0xc0) &&
|
||||
+ (buf[3] == 0xde)) {
|
||||
+ /* end of filesystem. erase everything after this point */
|
||||
+ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset);
|
||||
+ c->flags |= (1 << 7);
|
||||
+
|
||||
+ return BLK_STATE_ALLFF;
|
||||
+ }
|
||||
+
|
||||
/* We temporarily use 'ofs' as a pointer into the buffer/jeb */
|
||||
ofs = 0;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
diff -urN linux-2.6.19.old/drivers/net/r8169.c linux-2.6.19.dev/drivers/net/r8169.c
|
||||
--- linux-2.6.19.old/drivers/net/r8169.c 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/drivers/net/r8169.c 2006-12-14 03:14:01.000000000 +0100
|
||||
@@ -491,7 +491,7 @@
|
||||
#endif
|
||||
|
||||
static const u16 rtl8169_intr_mask =
|
||||
- SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK;
|
||||
+ LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK;
|
||||
static const u16 rtl8169_napi_event =
|
||||
RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr;
|
||||
static const unsigned int rtl8169_rx_config =
|
||||
@@ -2584,10 +2584,12 @@
|
||||
if (!(status & rtl8169_intr_mask))
|
||||
break;
|
||||
|
||||
+#if 0
|
||||
if (unlikely(status & SYSErr)) {
|
||||
rtl8169_pcierr_interrupt(dev);
|
||||
break;
|
||||
}
|
||||
+#endif
|
||||
|
||||
if (status & LinkChg)
|
||||
rtl8169_check_link_status(dev, tp, ioaddr);
|
||||
7807
target/linux/etrax/patches/generic_2.6/209-mini_fo.patch
Normal file
7807
target/linux/etrax/patches/generic_2.6/209-mini_fo.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
--- linux.old/include/linux/netdevice.h 2006-12-30 18:49:37.916951328 +0100
|
||||
+++ linux.dev/include/linux/netdevice.h 2006-12-30 18:49:49.573179312 +0100
|
||||
@@ -526,6 +526,8 @@
|
||||
struct class_device class_dev;
|
||||
/* space for optional statistics and wireless sysfs groups */
|
||||
struct attribute_group *sysfs_groups[3];
|
||||
+
|
||||
+ void *ieee80211_ptr;
|
||||
};
|
||||
|
||||
#define NETDEV_ALIGN 32
|
||||
@@ -0,0 +1,11 @@
|
||||
--- linux.old/drivers/mtd/devices/block2mtd.c 2007-02-01 20:13:47.147274772 +0100
|
||||
+++ linux/drivers/mtd/devices/block2mtd.c 2007-02-01 20:19:59.753034993 +0100
|
||||
@@ -40,7 +40,7 @@
|
||||
static LIST_HEAD(blkmtd_device_list);
|
||||
|
||||
|
||||
-#define PAGE_READAHEAD 64
|
||||
+#define PAGE_READAHEAD 0
|
||||
static void cache_readahead(struct address_space *mapping, int index)
|
||||
{
|
||||
filler_t *filler = (filler_t*)mapping->a_ops->readpage;
|
||||
@@ -0,0 +1,11 @@
|
||||
--- linux.dev/drivers/mtd/devices/block2mtd.c.old 2007-02-18 14:08:59.519952312 +0100
|
||||
+++ linux.dev/drivers/mtd/devices/block2mtd.c 2007-02-18 14:09:04.219237912 +0100
|
||||
@@ -111,7 +111,7 @@
|
||||
if (IS_ERR(page))
|
||||
return PTR_ERR(page);
|
||||
|
||||
- max = (u_long*)page_address(page) + PAGE_SIZE;
|
||||
+ max = (u_long*) ((u8 *) page_address(page) + PAGE_SIZE);
|
||||
for (p=(u_long*)page_address(page); p<max; p++)
|
||||
if (*p != -1UL) {
|
||||
lock_page(page);
|
||||
13085
target/linux/etrax/patches/generic_2.6/510-Yaffs.patch
Normal file
13085
target/linux/etrax/patches/generic_2.6/510-Yaffs.patch
Normal file
File diff suppressed because it is too large
Load Diff
12
target/linux/etrax/patches/generic_2.6/700-airprime.patch
Normal file
12
target/linux/etrax/patches/generic_2.6/700-airprime.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff -urN linux-2.6.19.2-old/drivers/usb/serial/airprime.c linux-2.6.19.2-dev/drivers/usb/serial/airprime.c
|
||||
--- linux-2.6.19.2-old/drivers/usb/serial/airprime.c 2007-05-01 14:11:28.000000000 -0700
|
||||
+++ linux-2.6.19.2-dev/drivers/usb/serial/airprime.c 2007-05-01 14:12:03.000000000 -0700
|
||||
@@ -20,6 +20,8 @@
|
||||
{ USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
|
||||
{ USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */
|
||||
{ USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */
|
||||
+ { USB_DEVICE(0x1410, 0x1130) }, /* Novatel Wireless S720 CDMA/EV-DO */
|
||||
+ { USB_DEVICE(0x1410, 0x2110) }, /* Novatel Wireless U720 CDMA/EV-DO */
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, id_table);
|
||||
@@ -0,0 +1,48 @@
|
||||
diff -urN linux-2.6.19.old/include/linux/time.h linux-2.6.19.dev/include/linux/time.h
|
||||
--- linux-2.6.19.old/include/linux/time.h 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/include/linux/time.h 2006-12-14 03:14:05.000000000 +0100
|
||||
@@ -1,6 +1,10 @@
|
||||
#ifndef _LINUX_TIME_H
|
||||
#define _LINUX_TIME_H
|
||||
|
||||
+#ifndef __KERNEL__
|
||||
+#include <time.h>
|
||||
+#else
|
||||
+
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
@@ -223,4 +227,6 @@
|
||||
*/
|
||||
#define TIMER_ABSTIME 0x01
|
||||
|
||||
+#endif /* __KERNEL__ DEBIAN */
|
||||
+
|
||||
#endif
|
||||
diff -urN linux-2.6.19.old/include/linux/types.h linux-2.6.19.dev/include/linux/types.h
|
||||
--- linux-2.6.19.old/include/linux/types.h 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/include/linux/types.h 2006-12-14 03:14:05.000000000 +0100
|
||||
@@ -1,6 +1,14 @@
|
||||
#ifndef _LINUX_TYPES_H
|
||||
#define _LINUX_TYPES_H
|
||||
|
||||
+/* Debian: Use userland types instead. */
|
||||
+#ifndef __KERNEL__
|
||||
+# include <sys/types.h>
|
||||
+/* For other kernel headers. */
|
||||
+# include <linux/posix_types.h>
|
||||
+# include <asm/types.h>
|
||||
+#else
|
||||
+
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define BITS_TO_LONGS(bits) \
|
||||
@@ -156,6 +164,8 @@
|
||||
|
||||
#endif /* __KERNEL_STRICT_NAMES */
|
||||
|
||||
+#endif /* __KERNEL__ DEBIAN */
|
||||
+
|
||||
/*
|
||||
* Below are truly Linux-specific types that should never collide with
|
||||
* any application/library that wants linux/types.h.
|
||||
@@ -0,0 +1,11 @@
|
||||
diff -urN linux-2.6.19.old/include/asm-mips/bitops.h linux-2.6.19.dev/include/asm-mips/bitops.h
|
||||
--- linux-2.6.19.old/include/asm-mips/bitops.h 2006-11-29 22:57:37.000000000 +0100
|
||||
+++ linux-2.6.19.dev/include/asm-mips/bitops.h 2006-12-14 03:14:07.000000000 +0100
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/types.h>
|
||||
+#include <asm/war.h>
|
||||
#include <asm/bug.h>
|
||||
#include <asm/byteorder.h> /* sigh ... */
|
||||
#include <asm/cpu-features.h>
|
||||
@@ -0,0 +1,145 @@
|
||||
diff -urN linux-2.6.19.1/scripts/mod/file2alias.c linux-2.6.19.1.new/scripts/mod/file2alias.c
|
||||
--- linux-2.6.19.1/scripts/mod/file2alias.c 2006-12-11 20:32:53.000000000 +0100
|
||||
+++ linux-2.6.19.1.new/scripts/mod/file2alias.c 2007-01-02 15:28:47.000000000 +0100
|
||||
@@ -37,7 +37,21 @@
|
||||
* even potentially has different endianness and word sizes, since
|
||||
* we handle those differences explicitly below */
|
||||
#include "../../include/linux/mod_devicetable.h"
|
||||
+#ifndef __APPLE__
|
||||
#include "../../include/linux/input.h"
|
||||
+#else
|
||||
+#define EV_MAX 0x1f
|
||||
+#define KEY_MUTE 113
|
||||
+#define KEY_MIN_INTERESTING KEY_MUTE
|
||||
+#define KEY_MAX 0x1ff
|
||||
+#define REL_MAX 0x0f
|
||||
+#define ABS_MAX 0x3f
|
||||
+#define MSC_MAX 0x07
|
||||
+#define LED_MAX 0x0f
|
||||
+#define SND_MAX 0x07
|
||||
+#define FF_MAX 0x7f
|
||||
+#define SW_MAX 0x0f
|
||||
+#endif
|
||||
|
||||
#define ADD(str, sep, cond, field) \
|
||||
do { \
|
||||
diff -urN linux-2.6.19.1/scripts/mod/mk_elfconfig.c linux-2.6.19.1.new/scripts/mod/mk_elfconfig.c
|
||||
--- linux-2.6.19.1/scripts/mod/mk_elfconfig.c 2006-12-11 20:32:53.000000000 +0100
|
||||
+++ linux-2.6.19.1.new/scripts/mod/mk_elfconfig.c 2007-01-02 15:43:57.000000000 +0100
|
||||
@@ -1,7 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
+#ifndef __APPLE__
|
||||
#include <elf.h>
|
||||
+#else
|
||||
+#include "../../../../../tools/sstrip/include/elf.h"
|
||||
+#endif
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
diff -urN linux-2.6.19.1/scripts/mod/modpost.h linux-2.6.19.1.new/scripts/mod/modpost.h
|
||||
--- linux-2.6.19.1/scripts/mod/modpost.h 2006-12-11 20:32:53.000000000 +0100
|
||||
+++ linux-2.6.19.1.new/scripts/mod/modpost.h 2007-01-02 15:40:55.000000000 +0100
|
||||
@@ -7,7 +7,11 @@
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
+#ifndef __APPLE__
|
||||
#include <elf.h>
|
||||
+#else
|
||||
+#include "../../../../../tools/sstrip/include/elf.h"
|
||||
+#endif
|
||||
|
||||
#include "elfconfig.h"
|
||||
|
||||
diff -urN linux-2.6.19.1/scripts/mod/sumversion.c linux-2.6.19.1.new/scripts/mod/sumversion.c
|
||||
--- linux-2.6.19.1/scripts/mod/sumversion.c 2006-12-11 20:32:53.000000000 +0100
|
||||
+++ linux-2.6.19.1.new/scripts/mod/sumversion.c 2007-01-02 15:30:23.000000000 +0100
|
||||
@@ -8,6 +8,9 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "modpost.h"
|
||||
+#ifdef __APPLE__
|
||||
+#include <limits.h>
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Stolen form Cryptographic API.
|
||||
diff -urN linux-2.6.19.1/scripts/kconfig linux-2.6.19.1.new/scripts/kconfig/Makefile
|
||||
--- linux-2.6.19.1/scripts/kconfig/Makefile 2007-01-04 17:49:35.000000000 +0100
|
||||
+++ linux-2.6.19.1.new/scripts/kconfig/Makefile 2007-01-04 17:50:37.000000000 +0100
|
||||
@@ -87,6 +87,9 @@
|
||||
# we really need to do so. (Do not call gcc as part of make mrproper)
|
||||
HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
|
||||
HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
|
||||
+ifeq ($(shell uname -s),Darwin)
|
||||
+HOST_LOADLIBES += -lncurses
|
||||
+endif
|
||||
|
||||
HOST_EXTRACFLAGS += -DLOCALE
|
||||
|
||||
diff -urN linux-2.6.19.1/scripts/genksyms/parse.y linux-2.6.19.1.new/scripts/genksyms/parse.y
|
||||
--- linux-2.6.19.1/scripts/genksyms/parse.y 2006-12-11 20:32:53.000000000 +0100
|
||||
+++ linux-2.6.19.1.new/scripts/genksyms/parse.y 2007-01-04 19:20:55.000000000 +0100
|
||||
@@ -24,7 +24,9 @@
|
||||
%{
|
||||
|
||||
#include <assert.h>
|
||||
+#ifndef __APPLE__
|
||||
#include <malloc.h>
|
||||
+#endif
|
||||
#include "genksyms.h"
|
||||
|
||||
static int is_typedef;
|
||||
diff -urN linux-2.6.19.1/scripts/genksyms/parse.c_shipped linux-2.6.19.1.new/scripts/genksyms/parse.c_shipped
|
||||
--- linux-2.6.19.1/scripts/genksyms/parse.c_shipped 2007-01-04 19:34:09.000000000 +0100
|
||||
+++ linux-2.6.19.1.new/scripts/genksyms/parse.c_shipped 2007-01-04 19:34:02.000000000 +0100
|
||||
@@ -144,7 +144,9 @@
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
+#ifndef __APPLE__
|
||||
#include <malloc.h>
|
||||
+#endif
|
||||
#include "genksyms.h"
|
||||
|
||||
static int is_typedef;
|
||||
--- linux-2.6.19.1/scripts/kallsyms.c 2006-12-11 20:32:53.000000000 +0100
|
||||
+++ linux-2.6.19.1.new/scripts/kallsyms.c 2007-01-04 19:46:38.000000000 +0100
|
||||
@@ -30,6 +30,35 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
+#ifdef __APPLE__
|
||||
+/* Darwin has no memmem implementation, this one is ripped of the uClibc-0.9.28 source */
|
||||
+void *memmem (const void *haystack, size_t haystack_len,
|
||||
+ const void *needle, size_t needle_len)
|
||||
+{
|
||||
+ const char *begin;
|
||||
+ const char *const last_possible
|
||||
+ = (const char *) haystack + haystack_len - needle_len;
|
||||
+
|
||||
+ if (needle_len == 0)
|
||||
+ /* The first occurrence of the empty string is deemed to occur at
|
||||
+ the beginning of the string. */
|
||||
+ return (void *) haystack;
|
||||
+
|
||||
+ /* Sanity check, otherwise the loop might search through the whole
|
||||
+ memory. */
|
||||
+ if (__builtin_expect (haystack_len < needle_len, 0))
|
||||
+ return NULL;
|
||||
+
|
||||
+ for (begin = (const char *) haystack; begin <= last_possible; ++begin)
|
||||
+ if (begin[0] == ((const char *) needle)[0] &&
|
||||
+ !memcmp ((const void *) &begin[1],
|
||||
+ (const void *) ((const char *) needle + 1),
|
||||
+ needle_len - 1))
|
||||
+ return (void *) begin;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+#endif
|
||||
|
||||
#define KSYM_NAME_LEN 127
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
--- linux-2.6.19.2/include/linux/stddef.h.old 2007-02-14 03:34:54.861805424 +0100
|
||||
+++ linux-2.6.19.2/include/linux/stddef.h 2007-02-14 03:35:06.331061832 +0100
|
||||
@@ -16,6 +16,7 @@
|
||||
false = 0,
|
||||
true = 1
|
||||
};
|
||||
+#endif /* __KERNEL__ */
|
||||
|
||||
#undef offsetof
|
||||
#ifdef __compiler_offsetof
|
||||
@@ -23,6 +24,5 @@
|
||||
#else
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
#endif
|
||||
-#endif /* __KERNEL__ */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
diff -urN linux-2.6.19.2/scripts/gen_initramfs_list.sh linux-2.6.19.2.new/scripts/gen_initramfs_list.sh
|
||||
--- linux-2.6.19.2/scripts/gen_initramfs_list.sh 2007-01-10 20:10:37.000000000 +0100
|
||||
+++ linux-2.6.19.2.new/scripts/gen_initramfs_list.sh 2007-05-03 16:25:06.000000000 +0200
|
||||
@@ -120,9 +120,9 @@
|
||||
;;
|
||||
"nod")
|
||||
local dev_type=
|
||||
- local maj=$(LC_ALL=C ls -l "${location}" | \
|
||||
+ local maj=$(LC_ALL=C ls --time-style=locale -l "${location}" | \
|
||||
gawk '{sub(/,/, "", $5); print $5}')
|
||||
- local min=$(LC_ALL=C ls -l "${location}" | \
|
||||
+ local min=$(LC_ALL=C ls --time-style=locale -l "${location}" | \
|
||||
gawk '{print $6}')
|
||||
|
||||
if [ -b "${location}" ]; then
|
||||
@@ -133,7 +133,7 @@
|
||||
str="${ftype} ${name} ${str} ${dev_type} ${maj} ${min}"
|
||||
;;
|
||||
"slink")
|
||||
- local target=$(LC_ALL=C ls -l "${location}" | \
|
||||
+ local target=$(LC_ALL=C ls --time-style=locale -l "${location}" | \
|
||||
gawk '{print $11}')
|
||||
str="${ftype} ${name} ${target} ${str}"
|
||||
;;
|
||||
18
target/linux/etrax/patches/generic_2.6/905-zydas-zyxel.patch
Normal file
18
target/linux/etrax/patches/generic_2.6/905-zydas-zyxel.patch
Normal file
@@ -0,0 +1,18 @@
|
||||
diff -urN linux-2.6.19.2.orig/drivers/net/wireless/zd1211rw/zd_usb.c linux-2.6.19.2/drivers/net/wireless/zd1211rw/zd_usb.c
|
||||
--- linux-2.6.19.2.orig/drivers/net/wireless/zd1211rw/zd_usb.c 2007-06-13 23:14:44.000000000 +0200
|
||||
+++ linux-2.6.19.2/drivers/net/wireless/zd1211rw/zd_usb.c 2007-06-13 23:19:51.000000000 +0200
|
||||
@@ -47,11 +47,13 @@
|
||||
{ USB_DEVICE(0x0586, 0x3402), .driver_info = DEVICE_ZD1211 },
|
||||
{ USB_DEVICE(0x0b3b, 0x5630), .driver_info = DEVICE_ZD1211 },
|
||||
{ USB_DEVICE(0x0b05, 0x170c), .driver_info = DEVICE_ZD1211 },
|
||||
+ { USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 },
|
||||
/* ZD1211B */
|
||||
{ USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
|
||||
{ USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
|
||||
+
|
||||
/* "Driverless" devices that need ejecting */
|
||||
{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
|
||||
{}
|
||||
Binary files linux-2.6.19.2.orig/drivers/net/wireless/zd1211rw/.zd_usb.c.swp and linux-2.6.19.2/drivers/net/wireless/zd1211rw/.zd_usb.c.swp differ
|
||||
16
target/linux/etrax/profiles/100-generic.mk
Normal file
16
target/linux/etrax/profiles/100-generic.mk
Normal file
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define Profile/default
|
||||
NAME:=Normal (default)
|
||||
endef
|
||||
|
||||
define Profile/default/Description
|
||||
Normal Foxboard setup (no vhdl)
|
||||
endef
|
||||
$(eval $(call Profile,default))
|
||||
|
||||
17
target/linux/etrax/profiles/101-vhdl-nofb.mk
Normal file
17
target/linux/etrax/profiles/101-vhdl-nofb.mk
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define Profile/vhdl_no_fb
|
||||
NAME:=FOXVHDL no fb
|
||||
# PACKAGES:=kmod-madwifi
|
||||
endef
|
||||
|
||||
define Profile/vhdl_no_fb/Description
|
||||
Setup the Foxboard for FOXVHDL support with no framebuffer
|
||||
endef
|
||||
$(eval $(call Profile,vhdl_no_fb))
|
||||
|
||||
Reference in New Issue
Block a user