linux/2.6.37: R.I.P.

SVN-Revision: 31687
master
Gabor Juhos 12 years ago
parent c8cede6aa7
commit 08ed044595
  1. 3021
      target/linux/generic/config-2.6.37
  2. 11
      target/linux/generic/patches-2.6.37/010-gcc4_inline_fix.patch
  3. 2211
      target/linux/generic/patches-2.6.37/020-ssb_update.patch
  4. 4978
      target/linux/generic/patches-2.6.37/025-bcma_backport.patch
  5. 208
      target/linux/generic/patches-2.6.37/030-mips_multi_machine_support.patch
  6. 11
      target/linux/generic/patches-2.6.37/031-mips_mark_unused.patch
  7. 11
      target/linux/generic/patches-2.6.37/032-fs_binfmt_elft_mark_unused.patch
  8. 227
      target/linux/generic/patches-2.6.37/040-jhash3.patch
  9. 14
      target/linux/generic/patches-2.6.37/050-solos_dont_null_deref.patch
  10. 13
      target/linux/generic/patches-2.6.37/051-solos_uniform_vpi_vci.patch
  11. 48
      target/linux/generic/patches-2.6.37/052-solos-debug_skbuff.patch
  12. 100
      target/linux/generic/patches-2.6.37/053-solos-vccs_release.patch
  13. 11
      target/linux/generic/patches-2.6.37/060-backport_tos2prio_ecn_fix.patch
  14. 2787
      target/linux/generic/patches-2.6.37/100-overlayfs.patch
  15. 78
      target/linux/generic/patches-2.6.37/101-overlayfs_2.6.37_backport.patch
  16. 124
      target/linux/generic/patches-2.6.37/102-overlayfs_fix_readdir_deadlock.patch
  17. 76
      target/linux/generic/patches-2.6.37/103-overlayfs_fix_readdir_unlink_deadlock.patch
  18. 25
      target/linux/generic/patches-2.6.37/110_fix_ecn_marking_ipv6.patch
  19. 11
      target/linux/generic/patches-2.6.37/200-fix_localversion.patch
  20. 24
      target/linux/generic/patches-2.6.37/201-extra_optimization.patch
  21. 102
      target/linux/generic/patches-2.6.37/210-darwin_scripts_include.patch
  22. 17
      target/linux/generic/patches-2.6.37/211-stddef_include.patch
  23. 119
      target/linux/generic/patches-2.6.37/220-module_exports.patch
  24. 54
      target/linux/generic/patches-2.6.37/230-openwrt_lzma_options.patch
  25. 12
      target/linux/generic/patches-2.6.37/240-atm_header_changes.patch
  26. 18
      target/linux/generic/patches-2.6.37/250-netfilter_depends.patch
  27. 11
      target/linux/generic/patches-2.6.37/251-sound_kconfig.patch
  28. 10
      target/linux/generic/patches-2.6.37/252-mv_cesa_depends.patch
  29. 29
      target/linux/generic/patches-2.6.37/253-ssb_b43_default_on.patch
  30. 23
      target/linux/generic/patches-2.6.37/254-textsearch_kconfig_hacks.patch
  31. 19
      target/linux/generic/patches-2.6.37/255-lib80211_kconfig_hacks.patch
  32. 47
      target/linux/generic/patches-2.6.37/256-crypto_add_kconfig_prompts.patch
  33. 22
      target/linux/generic/patches-2.6.37/257-wireless_ext_kconfig_hack.patch
  34. 11
      target/linux/generic/patches-2.6.37/258-lzo_decompressor_kconfig_dep.patch
  35. 28
      target/linux/generic/patches-2.6.37/301-mips_image_cmdline_hack.patch
  36. 18
      target/linux/generic/patches-2.6.37/302-mips_use_generic_thread_info_allocator.patch
  37. 11
      target/linux/generic/patches-2.6.37/303-mips_fix_kexec.patch
  38. 160
      target/linux/generic/patches-2.6.37/304-mips_disable_fpu.patch
  39. 370
      target/linux/generic/patches-2.6.37/305-mips_module_reloc.patch
  40. 83
      target/linux/generic/patches-2.6.37/306-mips_mem_functions_performance.patch
  41. 35
      target/linux/generic/patches-2.6.37/307-mips_oprofile_fix.patch
  42. 11
      target/linux/generic/patches-2.6.37/308-mips_boot.patch
  43. 13
      target/linux/generic/patches-2.6.37/310-arm_module_unresolved_weak_sym.patch
  44. 389
      target/linux/generic/patches-2.6.37/311-arm_update_mach_types.patch
  45. 31
      target/linux/generic/patches-2.6.37/320-ppc4xx_optimization.patch
  46. 10
      target/linux/generic/patches-2.6.37/321-powerpc_crtsavres_prereq.patch
  47. 9
      target/linux/generic/patches-2.6.37/322-powerpc_asm_segment_h.patch
  48. 331
      target/linux/generic/patches-2.6.37/400-rootfs_split.patch
  49. 146
      target/linux/generic/patches-2.6.37/401-partial_eraseblock_write.patch
  50. 18
      target/linux/generic/patches-2.6.37/410-mtd_info_move_forward_decl.patch
  51. 30
      target/linux/generic/patches-2.6.37/420-redboot_space.patch
  52. 60
      target/linux/generic/patches-2.6.37/421-redboot_boardconfig.patch
  53. 35
      target/linux/generic/patches-2.6.37/430-mtd_myloader_partition_parser.patch
  54. 115
      target/linux/generic/patches-2.6.37/440-block2mtd_init.patch
  55. 292
      target/linux/generic/patches-2.6.37/441-block2mtd_refresh.patch
  56. 17
      target/linux/generic/patches-2.6.37/442-block2mtd_probe.patch
  57. 37
      target/linux/generic/patches-2.6.37/450-mtd_plat_nand_chip_fixup.patch
  58. 12
      target/linux/generic/patches-2.6.37/451-mtd_fix_nand_correct_data_return_code.patch
  59. 15
      target/linux/generic/patches-2.6.37/460-cfi_show_amd_extended_table_version.patch
  60. 39
      target/linux/generic/patches-2.6.37/470-mtd_m25p80_add_pm25lv_flash_support.patch
  61. 12
      target/linux/generic/patches-2.6.37/471-mtd_m25p80_add_en25f32_chip_support.patch
  62. 20
      target/linux/generic/patches-2.6.37/472-mtd_m25p80_add_MX25L1606E_support.patch
  63. 41
      target/linux/generic/patches-2.6.37/473-mtd_samsung_flash.patch
  64. 10
      target/linux/generic/patches-2.6.37/474-mtd_m25p80_add_w25q128.patch
  65. 12
      target/linux/generic/patches-2.6.37/475-mtd_concat_sync_fix.patch
  66. 18
      target/linux/generic/patches-2.6.37/500-yaffs_support.patch
  67. 12344
      target/linux/generic/patches-2.6.37/501-yaffs_cvs_2009_04_24.patch
  68. 27068
      target/linux/generic/patches-2.6.37/502-yaffs_git_2010_10_20.patch
  69. 17
      target/linux/generic/patches-2.6.37/503-yaffs_symlink_bug.patch
  70. 20
      target/linux/generic/patches-2.6.37/504-yaffs_mutex_fix.patch
  71. 5142
      target/linux/generic/patches-2.6.37/510-jffs2_make_lzma_available.patch
  72. 485
      target/linux/generic/patches-2.6.37/511-debloat_lzma.patch
  73. 132
      target/linux/generic/patches-2.6.37/512-jffs2_eofdetect.patch
  74. 249
      target/linux/generic/patches-2.6.37/520-squashfs_revert_to_2.6.35.patch
  75. 219
      target/linux/generic/patches-2.6.37/521-squashfs_add_lzma.patch
  76. 165
      target/linux/generic/patches-2.6.37/522-squashfs_make_lzma_available.patch
  77. 2142
      target/linux/generic/patches-2.6.37/600-netfilter_layer7_2.22.patch
  78. 108
      target/linux/generic/patches-2.6.37/601-netfilter_layer7_pktmatch.patch
  79. 51
      target/linux/generic/patches-2.6.37/602-netfilter_layer7_match.patch
  80. 61
      target/linux/generic/patches-2.6.37/603-netfilter_layer7_2.6.36_fix.patch
  81. 118
      target/linux/generic/patches-2.6.37/604-netfilter_cisco_794x_iphone.patch
  82. 26
      target/linux/generic/patches-2.6.37/606-netfilter_dscp_ipv6_mangle.patch
  83. 795
      target/linux/generic/patches-2.6.37/620-sched_esfq.patch
  84. 172
      target/linux/generic/patches-2.6.37/621-sched_act_connmark.patch
  85. 132
      target/linux/generic/patches-2.6.37/630-packet_socket_type.patch
  86. 15
      target/linux/generic/patches-2.6.37/640-bridge_no_eap_forward.patch
  87. 11
      target/linux/generic/patches-2.6.37/641-bridge_always_accept_eap.patch
  88. 103
      target/linux/generic/patches-2.6.37/642-bridge_port_isolate.patch
  89. 20
      target/linux/generic/patches-2.6.37/650-pppoe_header_pad.patch
  90. 11
      target/linux/generic/patches-2.6.37/651-wireless_mesh_header.patch
  91. 25
      target/linux/generic/patches-2.6.37/700-swconfig.patch
  92. 81
      target/linux/generic/patches-2.6.37/701-phy_extension.patch
  93. 45
      target/linux/generic/patches-2.6.37/702-phy_add_aneg_done_function.patch
  94. 26
      target/linux/generic/patches-2.6.37/720-phy_adm6996.patch
  95. 63
      target/linux/generic/patches-2.6.37/721-phy_packets.patch
  96. 22
      target/linux/generic/patches-2.6.37/722-phy_mvswitch.patch
  97. 23
      target/linux/generic/patches-2.6.37/723-phy_ip175c.patch
  98. 23
      target/linux/generic/patches-2.6.37/724-phy_ar8216.patch
  99. 23
      target/linux/generic/patches-2.6.37/725-phy_rtl8306.patch
  100. 44
      target/linux/generic/patches-2.6.37/726-phy_rtl8366.patch
  101. Some files were not shown because too many files have changed in this diff Show More

File diff suppressed because it is too large Load Diff

@ -1,11 +0,0 @@
--- a/arch/mips/include/asm/system.h
+++ b/arch/mips/include/asm/system.h
@@ -194,7 +194,7 @@ extern __u64 __xchg_u64_unsupported_on_3
#define __xchg_u64 __xchg_u64_unsupported_on_32bit_kernels
#endif
-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:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,208 +0,0 @@
--- /dev/null
+++ b/arch/mips/include/asm/mips_machine.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.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.
+ *
+ */
+
+#ifndef __ASM_MIPS_MACHINE_H
+#define __ASM_MIPS_MACHINE_H
+
+#include <linux/init.h>
+#include <linux/list.h>
+
+#include <asm/bootinfo.h>
+
+struct mips_machine {
+ unsigned long mach_type;
+ const char *mach_id;
+ const char *mach_name;
+ void (*mach_setup)(void);
+};
+
+#define MIPS_MACHINE(_type, _id, _name, _setup) \
+static const char machine_name_##_type[] __initconst \
+ __aligned(1) = _name; \
+static const char machine_id_##_type[] __initconst \
+ __aligned(1) = _id; \
+static struct mips_machine machine_##_type \
+ __used __section(.mips.machines.init) = \
+{ \
+ .mach_type = _type, \
+ .mach_id = machine_id_##_type, \
+ .mach_name = machine_name_##_type, \
+ .mach_setup = _setup, \
+};
+
+extern long __mips_machines_start;
+extern long __mips_machines_end;
+
+#ifdef CONFIG_MIPS_MACHINE
+int mips_machtype_setup(char *id) __init;
+void mips_machine_setup(void) __init;
+void mips_set_machine_name(const char *name) __init;
+char *mips_get_machine_name(void);
+#else
+static inline int mips_machtype_setup(char *id) { return 1; }
+static inline void mips_machine_setup(void) { }
+static inline void mips_set_machine_name(const char *name) { }
+static inline char *mips_get_machine_name(void) { return NULL; }
+#endif /* CONFIG_MIPS_MACHINE */
+
+#endif /* __ASM_MIPS_MACHINE_H */
--- /dev/null
+++ b/arch/mips/kernel/mips_machine.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.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/mm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include <asm/mips_machine.h>
+
+static struct mips_machine *mips_machine __initdata;
+static char *mips_machine_name = "Unknown";
+
+#define for_each_machine(mach) \
+ for ((mach) = (struct mips_machine *)&__mips_machines_start; \
+ (mach) && \
+ (unsigned long)(mach) < (unsigned long)&__mips_machines_end; \
+ (mach)++)
+
+__init void mips_set_machine_name(const char *name)
+{
+ char *p;
+
+ if (name == NULL)
+ return;
+
+ p = kstrdup(name, GFP_KERNEL);
+ if (!p)
+ pr_err("MIPS: no memory for machine_name\n");
+
+ mips_machine_name = p;
+}
+
+char *mips_get_machine_name(void)
+{
+ return mips_machine_name;
+}
+
+__init int mips_machtype_setup(char *id)
+{
+ struct mips_machine *mach;
+
+ for_each_machine(mach) {
+ if (mach->mach_id == NULL)
+ continue;
+
+ if (strcmp(mach->mach_id, id) == 0) {
+ mips_machtype = mach->mach_type;
+ return 0;
+ }
+ }
+
+ pr_err("MIPS: no machine found for id '%s', supported machines:\n", id);
+ pr_err("%-24s : %s\n", "id", "name");
+ for_each_machine(mach)
+ pr_err("%-24s : %s\n", mach->mach_id, mach->mach_name);
+
+ return 1;
+}
+
+__setup("machtype=", mips_machtype_setup);
+
+__init void mips_machine_setup(void)
+{
+ struct mips_machine *mach;
+
+ for_each_machine(mach) {
+ if (mips_machtype == mach->mach_type) {
+ mips_machine = mach;
+ break;
+ }
+ }
+
+ if (!mips_machine)
+ return;
+
+ mips_set_machine_name(mips_machine->mach_name);
+ pr_info("MIPS: machine is %s\n", mips_machine_name);
+
+ if (mips_machine->mach_setup)
+ mips_machine->mach_setup();
+}
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o
+obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
obj-$(CONFIG_OF) += prom.o
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -883,6 +883,9 @@ config MIPS_DISABLE_OBSOLETE_IDE
config SYNC_R4K
bool
+config MIPS_MACHINE
+ def_bool n
+
config NO_IOPORT
def_bool n
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -12,6 +12,7 @@
#include <asm/cpu-features.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
+#include <asm/mips_machine.h>
unsigned int vced_count, vcei_count;
@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file
/*
* For the first processor also print the system type
*/
- if (n == 0)
+ if (n == 0) {
seq_printf(m, "system type\t\t: %s\n", get_system_type());
+ if (mips_get_machine_name())
+ seq_printf(m, "machine\t\t\t: %s\n",
+ mips_get_machine_name());
+ }
seq_printf(m, "processor\t\t: %ld\n", n);
sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -98,6 +98,13 @@ SECTIONS
INIT_TEXT_SECTION(PAGE_SIZE)
INIT_DATA_SECTION(16)
+ . = ALIGN(4);
+ .mips.machines.init : AT(ADDR(.mips.machines.init) - LOAD_OFFSET) {
+ __mips_machines_start = .;
+ *(.mips.machines.init)
+ __mips_machines_end = .;
+ }
+
/* .exit.text is discarded at runtime, not link time, to deal with
* references from .rodata
*/

@ -1,11 +0,0 @@
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -115,7 +115,7 @@ static int protected_save_fp_context32(s
static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
{
- int err, tmp;
+ int err, tmp __maybe_unused;
while (1) {
lock_fpu_owner();
own_fpu_inatomic(0);

@ -1,11 +0,0 @@
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -575,7 +575,7 @@ static int load_elf_binary(struct linux_
unsigned long elf_entry;
unsigned long interp_load_addr = 0;
unsigned long start_code, end_code, start_data, end_data;
- unsigned long reloc_func_desc = 0;
+ unsigned long reloc_func_desc __maybe_unused = 0;
int executable_stack = EXSTACK_DEFAULT;
unsigned long def_flags = 0;
struct {

@ -1,227 +0,0 @@
--- a/include/linux/jhash.h
+++ b/include/linux/jhash.h
@@ -3,80 +3,95 @@
/* jhash.h: Jenkins hash support.
*
- * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
+ * Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net)
*
* http://burtleburtle.net/bob/hash/
*
* These are the credits from Bob's sources:
*
- * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
- * hash(), hash2(), hash3, and mix() are externally useful functions.
- * Routines to test the hash are included if SELF_TEST is defined.
- * You can use this free for any purpose. It has no warranty.
+ * lookup3.c, by Bob Jenkins, May 2006, Public Domain.
*
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * These are functions for producing 32-bit hashes for hash table lookup.
+ * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
+ * are externally useful functions. Routines to test the hash are included
+ * if SELF_TEST is defined. You can use this free for any purpose. It's in
+ * the public domain. It has no warranty.
+ *
+ * Copyright (C) 2009 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
*
* I've modified Bob's hash to be useful in the Linux kernel, and
- * any bugs present are surely my fault. -DaveM
+ * any bugs present are my fault. Jozsef
*/
-/* NOTE: Arguments are modified. */
-#define __jhash_mix(a, b, c) \
+#define __rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+/* __jhash_mix - mix 3 32-bit values reversibly. */
+#define __jhash_mix(a,b,c) \
{ \
- a -= b; a -= c; a ^= (c>>13); \
- b -= c; b -= a; b ^= (a<<8); \
- c -= a; c -= b; c ^= (b>>13); \
- a -= b; a -= c; a ^= (c>>12); \
- b -= c; b -= a; b ^= (a<<16); \
- c -= a; c -= b; c ^= (b>>5); \
- a -= b; a -= c; a ^= (c>>3); \
- b -= c; b -= a; b ^= (a<<10); \
- c -= a; c -= b; c ^= (b>>15); \
+ a -= c; a ^= __rot(c, 4); c += b; \
+ b -= a; b ^= __rot(a, 6); a += c; \
+ c -= b; c ^= __rot(b, 8); b += a; \
+ a -= c; a ^= __rot(c,16); c += b; \
+ b -= a; b ^= __rot(a,19); a += c; \
+ c -= b; c ^= __rot(b, 4); b += a; \
}
-/* The golden ration: an arbitrary value */
-#define JHASH_GOLDEN_RATIO 0x9e3779b9
+/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
+#define __jhash_final(a,b,c) \
+{ \
+ c ^= b; c -= __rot(b,14); \
+ a ^= c; a -= __rot(c,11); \
+ b ^= a; b -= __rot(a,25); \
+ c ^= b; c -= __rot(b,16); \
+ a ^= c; a -= __rot(c,4); \
+ b ^= a; b -= __rot(a,14); \
+ c ^= b; c -= __rot(b,24); \
+}
+
+/* An arbitrary initial parameter */
+#define JHASH_GOLDEN_RATIO 0xdeadbeef
/* The most generic version, hashes an arbitrary sequence
* of bytes. No alignment or length assumptions are made about
- * the input key.
+ * the input key. The result depends on endianness.
*/
static inline u32 jhash(const void *key, u32 length, u32 initval)
{
- u32 a, b, c, len;
+ u32 a,b,c;
const u8 *k = key;
- len = length;
- a = b = JHASH_GOLDEN_RATIO;
- c = initval;
-
- while (len >= 12) {
- a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24));
- b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24));
- c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24));
-
- __jhash_mix(a,b,c);
+ /* Set up the internal state */
+ a = b = c = JHASH_GOLDEN_RATIO + length + initval;
+ /* all but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12) {
+ a += (k[0] + ((u32)k[1]<<8) + ((u32)k[2]<<16) + ((u32)k[3]<<24));
+ b += (k[4] + ((u32)k[5]<<8) + ((u32)k[6]<<16) + ((u32)k[7]<<24));
+ c += (k[8] + ((u32)k[9]<<8) + ((u32)k[10]<<16) + ((u32)k[11]<<24));
+ __jhash_mix(a, b, c);
+ length -= 12;
k += 12;
- len -= 12;
}
- c += length;
- switch (len) {
- case 11: c += ((u32)k[10]<<24);
- case 10: c += ((u32)k[9]<<16);
- case 9 : c += ((u32)k[8]<<8);
- case 8 : b += ((u32)k[7]<<24);
- case 7 : b += ((u32)k[6]<<16);
- case 6 : b += ((u32)k[5]<<8);
+ /* last block: affect all 32 bits of (c) */
+ /* all the case statements fall through */
+ switch (length) {
+ case 12: c += (u32)k[11]<<24;
+ case 11: c += (u32)k[10]<<16;
+ case 10: c += (u32)k[9]<<8;
+ case 9 : c += k[8];
+ case 8 : b += (u32)k[7]<<24;
+ case 7 : b += (u32)k[6]<<16;
+ case 6 : b += (u32)k[5]<<8;
case 5 : b += k[4];
- case 4 : a += ((u32)k[3]<<24);
- case 3 : a += ((u32)k[2]<<16);
- case 2 : a += ((u32)k[1]<<8);
+ case 4 : a += (u32)k[3]<<24;
+ case 3 : a += (u32)k[2]<<16;
+ case 2 : a += (u32)k[1]<<8;
case 1 : a += k[0];
- };
-
- __jhash_mix(a,b,c);
+ __jhash_final(a, b, c);
+ case 0 :
+ break;
+ }
return c;
}
@@ -86,28 +101,31 @@ static inline u32 jhash(const void *key,
*/
static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
{
- u32 a, b, c, len;
+ u32 a, b, c;
- a = b = JHASH_GOLDEN_RATIO;
- c = initval;
- len = length;
+ /* Set up the internal state */
+ a = b = c = JHASH_GOLDEN_RATIO + (length<<2) + initval;
- while (len >= 3) {
+ /* handle most of the key */
+ while (length > 3) {
a += k[0];
b += k[1];
c += k[2];
__jhash_mix(a, b, c);
- k += 3; len -= 3;
+ length -= 3;
+ k += 3;
}
- c += length * 4;
-
- switch (len) {
- case 2 : b += k[1];
- case 1 : a += k[0];
- };
-
- __jhash_mix(a,b,c);
+ /* handle the last 3 u32's */
+ /* all the case statements fall through */
+ switch (length) {
+ case 3: c += k[2];
+ case 2: b += k[1];
+ case 1: a += k[0];
+ __jhash_final(a, b, c);
+ case 0: /* case 0: nothing left to add */
+ break;
+ }
return c;
}
@@ -115,29 +133,26 @@ static inline u32 jhash2(const u32 *k, u
/* A special ultra-optimized versions that knows they are hashing exactly
* 3, 2 or 1 word(s).
- *
- * NOTE: In particular the "c += length; __jhash_mix(a,b,c);" normally
- * done at the end is not done here.
*/
static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
{
- a += JHASH_GOLDEN_RATIO;
- b += JHASH_GOLDEN_RATIO;
- c += initval;
+ a += JHASH_GOLDEN_RATIO + initval;
+ b += JHASH_GOLDEN_RATIO + initval;
+ c += JHASH_GOLDEN_RATIO + initval;
- __jhash_mix(a, b, c);
+ __jhash_final(a, b, c);
return c;
}
static inline u32 jhash_2words(u32 a, u32 b, u32 initval)
{
- return jhash_3words(a, b, 0, initval);
+ return jhash_3words(0, a, b, initval);
}
static inline u32 jhash_1word(u32 a, u32 initval)
{
- return jhash_3words(a, 0, 0, initval);
+ return jhash_3words(0, 0, a, initval);
}
#endif /* _LINUX_JHASH_H */

@ -1,14 +0,0 @@
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -866,8 +866,9 @@ static int popen(struct atm_vcc *vcc)
}
skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
- if (!skb && net_ratelimit()) {
- dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n");
+ if (!skb) {
+ if (net_ratelimit())
+ dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n");
return -ENOMEM;
}
header = (void *)skb_put(skb, sizeof(*header));

@ -1,13 +0,0 @@
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -710,8 +710,8 @@ void solos_bh(unsigned long card_arg)
le16_to_cpu(header->vci));
if (!vcc) {
if (net_ratelimit())
- dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n",
- le16_to_cpu(header->vci), le16_to_cpu(header->vpi),
+ dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n",
+ le16_to_cpu(header->vpi), le16_to_cpu(header->vci),
port);
continue;
}

@ -1,48 +0,0 @@
commit 18b429e74eeafe42e947b1b0f9a760c7153a0b5c
Author: Philip A. Prindeville <philipp@redfish-solutions.com>
Date: Wed Mar 30 12:59:26 2011 +0000
atm/solos-pci: Don't include frame pseudo-header on transmit hex-dump
Omit pkt_hdr preamble when dumping transmitted packet as hex-dump;
we can pull this up because the frame has already been sent, and
dumping it is the last thing we do with it before freeing it.
Also include the size, vpi, and vci in the debug as is done on
receive.
Use "port" consistently instead of "device" intermittently.
Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/atm/solos-pci.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -697,7 +697,7 @@ void solos_bh(unsigned long card_arg)
size);
}
if (atmdebug) {
- dev_info(&card->dev->dev, "Received: device %d\n", port);
+ dev_info(&card->dev->dev, "Received: port %d\n", port);
dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
size, le16_to_cpu(header->vpi),
le16_to_cpu(header->vci));
@@ -1018,8 +1018,15 @@ static uint32_t fpga_tx(struct solos_car
/* Clean up and free oldskb now it's gone */
if (atmdebug) {
+ struct pkt_hdr *header = (void *)oldskb->data;
+ int size = le16_to_cpu(header->size);
+
+ skb_pull(oldskb, sizeof(*header));
dev_info(&card->dev->dev, "Transmitted: port %d\n",
port);
+ dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
+ size, le16_to_cpu(header->vpi),
+ le16_to_cpu(header->vci));
print_buffer(oldskb);
}

@ -1,100 +0,0 @@
commit c031235b395433350f25943b7580a5e343c7b7b2
Author: Philip A. Prindeville <philipp@redfish-solutions.com>
Date: Wed Mar 30 13:17:04 2011 +0000
atm/solos-pci: Don't flap VCs when carrier state changes
Don't flap VCs when carrier state changes; higher-level protocols
can detect loss of connectivity and act accordingly. This is more
consistent with how other network interfaces work.
We no longer use release_vccs() so we can delete it.
release_vccs() was duplicated from net/atm/common.c; make the
corresponding function exported, since other code duplicates it
and could leverage it if it were public.
Signed-off-by: Philip A. Prindeville <philipp@redfish-solutions.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/atm/solos-pci.c | 26 +-------------------------
include/linux/atmdev.h | 1 +
net/atm/common.c | 1 +
3 files changed, 3 insertions(+), 25 deletions(-)
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -165,7 +165,6 @@ static uint32_t fpga_tx(struct solos_car
static irqreturn_t solos_irq(int irq, void *dev_id);
static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
static int list_vccs(int vci);
-static void release_vccs(struct atm_dev *dev);
static int atm_init(struct solos_card *, struct device *);
static void atm_remove(struct solos_card *);
static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
@@ -384,7 +383,6 @@ static int process_status(struct solos_c
/* Anything but 'Showtime' is down */
if (strcmp(state_str, "Showtime")) {
atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST);
- release_vccs(card->atmdev[port]);
dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str);
return 0;
}
@@ -830,28 +828,6 @@ static int list_vccs(int vci)
return num_found;
}
-static void release_vccs(struct atm_dev *dev)
-{
- int i;
-
- write_lock_irq(&vcc_sklist_lock);
- for (i = 0; i < VCC_HTABLE_SIZE; i++) {
- struct hlist_head *head = &vcc_hash[i];
- struct hlist_node *node, *tmp;
- struct sock *s;
- struct atm_vcc *vcc;
-
- sk_for_each_safe(s, node, tmp, head) {
- vcc = atm_sk(s);
- if (vcc->dev == dev) {
- vcc_release_async(vcc, -EPIPE);
- sk_del_node_init(s);
- }
- }
- }
- write_unlock_irq(&vcc_sklist_lock);
-}
-
static int popen(struct atm_vcc *vcc)
{
@@ -1269,7 +1245,7 @@ static int atm_init(struct solos_card *c
card->atmdev[i]->ci_range.vci_bits = 16;
card->atmdev[i]->dev_data = card;
card->atmdev[i]->phy_data = (void *)(unsigned long)i;
- atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN);
+ atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND);
skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
if (!skb) {
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -443,6 +443,7 @@ void atm_dev_signal_change(struct atm_de
void vcc_insert_socket(struct sock *sk);
+void atm_dev_release_vccs(struct atm_dev *dev);
/*
* This is approximately the algorithm used by alloc_skb.
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -252,6 +252,7 @@ void atm_dev_release_vccs(struct atm_dev
}
write_unlock_irq(&vcc_sklist_lock);
}
+EXPORT_SYMBOL(atm_dev_release_vccs);
static int adjust_tp(struct atm_trafprm *tp, unsigned char aal)
{

@ -1,11 +0,0 @@
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -165,7 +165,7 @@ static struct dst_ops ipv4_dst_ops = {
const __u8 ip_tos2prio[16] = {
TC_PRIO_BESTEFFORT,
- ECN_OR_COST(FILLER),
+ ECN_OR_COST(BESTEFFORT),
TC_PRIO_BESTEFFORT,
ECN_OR_COST(BESTEFFORT),
TC_PRIO_BULK,

File diff suppressed because it is too large Load Diff

@ -1,78 +0,0 @@
--- a/fs/overlayfs/overlayfs.c
+++ b/fs/overlayfs/overlayfs.c
@@ -28,13 +28,8 @@ struct ovl_fs {
struct ovl_entry {
struct dentry *__upperdentry;
struct dentry *lowerdentry;
- union {
- struct {
- u64 version;
- bool opaque;
- };
- struct rcu_head rcu;
- };
+ u64 version;
+ bool opaque;
};
static const char *ovl_whiteout_xattr = "trusted.overlay.whiteout";
@@ -632,12 +627,6 @@ static const struct file_operations ovl_
static const struct inode_operations ovl_dir_inode_operations;
-static void ovl_entry_free(struct rcu_head *head)
-{
- struct ovl_entry *oe = container_of(head, struct ovl_entry, rcu);
- kfree(oe);
-}
-
static void ovl_dentry_release(struct dentry *dentry)
{
struct ovl_entry *oe = dentry->d_fsdata;
@@ -645,7 +634,7 @@ static void ovl_dentry_release(struct de
if (oe) {
dput(oe->__upperdentry);
dput(oe->lowerdentry);
- call_rcu(&oe->rcu, ovl_entry_free);
+ kfree(oe);
}
}
@@ -1338,7 +1327,7 @@ static int ovl_dir_getattr(struct vfsmou
return 0;
}
-static int ovl_permission(struct inode *inode, int mask, unsigned int flags)
+static int ovl_permission(struct inode *inode, int mask)
{
struct ovl_entry *oe;
struct dentry *alias = NULL;
@@ -1349,8 +1338,6 @@ static int ovl_permission(struct inode *
if (S_ISDIR(inode->i_mode)) {
oe = inode->i_private;
- } else if (flags & IPERM_FLAG_RCU) {
- return -ECHILD;
} else {
/*
* For non-directories find an alias and get the info
@@ -1377,7 +1364,6 @@ static int ovl_permission(struct inode *
/* Careful in RCU walk mode */
realinode = ACCESS_ONCE(realdentry->d_inode);
if (!realinode) {
- WARN_ON(!(flags & IPERM_FLAG_RCU));
return -ENOENT;
}
@@ -1402,9 +1388,9 @@ static int ovl_permission(struct inode *
}
if (realinode->i_op->permission)
- err = realinode->i_op->permission(realinode, mask, flags);
+ err = realinode->i_op->permission(realinode, mask);
else
- err = generic_permission(realinode, mask, flags,
+ err = generic_permission(realinode, mask,
realinode->i_op->check_acl);
out_dput:
dput(alias);

@ -1,124 +0,0 @@
--- a/fs/overlayfs/overlayfs.c
+++ b/fs/overlayfs/overlayfs.c
@@ -248,8 +248,7 @@ static struct ovl_cache_entry *ovl_cache
}
static struct ovl_cache_entry *ovl_cache_entry_new(const char *name, int len,
- u64 ino, unsigned int d_type,
- bool is_whiteout)
+ u64 ino, unsigned int d_type)
{
struct ovl_cache_entry *p;
@@ -262,7 +261,7 @@ static struct ovl_cache_entry *ovl_cache
p->len = len;
p->type = d_type;
p->ino = ino;
- p->is_whiteout = is_whiteout;
+ p->is_whiteout = false;
}
return p;
@@ -270,7 +269,7 @@ static struct ovl_cache_entry *ovl_cache
static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
const char *name, int len, u64 ino,
- unsigned int d_type, bool is_whiteout)
+ unsigned int d_type)
{
struct rb_node **newp = &rdd->root->rb_node;
struct rb_node *parent = NULL;
@@ -291,11 +290,18 @@ static int ovl_cache_entry_add_rb(struct
return 0;
}
- p = ovl_cache_entry_new(name, len, ino, d_type, is_whiteout);
+ p = ovl_cache_entry_new(name, len, ino, d_type);
if (p == NULL)
return -ENOMEM;
- list_add_tail(&p->l_node, rdd->list);
+ /*
+ * Add links before other types to be able to quicky mark
+ * any whiteout entries
+ */
+ if (d_type == DT_LNK)
+ list_add(&p->l_node, rdd->list);
+ else
+ list_add_tail(&p->l_node, rdd->list);
rb_link_node(&p->node, parent, newp);
rb_insert_color(&p->node, rdd->root);
@@ -313,7 +319,7 @@ static int ovl_fill_lower(void *buf, con
if (p) {
list_move_tail(&p->l_node, rdd->middle);
} else {
- p = ovl_cache_entry_new(name, namelen, ino, d_type, false);
+ p = ovl_cache_entry_new(name, namelen, ino, d_type);
if (p == NULL)
rdd->err = -ENOMEM;
else
@@ -338,26 +344,9 @@ static int ovl_fill_upper(void *buf, con
loff_t offset, u64 ino, unsigned int d_type)
{
struct ovl_readdir_data *rdd = buf;
- bool is_whiteout = false;
rdd->count++;
- if (d_type == DT_LNK) {
- struct dentry *dentry;
-
- dentry = lookup_one_len(name, rdd->dir, namelen);
- if (IS_ERR(dentry)) {
- rdd->err = PTR_ERR(dentry);
- goto out;
- }
- is_whiteout = ovl_is_whiteout(dentry);
- dput(dentry);
- }
-
- rdd->err = ovl_cache_entry_add_rb(rdd, name, namelen, ino, d_type,
- is_whiteout);
-
-out:
- return rdd->err;
+ return ovl_cache_entry_add_rb(rdd, name, namelen, ino, d_type);
}
static int ovl_dir_read(struct path *realpath, struct ovl_readdir_data *rdd,
@@ -423,6 +412,26 @@ static void ovl_dir_reset(struct file *f
}
}
+static void ovl_dir_mark_whiteouts(struct ovl_readdir_data *rdd)
+{
+ struct ovl_cache_entry *p;
+ struct dentry *dentry;
+
+ mutex_lock(&rdd->dir->d_inode->i_mutex);
+ list_for_each_entry(p, rdd->list, l_node) {
+ if (p->type != DT_LNK)
+ break;
+
+ dentry = lookup_one_len(p->name, rdd->dir, p->len);
+ if (IS_ERR(dentry))
+ continue;
+
+ p->is_whiteout = ovl_is_whiteout(dentry);
+ dput(dentry);
+ }
+ mutex_unlock(&rdd->dir->d_inode->i_mutex);
+}
+
static int ovl_dir_read_merged(struct path *upperpath, struct path *lowerpath,
struct ovl_readdir_data *rdd)
{
@@ -436,6 +445,8 @@ static int ovl_dir_read_merged(struct pa
err = ovl_dir_read(upperpath, rdd, ovl_fill_upper);
if (err)
goto out;
+
+ ovl_dir_mark_whiteouts(rdd);
}
/*
* Insert lowerpath entries before upperpath ones, this allows

@ -1,76 +0,0 @@
--- a/fs/overlayfs/overlayfs.c
+++ b/fs/overlayfs/overlayfs.c
@@ -1686,37 +1686,56 @@ static int ovl_check_empty_dir(struct de
return err;
}
-static int ovl_unlink_whiteout(void *buf, const char *name, int namelen,
- loff_t offset, u64 ino, unsigned int d_type)
+static int ovl_fill_links(void *buf, const char *name, int namelen,
+ loff_t offset, u64 ino, unsigned int d_type)
{
struct ovl_readdir_data *rdd = buf;
+ struct ovl_cache_entry *p;
- rdd->count++;
- /* check d_type to filter out "." and ".." */
- if (d_type == DT_LNK) {
- struct dentry *dentry;
+ if (d_type != DT_LNK)
+ return 0;
- dentry = lookup_one_len(name, rdd->dir, namelen);
- if (IS_ERR(dentry)) {
- rdd->err = PTR_ERR(dentry);
- } else {
- rdd->err = vfs_unlink(rdd->dir->d_inode, dentry);
- dput(dentry);
- }
- }
+ p = ovl_cache_entry_new(name, namelen, ino, d_type);
+ if (!p)
+ return -ENOMEM;
- return rdd->err;
+ list_add(&p->l_node, rdd->list);
+ return 0;
}
static int ovl_remove_whiteouts(struct dentry *dentry)
{
struct path upperpath;
- struct ovl_readdir_data rdd = { .list = NULL };
+ LIST_HEAD(list);
+ struct ovl_readdir_data rdd = { .list = &list };
+ struct ovl_cache_entry *p, *t;
+ int ret;
ovl_path_upper(dentry, &upperpath);
rdd.dir = upperpath.dentry;
- return ovl_dir_read(&upperpath, &rdd, ovl_unlink_whiteout);
+ ret = ovl_dir_read(&upperpath, &rdd, ovl_fill_links);
+
+ mutex_lock(&rdd.dir->d_inode->i_mutex);
+ list_for_each_entry_safe(p, t, &list, l_node) {
+ struct dentry *dentry;
+
+ if (!ret) {
+ dentry = lookup_one_len(p->name, rdd.dir, p->len);
+ if (IS_ERR(dentry)) {
+ ret = PTR_ERR(dentry);
+ } else {
+ ret = vfs_unlink(rdd.dir->d_inode, dentry);
+ dput(dentry);
+ }
+ }
+
+ list_del(&p->l_node);
+ kfree(p);
+ }
+ mutex_unlock(&rdd.dir->d_inode->i_mutex);
+
+ return ret;
}
static int ovl_rmdir(struct inode *dir, struct dentry *dentry)

@ -1,25 +0,0 @@
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -38,9 +38,19 @@ static inline __u8 INET_ECN_encapsulate(
return outer;
}
-#define INET_ECN_xmit(sk) do { inet_sk(sk)->tos |= INET_ECN_ECT_0; } while (0)
-#define INET_ECN_dontxmit(sk) \
- do { inet_sk(sk)->tos &= ~INET_ECN_MASK; } while (0)
+static inline void INET_ECN_xmit(struct sock *sk)
+{
+ inet_sk(sk)->tos |= INET_ECN_ECT_0;
+ if (inet6_sk(sk) != NULL)
+ inet6_sk(sk)->tclass |= INET_ECN_ECT_0;
+}
+
+static inline void INET_ECN_dontxmit(struct sock *sk)
+{
+ inet_sk(sk)->tos &= ~INET_ECN_MASK;
+ if (inet6_sk(sk) != NULL)
+ inet6_sk(sk)->tclass &= ~INET_ECN_MASK;
+}
#define IP6_ECN_flow_init(label) do { \
(label) &= ~htonl(INET_ECN_MASK << 20); \

@ -1,11 +0,0 @@
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -164,7 +164,7 @@ else
# annotated or signed tagged state (as git describe only
# looks at signed or annotated tags - git tag -a/-s) and
# LOCALVERSION= is not specified
- if test "${LOCALVERSION+set}" != "set"; then
+ if test "${CONFIG_LOCALVERSION+set}" != "set"; then
scm=$(scm_version --short)
res="$res${scm:++}"
fi

@ -1,24 +0,0 @@
--- a/Makefile
+++ b/Makefile
@@ -538,9 +538,9 @@ endif # $(dot-config)
all: vmlinux
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
-KBUILD_CFLAGS += -Os
+KBUILD_CFLAGS += -Os -fno-caller-saves
else
-KBUILD_CFLAGS += -O2
+KBUILD_CFLAGS += -O2 -fno-reorder-blocks -fno-tree-ch -fno-caller-saves
endif
include $(srctree)/arch/$(SRCARCH)/Makefile
@@ -595,6 +595,9 @@ endif
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
KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)

@ -1,102 +0,0 @@
--- a/scripts/genksyms/parse.c_shipped
+++ b/scripts/genksyms/parse.c_shipped
@@ -160,7 +160,9 @@
#include <assert.h>
+#ifndef __APPLE__
#include <malloc.h>
+#endif
#include "genksyms.h"
static int is_typedef;
--- a/scripts/genksyms/parse.y
+++ b/scripts/genksyms/parse.y
@@ -24,7 +24,9 @@
%{
#include <assert.h>
+#ifndef __APPLE__
#include <malloc.h>
+#endif
#include "genksyms.h"
static int is_typedef;
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -22,6 +22,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
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -147,6 +147,9 @@ check-lxdialog := $(srctree)/$(src)/lxd
# we really need to do so. (Do not call gcc as part of make mrproper)
HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \
-DLOCALE
+ifeq ($(shell uname -s),Darwin)
+HOST_LOADLIBES += -lncurses
+endif
# ===========================================================================
# Shared Makefile for the various kconfig executables:
--- a/scripts/mod/mk_elfconfig.c
+++ b/scripts/mod/mk_elfconfig.c
@@ -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)
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -7,7 +7,11 @@
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
+#if !(defined(__APPLE__) || defined(__CYGWIN__))
#include <elf.h>
+#else
+#include "../../../../../tools/sstrip/include/elf.h"
+#endif
#include "elfconfig.h"

@ -1,17 +0,0 @@
--- a/include/linux/stddef.h
+++ b/include/linux/stddef.h
@@ -16,6 +16,7 @@ enum {
false = 0,
true = 1
};
+#endif /* __KERNEL__ */
#undef offsetof
#ifdef __compiler_offsetof
@@ -23,6 +24,5 @@ enum {
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
-#endif /* __KERNEL__ */
#endif

@ -1,119 +0,0 @@
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -52,6 +52,27 @@
#define LOAD_OFFSET 0
#endif
+#ifndef SYMTAB_KEEP_STR
+#define SYMTAB_KEEP_STR *(__ksymtab_strings.*)
+#define SYMTAB_DISCARD_STR
+#else
+#define SYMTAB_DISCARD_STR *(__ksymtab_strings.*)
+#endif
+
+#ifndef SYMTAB_KEEP
+#define SYMTAB_KEEP *(__ksymtab.*)
+#define SYMTAB_DISCARD
+#else
+#define SYMTAB_DISCARD *(__ksymtab.*)
+#endif
+
+#ifndef SYMTAB_KEEP_GPL
+#define SYMTAB_KEEP_GPL *(__ksymtab_gpl.*)
+#define SYMTAB_DISCARD_GPL
+#else
+#define SYMTAB_DISCARD_GPL *(__ksymtab_gpl.*)
+#endif
+
#ifndef SYMBOL_PREFIX
#define VMLINUX_SYMBOL(sym) sym
#else
@@ -267,35 +288,35 @@
/* Kernel symbol table: Normal symbols */ \
__ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab) = .; \
- *(__ksymtab) \
+ SYMTAB_KEEP \
VMLINUX_SYMBOL(__stop___ksymtab) = .; \
} \
\
/* Kernel symbol table: GPL-only symbols */ \
__ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \
- *(__ksymtab_gpl) \
+ SYMTAB_KEEP_GPL \
VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \
} \
\
/* Kernel symbol table: Normal unused symbols */ \
__ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab_unused) = .; \
- *(__ksymtab_unused) \
+ *(__ksymtab_unused.*) \
VMLINUX_SYMBOL(__stop___ksymtab_unused) = .; \
} \
\
/* Kernel symbol table: GPL-only unused symbols */ \
__ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .; \
- *(__ksymtab_unused_gpl) \
+ *(__ksymtab_unused_gpl.*) \
VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .; \
} \
\
/* Kernel symbol table: GPL-future-only symbols */ \
__ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \
- *(__ksymtab_gpl_future) \
+ *(__ksymtab_gpl_future.*) \
VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \
} \
\
@@ -336,7 +357,7 @@
\
/* Kernel symbol table: strings */ \
__ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
- *(__ksymtab_strings) \
+ SYMTAB_KEEP_STR \
} \
\
/* __*init sections */ \
@@ -660,6 +681,9 @@
EXIT_TEXT \
EXIT_DATA \
EXIT_CALL \
+ SYMTAB_DISCARD \
+ SYMTAB_DISCARD_GPL \
+ SYMTAB_DISCARD_STR \
*(.discard) \
*(.discard.*) \
}
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -202,16 +202,24 @@ struct module_use {
#define __CRC_SYMBOL(sym, sec)
#endif
+#ifdef MODULE
+#define __EXPORT_SUFFIX(sym)
+#else
+#define __EXPORT_SUFFIX(sym) "." #sym
+#endif
+
/* For every exported symbol, place a struct in the __ksymtab section */
#define __EXPORT_SYMBOL(sym, sec) \
extern typeof(sym) sym; \
__CRC_SYMBOL(sym, sec) \
static const char __kstrtab_##sym[] \
- __attribute__((section("__ksymtab_strings"), aligned(1))) \
+ __attribute__((section("__ksymtab_strings" \
+ __EXPORT_SUFFIX(sym)), aligned(1))) \
= MODULE_SYMBOL_PREFIX #sym; \
static const struct kernel_symbol __ksymtab_##sym \
__used \
- __attribute__((section("__ksymtab" sec), unused)) \
+ __attribute__((section("__ksymtab" sec \
+ __EXPORT_SUFFIX(sym)), unused)) \
= { (unsigned long)&sym, __kstrtab_##sym }
#define EXPORT_SYMBOL(sym) \

@ -1,54 +0,0 @@
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -231,7 +231,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^)
quiet_cmd_lzma = LZMA $@
cmd_lzma = (cat $(filter-out FORCE,$^) | \
- lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
+ lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
(rm -f $@ ; false)
quiet_cmd_lzo = LZO $@
--- a/scripts/gen_initramfs_list.sh
+++ b/scripts/gen_initramfs_list.sh
@@ -226,7 +226,7 @@ cpio_list=
output="/dev/stdout"
output_file=""
is_cpio_compressed=
-compr="gzip -9 -f"
+compr="gzip -9 -f -"
arg="$1"
case "$arg" in
@@ -240,9 +240,9 @@ case "$arg" in
output_file="$1"
cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
output=${cpio_list}
- echo "$output_file" | grep -q "\.gz$" && compr="gzip -9 -f"
- echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f"
- echo "$output_file" | grep -q "\.lzma$" && compr="lzma -9 -f"
+ echo "$output_file" | grep -q "\.gz$" && compr="gzip -9 -f -"
+ echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f -"
+ echo "$output_file" | grep -q "\.lzma$" && compr="lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so"
echo "$output_file" | grep -q "\.lzo$" && compr="lzop -9 -f"
echo "$output_file" | grep -q "\.cpio$" && compr="cat"
shift
@@ -294,7 +294,7 @@ if [ ! -z ${output_file} ]; then
if [ "${is_cpio_compressed}" = "compressed" ]; then
cat ${cpio_tfile} > ${output_file}
else
- (cat ${cpio_tfile} | ${compr} - > ${output_file}) \
+ (cat ${cpio_tfile} | ${compr} > ${output_file}) \
|| (rm -f ${output_file} ; false)
fi
[ -z ${cpio_file} ] && rm ${cpio_tfile}
--- a/lib/decompress.c
+++ b/lib/decompress.c
@@ -36,6 +36,7 @@ static const struct compress_format {
{ {037, 0236}, "gzip", gunzip },
{ {0x42, 0x5a}, "bzip2", bunzip2 },
{ {0x5d, 0x00}, "lzma", unlzma },
+ { {0x6d, 0x00}, "lzma-openwrt", unlzma },
{ {0x89, 0x4c}, "lzo", unlzo },
{ {0, 0}, NULL, NULL }
};

@ -1,12 +0,0 @@
--- a/include/linux/atm.h
+++ b/include/linux/atm.h
@@ -139,6 +139,9 @@ struct atm_trafprm {
int min_pcr; /* minimum PCR in cells per second */
int max_cdv; /* maximum CDV in microseconds */
int max_sdu; /* maximum SDU in bytes */
+ int scr; /* sustained rate in cells per second */
+ int mbs; /* maximum burst size (MBS) in cells */
+ int cdv; /* Cell delay varition */
/* extra params for ABR */
unsigned int icr; /* Initial Cell Rate (24-bit) */
unsigned int tbe; /* Transient Buffer Exposure (24-bit) */

@ -1,18 +0,0 @@
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -152,7 +152,6 @@ config NF_CONNTRACK_FTP
config NF_CONNTRACK_H323
tristate "H.323 protocol support"
- depends on (IPV6 || IPV6=n)
depends on NETFILTER_ADVANCED
help
H.323 is a VoIP signalling protocol from ITU-T. As one of the most
@@ -558,7 +557,6 @@ config NETFILTER_XT_TARGET_SECMARK
config NETFILTER_XT_TARGET_TCPMSS
tristate '"TCPMSS" target support'
- depends on (IPV6 || IPV6=n)
default m if NETFILTER_ADVANCED=n
---help---
This option adds a `TCPMSS' target, which allows you to alter the

@ -1,11 +0,0 @@
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -8,7 +8,7 @@ config SND_PCM
select GCD
config SND_HWDEP
- tristate
+ tristate "Sound hardware support"
config SND_RAWMIDI
tristate

@ -1,10 +0,0 @@
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -162,6 +162,7 @@ config CRYPTO_DEV_MV_CESA
depends on PLAT_ORION
select CRYPTO_ALGAPI
select CRYPTO_AES
+ select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
help
This driver allows you to utilize the Cryptographic Engines and

@ -1,29 +0,0 @@
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -29,6 +29,7 @@ config SSB_SPROM
config SSB_BLOCKIO
bool
depends on SSB
+ default y
config SSB_PCIHOST_POSSIBLE
bool
@@ -49,7 +50,7 @@ config SSB_PCIHOST
config SSB_B43_PCI_BRIDGE
bool
depends on SSB_PCIHOST
- default n
+ default y
config SSB_PCMCIAHOST_POSSIBLE
bool
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -17,6 +17,7 @@ config BCMA
config BCMA_BLOCKIO
bool
depends on BCMA
+ default y
config BCMA_HOST_PCI_POSSIBLE
bool

@ -1,23 +0,0 @@
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -152,16 +152,16 @@ config REED_SOLOMON_DEC16
# Textsearch support is select'ed if needed
#
config TEXTSEARCH
- boolean
+ boolean "Textsearch support"
config TEXTSEARCH_KMP
- tristate
+ tristate "Textsearch KMP"
config TEXTSEARCH_BM
- tristate
+ tristate "Textsearch BM"
config TEXTSEARCH_FSM
- tristate
+ tristate "Textsearch FSM"
config BTREE
boolean

@ -1,19 +0,0 @@
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -142,13 +142,13 @@ config LIB80211
you want this built into your kernel.
config LIB80211_CRYPT_WEP
- tristate
+ tristate "LIB80211_CRYPT_WEP"
config LIB80211_CRYPT_CCMP
- tristate
+ tristate "LIB80211_CRYPT_CCMP"
config LIB80211_CRYPT_TKIP
- tristate
+ tristate "LIB80211_CRYPT_TKIP"
config LIB80211_DEBUG
bool "lib80211 debugging messages"

@ -1,47 +0,0 @@
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -31,7 +31,7 @@ config CRYPTO_FIPS
this is.
config CRYPTO_ALGAPI
- tristate
+ tristate "ALGAPI"
select CRYPTO_ALGAPI2
help
This option provides the API for cryptographic algorithms.
@@ -40,7 +40,7 @@ config CRYPTO_ALGAPI2
tristate
config CRYPTO_AEAD
- tristate
+ tristate "AEAD"
select CRYPTO_AEAD2
select CRYPTO_ALGAPI
@@ -49,7 +49,7 @@ config CRYPTO_AEAD2
select CRYPTO_ALGAPI2
config CRYPTO_BLKCIPHER
- tristate
+ tristate "BLKCIPHER"
select CRYPTO_BLKCIPHER2
select CRYPTO_ALGAPI
@@ -60,7 +60,7 @@ config CRYPTO_BLKCIPHER2
select CRYPTO_WORKQUEUE
config CRYPTO_HASH
- tristate
+ tristate "HASH"
select CRYPTO_HASH2
select CRYPTO_ALGAPI
@@ -69,7 +69,7 @@ config CRYPTO_HASH2
select CRYPTO_ALGAPI2
config CRYPTO_RNG
- tristate
+ tristate "RNG"
select CRYPTO_RNG2
select CRYPTO_ALGAPI

@ -1,22 +0,0 @@
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -1,5 +1,5 @@
config WIRELESS_EXT
- bool
+ bool "Wireless extensions"
config WEXT_CORE
def_bool y
@@ -11,10 +11,10 @@ config WEXT_PROC
depends on WEXT_CORE
config WEXT_SPY
- bool
+ bool "WEXT_SPY"
config WEXT_PRIV
- bool
+ bool "WEXT_PRIV"
config CFG80211
tristate "cfg80211 - wireless configuration API"

@ -1,11 +0,0 @@
--- a/usr/Kconfig
+++ b/usr/Kconfig
@@ -75,7 +75,7 @@ config RD_LZMA
config RD_LZO
bool "Support initial ramdisks compressed using LZO" if EMBEDDED
default !EMBEDDED
- depends on BLK_DEV_INITRD
+ depends on BLK_DEV_INITRD && HAVE_KERNEL_LZO
select DECOMPRESS_LZO
help
Support loading of a LZO encoded initial ramdisk or cpio buffer

@ -1,28 +0,0 @@
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -886,6 +886,10 @@ config SYNC_R4K
config MIPS_MACHINE
def_bool n
+config IMAGE_CMDLINE_HACK
+ bool "OpenWrt specific image command line hack"
+ default n
+
config NO_IOPORT
def_bool n
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -141,6 +141,12 @@ FEXPORT(__kernel_entry)
j kernel_entry
#endif
+#ifdef CONFIG_IMAGE_CMDLINE_HACK
+ .ascii "CMDLINE:"
+EXPORT(__image_cmdline)
+ .fill 0x400
+#endif /* CONFIG_IMAGE_CMDLINE_HACK */
+
__REF
NESTED(kernel_entry, 16, sp) # kernel entry point

@ -1,18 +0,0 @@
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -85,6 +85,7 @@ register struct thread_info *__current_t
#define STACK_WARN (THREAD_SIZE / 8)
+#if 0
#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
#ifdef CONFIG_DEBUG_STACK_USAGE
@@ -94,6 +95,7 @@ register struct thread_info *__current_t
#endif
#define free_thread_info(info) kfree(info)
+#endif
#endif /* !__ASSEMBLY__ */

@ -1,11 +0,0 @@
--- a/arch/mips/kernel/machine_kexec.c
+++ b/arch/mips/kernel/machine_kexec.c
@@ -52,7 +52,7 @@ machine_kexec(struct kimage *image)
reboot_code_buffer =
(unsigned long)page_address(image->control_code_page);
- kexec_start_address = image->start;
+ kexec_start_address = (unsigned long) phys_to_virt(image->start);
kexec_indirection_page =
(unsigned long) phys_to_virt(image->head & PAGE_MASK);

@ -1,160 +0,0 @@
MIPS: allow disabling the kernel FPU emulator
This patch allows turning off the in-kernel Algorithmics
FPU emulator support, which allows one to save a couple of
precious blocks on an embedded system.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
--
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -871,6 +871,17 @@ config I8259
config MIPS_BONITO64
bool
+config MIPS_FPU_EMU
+ bool "Enable FPU emulation"
+ default y
+ help
+ This option allows building a kernel with or without the Algorithmics
+ FPU emulator enabled. Turning off this option results in a kernel which
+ does not catch floating operations exceptions. Make sure that your toolchain
+ is configured to enable software floating point emulation in that case.
+
+ If unsure say Y here.
+
config MIPS_MSC
bool
--- a/arch/mips/math-emu/Makefile
+++ b/arch/mips/math-emu/Makefile
@@ -2,11 +2,13 @@
# Makefile for the Linux/MIPS kernel FPU emulation.
#
-obj-y := cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
+obj-y := kernel_linkage.o dsemul.o cp1emu.o
+
+obj-$(CONFIG_MIPS_FPU_EMU) += ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \
dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
- dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o
+ dp_sqrt.o sp_sqrt.o
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -58,7 +58,11 @@
#define __mips 4
/* Function which emulates a floating point instruction. */
+#ifdef CONFIG_DEBUG_FS
+DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
+#endif
+#ifdef CONFIG_MIPS_FPU_EMU
static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
mips_instruction);
@@ -69,10 +73,6 @@ static int fpux_emu(struct pt_regs *,
/* Further private data for which no space exists in mips_fpu_struct */
-#ifdef CONFIG_DEBUG_FS
-DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
-#endif
-
/* Control registers */
#define FPCREG_RID 0 /* $0 = revision id */
@@ -1361,7 +1361,6 @@ int fpu_emulator_cop1Handler(struct pt_r
return sig;
}
-
#ifdef CONFIG_DEBUG_FS
static int fpuemu_stat_get(void *data, u64 *val)
@@ -1410,4 +1409,11 @@ static int __init debugfs_fpuemu(void)
return 0;
}
__initcall(debugfs_fpuemu);
-#endif
+#endif /* CONFIG_DEBUGFS */
+#else
+int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ int has_fpu)
+{
+ return 0;
+}
+#endif /* CONFIG_MIPS_FPU_EMU */
--- a/arch/mips/math-emu/dsemul.c
+++ b/arch/mips/math-emu/dsemul.c
@@ -109,6 +109,7 @@ int mips_dsemul(struct pt_regs *regs, mi
return SIGILL; /* force out of emulation loop */
}
+#ifdef CONFIG_MIPS_FPU_EMU
int do_dsemulret(struct pt_regs *xcp)
{
struct emuframe __user *fr;
@@ -165,3 +166,9 @@ int do_dsemulret(struct pt_regs *xcp)
return 1;
}
+#else
+int do_dsemulret(struct pt_regs *xcp)
+{
+ return 0;
+}
+#endif /* CONFIG_MIPS_FPU_EMU */
--- a/arch/mips/math-emu/kernel_linkage.c
+++ b/arch/mips/math-emu/kernel_linkage.c
@@ -29,6 +29,7 @@
#define SIGNALLING_NAN 0x7ff800007ff80000LL
+#ifdef CONFIG_MIPS_FPU_EMU
void fpu_emulator_init_fpu(void)
{
static int first = 1;
@@ -112,4 +113,36 @@ int fpu_emulator_restore_context32(struc
return err;
}
-#endif
+#endif /* CONFIG_64BIT */
+#else
+
+void fpu_emulator_init_fpu(void)
+{
+ printk(KERN_INFO "FPU emulator disabled, make sure your toolchain"
+ "was compiled with software floating point support (soft-float)\n");
+ return;
+}
+
+int fpu_emulator_save_context(struct sigcontext __user *sc)
+{
+ return 0;
+}
+
+int fpu_emulator_restore_context(struct sigcontext __user *sc)
+{
+ return 0;
+}
+
+int fpu_emulator_save_context32(struct sigcontext32 __user *sc)
+{
+ return 0;
+}
+
+int fpu_emulator_restore_context32(struct sigcontext32 __user *sc)
+{
+ return 0;
+}
+
+#ifdef CONFIG_64BIT
+#endif /* CONFIG_64BIT */
+#endif /* CONFIG_MIPS_FPU_EMU */

@ -1,370 +0,0 @@
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -90,8 +90,8 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
cflags-y += -G 0 -mno-abicalls -fno-pic -pipe
cflags-y += -msoft-float
LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
-KBUILD_AFLAGS_MODULE += -mlong-calls
-KBUILD_CFLAGS_MODULE += -mlong-calls
+KBUILD_AFLAGS_MODULE += -mno-long-calls
+KBUILD_CFLAGS_MODULE += -mno-long-calls
cflags-y += -ffreestanding
--- a/arch/mips/include/asm/module.h
+++ b/arch/mips/include/asm/module.h
@@ -9,6 +9,11 @@ struct mod_arch_specific {
struct list_head dbe_list;
const struct exception_table_entry *dbe_start;
const struct exception_table_entry *dbe_end;
+
+ void *phys_plt_tbl;
+ void *virt_plt_tbl;
+ unsigned int phys_plt_offset;
+ unsigned int virt_plt_offset;
};
typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -43,6 +43,117 @@ static struct mips_hi16 *mips_hi16_list;
static LIST_HEAD(dbe_list);
static DEFINE_SPINLOCK(dbe_lock);
+/*
+ * Get the potential max trampolines size required of the init and
+ * non-init sections. Only used if we cannot find enough contiguous
+ * physically mapped memory to put the module into.
+ */
+static unsigned int
+get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
+ const char *secstrings, unsigned int symindex, bool is_init)
+{
+ unsigned long ret = 0;
+ unsigned int i, j;
+ Elf_Sym *syms;
+
+ /* Everything marked ALLOC (this includes the exported symbols) */
+ for (i = 1; i < hdr->e_shnum; ++i) {
+ unsigned int info = sechdrs[i].sh_info;
+
+ if (sechdrs[i].sh_type != SHT_REL
+ && sechdrs[i].sh_type != SHT_RELA)
+ continue;
+
+ /* Not a valid relocation section? */
+ if (info >= hdr->e_shnum)
+ continue;
+
+ /* Don't bother with non-allocated sections */
+ if (!(sechdrs[info].sh_flags & SHF_ALLOC))
+ continue;
+
+ /* If it's called *.init*, and we're not init, we're
+ not interested */
+ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0)
+ != is_init)
+ continue;
+
+ syms = (Elf_Sym *) sechdrs[symindex].sh_addr;
+ if (sechdrs[i].sh_type == SHT_REL) {
+ Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr;
+ unsigned int size = sechdrs[i].sh_size / sizeof(*rel);
+
+ for (j = 0; j < size; ++j) {
+ Elf_Sym *sym;
+
+ if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26)
+ continue;
+
+ sym = syms + ELF_MIPS_R_SYM(rel[j]);
+ if (!is_init && sym->st_shndx != SHN_UNDEF)
+ continue;
+
+ ret += 4 * sizeof(int);
+ }
+ } else {
+ Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr;
+ unsigned int size = sechdrs[i].sh_size / sizeof(*rela);
+
+ for (j = 0; j < size; ++j) {
+ Elf_Sym *sym;
+
+ if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26)
+ continue;
+
+ sym = syms + ELF_MIPS_R_SYM(rela[j]);
+ if (!is_init && sym->st_shndx != SHN_UNDEF)
+ continue;
+
+ ret += 4 * sizeof(int);
+ }
+ }
+ }
+
+ return ret;
+}
+
+#ifndef MODULE_START
+static void *alloc_phys(unsigned long size)
+{
+ unsigned order;
+ struct page *page;
+ struct page *p;
+
+ size = PAGE_ALIGN(size);
+ order = get_order(size);
+
+ page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN |
+ __GFP_THISNODE, order);
+ if (!page)
+ return NULL;
+
+ split_page(page, order);
+
+ for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p)
+ __free_page(p);
+
+ return page_address(page);
+}
+#endif
+
+static void free_phys(void *ptr, unsigned long size)
+{
+ struct page *page;
+ struct page *end;
+
+ page = virt_to_page(ptr);
+ end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT);
+
+ for (; page < end; ++page)
+ __free_page(page);
+}
+
+
void *module_alloc(unsigned long size)
{
#ifdef MODULE_START
@@ -58,21 +169,99 @@ void *module_alloc(unsigned long size)
return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL);
#else
+ void *ptr;
+
if (size == 0)
return NULL;
- return vmalloc(size);
+
+ ptr = alloc_phys(size);
+
+ /* If we failed to allocate physically contiguous memory,
+ * fall back to regular vmalloc. The module loader code will
+ * create jump tables to handle long jumps */
+ if (!ptr)
+ return vmalloc(size);
+
+ return ptr;
+#endif
+}
+
+static inline bool is_phys_addr(void *ptr)
+{
+#ifdef CONFIG_64BIT
+ return (KSEGX((unsigned long)ptr) == CKSEG0);
+#else
+ return (KSEGX(ptr) == KSEG0);
#endif
}
/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
{
- vfree(module_region);
+ if (is_phys_addr(module_region)) {
+ if (mod->module_init == module_region)
+ free_phys(module_region, mod->init_size);
+ else if (mod->module_core == module_region)
+ free_phys(module_region, mod->core_size);
+ else
+ BUG();
+ } else {
+ vfree(module_region);
+ }
+}
+
+static void *__module_alloc(int size, bool phys)
+{
+ void *ptr;
+
+ if (phys)
+ ptr = kmalloc(size, GFP_KERNEL);
+ else
+ ptr = vmalloc(size);
+ return ptr;
+}
+
+static void __module_free(void *ptr)
+{
+ if (is_phys_addr(ptr))
+ kfree(ptr);
+ else
+ vfree(ptr);
}
int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
char *secstrings, struct module *mod)
{
+ unsigned int symindex = 0;
+ unsigned int core_size, init_size;
+ int i;
+
+ for (i = 1; i < hdr->e_shnum; i++)
+ if (sechdrs[i].sh_type == SHT_SYMTAB)
+ symindex = i;
+
+ core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false);
+ init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true);
+
+ mod->arch.phys_plt_offset = 0;
+ mod->arch.virt_plt_offset = 0;
+ mod->arch.phys_plt_tbl = NULL;
+ mod->arch.virt_plt_tbl = NULL;
+
+ if ((core_size + init_size) == 0)
+ return 0;
+
+ mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1);
+ if (!mod->arch.phys_plt_tbl)
+ return -ENOMEM;
+
+ mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0);
+ if (!mod->arch.virt_plt_tbl) {
+ __module_free(mod->arch.phys_plt_tbl);
+ mod->arch.phys_plt_tbl = NULL;
+ return -ENOMEM;
+ }
+
return 0;
}
@@ -95,28 +284,36 @@ static int apply_r_mips_32_rela(struct m
return 0;
}
-static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
+static Elf_Addr add_plt_entry_to(unsigned *plt_offset,
+ void *start, Elf_Addr v)
{
- if (v % 4) {
- pr_err("module %s: dangerous R_MIPS_26 REL relocation\n",
- me->name);
- return -ENOEXEC;
- }
+ unsigned *tramp = start + *plt_offset;
+ *plt_offset += 4 * sizeof(int);
- if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
- printk(KERN_ERR
- "module %s: relocation overflow\n",
- me->name);
- return -ENOEXEC;
- }
+ /* adjust carry for addiu */
+ if (v & 0x00008000)
+ v += 0x10000;
- *location = (*location & ~0x03ffffff) |
- ((*location + (v >> 2)) & 0x03ffffff);
+ tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */
+ tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */
+ tramp[2] = 0x03200008; /* jr t9 */
+ tramp[3] = 0x00000000; /* nop */
- return 0;
+ return (Elf_Addr) tramp;
}
-static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
+static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v)
+{
+ if (is_phys_addr(location))
+ return add_plt_entry_to(&me->arch.phys_plt_offset,
+ me->arch.phys_plt_tbl, v);
+ else
+ return add_plt_entry_to(&me->arch.virt_plt_offset,
+ me->arch.virt_plt_tbl, v);
+
+}
+
+static int set_r_mips_26(struct module *me, u32 *location, u32 ofs, Elf_Addr v)
{
if (v % 4) {
pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n",
@@ -125,17 +322,31 @@ static int apply_r_mips_26_rela(struct m
}
if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
- printk(KERN_ERR
+ v = add_plt_entry(me, location, v + (ofs << 2));
+ if (!v) {
+ printk(KERN_ERR
"module %s: relocation overflow\n",
me->name);
- return -ENOEXEC;
+ return -ENOEXEC;
+ }
+ ofs = 0;
}
- *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
+ *location = (*location & ~0x03ffffff) | ((ofs + (v >> 2)) & 0x03ffffff);
return 0;
}
+static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ return set_r_mips_26(me, location, *location & 0x03ffffff, v);
+}
+
+static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ return set_r_mips_26(me, location, 0, v);
+}
+
static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
{
struct mips_hi16 *n;
@@ -400,11 +611,32 @@ int module_finalize(const Elf_Ehdr *hdr,
list_add(&me->arch.dbe_list, &dbe_list);
spin_unlock_irq(&dbe_lock);
}
+
+ /* Get rid of the fixup trampoline if we're running the module
+ * from physically mapped address space */
+ if (me->arch.phys_plt_offset == 0) {
+ __module_free(me->arch.phys_plt_tbl);
+ me->arch.phys_plt_tbl = NULL;
+ }
+ if (me->arch.virt_plt_offset == 0) {
+ __module_free(me->arch.virt_plt_tbl);
+ me->arch.virt_plt_tbl = NULL;
+ }
+
return 0;
}
void module_arch_cleanup(struct module *mod)
{
+ if (mod->arch.phys_plt_tbl) {
+ __module_free(mod->arch.phys_plt_tbl);
+ mod->arch.phys_plt_tbl = NULL;
+ }
+ if (mod->arch.virt_plt_tbl) {
+ __module_free(mod->arch.virt_plt_tbl);
+ mod->arch.virt_plt_tbl = NULL;
+ }
+
spin_lock_irq(&dbe_lock);
list_del(&mod->arch.dbe_list);
spin_unlock_irq(&dbe_lock);

@ -1,83 +0,0 @@
--- a/arch/mips/include/asm/string.h
+++ b/arch/mips/include/asm/string.h
@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__
#define __HAVE_ARCH_MEMSET
extern void *memset(void *__s, int __c, size_t __count);
+#define memset(__s, __c, len) \
+({ \
+ size_t __len = (len); \
+ void *__ret; \
+ if (__builtin_constant_p(len) && __len >= 64) \
+ __ret = memset((__s), (__c), __len); \
+ else \
+ __ret = __builtin_memset((__s), (__c), __len); \
+ __ret; \
+})
#define __HAVE_ARCH_MEMCPY
extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
+#define memcpy(dst, src, len) \
+({ \
+ size_t __len = (len); \
+ void *__ret; \
+ if (__builtin_constant_p(len) && __len >= 64) \
+ __ret = memcpy((dst), (src), __len); \
+ else \
+ __ret = __builtin_memcpy((dst), (src), __len); \
+ __ret; \
+})
#define __HAVE_ARCH_MEMMOVE
extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
+#define memmove(dst, src, len) \
+({ \
+ size_t __len = (len); \
+ void *__ret; \
+ if (__builtin_constant_p(len) && __len >= 64) \
+ __ret = memmove((dst), (src), __len); \
+ else \
+ __ret = __builtin_memmove((dst), (src), __len); \
+ __ret; \
+})
+
+#define __HAVE_ARCH_MEMCMP
+#define memcmp(src1, src2, len) __builtin_memcmp((src1), (src2), (len))
#endif /* _ASM_STRING_H */
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -3,7 +3,7 @@
#
lib-y += csum_partial.o delay.o memcpy.o memcpy-inatomic.o memset.o \
- strlen_user.o strncpy_user.o strnlen_user.o uncached.o
+ strlen_user.o strncpy_user.o strnlen_user.o uncached.o memcmp.o
obj-y += iomap.o
obj-$(CONFIG_PCI) += iomap-pci.o
--- /dev/null
+++ b/arch/mips/lib/memcmp.c
@@ -0,0 +1,22 @@
+/*
+ * copied from linux/lib/string.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+
+#undef memcmp
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+ const unsigned char *su1, *su2;
+ int res = 0;
+
+ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+ if ((res = *su1 - *su2) != 0)
+ break;
+ return res;
+}
+EXPORT_SYMBOL(memcmp);
+

@ -1,35 +0,0 @@
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -298,6 +298,11 @@ static void reset_counters(void *arg)
}
}
+static irqreturn_t mipsxx_perfcount_int(int irq, void *dev_id)
+{
+ return mipsxx_perfcount_handler();
+}
+
static int __init mipsxx_init(void)
{
int counters;
@@ -374,6 +379,10 @@ static int __init mipsxx_init(void)
save_perf_irq = perf_irq;
perf_irq = mipsxx_perfcount_handler;
+ if (cp0_perfcount_irq >= 0)
+ return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int,
+ IRQF_SHARED, "Perfcounter", save_perf_irq);
+
return 0;
}
@@ -381,6 +390,9 @@ static void mipsxx_exit(void)
{
int counters = op_model_mipsxx_ops.num_counters;
+ if (cp0_perfcount_irq >= 0)
+ free_irq(cp0_perfcount_irq, save_perf_irq);
+
counters = counters_per_cpu_to_total(counters);
on_each_cpu(reset_counters, (void *)(long)counters, 1);

@ -1,11 +0,0 @@
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -121,6 +121,8 @@
#endif
.endm
+ j kernel_entry
+ nop
#ifndef CONFIG_NO_EXCEPT_FILL
/*
* Reserved space for exception handlers.

@ -1,13 +0,0 @@
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -134,6 +134,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons
return -ENOEXEC;
}
+ if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) &&
+ ELF_ST_BIND(sym->st_info) == STB_WEAK)
+ continue;
+
loc = dstsec->sh_addr + rel->r_offset;
switch (ELF32_R_TYPE(rel->r_info)) {

@ -1,389 +0,0 @@
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
#
# http://www.arm.linux.org.uk/developer/machines/?action=new
#
-# Last update: Sun Dec 12 23:24:27 2010
+# Last update: Wed Feb 2 23:04:05 2011
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -1319,7 +1319,7 @@ mistral MACH_MISTRAL MISTRAL 1315
msm MACH_MSM MSM 1316
ct5910 MACH_CT5910 CT5910 1317
ct5912 MACH_CT5912 CT5912 1318
-hynet_ine MACH_HYNET_INE HYNET_INE 1319
+argonst_mp MACH_HYNET_INE HYNET_INE 1319
hynet_app MACH_HYNET_APP HYNET_APP 1320
msm7200 MACH_MSM7200 MSM7200 1321
msm7600 MACH_MSM7600 MSM7600 1322
@@ -1777,7 +1777,7 @@ wdg002 MACH_WDG002 WDG002 1785
sg560adsl MACH_SG560ADSL SG560ADSL 1786
nextio_n2800_ica MACH_NEXTIO_N2800_ICA NEXTIO_N2800_ICA 1787
dove_db MACH_DOVE_DB DOVE_DB 1788
-marvell_newdb MACH_MARVELL_NEWDB MARVELL_NEWDB 1789
+dove_avng MACH_MARVELL_NEWDB MARVELL_NEWDB 1789
vandihud MACH_VANDIHUD VANDIHUD 1790
magx_e8 MACH_MAGX_E8 MAGX_E8 1791
magx_z6 MACH_MAGX_Z6 MAGX_Z6 1792
@@ -1877,7 +1877,7 @@ ued MACH_UED UED 1885
esiblade MACH_ESIBLADE ESIBLADE 1886
eye02 MACH_EYE02 EYE02 1887
imx27kbd MACH_IMX27KBD IMX27KBD 1888
-sst61vc010_fpga MACH_SST61VC010_FPGA SST61VC010_FPGA 1889
+p87_fpga MACH_SST61VC010_FPGA SST61VC010_FPGA 1889
kixvp435 MACH_KIXVP435 KIXVP435 1890
kixnp435 MACH_KIXNP435 KIXNP435 1891
africa MACH_AFRICA AFRICA 1892
@@ -2240,7 +2240,7 @@ arm_ultimator2 MACH_ARM_ULTIMATOR2 ARM_
vs_v210 MACH_VS_V210 VS_V210 2252
vs_v212 MACH_VS_V212 VS_V212 2253
hmt MACH_HMT HMT 2254
-suen3 MACH_SUEN3 SUEN3 2255
+km_kirkwood MACH_KM_KIRKWOOD KM_KIRKWOOD 2255
vesper MACH_VESPER VESPER 2256
str9 MACH_STR9 STR9 2257
omap3_wl_ff MACH_OMAP3_WL_FF OMAP3_WL_FF 2258
@@ -2308,7 +2308,7 @@ ecac2378 MACH_ECAC2378 ECAC2378 2319
tazkiosk MACH_TAZKIOSK TAZKIOSK 2320
whiterabbit_mch MACH_WHITERABBIT_MCH WHITERABBIT_MCH 2321
sbox9263 MACH_SBOX9263 SBOX9263 2322
-oreo MACH_OREO OREO 2323
+oreo_camera MACH_OREO OREO 2323
smdk6442 MACH_SMDK6442 SMDK6442 2324
openrd_base MACH_OPENRD_BASE OPENRD_BASE 2325
incredible MACH_INCREDIBLE INCREDIBLE 2326
@@ -2374,7 +2374,7 @@ sch_m490 MACH_SCH_M490 SCH_M490 2386
rbl01 MACH_RBL01 RBL01 2387
omnifi MACH_OMNIFI OMNIFI 2388
otavalo MACH_OTAVALO OTAVALO 2389
-sienna MACH_SIENNA SIENNA 2390
+siena MACH_SIENNA SIENNA 2390
htc_excalibur_s620 MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620 2391
htc_opal MACH_HTC_OPAL HTC_OPAL 2392
touchbook MACH_TOUCHBOOK TOUCHBOOK 2393
@@ -2446,7 +2446,7 @@ siogentoo1 MACH_SIOGENTOO1 SIOGENTOO1
siogentoo2 MACH_SIOGENTOO2 SIOGENTOO2 2459
sm3k MACH_SM3K SM3K 2460
acer_tempo_f900 MACH_ACER_TEMPO_F900 ACER_TEMPO_F900 2461
-sst61vc010_dev MACH_SST61VC010_DEV SST61VC010_DEV 2462
+p87_dev MACH_SST61VC010_DEV SST61VC010_DEV 2462
glittertind MACH_GLITTERTIND GLITTERTIND 2463
omap_zoom3 MACH_OMAP_ZOOM3 OMAP_ZOOM3 2464
omap_3630sdp MACH_OMAP_3630SDP OMAP_3630SDP 2465
@@ -2498,7 +2498,7 @@ hiram MACH_HIRAM HIRAM 2510
phy3250 MACH_PHY3250 PHY3250 2511
ea3250 MACH_EA3250 EA3250 2512
fdi3250 MACH_FDI3250 FDI3250 2513
-whitestone MACH_WHITESTONE WHITESTONE 2514
+htcwhitestone MACH_WHITESTONE WHITESTONE 2514
at91sam9263nit MACH_AT91SAM9263NIT AT91SAM9263NIT 2515
ccmx51 MACH_CCMX51 CCMX51 2516
ccmx51js MACH_CCMX51JS CCMX51JS 2517
@@ -2561,7 +2561,7 @@ magnolia2 MACH_MAGNOLIA2 MAGNOLIA2 25
emxx MACH_EMXX EMXX 2574
outlaw MACH_OUTLAW OUTLAW 2575
riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576
-riot_vox MACH_RIOT_VOX RIOT_VOX 2577
+riot_gx2 MACH_RIOT_VOX RIOT_VOX 2577
riot_x37 MACH_RIOT_X37 RIOT_X37 2578
mega25mx MACH_MEGA25MX MEGA25MX 2579
benzina2 MACH_BENZINA2 BENZINA2 2580
@@ -2582,7 +2582,7 @@ omap3_bulldog MACH_OMAP3_BULLDOG OMAP3_
pca101 MACH_PCA101 PCA101 2595
buzzc MACH_BUZZC BUZZC 2596
sasie2 MACH_SASIE2 SASIE2 2597
-davinci_cio MACH_DAVINCI_CIO DAVINCI_CIO 2598
+davinci_dm6467_cio MACH_DAVINCI_CIO DAVINCI_CIO 2598
smartmeter_dl MACH_SMARTMETER_DL SMARTMETER_DL 2599
wzl6410 MACH_WZL6410 WZL6410 2600
wzl6410m MACH_WZL6410M WZL6410M 2601
@@ -2591,7 +2591,7 @@ wzl6410i MACH_WZL6410I WZL6410I 2603
spacecom1 MACH_SPACECOM1 SPACECOM1 2604
pingu920 MACH_PINGU920 PINGU920 2605
bravoc MACH_BRAVOC BRAVOC 2606
-cybo2440 MACH_CYBO2440 CYBO2440 2607
+mydev MACH_CYBO2440 CYBO2440 2607
vdssw MACH_VDSSW VDSSW 2608
romulus MACH_ROMULUS ROMULUS 2609
omap_magic MACH_OMAP_MAGIC OMAP_MAGIC 2610
@@ -2683,7 +2683,7 @@ lkevm MACH_LKEVM LKEVM 2695
mw6410 MACH_MW6410 MW6410 2696
terastation_wxl MACH_TERASTATION_WXL TERASTATION_WXL 2697
cpu8000e MACH_CPU8000E CPU8000E 2698
-catania MACH_CATANIA CATANIA 2699
+catania_s MACH_CATANIA CATANIA 2699
tokyo MACH_TOKYO TOKYO 2700
msm7201a_surf MACH_MSM7201A_SURF MSM7201A_SURF 2701
msm7201a_ffa MACH_MSM7201A_FFA MSM7201A_FFA 2702
@@ -2741,7 +2741,7 @@ wbd222 MACH_WBD222 WBD222 2753
mt65xx MACH_MT65XX MT65XX 2754
msm8x60_surf MACH_MSM8X60_SURF MSM8X60_SURF 2755
msm8x60_sim MACH_MSM8X60_SIM MSM8X60_SIM 2756
-vmc300 MACH_VMC300 VMC300 2757
+cvc600 MACH_VMC300 VMC300 2757
tcc8000_sdk MACH_TCC8000_SDK TCC8000_SDK 2758
nanos MACH_NANOS NANOS 2759
stamp9g10 MACH_STAMP9G10 STAMP9G10 2760
@@ -2750,7 +2750,7 @@ h6053 MACH_H6053 H6053 2762
smint01 MACH_SMINT01 SMINT01 2763
prtlvt2 MACH_PRTLVT2 PRTLVT2 2764
ap420 MACH_AP420 AP420 2765
-htcshift MACH_HTCSHIFT HTCSHIFT 2766
+htcclio MACH_HTCSHIFT HTCSHIFT 2766
davinci_dm365_fc MACH_DAVINCI_DM365_FC DAVINCI_DM365_FC 2767
msm8x55_surf MACH_MSM8X55_SURF MSM8X55_SURF 2768
msm8x55_ffa MACH_MSM8X55_FFA MSM8X55_FFA 2769
@@ -2761,7 +2761,7 @@ oreo_controller MACH_OREO_CONTROLLER OR
kopin_models MACH_KOPIN_MODELS KOPIN_MODELS 2774
ttc_vision2 MACH_TTC_VISION2 TTC_VISION2 2775
cns3420vb MACH_CNS3420VB CNS3420VB 2776
-lpc2 MACH_LPC2 LPC2 2777
+lpc_evo MACH_LPC2 LPC2 2777
olympus MACH_OLYMPUS OLYMPUS 2778
vortex MACH_VORTEX VORTEX 2779
s5pc200 MACH_S5PC200 S5PC200 2780
@@ -2788,7 +2788,7 @@ ti8168evm MACH_TI8168EVM TI8168EVM 28
neocoreomap MACH_NEOCOREOMAP NEOCOREOMAP 2801
withings_wbp MACH_WITHINGS_WBP WITHINGS_WBP 2802
dbps MACH_DBPS DBPS 2803
-sbc9261 MACH_SBC9261 SBC9261 2804
+at91sam9261 MACH_SBC9261 SBC9261 2804
pcbfp0001 MACH_PCBFP0001 PCBFP0001 2805
speedy MACH_SPEEDY SPEEDY 2806
chrysaor MACH_CHRYSAOR CHRYSAOR 2807
@@ -2812,7 +2812,7 @@ p565 MACH_P565 P565 2824
acer_a4 MACH_ACER_A4 ACER_A4 2825
davinci_dm368_bip MACH_DAVINCI_DM368_BIP DAVINCI_DM368_BIP 2826
eshare MACH_ESHARE ESHARE 2827
-hw_omapl138_europa MACH_HW_OMAPL138_EUROPA HW_OMAPL138_EUROPA 2828
+omapl138_europa MACH_HW_OMAPL138_EUROPA HW_OMAPL138_EUROPA 2828
wlbargn MACH_WLBARGN WLBARGN 2829
bm170 MACH_BM170 BM170 2830
netspace_mini_v2 MACH_NETSPACE_MINI_V2 NETSPACE_MINI_V2 2831
@@ -2879,7 +2879,7 @@ davinci_picto MACH_DAVINCI_PICTO DAVINC
mecha MACH_MECHA MECHA 2892
bubba3 MACH_BUBBA3 BUBBA3 2893
pupitre MACH_PUPITRE PUPITRE 2894
-tegra_harmony MACH_TEGRA_HARMONY TEGRA_HARMONY 2895
+tegra_unused MACH_TEGRA_HARMONY TEGRA_HARMONY 2895
tegra_vogue MACH_TEGRA_VOGUE TEGRA_VOGUE 2896
tegra_e1165 MACH_TEGRA_E1165 TEGRA_E1165 2897
simplenet MACH_SIMPLENET SIMPLENET 2898
@@ -2896,6 +2896,7 @@ e10 MACH_E10 E10 2908
app3k_robin MACH_APP3K_ROBIN APP3K_ROBIN 2909
pov15hd MACH_POV15HD POV15HD 2910
stella MACH_STELLA STELLA 2911
+htc_iolite MACH_MACH_HTC_IOLITE MACH_HTC_IOLITE 2912
linkstation_lschl MACH_LINKSTATION_LSCHL LINKSTATION_LSCHL 2913
netwalker MACH_NETWALKER NETWALKER 2914
acsx106 MACH_ACSX106 ACSX106 2915
@@ -2959,6 +2960,7 @@ davinci_dm355_mmm MACH_DAVINCI_DM355_MMM
pc9260_v2 MACH_PC9260_V2 PC9260_V2 2973
ptx7545 MACH_PTX7545 PTX7545 2974
tm_efdc MACH_TM_EFDC TM_EFDC 2975
+remove_me MACH_WALDO1 WALDO1 2976
omap3_waldo1 MACH_OMAP3_WALDO1 OMAP3_WALDO1 2977
flyer MACH_FLYER FLYER 2978
tornado3240 MACH_TORNADO3240 TORNADO3240 2979
@@ -2969,7 +2971,7 @@ netspace_lite_v2 MACH_NETSPACE_LITE_V2 N
ssc MACH_SSC SSC 2984
premierwave_en MACH_PREMIERWAVE_EN PREMIERWAVE_EN 2985
wasabi MACH_WASABI WASABI 2986
-vivow MACH_VIVOW VIVOW 2987
+vivo_w MACH_VIVOW VIVOW 2987
mx50_rdp MACH_MX50_RDP MX50_RDP 2988
universal_c210 MACH_UNIVERSAL_C210 UNIVERSAL_C210 2989
real6410 MACH_REAL6410 REAL6410 2990
@@ -2987,7 +2989,7 @@ pxwnas_500_1000 MACH_PXWNAS_500_1000 PX
ea20 MACH_EA20 EA20 3002
awm2 MACH_AWM2 AWM2 3003
ti8148evm MACH_TI8148EVM TI8148EVM 3004
-tegra_seaboard MACH_TEGRA_SEABOARD TEGRA_SEABOARD 3005
+seaboard MACH_SEABOARD SEABOARD 3005
linkstation_chlv2 MACH_LINKSTATION_CHLV2 LINKSTATION_CHLV2 3006
tera_pro2_rack MACH_TERA_PRO2_RACK TERA_PRO2_RACK 3007
rubys MACH_RUBYS RUBYS 3008
@@ -3017,12 +3019,12 @@ remus MACH_REMUS REMUS 3031
at91cap7xdk MACH_AT91CAP7XDK AT91CAP7XDK 3032
at91cap7stk MACH_AT91CAP7STK AT91CAP7STK 3033
kt_sbc_sam9_1 MACH_KT_SBC_SAM9_1 KT_SBC_SAM9_1 3034
-oratisrouter MACH_ORATISROUTER ORATISROUTER 3035
+at91sam9263router MACH_ORATISROUTER ORATISROUTER 3035
armada_xp_db MACH_ARMADA_XP_DB ARMADA_XP_DB 3036
spdm MACH_SPDM SPDM 3037
gtib MACH_GTIB GTIB 3038
dgm3240 MACH_DGM3240 DGM3240 3039
-atlas_i_lpe MACH_ATLAS_I_LPE ATLAS_I_LPE 3040
+iv_atlas_i_lpe MACH_ATLAS_I_LPE ATLAS_I_LPE 3040
htcmega MACH_HTCMEGA HTCMEGA 3041
tricorder MACH_TRICORDER TRICORDER 3042
tx28 MACH_TX28 TX28 3043
@@ -3038,6 +3040,7 @@ s5pc110_crespo MACH_S5PC110_CRESPO S5PC
controltek9g20 MACH_CONTROLTEK9G20 CONTROLTEK9G20 3053
tin307 MACH_TIN307 TIN307 3054
tin510 MACH_TIN510 TIN510 3055
+ep3505 MACH_EP3517 EP3517 3056
bluecheese MACH_BLUECHEESE BLUECHEESE 3057
tem3x30 MACH_TEM3X30 TEM3X30 3058
harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059
@@ -3062,7 +3065,7 @@ clod MACH_CLOD CLOD 3077
rump MACH_RUMP RUMP 3078
tenderloin MACH_TENDERLOIN TENDERLOIN 3079
shortloin MACH_SHORTLOIN SHORTLOIN 3080
-crespo MACH_CRESPO CRESPO 3081
+roml1 MACH_CRESPO CRESPO 3081
antares MACH_ANTARES ANTARES 3082
wb40n MACH_WB40N WB40N 3083
herring MACH_HERRING HERRING 3084
@@ -3109,9 +3112,9 @@ msm8x60_fluid MACH_MSM8X60_FLUID MSM8X6
smartqv5 MACH_SMARTQV5 SMARTQV5 3125
smartqv3 MACH_SMARTQV3 SMARTQV3 3126
smartqv7 MACH_SMARTQV7 SMARTQV7 3127
-paz00 MACH_PAZ00 PAZ00 3128
+tegra_paz00 MACH_PAZ00 PAZ00 3128
acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129
-htcwillow MACH_HTCWILLOW HTCWILLOW 3130
+htc_willow MACH_HTCWILLOW HTCWILLOW 3130
fwbd_0404 MACH_FWBD_0404 FWBD_0404 3131
hdgu MACH_HDGU HDGU 3132
pyramid MACH_PYRAMID PYRAMID 3133
@@ -3162,7 +3165,7 @@ b5500 MACH_B5500 B5500 3177
s5500 MACH_S5500 S5500 3178
icon MACH_ICON ICON 3179
elephant MACH_ELEPHANT ELEPHANT 3180
-msm8x60_fusion MACH_MSM8X60_FUSION MSM8X60_FUSION 3181
+msm8x60_charm_surf MACH_MSM8X60_FUSION MSM8X60_FUSION 3181
shooter MACH_SHOOTER SHOOTER 3182
spade_lte MACH_SPADE_LTE SPADE_LTE 3183
philhwani MACH_PHILHWANI PHILHWANI 3184
@@ -3174,13 +3177,13 @@ ag5evm MACH_AG5EVM AG5EVM 3189
sc575plc MACH_SC575PLC SC575PLC 3190
sc575hmi MACH_SC575IPC SC575IPC 3191
omap3_tdm3730 MACH_OMAP3_TDM3730 OMAP3_TDM3730 3192
-g7 MACH_G7 G7 3193
+rover_g7 MACH_G7 G7 3193
top9000_eval MACH_TOP9000_EVAL TOP9000_EVAL 3194
top9000_su MACH_TOP9000_SU TOP9000_SU 3195
utm300 MACH_UTM300 UTM300 3196
tsunagi MACH_TSUNAGI TSUNAGI 3197
ts75xx MACH_TS75XX TS75XX 3198
-msm8x60_fusn_ffa MACH_MSM8X60_FUSN_FFA MSM8X60_FUSN_FFA 3199
+msm8x60_charm_ffa MACH_MSM8X60_FUSN_FFA MSM8X60_FUSN_FFA 3199
ts47xx MACH_TS47XX TS47XX 3200
da850_k5 MACH_DA850_K5 DA850_K5 3201
ax502 MACH_AX502 AX502 3202
@@ -3190,9 +3193,10 @@ synergy MACH_SYNERGY SYNERGY 3205
ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206
wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207
punica MACH_PUNICA PUNICA 3208
-sbc_nt250 MACH_SBC_NT250 SBC_NT250 3209
+trimslice MACH_SBC_NT250 SBC_NT250 3209
mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210
mackerel MACH_MACKEREL MACKEREL 3211
+pvd_imx27 MACH_MACH_PVD_IMX27 MACH_PVD_IMX27 3212
fa9x27 MACH_FA9X27 FA9X27 3213
ns2816tb MACH_NS2816TB NS2816TB 3214
ns2816_ntpad MACH_NS2816_NTPAD NS2816_NTPAD 3215
@@ -3219,3 +3223,100 @@ pivicc MACH_PIVICC PIVICC 3235
pcm048 MACH_PCM048 PCM048 3236
dds MACH_DDS DDS 3237
chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238
+ts48xx MACH_TS48XX TS48XX 3239
+tonga2_tfttimer MACH_TONGA2_TFTTIMER TONGA2_TFTTIMER 3240
+whistler MACH_WHISTLER WHISTLER 3241
+asl_phoenix MACH_ASL_PHOENIX ASL_PHOENIX 3242
+at91sam9263otlite MACH_AT91SAM9263OTLITE AT91SAM9263OTLITE 3243
+ddplug MACH_DDPLUG DDPLUG 3244
+d2plug MACH_D2PLUG D2PLUG 3245
+kzm9d MACH_KZM9D KZM9D 3246
+verdi_lte MACH_VERDI_LTE VERDI_LTE 3247
+nanozoom MACH_NANOZOOM NANOZOOM 3248
+dm3730_som_lv MACH_DM3730_SOM_LV DM3730_SOM_LV 3249
+dm3730_torpedo MACH_DM3730_TORPEDO DM3730_TORPEDO 3250
+anchovy MACH_ANCHOVY ANCHOVY 3251
+linux MACH_LINUX LINUX 3252
+re2rev20 MACH_RE2REV20 RE2REV20 3253
+re2rev21 MACH_RE2REV21 RE2REV21 3254
+cns21xx MACH_CNS21XX CNS21XX 3255
+rider MACH_RIDER RIDER 3257
+nsk330 MACH_NSK330 NSK330 3258
+cns2133evb MACH_CNS2133EVB CNS2133EVB 3259
+z3_816x_mod MACH_Z3_816X_MOD Z3_816X_MOD 3260
+z3_814x_mod MACH_Z3_814X_MOD Z3_814X_MOD 3261
+beect MACH_BEECT BEECT 3262
+dma_thunderbug MACH_DMA_THUNDERBUG DMA_THUNDERBUG 3263
+omn_at91sam9g20 MACH_OMN_AT91SAM9G20 OMN_AT91SAM9G20 3264
+mx25_e2s_uc MACH_MX25_E2S_UC MX25_E2S_UC 3265
+mione MACH_MIONE MIONE 3266
+top9000_tcu MACH_TOP9000_TCU TOP9000_TCU 3267
+top9000_bsl MACH_TOP9000_BSL TOP9000_BSL 3268
+kingdom MACH_KINGDOM KINGDOM 3269
+armadillo460 MACH_ARMADILLO460 ARMADILLO460 3270
+lq2 MACH_LQ2 LQ2 3271
+sweda_tms2 MACH_SWEDA_TMS2 SWEDA_TMS2 3272
+mx53_loco MACH_MX53_LOCO MX53_LOCO 3273
+acer_a7 MACH_MACH_ACER_A7 MACH_ACER_A7 3274
+acer_a8 MACH_ACER_A8 ACER_A8 3275
+acer_gauguin MACH_ACER_GAUGUIN ACER_GAUGUIN 3276
+guppy MACH_GUPPY GUPPY 3277
+mx61_ard MACH_MX61_ARD MX61_ARD 3278
+tx53 MACH_TX53 TX53 3279
+omapl138_case_a3 MACH_OMAPL138_CASE_A3 OMAPL138_CASE_A3 3280
+uemd MACH_UEMD UEMD 3281
+ccwmx51mut MACH_CCWMX51MUT CCWMX51MUT 3282
+rockhopper MACH_ROCKHOPPER ROCKHOPPER 3283
+nookcolor MACH_NOOKCOLOR NOOKCOLOR 3284
+hkdkc100 MACH_HKDKC100 HKDKC100 3285
+ts42xx MACH_TS42XX TS42XX 3286
+aebl MACH_AEBL AEBL 3287
+wario MACH_WARIO WARIO 3288
+gfs_spm MACH_GFS_SPM GFS_SPM 3289
+cm_t3730 MACH_CM_T3730 CM_T3730 3290
+isc3 MACH_ISC3 ISC3 3291
+rascal MACH_RASCAL RASCAL 3292
+hrefv60 MACH_HREFV60 HREFV60 3293
+tpt_2_0 MACH_TPT_2_0 TPT_2_0 3294
+pyramid_td MACH_PYRAMID_TD PYRAMID_TD 3295
+splendor MACH_SPLENDOR SPLENDOR 3296
+guf_planet MACH_GUF_PLANET GUF_PLANET 3297
+msm8x60_qt MACH_MSM8X60_QT MSM8X60_QT 3298
+htc_hd_mini MACH_HTC_HD_MINI HTC_HD_MINI 3299
+athene MACH_ATHENE ATHENE 3300
+deep_r_ek_1 MACH_DEEP_R_EK_1 DEEP_R_EK_1 3301
+vivow_ct MACH_VIVOW_CT VIVOW_CT 3302
+nery_1000 MACH_NERY_1000 NERY_1000 3303
+rfl109145_ssrv MACH_RFL109145_SSRV RFL109145_SSRV 3304
+nmh MACH_NMH NMH 3305
+wn802t MACH_WN802T WN802T 3306
+dragonet MACH_DRAGONET DRAGONET 3307
+geneva_b MACH_GENEVA_B GENEVA_B 3308
+at91sam9263desk16l MACH_AT91SAM9263DESK16L AT91SAM9263DESK16L 3309
+bcmhana_sv MACH_BCMHANA_SV BCMHANA_SV 3310
+bcmhana_tablet MACH_BCMHANA_TABLET BCMHANA_TABLET 3311
+koi MACH_KOI KOI 3312
+ts4800 MACH_TS4800 TS4800 3313
+tqma9263 MACH_TQMA9263 TQMA9263 3314
+holiday MACH_HOLIDAY HOLIDAY 3315
+dma_6410 MACH_DMA6410 DMA6410 3316
+pcats_overlay MACH_PCATS_OVERLAY PCATS_OVERLAY 3317
+hwgw6410 MACH_HWGW6410 HWGW6410 3318
+shenzhou MACH_SHENZHOU SHENZHOU 3319
+cwme9210 MACH_CWME9210 CWME9210 3320
+cwme9210js MACH_CWME9210JS CWME9210JS 3321
+pgs_v1 MACH_PGS_SITARA PGS_SITARA 3322
+colibri_tegra2 MACH_COLIBRI_TEGRA2 COLIBRI_TEGRA2 3323
+w21 MACH_W21 W21 3324
+polysat1 MACH_POLYSAT1 POLYSAT1 3325
+dataway MACH_DATAWAY DATAWAY 3326
+cobral138 MACH_COBRAL138 COBRAL138 3327
+roverpcs8 MACH_ROVERPCS8 ROVERPCS8 3328
+marvelc MACH_MARVELC MARVELC 3329
+navefihid MACH_NAVEFIHID NAVEFIHID 3330
+dm365_cv100 MACH_DM365_CV100 DM365_CV100 3331
+able MACH_ABLE ABLE 3332
+legacy MACH_LEGACY LEGACY 3333
+icong MACH_ICONG ICONG 3334
+rover_g8 MACH_ROVER_G8 ROVER_G8 3335
+t5388p MACH_T5388P T5388P 3336

@ -1,31 +0,0 @@
Upstream doesn't optimize the kernel and bootwrappers for ppc44x because
they still want to support gcc 3.3 -- well, we don't.
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -130,7 +130,8 @@ ifeq ($(CONFIG_FUNCTION_TRACER),y)
KBUILD_CFLAGS += -mno-sched-epilog
endif
-cpu-as-$(CONFIG_4xx) += -Wa,-m405
+cpu-as-$(CONFIG_40x) += -Wa,-m405
+cpu-as-$(CONFIG_44x) += -Wa,-m440
cpu-as-$(CONFIG_6xx) += -Wa,-maltivec
cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec
cpu-as-$(CONFIG_E500) += -Wa,-me500
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -38,10 +38,10 @@ BOOTCFLAGS += -I$(obj) -I$(srctree)/$(ob
DTS_FLAGS ?= -p 1024
$(obj)/4xx.o: BOOTCFLAGS += -mcpu=405
-$(obj)/ebony.o: BOOTCFLAGS += -mcpu=405
+$(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
$(obj)/cuboot-hotfoot.o: BOOTCFLAGS += -mcpu=405
-$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405
-$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
+$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=440
+$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=440
$(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405

@ -1,10 +0,0 @@
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -94,7 +94,6 @@ else
endif
endif
-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
ifeq ($(CONFIG_TUNE_CELL),y)
KBUILD_CFLAGS += $(call cc-option,-mtune=cell)

@ -1,9 +0,0 @@
--- /dev/null
+++ b/include/asm-powerpc/segment.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
+
+/* Only here because we have some old header files that expect it.. */
+
+#endif /* _ASM_SEGMENT_H */

@ -1,331 +0,0 @@
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -53,6 +53,16 @@ config MTD_PARTITIONS
devices. Partitioning on NFTL 'devices' is a different - that's the
'normal' form of partitioning used on a block device.
+config MTD_ROOTFS_ROOT_DEV
+ bool "Automatically set 'rootfs' partition to be root filesystem"
+ depends on MTD_PARTITIONS
+ default y
+
+config MTD_ROOTFS_SPLIT
+ 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
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -29,6 +29,8 @@
#include <linux/kmod.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <linux/root_dev.h>
+#include <linux/magic.h>
#include <linux/err.h>
/* Our partition linked list */
@@ -48,7 +50,7 @@ struct mtd_part {
* the pointer to that structure with this macro.
*/
#define PART(x) ((struct mtd_part *)(x))
-
+#define IS_PART(mtd) (mtd->read == part_read)
/*
* MTD methods which simply translate the effective address and pass through
@@ -618,6 +620,155 @@ int mtd_del_partition(struct mtd_info *m
}
EXPORT_SYMBOL_GPL(mtd_del_partition);
+#ifdef CONFIG_MTD_ROOTFS_SPLIT
+#define ROOTFS_SPLIT_NAME "rootfs_data"
+#define ROOTFS_REMOVED_NAME "<removed>"
+
+struct squashfs_super_block {
+ __le32 s_magic;
+ __le32 pad0[9];
+ __le64 bytes_used;
+};
+
+
+static int split_squashfs(struct mtd_info *master, int offset, int *split_offset)
+{
+ struct squashfs_super_block sb;
+ int len, ret;
+
+ ret = master->read(master, offset, sizeof(sb), &len, (void *) &sb);
+ if (ret || (len != sizeof(sb))) {
+ printk(KERN_ALERT "split_squashfs: error occured while reading "
+ "from \"%s\"\n", master->name);
+ return -EINVAL;
+ }
+
+ if (SQUASHFS_MAGIC != le32_to_cpu(sb.s_magic) ) {
+ printk(KERN_ALERT "split_squashfs: no squashfs found in \"%s\"\n",
+ master->name);
+ *split_offset = 0;
+ return 0;
+ }
+
+ if (le64_to_cpu((sb.bytes_used)) <= 0) {
+ printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n",
+ master->name);
+ *split_offset = 0;
+ return 0;
+ }
+
+ len = (u32) le64_to_cpu(sb.bytes_used);
+ len += (offset & 0x000fffff);
+ len += (master->erasesize - 1);
+ len &= ~(master->erasesize - 1);
+ len -= (offset & 0x000fffff);
+ *split_offset = offset + len;
+
+ return 0;
+}
+
+static int split_rootfs_data(struct mtd_info *master, struct mtd_info *rpart, const struct mtd_partition *part)
+{
+ struct mtd_partition *dpart;
+ struct mtd_part *slave = NULL;
+ struct mtd_part *spart;
+ int ret, split_offset = 0;
+
+ spart = PART(rpart);
+ ret = split_squashfs(master, spart->offset, &split_offset);
+ if (ret)
+ return ret;
+
+ if (split_offset <= 0)
+ return 0;
+
+ dpart = kmalloc(sizeof(*part)+sizeof(ROOTFS_SPLIT_NAME)+1, GFP_KERNEL);
+ if (dpart == NULL) {
+ printk(KERN_INFO "split_squashfs: no memory for partition \"%s\"\n",
+ ROOTFS_SPLIT_NAME);
+ return -ENOMEM;
+ }
+
+ memcpy(dpart, part, sizeof(*part));
+ strcpy((char *)&dpart[1], ROOTFS_SPLIT_NAME);
+ dpart->name = (unsigned char *)&dpart[1];
+
+ dpart->size = rpart->size - (split_offset - spart->offset);
+ dpart->offset = split_offset;
+
+ if (dpart == NULL)
+ return 1;
+
+ printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=%llX, len=%llX \n",
+ ROOTFS_SPLIT_NAME, dpart->offset, dpart->size);
+
+ slave = allocate_partition(master, dpart, 0, split_offset);
+ if (IS_ERR(slave))
+ return PTR_ERR(slave);
+ mutex_lock(&mtd_partitions_mutex);
+ list_add(&slave->list, &mtd_partitions);
+ mutex_unlock(&mtd_partitions_mutex);
+
+ add_mtd_device(&slave->mtd);
+
+ rpart->split = &slave->mtd;
+
+ return 0;
+}
+
+static int refresh_rootfs_split(struct mtd_info *mtd)
+{
+ struct mtd_partition tpart;
+ struct mtd_part *part;
+ char *name;
+ //int index = 0;
+ int offset, size;
+ int ret;
+
+ part = PART(mtd);
+
+ /* check for the new squashfs offset first */
+ ret = split_squashfs(part->master, part->offset, &offset);
+ if (ret)
+ return ret;
+
+ if ((offset > 0) && !mtd->split) {
+ printk(KERN_INFO "%s: creating new split partition for \"%s\"\n", __func__, mtd->name);
+ /* if we don't have a rootfs split partition, create a new one */
+ tpart.name = (char *) mtd->name;
+ tpart.size = mtd->size;
+ tpart.offset = part->offset;
+
+ return split_rootfs_data(part->master, &part->mtd, &tpart);
+ } else if ((offset > 0) && mtd->split) {
+ /* update the offsets of the existing partition */
+ size = mtd->size + part->offset - offset;
+
+ part = PART(mtd->split);
+ part->offset = offset;
+ part->mtd.size = size;
+ printk(KERN_INFO "%s: %s partition \"" ROOTFS_SPLIT_NAME "\", offset: 0x%06x (0x%06x)\n",
+ __func__, (!strcmp(part->mtd.name, ROOTFS_SPLIT_NAME) ? "updating" : "creating"),
+ (u32) part->offset, (u32) part->mtd.size);
+ name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL);
+ strcpy(name, ROOTFS_SPLIT_NAME);
+ part->mtd.name = name;
+ } else if ((offset <= 0) && mtd->split) {
+ printk(KERN_INFO "%s: removing partition \"%s\"\n", __func__, mtd->split->name);
+
+ /* mark existing partition as removed */
+ part = PART(mtd->split);
+ name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL);
+ strcpy(name, ROOTFS_REMOVED_NAME);
+ part->mtd.name = name;
+ part->offset = 0;
+ part->mtd.size = 0;
+ }
+
+ return 0;
+}
+#endif /* CONFIG_MTD_ROOTFS_SPLIT */
+
/*
* 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
@@ -633,7 +784,7 @@ int add_mtd_partitions(struct mtd_info *
{
struct mtd_part *slave;
uint64_t cur_offset = 0;
- int i;
+ int i, ret;
printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
@@ -648,6 +799,21 @@ int add_mtd_partitions(struct mtd_info *
add_mtd_device(&slave->mtd);
+ if (!strcmp(parts[i].name, "rootfs")) {
+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
+ if (ROOT_DEV == 0) {
+ printk(KERN_NOTICE "mtd: partition \"rootfs\" "
+ "set to be root filesystem\n");
+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, slave->mtd.index);
+ }
+#endif
+#ifdef CONFIG_MTD_ROOTFS_SPLIT
+ ret = split_rootfs_data(master, &slave->mtd, &parts[i]);
+ /* if (ret == 0)
+ * j++; */
+#endif
+ }
+
cur_offset = slave->offset + slave->mtd.size;
}
@@ -655,6 +821,32 @@ int add_mtd_partitions(struct mtd_info *
}
EXPORT_SYMBOL(add_mtd_partitions);
+int refresh_mtd_partitions(struct mtd_info *mtd)
+{
+ int ret = 0;
+
+ if (IS_PART(mtd)) {
+ struct mtd_part *part;
+ struct mtd_info *master;
+
+ part = PART(mtd);
+ master = part->master;
+ if (master->refresh_device)
+ ret = master->refresh_device(master);
+ }
+
+ if (!ret && mtd->refresh_device)
+ ret = mtd->refresh_device(mtd);
+
+#ifdef CONFIG_MTD_ROOTFS_SPLIT
+ if (!ret && IS_PART(mtd) && !strcmp(mtd->name, "rootfs"))
+ refresh_rootfs_split(mtd);
+#endif
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(refresh_mtd_partitions);
+
static DEFINE_SPINLOCK(part_parser_lock);
static LIST_HEAD(part_parsers);
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -956,6 +956,13 @@ static int mtd_ioctl(struct file *file,
break;
}
#endif
+#ifdef CONFIG_MTD_PARTITIONS
+ case MTDREFRESH:
+ {
+ ret = refresh_mtd_partitions(mtd);
+ break;
+ }
+#endif
default:
ret = -ENOTTY;
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -125,6 +125,7 @@ struct nand_ecclayout {
struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
};
+struct mtd_info;
struct mtd_info {
u_char type;
uint32_t flags;
@@ -266,6 +267,9 @@ struct mtd_info {
struct device dev;
int usecount;
+ int (*refresh_device)(struct mtd_info *mtd);
+ struct mtd_info *split;
+
/* If the driver is something smart, like UBI, it may need to maintain
* its own reference counting. The below functions are only for driver.
* The driver may register its callbacks. These callbacks are not
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -34,12 +34,14 @@
* erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
*/
+struct mtd_partition;
struct mtd_partition {
- char *name; /* identifier string */
+ const char *name; /* identifier string */
uint64_t size; /* partition size */
uint64_t offset; /* offset within the master MTD space */
uint32_t mask_flags; /* master MTD flags to mask out for this partition */
struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only) */
+ int (*refresh_partition)(struct mtd_info *);
};
#define MTDPART_OFS_NXTBLK (-2)
@@ -51,6 +53,7 @@ struct mtd_info;
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
int del_mtd_partitions(struct mtd_info *);
+int refresh_mtd_partitions(struct mtd_info *);
/*
* Functions dealing with the various ways of partitioning the space
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -127,6 +127,7 @@ struct otp_info {
#define MEMWRITEOOB64 _IOWR('M', 21, struct mtd_oob_buf64)
#define MEMREADOOB64 _IOWR('M', 22, struct mtd_oob_buf64)
#define MEMISLOCKED _IOR('M', 23, struct erase_info_user)
+#define MTDREFRESH _IO('M', 50)
/*
* Obsolete legacy interface. Keep it in order not to break userspace

@ -1,146 +0,0 @@
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -33,6 +33,8 @@
#include <linux/magic.h>
#include <linux/err.h>
+#define MTD_ERASE_PARTIAL 0x8000 /* partition only covers parts of an erase block */
+
/* Our partition linked list */
static LIST_HEAD(mtd_partitions);
static DEFINE_MUTEX(mtd_partitions_mutex);
@@ -239,13 +241,60 @@ static int part_erase(struct mtd_info *m
return -EROFS;
if (instr->addr >= mtd->size)
return -EINVAL;
+
+ instr->partial_start = false;
+ if (mtd->flags & MTD_ERASE_PARTIAL) {
+ size_t readlen = 0;
+ u64 mtd_ofs;
+
+ instr->erase_buf = kmalloc(part->master->erasesize, GFP_ATOMIC);
+ if (!instr->erase_buf)
+ return -ENOMEM;
+
+ mtd_ofs = part->offset + instr->addr;
+ instr->erase_buf_ofs = do_div(mtd_ofs, part->master->erasesize);
+
+ if (instr->erase_buf_ofs > 0) {
+ instr->addr -= instr->erase_buf_ofs;
+ ret = part->master->read(part->master,
+ instr->addr + part->offset,
+ part->master->erasesize,
+ &readlen, instr->erase_buf);
+
+ instr->partial_start = true;
+ } else {
+ mtd_ofs = part->offset + part->mtd.size;
+ instr->erase_buf_ofs = part->master->erasesize -
+ do_div(mtd_ofs, part->master->erasesize);
+
+ if (instr->erase_buf_ofs > 0) {
+ instr->len += instr->erase_buf_ofs;
+ ret = part->master->read(part->master,
+ part->offset + instr->addr +
+ instr->len - part->master->erasesize,
+ part->master->erasesize, &readlen,
+ instr->erase_buf);
+ } else {
+ ret = 0;
+ }
+ }
+ if (ret < 0) {
+ kfree(instr->erase_buf);
+ return ret;
+ }
+
+ }
+
instr->addr += part->offset;
ret = part->master->erase(part->master, instr);
if (ret) {
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
instr->fail_addr -= part->offset;
instr->addr -= part->offset;
+ if (mtd->flags & MTD_ERASE_PARTIAL)
+ kfree(instr->erase_buf);
}
+
return ret;
}
@@ -253,7 +302,25 @@ void mtd_erase_callback(struct erase_inf
{
if (instr->mtd->erase == part_erase) {
struct mtd_part *part = PART(instr->mtd);
+ size_t wrlen = 0;
+ if (instr->mtd->flags & MTD_ERASE_PARTIAL) {
+ if (instr->partial_start) {
+ part->master->write(part->master,
+ instr->addr, instr->erase_buf_ofs,
+ &wrlen, instr->erase_buf);
+ instr->addr += instr->erase_buf_ofs;
+ } else {
+ instr->len -= instr->erase_buf_ofs;
+ part->master->write(part->master,
+ instr->addr + instr->len,
+ instr->erase_buf_ofs, &wrlen,
+ instr->erase_buf +
+ part->master->erasesize -
+ instr->erase_buf_ofs);
+ }
+ kfree(instr->erase_buf);
+ }
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
instr->fail_addr -= part->offset;
instr->addr -= part->offset;
@@ -511,18 +578,24 @@ static struct mtd_part *allocate_partiti
if ((slave->mtd.flags & MTD_WRITEABLE) &&
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
/* 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(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
- part->name);
+ slave->mtd.flags |= MTD_ERASE_PARTIAL;
+ if (((u32) slave->mtd.size) > master->erasesize)
+ slave->mtd.flags &= ~MTD_WRITEABLE;
+ else
+ slave->mtd.erasesize = slave->mtd.size;
}
if ((slave->mtd.flags & MTD_WRITEABLE) &&
- mtd_mod_by_eb(slave->mtd.size, &slave->mtd)) {
- slave->mtd.flags &= ~MTD_WRITEABLE;
- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
- part->name);
- }
+ mtd_mod_by_eb(slave->offset + slave->mtd.size, &slave->mtd)) {
+ slave->mtd.flags |= MTD_ERASE_PARTIAL;
+
+ if ((u32) slave->mtd.size > master->erasesize)
+ slave->mtd.flags &= ~MTD_WRITEABLE;
+ else
+ slave->mtd.erasesize = slave->mtd.size;
+ }
+ if ((slave->mtd.flags & (MTD_ERASE_PARTIAL|MTD_WRITEABLE)) == MTD_ERASE_PARTIAL)
+ printk(KERN_WARNING"mtd: partition \"%s\" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only\n",
+ part->name);
slave->mtd.ecclayout = master->ecclayout;
if (master->block_isbad) {
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -57,6 +57,10 @@ struct erase_info {
u_long priv;
u_char state;
struct erase_info *next;
+
+ u8 *erase_buf;
+ u32 erase_buf_ofs;
+ bool partial_start;
};
struct mtd_erase_region_info {

@ -1,18 +0,0 @@
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -33,6 +33,7 @@
* Note: writeable partitions require their size and offset be
* erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
*/
+struct mtd_info;
struct mtd_partition;
struct mtd_partition {
@@ -49,7 +50,6 @@ struct mtd_partition {
#define MTDPART_SIZ_FULL (0)
-struct mtd_info;
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
int del_mtd_partitions(struct mtd_info *);

@ -1,30 +0,0 @@
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -267,14 +267,21 @@ static int parse_redboot_partitions(stru
#endif
names += strlen(names)+1;
-#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) {
- i++;
- parts[i].offset = parts[i-1].size + parts[i-1].offset;
- parts[i].size = fl->next->img->flash_base - parts[i].offset;
- parts[i].name = nullname;
- }
+ if (!strcmp(parts[i].name, "rootfs")) {
+ parts[i].size = fl->next->img->flash_base;
+ parts[i].size &= ~(master->erasesize - 1);
+ parts[i].size -= parts[i].offset;
+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
+ nrparts--;
+ } else {
+ i++;
+ parts[i].offset = parts[i-1].size + parts[i-1].offset;
+ parts[i].size = fl->next->img->flash_base - parts[i].offset;
+ parts[i].name = nullname;
#endif
+ }
+ }
tmp_fl = fl;
fl = fl->next;
kfree(tmp_fl);

@ -1,60 +0,0 @@
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -29,6 +29,8 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#define BOARD_CONFIG_PART "boardconfig"
+
struct fis_image_desc {
unsigned char name[16]; // Null terminated name
uint32_t flash_base; // Address within FLASH of image
@@ -59,6 +61,7 @@ static int parse_redboot_partitions(stru
struct mtd_partition **pparts,
unsigned long fis_origin)
{
+ unsigned long max_offset = 0;
int nrparts = 0;
struct fis_image_desc *buf;
struct mtd_partition *parts;
@@ -227,14 +230,14 @@ static int parse_redboot_partitions(stru
}
}
#endif
- parts = kzalloc(sizeof(*parts)*nrparts + nulllen + namelen, GFP_KERNEL);
+ parts = kzalloc(sizeof(*parts) * (nrparts + 1) + nulllen + namelen + sizeof(BOARD_CONFIG_PART), GFP_KERNEL);
if (!parts) {
ret = -ENOMEM;
goto out;
}
- nullname = (char *)&parts[nrparts];
+ nullname = (char *)&parts[nrparts + 1];
#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
if (nulllen > 0) {
strcpy(nullname, nullstring);
@@ -253,6 +256,8 @@ static int parse_redboot_partitions(stru
}
#endif
for ( ; i<nrparts; i++) {
+ if(max_offset < buf[i].flash_base + buf[i].size)
+ max_offset = buf[i].flash_base + buf[i].size;
parts[i].size = fl->img->size;
parts[i].offset = fl->img->flash_base;
parts[i].name = names;
@@ -286,6 +291,14 @@ static int parse_redboot_partitions(stru
fl = fl->next;
kfree(tmp_fl);
}
+ if(master->size - max_offset >= master->erasesize)
+ {
+ parts[nrparts].size = master->size - max_offset;
+ parts[nrparts].offset = max_offset;
+ parts[nrparts].name = names;
+ strcpy(names, BOARD_CONFIG_PART);
+ nrparts++;
+ }
ret = nrparts;
*pparts = parts;
out:

@ -1,35 +0,0 @@
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -181,6 +181,22 @@ config MTD_AR7_PARTS
---help---
TI AR7 partitioning support
+config MTD_MYLOADER_PARTS
+ tristate "MyLoader partition parsing"
+ depends on MTD_PARTITIONS && (ADM5120 || ATHEROS_AR231X || ATHEROS_AR71XX)
+ ---help---
+ MyLoader is a bootloader which allows the user to define partitions
+ in flash devices, by putting a table in the second erase block
+ on the device, similar to a partition table. This table gives the
+ offsets and lengths of the user defined partitions.
+
+ If you need code which can detect and parse these tables, and
+ register MTD 'partitions' corresponding to each image detected,
+ enable this option.
+
+ You will still need the parsing functions to be called by the driver
+ for your particular device. It won't happen automatically.
+
comment "User Modules And Translation Layers"
config MTD_CHAR
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdli
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
# 'Users' - code which presents functionality to userspace.
obj-$(CONFIG_MTD_CHAR) += mtdchar.o

@ -1,115 +0,0 @@
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -14,6 +14,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>
@@ -232,10 +233,11 @@ static void block2mtd_free_device(struct
/* 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, const char *mtdname)
{
struct block_device *bdev;
struct block2mtd_dev *dev;
+ struct mtd_partition *part;
char *name;
if (!devname)
@@ -275,13 +277,16 @@ static struct block2mtd_dev *add_device(
/* Setup the MTD structure */
/* make the name contain the block device in */
- name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname);
+ if (!mtdname)
+ mtdname = devname;
+ name = kmalloc(strlen(mtdname) + 1, GFP_KERNEL);
if (!name)
goto devinit_err;
+ strcpy(name, mtdname);
dev->mtd.name = name;
- 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;
@@ -294,14 +299,17 @@ static struct block2mtd_dev *add_device(
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("block2mtd: "),
- dev->mtd.erasesize >> 10, dev->mtd.erasesize);
+ mtdname, dev->mtd.erasesize >> 10, dev->mtd.erasesize);
return dev;
devinit_err:
@@ -374,9 +382,9 @@ static char block2mtd_paramline[80 + 12]
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;
@@ -387,7 +395,7 @@ static int block2mtd_setup2(const char *
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)
@@ -406,8 +414,10 @@ static int block2mtd_setup2(const char *
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;
}
@@ -441,7 +451,7 @@ static int block2mtd_setup(const char *v
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)
{
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -715,6 +715,7 @@ rescan:
kfree(state);
return 0;
}
+EXPORT_SYMBOL(rescan_partitions);
unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p)
{

@ -1,292 +0,0 @@
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -30,6 +30,8 @@ struct block2mtd_dev {
struct block_device *blkdev;
struct mtd_info mtd;
struct mutex write_mutex;
+ rwlock_t bdev_mutex;
+ char devname[0];
};
@@ -82,6 +84,12 @@ static int block2mtd_erase(struct mtd_in
size_t len = instr->len;
int err;
+ read_lock(&dev->bdev_mutex);
+ if (!dev->blkdev) {
+ err = -EINVAL;
+ goto done;
+ }
+
instr->state = MTD_ERASING;
mutex_lock(&dev->write_mutex);
err = _block2mtd_erase(dev, from, len);
@@ -93,6 +101,10 @@ static int block2mtd_erase(struct mtd_in
instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr);
+
+done:
+ read_unlock(&dev->bdev_mutex);
+
return err;
}
@@ -104,10 +116,14 @@ static int block2mtd_read(struct mtd_inf
struct page *page;
int index = from >> PAGE_SHIFT;
int offset = from & (PAGE_SIZE-1);
- int cpylen;
+ int cpylen, err = 0;
+
+ read_lock(&dev->bdev_mutex);
+ if (!dev->blkdev || (from > mtd->size)) {
+ err = -EINVAL;
+ goto done;
+ }
- if (from > mtd->size)
- return -EINVAL;
if (from + len > mtd->size)
len = mtd->size - from;
@@ -122,10 +138,14 @@ static int block2mtd_read(struct mtd_inf
len = len - cpylen;
page = page_read(dev->blkdev->bd_inode->i_mapping, index);
- if (!page)
- return -ENOMEM;
- if (IS_ERR(page))
- return PTR_ERR(page);
+ if (!page) {
+ err = -ENOMEM;
+ goto done;
+ }
+ if (IS_ERR(page)) {
+ err = PTR_ERR(page);
+ goto done;
+ }
memcpy(buf, page_address(page) + offset, cpylen);
page_cache_release(page);
@@ -136,7 +156,10 @@ static int block2mtd_read(struct mtd_inf
offset = 0;
index++;
}
- return 0;
+
+done:
+ read_unlock(&dev->bdev_mutex);
+ return err;
}
@@ -188,12 +211,22 @@ static int block2mtd_write(struct mtd_in
size_t *retlen, const u_char *buf)
{
struct block2mtd_dev *dev = mtd->priv;
- int err;
+ int err = 0;
+
+ read_lock(&dev->bdev_mutex);
+ if (!dev->blkdev) {
+ err = -EINVAL;
+ goto done;
+ }
if (!len)
- return 0;
- if (to >= mtd->size)
- return -ENOSPC;
+ goto done;
+
+ if (to >= mtd->size) {
+ err = -ENOSPC;
+ goto done;
+ }
+
if (to + len > mtd->size)
len = mtd->size - to;
@@ -202,6 +235,9 @@ static int block2mtd_write(struct mtd_in
mutex_unlock(&dev->write_mutex);
if (err > 0)
err = 0;
+
+done:
+ read_unlock(&dev->bdev_mutex);
return err;
}
@@ -210,52 +246,29 @@ static int block2mtd_write(struct mtd_in
static void block2mtd_sync(struct mtd_info *mtd)
{
struct block2mtd_dev *dev = mtd->priv;
- sync_blockdev(dev->blkdev);
- return;
-}
-
-
-static void block2mtd_free_device(struct block2mtd_dev *dev)
-{
- if (!dev)
- return;
-
- kfree(dev->mtd.name);
- if (dev->blkdev) {
- invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
- 0, -1);
- close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE);
- }
+ read_lock(&dev->bdev_mutex);
+ if (dev->blkdev)
+ sync_blockdev(dev->blkdev);
+ read_unlock(&dev->bdev_mutex);
- kfree(dev);
+ return;
}
-/* FIXME: ensure that mtd->size % erase_size == 0 */
-static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname)
+static int _open_bdev(struct block2mtd_dev *dev)
{
struct block_device *bdev;
- struct block2mtd_dev *dev;
- struct mtd_partition *part;
- char *name;
-
- if (!devname)
- return NULL;
-
- dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
- if (!dev)
- return NULL;
/* Get a handle on the device */
- bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, NULL);
+ bdev = open_bdev_exclusive(dev->devname, FMODE_READ|FMODE_WRITE, NULL);
#ifndef MODULE
if (IS_ERR(bdev)) {
/* We might not have rootfs mounted at this point. Try
to resolve the device name by other means. */
- dev_t devt = name_to_dev_t(devname);
+ dev_t devt = name_to_dev_t(dev->devname);
if (devt) {
bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ);
}
@@ -263,17 +276,98 @@ static struct block2mtd_dev *add_device(
#endif
if (IS_ERR(bdev)) {
- ERROR("error: cannot open device %s", devname);
- goto devinit_err;
+ ERROR("error: cannot open device %s", dev->devname);
+ return 1;
}
dev->blkdev = bdev;
if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
ERROR("attempting to use an MTD device as a block device");
- goto devinit_err;
+ return 1;
}
+ return 0;
+}
+
+static void _close_bdev(struct block2mtd_dev *dev)
+{
+ struct block_device *bdev;
+
+ if (!dev->blkdev)
+ return;
+
+ bdev = dev->blkdev;
+ invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 0, -1);
+ close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE);
+ dev->blkdev = NULL;
+}
+
+static void block2mtd_free_device(struct block2mtd_dev *dev)
+{
+ if (!dev)
+ return;
+
+ kfree(dev->mtd.name);
+ _close_bdev(dev);
+ kfree(dev);
+}
+
+
+static int block2mtd_refresh(struct mtd_info *mtd)
+{
+ struct block2mtd_dev *dev = mtd->priv;
+ struct block_device *bdev;
+ dev_t devt;
+ int err = 0;
+
+ /* no other mtd function can run at this point */
+ write_lock(&dev->bdev_mutex);
+
+ /* get the device number for the whole disk */
+ devt = MKDEV(MAJOR(dev->blkdev->bd_dev), 0);
+
+ /* close the old block device */
+ _close_bdev(dev);
+
+ /* open the whole disk, issue a partition rescan, then */
+ bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ);
+ if (!bdev || !bdev->bd_disk)
+ err = -EINVAL;
+#ifndef CONFIG_MTD_BLOCK2MTD_MODULE
+ else
+ err = rescan_partitions(bdev->bd_disk, bdev);
+#endif
+ if (bdev)
+ close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE);
+
+ /* try to open the partition block device again */
+ _open_bdev(dev);
+ write_unlock(&dev->bdev_mutex);
+
+ return err;
+}
+
+/* FIXME: ensure that mtd->size % erase_size == 0 */
+static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname)
+{
+ struct block2mtd_dev *dev;
+ struct mtd_partition *part;
+ char *name;
+
+ if (!devname)
+ return NULL;
+
+ dev = kzalloc(sizeof(struct block2mtd_dev) + strlen(devname) + 1, GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ strcpy(dev->devname, devname);
+
+ if (_open_bdev(dev))
+ goto devinit_err;
+
mutex_init(&dev->write_mutex);
+ rwlock_init(&dev->bdev_mutex);
/* Setup the MTD structure */
/* make the name contain the block device in */
@@ -298,6 +392,7 @@ static struct block2mtd_dev *add_device(
dev->mtd.read = block2mtd_read;
dev->mtd.priv = dev;
dev->mtd.owner = THIS_MODULE;
+ dev->mtd.refresh_device = block2mtd_refresh;
part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
part->name = dev->mtd.name;

@ -1,17 +0,0 @@
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -264,11 +264,13 @@ static int _open_bdev(struct block2mtd_d
bdev = open_bdev_exclusive(dev->devname, FMODE_READ|FMODE_WRITE, NULL);
#ifndef MODULE
if (IS_ERR(bdev)) {
+ dev_t devt;
/* We might not have rootfs mounted at this point. Try
to resolve the device name by other means. */
- dev_t devt = name_to_dev_t(dev->devname);
+ wait_for_device_probe();
+ devt = name_to_dev_t(dev->devname);
if (devt) {
bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ);
}

@ -1,37 +0,0 @@
---
drivers/mtd/nand/plat_nand.c | 13 ++++++++++++-
include/linux/mtd/nand.h | 1 +
2 files changed, 13 insertions(+), 1 deletion(-)
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -620,6 +620,7 @@ struct platform_nand_chip {
int chip_delay;
unsigned int options;
const char **part_probe_types;
+ int (*chip_fixup)(struct mtd_info *mtd);
void (*set_parts)(uint64_t size, struct platform_nand_chip *chip);
void *priv;
};
--- a/drivers/mtd/nand/plat_nand.c
+++ b/drivers/mtd/nand/plat_nand.c
@@ -96,7 +96,18 @@ static int __devinit plat_nand_probe(str
}
/* Scan to find existance of the device */
- if (nand_scan(&data->mtd, pdata->chip.nr_chips)) {
+ if (nand_scan_ident(&data->mtd, pdata->chip.nr_chips, NULL)) {
+ res = -ENXIO;
+ goto out;
+ }
+
+ if (pdata->chip.chip_fixup) {
+ res = pdata->chip.chip_fixup(&data->mtd);
+ if (res)
+ goto out;
+ }
+
+ if (nand_scan_tail(&data->mtd)) {
err = -ENXIO;
goto out;
}

@ -1,12 +0,0 @@
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -507,8 +507,7 @@ int __nand_correct_data(unsigned char *b
if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
return 1; /* error in ecc data; no action needed */
- printk(KERN_ERR "uncorrectable error : ");
- return -1;
+ return -EBADMSG;
}
EXPORT_SYMBOL(__nand_correct_data);

@ -1,15 +0,0 @@
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -446,9 +446,9 @@ struct mtd_info *cfi_cmdset_0002(struct
/*
* Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4
- * see: http://cs.ozerki.net/zap/pub/axim-x5/docs/cfi_r20.pdf, page 19
- * http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf
- * http://www.spansion.com/Support/Datasheets/s29ws-p_00_a12_e.pdf
+ * see: Spec 1.3 http://cs.ozerki.net/zap/pub/axim-x5/docs/cfi_r20.pdf, page 19
+ * http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf
+ * Spec 1.4 http://www.spansion.com/Support/AppNotes/CFI_Spec_AN_03.pdf, page 9
*/
if (extp->MajorVersion != '1' ||
(extp->MajorVersion == '1' && (extp->MinorVersion < '0' || extp->MinorVersion > '4'))) {

@ -1,39 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -43,6 +43,7 @@
#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
#define OPCODE_BE_32K 0x52 /* Erase 32KiB block */
#define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */
+#define OPCODE_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips*/
#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
#define OPCODE_RDID 0x9f /* Read JEDEC ID */
@@ -598,6 +599,7 @@ struct flash_info {
u16 flags;
#define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */
#define M25P_NO_ERASE 0x02 /* No erase command needed */
+#define SECT_4K_PMC 0x04 /* OPCODE_BE_4K_PMC works uniformly */
};
#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
@@ -654,6 +656,10 @@ static const struct spi_device_id m25p_i
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
+ /* PMC -- pm25x "blocks" are 32K, sectors are 4K */
+ { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
+ { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) },
+
/* Spansion -- single (large) sector size only, at least
* for the chips listed here (without boot sectors).
*/
@@ -873,6 +879,9 @@ static int __devinit m25p_probe(struct s
if (info->flags & SECT_4K) {
flash->erase_opcode = OPCODE_BE_4K;
flash->mtd.erasesize = 4096;
+ } else if (info->flags & SECT_4K_PMC) {
+ flash->erase_opcode = OPCODE_BE_4K_PMC;
+ flash->mtd.erasesize = 4096;
} else {
flash->erase_opcode = OPCODE_SE;
flash->mtd.erasesize = info->sector_size;

@ -1,12 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -639,7 +639,8 @@ static const struct spi_device_id m25p_i
{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
{ "at26df321", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) },
- /* EON -- en25pxx */
+ /* EON -- en25xxx */
+ { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) },
{ "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) },
{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },

@ -1,20 +0,0 @@
From da9c4c174ad5086e5ccff23a5ffd1f9750b77c85 Mon Sep 17 00:00:00 2001
From: Gabor Juhos <juhosg@openwrt.org>
Date: Thu, 24 Mar 2011 21:43:48 +0100
Subject: [PATCH] mtd: m25p80: add support for the MX25L1606E chip
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
drivers/mtd/devices/m25p80.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -652,6 +652,7 @@ static const struct spi_device_id m25p_i
/* Macronix */
{ "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) },
{ "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) },
+ { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) },
{ "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) },
{ "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) },
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },

@ -1,41 +0,0 @@
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -392,9 +392,35 @@ static struct cfi_fixup fixup_table[] =
static void cfi_fixup_major_minor(struct cfi_private *cfi,
struct cfi_pri_amdstd *extp)
{
- if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e &&
- extp->MajorVersion == '0')
- extp->MajorVersion = '1';
+ /* Manufacturers are defined in include/linux/mtd/cfi.h */
+
+ if (cfi->mfr == CFI_MFR_SAMSUNG &&
+ extp->MajorVersion == '0') {
+ printk(" Fixed Samsung's Amd/Fujitsu Extended Query version from %c.%c",
+ extp->MajorVersion, extp->MinorVersion);
+
+ extp->MajorVersion = '1';
+ extp->MinorVersion = '0';
+
+ printk(" to %c.%c.\n",
+ extp->MajorVersion, extp->MinorVersion);
+ }
+
+ if (cfi->mfr == CFI_MFR_SAMSUNG &&
+ extp->MajorVersion == '3' && extp->MinorVersion == '3') {
+ printk(KERN_NOTICE " Newer Samsung flash detected, "
+ "should be compatible with Amd/Fujitsu.\n");
+
+ printk(" Fixed Samsung's Amd/Fujitsu Extended Query version from %c.%c",
+ extp->MajorVersion, extp->MinorVersion);
+
+ extp->MajorVersion = '1'; // set to 1.3
+ extp->MinorVersion = '3';
+
+ printk(" to %c.%c.\n",
+ extp->MajorVersion, extp->MinorVersion);
+ }
+
/*
* SST 38VF640x chips report major=0xFF / minor=0xFF.
*/

@ -1,10 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -726,6 +726,7 @@ static const struct spi_device_id m25p_i
{ "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
+ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
/* Catalyst / On Semiconductor -- non-JEDEC */
{ "cat25c11", CAT25_INFO( 16, 8, 16, 1) },

@ -1,12 +0,0 @@
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -619,7 +619,8 @@ static void concat_sync(struct mtd_info
for (i = 0; i < concat->num_subdev; i++) {
struct mtd_info *subdev = concat->subdev[i];
- subdev->sync(subdev);
+ if (subdev->sync)
+ subdev->sync(subdev);
}
}

@ -1,18 +0,0 @@
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -44,6 +44,7 @@ source "fs/gfs2/Kconfig"
source "fs/ocfs2/Kconfig"
source "fs/btrfs/Kconfig"
source "fs/nilfs2/Kconfig"
+source "fs/yaffs2/Kconfig"
endif # BLOCK
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -122,3 +122,5 @@ obj-$(CONFIG_BTRFS_FS) += btrfs/
obj-$(CONFIG_GFS2_FS) += gfs2/
obj-$(CONFIG_EXOFS_FS) += exofs/
obj-$(CONFIG_CEPH_FS) += ceph/
+obj-$(CONFIG_YAFFS_FS) += yaffs2/
+

@ -1,17 +0,0 @@
--- a/fs/yaffs2/yaffs_guts.c
+++ b/fs/yaffs2/yaffs_guts.c
@@ -1709,11 +1709,11 @@ static int yaffs_change_obj_name(yaffs_o
}
/* TODO: Do we need this different handling for YAFFS2 and YAFFS1?? */
- if (obj->my_dev->param.is_yaffs2)
+ // if (obj->my_dev->param.is_yaffs2)
unlinkOp = (new_dir == obj->my_dev->unlinked_dir);
- else
+ /* else
unlinkOp = (new_dir == obj->my_dev->unlinked_dir
- && obj->variant_type == YAFFS_OBJECT_TYPE_FILE);
+ && obj->variant_type == YAFFS_OBJECT_TYPE_FILE); */
deleteOp = (new_dir == obj->my_dev->del_dir);

@ -1,20 +0,0 @@
--- a/fs/yaffs2/yaffs_vfs_glue.c
+++ b/fs/yaffs2/yaffs_vfs_glue.c
@@ -3036,7 +3036,7 @@ static struct super_block *yaffs_interna
YINIT_LIST_HEAD(&(yaffs_dev_to_lc(dev)->searchContexts));
param->remove_obj_fn = yaffs_remove_obj_callback;
- init_MUTEX(&(yaffs_dev_to_lc(dev)->grossLock));
+ sema_init(&(yaffs_dev_to_lc(dev)->grossLock), 1);
yaffs_gross_lock(dev);
@@ -3494,7 +3494,7 @@ static int __init init_yaffs_fs(void)
- init_MUTEX(&yaffs_context_lock);
+ sema_init((&yaffs_context_lock), 1);
/* Install the proc_fs entries */
my_proc_entry = create_proc_entry("yaffs",

@ -1,485 +0,0 @@
--- a/include/linux/lzma/LzmaDec.h
+++ b/include/linux/lzma/LzmaDec.h
@@ -31,14 +31,6 @@ typedef struct _CLzmaProps
UInt32 dicSize;
} CLzmaProps;
-/* LzmaProps_Decode - decodes properties
-Returns:
- SZ_OK
- SZ_ERROR_UNSUPPORTED - Unsupported properties
-*/
-
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
-
/* ---------- LZMA Decoder state ---------- */
@@ -70,8 +62,6 @@ typedef struct
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
-void LzmaDec_Init(CLzmaDec *p);
-
/* There are two types of LZMA streams:
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
@@ -108,97 +98,6 @@ typedef enum
/* ELzmaStatus is used only as output value for function call */
-
-/* ---------- Interfaces ---------- */
-
-/* There are 3 levels of interfaces:
- 1) Dictionary Interface
- 2) Buffer Interface
- 3) One Call Interface
- You can select any of these interfaces, but don't mix functions from different
- groups for same object. */
-
-
-/* There are two variants to allocate state for Dictionary Interface:
- 1) LzmaDec_Allocate / LzmaDec_Free
- 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
- You can use variant 2, if you set dictionary buffer manually.
- For Buffer Interface you must always use variant 1.
-
-LzmaDec_Allocate* can return:
- SZ_OK
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_UNSUPPORTED - Unsupported properties
-*/
-
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
-
-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
-
-/* ---------- Dictionary Interface ---------- */
-
-/* You can use it, if you want to eliminate the overhead for data copying from
- dictionary to some other external buffer.
- You must work with CLzmaDec variables directly in this interface.
-
- STEPS:
- LzmaDec_Constr()
- LzmaDec_Allocate()
- for (each new stream)
- {
- LzmaDec_Init()
- while (it needs more decompression)
- {
- LzmaDec_DecodeToDic()
- use data from CLzmaDec::dic and update CLzmaDec::dicPos
- }
- }
- LzmaDec_Free()
-*/
-
-/* LzmaDec_DecodeToDic
-
- The decoding to internal dictionary buffer (CLzmaDec::dic).
- You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
-
-finishMode:
- It has meaning only if the decoding reaches output limit (dicLimit).
- LZMA_FINISH_ANY - Decode just dicLimit bytes.
- LZMA_FINISH_END - Stream must be finished after dicLimit.
-
-Returns:
- SZ_OK
- status:
- LZMA_STATUS_FINISHED_WITH_MARK
- LZMA_STATUS_NOT_FINISHED
- LZMA_STATUS_NEEDS_MORE_INPUT
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
- SZ_ERROR_DATA - Data error
-*/
-
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-
-
-/* ---------- Buffer Interface ---------- */
-
-/* It's zlib-like interface.
- See LzmaDec_DecodeToDic description for information about STEPS and return results,
- but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
- to work with CLzmaDec variables manually.
-
-finishMode:
- It has meaning only if the decoding reaches output limit (*destLen).
- LZMA_FINISH_ANY - Decode just destLen bytes.
- LZMA_FINISH_END - Stream must be finished after (*destLen).
-*/
-
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-
-
/* ---------- One Call Interface ---------- */
/* LzmaDecode
--- a/lib/lzma/LzmaDec.c
+++ b/lib/lzma/LzmaDec.c
@@ -682,7 +682,7 @@ static void LzmaDec_InitRc(CLzmaDec *p,
p->needFlush = 0;
}
-void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
+static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
{
p->needFlush = 1;
p->remainLen = 0;
@@ -698,7 +698,7 @@ void LzmaDec_InitDicAndState(CLzmaDec *p
p->needInitState = 1;
}
-void LzmaDec_Init(CLzmaDec *p)
+static void LzmaDec_Init(CLzmaDec *p)
{
p->dicPos = 0;
LzmaDec_InitDicAndState(p, True, True);
@@ -716,7 +716,7 @@ static void LzmaDec_InitStateReal(CLzmaD
p->needInitState = 0;
}
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
+static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT inSize = *srcLen;
@@ -837,7 +837,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, Si
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
}
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+static __maybe_unused SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT outSize = *destLen;
SizeT inSize = *srcLen;
@@ -877,7 +877,7 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, By
}
}
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->probs);
p->probs = 0;
@@ -889,13 +889,13 @@ static void LzmaDec_FreeDict(CLzmaDec *p
p->dic = 0;
}
-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+static void __maybe_unused LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
{
LzmaDec_FreeProbs(p, alloc);
LzmaDec_FreeDict(p, alloc);
}
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
+static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
{
UInt32 dicSize;
Byte d;
@@ -935,7 +935,7 @@ static SRes LzmaDec_AllocateProbs2(CLzma
return SZ_OK;
}
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+static SRes __maybe_unused LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
{
CLzmaProps propNew;
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
@@ -944,7 +944,7 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p,
return SZ_OK;
}
-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+static SRes __maybe_unused LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
{
CLzmaProps propNew;
SizeT dicBufSize;
--- a/include/linux/lzma/LzmaEnc.h
+++ b/include/linux/lzma/LzmaEnc.h
@@ -31,9 +31,6 @@ typedef struct _CLzmaEncProps
} CLzmaEncProps;
void LzmaEncProps_Init(CLzmaEncProps *p);
-void LzmaEncProps_Normalize(CLzmaEncProps *p);
-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
-
/* ---------- CLzmaEncHandle Interface ---------- */
@@ -53,26 +50,9 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc *
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
-SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-/* ---------- One Call Interface ---------- */
-
-/* LzmaEncode
-Return code:
- SZ_OK - OK
- SZ_ERROR_MEM - Memory allocation error
- SZ_ERROR_PARAM - Incorrect paramater
- SZ_ERROR_OUTPUT_EOF - output buffer overflow
- SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
-*/
-
-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-
#ifdef __cplusplus
}
#endif
--- a/lib/lzma/LzmaEnc.c
+++ b/lib/lzma/LzmaEnc.c
@@ -53,7 +53,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p)
p->writeEndMark = 0;
}
-void LzmaEncProps_Normalize(CLzmaEncProps *p)
+static void LzmaEncProps_Normalize(CLzmaEncProps *p)
{
int level = p->level;
if (level < 0) level = 5;
@@ -76,7 +76,7 @@ void LzmaEncProps_Normalize(CLzmaEncProp
#endif
}
-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
+static UInt32 __maybe_unused LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
{
CLzmaEncProps props = *props2;
LzmaEncProps_Normalize(&props);
@@ -93,7 +93,7 @@ UInt32 LzmaEncProps_GetDictSize(const CL
#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
-UInt32 GetPosSlot1(UInt32 pos)
+static UInt32 GetPosSlot1(UInt32 pos)
{
UInt32 res;
BSR2_RET(pos, res);
@@ -107,7 +107,7 @@ UInt32 GetPosSlot1(UInt32 pos)
#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
-void LzmaEnc_FastPosInit(Byte *g_FastPos)
+static void LzmaEnc_FastPosInit(Byte *g_FastPos)
{
int c = 2, slotFast;
g_FastPos[0] = 0;
@@ -339,7 +339,7 @@ typedef struct
CSaveState saveState;
} CLzmaEnc;
-void LzmaEnc_SaveState(CLzmaEncHandle pp)
+static void __maybe_unused LzmaEnc_SaveState(CLzmaEncHandle pp)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
CSaveState *dest = &p->saveState;
@@ -365,7 +365,7 @@ void LzmaEnc_SaveState(CLzmaEncHandle pp
memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
}
-void LzmaEnc_RestoreState(CLzmaEncHandle pp)
+static void __maybe_unused LzmaEnc_RestoreState(CLzmaEncHandle pp)
{
CLzmaEnc *dest = (CLzmaEnc *)pp;
const CSaveState *p = &dest->saveState;
@@ -600,7 +600,7 @@ static void LitEnc_EncodeMatched(CRangeE
while (symbol < 0x10000);
}
-void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
{
UInt32 i;
for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
@@ -1676,7 +1676,7 @@ static void FillDistancesPrices(CLzmaEnc
p->matchPriceCount = 0;
}
-void LzmaEnc_Construct(CLzmaEnc *p)
+static void LzmaEnc_Construct(CLzmaEnc *p)
{
RangeEnc_Construct(&p->rc);
MatchFinder_Construct(&p->matchFinderBase);
@@ -1709,7 +1709,7 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc *
return p;
}
-void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
+static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->litProbs);
alloc->Free(alloc, p->saveState.litProbs);
@@ -2074,7 +2074,7 @@ SRes LzmaEnc_MemPrepare(CLzmaEncHandle p
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
}
-void LzmaEnc_Finish(CLzmaEncHandle pp)
+static void LzmaEnc_Finish(CLzmaEncHandle pp)
{
#ifndef _7ZIP_ST
CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -2108,7 +2108,7 @@ static size_t MyWrite(void *pp, const vo
}
-UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
+static UInt32 __maybe_unused LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
{
const CLzmaEnc *p = (CLzmaEnc *)pp;
return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
@@ -2120,7 +2120,7 @@ const Byte *LzmaEnc_GetCurBuf(CLzmaEncHa
return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
}
-SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
+static SRes __maybe_unused LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -2248,7 +2248,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp
return res;
}
-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+static __maybe_unused SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
{
--- a/include/linux/lzma/LzFind.h
+++ b/include/linux/lzma/LzFind.h
@@ -55,11 +55,6 @@ typedef struct _CMatchFinder
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
-int MatchFinder_NeedMove(CMatchFinder *p);
-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
-void MatchFinder_MoveBlock(CMatchFinder *p);
-void MatchFinder_ReadIfRequired(CMatchFinder *p);
-
void MatchFinder_Construct(CMatchFinder *p);
/* Conditions:
@@ -70,12 +65,6 @@ int MatchFinder_Create(CMatchFinder *p,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
-
-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
- UInt32 *distances, UInt32 maxLen);
/*
Conditions:
@@ -102,12 +91,6 @@ typedef struct _IMatchFinder
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
-void MatchFinder_Init(CMatchFinder *p);
-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-
#ifdef __cplusplus
}
#endif
--- a/lib/lzma/LzFind.c
+++ b/lib/lzma/LzFind.c
@@ -42,12 +42,12 @@ static int LzInWindow_Create(CMatchFinde
return (p->bufferBase != 0);
}
-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
-Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
+static Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
+static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
-UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
+static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
+static void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
{
p->posLimit -= subValue;
p->pos -= subValue;
@@ -268,7 +268,7 @@ static void MatchFinder_SetLimits(CMatch
p->posLimit = p->pos + limit;
}
-void MatchFinder_Init(CMatchFinder *p)
+static void MatchFinder_Init(CMatchFinder *p)
{
UInt32 i;
for (i = 0; i < p->hashSizeSum; i++)
@@ -287,7 +287,7 @@ static UInt32 MatchFinder_GetSubValue(CM
return (p->pos - p->historySize - 1) & kNormalizeMask;
}
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
+static void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
{
UInt32 i;
for (i = 0; i < numItems; i++)
@@ -350,7 +350,7 @@ static UInt32 * Hc_GetMatchesSpec(UInt32
}
}
-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+static UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
UInt32 *distances, UInt32 maxLen)
{
@@ -492,7 +492,7 @@ static UInt32 Bt2_MatchFinder_GetMatches
GET_MATCHES_FOOTER(offset, 1)
}
-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+static __maybe_unused UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 offset;
GET_MATCHES_HEADER(3)
@@ -632,7 +632,7 @@ static UInt32 Hc4_MatchFinder_GetMatches
MOVE_POS_RET
}
-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+static __maybe_unused UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 offset;
GET_MATCHES_HEADER(3)
@@ -657,7 +657,7 @@ static void Bt2_MatchFinder_Skip(CMatchF
while (--num != 0);
}
-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+static __maybe_unused void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
@@ -718,7 +718,7 @@ static void Hc4_MatchFinder_Skip(CMatchF
while (--num != 0);
}
-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+static __maybe_unused void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{

@ -1,132 +0,0 @@
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -112,6 +112,17 @@ static int jffs2_build_filesystem(struct
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. */
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -72,7 +72,7 @@ static int file_dirty(struct jffs2_sb_in
return ret;
if ((ret = jffs2_scan_dirty_space(c, jeb, jeb->free_size)))
return ret;
- /* Turned wasted size into dirty, since we apparently
+ /* Turned wasted size into dirty, since we apparently
think it's recoverable now. */
jeb->dirty_size += jeb->wasted_size;
c->dirty_size += jeb->wasted_size;
@@ -144,8 +144,11 @@ int jffs2_scan_medium(struct jffs2_sb_in
/* 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;
@@ -402,7 +405,7 @@ static int jffs2_scan_xref_node(struct j
if (!ref)
return -ENOMEM;
- /* BEFORE jffs2_build_xattr_subsystem() called,
+ /* BEFORE jffs2_build_xattr_subsystem() called,
* and AFTER xattr_ref is marked as a dead xref,
* ref->xid is used to store 32bit xid, xd is not used
* ref->ino is used to store 32bit inode-number, ic is not used
@@ -475,7 +478,7 @@ static int jffs2_scan_eraseblock (struct
struct jffs2_sum_marker *sm;
void *sumptr = NULL;
uint32_t sumlen;
-
+
if (!buf_size) {
/* XIP case. Just look, point at the summary if it's there */
sm = (void *)buf + c->sector_size - sizeof(*sm);
@@ -491,9 +494,9 @@ static int jffs2_scan_eraseblock (struct
buf_len = sizeof(*sm);
/* Read as much as we want into the _end_ of the preallocated buffer */
- err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len,
+ err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len,
jeb->offset + c->sector_size - buf_len,
- buf_len);
+ buf_len);
if (err)
return err;
@@ -512,9 +515,9 @@ static int jffs2_scan_eraseblock (struct
}
if (buf_len < sumlen) {
/* Need to read more so that the entire summary node is present */
- err = jffs2_fill_scan_buf(c, sumptr,
+ err = jffs2_fill_scan_buf(c, sumptr,
jeb->offset + c->sector_size - sumlen,
- sumlen - buf_len);
+ sumlen - buf_len);
if (err)
return err;
}
@@ -527,7 +530,7 @@ static int jffs2_scan_eraseblock (struct
if (buf_size && sumlen > buf_size)
kfree(sumptr);
- /* If it returns with a real error, bail.
+ /* If it returns with a real error, bail.
If it returns positive, that's a block classification
(i.e. BLK_STATE_xxx) so return that too.
If it returns zero, fall through to full scan. */
@@ -548,6 +551,17 @@ static int jffs2_scan_eraseblock (struct
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;
max_ofs = EMPTY_SCAN_SIZE(c->sector_size);
@@ -673,7 +687,7 @@ scan_more:
scan_end = buf_len;
goto more_empty;
}
-
+
/* See how much more there is to read in this eraseblock... */
buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
if (!buf_len) {
@@ -909,7 +923,7 @@ scan_more:
D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x, wasted 0x%08x\n",
jeb->offset,jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size, jeb->wasted_size));
-
+
/* mark_node_obsolete can add to wasted !! */
if (jeb->wasted_size) {
jeb->dirty_size += jeb->wasted_size;

@ -1,249 +0,0 @@
--- a/fs/squashfs/decompressor.c
+++ b/fs/squashfs/decompressor.c
@@ -40,11 +40,9 @@ static const struct squashfs_decompresso
NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0
};
-#ifndef CONFIG_SQUASHFS_LZO
static const struct squashfs_decompressor squashfs_lzo_unsupported_comp_ops = {
NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
};
-#endif
static const struct squashfs_decompressor squashfs_unknown_comp_ops = {
NULL, NULL, NULL, 0, "unknown", 0
@@ -53,11 +51,7 @@ static const struct squashfs_decompresso
static const struct squashfs_decompressor *decompressor[] = {
&squashfs_zlib_comp_ops,
&squashfs_lzma_unsupported_comp_ops,
-#ifdef CONFIG_SQUASHFS_LZO
- &squashfs_lzo_comp_ops,
-#else
&squashfs_lzo_unsupported_comp_ops,
-#endif
&squashfs_unknown_comp_ops
};
--- a/fs/squashfs/Kconfig
+++ b/fs/squashfs/Kconfig
@@ -5,13 +5,13 @@ config SQUASHFS
help
Saying Y here includes support for SquashFS 4.0 (a Compressed
Read-Only File System). Squashfs is a highly compressed read-only
- filesystem for Linux. It uses zlib/lzo compression to compress both
+ filesystem for Linux. It uses zlib compression to compress both
files, inodes and directories. Inodes in the system are very small
and all blocks are packed to minimise data overhead. Block sizes
greater than 4K are supported up to a maximum of 1 Mbytes (default
block size 128K). SquashFS 4.0 supports 64 bit filesystems and files
(larger than 4GB), full uid/gid information, hard links and
- timestamps.
+ timestamps.
Squashfs is intended for general read-only filesystem use, for
archival use (i.e. in cases where a .tar.gz file may be used), and in
@@ -26,7 +26,7 @@ config SQUASHFS
If unsure, say N.
-config SQUASHFS_XATTR
+config SQUASHFS_XATTRS
bool "Squashfs XATTR support"
depends on SQUASHFS
default n
@@ -37,24 +37,9 @@ config SQUASHFS_XATTR
If unsure, say N.
-config SQUASHFS_LZO
- bool "Include support for LZO compressed file systems"
- depends on SQUASHFS
- default n
- select LZO_DECOMPRESS
- help
- Saying Y here includes support for reading Squashfs file systems
- compressed with LZO compresssion. LZO compression is mainly
- aimed at embedded systems with slower CPUs where the overheads
- of zlib are too high.
-
- LZO is not the standard compression used in Squashfs and so most
- file systems will be readable without selecting this option.
-
- If unsure, say N.
-
config SQUASHFS_EMBEDDED
- bool "Additional option for memory-constrained systems"
+
+ bool "Additional option for memory-constrained systems"
depends on SQUASHFS
default n
help
--- a/fs/squashfs/lzo_wrapper.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2010 LG Electronics
- * Chan Jeong <chan.jeong@lge.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2,
- * or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * lzo_wrapper.c
- */
-
-#include <linux/mutex.h>
-#include <linux/buffer_head.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/lzo.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs_fs_i.h"
-#include "squashfs.h"
-#include "decompressor.h"
-
-struct squashfs_lzo {
- void *input;
- void *output;
-};
-
-static void *lzo_init(struct squashfs_sb_info *msblk)
-{
- int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
-
- struct squashfs_lzo *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
- if (stream == NULL)
- goto failed;
- stream->input = vmalloc(block_size);
- if (stream->input == NULL)
- goto failed;
- stream->output = vmalloc(block_size);
- if (stream->output == NULL)
- goto failed2;
-
- return stream;
-
-failed2:
- vfree(stream->input);
-failed:
- ERROR("Failed to allocate lzo workspace\n");
- kfree(stream);
- return NULL;
-}
-
-
-static void lzo_free(void *strm)
-{
- struct squashfs_lzo *stream = strm;
-
- if (stream) {
- vfree(stream->input);
- vfree(stream->output);
- }
- kfree(stream);
-}
-
-
-static int lzo_uncompress(struct squashfs_sb_info *msblk, void **buffer,
- struct buffer_head **bh, int b, int offset, int length, int srclength,
- int pages)
-{
- struct squashfs_lzo *stream = msblk->stream;
- void *buff = stream->input;
- int avail, i, bytes = length, res;
- size_t out_len = srclength;
-
- mutex_lock(&msblk->read_data_mutex);
-
- for (i = 0; i < b; i++) {
- wait_on_buffer(bh[i]);
- if (!buffer_uptodate(bh[i]))
- goto block_release;
-
- avail = min(bytes, msblk->devblksize - offset);
- memcpy(buff, bh[i]->b_data + offset, avail);
- buff += avail;
- bytes -= avail;
- offset = 0;
- put_bh(bh[i]);
- }
-
- res = lzo1x_decompress_safe(stream->input, (size_t)length,
- stream->output, &out_len);
- if (res != LZO_E_OK)
- goto failed;
-
- res = bytes = (int)out_len;
- for (i = 0, buff = stream->output; bytes && i < pages; i++) {
- avail = min_t(int, bytes, PAGE_CACHE_SIZE);
- memcpy(buffer[i], buff, avail);
- buff += avail;
- bytes -= avail;
- }
-
- mutex_unlock(&msblk->read_data_mutex);
- return res;
-
-block_release:
- for (; i < b; i++)
- put_bh(bh[i]);
-
-failed:
- mutex_unlock(&msblk->read_data_mutex);
-
- ERROR("lzo decompression failed, data probably corrupt\n");
- return -EIO;
-}
-
-const struct squashfs_decompressor squashfs_lzo_comp_ops = {
- .init = lzo_init,
- .free = lzo_free,
- .decompress = lzo_uncompress,
- .id = LZO_COMPRESSION,
- .name = "lzo",
- .supported = 1
-};
--- a/fs/squashfs/Makefile
+++ b/fs/squashfs/Makefile
@@ -5,5 +5,5 @@
obj-$(CONFIG_SQUASHFS) += squashfs.o
squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o
-squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o
-squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o
+squashfs-$(CONFIG_SQUASHFS_XATTRS) += xattr.o xattr_id.o
+
--- a/fs/squashfs/squashfs.h
+++ b/fs/squashfs/squashfs.h
@@ -104,6 +104,3 @@ extern const struct xattr_handler *squas
/* zlib_wrapper.c */
extern const struct squashfs_decompressor squashfs_zlib_comp_ops;
-
-/* lzo_wrapper.c */
-extern const struct squashfs_decompressor squashfs_lzo_comp_ops;
--- a/fs/squashfs/xattr.h
+++ b/fs/squashfs/xattr.h
@@ -21,7 +21,7 @@
* xattr.h
*/
-#ifdef CONFIG_SQUASHFS_XATTR
+#ifdef CONFIG_SQUASHFS_XATTRS
extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64,
u64 *, int *);
extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *,

@ -1,219 +0,0 @@
From f49e1efdd179d54e814ff2a8e8f469496583062c Mon Sep 17 00:00:00 2001
From: Phillip Lougher <phillip@lougher.demon.co.uk>
Date: Tue, 20 Oct 2009 10:54:36 +0100
Subject: [PATCH] Squashfs: add LZMA compression
Add support for LZMA compressed filesystems. This is an initial
implementation.
Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
---
fs/squashfs/Kconfig | 5 ++
fs/squashfs/Makefile | 1 +
fs/squashfs/decompressor.c | 4 +
fs/squashfs/lzma_wrapper.c | 151 ++++++++++++++++++++++++++++++++++++++++++++
fs/squashfs/squashfs.h | 3 +
5 files changed, 164 insertions(+), 0 deletions(-)
create mode 100644 fs/squashfs/lzma_wrapper.c
--- a/fs/squashfs/Kconfig
+++ b/fs/squashfs/Kconfig
@@ -37,6 +37,11 @@ config SQUASHFS_XATTRS
If unsure, say N.
+config SQUASHFS_LZMA
+ bool "Include support for LZMA compressed file systems"
+ depends on SQUASHFS
+ select DECOMPRESS_LZMA
+
config SQUASHFS_EMBEDDED
bool "Additional option for memory-constrained systems"
--- a/fs/squashfs/Makefile
+++ b/fs/squashfs/Makefile
@@ -5,5 +5,5 @@
obj-$(CONFIG_SQUASHFS) += squashfs.o
squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o
-squashfs-$(CONFIG_SQUASHFS_XATTRS) += xattr.o xattr_id.o
+squashfs-$(CONFIG_SQUASHFS_LZMA) += lzma_wrapper.o
--- a/fs/squashfs/decompressor.c
+++ b/fs/squashfs/decompressor.c
@@ -50,7 +50,11 @@ static const struct squashfs_decompresso
static const struct squashfs_decompressor *decompressor[] = {
&squashfs_zlib_comp_ops,
+#ifdef CONFIG_SQUASHFS_LZMA
+ &squashfs_lzma_comp_ops,
+#else
&squashfs_lzma_unsupported_comp_ops,
+#endif
&squashfs_lzo_unsupported_comp_ops,
&squashfs_unknown_comp_ops
};
--- /dev/null
+++ b/fs/squashfs/lzma_wrapper.c
@@ -0,0 +1,152 @@
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ * Phillip Lougher <phillip@lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * lzma_wrapper.c
+ */
+
+#include <asm/unaligned.h>
+#include <linux/buffer_head.h>
+#include <linux/mutex.h>
+#include <linux/vmalloc.h>
+#include <linux/decompress/unlzma.h>
+#include <linux/slab.h>
+
+#include "squashfs_fs.h"
+#include "squashfs_fs_sb.h"
+#include "squashfs_fs_i.h"
+#include "squashfs.h"
+#include "decompressor.h"
+
+struct squashfs_lzma {
+ void *input;
+ void *output;
+};
+
+/* decompress_unlzma.c is currently non re-entrant... */
+DEFINE_MUTEX(lzma_mutex);
+
+/* decompress_unlzma.c doesn't provide any context in its callbacks... */
+static int lzma_error;
+
+static void error(char *m)
+{
+ ERROR("unlzma error: %s\n", m);
+ lzma_error = 1;
+}
+
+
+static void *lzma_init(struct squashfs_sb_info *msblk)
+{
+ struct squashfs_lzma *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
+ if (stream == NULL)
+ goto failed;
+ stream->input = vmalloc(msblk->block_size);
+ if (stream->input == NULL)
+ goto failed;
+ stream->output = vmalloc(msblk->block_size);
+ if (stream->output == NULL)
+ goto failed2;
+
+ return stream;
+
+failed2:
+ vfree(stream->input);
+failed:
+ ERROR("failed to allocate lzma workspace\n");
+ kfree(stream);
+ return NULL;
+}
+
+
+static void lzma_free(void *strm)
+{
+ struct squashfs_lzma *stream = strm;
+
+ if (stream) {
+ vfree(stream->input);
+ vfree(stream->output);
+ }
+ kfree(stream);
+}
+
+
+static int lzma_uncompress(struct squashfs_sb_info *msblk, void **buffer,
+ struct buffer_head **bh, int b, int offset, int length, int srclength,
+ int pages)
+{
+ struct squashfs_lzma *stream = msblk->stream;
+ void *buff = stream->input;
+ int avail, i, bytes = length, res;
+
+ mutex_lock(&lzma_mutex);
+
+ for (i = 0; i < b; i++) {
+ wait_on_buffer(bh[i]);
+ if (!buffer_uptodate(bh[i]))
+ goto block_release;
+
+ avail = min(bytes, msblk->devblksize - offset);
+ memcpy(buff, bh[i]->b_data + offset, avail);
+ buff += avail;
+ bytes -= avail;
+ offset = 0;
+ put_bh(bh[i]);
+ }
+
+ lzma_error = 0;
+ res = unlzma(stream->input, length, NULL, NULL, stream->output, NULL,
+ error);
+ if (res || lzma_error)
+ goto failed;
+
+ /* uncompressed size is stored in the LZMA header (5 byte offset) */
+ res = bytes = get_unaligned_le32(stream->input + 5);
+ for (i = 0, buff = stream->output; bytes && i < pages; i++) {
+ avail = min_t(int, bytes, PAGE_CACHE_SIZE);
+ memcpy(buffer[i], buff, avail);
+ buff += avail;
+ bytes -= avail;
+ }
+ if (bytes)
+ goto failed;
+
+ mutex_unlock(&lzma_mutex);
+ return res;
+
+block_release:
+ for (; i < b; i++)
+ put_bh(bh[i]);
+
+failed:
+ mutex_unlock(&lzma_mutex);
+
+ ERROR("lzma decompression failed, data probably corrupt\n");
+ return -EIO;
+}
+
+const struct squashfs_decompressor squashfs_lzma_comp_ops = {
+ .init = lzma_init,
+ .free = lzma_free,
+ .decompress = lzma_uncompress,
+ .id = LZMA_COMPRESSION,
+ .name = "lzma",
+ .supported = 1
+};
+
--- a/fs/squashfs/squashfs.h
+++ b/fs/squashfs/squashfs.h
@@ -104,3 +104,6 @@ extern const struct xattr_handler *squas
/* zlib_wrapper.c */
extern const struct squashfs_decompressor squashfs_zlib_comp_ops;
+
+/* lzma wrapper.c */
+extern const struct squashfs_decompressor squashfs_lzma_comp_ops;

@ -1,165 +0,0 @@
From fdf23ed283bc6ef5c25076ce2065f892120ff556 Mon Sep 17 00:00:00 2001
From: Phillip Lougher <phillip@lougher.demon.co.uk>
Date: Thu, 22 Oct 2009 04:57:38 +0100
Subject: [PATCH] Squashfs: Make unlzma available to non initramfs/initrd code
Add a config option DECOMPRESS_LZMA_NEEDED which allows subsystems to
specify they need the unlzma code. Normally decompress_unlzma.c is
compiled with __init and unlzma is not exported to modules.
Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
---
fs/squashfs/Kconfig | 1 +
include/linux/decompress/bunzip2_mm.h | 12 ++++++++++++
include/linux/decompress/inflate_mm.h | 12 ++++++++++++
include/linux/decompress/mm.h | 3 ---
include/linux/decompress/unlzma_mm.h | 20 ++++++++++++++++++++
lib/Kconfig | 3 +++
lib/decompress_bunzip2.c | 1 +
lib/decompress_inflate.c | 1 +
lib/decompress_unlzma.c | 5 ++++-
9 files changed, 54 insertions(+), 4 deletions(-)
create mode 100644 include/linux/decompress/bunzip2_mm.h
create mode 100644 include/linux/decompress/inflate_mm.h
create mode 100644 include/linux/decompress/unlzma_mm.h
--- a/fs/squashfs/Kconfig
+++ b/fs/squashfs/Kconfig
@@ -41,6 +41,7 @@ config SQUASHFS_LZMA
bool "Include support for LZMA compressed file systems"
depends on SQUASHFS
select DECOMPRESS_LZMA
+ select DECOMPRESS_LZMA_NEEDED
config SQUASHFS_EMBEDDED
--- /dev/null
+++ b/include/linux/decompress/bunzip2_mm.h
@@ -0,0 +1,12 @@
+#ifndef BUNZIP2_MM_H
+#define BUNZIP2_MM_H
+
+#ifdef STATIC
+/* Code active when included from pre-boot environment: */
+#define INIT
+#else
+/* Compile for initramfs/initrd code only */
+#define INIT __init
+#endif
+
+#endif
--- /dev/null
+++ b/include/linux/decompress/inflate_mm.h
@@ -0,0 +1,12 @@
+#ifndef INFLATE_MM_H
+#define INFLATE_MM_H
+
+#ifdef STATIC
+/* Code active when included from pre-boot environment: */
+#define INIT
+#else
+/* Compile for initramfs/initrd code only */
+#define INIT __init
+#endif
+
+#endif
--- a/include/linux/decompress/mm.h
+++ b/include/linux/decompress/mm.h
@@ -63,8 +63,6 @@ static void free(void *where)
#define set_error_fn(x)
-#define INIT
-
#else /* STATIC */
/* Code active when compiled standalone for use when loading ramdisk: */
@@ -87,7 +85,6 @@ static void free(void *where)
static void(*error)(char *m);
#define set_error_fn(x) error = x;
-#define INIT __init
#define STATIC
#include <linux/init.h>
--- /dev/null
+++ b/include/linux/decompress/unlzma_mm.h
@@ -0,0 +1,20 @@
+#ifndef UNLZMA_MM_H
+#define UNLZMA_MM_H
+
+#ifdef STATIC
+
+/* Code active when included from pre-boot environment: */
+#define INIT
+
+#elif defined(CONFIG_DECOMPRESS_LZMA_NEEDED)
+
+/* Make it available to non initramfs/initrd code */
+#define INIT
+#include <linux/module.h>
+#else
+
+/* Compile for initramfs/initrd code only */
+#define INIT __init
+#endif
+
+#endif
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -130,6 +130,9 @@ config DECOMPRESS_LZO
select LZO_DECOMPRESS
tristate
+config DECOMPRESS_LZMA_NEEDED
+ boolean
+
#
# Generic allocator support is selected if needed
#
--- a/lib/decompress_bunzip2.c
+++ b/lib/decompress_bunzip2.c
@@ -52,6 +52,7 @@
#include <linux/slab.h>
#endif /* STATIC */
+#include <linux/decompress/bunzip2_mm.h>
#include <linux/decompress/mm.h>
#ifndef INT_MAX
--- a/lib/decompress_inflate.c
+++ b/lib/decompress_inflate.c
@@ -23,6 +23,7 @@
#endif /* STATIC */
+#include <linux/decompress/inflate_mm.h>
#include <linux/decompress/mm.h>
#define GZIP_IOBUF_SIZE (16*1024)
--- a/lib/decompress_unlzma.c
+++ b/lib/decompress_unlzma.c
@@ -36,6 +36,7 @@
#include <linux/slab.h>
#endif /* STATIC */
+#include <linux/decompress/unlzma_mm.h>
#include <linux/decompress/mm.h>
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
@@ -531,7 +532,7 @@ static inline void INIT process_bit1(str
-STATIC inline int INIT unlzma(unsigned char *buf, int in_len,
+STATIC int INIT unlzma(unsigned char *buf, int in_len,
int(*fill)(void*, unsigned int),
int(*flush)(void*, unsigned int),
unsigned char *output,
@@ -664,4 +665,6 @@ STATIC int INIT decompress(unsigned char
{
return unlzma(buf, in_len - 4, fill, flush, output, posp, error_fn);
}
+#elif defined(CONFIG_DECOMPRESS_LZMA_NEEDED)
+EXPORT_SYMBOL(unlzma);
#endif

@ -1,108 +0,0 @@
--- a/include/linux/netfilter/xt_layer7.h
+++ b/include/linux/netfilter/xt_layer7.h
@@ -8,6 +8,7 @@ struct xt_layer7_info {
char protocol[MAX_PROTOCOL_LEN];
char pattern[MAX_PATTERN_LEN];
u_int8_t invert;
+ u_int8_t pkt;
};
#endif /* _XT_LAYER7_H */
--- a/net/netfilter/xt_layer7.c
+++ b/net/netfilter/xt_layer7.c
@@ -314,33 +314,35 @@ static int match_no_append(struct nf_con
}
/* add the new app data to the conntrack. Return number of bytes added. */
-static int add_data(struct nf_conn * 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') {
/* the kernel version of tolower mungs 'upper ascii' */
- master_conntrack->layer7.app_data[length+oldlength] =
+ target[length+offset] =
isascii(app_data[i])?
tolower(app_data[i]) : app_data[i];
length++;
}
}
+ target[length+offset] = '\0';
+
+ return length;
+}
+
+/* add the new app data to the conntrack. Return number of bytes added. */
+static int add_data(struct nf_conn * master_conntrack,
+ char * app_data, int appdatalen)
+{
+ int length;
- master_conntrack->layer7.app_data[length+oldlength] = '\0';
- master_conntrack->layer7.app_data_len = length + oldlength;
+ 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;
}
@@ -438,7 +440,7 @@ match(const struct sk_buff *skbin,
enum ip_conntrack_info master_ctinfo, ctinfo;
struct nf_conn *master_conntrack, *conntrack;
- unsigned char * app_data;
+ unsigned char *app_data, *tmp_data;
unsigned int pattern_result, appdatalen;
regexp * comppattern;
@@ -466,8 +468,8 @@ match(const struct sk_buff *skbin,
master_conntrack = master_ct(master_conntrack);
/* if we've classified it or seen too many packets */
- if(total_acct_packets(master_conntrack) > num_packets ||
- master_conntrack->layer7.app_proto) {
+ if(!info->pkt && (total_acct_packets(master_conntrack) > num_packets ||
+ master_conntrack->layer7.app_proto)) {
pattern_result = match_no_append(conntrack, master_conntrack,
ctinfo, master_ctinfo, info);
@@ -500,6 +502,25 @@ match(const struct sk_buff *skbin,
/* the return value gets checked later, when we're ready to use it */
comppattern = compile_and_cache(info->pattern, info->protocol);
+ 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;
+ spin_unlock_bh(&l7_lock);
+
+ return (pattern_result ^ info->invert);
+ }
+
/* On the first packet of a connection, allocate space for app data */
if(total_acct_packets(master_conntrack) == 1 && !skb->cb[0] &&
!master_conntrack->layer7.app_data){

@ -1,51 +0,0 @@
--- a/net/netfilter/xt_layer7.c
+++ b/net/netfilter/xt_layer7.c
@@ -415,7 +415,9 @@ static int layer7_write_proc(struct file
}
static bool
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+match(const struct sk_buff *skbin, struct xt_action_param *par)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
match(const struct sk_buff *skbin, const struct xt_match_param *par)
#else
match(const struct sk_buff *skbin,
@@ -597,14 +599,19 @@ match(const struct sk_buff *skbin,
}
// load nf_conntrack_ipv4
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+static int
+#else
+static bool
+#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-static bool check(const struct xt_mtchk_param *par)
+check(const struct xt_mtchk_param *par)
{
if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
printk(KERN_WARNING "can't load conntrack support for "
"proto=%d\n", par->match->family);
#else
-static bool check(const char *tablename, const void *inf,
+check(const char *tablename, const void *inf,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{
@@ -612,9 +619,15 @@ static bool check(const char *tablename,
printk(KERN_WARNING "can't load conntrack support for "
"proto=%d\n", match->family);
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+ return -EINVAL;
+ }
+ return 0;
+#else
return 0;
}
return 1;
+#endif
}

@ -1,61 +0,0 @@
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -760,6 +760,27 @@ config NETFILTER_XT_MATCH_IPVS
If unsure, say N.
+config NETFILTER_XT_MATCH_LAYER7
+ tristate '"layer7" match support'
+ depends on EXPERIMENTAL
+ depends on NETFILTER_XTABLES
+ depends on NETFILTER_ADVANCED
+ depends on NF_CONNTRACK
+ help
+ Say Y if you want to be able to classify connections (and their
+ packets) based on regular expression matching of their application
+ layer data. This is one way to classify applications such as
+ peer-to-peer filesharing systems that do not always use the same
+ port.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config NETFILTER_XT_MATCH_LAYER7_DEBUG
+ bool 'Layer 7 debugging output'
+ depends on NETFILTER_XT_MATCH_LAYER7
+ help
+ Say Y to get lots of debugging output.
+
config NETFILTER_XT_MATCH_LENGTH
tristate '"length" match support'
depends on NETFILTER_ADVANCED
@@ -946,26 +967,11 @@ config NETFILTER_XT_MATCH_STATE
To compile it as a module, choose M here. If unsure, say N.
-config NETFILTER_XT_MATCH_LAYER7
- tristate '"layer7" match support'
- depends on NETFILTER_XTABLES
- depends on EXPERIMENTAL && (IP_NF_CONNTRACK || NF_CONNTRACK)
- depends on NETFILTER_ADVANCED
- help
- Say Y if you want to be able to classify connections (and their
- packets) based on regular expression matching of their application
- layer data. This is one way to classify applications such as
- peer-to-peer filesharing systems that do not always use the same
- port.
-
- To compile it as a module, choose M here. If unsure, say N.
-
config NETFILTER_XT_MATCH_LAYER7_DEBUG
- bool 'Layer 7 debugging output'
- depends on NETFILTER_XT_MATCH_LAYER7
- help
- Say Y to get lots of debugging output.
-
+ bool 'Layer 7 debugging output'
+ depends on NETFILTER_XT_MATCH_LAYER7
+ help
+ Say Y to get lots of debugging output.
config NETFILTER_XT_MATCH_STATISTIC
tristate '"statistic" match support'

@ -1,118 +0,0 @@
--- a/include/linux/netfilter/nf_conntrack_sip.h
+++ b/include/linux/netfilter/nf_conntrack_sip.h
@@ -2,12 +2,15 @@
#define __NF_CONNTRACK_SIP_H__
#ifdef __KERNEL__
+#include <linux/types.h>
+
#define SIP_PORT 5060
#define SIP_TIMEOUT 3600
struct nf_ct_sip_master {
unsigned int register_cseq;
unsigned int invite_cseq;
+ __be16 forced_dport;
};
enum sip_expectation_classes {
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -73,6 +73,7 @@ static int map_addr(struct sk_buff *skb,
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+ struct nf_conn_help *help = nfct_help(ct);
char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
unsigned int buflen;
__be32 newaddr;
@@ -85,7 +86,8 @@ static int map_addr(struct sk_buff *skb,
} else if (ct->tuplehash[dir].tuple.dst.u3.ip == addr->ip &&
ct->tuplehash[dir].tuple.dst.u.udp.port == port) {
newaddr = ct->tuplehash[!dir].tuple.src.u3.ip;
- newport = ct->tuplehash[!dir].tuple.src.u.udp.port;
+ newport = help->help.ct_sip_info.forced_dport ? :
+ ct->tuplehash[!dir].tuple.src.u.udp.port;
} else
return 1;
@@ -121,6 +123,7 @@ static unsigned int ip_nat_sip(struct sk
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+ struct nf_conn_help *help = nfct_help(ct);
unsigned int coff, matchoff, matchlen;
enum sip_header_types hdr;
union nf_inet_addr addr;
@@ -229,6 +232,20 @@ next:
!map_sip_addr(skb, dataoff, dptr, datalen, SIP_HDR_TO))
return NF_DROP;
+ /* Mangle destination port for Cisco phones, then fix up checksums */
+ if (dir == IP_CT_DIR_REPLY && help->help.ct_sip_info.forced_dport) {
+ struct udphdr *uh;
+
+ if (!skb_make_writable(skb, skb->len))
+ return NF_DROP;
+
+ uh = (struct udphdr *)(skb->data + ip_hdrlen(skb));
+ uh->dest = help->help.ct_sip_info.forced_dport;
+
+ if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, 0, 0, NULL, 0))
+ return NF_DROP;
+ }
+
return NF_ACCEPT;
}
@@ -280,8 +297,10 @@ static unsigned int ip_nat_sip_expect(st
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+ struct nf_conn_help *help = nfct_help(ct);
__be32 newip;
u_int16_t port;
+ __be16 srcport;
char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
unsigned buflen;
@@ -294,8 +313,9 @@ static unsigned int ip_nat_sip_expect(st
/* If the signalling port matches the connection's source port in the
* original direction, try to use the destination port in the opposite
* direction. */
- if (exp->tuple.dst.u.udp.port ==
- ct->tuplehash[dir].tuple.src.u.udp.port)
+ srcport = help->help.ct_sip_info.forced_dport ? :
+ ct->tuplehash[dir].tuple.src.u.udp.port;
+ if (exp->tuple.dst.u.udp.port == srcport)
port = ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port);
else
port = ntohs(exp->tuple.dst.u.udp.port);
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -1363,8 +1363,25 @@ static int process_sip_request(struct sk
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+ struct nf_conn_help *help = nfct_help(ct);
+ enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
unsigned int matchoff, matchlen;
unsigned int cseq, i;
+ union nf_inet_addr addr;
+ __be16 port;
+
+ /* Many Cisco IP phones use a high source port for SIP requests, but
+ * listen for the response on port 5060. If we are the local
+ * router for one of these phones, save the port number from the
+ * Via: header so that nf_nat_sip can redirect the responses to
+ * the correct port.
+ */
+ if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
+ SIP_HDR_VIA_UDP, NULL, &matchoff,
+ &matchlen, &addr, &port) > 0 &&
+ port != ct->tuplehash[dir].tuple.src.u.udp.port &&
+ nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.src.u3))
+ help->help.ct_sip_info.forced_dport = port;
for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
const struct sip_handler *handler;

@ -1,26 +0,0 @@
From: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
Date: Tue, 10 May 2011 08:00:21 +0000 (+0200)
Subject: netfilter: IPv6: fix DSCP mangle code
X-Git-Tag: v2.6.39~15^2~13^2~1
X-Git-Url: http://git390.marist.edu/cgi-bin/gitweb.cgi?p=linux-2.6.git;a=commitdiff_plain;h=1ed2f73d90fb49bcf5704aee7e9084adb882bfc5
netfilter: IPv6: fix DSCP mangle code
The mask indicates the bits one wants to zero out, so it needs to be
inverted before applying to the original TOS field.
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -99,7 +99,7 @@ tos_tg6(struct sk_buff *skb, const struc
u_int8_t orig, nv;
orig = ipv6_get_dsfield(iph);
- nv = (orig & info->tos_mask) ^ info->tos_value;
+ nv = (orig & ~info->tos_mask) ^ info->tos_value;
if (orig != nv) {
if (!skb_make_writable(skb, sizeof(struct iphdr)))

@ -1,795 +0,0 @@
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -173,8 +173,37 @@ struct tc_sfq_xstats {
*
* 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,
+ /* conntrack */
+ TCA_SFQ_HASH_CTORIGDST,
+ TCA_SFQ_HASH_CTORIGSRC,
+ TCA_SFQ_HASH_CTREPLDST,
+ TCA_SFQ_HASH_CTREPLSRC,
+ TCA_SFQ_HASH_CTNATCHG,
+};
+
+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 {
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -137,6 +137,37 @@ config NET_SCH_SFQ
To compile this code as a module, choose M here: the
module will be called sch_sfq.
+config NET_SCH_ESFQ
+ tristate "Enhanced Stochastic Fairness Queueing (ESFQ)"
+ ---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.
+
+ ESFQ also adds control of the hash function used to identify packet
+ flows. The original SFQ discipline hashes by connection; ESFQ add
+ several other hashing methods, such as by src IP or by dst IP, 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_ESFQ_NFCT
+ bool "Connection Tracking Hash Types"
+ depends on NET_SCH_ESFQ && NF_CONNTRACK
+ ---help---
+ Say Y here to enable support for hashing based on netfilter connection
+ tracking information. This is useful for a router that is also using
+ NAT to connect privately-addressed hosts to the Internet. If you want
+ to provide fair distribution of upstream bandwidth, ESFQ must use
+ connection tracking information, since all outgoing packets will share
+ the same source address.
+
config NET_SCH_TEQL
tristate "True Link Equalizer (TEQL)"
---help---
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_NET_SCH_GRED) += sch_gred.o
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
--- /dev/null
+++ b/net/sched/sch_esfq.c
@@ -0,0 +1,702 @@
+/*
+ * 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 usage of jhash.
+ * Added conntrack support.
+ * Added ctnatchg hash (thanks to Ben Pfountz).
+ */
+
+#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 <net/netlink.h>
+#include <linux/ipv6.h>
+#include <net/route.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <net/pkt_sched.h>
+#include <linux/jhash.h>
+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
+#include <net/netfilter/nf_conntrack.h>
+#endif
+
+/* 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 alternate hash types.
+
+ classic: same as in sch_sfq.c
+ dst: destination IP address
+ src: source IP address
+ fwmark: netfilter mark value
+ ctorigdst: original destination IP address
+ ctorigsrc: original source IP address
+ ctrepldst: reply destination IP address
+ ctreplsrc: reply source IP
+
+*/
+
+#define ESFQ_HEAD 0
+#define ESFQ_TAIL 1
+
+/* 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 */
+};
+
+/* This contains the info we will hash. */
+struct esfq_packet_info
+{
+ u32 proto; /* protocol or port */
+ u32 src; /* source from packet header */
+ u32 dst; /* destination from packet header */
+ u32 ctorigsrc; /* original source from conntrack */
+ u32 ctorigdst; /* original destination from conntrack */
+ u32 ctreplsrc; /* reply source from conntrack */
+ u32 ctrepldst; /* reply destination from conntrack */
+ u32 mark; /* netfilter mark (fwmark) */
+};
+
+static __inline__ unsigned esfq_jhash_1word(struct esfq_sched_data *q,u32 a)
+{
+ return jhash_1word(a, q->perturbation) & (q->hash_divisor-1);
+}
+
+static __inline__ unsigned esfq_jhash_2words(struct esfq_sched_data *q, u32 a, u32 b)
+{
+ return jhash_2words(a, b, q->perturbation) & (q->hash_divisor-1);
+}
+
+static __inline__ unsigned esfq_jhash_3words(struct esfq_sched_data *q, u32 a, u32 b, u32 c)
+{
+ return jhash_3words(a, b, c, q->perturbation) & (q->hash_divisor-1);
+}
+
+static unsigned esfq_hash(struct esfq_sched_data *q, struct sk_buff *skb)
+{
+ struct esfq_packet_info info;
+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+#endif
+
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
+ {
+ struct iphdr *iph = ip_hdr(skb);
+ info.dst = iph->daddr;
+ info.src = iph->saddr;
+ 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))
+ info.proto = *(((u32*)iph) + iph->ihl);
+ else
+ info.proto = iph->protocol;
+ break;
+ }
+ case __constant_htons(ETH_P_IPV6):
+ {
+ struct ipv6hdr *iph = ipv6_hdr(skb);
+ /* Hash ipv6 addresses into a u32. This isn't ideal,
+ * but the code is simple. */
+ info.dst = jhash2(iph->daddr.s6_addr32, 4, q->perturbation);
+ info.src = jhash2(iph->saddr.s6_addr32, 4, q->perturbation);
+ if (iph->nexthdr == IPPROTO_TCP ||
+ iph->nexthdr == IPPROTO_UDP ||
+ iph->nexthdr == IPPROTO_SCTP ||
+ iph->nexthdr == IPPROTO_DCCP ||
+ iph->nexthdr == IPPROTO_ESP)
+ info.proto = *(u32*)&iph[1];
+ else
+ info.proto = iph->nexthdr;
+ break;
+ }
+ default:
+ info.dst = (u32)(unsigned long)skb_dst(skb);
+ info.src = (u32)(unsigned long)skb->sk;
+ info.proto = skb->protocol;
+ }
+
+ info.mark = skb->mark;
+
+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
+ /* defaults if there is no conntrack info */
+ info.ctorigsrc = info.src;
+ info.ctorigdst = info.dst;
+ info.ctreplsrc = info.dst;
+ info.ctrepldst = info.src;
+ /* collect conntrack info */
+ if (ct && ct != &nf_conntrack_untracked) {
+ if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ info.ctorigsrc = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip;
+ info.ctorigdst = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip;
+ info.ctreplsrc = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip;
+ info.ctrepldst = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip;
+ }
+ else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
+ /* Again, hash ipv6 addresses into a single u32. */
+ info.ctorigsrc = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip6, 4, q->perturbation);
+ info.ctorigdst = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip6, 4, q->perturbation);
+ info.ctreplsrc = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip6, 4, q->perturbation);
+ info.ctrepldst = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip6, 4, q->perturbation);
+ }
+
+ }
+#endif
+
+ switch(q->hash_kind) {
+ case TCA_SFQ_HASH_CLASSIC:
+ return esfq_jhash_3words(q, info.dst, info.src, info.proto);
+ case TCA_SFQ_HASH_DST:
+ return esfq_jhash_1word(q, info.dst);
+ case TCA_SFQ_HASH_SRC:
+ return esfq_jhash_1word(q, info.src);
+ case TCA_SFQ_HASH_FWMARK:
+ return esfq_jhash_1word(q, info.mark);
+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
+ case TCA_SFQ_HASH_CTORIGDST:
+ return esfq_jhash_1word(q, info.ctorigdst);
+ case TCA_SFQ_HASH_CTORIGSRC:
+ return esfq_jhash_1word(q, info.ctorigsrc);
+ case TCA_SFQ_HASH_CTREPLDST:
+ return esfq_jhash_1word(q, info.ctrepldst);
+ case TCA_SFQ_HASH_CTREPLSRC:
+ return esfq_jhash_1word(q, info.ctreplsrc);
+ case TCA_SFQ_HASH_CTNATCHG:
+ {
+ if (info.ctorigdst == info.ctreplsrc)
+ return esfq_jhash_1word(q, info.ctorigsrc);
+ return esfq_jhash_1word(q, info.ctreplsrc);
+ }
+#endif
+ default:
+ if (net_ratelimit())
+ printk(KERN_WARNING "ESFQ: Unknown hash method. Falling back to classic.\n");
+ }
+ return esfq_jhash_3words(q, info.dst, info.src, info.proto);
+}
+
+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++;
+ sch->qstats.backlog -= len;
+ 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++;
+ sch->qstats.backlog -= len;
+ return len;
+ }
+
+ return 0;
+}
+
+static void esfq_q_enqueue(struct sk_buff *skb, struct esfq_sched_data *q, unsigned int end)
+{
+ 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;
+ }
+
+ if (end == ESFQ_TAIL)
+ __skb_queue_tail(&q->qs[x], skb);
+ else
+ __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;
+ }
+ }
+}
+
+static int esfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ esfq_q_enqueue(skb, q, ESFQ_TAIL);
+ sch->qstats.backlog += skb->len;
+ if (++sch->q.qlen < q->limit-1) {
+ sch->bstats.bytes += skb->len;
+ sch->bstats.packets++;
+ return 0;
+ }
+
+ sch->qstats.drops++;
+ esfq_drop(sch);
+ return NET_XMIT_CN;
+}
+
+static struct sk_buff *esfq_peek(struct Qdisc* sch)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ esfq_index a;
+
+ /* No active slots */
+ if (q->tail == q->depth)
+ return NULL;
+
+ a = q->next[q->tail];
+ return skb_peek(&q->qs[a]);
+}
+
+static struct sk_buff *esfq_q_dequeue(struct esfq_sched_data *q)
+{
+ 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);
+
+ /* 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 struct sk_buff *esfq_dequeue(struct Qdisc* sch)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ struct sk_buff *skb;
+
+ skb = esfq_q_dequeue(q);
+ if (skb == NULL)
+ return NULL;
+ sch->q.qlen--;
+ sch->qstats.backlog -= skb->len;
+ return skb;
+}
+
+static void esfq_q_destroy(struct esfq_sched_data *q)
+{
+ 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 void esfq_destroy(struct Qdisc *sch)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ esfq_q_destroy(q);
+}
+
+
+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 unsigned int esfq_check_hash(unsigned int kind)
+{
+ switch (kind) {
+ case TCA_SFQ_HASH_CTORIGDST:
+ case TCA_SFQ_HASH_CTORIGSRC:
+ case TCA_SFQ_HASH_CTREPLDST:
+ case TCA_SFQ_HASH_CTREPLSRC:
+ case TCA_SFQ_HASH_CTNATCHG:
+#ifndef CONFIG_NET_SCH_ESFQ_NFCT
+ {
+ if (net_ratelimit())
+ printk(KERN_WARNING "ESFQ: Conntrack hash types disabled in kernel config. Falling back to classic.\n");
+ return TCA_SFQ_HASH_CLASSIC;
+ }
+#endif
+ case TCA_SFQ_HASH_CLASSIC:
+ case TCA_SFQ_HASH_DST:
+ case TCA_SFQ_HASH_SRC:
+ case TCA_SFQ_HASH_FWMARK:
+ return kind;
+ default:
+ {
+ if (net_ratelimit())
+ printk(KERN_WARNING "ESFQ: Unknown hash type. Falling back to classic.\n");
+ return TCA_SFQ_HASH_CLASSIC;
+ }
+ }
+}
+
+static int esfq_q_init(struct esfq_sched_data *q, struct nlattr *opt)
+{
+ struct tc_esfq_qopt *ctl = nla_data(opt);
+ esfq_index p = ~0U/2;
+ int i;
+
+ if (opt && opt->nla_len < nla_attr_size(sizeof(*ctl)))
+ return -EINVAL;
+
+ q->perturbation = 0;
+ q->hash_kind = TCA_SFQ_HASH_CLASSIC;
+ q->max_depth = 0;
+ if (opt == NULL) {
+ q->perturb_period = 0;
+ q->hash_divisor = 1024;
+ q->tail = q->limit = q->depth = 128;
+
+ } else {
+ struct tc_esfq_qopt *ctl = nla_data(opt);
+ if (ctl->quantum)
+ q->quantum = ctl->quantum;
+ 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 = esfq_check_hash(ctl->hash_kind);
+ }
+ }
+
+ 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:
+ esfq_q_destroy(q);
+ return -ENOBUFS;
+}
+
+static int esfq_init(struct Qdisc *sch, struct nlattr *opt)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ int err;
+
+ q->quantum = psched_mtu(qdisc_dev(sch)); /* default */
+ if ((err = esfq_q_init(q, opt)))
+ return err;
+
+ init_timer(&q->perturb_timer);
+ q->perturb_timer.data = (unsigned long)sch;
+ q->perturb_timer.function = esfq_perturbation;
+ if (q->perturb_period) {
+ q->perturb_timer.expires = jiffies + q->perturb_period;
+ add_timer(&q->perturb_timer);
+ }
+
+ return 0;
+}
+
+static int esfq_change(struct Qdisc *sch, struct nlattr *opt)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ struct esfq_sched_data new;
+ struct sk_buff *skb;
+ int err;
+
+ /* set up new queue */
+ memset(&new, 0, sizeof(struct esfq_sched_data));
+ new.quantum = psched_mtu(qdisc_dev(sch)); /* default */
+ if ((err = esfq_q_init(&new, opt)))
+ return err;
+
+ /* copy all packets from the old queue to the new queue */
+ sch_tree_lock(sch);
+ while ((skb = esfq_q_dequeue(q)) != NULL)
+ esfq_q_enqueue(skb, &new, ESFQ_TAIL);
+
+ /* clean up the old queue */
+ esfq_q_destroy(q);
+
+ /* copy elements of the new queue into the old queue */
+ q->perturb_period = new.perturb_period;
+ q->quantum = new.quantum;
+ q->limit = new.limit;
+ q->depth = new.depth;
+ q->hash_divisor = new.hash_divisor;
+ q->hash_kind = new.hash_kind;
+ q->tail = new.tail;
+ q->max_depth = new.max_depth;
+ q->ht = new.ht;
+ q->dep = new.dep;
+ q->next = new.next;
+ q->allot = new.allot;
+ q->hash = new.hash;
+ q->qs = new.qs;
+
+ /* finish up */
+ 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_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ unsigned char *b = skb_tail_pointer(skb);
+ 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;
+
+ NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+
+ return skb->len;
+
+nla_put_failure:
+ nlmsg_trim(skb, b);
+ 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,
+ .peek = esfq_peek,
+ .drop = esfq_drop,
+ .init = esfq_init,
+ .reset = esfq_reset,
+ .destroy = esfq_destroy,
+ .change = esfq_change,
+ .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");

@ -1,172 +0,0 @@
--- /dev/null
+++ b/net/sched/act_connmark.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/pkt_cls.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <net/netlink.h>
+#include <net/pkt_sched.h>
+#include <net/act_api.h>
+
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_core.h>
+
+#define TCA_ACT_CONNMARK 20
+
+#define CONNMARK_TAB_MASK 3
+static struct tcf_common *tcf_connmark_ht[CONNMARK_TAB_MASK + 1];
+static u32 connmark_idx_gen;
+static DEFINE_RWLOCK(connmark_lock);
+
+static struct tcf_hashinfo connmark_hash_info = {
+ .htab = tcf_connmark_ht,
+ .hmask = CONNMARK_TAB_MASK,
+ .lock = &connmark_lock,
+};
+
+static int tcf_connmark(struct sk_buff *skb, struct tc_action *a,
+ struct tcf_result *res)
+{
+ struct nf_conn *c;
+ enum ip_conntrack_info ctinfo;
+ int proto;
+ int r;
+
+ if (skb->protocol == htons(ETH_P_IP)) {
+ if (skb->len < sizeof(struct iphdr))
+ goto out;
+ proto = PF_INET;
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ if (skb->len < sizeof(struct ipv6hdr))
+ goto out;
+ proto = PF_INET6;
+ } else
+ goto out;
+
+ r = nf_conntrack_in(dev_net(skb->dev), proto, NF_INET_PRE_ROUTING, skb);
+ if (r != NF_ACCEPT)
+ goto out;
+
+ c = nf_ct_get(skb, &ctinfo);
+ if (!c)
+ goto out;
+
+ skb->mark = c->mark;
+ nf_conntrack_put(skb->nfct);
+ skb->nfct = NULL;
+
+out:
+ return TC_ACT_PIPE;
+}
+
+static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est,
+ struct tc_action *a, int ovr, int bind)
+{
+ struct tcf_common *pc;
+
+ pc = tcf_hash_create(0, est, a, sizeof(*pc), bind,
+ &connmark_idx_gen, &connmark_hash_info);
+ if (IS_ERR(pc))
+ return PTR_ERR(pc);
+
+ tcf_hash_insert(pc, &connmark_hash_info);
+
+ return ACT_P_CREATED;
+}
+
+static inline int tcf_connmark_cleanup(struct tc_action *a, int bind)
+{
+ if (a->priv)
+ return tcf_hash_release(a->priv, bind, &connmark_hash_info);
+ return 0;
+}
+
+static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
+ int bind, int ref)
+{
+ return skb->len;
+}
+
+static struct tc_action_ops act_connmark_ops = {
+ .kind = "connmark",
+ .hinfo = &connmark_hash_info,
+ .type = TCA_ACT_CONNMARK,
+ .capab = TCA_CAP_NONE,
+ .owner = THIS_MODULE,
+ .act = tcf_connmark,
+ .dump = tcf_connmark_dump,
+ .cleanup = tcf_connmark_cleanup,
+ .init = tcf_connmark_init,
+ .walk = tcf_generic_walker,
+};
+
+MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>");
+MODULE_DESCRIPTION("Connection tracking mark restoring");
+MODULE_LICENSE("GPL");
+
+static int __init connmark_init_module(void)
+{
+ return tcf_register_action(&act_connmark_ops);
+}
+
+static void __exit connmark_cleanup_module(void)
+{
+ tcf_unregister_action(&act_connmark_ops);
+}
+
+module_init(connmark_init_module);
+module_exit(connmark_cleanup_module);
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -559,6 +559,19 @@ config NET_ACT_CSUM
To compile this code as a module, choose M here: the
module will be called act_csum.
+config NET_ACT_CONNMARK
+ tristate "Connection Tracking Marking"
+ depends on NET_CLS_ACT
+ depends on NF_CONNTRACK
+ depends on NF_CONNTRACK_MARK
+ ---help---
+ Say Y here to restore the connmark from a scheduler action
+
+ If unsure, say N.
+
+ To compile this code as a module, choose M here: the
+ module will be called act_connmark.
+
config NET_CLS_IND
bool "Incoming device classification"
depends on NET_CLS_U32 || NET_CLS_FW
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit
obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o
obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
obj-$(CONFIG_NET_ACT_CSUM) += act_csum.o
+obj-$(CONFIG_NET_ACT_CONNMARK) += act_connmark.o
obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o
obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o

@ -1,132 +0,0 @@
This patch allows the user to specify desired packet types (outgoing,
broadcast, unicast, etc.) on packet sockets via setsockopt.
This can reduce the load in situations where only a limited number
of packet types are necessary
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
--- a/include/linux/if_packet.h
+++ b/include/linux/if_packet.h
@@ -29,6 +29,8 @@ struct sockaddr_ll {
/* These ones are invisible by user level */
#define PACKET_LOOPBACK 5 /* MC/BRD frame looped back */
#define PACKET_FASTROUTE 6 /* Fastrouted frame */
+#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */
+
/* Packet socket options */
@@ -49,6 +51,7 @@ struct sockaddr_ll {
#define PACKET_VNET_HDR 15
#define PACKET_TX_TIMESTAMP 16
#define PACKET_TIMESTAMP 17
+#define PACKET_RECV_TYPE 18
struct tpacket_stats {
unsigned int tp_packets;
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -205,6 +205,7 @@ struct packet_sock {
unsigned int tp_loss:1;
unsigned int tp_tstamp;
struct packet_type prot_hook ____cacheline_aligned_in_smp;
+ unsigned int pkt_type;
};
struct packet_skb_cb {
@@ -341,6 +342,7 @@ static int packet_rcv_spkt(struct sk_buf
{
struct sock *sk;
struct sockaddr_pkt *spkt;
+ struct packet_sock *po;
/*
* When we registered the protocol we saved the socket in the data
@@ -348,6 +350,7 @@ static int packet_rcv_spkt(struct sk_buf
*/
sk = pt->af_packet_priv;
+ po = pkt_sk(sk);
/*
* Yank back the headers [hope the device set this
@@ -360,7 +363,7 @@ static int packet_rcv_spkt(struct sk_buf
* so that this procedure is noop.
*/
- if (skb->pkt_type == PACKET_LOOPBACK)
+ if (!(po->pkt_type & (1 << skb->pkt_type)))
goto out;
if (!net_eq(dev_net(dev), sock_net(sk)))
@@ -539,12 +542,12 @@ static int packet_rcv(struct sk_buff *sk
int skb_len = skb->len;
unsigned int snaplen, res;
- if (skb->pkt_type == PACKET_LOOPBACK)
- goto drop;
-
sk = pt->af_packet_priv;
po = pkt_sk(sk);
+ if (!(po->pkt_type & (1 << skb->pkt_type)))
+ goto drop;
+
if (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
@@ -660,12 +663,12 @@ static int tpacket_rcv(struct sk_buff *s
struct timespec ts;
struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
- if (skb->pkt_type == PACKET_LOOPBACK)
- goto drop;
-
sk = pt->af_packet_priv;
po = pkt_sk(sk);
+ if (!(po->pkt_type & (1 << skb->pkt_type)))
+ goto drop;
+
if (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
@@ -1488,6 +1491,7 @@ static int packet_create(struct net *net
spin_lock_init(&po->bind_lock);
mutex_init(&po->pg_vec_lock);
po->prot_hook.func = packet_rcv;
+ po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK);
if (sock->type == SOCK_PACKET)
po->prot_hook.func = packet_rcv_spkt;
@@ -2057,6 +2061,16 @@ packet_setsockopt(struct socket *sock, i
po->tp_tstamp = val;
return 0;
}
+ case PACKET_RECV_TYPE:
+ {
+ unsigned int val;
+ if (optlen != sizeof(val))
+ return -EINVAL;
+ if (copy_from_user(&val, optval, sizeof(val)))
+ return -EFAULT;
+ po->pkt_type = val & ~PACKET_LOOPBACK;
+ return 0;
+ }
default:
return -ENOPROTOOPT;
}
@@ -2114,6 +2128,13 @@ static int packet_getsockopt(struct sock
data = &val;
break;
+ case PACKET_RECV_TYPE:
+ if (len > sizeof(unsigned int))
+ len = sizeof(unsigned int);
+ val = po->pkt_type;
+
+ data = &val;
+ break;
case PACKET_VERSION:
if (len > sizeof(int))
len = sizeof(int);

@ -1,15 +0,0 @@
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -73,7 +73,11 @@ int br_handle_frame_finish(struct sk_buf
dst = NULL;
- if (is_multicast_ether_addr(dest)) {
+ if (skb->protocol == htons(ETH_P_PAE)) {
+ skb2 = skb;
+ /* Do not forward 802.1x/EAP frames */
+ skb = NULL;
+ } else if (is_multicast_ether_addr(dest)) {
mdst = br_mdb_get(br, skb);
if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
if ((mdst && !hlist_unhashed(&mdst->mglist)) ||

@ -1,11 +0,0 @@
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -60,7 +60,7 @@ int br_handle_frame_finish(struct sk_buf
br_multicast_rcv(br, p, skb))
goto drop;
- if (p->state == BR_STATE_LEARNING)
+ if ((p->state == BR_STATE_LEARNING) && skb->protocol != htons(ETH_P_PAE))
goto drop;
BR_INPUT_SKB_CB(skb)->brdev = br->dev;

@ -1,103 +0,0 @@
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -132,6 +132,7 @@ struct net_bridge_port
unsigned long flags;
#define BR_HAIRPIN_MODE 0x00000001
+#define BR_ISOLATE_MODE 0x00000002
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
u32 multicast_startup_queries_sent;
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -159,6 +159,22 @@ static ssize_t store_hairpin_mode(struct
static BRPORT_ATTR(hairpin_mode, S_IRUGO | S_IWUSR,
show_hairpin_mode, store_hairpin_mode);
+static ssize_t show_isolate_mode(struct net_bridge_port *p, char *buf)
+{
+ int isolate_mode = (p->flags & BR_ISOLATE_MODE) ? 1 : 0;
+ return sprintf(buf, "%d\n", isolate_mode);
+}
+static ssize_t store_isolate_mode(struct net_bridge_port *p, unsigned long v)
+{
+ if (v)
+ p->flags |= BR_ISOLATE_MODE;
+ else
+ p->flags &= ~BR_ISOLATE_MODE;
+ return 0;
+}
+static BRPORT_ATTR(isolate_mode, S_IRUGO | S_IWUSR,
+ show_isolate_mode, store_isolate_mode);
+
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
{
@@ -191,6 +207,7 @@ static struct brport_attribute *brport_a
&brport_attr_hold_timer,
&brport_attr_flush,
&brport_attr_hairpin_mode,
+ &brport_attr_isolate_mode,
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
&brport_attr_multicast_router,
#endif
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -91,7 +91,8 @@ int br_handle_frame_finish(struct sk_buf
skb2 = skb;
br->dev->stats.multicast++;
- } else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) {
+ } else if ((p->flags & BR_ISOLATE_MODE) ||
+ ((dst = __br_fdb_get(br, dest)) && dst->is_local)) {
skb2 = skb;
/* Do not forward the packet since it's local. */
skb = NULL;
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -113,7 +113,7 @@ void br_deliver(const struct net_bridge_
/* called with rcu_read_lock */
void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0)
{
- if (should_deliver(to, skb)) {
+ if (should_deliver(to, skb) && !(to->flags & BR_ISOLATE_MODE)) {
if (skb0)
deliver_clone(to, skb, __br_forward);
else
@@ -168,7 +168,8 @@ out:
static void br_flood(struct net_bridge *br, struct sk_buff *skb,
struct sk_buff *skb0,
void (*__packet_hook)(const struct net_bridge_port *p,
- struct sk_buff *skb))
+ struct sk_buff *skb),
+ bool forward)
{
struct net_bridge_port *p;
struct net_bridge_port *prev;
@@ -176,6 +177,9 @@ static void br_flood(struct net_bridge *
prev = NULL;
list_for_each_entry_rcu(p, &br->port_list, list) {
+ if (forward && (p->flags & BR_ISOLATE_MODE))
+ continue;
+
prev = maybe_deliver(prev, p, skb, __packet_hook);
if (IS_ERR(prev))
goto out;
@@ -199,14 +203,14 @@ out:
/* called with rcu_read_lock */
void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb)
{
- br_flood(br, skb, NULL, __br_deliver);
+ br_flood(br, skb, NULL, __br_deliver, false);
}
/* called under bridge lock */
void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
struct sk_buff *skb2)
{
- br_flood(br, skb, skb2, __br_forward);
+ br_flood(br, skb, skb2, __br_forward, true);
}
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING

@ -1,20 +0,0 @@
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -855,7 +855,7 @@ static int pppoe_sendmsg(struct kiocb *i
goto end;
- skb = sock_wmalloc(sk, total_len + dev->hard_header_len + 32,
+ skb = sock_wmalloc(sk, total_len + dev->hard_header_len + 32 + NET_SKB_PAD,
0, GFP_KERNEL);
if (!skb) {
error = -ENOMEM;
@@ -863,7 +863,7 @@ static int pppoe_sendmsg(struct kiocb *i
}
/* Reserve space for headers. */
- skb_reserve(skb, dev->hard_header_len);
+ skb_reserve(skb, dev->hard_header_len + NET_SKB_PAD);
skb_reset_network_header(skb);
skb->dev = dev;

@ -1,11 +0,0 @@
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -145,7 +145,7 @@ static inline bool dev_xmit_complete(int
*/
#if defined(CONFIG_WLAN) || defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
-# if defined(CONFIG_MAC80211_MESH)
+# if 1 || defined(CONFIG_MAC80211_MESH)
# define LL_MAX_HEADER 128
# else
# define LL_MAX_HEADER 96

@ -1,25 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -13,6 +13,12 @@ menuconfig PHYLIB
if PHYLIB
+config SWCONFIG
+ tristate "Switch configuration API"
+ ---help---
+ Switch configuration API using netlink. This allows
+ you to configure the VLAN features of certain switches.
+
comment "MII PHY device drivers"
config MARVELL_PHY
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -3,6 +3,7 @@
libphy-objs := phy.o phy_device.o mdio_bus.o
obj-$(CONFIG_PHYLIB) += libphy.o
+obj-$(CONFIG_SWCONFIG) += swconfig.o
obj-$(CONFIG_MARVELL_PHY) += marvell.o
obj-$(CONFIG_DAVICOM_PHY) += davicom.o
obj-$(CONFIG_CICADA_PHY) += cicada.o

@ -1,81 +0,0 @@
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -297,6 +297,50 @@ int phy_ethtool_gset(struct phy_device *
}
EXPORT_SYMBOL(phy_ethtool_gset);
+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
+{
+ u32 cmd;
+ int tmp;
+ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ struct ethtool_value edata = { ETHTOOL_GLINK };
+
+ if (get_user(cmd, (u32 *) useraddr))
+ return -EFAULT;
+
+ switch (cmd) {
+ case ETHTOOL_GSET:
+ phy_ethtool_gset(phydev, &ecmd);
+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
+ return -EFAULT;
+ return 0;
+
+ case ETHTOOL_SSET:
+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
+ return -EFAULT;
+ return phy_ethtool_sset(phydev, &ecmd);
+
+ case ETHTOOL_NWAY_RST:
+ /* if autoneg is off, it's an error */
+ tmp = phy_read(phydev, MII_BMCR);
+ if (tmp & BMCR_ANENABLE) {
+ tmp |= (BMCR_ANRESTART);
+ phy_write(phydev, MII_BMCR, tmp);
+ return 0;
+ }
+ return -EINVAL;
+
+ case ETHTOOL_GLINK:
+ edata.data = (phy_read(phydev,
+ MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
+
+ return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(phy_ethtool_ioctl);
+
/**
* phy_mii_ioctl - generic PHY MII ioctl interface
* @phydev: the phy_device struct
@@ -351,7 +395,7 @@ int phy_mii_ioctl(struct phy_device *phy
}
phy_write(phydev, mii_data->reg_num, val);
-
+
if (mii_data->reg_num == MII_BMCR &&
val & BMCR_RESET &&
phydev->drv->config_init) {
@@ -470,7 +514,7 @@ static void phy_force_reduction(struct p
int idx;
idx = phy_find_setting(phydev->speed, phydev->duplex);
-
+
idx++;
idx = phy_find_valid(idx, phydev->supported);
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -508,6 +508,7 @@ void phy_start_machine(struct phy_device
void phy_stop_machine(struct phy_device *phydev);
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
int phy_mii_ioctl(struct phy_device *phydev,
struct ifreq *ifr, int cmd);
int phy_start_interrupts(struct phy_device *phydev);

@ -1,45 +0,0 @@
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -386,9 +386,18 @@ struct phy_driver {
*/
int (*config_aneg)(struct phy_device *phydev);
+ /* Determine if autonegotiation is done */
+ int (*aneg_done)(struct phy_device *phydev);
+
/* Determines the negotiated speed and duplex */
int (*read_status)(struct phy_device *phydev);
+ /*
+ * Update the value in phydev->link to reflect the
+ * current link value
+ */
+ int (*update_link)(struct phy_device *phydev);
+
/* Clears any pending interrupts */
int (*ack_interrupt)(struct phy_device *phydev);
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -715,6 +715,9 @@ int genphy_update_link(struct phy_device
{
int status;
+ if (phydev->drv->update_link)
+ return phydev->drv->update_link(phydev);
+
/* Do a fake read */
status = phy_read(phydev, MII_BMSR);
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -106,6 +106,9 @@ static inline int phy_aneg_done(struct p
{
int retval;
+ if (phydev->drv->aneg_done)
+ return phydev->drv->aneg_done(phydev);
+
retval = phy_read(phydev, MII_BMSR);
return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE);

@ -1,26 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -98,6 +98,13 @@ config MICREL_PHY
---help---
Supports the KSZ9021, VSC8201, KS8001 PHYs.
+config ADM6996_PHY
+ tristate "Driver for ADM6996 switches"
+ select SWCONFIG
+ ---help---
+ Currently supports the ADM6996FC and ADM6996M switches.
+ Support for FC is very limited.
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_VITESSE_PHY) += vitesse.o
obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
+obj-$(CONFIG_ADM6996_PHY) += adm6996.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o

@ -1,63 +0,0 @@
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -149,6 +149,18 @@ int phy_scan_fixups(struct phy_device *p
}
EXPORT_SYMBOL(phy_scan_fixups);
+static int generic_receive_skb(struct sk_buff *skb)
+{
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ return netif_receive_skb(skb);
+}
+
+static int generic_rx(struct sk_buff *skb)
+{
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ return netif_rx(skb);
+}
+
static struct phy_device* phy_device_create(struct mii_bus *bus,
int addr, int phy_id)
{
@@ -180,6 +192,8 @@ static struct phy_device* phy_device_cre
dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
dev->state = PHY_DOWN;
+ dev->netif_receive_skb = &generic_receive_skb;
+ dev->netif_rx = &generic_rx;
mutex_init(&dev->lock);
INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -332,6 +332,20 @@ struct phy_device {
void (*adjust_link)(struct net_device *dev);
void (*adjust_state)(struct net_device *dev);
+
+ /*
+ * By default these point to the original functions
+ * with the same name. adding them to the phy_device
+ * allows the phy driver to override them for packet
+ * mangling if the ethernet driver supports it
+ * This is required to support some really horrible
+ * switches such as the Marvell 88E6060
+ */
+ int (*netif_receive_skb)(struct sk_buff *skb);
+ int (*netif_rx)(struct sk_buff *skb);
+
+ /* alignment offset for packets */
+ int pkt_align;
};
#define to_phy_device(d) container_of(d, struct phy_device, dev)
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -957,6 +957,7 @@ struct net_device {
void *ax25_ptr; /* AX.25 specific data */
struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data,
assign before registering */
+ void *phy_ptr; /* PHY device specific data */
/*
* Cache lines mostly used on receive path (including eth_type_trans())

@ -1,22 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -105,6 +105,9 @@ config ADM6996_PHY
Currently supports the ADM6996FC and ADM6996M switches.
Support for FC is very limited.
+config MVSWITCH_PHY
+ tristate "Driver for Marvell 88E6060 switches"
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_ADM6996_PHY) += adm6996.o
+obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o

@ -1,23 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -108,6 +108,10 @@ config ADM6996_PHY
config MVSWITCH_PHY
tristate "Driver for Marvell 88E6060 switches"
+config IP17XX_PHY
+ tristate "Driver for IC+ IP17xx switches"
+ select SWCONFIG
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_ADM6996_PHY) += adm6996.o
obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
+obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o

@ -1,23 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -112,6 +112,10 @@ config IP17XX_PHY
tristate "Driver for IC+ IP17xx switches"
select SWCONFIG
+config AR8216_PHY
+ tristate "Driver for Atheros AR8216 switches"
+ select SWCONFIG
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_ADM6996_PHY) += adm6996.o
obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
+obj-$(CONFIG_AR8216_PHY) += ar8216.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o

@ -1,23 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -116,6 +116,10 @@ config AR8216_PHY
tristate "Driver for Atheros AR8216 switches"
select SWCONFIG
+config RTL8306_PHY
+ tristate "Driver for Realtek RTL8306S switches"
+ select SWCONFIG
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_AR8216_PHY) += ar8216.o
+obj-$(CONFIG_RTL8306_PHY) += rtl8306.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o

@ -1,44 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -158,4 +158,29 @@ config MDIO_OCTEON
If in doubt, say Y.
+config RTL8366_SMI
+ tristate "Driver for the RTL8366 SMI interface"
+ depends on GENERIC_GPIO
+ ---help---
+ This module implements the SMI interface protocol which is used
+ by some RTL8366 ethernet switch devices via the generic GPIO API.
+
+if RTL8366_SMI
+
+config RTL8366S_PHY
+ tristate "Driver for the Realtek RTL8366S switch"
+ select SWCONFIG
+
+config RTL8366RB_PHY
+ tristate "Driver for the Realtek RTL8366RB switch"
+ select SWCONFIG
+
+config RTL8366S_PHY_DEBUG_FS
+ bool "RTL8366 switch driver DEBUG_FS support"
+ depends on RTL8366S_PHY || RTL8366RB_PHY
+ depends on DEBUG_FS
+ default n
+
+endif # RTL8366_SMI
+
endif # PHYLIB
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -20,6 +20,9 @@ obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_AR8216_PHY) += ar8216.o
obj-$(CONFIG_RTL8306_PHY) += rtl8306.o
+obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o
+obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o
+obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save