]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branches 'x86/apic', 'x86/cpu', 'x86/fixmap', 'x86/mm', 'x86/sched', 'x86/setup...
authorIngo Molnar <mingo@elte.hu>
Wed, 4 Mar 2009 01:22:31 +0000 (02:22 +0100)
committerIngo Molnar <mingo@elte.hu>
Wed, 4 Mar 2009 01:22:31 +0000 (02:22 +0100)
160 files changed:
Documentation/scsi/cxgb3i.txt
Documentation/x86/boot.txt
MAINTAINERS
arch/mips/include/asm/seccomp.h
arch/powerpc/include/asm/compat.h
arch/powerpc/include/asm/seccomp.h
arch/sparc/include/asm/compat.h
arch/sparc/include/asm/seccomp.h
arch/x86/Kconfig
arch/x86/boot/compressed/Makefile
arch/x86/boot/compressed/misc.c
arch/x86/include/asm/apic.h
arch/x86/include/asm/boot.h
arch/x86/include/asm/fixmap.h
arch/x86/include/asm/fixmap_32.h [deleted file]
arch/x86/include/asm/fixmap_64.h [deleted file]
arch/x86/include/asm/numa_32.h
arch/x86/include/asm/seccomp_32.h
arch/x86/include/asm/seccomp_64.h
arch/x86/include/asm/setup.h
arch/x86/include/asm/uaccess_32.h
arch/x86/include/asm/uaccess_64.h
arch/x86/include/asm/uv/uv.h
arch/x86/kernel/Makefile
arch/x86/kernel/apic/apic_flat_64.c
arch/x86/kernel/apic/bigsmp_32.c
arch/x86/kernel/apic/es7000_32.c
arch/x86/kernel/apic/numaq_32.c
arch/x86/kernel/apic/probe_32.c
arch/x86/kernel/apic/probe_64.c
arch/x86/kernel/apic/summit_32.c
arch/x86/kernel/apic/x2apic_cluster.c
arch/x86/kernel/apic/x2apic_phys.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/proc.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/setup.c
arch/x86/kernel/signal.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/vsmp_64.c
arch/x86/mm/Makefile
arch/x86/mm/highmem_32.c
arch/x86/mm/init.c [new file with mode: 0644]
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c
arch/x86/mm/numa_32.c
arch/x86/mm/pgtable.c
arch/x86/mm/pgtable_32.c
arch/x86/oprofile/op_model_ppro.c
drivers/gpu/drm/drm_bufs.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_lock.c
drivers/gpu/drm/drm_stub.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_irq.c
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/bf54x-keys.c
drivers/input/keyboard/corgikbd.c
drivers/input/keyboard/omap-keypad.c
drivers/input/keyboard/spitzkbd.c
drivers/input/mouse/Kconfig
drivers/input/mouse/elantech.c
drivers/input/mouse/pxa930_trkball.c
drivers/input/mouse/synaptics.c
drivers/input/serio/ambakmi.c
drivers/input/serio/gscps2.c
drivers/input/serio/sa1111ps2.c
drivers/input/touchscreen/atmel_tsadcc.c
drivers/input/touchscreen/corgi_ts.c
drivers/input/touchscreen/tsc2007.c
drivers/input/touchscreen/usbtouchscreen.c
drivers/media/video/uvc/uvc_status.c
drivers/message/fusion/mptbase.c
drivers/mmc/host/sdhci-pci.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/net/b44.c
drivers/net/gianfar.c
drivers/net/hp-plus.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/r8169.c
drivers/net/usb/asix.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/usbnet.c
drivers/net/usb/zaurus.c
drivers/net/veth.c
drivers/net/wireless/ath9k/main.c
drivers/net/wireless/libertas/ethtool.c
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/persistcfg.c
drivers/net/wireless/libertas/scan.c
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/libertas/wext.c
drivers/net/wireless/orinoco/orinoco.c
drivers/net/wireless/rtl818x/rtl8187_dev.c
drivers/scsi/cxgb3i/cxgb3i.h
drivers/scsi/cxgb3i/cxgb3i_ddp.c
drivers/scsi/cxgb3i/cxgb3i_ddp.h
drivers/scsi/cxgb3i/cxgb3i_init.c
drivers/scsi/cxgb3i/cxgb3i_iscsi.c
drivers/scsi/cxgb3i/cxgb3i_offload.c
drivers/scsi/cxgb3i/cxgb3i_offload.h
drivers/scsi/cxgb3i/cxgb3i_pdu.c
drivers/scsi/cxgb3i/cxgb3i_pdu.h
drivers/scsi/hptiop.c
drivers/scsi/scsi_lib.c
drivers/scsi/sd.c
fs/Makefile
fs/ext4/balloc.c
fs/ext4/inode.c
fs/ext4/super.c
include/linux/Kbuild
include/linux/dcbnl.h
include/linux/decompress/bunzip2.h [new file with mode: 0644]
include/linux/decompress/generic.h [new file with mode: 0644]
include/linux/decompress/inflate.h [new file with mode: 0644]
include/linux/decompress/mm.h [new file with mode: 0644]
include/linux/decompress/unlzma.h [new file with mode: 0644]
include/linux/io-mapping.h
include/linux/netfilter/xt_NFLOG.h
include/linux/uaccess.h
include/net/netfilter/nf_conntrack_core.h
init/Kconfig
init/do_mounts_rd.c
init/initramfs.c
kernel/seccomp.c
lib/Kconfig
lib/Makefile
lib/decompress.c [new file with mode: 0644]
lib/decompress_bunzip2.c [new file with mode: 0644]
lib/decompress_inflate.c [new file with mode: 0644]
lib/decompress_unlzma.c [new file with mode: 0644]
lib/zlib_inflate/inflate.h
lib/zlib_inflate/inftrees.h
mm/filemap.c
mm/filemap_xip.c
net/8021q/vlan_core.c
net/core/dev.c
net/ipv4/tcp_input.c
net/ipv4/tcp_scalable.c
net/ipv6/inet6_hashtables.c
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
net/netfilter/nfnetlink_log.c
net/netfilter/x_tables.c
net/netfilter/xt_recent.c
net/sched/sch_drr.c
scripts/Makefile.lib
scripts/bin_size [new file with mode: 0644]
scripts/gen_initramfs_list.sh
security/selinux/netlabel.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
usr/Kconfig
usr/Makefile
usr/initramfs_data.S
usr/initramfs_data.bz2.S [new file with mode: 0644]
usr/initramfs_data.gz.S [new file with mode: 0644]
usr/initramfs_data.lzma.S [new file with mode: 0644]

index 8141fa01978e0d7392390e68009c0b612ba0aa6f..7ac8032ee9b2a5f082554386c46df084fe993a5b 100644 (file)
@@ -4,7 +4,7 @@ Introduction
 ============
 
 The Chelsio T3 ASIC based Adapters (S310, S320, S302, S304, Mezz cards, etc.
-series of products) supports iSCSI acceleration and iSCSI Direct Data Placement
+series of products) support iSCSI acceleration and iSCSI Direct Data Placement
 (DDP) where the hardware handles the expensive byte touching operations, such
 as CRC computation and verification, and direct DMA to the final host memory
 destination:
@@ -31,9 +31,9 @@ destination:
          the TCP segments onto the wire. It handles TCP retransmission if
          needed.
 
-         On receving, S3 h/w recovers the iSCSI PDU by reassembling TCP
+         On receiving, S3 h/w recovers the iSCSI PDU by reassembling TCP
          segments, separating the header and data, calculating and verifying
-         the digests, then forwards the header to the host. The payload data,
+         the digests, then forwarding the header to the host. The payload data,
          if possible, will be directly placed into the pre-posted host DDP
          buffer. Otherwise, the payload data will be sent to the host too.
 
@@ -68,9 +68,8 @@ The following steps need to be taken to accelerates the open-iscsi initiator:
        sure the ip address is unique in the network.
 
 3. edit /etc/iscsi/iscsid.conf
-   The default setting for MaxRecvDataSegmentLength (131072) is too big,
-   replace "node.conn[0].iscsi.MaxRecvDataSegmentLength" to be a value no
-   bigger than 15360 (for example 8192):
+   The default setting for MaxRecvDataSegmentLength (131072) is too big;
+   replace with a value no bigger than 15360 (for example 8192):
 
        node.conn[0].iscsi.MaxRecvDataSegmentLength = 8192
 
index 12299697b7cdb29feb8055889e2563a8bdfccefb..e0203662f9e9f8a1a907060437f3fcdf907e2667 100644 (file)
@@ -543,7 +543,10 @@ Protocol:  2.08+
 
   The payload may be compressed. The format of both the compressed and
   uncompressed data should be determined using the standard magic
-  numbers. Currently only gzip compressed ELF is used.
+  numbers.  The currently supported compression formats are gzip
+  (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A) and LZMA
+  (magic number 5D 00).  The uncompressed payload is currently always ELF
+  (magic number 7F 45 4C 46).
   
 Field name:    payload_length
 Type:          read
index 59fd2d1d94a772a6262669ff8947b35b4bbd0f7a..1c2ca1dc66f2006765dba54bb05edf8a5b57d258 100644 (file)
@@ -2464,7 +2464,7 @@ S:        Maintained
 
 ISDN SUBSYSTEM
 P:     Karsten Keil
-M:     kkeil@suse.de
+M:     isdn@linux-pingi.de
 L:     isdn4linux@listserv.isdn4linux.de (subscribers-only)
 W:     http://www.isdn4linux.de
 T:     git kernel.org:/pub/scm/linux/kernel/kkeil/isdn-2.6.git
index 36ed44070256243fe1bac9f7618154481fabd7ef..a6772e9507f5ac109d5422d66c1184dcbbc7839d 100644 (file)
@@ -1,6 +1,5 @@
 #ifndef __ASM_SECCOMP_H
 
-#include <linux/thread_info.h>
 #include <linux/unistd.h>
 
 #define __NR_seccomp_read __NR_read
index d811a8cd7b58c9397200be83cf0ee333c313e037..4774c2f92232b8ce98177d555b4d2c592dc076e5 100644 (file)
@@ -210,5 +210,10 @@ struct compat_shmid64_ds {
        compat_ulong_t __unused6;
 };
 
+static inline int is_compat_task(void)
+{
+       return test_thread_flag(TIF_32BIT);
+}
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_COMPAT_H */
index 853765eb1f6584e23edc6f1c8c3272814c0fa395..00c1d9133cfe12fa17db2d6f25a0f34c3e72ce20 100644 (file)
@@ -1,10 +1,6 @@
 #ifndef _ASM_POWERPC_SECCOMP_H
 #define _ASM_POWERPC_SECCOMP_H
 
-#ifdef __KERNEL__
-#include <linux/thread_info.h>
-#endif
-
 #include <linux/unistd.h>
 
 #define __NR_seccomp_read __NR_read
index f260b58f5ce9d34ac224d2781bf4e0ac277849d4..0e706257918f35397b10657be3b95538ef23e45b 100644 (file)
@@ -240,4 +240,9 @@ struct compat_shmid64_ds {
        unsigned int    __unused2;
 };
 
+static inline int is_compat_task(void)
+{
+       return test_thread_flag(TIF_32BIT);
+}
+
 #endif /* _ASM_SPARC64_COMPAT_H */
index 7fcd9968192bc0b26b1fe7d1c67a1e3f08b5359c..adca1bce41d4a2b96632a1dfdcdab457df916bf1 100644 (file)
@@ -1,11 +1,5 @@
 #ifndef _ASM_SECCOMP_H
 
-#include <linux/thread_info.h> /* already defines TIF_32BIT */
-
-#ifndef TIF_32BIT
-#error "unexpected TIF_32BIT on sparc64"
-#endif
-
 #include <linux/unistd.h>
 
 #define __NR_seccomp_read __NR_read
index d9084320279e6e1cc07933dd088d9ac3dd612c63..469f3450bf813af117549a3234b73be12041d0d3 100644 (file)
@@ -40,6 +40,9 @@ config X86
        select HAVE_GENERIC_DMA_COHERENT if X86_32
        select HAVE_EFFICIENT_UNALIGNED_ACCESS
        select USER_STACKTRACE_SUPPORT
+       select HAVE_KERNEL_GZIP
+       select HAVE_KERNEL_BZIP2
+       select HAVE_KERNEL_LZMA
 
 config ARCH_DEFCONFIG
        string
index 1771c804e02f57b26d5d4f9f1db8cdb1f7a4ed62..3ca4c194b8e588217dabef4dc5da54bcb2489edd 100644 (file)
@@ -4,7 +4,7 @@
 # create a compressed vmlinux image from the original vmlinux
 #
 
-targets := vmlinux vmlinux.bin vmlinux.bin.gz head_$(BITS).o misc.o piggy.o
+targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o
 
 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
@@ -47,18 +47,35 @@ ifeq ($(CONFIG_X86_32),y)
 ifdef CONFIG_RELOCATABLE
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE
        $(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin.all FORCE
+       $(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin.all FORCE
+       $(call if_changed,lzma)
 else
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
        $(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+       $(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+       $(call if_changed,lzma)
 endif
 LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
 
 else
+
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
        $(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+       $(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+       $(call if_changed,lzma)
 
 LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T
 endif
 
-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+suffix_$(CONFIG_KERNEL_GZIP)  = gz
+suffix_$(CONFIG_KERNEL_BZIP2) = bz2
+suffix_$(CONFIG_KERNEL_LZMA)  = lzma
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE
        $(call if_changed,ld)
index da062216948a6951990f354fa11ee9125b865fe7..e45be73684ffe3bd5559029eb86cf66ec00ff250 100644 (file)
 /*
  * gzip declarations
  */
-
-#define OF(args)       args
 #define STATIC         static
 
 #undef memset
 #undef memcpy
 #define memzero(s, n)  memset((s), 0, (n))
 
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-/*
- * Window size must be at least 32k, and a power of two.
- * We don't actually have a window just a huge output buffer,
- * so we report a 2G window size, as that should always be
- * larger than our output buffer:
- */
-#define WSIZE          0x80000000
-
-/* Input buffer: */
-static unsigned char   *inbuf;
-
-/* Sliding window buffer (and final output buffer): */
-static unsigned char   *window;
-
-/* Valid bytes in inbuf: */
-static unsigned                insize;
-
-/* Index of next byte to be processed in inbuf: */
-static unsigned                inptr;
-
-/* Bytes in output buffer: */
-static unsigned                outcnt;
-
-/* gzip flag byte */
-#define ASCII_FLAG     0x01 /* bit 0 set: file probably ASCII text */
-#define CONTINUATION   0x02 /* bit 1 set: continuation of multi-part gz file */
-#define EXTRA_FIELD    0x04 /* bit 2 set: extra field present */
-#define ORIG_NAM       0x08 /* bit 3 set: original file name present */
-#define COMMENT                0x10 /* bit 4 set: file comment present */
-#define ENCRYPTED      0x20 /* bit 5 set: file is encrypted */
-#define RESERVED       0xC0 /* bit 6, 7:  reserved */
-
-#define get_byte()     (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  define Assert(cond, msg) do { if (!(cond)) error(msg); } while (0)
-#  define Trace(x)     do { fprintf x; } while (0)
-#  define Tracev(x)    do { if (verbose) fprintf x ; } while (0)
-#  define Tracevv(x)   do { if (verbose > 1) fprintf x ; } while (0)
-#  define Tracec(c, x) do { if (verbose && (c)) fprintf x ; } while (0)
-#  define Tracecv(c, x)        do { if (verbose > 1 && (c)) fprintf x ; } while (0)
-#else
-#  define Assert(cond, msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c, x)
-#  define Tracecv(c, x)
-#endif
 
-static int  fill_inbuf(void);
-static void flush_window(void);
 static void error(char *m);
 
 /*
@@ -189,13 +131,8 @@ static void error(char *m);
 static struct boot_params *real_mode;          /* Pointer to real-mode data */
 static int quiet;
 
-extern unsigned char input_data[];
-extern int input_len;
-
-static long bytes_out;
-
 static void *memset(void *s, int c, unsigned n);
-static void *memcpy(void *dest, const void *src, unsigned n);
+void *memcpy(void *dest, const void *src, unsigned n);
 
 static void __putstr(int, const char *);
 #define putstr(__x)  __putstr(0, __x)
@@ -213,7 +150,17 @@ static char *vidmem;
 static int vidport;
 static int lines, cols;
 
-#include "../../../../lib/inflate.c"
+#ifdef CONFIG_KERNEL_GZIP
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_BZIP2
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
 
 static void scroll(void)
 {
@@ -282,7 +229,7 @@ static void *memset(void *s, int c, unsigned n)
        return s;
 }
 
-static void *memcpy(void *dest, const void *src, unsigned n)
+void *memcpy(void *dest, const void *src, unsigned n)
 {
        int i;
        const char *s = src;
@@ -293,38 +240,6 @@ static void *memcpy(void *dest, const void *src, unsigned n)
        return dest;
 }
 
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-static int fill_inbuf(void)
-{
-       error("ran out of input data");
-       return 0;
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
-{
-       /* With my window equal to my output buffer
-        * I only need to compute the crc here.
-        */
-       unsigned long c = crc;         /* temporary variable */
-       unsigned n;
-       unsigned char *in, ch;
-
-       in = window;
-       for (n = 0; n < outcnt; n++) {
-               ch = *in++;
-               c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-       }
-       crc = c;
-       bytes_out += (unsigned long)outcnt;
-       outcnt = 0;
-}
 
 static void error(char *x)
 {
@@ -407,12 +322,8 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
        lines = real_mode->screen_info.orig_video_lines;
        cols = real_mode->screen_info.orig_video_cols;
 
-       window = output;                /* Output buffer (Normally at 1M) */
        free_mem_ptr     = heap;        /* Heap */
        free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
-       inbuf  = input_data;            /* Input buffer */
-       insize = input_len;
-       inptr  = 0;
 
 #ifdef CONFIG_X86_64
        if ((unsigned long)output & (__KERNEL_ALIGN - 1))
@@ -430,10 +341,9 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
 #endif
 #endif
 
-       makecrc();
        if (!quiet)
                putstr("\nDecompressing Linux... ");
-       gunzip();
+       decompress(input_data, input_len, NULL, NULL, output, NULL, error);
        parse_elf(output);
        if (!quiet)
                putstr("done.\nBooting the kernel.\n");
index a6208dc746338fa1fd10810e29b1a4dd108998e9..4ef949c1972e6bfacb80d477fefc427cadfecd8f 100644 (file)
@@ -75,7 +75,14 @@ static inline void default_inquire_remote_apic(int apicid)
 #define setup_secondary_clock setup_secondary_APIC_clock
 #endif
 
+#ifdef CONFIG_X86_VSMP
 extern int is_vsmp_box(void);
+#else
+static inline int is_vsmp_box(void)
+{
+       return 0;
+}
+#endif
 extern void xapic_wait_icr_idle(void);
 extern u32 safe_xapic_wait_icr_idle(void);
 extern void xapic_icr_write(u32, u32);
@@ -306,7 +313,7 @@ struct apic {
        void (*send_IPI_self)(int vector);
 
        /* wakeup_secondary_cpu */
-       int (*wakeup_cpu)(int apicid, unsigned long start_eip);
+       int (*wakeup_secondary_cpu)(int apicid, unsigned long start_eip);
 
        int trampoline_phys_low;
        int trampoline_phys_high;
@@ -324,8 +331,21 @@ struct apic {
        u32 (*safe_wait_icr_idle)(void);
 };
 
+/*
+ * Pointer to the local APIC driver in use on this system (there's
+ * always just one such driver in use - the kernel decides via an
+ * early probing process which one it picks - and then sticks to it):
+ */
 extern struct apic *apic;
 
+/*
+ * APIC functionality to boot other CPUs - only used on SMP:
+ */
+#ifdef CONFIG_SMP
+extern atomic_t init_deasserted;
+extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
+#endif
+
 static inline u32 apic_read(u32 reg)
 {
        return apic->read(reg);
@@ -384,9 +404,7 @@ static inline unsigned default_get_apic_id(unsigned long x)
 #define DEFAULT_TRAMPOLINE_PHYS_LOW            0x467
 #define DEFAULT_TRAMPOLINE_PHYS_HIGH           0x469
 
-#ifdef CONFIG_X86_32
-extern void es7000_update_apic_to_cluster(void);
-#else
+#ifdef CONFIG_X86_64
 extern struct apic apic_flat;
 extern struct apic apic_physflat;
 extern struct apic apic_x2apic_cluster;
index dd61616cb73d1d3aab1bb7d5c2dfd8923ec6e672..6526cf08b0e4604583b1b3e8c972e0f31fe1b44e 100644 (file)
 #define EXTENDED_VGA   0xfffe          /* 80x50 mode */
 #define ASK_VGA                0xfffd          /* ask for it at bootup */
 
+#ifdef __KERNEL__
+
 /* Physical address where kernel should be loaded. */
 #define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
                                + (CONFIG_PHYSICAL_ALIGN - 1)) \
                                & ~(CONFIG_PHYSICAL_ALIGN - 1))
 
+#ifdef CONFIG_KERNEL_BZIP2
+#define BOOT_HEAP_SIZE             0x400000
+#else /* !CONFIG_KERNEL_BZIP2 */
+
 #ifdef CONFIG_X86_64
 #define BOOT_HEAP_SIZE 0x7000
-#define BOOT_STACK_SIZE        0x4000
 #else
 #define BOOT_HEAP_SIZE 0x4000
+#endif
+
+#endif /* !CONFIG_KERNEL_BZIP2 */
+
+#ifdef CONFIG_X86_64
+#define BOOT_STACK_SIZE        0x4000
+#else
 #define BOOT_STACK_SIZE        0x1000
 #endif
 
+#endif /* __KERNEL__ */
+
 #endif /* _ASM_X86_BOOT_H */
index 23696d44a0af85fb2d3bf407d8b44def4874bf81..dca8f03da5b29574af570717c435ea3a5320f22e 100644 (file)
+/*
+ * fixmap.h: compile-time virtual memory allocation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 Ingo Molnar
+ *
+ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+ * x86_32 and x86_64 integration by Gustavo F. Padovan, February 2009
+ */
+
 #ifndef _ASM_X86_FIXMAP_H
 #define _ASM_X86_FIXMAP_H
 
+#ifndef __ASSEMBLY__
+#include <linux/kernel.h>
+#include <asm/acpi.h>
+#include <asm/apicdef.h>
+#include <asm/page.h>
+#ifdef CONFIG_X86_32
+#include <linux/threads.h>
+#include <asm/kmap_types.h>
+#else
+#include <asm/vsyscall.h>
+#ifdef CONFIG_EFI
+#include <asm/efi.h>
+#endif
+#endif
+
+/*
+ * We can't declare FIXADDR_TOP as variable for x86_64 because vsyscall
+ * uses fixmaps that relies on FIXADDR_TOP for proper address calculation.
+ * Because of this, FIXADDR_TOP x86 integration was left as later work.
+ */
+#ifdef CONFIG_X86_32
+/* used by vmalloc.c, vsyscall.lds.S.
+ *
+ * Leave one empty page between vmalloc'ed areas and
+ * the start of the fixmap.
+ */
+extern unsigned long __FIXADDR_TOP;
+#define FIXADDR_TOP    ((unsigned long)__FIXADDR_TOP)
+
+#define FIXADDR_USER_START     __fix_to_virt(FIX_VDSO)
+#define FIXADDR_USER_END       __fix_to_virt(FIX_VDSO - 1)
+#else
+#define FIXADDR_TOP    (VSYSCALL_END-PAGE_SIZE)
+
+/* Only covers 32bit vsyscalls currently. Need another set for 64bit. */
+#define FIXADDR_USER_START     ((unsigned long)VSYSCALL32_VSYSCALL)
+#define FIXADDR_USER_END       (FIXADDR_USER_START + PAGE_SIZE)
+#endif
+
+
+/*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+ * in the boot process.
+ * for x86_32: We allocate these special addresses
+ * from the end of virtual memory (0xfffff000) backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+ *
+ * These 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages (or larger if used with an increment
+ * higher than 1). Use set_fixmap(idx,phys) to associate
+ * physical memory with fixmap indices.
+ *
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ */
+enum fixed_addresses {
 #ifdef CONFIG_X86_32
-# include "fixmap_32.h"
+       FIX_HOLE,
+       FIX_VDSO,
 #else
-# include "fixmap_64.h"
+       VSYSCALL_LAST_PAGE,
+       VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE
+                           + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
+       VSYSCALL_HPET,
 #endif
+       FIX_DBGP_BASE,
+       FIX_EARLYCON_MEM_BASE,
+#ifdef CONFIG_X86_LOCAL_APIC
+       FIX_APIC_BASE,  /* local (CPU) APIC) -- required for SMP or not */
+#endif
+#ifdef CONFIG_X86_IO_APIC
+       FIX_IO_APIC_BASE_0,
+       FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1,
+#endif
+#ifdef CONFIG_X86_64
+#ifdef CONFIG_EFI
+       FIX_EFI_IO_MAP_LAST_PAGE,
+       FIX_EFI_IO_MAP_FIRST_PAGE = FIX_EFI_IO_MAP_LAST_PAGE
+                                 + MAX_EFI_IO_PAGES - 1,
+#endif
+#endif
+#ifdef CONFIG_X86_VISWS_APIC
+       FIX_CO_CPU,     /* Cobalt timer */
+       FIX_CO_APIC,    /* Cobalt APIC Redirection Table */
+       FIX_LI_PCIA,    /* Lithium PCI Bridge A */
+       FIX_LI_PCIB,    /* Lithium PCI Bridge B */
+#endif
+#ifdef CONFIG_X86_F00F_BUG
+       FIX_F00F_IDT,   /* Virtual mapping for IDT */
+#endif
+#ifdef CONFIG_X86_CYCLONE_TIMER
+       FIX_CYCLONE_TIMER, /*cyclone timer register*/
+#endif
+#ifdef CONFIG_X86_32
+       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+#ifdef CONFIG_PCI_MMCONFIG
+       FIX_PCIE_MCFG,
+#endif
+#endif
+#ifdef CONFIG_PARAVIRT
+       FIX_PARAVIRT_BOOTMAP,
+#endif
+       __end_of_permanent_fixed_addresses,
+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
+       FIX_OHCI1394_BASE,
+#endif
+       /*
+        * 256 temporary boot-time mappings, used by early_ioremap(),
+        * before ioremap() is functional.
+        *
+        * We round it up to the next 256 pages boundary so that we
+        * can have a single pgd entry and a single pte table:
+        */
+#define NR_FIX_BTMAPS          64
+#define FIX_BTMAPS_SLOTS       4
+       FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
+                       (__end_of_permanent_fixed_addresses & 255),
+       FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,
+#ifdef CONFIG_X86_32
+       FIX_WP_TEST,
+#endif
+       __end_of_fixed_addresses
+};
+
+
+extern void reserve_top_address(unsigned long reserve);
+
+#define FIXADDR_SIZE   (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_BOOT_SIZE      (__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START          (FIXADDR_TOP - FIXADDR_SIZE)
+#define FIXADDR_BOOT_START     (FIXADDR_TOP - FIXADDR_BOOT_SIZE)
 
 extern int fixmaps_set;
 
@@ -69,4 +213,5 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr)
        BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
        return __virt_to_fix(vaddr);
 }
+#endif /* !__ASSEMBLY__ */
 #endif /* _ASM_X86_FIXMAP_H */
diff --git a/arch/x86/include/asm/fixmap_32.h b/arch/x86/include/asm/fixmap_32.h
deleted file mode 100644 (file)
index 047d9ba..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * fixmap.h: compile-time virtual memory allocation
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1998 Ingo Molnar
- *
- * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
- */
-
-#ifndef _ASM_X86_FIXMAP_32_H
-#define _ASM_X86_FIXMAP_32_H
-
-
-/* used by vmalloc.c, vsyscall.lds.S.
- *
- * Leave one empty page between vmalloc'ed areas and
- * the start of the fixmap.
- */
-extern unsigned long __FIXADDR_TOP;
-#define FIXADDR_USER_START     __fix_to_virt(FIX_VDSO)
-#define FIXADDR_USER_END       __fix_to_virt(FIX_VDSO - 1)
-
-#ifndef __ASSEMBLY__
-#include <linux/kernel.h>
-#include <asm/acpi.h>
-#include <asm/apicdef.h>
-#include <asm/page.h>
-#include <linux/threads.h>
-#include <asm/kmap_types.h>
-
-/*
- * Here we define all the compile-time 'special' virtual
- * addresses. The point is to have a constant address at
- * compile time, but to set the physical address only
- * in the boot process. We allocate these special addresses
- * from the end of virtual memory (0xfffff000) backwards.
- * Also this lets us do fail-safe vmalloc(), we
- * can guarantee that these special addresses and
- * vmalloc()-ed addresses never overlap.
- *
- * these 'compile-time allocated' memory buffers are
- * fixed-size 4k pages. (or larger if used with an increment
- * highger than 1) use fixmap_set(idx,phys) to associate
- * physical memory with fixmap indices.
- *
- * TLB entries of such buffers will not be flushed across
- * task switches.
- */
-enum fixed_addresses {
-       FIX_HOLE,
-       FIX_VDSO,
-       FIX_DBGP_BASE,
-       FIX_EARLYCON_MEM_BASE,
-#ifdef CONFIG_X86_LOCAL_APIC
-       FIX_APIC_BASE,  /* local (CPU) APIC) -- required for SMP or not */
-#endif
-#ifdef CONFIG_X86_IO_APIC
-       FIX_IO_APIC_BASE_0,
-       FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
-#endif
-#ifdef CONFIG_X86_VISWS_APIC
-       FIX_CO_CPU,     /* Cobalt timer */
-       FIX_CO_APIC,    /* Cobalt APIC Redirection Table */
-       FIX_LI_PCIA,    /* Lithium PCI Bridge A */
-       FIX_LI_PCIB,    /* Lithium PCI Bridge B */
-#endif
-#ifdef CONFIG_X86_F00F_BUG
-       FIX_F00F_IDT,   /* Virtual mapping for IDT */
-#endif
-#ifdef CONFIG_X86_CYCLONE_TIMER
-       FIX_CYCLONE_TIMER, /*cyclone timer register*/
-#endif
-       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
-       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
-#ifdef CONFIG_PCI_MMCONFIG
-       FIX_PCIE_MCFG,
-#endif
-#ifdef CONFIG_PARAVIRT
-       FIX_PARAVIRT_BOOTMAP,
-#endif
-       __end_of_permanent_fixed_addresses,
-       /*
-        * 256 temporary boot-time mappings, used by early_ioremap(),
-        * before ioremap() is functional.
-        *
-        * We round it up to the next 256 pages boundary so that we
-        * can have a single pgd entry and a single pte table:
-        */
-#define NR_FIX_BTMAPS          64
-#define FIX_BTMAPS_SLOTS       4
-       FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
-                       (__end_of_permanent_fixed_addresses & 255),
-       FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,
-       FIX_WP_TEST,
-#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
-       FIX_OHCI1394_BASE,
-#endif
-       __end_of_fixed_addresses
-};
-
-extern void reserve_top_address(unsigned long reserve);
-
-
-#define FIXADDR_TOP    ((unsigned long)__FIXADDR_TOP)
-
-#define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
-#define __FIXADDR_BOOT_SIZE    (__end_of_fixed_addresses << PAGE_SHIFT)
-#define FIXADDR_START          (FIXADDR_TOP - __FIXADDR_SIZE)
-#define FIXADDR_BOOT_START     (FIXADDR_TOP - __FIXADDR_BOOT_SIZE)
-
-#endif /* !__ASSEMBLY__ */
-#endif /* _ASM_X86_FIXMAP_32_H */
diff --git a/arch/x86/include/asm/fixmap_64.h b/arch/x86/include/asm/fixmap_64.h
deleted file mode 100644 (file)
index 298d9ba..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * fixmap.h: compile-time virtual memory allocation
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1998 Ingo Molnar
- */
-
-#ifndef _ASM_X86_FIXMAP_64_H
-#define _ASM_X86_FIXMAP_64_H
-
-#include <linux/kernel.h>
-#include <asm/acpi.h>
-#include <asm/apicdef.h>
-#include <asm/page.h>
-#include <asm/vsyscall.h>
-#include <asm/efi.h>
-
-/*
- * Here we define all the compile-time 'special' virtual
- * addresses. The point is to have a constant address at
- * compile time, but to set the physical address only
- * in the boot process.
- *
- * These 'compile-time allocated' memory buffers are
- * fixed-size 4k pages (or larger if used with an increment
- * higher than 1). Use set_fixmap(idx,phys) to associate
- * physical memory with fixmap indices.
- *
- * TLB entries of such buffers will not be flushed across
- * task switches.
- */
-
-enum fixed_addresses {
-       VSYSCALL_LAST_PAGE,
-       VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE
-                           + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
-       VSYSCALL_HPET,
-       FIX_DBGP_BASE,
-       FIX_EARLYCON_MEM_BASE,
-       FIX_APIC_BASE,  /* local (CPU) APIC) -- required for SMP or not */
-       FIX_IO_APIC_BASE_0,
-       FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1,
-       FIX_EFI_IO_MAP_LAST_PAGE,
-       FIX_EFI_IO_MAP_FIRST_PAGE = FIX_EFI_IO_MAP_LAST_PAGE
-                                 + MAX_EFI_IO_PAGES - 1,
-#ifdef CONFIG_PARAVIRT
-       FIX_PARAVIRT_BOOTMAP,
-#endif
-       __end_of_permanent_fixed_addresses,
-#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
-       FIX_OHCI1394_BASE,
-#endif
-       /*
-        * 256 temporary boot-time mappings, used by early_ioremap(),
-        * before ioremap() is functional.
-        *
-        * We round it up to the next 256 pages boundary so that we
-        * can have a single pgd entry and a single pte table:
-        */
-#define NR_FIX_BTMAPS          64
-#define FIX_BTMAPS_SLOTS       4
-       FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
-                       (__end_of_permanent_fixed_addresses & 255),
-       FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,
-       __end_of_fixed_addresses
-};
-
-#define FIXADDR_TOP    (VSYSCALL_END-PAGE_SIZE)
-#define FIXADDR_SIZE   (__end_of_fixed_addresses << PAGE_SHIFT)
-#define FIXADDR_START  (FIXADDR_TOP - FIXADDR_SIZE)
-
-/* Only covers 32bit vsyscalls currently. Need another set for 64bit. */
-#define FIXADDR_USER_START     ((unsigned long)VSYSCALL32_VSYSCALL)
-#define FIXADDR_USER_END       (FIXADDR_USER_START + PAGE_SIZE)
-
-#endif /* _ASM_X86_FIXMAP_64_H */
index e9f5db796244b200249802673bc30022b8d8cc94..a37229011b56bc5c013610e85cb3a597d2b7a8ff 100644 (file)
@@ -4,8 +4,12 @@
 extern int pxm_to_nid(int pxm);
 extern void numa_remove_cpu(int cpu);
 
-#ifdef CONFIG_NUMA
+#ifdef CONFIG_HIGHMEM
 extern void set_highmem_pages_init(void);
+#else
+static inline void set_highmem_pages_init(void)
+{
+}
 #endif
 
 #endif /* _ASM_X86_NUMA_32_H */
index a6ad87b352c448e8b1f2c2b3e3dd9591fe593248..b811d6f5780cd261a8e33a7799d3bd50aa46015b 100644 (file)
@@ -1,12 +1,6 @@
 #ifndef _ASM_X86_SECCOMP_32_H
 #define _ASM_X86_SECCOMP_32_H
 
-#include <linux/thread_info.h>
-
-#ifdef TIF_32BIT
-#error "unexpected TIF_32BIT on i386"
-#endif
-
 #include <linux/unistd.h>
 
 #define __NR_seccomp_read __NR_read
index 4171bb794e9e736bbfcb60588a4e9d81d1edcb31..84ec1bd161a5839bdce90c4f8ed80f53bd45f03e 100644 (file)
@@ -1,14 +1,6 @@
 #ifndef _ASM_X86_SECCOMP_64_H
 #define _ASM_X86_SECCOMP_64_H
 
-#include <linux/thread_info.h>
-
-#ifdef TIF_32BIT
-#error "unexpected TIF_32BIT on x86_64"
-#else
-#define TIF_32BIT TIF_IA32
-#endif
-
 #include <linux/unistd.h>
 #include <asm/ia32_unistd.h>
 
index 66801cb72f69620c8ff5f41f32ba96ea8a09190f..05c6f6b11fd5d25354ddcd7d3d07cf7cf7bf3fe5 100644 (file)
@@ -31,7 +31,6 @@ struct x86_quirks {
        void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable,
                                unsigned short oemsize);
        int (*setup_ioapic_ids)(void);
-       int (*update_apic)(void);
 };
 
 extern void x86_quirk_pre_intr_init(void);
@@ -65,7 +64,11 @@ extern void x86_quirk_time_init(void);
 #include <asm/bootparam.h>
 
 /* Interrupt control for vSMPowered x86_64 systems */
+#ifdef CONFIG_X86_VSMP
 void vsmp_init(void);
+#else
+static inline void vsmp_init(void) { }
+#endif
 
 void setup_bios_corruption_check(void);
 
@@ -77,8 +80,6 @@ static inline void visws_early_detect(void) { }
 static inline int is_visws_box(void) { return 0; }
 #endif
 
-extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
-extern int wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip);
 extern struct x86_quirks *x86_quirks;
 extern unsigned long saved_video_mode;
 
index a0ba61386972d573d0b6c8e975833072d1a2664e..5e06259e90e5a736539948ae22e1de25444ba485 100644 (file)
@@ -157,7 +157,7 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
 }
 
 static __always_inline unsigned long __copy_from_user_nocache(void *to,
-               const void __user *from, unsigned long n, unsigned long total)
+                               const void __user *from, unsigned long n)
 {
        might_fault();
        if (__builtin_constant_p(n)) {
@@ -180,7 +180,7 @@ static __always_inline unsigned long __copy_from_user_nocache(void *to,
 
 static __always_inline unsigned long
 __copy_from_user_inatomic_nocache(void *to, const void __user *from,
-                                 unsigned long n, unsigned long total)
+                                 unsigned long n)
 {
        return __copy_from_user_ll_nocache_nozero(to, from, n);
 }
index dcaa0404cf7be6a3ae709e47a15fe027a512af01..8cc687326eb80f20726852c9ba66c68837e8176a 100644 (file)
@@ -188,29 +188,18 @@ __copy_to_user_inatomic(void __user *dst, const void *src, unsigned size)
 extern long __copy_user_nocache(void *dst, const void __user *src,
                                unsigned size, int zerorest);
 
-static inline int __copy_from_user_nocache(void *dst, const void __user *src,
-                                  unsigned size, unsigned long total)
+static inline int
+__copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
 {
        might_sleep();
-       /*
-        * In practice this limit means that large file write()s
-        * which get chunked to 4K copies get handled via
-        * non-temporal stores here. Smaller writes get handled
-        * via regular __copy_from_user():
-        */
-       if (likely(total >= PAGE_SIZE))
-               return __copy_user_nocache(dst, src, size, 1);
-       else
-               return __copy_from_user(dst, src, size);
+       return __copy_user_nocache(dst, src, size, 1);
 }
 
-static inline int __copy_from_user_inatomic_nocache(void *dst,
-           const void __user *src, unsigned size, unsigned total)
+static inline int
+__copy_from_user_inatomic_nocache(void *dst, const void __user *src,
+                                 unsigned size)
 {
-       if (likely(total >= PAGE_SIZE))
-               return __copy_user_nocache(dst, src, size, 0);
-       else
-               return __copy_from_user_inatomic(dst, src, size);
+       return __copy_user_nocache(dst, src, size, 0);
 }
 
 unsigned long
index 8242bf96581252a56938b2de18d978141ee9e219..c0a01b5d985bec4078e60c1856fcb1c1e7c99376 100644 (file)
@@ -12,7 +12,6 @@ extern enum uv_system_type get_uv_system_type(void);
 extern int is_uv_system(void);
 extern void uv_cpu_init(void);
 extern void uv_system_init(void);
-extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip);
 extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
                                                 struct mm_struct *mm,
                                                 unsigned long va,
@@ -24,8 +23,6 @@ static inline enum uv_system_type get_uv_system_type(void) { return UV_NONE; }
 static inline int is_uv_system(void)   { return 0; }
 static inline void uv_cpu_init(void)   { }
 static inline void uv_system_init(void)        { }
-static inline int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip)
-{ return 1; }
 static inline const struct cpumask *
 uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm,
                    unsigned long va, unsigned int cpu)
index de5657c039e90c99d6fc52e12f8e32e737744ed7..95f216bbfaf16f6b8572c40c4cdfa756758f6be5 100644 (file)
@@ -70,7 +70,7 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER)   += ftrace.o
 obj-$(CONFIG_KEXEC)            += machine_kexec_$(BITS).o
 obj-$(CONFIG_KEXEC)            += relocate_kernel_$(BITS).o crash.o
 obj-$(CONFIG_CRASH_DUMP)       += crash_dump_$(BITS).o
-obj-y                          += vsmp_64.o
+obj-$(CONFIG_X86_VSMP)         += vsmp_64.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
 obj-$(CONFIG_MODULES)          += module_$(BITS).o
 obj-$(CONFIG_EFI)              += efi.o efi_$(BITS).o efi_stub_$(BITS).o
index 3b002995e14577f1a906a3445c52b73027d8dd19..f933822dba188fa8cac62e5b404ead77becf4b78 100644 (file)
@@ -222,7 +222,6 @@ struct apic apic_flat =  {
        .send_IPI_all                   = flat_send_IPI_all,
        .send_IPI_self                  = apic_send_IPI_self,
 
-       .wakeup_cpu                     = NULL,
        .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
        .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
        .wait_for_init_deassert         = NULL,
@@ -373,7 +372,6 @@ struct apic apic_physflat =  {
        .send_IPI_all                   = physflat_send_IPI_all,
        .send_IPI_self                  = apic_send_IPI_self,
 
-       .wakeup_cpu                     = NULL,
        .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
        .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
        .wait_for_init_deassert         = NULL,
index 0b1093394fdf59f1c3a2626002e9c4607343f6c2..d806ecaa948fb6c32bec90f20f1ec49891971f2b 100644 (file)
 #include <asm/apic.h>
 #include <asm/ipi.h>
 
-static inline unsigned bigsmp_get_apic_id(unsigned long x)
+static unsigned bigsmp_get_apic_id(unsigned long x)
 {
        return (x >> 24) & 0xFF;
 }
 
-static inline int bigsmp_apic_id_registered(void)
+static int bigsmp_apic_id_registered(void)
 {
        return 1;
 }
 
-static inline const cpumask_t *bigsmp_target_cpus(void)
+static const cpumask_t *bigsmp_target_cpus(void)
 {
 #ifdef CONFIG_SMP
        return &cpu_online_map;
@@ -35,13 +35,12 @@ static inline const cpumask_t *bigsmp_target_cpus(void)
 #endif
 }
 
-static inline unsigned long
-bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid)
+static unsigned long bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid)
 {
        return 0;
 }
 
-static inline unsigned long bigsmp_check_apicid_present(int bit)
+static unsigned long bigsmp_check_apicid_present(int bit)
 {
        return 1;
 }
@@ -64,7 +63,7 @@ static inline unsigned long calculate_ldr(int cpu)
  * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
  * document number 292116).  So here it goes...
  */
-static inline void bigsmp_init_apic_ldr(void)
+static void bigsmp_init_apic_ldr(void)
 {
        unsigned long val;
        int cpu = smp_processor_id();
@@ -74,19 +73,19 @@ static inline void bigsmp_init_apic_ldr(void)
        apic_write(APIC_LDR, val);
 }
 
-static inline void bigsmp_setup_apic_routing(void)
+static void bigsmp_setup_apic_routing(void)
 {
        printk(KERN_INFO
                "Enabling APIC mode:  Physflat.  Using %d I/O APICs\n",
                nr_ioapics);
 }
 
-static inline int bigsmp_apicid_to_node(int logical_apicid)
+static int bigsmp_apicid_to_node(int logical_apicid)
 {
        return apicid_2_node[hard_smp_processor_id()];
 }
 
-static inline int bigsmp_cpu_present_to_apicid(int mps_cpu)
+static int bigsmp_cpu_present_to_apicid(int mps_cpu)
 {
        if (mps_cpu < nr_cpu_ids)
                return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu);
@@ -94,7 +93,7 @@ static inline int bigsmp_cpu_present_to_apicid(int mps_cpu)
        return BAD_APICID;
 }
 
-static inline physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid)
+static physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid)
 {
        return physid_mask_of_physid(phys_apicid);
 }
@@ -107,29 +106,24 @@ static inline int bigsmp_cpu_to_logical_apicid(int cpu)
        return cpu_physical_id(cpu);
 }
 
-static inline physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map)
+static physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map)
 {
        /* For clustered we don't have a good way to do this yet - hack */
        return physids_promote(0xFFL);
 }
 
-static inline void bigsmp_setup_portio_remap(void)
-{
-}
-
-static inline int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid)
+static int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid)
 {
        return 1;
 }
 
 /* As we are using single CPU as destination, pick only one CPU here */
-static inline unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask)
 {
        return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask));
 }
 
-static inline unsigned int
-bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                              const struct cpumask *andmask)
 {
        int cpu;
@@ -148,7 +142,7 @@ bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
        return BAD_APICID;
 }
 
-static inline int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
+static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
 {
        return cpuid_apic >> index_msb;
 }
@@ -158,12 +152,12 @@ static inline void bigsmp_send_IPI_mask(const struct cpumask *mask, int vector)
        default_send_IPI_mask_sequence_phys(mask, vector);
 }
 
-static inline void bigsmp_send_IPI_allbutself(int vector)
+static void bigsmp_send_IPI_allbutself(int vector)
 {
        default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
 }
 
-static inline void bigsmp_send_IPI_all(int vector)
+static void bigsmp_send_IPI_all(int vector)
 {
        bigsmp_send_IPI_mask(cpu_online_mask, vector);
 }
@@ -256,7 +250,6 @@ struct apic apic_bigsmp = {
        .send_IPI_all                   = bigsmp_send_IPI_all,
        .send_IPI_self                  = default_send_IPI_self,
 
-       .wakeup_cpu                     = NULL,
        .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
        .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
 
index 320f2d2e4e54a5e9eed6a4e01ecd615f8ff21de1..19588f2770eea53f8664aaae4cfd0405c46f0541 100644 (file)
@@ -163,22 +163,17 @@ static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
        return 0;
 }
 
-static int __init es7000_update_apic(void)
+static int es7000_apic_is_cluster(void)
 {
-       apic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
-
        /* MPENTIUMIII */
        if (boot_cpu_data.x86 == 6 &&
-           (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) {
-               es7000_update_apic_to_cluster();
-               apic->wait_for_init_deassert = NULL;
-               apic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
-       }
+           (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11))
+               return 1;
 
        return 0;
 }
 
-static void __init setup_unisys(void)
+static void setup_unisys(void)
 {
        /*
         * Determine the generation of the ES7000 currently running.
@@ -192,14 +187,12 @@ static void __init setup_unisys(void)
        else
                es7000_plat = ES7000_CLASSIC;
        ioapic_renumber_irq = es7000_rename_gsi;
-
-       x86_quirks->update_apic = es7000_update_apic;
 }
 
 /*
  * Parse the OEM Table:
  */
-static int __init parse_unisys_oem(char *oemptr)
+static int parse_unisys_oem(char *oemptr)
 {
        int                     i;
        int                     success = 0;
@@ -261,7 +254,7 @@ static int __init parse_unisys_oem(char *oemptr)
 }
 
 #ifdef CONFIG_ACPI
-static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
+static int find_unisys_acpi_oem_table(unsigned long *oem_addr)
 {
        struct acpi_table_header *header = NULL;
        struct es7000_oem_table *table;
@@ -292,7 +285,7 @@ static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
        return 0;
 }
 
-static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
+static void unmap_unisys_acpi_oem_table(unsigned long oem_addr)
 {
        if (!oem_addr)
                return;
@@ -310,8 +303,10 @@ static int es7000_check_dsdt(void)
        return 0;
 }
 
+static int es7000_acpi_ret;
+
 /* Hook from generic ACPI tables.c */
-static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
        unsigned long oem_addr = 0;
        int check_dsdt;
@@ -332,10 +327,26 @@ static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
                 */
                unmap_unisys_acpi_oem_table(oem_addr);
        }
-       return ret;
+
+       es7000_acpi_ret = ret;
+
+       return ret && !es7000_apic_is_cluster();
 }
+
+static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
+{
+       int ret = es7000_acpi_ret;
+
+       return ret && es7000_apic_is_cluster();
+}
+
 #else /* !CONFIG_ACPI: */
-static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+       return 0;
+}
+
+static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
 {
        return 0;
 }
@@ -349,8 +360,7 @@ static void es7000_spin(int n)
                rep_nop();
 }
 
-static int __init
-es7000_mip_write(struct mip_reg *mip_reg)
+static int es7000_mip_write(struct mip_reg *mip_reg)
 {
        int status = 0;
        int spin;
@@ -383,7 +393,7 @@ es7000_mip_write(struct mip_reg *mip_reg)
        return status;
 }
 
-static void __init es7000_enable_apic_mode(void)
+static void es7000_enable_apic_mode(void)
 {
        struct mip_reg es7000_mip_reg;
        int mip_status;
@@ -416,11 +426,8 @@ static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask)
 
 static void es7000_wait_for_init_deassert(atomic_t *deassert)
 {
-#ifndef CONFIG_ES7000_CLUSTERED_APIC
        while (!atomic_read(deassert))
                cpu_relax();
-#endif
-       return;
 }
 
 static unsigned int es7000_get_apic_id(unsigned long x)
@@ -565,72 +572,24 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
        return 1;
 }
 
-static unsigned int
-es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask)
-{
-       int cpus_found = 0;
-       int num_bits_set;
-       int apicid;
-       int cpu;
-
-       num_bits_set = cpumask_weight(cpumask);
-       /* Return id to all */
-       if (num_bits_set == nr_cpu_ids)
-               return 0xFF;
-       /*
-        * The cpus in the mask must all be on the apic cluster.  If are not
-        * on the same apicid cluster return default value of target_cpus():
-        */
-       cpu = cpumask_first(cpumask);
-       apicid = es7000_cpu_to_logical_apicid(cpu);
-
-       while (cpus_found < num_bits_set) {
-               if (cpumask_test_cpu(cpu, cpumask)) {
-                       int new_apicid = es7000_cpu_to_logical_apicid(cpu);
-
-                       if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
-                               WARN(1, "Not a valid mask!");
-
-                               return 0xFF;
-                       }
-                       apicid = new_apicid;
-                       cpus_found++;
-               }
-               cpu++;
-       }
-       return apicid;
-}
-
 static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask)
 {
-       int cpus_found = 0;
-       int num_bits_set;
-       int apicid;
-       int cpu;
+       unsigned int round = 0;
+       int cpu, uninitialized_var(apicid);
 
-       num_bits_set = cpus_weight(*cpumask);
-       /* Return id to all */
-       if (num_bits_set == nr_cpu_ids)
-               return es7000_cpu_to_logical_apicid(0);
        /*
-        * The cpus in the mask must all be on the apic cluster.  If are not
-        * on the same apicid cluster return default value of target_cpus():
+        * The cpus in the mask must all be on the apic cluster.
         */
-       cpu = first_cpu(*cpumask);
-       apicid = es7000_cpu_to_logical_apicid(cpu);
-       while (cpus_found < num_bits_set) {
-               if (cpu_isset(cpu, *cpumask)) {
-                       int new_apicid = es7000_cpu_to_logical_apicid(cpu);
+       for_each_cpu(cpu, cpumask) {
+               int new_apicid = es7000_cpu_to_logical_apicid(cpu);
 
-                       if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
-                               printk("%s: Not a valid mask!\n", __func__);
+               if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
+                       WARN(1, "Not a valid mask!");
 
-                               return es7000_cpu_to_logical_apicid(0);
-                       }
-                       apicid = new_apicid;
-                       cpus_found++;
+                       return BAD_APICID;
                }
-               cpu++;
+               apicid = new_apicid;
+               round++;
        }
        return apicid;
 }
@@ -659,37 +618,103 @@ static int es7000_phys_pkg_id(int cpuid_apic, int index_msb)
        return cpuid_apic >> index_msb;
 }
 
-void __init es7000_update_apic_to_cluster(void)
-{
-       apic->target_cpus = target_cpus_cluster;
-       apic->irq_delivery_mode = dest_LowestPrio;
-       /* logical delivery broadcast to all procs: */
-       apic->irq_dest_mode = 1;
-
-       apic->init_apic_ldr = es7000_init_apic_ldr_cluster;
-
-       apic->cpu_mask_to_apicid = es7000_cpu_mask_to_apicid_cluster;
-}
-
 static int probe_es7000(void)
 {
        /* probed later in mptable/ACPI hooks */
        return 0;
 }
 
-static __init int
-es7000_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
+static int es7000_mps_ret;
+static int es7000_mps_oem_check(struct mpc_table *mpc, char *oem,
+               char *productid)
 {
+       int ret = 0;
+
        if (mpc->oemptr) {
                struct mpc_oemtable *oem_table =
                        (struct mpc_oemtable *)mpc->oemptr;
 
                if (!strncmp(oem, "UNISYS", 6))
-                       return parse_unisys_oem((char *)oem_table);
+                       ret = parse_unisys_oem((char *)oem_table);
        }
-       return 0;
+
+       es7000_mps_ret = ret;
+
+       return ret && !es7000_apic_is_cluster();
 }
 
+static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem,
+               char *productid)
+{
+       int ret = es7000_mps_ret;
+
+       return ret && es7000_apic_is_cluster();
+}
+
+struct apic apic_es7000_cluster = {
+
+       .name                           = "es7000",
+       .probe                          = probe_es7000,
+       .acpi_madt_oem_check            = es7000_acpi_madt_oem_check_cluster,
+       .apic_id_registered             = es7000_apic_id_registered,
+
+       .irq_delivery_mode              = dest_LowestPrio,
+       /* logical delivery broadcast to all procs: */
+       .irq_dest_mode                  = 1,
+
+       .target_cpus                    = target_cpus_cluster,
+       .disable_esr                    = 1,
+       .dest_logical                   = 0,
+       .check_apicid_used              = es7000_check_apicid_used,
+       .check_apicid_present           = es7000_check_apicid_present,
+
+       .vector_allocation_domain       = es7000_vector_allocation_domain,
+       .init_apic_ldr                  = es7000_init_apic_ldr_cluster,
+
+       .ioapic_phys_id_map             = es7000_ioapic_phys_id_map,
+       .setup_apic_routing             = es7000_setup_apic_routing,
+       .multi_timer_check              = NULL,
+       .apicid_to_node                 = es7000_apicid_to_node,
+       .cpu_to_logical_apicid          = es7000_cpu_to_logical_apicid,
+       .cpu_present_to_apicid          = es7000_cpu_present_to_apicid,
+       .apicid_to_cpu_present          = es7000_apicid_to_cpu_present,
+       .setup_portio_remap             = NULL,
+       .check_phys_apicid_present      = es7000_check_phys_apicid_present,
+       .enable_apic_mode               = es7000_enable_apic_mode,
+       .phys_pkg_id                    = es7000_phys_pkg_id,
+       .mps_oem_check                  = es7000_mps_oem_check_cluster,
+
+       .get_apic_id                    = es7000_get_apic_id,
+       .set_apic_id                    = NULL,
+       .apic_id_mask                   = 0xFF << 24,
+
+       .cpu_mask_to_apicid             = es7000_cpu_mask_to_apicid,
+       .cpu_mask_to_apicid_and         = es7000_cpu_mask_to_apicid_and,
+
+       .send_IPI_mask                  = es7000_send_IPI_mask,
+       .send_IPI_mask_allbutself       = NULL,
+       .send_IPI_allbutself            = es7000_send_IPI_allbutself,
+       .send_IPI_all                   = es7000_send_IPI_all,
+       .send_IPI_self                  = default_send_IPI_self,
+
+       .wakeup_secondary_cpu           = wakeup_secondary_cpu_via_mip,
+
+       .trampoline_phys_low            = 0x467,
+       .trampoline_phys_high           = 0x469,
+
+       .wait_for_init_deassert         = NULL,
+
+       /* Nothing to do for most platforms, since cleared by the INIT cycle: */
+       .smp_callin_clear_local_apic    = NULL,
+       .inquire_remote_apic            = default_inquire_remote_apic,
+
+       .read                           = native_apic_mem_read,
+       .write                          = native_apic_mem_write,
+       .icr_read                       = native_apic_icr_read,
+       .icr_write                      = native_apic_icr_write,
+       .wait_icr_idle                  = native_apic_wait_icr_idle,
+       .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+};
 
 struct apic apic_es7000 = {
 
@@ -737,8 +762,6 @@ struct apic apic_es7000 = {
        .send_IPI_all                   = es7000_send_IPI_all,
        .send_IPI_self                  = default_send_IPI_self,
 
-       .wakeup_cpu                     = NULL,
-
        .trampoline_phys_low            = 0x467,
        .trampoline_phys_high           = 0x469,
 
index d9d6d61eed82d0dd0ec72dd2fe062f688a154ec0..ba2fc6465534e1cd588edd124b7943098ed2c4c8 100644 (file)
@@ -69,7 +69,7 @@ struct mpc_trans {
 /* x86_quirks member */
 static int                             mpc_record;
 
-static __cpuinitdata struct mpc_trans  *translation_table[MAX_MPC_ENTRY];
+static struct mpc_trans                        *translation_table[MAX_MPC_ENTRY];
 
 int                                    mp_bus_id_to_node[MAX_MP_BUSSES];
 int                                    mp_bus_id_to_local[MAX_MP_BUSSES];
@@ -256,13 +256,6 @@ static int __init numaq_setup_ioapic_ids(void)
        return 1;
 }
 
-static int __init numaq_update_apic(void)
-{
-       apic->wakeup_cpu = wakeup_secondary_cpu_via_nmi;
-
-       return 0;
-}
-
 static struct x86_quirks numaq_x86_quirks __initdata = {
        .arch_pre_time_init             = numaq_pre_time_init,
        .arch_time_init                 = NULL,
@@ -278,7 +271,6 @@ static struct x86_quirks numaq_x86_quirks __initdata = {
        .mpc_oem_pci_bus                = mpc_oem_pci_bus,
        .smp_read_mpc_oem               = smp_read_mpc_oem,
        .setup_ioapic_ids               = numaq_setup_ioapic_ids,
-       .update_apic                    = numaq_update_apic,
 };
 
 static __init void early_check_numaq(void)
@@ -546,7 +538,7 @@ struct apic apic_numaq = {
        .send_IPI_all                   = numaq_send_IPI_all,
        .send_IPI_self                  = default_send_IPI_self,
 
-       .wakeup_cpu                     = NULL,
+       .wakeup_secondary_cpu           = wakeup_secondary_cpu_via_nmi,
        .trampoline_phys_low            = NUMAQ_TRAMPOLINE_PHYS_LOW,
        .trampoline_phys_high           = NUMAQ_TRAMPOLINE_PHYS_HIGH,
 
index 3a730fa574bb3214c7a6b22d70c7a4d5f2ccd734..141c99a1c26401e444bcc1f85e0d87a7bafc841f 100644 (file)
@@ -138,7 +138,6 @@ struct apic apic_default = {
        .send_IPI_all                   = default_send_IPI_all,
        .send_IPI_self                  = default_send_IPI_self,
 
-       .wakeup_cpu                     = NULL,
        .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
        .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
 
@@ -159,6 +158,7 @@ extern struct apic apic_numaq;
 extern struct apic apic_summit;
 extern struct apic apic_bigsmp;
 extern struct apic apic_es7000;
+extern struct apic apic_es7000_cluster;
 extern struct apic apic_default;
 
 struct apic *apic = &apic_default;
@@ -176,6 +176,7 @@ static struct apic *apic_probe[] __initdata = {
 #endif
 #ifdef CONFIG_X86_ES7000
        &apic_es7000,
+       &apic_es7000_cluster,
 #endif
        &apic_default,  /* must be last */
        NULL,
@@ -197,9 +198,6 @@ static int __init parse_apic(char *arg)
                }
        }
 
-       if (x86_quirks->update_apic)
-               x86_quirks->update_apic();
-
        /* Parsed again by __setup for debug/verbose */
        return 0;
 }
@@ -218,8 +216,6 @@ void __init generic_bigsmp_probe(void)
        if (!cmdline_apic && apic == &apic_default) {
                if (apic_bigsmp.probe()) {
                        apic = &apic_bigsmp;
-                       if (x86_quirks->update_apic)
-                               x86_quirks->update_apic();
                        printk(KERN_INFO "Overriding APIC driver with %s\n",
                               apic->name);
                }
@@ -240,9 +236,6 @@ void __init generic_apic_probe(void)
                /* Not visible without early console */
                if (!apic_probe[i])
                        panic("Didn't find an APIC driver");
-
-               if (x86_quirks->update_apic)
-                       x86_quirks->update_apic();
        }
        printk(KERN_INFO "Using APIC driver %s\n", apic->name);
 }
@@ -262,8 +255,6 @@ generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
 
                if (!cmdline_apic) {
                        apic = apic_probe[i];
-                       if (x86_quirks->update_apic)
-                               x86_quirks->update_apic();
                        printk(KERN_INFO "Switched to APIC driver `%s'.\n",
                               apic->name);
                }
@@ -284,8 +275,6 @@ int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 
                if (!cmdline_apic) {
                        apic = apic_probe[i];
-                       if (x86_quirks->update_apic)
-                               x86_quirks->update_apic();
                        printk(KERN_INFO "Switched to APIC driver `%s'.\n",
                               apic->name);
                }
index e7c163661c773e058b4e1a4a75c20588c59bc39c..8d7748efe6a801859e2cda4c96354a57d69237ea 100644 (file)
@@ -68,9 +68,6 @@ void __init default_setup_apic_routing(void)
                        apic = &apic_physflat;
                printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
        }
-
-       if (x86_quirks->update_apic)
-               x86_quirks->update_apic();
 }
 
 /* Same for both flat and physical. */
index 32838b57a94534d7519022ec2ad35facc56911e4..aac52fa873ffa35d63ee999609c70ca9d3003e85 100644 (file)
@@ -77,9 +77,9 @@ static void summit_send_IPI_all(int vector)
 extern int use_cyclone;
 
 #ifdef CONFIG_X86_SUMMIT_NUMA
-extern void setup_summit(void);
+static void setup_summit(void);
 #else
-#define setup_summit() {}
+static inline void setup_summit(void) {}
 #endif
 
 static int summit_mps_oem_check(struct mpc_table *mpc, char *oem,
@@ -291,33 +291,21 @@ static int summit_check_phys_apicid_present(int boot_cpu_physical_apicid)
 
 static unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
 {
-       int cpus_found = 0;
-       int num_bits_set;
-       int apicid;
-       int cpu;
+       unsigned int round = 0;
+       int cpu, apicid = 0;
 
-       num_bits_set = cpus_weight(*cpumask);
-       if (num_bits_set >= nr_cpu_ids)
-               return BAD_APICID;
        /*
         * The cpus in the mask must all be on the apic cluster.
         */
-       cpu = first_cpu(*cpumask);
-       apicid = summit_cpu_to_logical_apicid(cpu);
-
-       while (cpus_found < num_bits_set) {
-               if (cpu_isset(cpu, *cpumask)) {
-                       int new_apicid = summit_cpu_to_logical_apicid(cpu);
+       for_each_cpu(cpu, cpumask) {
+               int new_apicid = summit_cpu_to_logical_apicid(cpu);
 
-                       if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
-                               printk("%s: Not a valid mask!\n", __func__);
-
-                               return BAD_APICID;
-                       }
-                       apicid = apicid | new_apicid;
-                       cpus_found++;
+               if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
+                       printk("%s: Not a valid mask!\n", __func__);
+                       return BAD_APICID;
                }
-               cpu++;
+               apicid |= new_apicid;
+               round++;
        }
        return apicid;
 }
@@ -372,15 +360,15 @@ static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask)
 }
 
 #ifdef CONFIG_X86_SUMMIT_NUMA
-static struct rio_table_hdr *rio_table_hdr __initdata;
-static struct scal_detail   *scal_devs[MAX_NUMNODES] __initdata;
-static struct rio_detail    *rio_devs[MAX_NUMNODES*4] __initdata;
+static struct rio_table_hdr *rio_table_hdr;
+static struct scal_detail   *scal_devs[MAX_NUMNODES];
+static struct rio_detail    *rio_devs[MAX_NUMNODES*4];
 
 #ifndef CONFIG_X86_NUMAQ
-static int mp_bus_id_to_node[MAX_MP_BUSSES] __initdata;
+static int mp_bus_id_to_node[MAX_MP_BUSSES];
 #endif
 
-static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
+static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
 {
        int twister = 0, node = 0;
        int i, bus, num_buses;
@@ -442,7 +430,7 @@ static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
        return bus;
 }
 
-static int __init build_detail_arrays(void)
+static int build_detail_arrays(void)
 {
        unsigned long ptr;
        int i, scal_detail_size, rio_detail_size;
@@ -476,7 +464,7 @@ static int __init build_detail_arrays(void)
        return 1;
 }
 
-void __init setup_summit(void)
+void setup_summit(void)
 {
        unsigned long           ptr;
        unsigned short          offset;
@@ -574,7 +562,6 @@ struct apic apic_summit = {
        .send_IPI_all                   = summit_send_IPI_all,
        .send_IPI_self                  = default_send_IPI_self,
 
-       .wakeup_cpu                     = NULL,
        .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
        .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
 
index 354b9c45601d50c5f7a65156a24d764068b42572..8fb87b6dd63330c193890ac3ae5d704eda096ba2 100644 (file)
@@ -224,7 +224,6 @@ struct apic apic_x2apic_cluster = {
        .send_IPI_all                   = x2apic_send_IPI_all,
        .send_IPI_self                  = x2apic_send_IPI_self,
 
-       .wakeup_cpu                     = NULL,
        .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
        .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
        .wait_for_init_deassert         = NULL,
index 5bcb174409bca82a12141aae908b62aaf82e12e7..23625b9f98b28530657ca7d572cf4b7a4a60a378 100644 (file)
@@ -213,7 +213,6 @@ struct apic apic_x2apic_phys = {
        .send_IPI_all                   = x2apic_send_IPI_all,
        .send_IPI_self                  = x2apic_send_IPI_self,
 
-       .wakeup_cpu                     = NULL,
        .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
        .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
        .wait_for_init_deassert         = NULL,
index 20b4ad07c3a1f5ec04234bd411c98ce2dddec021..1bd6da1f8fadba5b0fd96c97355122629e9cc30d 100644 (file)
@@ -7,28 +7,28 @@
  *
  * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
  */
-
-#include <linux/kernel.h>
-#include <linux/threads.h>
-#include <linux/cpu.h>
 #include <linux/cpumask.h>
+#include <linux/hardirq.h>
+#include <linux/proc_fs.h>
+#include <linux/threads.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
-#include <linux/init.h>
 #include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/hardirq.h>
 #include <linux/timer.h>
-#include <linux/proc_fs.h>
-#include <asm/current.h>
-#include <asm/smp.h>
-#include <asm/apic.h>
-#include <asm/ipi.h>
-#include <asm/pgtable.h>
-#include <asm/uv/uv.h>
+#include <linux/cpu.h>
+#include <linux/init.h>
+
 #include <asm/uv/uv_mmrs.h>
 #include <asm/uv/uv_hub.h>
+#include <asm/current.h>
+#include <asm/pgtable.h>
 #include <asm/uv/bios.h>
+#include <asm/uv/uv.h>
+#include <asm/apic.h>
+#include <asm/ipi.h>
+#include <asm/smp.h>
 
 DEFINE_PER_CPU(int, x2apic_extra_bits);
 
@@ -91,24 +91,28 @@ static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask)
        cpumask_set_cpu(cpu, retmask);
 }
 
-int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip)
+static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip)
 {
+#ifdef CONFIG_SMP
        unsigned long val;
        int pnode;
 
        pnode = uv_apicid_to_pnode(phys_apicid);
        val = (1UL << UVH_IPI_INT_SEND_SHFT) |
            (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
-           (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
+           ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
            APIC_DM_INIT;
        uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
        mdelay(10);
 
        val = (1UL << UVH_IPI_INT_SEND_SHFT) |
            (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
-           (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
+           ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
            APIC_DM_STARTUP;
        uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
+
+       atomic_set(&init_deasserted, 1);
+#endif
        return 0;
 }
 
@@ -285,7 +289,7 @@ struct apic apic_x2apic_uv_x = {
        .send_IPI_all                   = uv_send_IPI_all,
        .send_IPI_self                  = uv_send_IPI_self,
 
-       .wakeup_cpu                     = NULL,
+       .wakeup_secondary_cpu           = uv_wakeup_secondary,
        .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
        .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
        .wait_for_init_deassert         = NULL,
@@ -365,7 +369,7 @@ static __init void map_high(char *id, unsigned long base, int shift,
        paddr = base << shift;
        bytes = (1UL << shift) * (max_pnode + 1);
        printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr,
-                                               paddr + bytes);
+                                               paddr + bytes);
        if (map_type == map_uc)
                init_extra_mapping_uc(paddr, bytes);
        else
@@ -528,7 +532,7 @@ late_initcall(uv_init_heartbeat);
 
 /*
  * Called on each cpu to initialize the per_cpu UV data area.
- *     ZZZ hotplug not supported yet
+ * FIXME: hotplug not supported yet
  */
 void __cpuinit uv_cpu_init(void)
 {
index 01b1244ef1c0f47456a246f89324973b4f74269e..d67e0e48bc2dfa1115bfc427323bd78e878d51fc 100644 (file)
@@ -7,11 +7,10 @@
 /*
  *     Get CPU information for use by the procfs.
  */
-#ifdef CONFIG_X86_32
 static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c,
                              unsigned int cpu)
 {
-#ifdef CONFIG_X86_HT
+#ifdef CONFIG_SMP
        if (c->x86_max_cores * smp_num_siblings > 1) {
                seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
                seq_printf(m, "siblings\t: %d\n",
@@ -24,6 +23,7 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c,
 #endif
 }
 
+#ifdef CONFIG_X86_32
 static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
 {
        /*
@@ -50,22 +50,6 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
                   c->wp_works_ok ? "yes" : "no");
 }
 #else
-static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c,
-                             unsigned int cpu)
-{
-#ifdef CONFIG_SMP
-       if (c->x86_max_cores * smp_num_siblings > 1) {
-               seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
-               seq_printf(m, "siblings\t: %d\n",
-                          cpus_weight(per_cpu(cpu_core_map, cpu)));
-               seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
-               seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
-               seq_printf(m, "apicid\t\t: %d\n", c->apicid);
-               seq_printf(m, "initial apicid\t: %d\n", c->initial_apicid);
-       }
-#endif
-}
-
 static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
 {
        seq_printf(m,
index fb2159a5c817099dba21dfe061eaa175c345fdaf..3d9672e59c16aeb0b16d0be4d0aae5f1b362f61c 100644 (file)
@@ -1383,7 +1383,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
 #ifdef CONFIG_X86_32
 # define IS_IA32       1
 #elif defined CONFIG_IA32_EMULATION
-# define IS_IA32       test_thread_flag(TIF_IA32)
+# define IS_IA32       is_compat_task()
 #else
 # define IS_IA32       0
 #endif
index 5b85759e7972f32ff93b9cf9797ecf9c2a907907..4c54bc0d8ff3cc632f10a2639628dbf0592f7715 100644 (file)
@@ -600,19 +600,7 @@ static int __init setup_elfcorehdr(char *arg)
 early_param("elfcorehdr", setup_elfcorehdr);
 #endif
 
-static int __init default_update_apic(void)
-{
-#ifdef CONFIG_SMP
-       if (!apic->wakeup_cpu)
-               apic->wakeup_cpu = wakeup_secondary_cpu_via_init;
-#endif
-
-       return 0;
-}
-
-static struct x86_quirks default_x86_quirks __initdata = {
-       .update_apic         = default_update_apic,
-};
+static struct x86_quirks default_x86_quirks __initdata;
 
 struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
 
@@ -875,9 +863,7 @@ void __init setup_arch(char **cmdline_p)
 
        reserve_initrd();
 
-#ifdef CONFIG_X86_64
        vsmp_init();
-#endif
 
        io_delay_init();
 
index 7cdcd16885ed9564b9f631de7b2ee2edc13862ac..d2cc6428c5875a6103a00757eeeec9ff0831508f 100644 (file)
@@ -187,40 +187,35 @@ setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
 /*
  * Set up a signal frame.
  */
-#ifdef CONFIG_X86_32
-static const struct {
-       u16 poplmovl;
-       u32 val;
-       u16 int80;
-} __attribute__((packed)) retcode = {
-       0xb858,         /* popl %eax; movl $..., %eax */
-       __NR_sigreturn,
-       0x80cd,         /* int $0x80 */
-};
-
-static const struct {
-       u8  movl;
-       u32 val;
-       u16 int80;
-       u8  pad;
-} __attribute__((packed)) rt_retcode = {
-       0xb8,           /* movl $..., %eax */
-       __NR_rt_sigreturn,
-       0x80cd,         /* int $0x80 */
-       0
-};
 
 /*
  * Determine which stack to use..
  */
+static unsigned long align_sigframe(unsigned long sp)
+{
+#ifdef CONFIG_X86_32
+       /*
+        * Align the stack pointer according to the i386 ABI,
+        * i.e. so that on function entry ((sp + 4) & 15) == 0.
+        */
+       sp = ((sp + 4) & -16ul) - 4;
+#else /* !CONFIG_X86_32 */
+       sp = round_down(sp, 16) - 8;
+#endif
+       return sp;
+}
+
 static inline void __user *
 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
-            void **fpstate)
+            void __user **fpstate)
 {
-       unsigned long sp;
-
        /* Default to using normal stack */
-       sp = regs->sp;
+       unsigned long sp = regs->sp;
+
+#ifdef CONFIG_X86_64
+       /* redzone */
+       sp -= 128;
+#endif /* CONFIG_X86_64 */
 
        /*
         * If we are on the alternate signal stack and would overflow it, don't.
@@ -234,30 +229,52 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
                if (sas_ss_flags(sp) == 0)
                        sp = current->sas_ss_sp + current->sas_ss_size;
        } else {
+#ifdef CONFIG_X86_32
                /* This is the legacy signal stack switching. */
                if ((regs->ss & 0xffff) != __USER_DS &&
                        !(ka->sa.sa_flags & SA_RESTORER) &&
                                ka->sa.sa_restorer)
                        sp = (unsigned long) ka->sa.sa_restorer;
+#endif /* CONFIG_X86_32 */
        }
 
        if (used_math()) {
-               sp = sp - sig_xstate_size;
-               *fpstate = (struct _fpstate *) sp;
+               sp -= sig_xstate_size;
+#ifdef CONFIG_X86_64
+               sp = round_down(sp, 64);
+#endif /* CONFIG_X86_64 */
+               *fpstate = (void __user *)sp;
+
                if (save_i387_xstate(*fpstate) < 0)
                        return (void __user *)-1L;
        }
 
-       sp -= frame_size;
-       /*
-        * Align the stack pointer according to the i386 ABI,
-        * i.e. so that on function entry ((sp + 4) & 15) == 0.
-        */
-       sp = ((sp + 4) & -16ul) - 4;
-
-       return (void __user *) sp;
+       return (void __user *)align_sigframe(sp - frame_size);
 }
 
+#ifdef CONFIG_X86_32
+static const struct {
+       u16 poplmovl;
+       u32 val;
+       u16 int80;
+} __attribute__((packed)) retcode = {
+       0xb858,         /* popl %eax; movl $..., %eax */
+       __NR_sigreturn,
+       0x80cd,         /* int $0x80 */
+};
+
+static const struct {
+       u8  movl;
+       u32 val;
+       u16 int80;
+       u8  pad;
+} __attribute__((packed)) rt_retcode = {
+       0xb8,           /* movl $..., %eax */
+       __NR_rt_sigreturn,
+       0x80cd,         /* int $0x80 */
+       0
+};
+
 static int
 __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
              struct pt_regs *regs)
@@ -388,24 +405,6 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        return 0;
 }
 #else /* !CONFIG_X86_32 */
-/*
- * Determine which stack to use..
- */
-static void __user *
-get_stack(struct k_sigaction *ka, unsigned long sp, unsigned long size)
-{
-       /* Default to using normal stack - redzone*/
-       sp -= 128;
-
-       /* This is the X/Open sanctioned signal stack switching.  */
-       if (ka->sa.sa_flags & SA_ONSTACK) {
-               if (sas_ss_flags(sp) == 0)
-                       sp = current->sas_ss_sp + current->sas_ss_size;
-       }
-
-       return (void __user *)round_down(sp - size, 64);
-}
-
 static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                            sigset_t *set, struct pt_regs *regs)
 {
@@ -414,15 +413,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        int err = 0;
        struct task_struct *me = current;
 
-       if (used_math()) {
-               fp = get_stack(ka, regs->sp, sig_xstate_size);
-               frame = (void __user *)round_down(
-                       (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
-
-               if (save_i387_xstate(fp) < 0)
-                       return -EFAULT;
-       } else
-               frame = get_stack(ka, regs->sp, sizeof(struct rt_sigframe)) - 8;
+       frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe), &fp);
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                return -EFAULT;
index 9ce666387f37c7a12b00eca4a0ccb3c7617d7f8a..249334f5080a16d2e5a6e2c4fb67a8c19be88891 100644 (file)
@@ -112,7 +112,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map);
 DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
 EXPORT_PER_CPU_SYMBOL(cpu_info);
 
-static atomic_t init_deasserted;
+atomic_t init_deasserted;
 
 
 /* Set if we find a B stepping CPU */
@@ -614,12 +614,6 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
        unsigned long send_status, accept_status = 0;
        int maxlvt, num_starts, j;
 
-       if (get_uv_system_type() == UV_NON_UNIQUE_APIC) {
-               send_status = uv_wakeup_secondary(phys_apicid, start_eip);
-               atomic_set(&init_deasserted, 1);
-               return send_status;
-       }
-
        maxlvt = lapic_get_maxlvt();
 
        /*
@@ -748,7 +742,8 @@ static void __cpuinit do_fork_idle(struct work_struct *work)
 /*
  * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
  * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
- * Returns zero if CPU booted OK, else error code from ->wakeup_cpu.
+ * Returns zero if CPU booted OK, else error code from
+ * ->wakeup_secondary_cpu.
  */
 static int __cpuinit do_boot_cpu(int apicid, int cpu)
 {
@@ -835,9 +830,13 @@ do_rest:
        }
 
        /*
-        * Starting actual IPI sequence...
+        * Kick the secondary CPU. Use the method in the APIC driver
+        * if it's defined - or use an INIT boot APIC message otherwise:
         */
-       boot_error = apic->wakeup_cpu(apicid, start_ip);
+       if (apic->wakeup_secondary_cpu)
+               boot_error = apic->wakeup_secondary_cpu(apicid, start_ip);
+       else
+               boot_error = wakeup_secondary_cpu_via_init(apicid, start_ip);
 
        if (!boot_error) {
                /*
index c609205df594ba54dac5b6c0823bd3a34f486725..74de562812ccc0e3e4886c18d945d669d282c48c 100644 (file)
@@ -22,7 +22,7 @@
 #include <asm/paravirt.h>
 #include <asm/setup.h>
 
-#if defined CONFIG_PCI && defined CONFIG_PARAVIRT
+#ifdef CONFIG_PARAVIRT
 /*
  * Interrupt control on vSMPowered systems:
  * ~AC is a shadow of IF.  If IF is 'on' AC should be 'off'
@@ -114,7 +114,6 @@ static void __init set_vsmp_pv_ops(void)
 }
 #endif
 
-#ifdef CONFIG_PCI
 static int is_vsmp = -1;
 
 static void __init detect_vsmp_box(void)
@@ -139,15 +138,6 @@ int is_vsmp_box(void)
                return 0;
        }
 }
-#else
-static void __init detect_vsmp_box(void)
-{
-}
-int is_vsmp_box(void)
-{
-       return 0;
-}
-#endif
 
 void __init vsmp_init(void)
 {
index 2b938a3849104c446287fa0cace4ef3701b87aea..08537747cb589b92db2bdeb4c7dd75c7f3ccf01c 100644 (file)
@@ -1,4 +1,4 @@
-obj-y  :=  init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
+obj-y  :=  init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
            pat.o pgtable.o gup.o
 
 obj-$(CONFIG_SMP)              += tlb.o
index bcc079c282dd33112a48b250ec227610c39697cb..00f127c80b0e38fa50eec531e8e85c8d1f18fd6d 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/highmem.h>
 #include <linux/module.h>
+#include <linux/swap.h> /* for totalram_pages */
 
 void *kmap(struct page *page)
 {
@@ -156,3 +157,36 @@ EXPORT_SYMBOL(kmap);
 EXPORT_SYMBOL(kunmap);
 EXPORT_SYMBOL(kmap_atomic);
 EXPORT_SYMBOL(kunmap_atomic);
+
+#ifdef CONFIG_NUMA
+void __init set_highmem_pages_init(void)
+{
+       struct zone *zone;
+       int nid;
+
+       for_each_zone(zone) {
+               unsigned long zone_start_pfn, zone_end_pfn;
+
+               if (!is_highmem(zone))
+                       continue;
+
+               zone_start_pfn = zone->zone_start_pfn;
+               zone_end_pfn = zone_start_pfn + zone->spanned_pages;
+
+               nid = zone_to_nid(zone);
+               printk(KERN_INFO "Initializing %s for node %d (%08lx:%08lx)\n",
+                               zone->name, nid, zone_start_pfn, zone_end_pfn);
+
+               add_highpages_with_active_regions(nid, zone_start_pfn,
+                                zone_end_pfn);
+       }
+       totalram_pages += totalhigh_pages;
+}
+#else
+void __init set_highmem_pages_init(void)
+{
+       add_highpages_with_active_regions(0, highstart_pfn, highend_pfn);
+
+       totalram_pages += totalhigh_pages;
+}
+#endif /* CONFIG_NUMA */
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
new file mode 100644 (file)
index 0000000..ce6a722
--- /dev/null
@@ -0,0 +1,49 @@
+#include <linux/swap.h>
+#include <asm/cacheflush.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+#include <asm/system.h>
+
+void free_init_pages(char *what, unsigned long begin, unsigned long end)
+{
+       unsigned long addr = begin;
+
+       if (addr >= end)
+               return;
+
+       /*
+        * If debugging page accesses then do not free this memory but
+        * mark them not present - any buggy init-section access will
+        * create a kernel page fault:
+        */
+#ifdef CONFIG_DEBUG_PAGEALLOC
+       printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
+               begin, PAGE_ALIGN(end));
+       set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
+#else
+       /*
+        * We just marked the kernel text read only above, now that
+        * we are going to free part of that, we need to make that
+        * writeable first.
+        */
+       set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
+
+       printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
+
+       for (; addr < end; addr += PAGE_SIZE) {
+               ClearPageReserved(virt_to_page(addr));
+               init_page_count(virt_to_page(addr));
+               memset((void *)(addr & ~(PAGE_SIZE-1)),
+                       POISON_FREE_INITMEM, PAGE_SIZE);
+               free_page(addr);
+               totalram_pages++;
+       }
+#endif
+}
+
+void free_initmem(void)
+{
+       free_init_pages("unused kernel memory",
+                       (unsigned long)(&__init_begin),
+                       (unsigned long)(&__init_end));
+}
index 06708ee94aa407d1e773afee5b1e1abc102b6635..0b087dcd2c18adc215bd5b5c4787428ca13fdf3e 100644 (file)
@@ -50,8 +50,6 @@
 #include <asm/setup.h>
 #include <asm/cacheflush.h>
 
-unsigned int __VMALLOC_RESERVE = 128 << 20;
-
 unsigned long max_low_pfn_mapped;
 unsigned long max_pfn_mapped;
 
@@ -469,22 +467,10 @@ void __init add_highpages_with_active_regions(int nid, unsigned long start_pfn,
        work_with_active_regions(nid, add_highpages_work_fn, &data);
 }
 
-#ifndef CONFIG_NUMA
-static void __init set_highmem_pages_init(void)
-{
-       add_highpages_with_active_regions(0, highstart_pfn, highend_pfn);
-
-       totalram_pages += totalhigh_pages;
-}
-#endif /* !CONFIG_NUMA */
-
 #else
 static inline void permanent_kmaps_init(pgd_t *pgd_base)
 {
 }
-static inline void set_highmem_pages_init(void)
-{
-}
 #endif /* CONFIG_HIGHMEM */
 
 void __init native_pagetable_setup_start(pgd_t *base)
@@ -847,10 +833,10 @@ static void __init find_early_table_space(unsigned long end, int use_pse)
        unsigned long puds, pmds, ptes, tables, start;
 
        puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
-       tables = PAGE_ALIGN(puds * sizeof(pud_t));
+       tables = roundup(puds * sizeof(pud_t), PAGE_SIZE);
 
        pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
-       tables += PAGE_ALIGN(pmds * sizeof(pmd_t));
+       tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE);
 
        if (use_pse) {
                unsigned long extra;
@@ -861,10 +847,10 @@ static void __init find_early_table_space(unsigned long end, int use_pse)
        } else
                ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT;
 
-       tables += PAGE_ALIGN(ptes * sizeof(pte_t));
+       tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE);
 
        /* for fixmap */
-       tables += PAGE_ALIGN(__end_of_fixed_addresses * sizeof(pte_t));
+       tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE);
 
        /*
         * RED-PEN putting page tables only on node 0 could
@@ -1214,45 +1200,6 @@ void mark_rodata_ro(void)
 }
 #endif
 
-void free_init_pages(char *what, unsigned long begin, unsigned long end)
-{
-#ifdef CONFIG_DEBUG_PAGEALLOC
-       /*
-        * If debugging page accesses then do not free this memory but
-        * mark them not present - any buggy init-section access will
-        * create a kernel page fault:
-        */
-       printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
-               begin, PAGE_ALIGN(end));
-       set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
-#else
-       unsigned long addr;
-
-       /*
-        * We just marked the kernel text read only above, now that
-        * we are going to free part of that, we need to make that
-        * writeable first.
-        */
-       set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
-
-       for (addr = begin; addr < end; addr += PAGE_SIZE) {
-               ClearPageReserved(virt_to_page(addr));
-               init_page_count(virt_to_page(addr));
-               memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
-               free_page(addr);
-               totalram_pages++;
-       }
-       printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
-#endif
-}
-
-void free_initmem(void)
-{
-       free_init_pages("unused kernel memory",
-                       (unsigned long)(&__init_begin),
-                       (unsigned long)(&__init_end));
-}
-
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
index e6d36b490250bed6952f2d93de3d1f337c3cf7f4..724e537432e75abfcea84ef50764a7d6d4f41109 100644 (file)
@@ -714,6 +714,8 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
        pos = start_pfn << PAGE_SHIFT;
        end_pfn = ((pos + (PMD_SIZE - 1)) >> PMD_SHIFT)
                        << (PMD_SHIFT - PAGE_SHIFT);
+       if (end_pfn > (end >> PAGE_SHIFT))
+               end_pfn = end >> PAGE_SHIFT;
        if (start_pfn < end_pfn) {
                nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
                pos = end_pfn << PAGE_SHIFT;
@@ -945,43 +947,6 @@ void __init mem_init(void)
                initsize >> 10);
 }
 
-void free_init_pages(char *what, unsigned long begin, unsigned long end)
-{
-       unsigned long addr = begin;
-
-       if (addr >= end)
-               return;
-
-       /*
-        * If debugging page accesses then do not free this memory but
-        * mark them not present - any buggy init-section access will
-        * create a kernel page fault:
-        */
-#ifdef CONFIG_DEBUG_PAGEALLOC
-       printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
-               begin, PAGE_ALIGN(end));
-       set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
-#else
-       printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
-
-       for (; addr < end; addr += PAGE_SIZE) {
-               ClearPageReserved(virt_to_page(addr));
-               init_page_count(virt_to_page(addr));
-               memset((void *)(addr & ~(PAGE_SIZE-1)),
-                       POISON_FREE_INITMEM, PAGE_SIZE);
-               free_page(addr);
-               totalram_pages++;
-       }
-#endif
-}
-
-void free_initmem(void)
-{
-       free_init_pages("unused kernel memory",
-                       (unsigned long)(&__init_begin),
-                       (unsigned long)(&__init_end));
-}
-
 #ifdef CONFIG_DEBUG_RODATA
 const int rodata_test_data = 0xC3;
 EXPORT_SYMBOL_GPL(rodata_test_data);
index 3957cd6d6454b832594c971f5c6860b84d5e4a11..451fe95a0352b3d63634231ea31c4eea016b2550 100644 (file)
@@ -423,32 +423,6 @@ void __init initmem_init(unsigned long start_pfn,
        setup_bootmem_allocator();
 }
 
-void __init set_highmem_pages_init(void)
-{
-#ifdef CONFIG_HIGHMEM
-       struct zone *zone;
-       int nid;
-
-       for_each_zone(zone) {
-               unsigned long zone_start_pfn, zone_end_pfn;
-
-               if (!is_highmem(zone))
-                       continue;
-
-               zone_start_pfn = zone->zone_start_pfn;
-               zone_end_pfn = zone_start_pfn + zone->spanned_pages;
-
-               nid = zone_to_nid(zone);
-               printk(KERN_INFO "Initializing %s for node %d (%08lx:%08lx)\n",
-                               zone->name, nid, zone_start_pfn, zone_end_pfn);
-
-               add_highpages_with_active_regions(nid, zone_start_pfn,
-                                zone_end_pfn);
-       }
-       totalram_pages += totalhigh_pages;
-#endif
-}
-
 #ifdef CONFIG_MEMORY_HOTPLUG
 static int paddr_to_nid(u64 addr)
 {
index 86f2ffc43c3d8b7cc28d2e019f570f1ecc6128c8..5b7c7c8464fe9f9dfeb36310a569b440a2bc5e38 100644 (file)
@@ -313,6 +313,24 @@ int ptep_clear_flush_young(struct vm_area_struct *vma,
        return young;
 }
 
+/**
+ * reserve_top_address - reserves a hole in the top of kernel address space
+ * @reserve - size of hole to reserve
+ *
+ * Can be used to relocate the fixmap area and poke a hole in the top
+ * of kernel address space to make room for a hypervisor.
+ */
+void __init reserve_top_address(unsigned long reserve)
+{
+#ifdef CONFIG_X86_32
+       BUG_ON(fixmaps_set > 0);
+       printk(KERN_INFO "Reserving virtual address space above 0x%08x\n",
+              (int)-reserve);
+       __FIXADDR_TOP = -reserve - PAGE_SIZE;
+       __VMALLOC_RESERVE += reserve;
+#endif
+}
+
 int fixmaps_set;
 
 void __native_set_fixmap(enum fixed_addresses idx, pte_t pte)
index 0951db9ee5190b351a843a71a755109a6fd1586e..f2e477c91c1b85d72bb3d7ec0659e647c67c968c 100644 (file)
@@ -20,6 +20,8 @@
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 
+unsigned int __VMALLOC_RESERVE = 128 << 20;
+
 /*
  * Associate a virtual page frame with a given physical page frame 
  * and protection flags for that frame.
@@ -97,22 +99,6 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
 unsigned long __FIXADDR_TOP = 0xfffff000;
 EXPORT_SYMBOL(__FIXADDR_TOP);
 
-/**
- * reserve_top_address - reserves a hole in the top of kernel address space
- * @reserve - size of hole to reserve
- *
- * Can be used to relocate the fixmap area and poke a hole in the top
- * of kernel address space to make room for a hypervisor.
- */
-void __init reserve_top_address(unsigned long reserve)
-{
-       BUG_ON(fixmaps_set > 0);
-       printk(KERN_INFO "Reserving virtual address space above 0x%08x\n",
-              (int)-reserve);
-       __FIXADDR_TOP = -reserve - PAGE_SIZE;
-       __VMALLOC_RESERVE += reserve;
-}
-
 /*
  * vmalloc=size forces the vmalloc area to be exactly 'size'
  * bytes. This can be used to increase (or decrease) the
index e9f80c744cf3409d72f77dd9044ec1dd90534609..10131fbdaadada1781bddde6749e83a4cb200a8f 100644 (file)
@@ -78,8 +78,18 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs)
        if (cpu_has_arch_perfmon) {
                union cpuid10_eax eax;
                eax.full = cpuid_eax(0xa);
-               if (counter_width < eax.split.bit_width)
-                       counter_width = eax.split.bit_width;
+
+               /*
+                * For Core2 (family 6, model 15), don't reset the
+                * counter width:
+                */
+               if (!(eax.split.version_id == 0 &&
+                       current_cpu_data.x86 == 6 &&
+                               current_cpu_data.x86_model == 15)) {
+
+                       if (counter_width < eax.split.bit_width)
+                               counter_width = eax.split.bit_width;
+               }
        }
 
        /* clear all counters */
index 72c667f9bee1aadbc4067687d05aca0849be751b..12715d3c078d6e9d111c265fe96b5ccc63961d3e 100644 (file)
@@ -420,7 +420,7 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
                                dev->sigdata.lock = NULL;
                        master->lock.hw_lock = NULL;   /* SHM removed */
                        master->lock.file_priv = NULL;
-                       wake_up_interruptible(&master->lock.lock_queue);
+                       wake_up_interruptible_all(&master->lock.lock_queue);
                }
                break;
        case _DRM_AGP:
index 6c020fe5431ca5eea366e60fd9560f5096e6da58..f52663ebe016f5ea194b5aa2a403881ebb2e0448 100644 (file)
@@ -484,6 +484,7 @@ int drm_release(struct inode *inode, struct file *filp)
        mutex_lock(&dev->struct_mutex);
 
        if (file_priv->is_master) {
+               struct drm_master *master = file_priv->master;
                struct drm_file *temp;
                list_for_each_entry(temp, &dev->filelist, lhead) {
                        if ((temp->master == file_priv->master) &&
@@ -491,6 +492,19 @@ int drm_release(struct inode *inode, struct file *filp)
                                temp->authenticated = 0;
                }
 
+               /**
+                * Since the master is disappearing, so is the
+                * possibility to lock.
+                */
+
+               if (master->lock.hw_lock) {
+                       if (dev->sigdata.lock == master->lock.hw_lock)
+                               dev->sigdata.lock = NULL;
+                       master->lock.hw_lock = NULL;
+                       master->lock.file_priv = NULL;
+                       wake_up_interruptible_all(&master->lock.lock_queue);
+               }
+
                if (file_priv->minor->master == file_priv->master) {
                        /* drop the reference held my the minor */
                        drm_master_put(&file_priv->minor->master);
index 46e7b28f0707397d545948dc21bbcc272f16eb6f..e2f70a516c34412112078131203309c3656622d7 100644 (file)
@@ -80,6 +80,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
                __set_current_state(TASK_INTERRUPTIBLE);
                if (!master->lock.hw_lock) {
                        /* Device has been unregistered */
+                       send_sig(SIGTERM, current, 0);
                        ret = -EINTR;
                        break;
                }
@@ -93,7 +94,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
                /* Contention */
                schedule();
                if (signal_pending(current)) {
-                       ret = -ERESTARTSYS;
+                       ret = -EINTR;
                        break;
                }
        }
index 46bb923b097c39ad6fef2c37f29e59ae0c648f42..096e2a37446d3e8fb333f45c342bc2a975607b34 100644 (file)
@@ -146,14 +146,6 @@ static void drm_master_destroy(struct kref *kref)
 
        drm_ht_remove(&master->magiclist);
 
-       if (master->lock.hw_lock) {
-               if (dev->sigdata.lock == master->lock.hw_lock)
-                       dev->sigdata.lock = NULL;
-               master->lock.hw_lock = NULL;
-               master->lock.file_priv = NULL;
-               wake_up_interruptible(&master->lock.lock_queue);
-       }
-
        drm_free(master, sizeof(*master), DRM_MEM_DRIVER);
 }
 
index c29feb97c36df3375d8de9387f256cc8b7bc3a42..85685bfd12daf02fb26bea88a90e521d6e3237c2 100644 (file)
@@ -211,7 +211,7 @@ fast_user_write(struct io_mapping *mapping,
 
        vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base);
        unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset,
-                                                     user_data, length, length);
+                                                     user_data, length);
        io_mapping_unmap_atomic(vaddr_atomic);
        if (unwritten)
                return -EFAULT;
index 548ff2c66431ee93a205b15d84362084da7486ce..87b6b603469ea278780af278fb9b7dc92d013ed0 100644 (file)
@@ -383,12 +383,13 @@ int i915_irq_emit(struct drm_device *dev, void *data,
        drm_i915_irq_emit_t *emit = data;
        int result;
 
-       RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
-
        if (!dev_priv) {
                DRM_ERROR("called with no initialization\n");
                return -EINVAL;
        }
+
+       RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
+
        mutex_lock(&dev->struct_mutex);
        result = i915_emit_irq(dev);
        mutex_unlock(&dev->struct_mutex);
index c3c8b9bc40ae6220f46a8dba295f8a87c7e1e6e3..45470f18d7e9ea7c252a1a2c4e671490483da36b 100644 (file)
@@ -839,7 +839,7 @@ static void atkbd_disconnect(struct serio *serio)
  */
 static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
 {
-       const unsigned int forced_release_keys[] = {
+       static const unsigned int forced_release_keys[] = {
                0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
        };
        int i;
@@ -856,7 +856,7 @@ static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
  */
 static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
 {
-       const unsigned int forced_release_keys[] = {
+       static const unsigned int forced_release_keys[] = {
                0x94,
        };
        int i;
index 19284016e0f4d1c2ce47e3f86f4a5f59e04445fc..ee855c5202e827b8545978f023204937b13dccc2 100644 (file)
@@ -209,8 +209,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
                goto out;
        }
 
-       if (!pdata->debounce_time || !pdata->debounce_time > MAX_MULT ||
-           !pdata->coldrive_time || !pdata->coldrive_time > MAX_MULT) {
+       if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT ||
+           !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) {
                printk(KERN_ERR DRV_NAME
                        ": Invalid Debounce/Columdrive Time from pdata\n");
                bfin_write_KPAD_MSEL(0xFF0);    /* Default MSEL */
index c8ed065ea0cbd9f2d360331c101b2052bc8d2ebb..abb04c82c622edd638228054f1d6dc8a9066accd 100644 (file)
@@ -288,7 +288,7 @@ static int corgikbd_resume(struct platform_device *dev)
 #define corgikbd_resume                NULL
 #endif
 
-static int __init corgikbd_probe(struct platform_device *pdev)
+static int __devinit corgikbd_probe(struct platform_device *pdev)
 {
        struct corgikbd *corgikbd;
        struct input_dev *input_dev;
@@ -368,7 +368,7 @@ static int __init corgikbd_probe(struct platform_device *pdev)
        return err;
 }
 
-static int corgikbd_remove(struct platform_device *pdev)
+static int __devexit corgikbd_remove(struct platform_device *pdev)
 {
        int i;
        struct corgikbd *corgikbd = platform_get_drvdata(pdev);
@@ -388,7 +388,7 @@ static int corgikbd_remove(struct platform_device *pdev)
 
 static struct platform_driver corgikbd_driver = {
        .probe          = corgikbd_probe,
-       .remove         = corgikbd_remove,
+       .remove         = __devexit_p(corgikbd_remove),
        .suspend        = corgikbd_suspend,
        .resume         = corgikbd_resume,
        .driver         = {
@@ -397,7 +397,7 @@ static struct platform_driver corgikbd_driver = {
        },
 };
 
-static int __devinit corgikbd_init(void)
+static int __init corgikbd_init(void)
 {
        return platform_driver_register(&corgikbd_driver);
 }
index 3f3d1198cdb10dd76fb4973766ab9d6e1908d246..058fa8b02c21ee1b939085c024c23884e2f6ca1d 100644 (file)
@@ -279,7 +279,7 @@ static int omap_kp_resume(struct platform_device *dev)
 #define omap_kp_resume NULL
 #endif
 
-static int __init omap_kp_probe(struct platform_device *pdev)
+static int __devinit omap_kp_probe(struct platform_device *pdev)
 {
        struct omap_kp *omap_kp;
        struct input_dev *input_dev;
@@ -422,7 +422,7 @@ err1:
        return -EINVAL;
 }
 
-static int omap_kp_remove(struct platform_device *pdev)
+static int __devexit omap_kp_remove(struct platform_device *pdev)
 {
        struct omap_kp *omap_kp = platform_get_drvdata(pdev);
 
@@ -454,7 +454,7 @@ static int omap_kp_remove(struct platform_device *pdev)
 
 static struct platform_driver omap_kp_driver = {
        .probe          = omap_kp_probe,
-       .remove         = omap_kp_remove,
+       .remove         = __devexit_p(omap_kp_remove),
        .suspend        = omap_kp_suspend,
        .resume         = omap_kp_resume,
        .driver         = {
@@ -463,7 +463,7 @@ static struct platform_driver omap_kp_driver = {
        },
 };
 
-static int __devinit omap_kp_init(void)
+static int __init omap_kp_init(void)
 {
        printk(KERN_INFO "OMAP Keypad Driver\n");
        return platform_driver_register(&omap_kp_driver);
index c48b76a46a58ef5adf68601171007db16cae1abb..9d1781a618e99466f0855f480cbb8974e6a3fbd8 100644 (file)
@@ -343,7 +343,7 @@ static int spitzkbd_resume(struct platform_device *dev)
 #define spitzkbd_resume                NULL
 #endif
 
-static int __init spitzkbd_probe(struct platform_device *dev)
+static int __devinit spitzkbd_probe(struct platform_device *dev)
 {
        struct spitzkbd *spitzkbd;
        struct input_dev *input_dev;
@@ -444,7 +444,7 @@ static int __init spitzkbd_probe(struct platform_device *dev)
        return err;
 }
 
-static int spitzkbd_remove(struct platform_device *dev)
+static int __devexit spitzkbd_remove(struct platform_device *dev)
 {
        int i;
        struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
@@ -470,7 +470,7 @@ static int spitzkbd_remove(struct platform_device *dev)
 
 static struct platform_driver spitzkbd_driver = {
        .probe          = spitzkbd_probe,
-       .remove         = spitzkbd_remove,
+       .remove         = __devexit_p(spitzkbd_remove),
        .suspend        = spitzkbd_suspend,
        .resume         = spitzkbd_resume,
        .driver         = {
@@ -479,7 +479,7 @@ static struct platform_driver spitzkbd_driver = {
        },
 };
 
-static int __devinit spitzkbd_init(void)
+static int __init spitzkbd_init(void)
 {
        return platform_driver_register(&spitzkbd_driver);
 }
index 9bef935ef19fa04dacc7cea89a79f87e13ce431f..4f38e6f7dfdd6db154b5d6ecc531a0f55e802019 100644 (file)
@@ -70,7 +70,7 @@ config MOUSE_PS2_SYNAPTICS
 config MOUSE_PS2_LIFEBOOK
        bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED
        default y
-       depends on MOUSE_PS2
+       depends on MOUSE_PS2 && X86
        help
          Say Y here if you have a Fujitsu B-series Lifebook PS/2
          TouchScreen connected to your system.
index b9a25d57bc5ea085222597430fd8bb242ba2adee..6ab0eb1ada1c6e94c5c4f3e14d846e24f6b3339d 100644 (file)
@@ -542,7 +542,7 @@ int elantech_detect(struct psmouse *psmouse, int set_properties)
            ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
            ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
            ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
-               pr_err("elantech.c: sending Elantech magic knock failed.\n");
+               pr_debug("elantech.c: sending Elantech magic knock failed.\n");
                return -1;
        }
 
@@ -551,8 +551,27 @@ int elantech_detect(struct psmouse *psmouse, int set_properties)
         * set of magic numbers
         */
        if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) {
-               pr_info("elantech.c: unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n",
-                       param[0], param[1], param[2]);
+               pr_debug("elantech.c: "
+                        "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n",
+                        param[0], param[1], param[2]);
+               return -1;
+       }
+
+       /*
+        * Query touchpad's firmware version and see if it reports known
+        * value to avoid mis-detection. Logitech mice are known to respond
+        * to Elantech magic knock and there might be more.
+        */
+       if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) {
+               pr_debug("elantech.c: failed to query firmware version.\n");
+               return -1;
+       }
+
+       pr_debug("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n",
+                param[0], param[1], param[2]);
+
+       if (param[0] == 0 || param[1] != 0) {
+               pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n");
                return -1;
        }
 
@@ -600,8 +619,7 @@ int elantech_init(struct psmouse *psmouse)
        int i, error;
        unsigned char param[3];
 
-       etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL);
-       psmouse->private = etd;
+       psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL);
        if (!etd)
                return -1;
 
@@ -610,14 +628,12 @@ int elantech_init(struct psmouse *psmouse)
                etd->parity[i] = etd->parity[i & (i - 1)] ^ 1;
 
        /*
-        * Find out what version hardware this is
+        * Do the version query again so we can store the result
         */
        if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) {
                pr_err("elantech.c: failed to query firmware version.\n");
                goto init_fail;
        }
-       pr_info("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n",
-               param[0], param[1], param[2]);
        etd->fw_version_maj = param[0];
        etd->fw_version_min = param[2];
 
index d297accf9a7feeb8077737c187d39d64c3f89c0b..1e827ad0afbedd58a36438cb1fe23e4a0ad3adf8 100644 (file)
@@ -83,7 +83,7 @@ static int write_tbcr(struct pxa930_trkball *trkball, int v)
 
        __raw_writel(v, trkball->mmio_base + TBCR);
 
-       while (i--) {
+       while (--i) {
                if (__raw_readl(trkball->mmio_base + TBCR) == v)
                        break;
                msleep(1);
index 865fc69e9bc39e8ef81b213722e572c95917fb0e..f3e4f7b0240d04d40521f3ff1b79302293c0ea32 100644 (file)
@@ -182,11 +182,6 @@ static int synaptics_identify(struct psmouse *psmouse)
 
 static int synaptics_query_hardware(struct psmouse *psmouse)
 {
-       int retries = 0;
-
-       while ((retries++ < 3) && psmouse_reset(psmouse))
-               /* empty */;
-
        if (synaptics_identify(psmouse))
                return -1;
        if (synaptics_model_id(psmouse))
@@ -582,6 +577,8 @@ static int synaptics_reconnect(struct psmouse *psmouse)
        struct synaptics_data *priv = psmouse->private;
        struct synaptics_data old_priv = *priv;
 
+       psmouse_reset(psmouse);
+
        if (synaptics_detect(psmouse, 0))
                return -1;
 
@@ -640,6 +637,8 @@ int synaptics_init(struct psmouse *psmouse)
        if (!priv)
                return -1;
 
+       psmouse_reset(psmouse);
+
        if (synaptics_query_hardware(psmouse)) {
                printk(KERN_ERR "Unable to query Synaptics hardware.\n");
                goto init_fail;
index b10ffae7c39b341319f89142e01b0845fe5001c3..e29cdc13a199c007ab8ac6c6337086fe3685c5c4 100644 (file)
@@ -57,7 +57,7 @@ static int amba_kmi_write(struct serio *io, unsigned char val)
        struct amba_kmi_port *kmi = io->port_data;
        unsigned int timeleft = 10000; /* timeout in 100ms */
 
-       while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && timeleft--)
+       while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && --timeleft)
                udelay(10);
 
        if (timeleft)
@@ -129,8 +129,8 @@ static int amba_kmi_probe(struct amba_device *dev, void *id)
        io->write       = amba_kmi_write;
        io->open        = amba_kmi_open;
        io->close       = amba_kmi_close;
-       strlcpy(io->name, dev->dev.bus_id, sizeof(io->name));
-       strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys));
+       strlcpy(io->name, dev_name(&dev->dev), sizeof(io->name));
+       strlcpy(io->phys, dev_name(&dev->dev), sizeof(io->phys));
        io->port_data   = kmi;
        io->dev.parent  = &dev->dev;
 
index adc3bd6e7f7bbc9a0d038d748dd3f95794a46f8f..bd0f92d9f40f991c479d9237b851e381887f47e8 100644 (file)
@@ -359,7 +359,7 @@ static int __init gscps2_probe(struct parisc_device *dev)
 
        snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s",
                 (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
-       strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
+       strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
        serio->id.type          = SERIO_8042;
        serio->write            = gscps2_write;
        serio->open             = gscps2_open;
index 2ad88780a170aec1a61bc118c6013ae09dbbfacd..57953c0eb82fa8302b23eb84edf9e6507e5915b3 100644 (file)
@@ -246,8 +246,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev)
        serio->write            = ps2_write;
        serio->open             = ps2_open;
        serio->close            = ps2_close;
-       strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name));
-       strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
+       strlcpy(serio->name, dev_name(&dev->dev), sizeof(serio->name));
+       strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
        serio->port_data        = ps2if;
        serio->dev.parent       = &dev->dev;
        ps2if->io               = serio;
index a89a6a8f05e6c9631f7368fb2488e080490b6fe0..055969e8be132de9a3954c85384b9801b4bcb667 100644 (file)
@@ -236,7 +236,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
        ts_dev->bufferedmeasure = 0;
 
        snprintf(ts_dev->phys, sizeof(ts_dev->phys),
-                "%s/input0", pdev->dev.bus_id);
+                "%s/input0", dev_name(&pdev->dev));
 
        input_dev->name = "atmel touch screen controller";
        input_dev->phys = ts_dev->phys;
index 65202c9f63ffbe4f7838654d59514ea34048ed7d..3fb51b54fe61e22a9960ae0cb58d19721a5d1932 100644 (file)
@@ -268,7 +268,7 @@ static int corgits_resume(struct platform_device *dev)
 #define corgits_resume         NULL
 #endif
 
-static int __init corgits_probe(struct platform_device *pdev)
+static int __devinit corgits_probe(struct platform_device *pdev)
 {
        struct corgi_ts *corgi_ts;
        struct input_dev *input_dev;
@@ -343,7 +343,7 @@ static int __init corgits_probe(struct platform_device *pdev)
        return err;
 }
 
-static int corgits_remove(struct platform_device *pdev)
+static int __devexit corgits_remove(struct platform_device *pdev)
 {
        struct corgi_ts *corgi_ts = platform_get_drvdata(pdev);
 
@@ -352,12 +352,13 @@ static int corgits_remove(struct platform_device *pdev)
        corgi_ts->machinfo->put_hsync();
        input_unregister_device(corgi_ts->input);
        kfree(corgi_ts);
+
        return 0;
 }
 
 static struct platform_driver corgits_driver = {
        .probe          = corgits_probe,
-       .remove         = corgits_remove,
+       .remove         = __devexit_p(corgits_remove),
        .suspend        = corgits_suspend,
        .resume         = corgits_resume,
        .driver         = {
@@ -366,7 +367,7 @@ static struct platform_driver corgits_driver = {
        },
 };
 
-static int __devinit corgits_init(void)
+static int __init corgits_init(void)
 {
        return platform_driver_register(&corgits_driver);
 }
index b75dc2990574e9549d483846d30f77e6f0eb08c1..4ab070246892c5935d8482af73f0499b98b199b6 100644 (file)
@@ -289,7 +289,8 @@ static int tsc2007_probe(struct i2c_client *client,
 
        pdata->init_platform_hw();
 
-       snprintf(ts->phys, sizeof(ts->phys), "%s/input0", client->dev.bus_id);
+       snprintf(ts->phys, sizeof(ts->phys),
+                "%s/input0", dev_name(&client->dev));
 
        input_dev->name = "TSC2007 Touchscreen";
        input_dev->phys = ts->phys;
index 5080b26ba1608ba2c54e1abe4de83d72d2ed62cf..fb7cb9bdfbd5c4971cedeb064b8839ae3d09365a 100644 (file)
@@ -60,6 +60,10 @@ static int swap_xy;
 module_param(swap_xy, bool, 0644);
 MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
 
+static int hwcalib_xy;
+module_param(hwcalib_xy, bool, 0644);
+MODULE_PARM_DESC(hwcalib_xy, "If set hw-calibrated X/Y are used if available");
+
 /* device specifc data/functions */
 struct usbtouch_usb;
 struct usbtouch_device_info {
@@ -118,6 +122,7 @@ enum {
 
 #define USB_DEVICE_HID_CLASS(vend, prod) \
        .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \
+               | USB_DEVICE_ID_MATCH_INT_PROTOCOL \
                | USB_DEVICE_ID_MATCH_DEVICE, \
        .idVendor = (vend), \
        .idProduct = (prod), \
@@ -260,8 +265,13 @@ static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 
 static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 {
-       dev->x = (pkt[8] << 8) | pkt[7];
-       dev->y = (pkt[10] << 8) | pkt[9];
+       if (hwcalib_xy) {
+               dev->x = (pkt[4] << 8) | pkt[3];
+               dev->y = 0xffff - ((pkt[6] << 8) | pkt[5]);
+       } else {
+               dev->x = (pkt[8] << 8) | pkt[7];
+               dev->y = (pkt[10] << 8) | pkt[9];
+       }
        dev->touch = (pkt[2] & 0x40) ? 1 : 0;
 
        return 1;
@@ -294,6 +304,12 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
                        return ret;
        }
 
+       /* Default min/max xy are the raw values, override if using hw-calib */
+       if (hwcalib_xy) {
+               input_set_abs_params(usbtouch->input, ABS_X, 0, 0xffff, 0, 0);
+               input_set_abs_params(usbtouch->input, ABS_Y, 0, 0xffff, 0, 0);
+       }
+
        return 0;
 }
 #endif
index c1e4ae27c61388f9c70c529badef2dfc9dd0808d..c705f248da8856d72c384d5b69b67df0c86a7567 100644 (file)
@@ -46,8 +46,8 @@ static int uvc_input_init(struct uvc_device *dev)
        usb_to_input_id(udev, &input->id);
        input->dev.parent = &dev->intf->dev;
 
-       set_bit(EV_KEY, input->evbit);
-       set_bit(BTN_0, input->keybit);
+       __set_bit(EV_KEY, input->evbit);
+       __set_bit(KEY_CAMERA, input->keybit);
 
        if ((ret = input_register_device(input)) < 0)
                goto error;
@@ -70,8 +70,10 @@ static void uvc_input_cleanup(struct uvc_device *dev)
 static void uvc_input_report_key(struct uvc_device *dev, unsigned int code,
        int value)
 {
-       if (dev->input)
+       if (dev->input) {
                input_report_key(dev->input, code, value);
+               input_sync(dev->input);
+       }
 }
 
 #else
@@ -96,7 +98,7 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len)
                        return;
                uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n",
                        data[1], data[3] ? "pressed" : "released", len);
-               uvc_input_report_key(dev, BTN_0, data[3]);
+               uvc_input_report_key(dev, KEY_CAMERA, data[3]);
        } else {
                uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x "
                        "len %d.\n", data[1], data[2], data[3], len);
index 96ac88317b8ecbadd702a3934c883b579e50aa49..ea3aafbbda449696b6653edc9ebf02094490e067 100644 (file)
@@ -91,9 +91,9 @@ MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \
                controllers (default=0)");
 
 static int mpt_msi_enable_sas;
-module_param(mpt_msi_enable_sas, int, 1);
+module_param(mpt_msi_enable_sas, int, 0);
 MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
-               controllers (default=1)");
+               controllers (default=0)");
 
 
 static int mpt_channel_mapping;
index 8cff5f5e7f86dfa6f743317910afb028db7ca2df..406da9a8d453718b7d057e174199a139cab332e1 100644 (file)
@@ -107,6 +107,7 @@ static const struct sdhci_pci_fixes sdhci_ene_714 = {
 
 static const struct sdhci_pci_fixes sdhci_cafe = {
        .quirks         = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
+                         SDHCI_QUIRK_NO_BUSY_IRQ |
                          SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
 };
 
index f52f3053ed9251a9d3c3b795997e0f6dbd3ffbf5..accb592764edb4522a24160eced3db7afca13f4a 100644 (file)
@@ -1291,8 +1291,11 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
                if (host->cmd->data)
                        DBG("Cannot wait for busy signal when also "
                                "doing a data transfer");
-               else
+               else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ))
                        return;
+
+               /* The controller does not support the end-of-busy IRQ,
+                * fall through and take the SDHCI_INT_RESPONSE */
        }
 
        if (intmask & SDHCI_INT_RESPONSE)
index ebb83657e27ab2b1257ab8ef54a3cb6de18d5abf..43c37c68d07af44c15ab89bb372730b13517be5a 100644 (file)
@@ -208,6 +208,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL                 (1<<12)
 /* Controller has an issue with buffer bits for small transfers */
 #define SDHCI_QUIRK_BROKEN_SMALL_PIO                   (1<<13)
+/* Controller does not provide transfer-complete interrupt when not busy */
+#define SDHCI_QUIRK_NO_BUSY_IRQ                                (1<<14)
 
        int                     irq;            /* Device IRQ */
        void __iomem *          ioaddr;         /* Mapped address */
index c38512ebcea65fd0408ae0821d3be177b2854e26..dc5f051005faaf2af5aafbf7fa46974537883e33 100644 (file)
@@ -1264,8 +1264,14 @@ static void b44_clear_stats(struct b44 *bp)
 static void b44_chip_reset(struct b44 *bp, int reset_kind)
 {
        struct ssb_device *sdev = bp->sdev;
+       bool was_enabled;
 
-       if (ssb_device_is_enabled(bp->sdev)) {
+       was_enabled = ssb_device_is_enabled(bp->sdev);
+
+       ssb_device_enable(bp->sdev, 0);
+       ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev);
+
+       if (was_enabled) {
                bw32(bp, B44_RCV_LAZY, 0);
                bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE);
                b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 200, 1);
@@ -1277,10 +1283,8 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
                }
                bw32(bp, B44_DMARX_CTRL, 0);
                bp->rx_prod = bp->rx_cons = 0;
-       } else
-               ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev);
+       }
 
-       ssb_device_enable(bp->sdev, 0);
        b44_clear_stats(bp);
 
        /*
@@ -2236,6 +2240,7 @@ static void __devexit b44_remove_one(struct ssb_device *sdev)
        struct net_device *dev = ssb_get_drvdata(sdev);
 
        unregister_netdev(dev);
+       ssb_device_disable(sdev, 0);
        ssb_bus_may_powerdown(sdev->bus);
        free_netdev(dev);
        ssb_pcihost_set_power_state(sdev, PCI_D3hot);
index 9b12a13a640f1383fdd3265ae3ebe69949f1b936..9831b3f408aa17fc44431c47b73b8e1057f046eb 100644 (file)
@@ -1284,7 +1284,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
        spin_lock_irqsave(&priv->txlock, flags);
 
        /* check if there is space to queue this packet */
-       if (nr_frags > priv->num_txbdfree) {
+       if ((nr_frags+1) > priv->num_txbdfree) {
                /* no space, stop the queue */
                netif_stop_queue(dev);
                dev->stats.tx_fifo_errors++;
index 5e070f44663504b7207e19caeb7fdd2a91621acb..0486cbe01adbc6195dcd8c4d186227f0cc4406d8 100644 (file)
@@ -467,7 +467,7 @@ init_module(void)
                        if (this_dev != 0) break; /* only autoprobe 1st one */
                        printk(KERN_NOTICE "hp-plus.c: Presently autoprobing (not recommended) for a single card.\n");
                }
-               dev = alloc_ei_netdev();
+               dev = alloc_eip_netdev();
                if (!dev)
                        break;
                dev->irq = irq[this_dev];
index 9f33e442f40339f0d4d862c05c7be39f29502694..13087782ac4068425c78d870022d2c872a5b0d66 100644 (file)
@@ -588,7 +588,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                adapter->pci_mem_read = netxen_nic_pci_mem_read_2M;
                adapter->pci_mem_write = netxen_nic_pci_mem_write_2M;
 
-               mem_ptr0 = ioremap(mem_base, mem_len);
+               mem_ptr0 = pci_ioremap_bar(pdev, 0);
+               if (mem_ptr0 == NULL) {
+                       dev_err(&pdev->dev, "failed to map PCI bar 0\n");
+                       return -EIO;
+               }
+
                pci_len0 = mem_len;
                first_page_group_start = 0;
                first_page_group_end   = 0;
@@ -795,9 +800,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * See if the firmware gave us a virtual-physical port mapping.
         */
        adapter->physical_port = adapter->portnum;
-       i = adapter->pci_read_normalize(adapter, CRB_V2P(adapter->portnum));
-       if (i != 0x55555555)
-               adapter->physical_port = i;
+       if (adapter->fw_major < 4) {
+               i = adapter->pci_read_normalize(adapter,
+                               CRB_V2P(adapter->portnum));
+               if (i != 0x55555555)
+                       adapter->physical_port = i;
+       }
 
        adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
 
index 0771eb6fc6eb452cbf9e0a06793b9f7d0ba32e4d..b3473401c83a3dd0257f006683a831a791c8b1c4 100644 (file)
@@ -81,9 +81,9 @@ static const int multicast_filter_limit = 32;
 #define RTL8169_TX_TIMEOUT     (6*HZ)
 #define RTL8169_PHY_TIMEOUT    (10*HZ)
 
-#define RTL_EEPROM_SIG         cpu_to_le32(0x8129)
-#define RTL_EEPROM_SIG_MASK    cpu_to_le32(0xffff)
+#define RTL_EEPROM_SIG         0x8129
 #define RTL_EEPROM_SIG_ADDR    0x0000
+#define RTL_EEPROM_MAC_ADDR    0x0007
 
 /* write/read MMIO register */
 #define RTL_W8(reg, val8)      writeb ((val8), ioaddr + (reg))
@@ -293,6 +293,11 @@ enum rtl_register_content {
        /* Cfg9346Bits */
        Cfg9346_Lock    = 0x00,
        Cfg9346_Unlock  = 0xc0,
+       Cfg9346_Program = 0x80,         /* Programming mode */
+       Cfg9346_EECS    = 0x08,         /* Chip select */
+       Cfg9346_EESK    = 0x04,         /* Serial data clock */
+       Cfg9346_EEDI    = 0x02,         /* Data input */
+       Cfg9346_EEDO    = 0x01,         /* Data output */
 
        /* rx_mode_bits */
        AcceptErr       = 0x20,
@@ -305,6 +310,7 @@ enum rtl_register_content {
        /* RxConfigBits */
        RxCfgFIFOShift  = 13,
        RxCfgDMAShift   =  8,
+       RxCfg9356SEL    =  6,           /* EEPROM type: 0 = 9346, 1 = 9356 */
 
        /* TxConfigBits */
        TxInterFrameGapShift = 24,
@@ -1963,6 +1969,108 @@ static const struct net_device_ops rtl8169_netdev_ops = {
 
 };
 
+/* Delay between EEPROM clock transitions. Force out buffered PCI writes. */
+#define RTL_EEPROM_DELAY()     RTL_R8(Cfg9346)
+#define RTL_EEPROM_READ_CMD    6
+
+/* read 16bit word stored in EEPROM. EEPROM is addressed by words. */
+static u16 rtl_eeprom_read(void __iomem *ioaddr, int addr)
+{
+       u16 result = 0;
+       int cmd, cmd_len, i;
+
+       /* check for EEPROM address size (in bits) */
+       if (RTL_R32(RxConfig) & (1 << RxCfg9356SEL)) {
+               /* EEPROM is 93C56 */
+               cmd_len = 3 + 8; /* 3 bits for command id and 8 for address */
+               cmd = (RTL_EEPROM_READ_CMD << 8) | (addr & 0xff);
+       } else {
+               /* EEPROM is 93C46 */
+               cmd_len = 3 + 6; /* 3 bits for command id and 6 for address */
+               cmd = (RTL_EEPROM_READ_CMD << 6) | (addr & 0x3f);
+       }
+
+       /* enter programming mode */
+       RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS);
+       RTL_EEPROM_DELAY();
+
+       /* write command and requested address */
+       while (cmd_len--) {
+               u8 x = Cfg9346_Program | Cfg9346_EECS;
+
+               x |= (cmd & (1 << cmd_len)) ? Cfg9346_EEDI : 0;
+
+               /* write a bit */
+               RTL_W8(Cfg9346, x);
+               RTL_EEPROM_DELAY();
+
+               /* raise clock */
+               RTL_W8(Cfg9346, x | Cfg9346_EESK);
+               RTL_EEPROM_DELAY();
+       }
+
+       /* lower clock */
+       RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS);
+       RTL_EEPROM_DELAY();
+
+       /* read back 16bit value */
+       for (i = 16; i > 0; i--) {
+               /* raise clock */
+               RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS | Cfg9346_EESK);
+               RTL_EEPROM_DELAY();
+
+               result <<= 1;
+               result |= (RTL_R8(Cfg9346) & Cfg9346_EEDO) ? 1 : 0;
+
+               /* lower clock */
+               RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS);
+               RTL_EEPROM_DELAY();
+       }
+
+       RTL_W8(Cfg9346, Cfg9346_Program);
+       /* leave programming mode */
+       RTL_W8(Cfg9346, Cfg9346_Lock);
+
+       return result;
+}
+
+static void rtl_init_mac_address(struct rtl8169_private *tp,
+                                void __iomem *ioaddr)
+{
+       struct pci_dev *pdev = tp->pci_dev;
+       u16 x;
+       u8 mac[8];
+
+       /* read EEPROM signature */
+       x = rtl_eeprom_read(ioaddr, RTL_EEPROM_SIG_ADDR);
+
+       if (x != RTL_EEPROM_SIG) {
+               dev_info(&pdev->dev, "Missing EEPROM signature: %04x\n", x);
+               return;
+       }
+
+       /* read MAC address */
+       x = rtl_eeprom_read(ioaddr, RTL_EEPROM_MAC_ADDR);
+       mac[0] = x & 0xff;
+       mac[1] = x >> 8;
+       x = rtl_eeprom_read(ioaddr, RTL_EEPROM_MAC_ADDR + 1);
+       mac[2] = x & 0xff;
+       mac[3] = x >> 8;
+       x = rtl_eeprom_read(ioaddr, RTL_EEPROM_MAC_ADDR + 2);
+       mac[4] = x & 0xff;
+       mac[5] = x >> 8;
+
+       if (netif_msg_probe(tp)) {
+               DECLARE_MAC_BUF(buf);
+
+               dev_info(&pdev->dev, "MAC address found in EEPROM: %s\n",
+                        print_mac(buf, mac));
+       }
+
+       if (is_valid_ether_addr(mac))
+               rtl_rar_set(tp, mac);
+}
+
 static int __devinit
 rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -2141,6 +2249,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        tp->mmio_addr = ioaddr;
 
+       rtl_init_mac_address(tp, ioaddr);
+
        /* Get MAC address */
        for (i = 0; i < MAC_ADDR_LEN; i++)
                dev->dev_addr[i] = RTL_R8(MAC0 + i);
index e009481c606c740cea0b2a30fd7bad7f30f3fe8d..396f821b5ff00cdd11bc5033b709b3c6ba06d131 100644 (file)
@@ -1451,6 +1451,14 @@ static const struct usb_device_id        products [] = {
        // Cables-to-Go USB Ethernet Adapter
        USB_DEVICE(0x0b95, 0x772a),
        .driver_info = (unsigned long) &ax88772_info,
+}, {
+       // ABOCOM for pci
+       USB_DEVICE(0x14ea, 0xab11),
+       .driver_info = (unsigned long) &ax88178_info,
+}, {
+       // ASIX 88772a
+       USB_DEVICE(0x0db0, 0xa877),
+       .driver_info = (unsigned long) &ax88772_info,
 },
        { },            // END
 };
index 0e061dfea78d15226e65da13e5aa1f764c09bd30..55e8ecc3a9e5d5bd6eb88038530ccada469bb2c6 100644 (file)
@@ -559,6 +559,11 @@ static const struct usb_device_id  products [] = {
        USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
                        USB_CDC_PROTO_NONE),
        .driver_info = (unsigned long) &cdc_info,
+}, {
+       /* Ericsson F3507g */
+       USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &cdc_info,
 },
        { },            // END
 };
index aa31490788880bb3b609acae0a9ab7332cce28c7..c32284ff3f54a698018021603e4ccbd92f7777a3 100644 (file)
@@ -723,8 +723,8 @@ u32 usbnet_get_link (struct net_device *net)
        if (dev->mii.mdio_read)
                return mii_link_ok(&dev->mii);
 
-       /* Otherwise, say we're up (to avoid breaking scripts) */
-       return 1;
+       /* Otherwise, dtrt for drivers calling netif_carrier_{on,off} */
+       return ethtool_op_get_link(net);
 }
 EXPORT_SYMBOL_GPL(usbnet_get_link);
 
index e24f7b3ace4bd470fcfbf65dffc69bf2df20f383..04882c8f9bf18dfd547802704c72012f18e57761 100644 (file)
@@ -341,6 +341,11 @@ static const struct usb_device_id  products [] = {
        USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
                        USB_CDC_PROTO_NONE),
        .driver_info = (unsigned long) &bogus_mdlm_info,
+}, {
+       /* Motorola MOTOMAGX phones */
+       USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &bogus_mdlm_info,
 },
 
 /* Olympus has some models with a Zaurus-compatible option.
index 108bbbeacfb61a956223094160715344894b7b2e..124fe75b8a8a964928092b3d42c397fa847ac943 100644 (file)
@@ -239,6 +239,16 @@ static int veth_open(struct net_device *dev)
        return 0;
 }
 
+static int veth_close(struct net_device *dev)
+{
+       struct veth_priv *priv = netdev_priv(dev);
+
+       netif_carrier_off(dev);
+       netif_carrier_off(priv->peer);
+
+       return 0;
+}
+
 static int veth_dev_init(struct net_device *dev)
 {
        struct veth_net_stats *stats;
@@ -265,6 +275,7 @@ static void veth_dev_free(struct net_device *dev)
 static const struct net_device_ops veth_netdev_ops = {
        .ndo_init            = veth_dev_init,
        .ndo_open            = veth_open,
+       .ndo_stop            = veth_close,
        .ndo_start_xmit      = veth_xmit,
        .ndo_get_stats       = veth_get_stats,
        .ndo_set_mac_address = eth_mac_addr,
@@ -280,44 +291,6 @@ static void veth_setup(struct net_device *dev)
        dev->destructor = veth_dev_free;
 }
 
-static void veth_change_state(struct net_device *dev)
-{
-       struct net_device *peer;
-       struct veth_priv *priv;
-
-       priv = netdev_priv(dev);
-       peer = priv->peer;
-
-       if (netif_carrier_ok(peer)) {
-               if (!netif_carrier_ok(dev))
-                       netif_carrier_on(dev);
-       } else {
-               if (netif_carrier_ok(dev))
-                       netif_carrier_off(dev);
-       }
-}
-
-static int veth_device_event(struct notifier_block *unused,
-                            unsigned long event, void *ptr)
-{
-       struct net_device *dev = ptr;
-
-       if (dev->netdev_ops->ndo_open != veth_open)
-               goto out;
-
-       switch (event) {
-       case NETDEV_CHANGE:
-               veth_change_state(dev);
-               break;
-       }
-out:
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block veth_notifier_block __read_mostly = {
-       .notifier_call  = veth_device_event,
-};
-
 /*
  * netlink interface
  */
@@ -468,14 +441,12 @@ static struct rtnl_link_ops veth_link_ops = {
 
 static __init int veth_init(void)
 {
-       register_netdevice_notifier(&veth_notifier_block);
        return rtnl_link_register(&veth_link_ops);
 }
 
 static __exit void veth_exit(void)
 {
        rtnl_link_unregister(&veth_link_ops);
-       unregister_netdevice_notifier(&veth_notifier_block);
 }
 
 module_init(veth_init);
index 727f067aca4f8a764cbf9284c287b20ad96b73e4..0e80990d8e843b7420ff437963d967e6a054d7eb 100644 (file)
@@ -1538,6 +1538,7 @@ bad2:
 bad:
        if (ah)
                ath9k_hw_detach(ah);
+       ath9k_exit_debug(sc);
 
        return error;
 }
@@ -1545,7 +1546,7 @@ bad:
 static int ath_attach(u16 devid, struct ath_softc *sc)
 {
        struct ieee80211_hw *hw = sc->hw;
-       int error = 0;
+       int error = 0, i;
 
        DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
 
@@ -1589,11 +1590,11 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
        /* initialize tx/rx engine */
        error = ath_tx_init(sc, ATH_TXBUF);
        if (error != 0)
-               goto detach;
+               goto error_attach;
 
        error = ath_rx_init(sc, ATH_RXBUF);
        if (error != 0)
-               goto detach;
+               goto error_attach;
 
 #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
        /* Initialze h/w Rfkill */
@@ -1601,8 +1602,9 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
                INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
 
        /* Initialize s/w rfkill */
-       if (ath_init_sw_rfkill(sc))
-               goto detach;
+       error = ath_init_sw_rfkill(sc);
+       if (error)
+               goto error_attach;
 #endif
 
        error = ieee80211_register_hw(hw);
@@ -1611,8 +1613,16 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
        ath_init_leds(sc);
 
        return 0;
-detach:
-       ath_detach(sc);
+
+error_attach:
+       /* cleanup tx queues */
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+
+       ath9k_hw_detach(sc->sc_ah);
+       ath9k_exit_debug(sc);
+
        return error;
 }
 
index 61d2f50470c8e82f76e031cc82011846689f4723..b118a35ec605dd36dafbb27968dacefec444a62d 100644 (file)
@@ -23,7 +23,7 @@ static const char * mesh_stat_strings[]= {
 static void lbs_ethtool_get_drvinfo(struct net_device *dev,
                                         struct ethtool_drvinfo *info)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        snprintf(info->fw_version, 32, "%u.%u.%u.p%u",
                priv->fwrelease >> 24 & 0xff,
@@ -47,7 +47,7 @@ static int lbs_ethtool_get_eeprom_len(struct net_device *dev)
 static int lbs_ethtool_get_eeprom(struct net_device *dev,
                                   struct ethtool_eeprom *eeprom, u8 * bytes)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct cmd_ds_802_11_eeprom_access cmd;
        int ret;
 
@@ -76,7 +76,7 @@ out:
 static void lbs_ethtool_get_stats(struct net_device *dev,
                                  struct ethtool_stats *stats, uint64_t *data)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct cmd_ds_mesh_access mesh_access;
        int ret;
 
@@ -113,7 +113,7 @@ static void lbs_ethtool_get_stats(struct net_device *dev,
 
 static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
                return MESH_STATS_NUM;
@@ -143,7 +143,7 @@ static void lbs_ethtool_get_strings(struct net_device *dev,
 static void lbs_ethtool_get_wol(struct net_device *dev,
                                struct ethtool_wolinfo *wol)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        if (priv->wol_criteria == 0xffffffff) {
                /* Interface driver didn't configure wake */
@@ -166,7 +166,7 @@ static void lbs_ethtool_get_wol(struct net_device *dev,
 static int lbs_ethtool_set_wol(struct net_device *dev,
                               struct ethtool_wolinfo *wol)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        uint32_t criteria = 0;
 
        if (priv->wol_criteria == 0xffffffff && wol->wolopts)
index 2fc637ad85c741b84b94ba1a7f230f30077a4b8a..ea3dc038be76e3c88d89abb9e75328b993501b77 100644 (file)
@@ -59,7 +59,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp);
 static ssize_t if_usb_firmware_set(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        struct if_usb_card *cardp = priv->card;
        char fwname[FIRMWARE_NAME_MAX];
        int ret;
@@ -86,7 +86,7 @@ static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set);
 static ssize_t if_usb_boot2_set(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        struct if_usb_card *cardp = priv->card;
        char fwname[FIRMWARE_NAME_MAX];
        int ret;
index 4e0007d200308d72741d5580eb0396684e636524..f76623e0ff9a55106c7a62855f21721a10dd4a8a 100644 (file)
@@ -222,7 +222,7 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
 static ssize_t lbs_anycast_get(struct device *dev,
                struct device_attribute *attr, char * buf)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        struct cmd_ds_mesh_access mesh_access;
        int ret;
 
@@ -241,7 +241,7 @@ static ssize_t lbs_anycast_get(struct device *dev,
 static ssize_t lbs_anycast_set(struct device *dev,
                struct device_attribute *attr, const char * buf, size_t count)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        struct cmd_ds_mesh_access mesh_access;
        uint32_t datum;
        int ret;
@@ -263,7 +263,7 @@ static ssize_t lbs_anycast_set(struct device *dev,
 static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        struct cmd_ds_mesh_access mesh_access;
        int ret;
        u32 retry_limit;
@@ -286,7 +286,7 @@ static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
 static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        struct cmd_ds_mesh_access mesh_access;
        int ret;
        unsigned long retry_limit;
@@ -321,7 +321,7 @@ static void lbs_remove_mesh(struct lbs_private *priv);
 static ssize_t lbs_rtap_get(struct device *dev,
                struct device_attribute *attr, char * buf)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        return snprintf(buf, 5, "0x%X\n", priv->monitormode);
 }
 
@@ -332,7 +332,7 @@ static ssize_t lbs_rtap_set(struct device *dev,
                struct device_attribute *attr, const char * buf, size_t count)
 {
        int monitor_mode;
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
 
        sscanf(buf, "%x", &monitor_mode);
        if (monitor_mode) {
@@ -383,7 +383,7 @@ static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
 static ssize_t lbs_mesh_get(struct device *dev,
                struct device_attribute *attr, char * buf)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
 }
 
@@ -393,7 +393,7 @@ static ssize_t lbs_mesh_get(struct device *dev,
 static ssize_t lbs_mesh_set(struct device *dev,
                struct device_attribute *attr, const char * buf, size_t count)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        int enable;
        int ret, action = CMD_ACT_MESH_CONFIG_STOP;
 
@@ -452,7 +452,7 @@ static struct attribute_group lbs_mesh_attr_group = {
  */
 static int lbs_dev_open(struct net_device *dev)
 {
-       struct lbs_private *priv = netdev_priv(dev) ;
+       struct lbs_private *priv = dev->ml_priv;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_NET);
@@ -521,7 +521,7 @@ static int lbs_mesh_stop(struct net_device *dev)
  */
 static int lbs_eth_stop(struct net_device *dev)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_NET);
 
@@ -538,7 +538,7 @@ static int lbs_eth_stop(struct net_device *dev)
 
 static void lbs_tx_timeout(struct net_device *dev)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_TX);
 
@@ -590,7 +590,7 @@ EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
  */
 static struct net_device_stats *lbs_get_stats(struct net_device *dev)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_NET);
        return &priv->stats;
@@ -599,7 +599,7 @@ static struct net_device_stats *lbs_get_stats(struct net_device *dev)
 static int lbs_set_mac_address(struct net_device *dev, void *addr)
 {
        int ret = 0;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct sockaddr *phwaddr = addr;
        struct cmd_ds_802_11_mac_address cmd;
 
@@ -732,7 +732,7 @@ static void lbs_set_mcast_worker(struct work_struct *work)
 
 static void lbs_set_multicast_list(struct net_device *dev)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        schedule_work(&priv->mcast_work);
 }
@@ -748,7 +748,7 @@ static void lbs_set_multicast_list(struct net_device *dev)
 static int lbs_thread(void *data)
 {
        struct net_device *dev = data;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        wait_queue_t wait;
 
        lbs_deb_enter(LBS_DEB_THREAD);
@@ -1184,6 +1184,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
                goto done;
        }
        priv = netdev_priv(dev);
+       dev->ml_priv = priv;
 
        if (lbs_init_adapter(priv)) {
                lbs_pr_err("failed to initialize adapter structure.\n");
index d42b7a5a1b3f32a564579771e19149429348db5b..18fe29faf99b1cb1362a81c5f65fe0e1c47cc46c 100644 (file)
@@ -18,7 +18,7 @@
 static int mesh_get_default_parameters(struct device *dev,
                                       struct mrvl_mesh_defaults *defs)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        struct cmd_ds_mesh_config cmd;
        int ret;
 
@@ -57,7 +57,7 @@ static ssize_t bootflag_get(struct device *dev,
 static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
                            const char *buf, size_t count)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        struct cmd_ds_mesh_config cmd;
        uint32_t datum;
        int ret;
@@ -100,7 +100,7 @@ static ssize_t boottime_get(struct device *dev,
 static ssize_t boottime_set(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        struct cmd_ds_mesh_config cmd;
        uint32_t datum;
        int ret;
@@ -152,7 +152,7 @@ static ssize_t channel_get(struct device *dev,
 static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
                           const char *buf, size_t count)
 {
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        struct cmd_ds_mesh_config cmd;
        uint32_t datum;
        int ret;
@@ -210,7 +210,7 @@ static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
        struct cmd_ds_mesh_config cmd;
        struct mrvl_mesh_defaults defs;
        struct mrvl_meshie *ie;
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        int len;
        int ret;
 
@@ -269,7 +269,7 @@ static ssize_t protocol_id_set(struct device *dev,
        struct cmd_ds_mesh_config cmd;
        struct mrvl_mesh_defaults defs;
        struct mrvl_meshie *ie;
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        uint32_t datum;
        int ret;
 
@@ -323,7 +323,7 @@ static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
        struct cmd_ds_mesh_config cmd;
        struct mrvl_mesh_defaults defs;
        struct mrvl_meshie *ie;
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        uint32_t datum;
        int ret;
 
@@ -377,7 +377,7 @@ static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
        struct cmd_ds_mesh_config cmd;
        struct mrvl_mesh_defaults defs;
        struct mrvl_meshie *ie;
-       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        uint32_t datum;
        int ret;
 
index 57f6c12cda2085a902a8fae4e1e950c138f34475..9014950f4328aa135835d74d3fb27ee19d9ac305 100644 (file)
@@ -945,7 +945,7 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
                 union iwreq_data *wrqu, char *extra)
 {
        DECLARE_SSID_BUF(ssid);
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -1008,7 +1008,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
                 struct iw_point *dwrq, char *extra)
 {
 #define SCAN_ITEM_SIZE 128
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        int err = 0;
        char *ev = extra;
        char *stop = ev + dwrq->length;
index dac462641170e6193da4f04cfd44e39222520ba3..68bec31ae03bcfb6c0659e3fefdb3a110a7d886e 100644 (file)
@@ -60,7 +60,7 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
 int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned long flags;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct txpd *txpd;
        char *p802x_hdr;
        uint16_t pkt_len;
index c6102e08179e6ba7d9fcc09d7fb8a26da721024b..f16d136ab4bb5555b2069fcdf151eedd0db47277 100644 (file)
@@ -163,7 +163,7 @@ static int lbs_get_name(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
                         struct iw_freq *fwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct chan_freq_power *cfp;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -189,7 +189,7 @@ static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info,
                        struct sockaddr *awrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -207,7 +207,7 @@ static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info,
 static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info,
                         struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -231,7 +231,7 @@ static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
                         struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -248,7 +248,7 @@ static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
 static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
                         struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -273,7 +273,7 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
                        struct iw_param *vwrq, char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        u32 val = vwrq->value;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -293,7 +293,7 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info,
                        struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        int ret = 0;
        u16 val = 0;
 
@@ -315,7 +315,7 @@ out:
 static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
                         struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        int ret = 0;
        u32 val = vwrq->value;
 
@@ -336,7 +336,7 @@ static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info,
                         struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        int ret = 0;
        u16 val = 0;
 
@@ -359,7 +359,7 @@ out:
 static int lbs_get_mode(struct net_device *dev,
                         struct iw_request_info *info, u32 * uwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -385,7 +385,7 @@ static int lbs_get_txpow(struct net_device *dev,
                          struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        s16 curlevel = 0;
        int ret = 0;
 
@@ -418,7 +418,7 @@ out:
 static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        int ret = 0;
        u16 slimit = 0, llimit = 0;
 
@@ -466,7 +466,7 @@ out:
 static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        int ret = 0;
        u16 val = 0;
 
@@ -542,7 +542,7 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info,
                          struct iw_point *dwrq, char *extra)
 {
        int i, j;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct iw_range *range = (struct iw_range *)extra;
        struct chan_freq_power *cfp;
        u8 rates[MAX_RATES + 1];
@@ -708,7 +708,7 @@ out:
 static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -758,7 +758,7 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_power(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -781,7 +781,7 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
                EXCELLENT = 95,
                PERFECT = 100
        };
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        u32 rssi_qual;
        u32 tx_qual;
        u32 quality = 0;
@@ -886,7 +886,7 @@ static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info,
                  struct iw_freq *fwrq, char *extra)
 {
        int ret = -EINVAL;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct chan_freq_power *cfp;
        struct assoc_request * assoc_req;
 
@@ -943,7 +943,7 @@ static int lbs_mesh_set_freq(struct net_device *dev,
                             struct iw_request_info *info,
                             struct iw_freq *fwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct chan_freq_power *cfp;
        int ret = -EINVAL;
 
@@ -994,7 +994,7 @@ out:
 static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
                  struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        u8 new_rate = 0;
        int ret = -EINVAL;
        u8 rates[MAX_RATES + 1];
@@ -1054,7 +1054,7 @@ out:
 static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info,
                  struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -1079,7 +1079,7 @@ static int lbs_set_mode(struct net_device *dev,
                  struct iw_request_info *info, u32 * uwrq, char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct assoc_request * assoc_req;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -1124,7 +1124,7 @@ static int lbs_get_encode(struct net_device *dev,
                           struct iw_request_info *info,
                           struct iw_point *dwrq, u8 * extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -1319,7 +1319,7 @@ static int lbs_set_encode(struct net_device *dev,
                    struct iw_point *dwrq, char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct assoc_request * assoc_req;
        u16 is_default = 0, index = 0, set_tx_key = 0;
 
@@ -1395,7 +1395,7 @@ static int lbs_get_encodeext(struct net_device *dev,
                              char *extra)
 {
        int ret = -EINVAL;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        int index, max_key_len;
 
@@ -1501,7 +1501,7 @@ static int lbs_set_encodeext(struct net_device *dev,
                              char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        int alg = ext->alg;
        struct assoc_request * assoc_req;
@@ -1639,7 +1639,7 @@ static int lbs_set_genie(struct net_device *dev,
                          struct iw_point *dwrq,
                          char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        int ret = 0;
        struct assoc_request * assoc_req;
 
@@ -1685,7 +1685,7 @@ static int lbs_get_genie(struct net_device *dev,
                          char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -1713,7 +1713,7 @@ static int lbs_set_auth(struct net_device *dev,
                         struct iw_param *dwrq,
                         char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct assoc_request * assoc_req;
        int ret = 0;
        int updated = 0;
@@ -1816,7 +1816,7 @@ static int lbs_get_auth(struct net_device *dev,
                         char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -1857,7 +1857,7 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
                   struct iw_param *vwrq, char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        s16 dbm = (s16) vwrq->value;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -1936,7 +1936,7 @@ out:
 static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
                   struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -1971,7 +1971,7 @@ static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
 static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
                   struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        int ret = 0;
        u8 ssid[IW_ESSID_MAX_SIZE];
        u8 ssid_len = 0;
@@ -2040,7 +2040,7 @@ static int lbs_mesh_get_essid(struct net_device *dev,
                              struct iw_request_info *info,
                              struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -2058,7 +2058,7 @@ static int lbs_mesh_set_essid(struct net_device *dev,
                              struct iw_request_info *info,
                              struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -2102,7 +2102,7 @@ static int lbs_mesh_set_essid(struct net_device *dev,
 static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
                 struct sockaddr *awrq, char *extra)
 {
-       struct lbs_private *priv = netdev_priv(dev);
+       struct lbs_private *priv = dev->ml_priv;
        struct assoc_request * assoc_req;
        int ret = 0;
 
index 45a04faa7818e7ead799eeee65030bd08ede0592..067d1a9c728b47e3755398c1a2809d7279eefd59 100644 (file)
@@ -3157,8 +3157,20 @@ static int orinoco_pm_notifier(struct notifier_block *notifier,
 
        return NOTIFY_DONE;
 }
+
+static void orinoco_register_pm_notifier(struct orinoco_private *priv)
+{
+       priv->pm_notifier.notifier_call = orinoco_pm_notifier;
+       register_pm_notifier(&priv->pm_notifier);
+}
+
+static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
+{
+       unregister_pm_notifier(&priv->pm_notifier);
+}
 #else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */
-#define orinoco_pm_notifier NULL
+#define orinoco_register_pm_notifier(priv) do { } while(0)
+#define orinoco_unregister_pm_notifier(priv) do { } while(0)
 #endif
 
 /********************************************************************/
@@ -3648,8 +3660,7 @@ struct net_device
        priv->cached_fw = NULL;
 
        /* Register PM notifiers */
-       priv->pm_notifier.notifier_call = orinoco_pm_notifier;
-       register_pm_notifier(&priv->pm_notifier);
+       orinoco_register_pm_notifier(priv);
 
        return dev;
 }
@@ -3673,7 +3684,7 @@ void free_orinocodev(struct net_device *dev)
                kfree(rx_data);
        }
 
-       unregister_pm_notifier(&priv->pm_notifier);
+       orinoco_unregister_pm_notifier(priv);
        orinoco_uncache_fw(priv);
 
        priv->wpa_ie_len = 0;
index 22bc07ef2f3784f70d3588d0a481993dde08a9b8..f4747a1134ba97420e8a0525964449efba6b5a2b 100644 (file)
@@ -48,6 +48,10 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
        {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
        {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
        {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B},
+       /* Surecom */
+       {USB_DEVICE(0x0769, 0x11F2), .driver_info = DEVICE_RTL8187},
+       /* Logitech */
+       {USB_DEVICE(0x0789, 0x010C), .driver_info = DEVICE_RTL8187},
        /* Netgear */
        {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
        {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
@@ -57,8 +61,16 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
        /* Sitecom */
        {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
        {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
+       /* Sphairon Access Systems GmbH */
+       {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187},
+       /* Dick Smith Electronics */
+       {USB_DEVICE(0x1371, 0x9401), .driver_info = DEVICE_RTL8187},
        /* Abocom */
        {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187},
+       /* Qcom */
+       {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187},
+       /* AirLive */
+       {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187},
        {}
 };
 
index fde6e4c634e71878c79e4ae771781fc968663467..a7cf550b9cca0ba030f7b58a8c81ccc2ef954e41 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/list.h>
 #include <linux/netdevice.h>
 #include <linux/scatterlist.h>
+#include <linux/skbuff.h>
 #include <scsi/libiscsi_tcp.h>
 
 /* from cxgb3 LLD */
@@ -113,6 +114,26 @@ struct cxgb3i_endpoint {
        struct cxgb3i_conn *cconn;
 };
 
+/**
+ * struct cxgb3i_task_data - private iscsi task data
+ *
+ * @nr_frags:  # of coalesced page frags (from scsi sgl)
+ * @frags:     coalesced page frags (from scsi sgl)
+ * @skb:       tx pdu skb
+ * @offset:    data offset for the next pdu
+ * @count:     max. possible pdu payload
+ * @sgoffset:  offset to the first sg entry for a given offset
+ */
+#define MAX_PDU_FRAGS  ((ULP2_MAX_PDU_PAYLOAD + 512 - 1) / 512)
+struct cxgb3i_task_data {
+       unsigned short nr_frags;
+       skb_frag_t frags[MAX_PDU_FRAGS];
+       struct sk_buff *skb;
+       unsigned int offset;
+       unsigned int count;
+       unsigned int sgoffset;
+};
+
 int cxgb3i_iscsi_init(void);
 void cxgb3i_iscsi_cleanup(void);
 
index 08f3a09d92330863fa692263ecd556b0185285d3..a83d36e4926fc64b646e3d828f1a0d878304a66b 100644 (file)
@@ -639,10 +639,11 @@ static int ddp_init(struct t3cdev *tdev)
        write_unlock(&cxgb3i_ddp_rwlock);
 
        ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x "
-                       "pkt %u,%u.\n",
+                       "pkt %u/%u, %u/%u.\n",
                        ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits,
                        ddp->idx_mask, ddp->rsvd_tag_mask,
-                       ddp->max_txsz, ddp->max_rxsz);
+                       ddp->max_txsz, uinfo.max_txsz,
+                       ddp->max_rxsz, uinfo.max_rxsz);
        return 0;
 
 free_ddp_map:
@@ -654,8 +655,8 @@ free_ddp_map:
  * cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource
  * @tdev: t3cdev adapter
  * @tformat: tag format
- * @txsz: max tx pkt size, filled in by this func.
- * @rxsz: max rx pkt size, filled in by this func.
+ * @txsz: max tx pdu payload size, filled in by this func.
+ * @rxsz: max rx pdu payload size, filled in by this func.
  * initialize the ddp pagepod manager for a given adapter if needed and
  * setup the tag format for a given iscsi entity
  */
@@ -685,10 +686,12 @@ int cxgb3i_adapter_ddp_init(struct t3cdev *tdev,
                      tformat->sw_bits, tformat->rsvd_bits,
                      tformat->rsvd_shift, tformat->rsvd_mask);
 
-       *txsz = ddp->max_txsz;
-       *rxsz = ddp->max_rxsz;
-       ddp_log_info("ddp max pkt size: %u, %u.\n",
-                    ddp->max_txsz, ddp->max_rxsz);
+       *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+                       ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN);
+       *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+                       ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN);
+       ddp_log_info("max payload size: %u/%u, %u/%u.\n",
+                    *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz);
        return 0;
 }
 EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init);
index 5c7c4d95c493c044141a38281e3a06b98f09464f..3faae7831c838a97693e6f91d4fe77460c9f7b5b 100644 (file)
@@ -13,6 +13,8 @@
 #ifndef __CXGB3I_ULP2_DDP_H__
 #define __CXGB3I_ULP2_DDP_H__
 
+#include <linux/vmalloc.h>
+
 /**
  * struct cxgb3i_tag_format - cxgb3i ulp tag format for an iscsi entity
  *
@@ -85,8 +87,9 @@ struct cxgb3i_ddp_info {
        struct sk_buff **gl_skb;
 };
 
+#define ISCSI_PDU_NONPAYLOAD_LEN       312 /* bhs(48) + ahs(256) + digest(8) */
 #define ULP2_MAX_PKT_SIZE      16224
-#define ULP2_MAX_PDU_PAYLOAD   (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_MAX)
+#define ULP2_MAX_PDU_PAYLOAD   (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN)
 #define PPOD_PAGES_MAX         4
 #define PPOD_PAGES_SHIFT       2       /* 4 pages per pod */
 
index 091ecb4d9f3d8c8febaed68af246c69b2e486768..1ce9f244e46c53d9725cb9d953b0b8169e1470fe 100644 (file)
@@ -12,8 +12,8 @@
 #include "cxgb3i.h"
 
 #define DRV_MODULE_NAME         "cxgb3i"
-#define DRV_MODULE_VERSION     "1.0.0"
-#define DRV_MODULE_RELDATE     "Jun. 1, 2008"
+#define DRV_MODULE_VERSION     "1.0.1"
+#define DRV_MODULE_RELDATE     "Jan. 2009"
 
 static char version[] =
        "Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME
index d83464b9b3f9c66c23fc9dd379626287e835cfdb..fa2a44f37b361e657a6d37bb452c90b6e461200c 100644 (file)
@@ -364,7 +364,8 @@ cxgb3i_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth,
 
        cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost,
                                          cmds_max,
-                                         sizeof(struct iscsi_tcp_task),
+                                         sizeof(struct iscsi_tcp_task) +
+                                         sizeof(struct cxgb3i_task_data),
                                          initial_cmdsn, ISCSI_MAX_TARGET);
        if (!cls_session)
                return NULL;
@@ -402,17 +403,15 @@ static inline int cxgb3i_conn_max_xmit_dlength(struct iscsi_conn *conn)
 {
        struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
        struct cxgb3i_conn *cconn = tcp_conn->dd_data;
-       unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
-                                cconn->hba->snic->tx_max_size -
-                                ISCSI_PDU_NONPAYLOAD_MAX);
+       unsigned int max = max(512 * MAX_SKB_FRAGS, SKB_TX_HEADROOM);
 
+       max = min(cconn->hba->snic->tx_max_size, max);
        if (conn->max_xmit_dlength)
-               conn->max_xmit_dlength = min_t(unsigned int,
-                                               conn->max_xmit_dlength, max);
+               conn->max_xmit_dlength = min(conn->max_xmit_dlength, max);
        else
                conn->max_xmit_dlength = max;
        align_pdu_size(conn->max_xmit_dlength);
-       cxgb3i_log_info("conn 0x%p, max xmit %u.\n",
+       cxgb3i_api_debug("conn 0x%p, max xmit %u.\n",
                         conn, conn->max_xmit_dlength);
        return 0;
 }
@@ -427,9 +426,7 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn)
 {
        struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
        struct cxgb3i_conn *cconn = tcp_conn->dd_data;
-       unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
-                                cconn->hba->snic->rx_max_size -
-                                ISCSI_PDU_NONPAYLOAD_MAX);
+       unsigned int max = cconn->hba->snic->rx_max_size;
 
        align_pdu_size(max);
        if (conn->max_recv_dlength) {
@@ -439,8 +436,7 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn)
                                         conn->max_recv_dlength, max);
                        return -EINVAL;
                }
-               conn->max_recv_dlength = min_t(unsigned int,
-                                               conn->max_recv_dlength, max);
+               conn->max_recv_dlength = min(conn->max_recv_dlength, max);
                align_pdu_size(conn->max_recv_dlength);
        } else
                conn->max_recv_dlength = max;
@@ -844,7 +840,7 @@ static struct scsi_host_template cxgb3i_host_template = {
        .proc_name              = "cxgb3i",
        .queuecommand           = iscsi_queuecommand,
        .change_queue_depth     = iscsi_change_queue_depth,
-       .can_queue              = 128 * (ISCSI_DEF_XMIT_CMDS_MAX - 1),
+       .can_queue              = CXGB3I_SCSI_QDEPTH_DFLT - 1,
        .sg_tablesize           = SG_ALL,
        .max_sectors            = 0xFFFF,
        .cmd_per_lun            = ISCSI_DEF_CMD_PER_LUN,
index a865f1fefe8bfebbcbc2af1a391238acb840849d..de3b3b614cca7a92fff8e395be632d3a3eb6b2db 100644 (file)
 #include "cxgb3i_ddp.h"
 
 #ifdef __DEBUG_C3CN_CONN__
-#define c3cn_conn_debug         cxgb3i_log_info
+#define c3cn_conn_debug                cxgb3i_log_debug
 #else
 #define c3cn_conn_debug(fmt...)
 #endif
 
 #ifdef __DEBUG_C3CN_TX__
-#define c3cn_tx_debug         cxgb3i_log_debug
+#define c3cn_tx_debug          cxgb3i_log_debug
 #else
 #define c3cn_tx_debug(fmt...)
 #endif
 
 #ifdef __DEBUG_C3CN_RX__
-#define c3cn_rx_debug         cxgb3i_log_debug
+#define c3cn_rx_debug          cxgb3i_log_debug
 #else
 #define c3cn_rx_debug(fmt...)
 #endif
@@ -47,9 +47,9 @@ static int cxgb3_rcv_win = 256 * 1024;
 module_param(cxgb3_rcv_win, int, 0644);
 MODULE_PARM_DESC(cxgb3_rcv_win, "TCP receive window in bytes (default=256KB)");
 
-static int cxgb3_snd_win = 64 * 1024;
+static int cxgb3_snd_win = 128 * 1024;
 module_param(cxgb3_snd_win, int, 0644);
-MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=64KB)");
+MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=128KB)");
 
 static int cxgb3_rx_credit_thres = 10 * 1024;
 module_param(cxgb3_rx_credit_thres, int, 0644);
@@ -301,8 +301,8 @@ static void act_open_req_arp_failure(struct t3cdev *dev, struct sk_buff *skb)
 static void skb_entail(struct s3_conn *c3cn, struct sk_buff *skb,
                       int flags)
 {
-       CXGB3_SKB_CB(skb)->seq = c3cn->write_seq;
-       CXGB3_SKB_CB(skb)->flags = flags;
+       skb_tcp_seq(skb) = c3cn->write_seq;
+       skb_flags(skb) = flags;
        __skb_queue_tail(&c3cn->write_queue, skb);
 }
 
@@ -457,12 +457,9 @@ static unsigned int wrlen __read_mostly;
  * The number of WRs needed for an skb depends on the number of fragments
  * in the skb and whether it has any payload in its main body.  This maps the
  * length of the gather list represented by an skb into the # of necessary WRs.
- *
- * The max. length of an skb is controlled by the max pdu size which is ~16K.
- * Also, assume the min. fragment length is the sector size (512), then add
- * extra fragment counts for iscsi bhs and payload padding.
+ * The extra two fragments are for iscsi bhs and payload padding.
  */
-#define SKB_WR_LIST_SIZE       (16384/512 + 3)
+#define SKB_WR_LIST_SIZE       (MAX_SKB_FRAGS + 2)
 static unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly;
 
 static void s3_init_wr_tab(unsigned int wr_len)
@@ -485,7 +482,7 @@ static void s3_init_wr_tab(unsigned int wr_len)
 
 static inline void reset_wr_list(struct s3_conn *c3cn)
 {
-       c3cn->wr_pending_head = NULL;
+       c3cn->wr_pending_head = c3cn->wr_pending_tail = NULL;
 }
 
 /*
@@ -496,7 +493,7 @@ static inline void reset_wr_list(struct s3_conn *c3cn)
 static inline void enqueue_wr(struct s3_conn *c3cn,
                              struct sk_buff *skb)
 {
-       skb_wr_data(skb) = NULL;
+       skb_tx_wr_next(skb) = NULL;
 
        /*
         * We want to take an extra reference since both us and the driver
@@ -509,10 +506,22 @@ static inline void enqueue_wr(struct s3_conn *c3cn,
        if (!c3cn->wr_pending_head)
                c3cn->wr_pending_head = skb;
        else
-               skb_wr_data(skb) = skb;
+               skb_tx_wr_next(c3cn->wr_pending_tail) = skb;
        c3cn->wr_pending_tail = skb;
 }
 
+static int count_pending_wrs(struct s3_conn *c3cn)
+{
+       int n = 0;
+       const struct sk_buff *skb = c3cn->wr_pending_head;
+
+       while (skb) {
+               n += skb->csum;
+               skb = skb_tx_wr_next(skb);
+       }
+       return n;
+}
+
 static inline struct sk_buff *peek_wr(const struct s3_conn *c3cn)
 {
        return c3cn->wr_pending_head;
@@ -529,8 +538,8 @@ static inline struct sk_buff *dequeue_wr(struct s3_conn *c3cn)
 
        if (likely(skb)) {
                /* Don't bother clearing the tail */
-               c3cn->wr_pending_head = skb_wr_data(skb);
-               skb_wr_data(skb) = NULL;
+               c3cn->wr_pending_head = skb_tx_wr_next(skb);
+               skb_tx_wr_next(skb) = NULL;
        }
        return skb;
 }
@@ -543,13 +552,14 @@ static void purge_wr_queue(struct s3_conn *c3cn)
 }
 
 static inline void make_tx_data_wr(struct s3_conn *c3cn, struct sk_buff *skb,
-                                  int len)
+                                  int len, int req_completion)
 {
        struct tx_data_wr *req;
 
        skb_reset_transport_header(skb);
        req = (struct tx_data_wr *)__skb_push(skb, sizeof(*req));
-       req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA));
+       req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA) |
+                       (req_completion ? F_WR_COMPL : 0));
        req->wr_lo = htonl(V_WR_TID(c3cn->tid));
        req->sndseq = htonl(c3cn->snd_nxt);
        /* len includes the length of any HW ULP additions */
@@ -592,7 +602,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion)
 
        if (unlikely(c3cn->state == C3CN_STATE_CONNECTING ||
                     c3cn->state == C3CN_STATE_CLOSE_WAIT_1 ||
-                    c3cn->state == C3CN_STATE_ABORTING)) {
+                    c3cn->state >= C3CN_STATE_ABORTING)) {
                c3cn_tx_debug("c3cn 0x%p, in closing state %u.\n",
                              c3cn, c3cn->state);
                return 0;
@@ -615,7 +625,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion)
                if (c3cn->wr_avail < wrs_needed) {
                        c3cn_tx_debug("c3cn 0x%p, skb len %u/%u, frag %u, "
                                      "wr %d < %u.\n",
-                                     c3cn, skb->len, skb->datalen, frags,
+                                     c3cn, skb->len, skb->data_len, frags,
                                      wrs_needed, c3cn->wr_avail);
                        break;
                }
@@ -627,20 +637,24 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion)
                c3cn->wr_unacked += wrs_needed;
                enqueue_wr(c3cn, skb);
 
-               if (likely(CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_NEED_HDR)) {
-                       len += ulp_extra_len(skb);
-                       make_tx_data_wr(c3cn, skb, len);
-                       c3cn->snd_nxt += len;
-                       if ((req_completion
-                            && c3cn->wr_unacked == wrs_needed)
-                           || (CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_COMPL)
-                           || c3cn->wr_unacked >= c3cn->wr_max / 2) {
-                               struct work_request_hdr *wr = cplhdr(skb);
+               c3cn_tx_debug("c3cn 0x%p, enqueue, skb len %u/%u, frag %u, "
+                               "wr %d, left %u, unack %u.\n",
+                               c3cn, skb->len, skb->data_len, frags,
+                               wrs_needed, c3cn->wr_avail, c3cn->wr_unacked);
+
 
-                               wr->wr_hi |= htonl(F_WR_COMPL);
+               if (likely(skb_flags(skb) & C3CB_FLAG_NEED_HDR)) {
+                       if ((req_completion &&
+                               c3cn->wr_unacked == wrs_needed) ||
+                           (skb_flags(skb) & C3CB_FLAG_COMPL) ||
+                           c3cn->wr_unacked >= c3cn->wr_max / 2) {
+                               req_completion = 1;
                                c3cn->wr_unacked = 0;
                        }
-                       CXGB3_SKB_CB(skb)->flags &= ~C3CB_FLAG_NEED_HDR;
+                       len += ulp_extra_len(skb);
+                       make_tx_data_wr(c3cn, skb, len, req_completion);
+                       c3cn->snd_nxt += len;
+                       skb_flags(skb) &= ~C3CB_FLAG_NEED_HDR;
                }
 
                total_size += skb->truesize;
@@ -735,8 +749,11 @@ static void process_act_establish(struct s3_conn *c3cn, struct sk_buff *skb)
        if (unlikely(c3cn_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED)))
                /* upper layer has requested closing */
                send_abort_req(c3cn);
-       else if (c3cn_push_tx_frames(c3cn, 1))
+       else {
+               if (skb_queue_len(&c3cn->write_queue))
+                       c3cn_push_tx_frames(c3cn, 1);
                cxgb3i_conn_tx_open(c3cn);
+       }
 }
 
 static int do_act_establish(struct t3cdev *cdev, struct sk_buff *skb,
@@ -1082,8 +1099,8 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb)
                return;
        }
 
-       CXGB3_SKB_CB(skb)->seq = ntohl(hdr_cpl->seq);
-       CXGB3_SKB_CB(skb)->flags = 0;
+       skb_tcp_seq(skb) = ntohl(hdr_cpl->seq);
+       skb_flags(skb) = 0;
 
        skb_reset_transport_header(skb);
        __skb_pull(skb, sizeof(struct cpl_iscsi_hdr));
@@ -1103,12 +1120,12 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb)
                goto abort_conn;
 
        skb_ulp_mode(skb) = ULP2_FLAG_DATA_READY;
-       skb_ulp_pdulen(skb) = ntohs(ddp_cpl.len);
-       skb_ulp_ddigest(skb) = ntohl(ddp_cpl.ulp_crc);
+       skb_rx_pdulen(skb) = ntohs(ddp_cpl.len);
+       skb_rx_ddigest(skb) = ntohl(ddp_cpl.ulp_crc);
        status = ntohl(ddp_cpl.ddp_status);
 
        c3cn_rx_debug("rx skb 0x%p, len %u, pdulen %u, ddp status 0x%x.\n",
-                     skb, skb->len, skb_ulp_pdulen(skb), status);
+                     skb, skb->len, skb_rx_pdulen(skb), status);
 
        if (status & (1 << RX_DDP_STATUS_HCRC_SHIFT))
                skb_ulp_mode(skb) |= ULP2_FLAG_HCRC_ERROR;
@@ -1126,7 +1143,7 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb)
        } else if (status & (1 << RX_DDP_STATUS_DDP_SHIFT))
                skb_ulp_mode(skb) |= ULP2_FLAG_DATA_DDPED;
 
-       c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_ulp_pdulen(skb);
+       c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_rx_pdulen(skb);
        __pskb_trim(skb, len);
        __skb_queue_tail(&c3cn->receive_queue, skb);
        cxgb3i_conn_pdu_ready(c3cn);
@@ -1151,12 +1168,27 @@ static int do_iscsi_hdr(struct t3cdev *t3dev, struct sk_buff *skb, void *ctx)
  * Process an acknowledgment of WR completion.  Advance snd_una and send the
  * next batch of work requests from the write queue.
  */
+static void check_wr_invariants(struct s3_conn *c3cn)
+{
+       int pending = count_pending_wrs(c3cn);
+
+       if (unlikely(c3cn->wr_avail + pending != c3cn->wr_max))
+               cxgb3i_log_error("TID %u: credit imbalance: avail %u, "
+                               "pending %u, total should be %u\n",
+                               c3cn->tid, c3cn->wr_avail, pending,
+                               c3cn->wr_max);
+}
+
 static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb)
 {
        struct cpl_wr_ack *hdr = cplhdr(skb);
        unsigned int credits = ntohs(hdr->credits);
        u32 snd_una = ntohl(hdr->snd_una);
 
+       c3cn_tx_debug("%u WR credits, avail %u, unack %u, TID %u, state %u.\n",
+                       credits, c3cn->wr_avail, c3cn->wr_unacked,
+                       c3cn->tid, c3cn->state);
+
        c3cn->wr_avail += credits;
        if (c3cn->wr_unacked > c3cn->wr_max - c3cn->wr_avail)
                c3cn->wr_unacked = c3cn->wr_max - c3cn->wr_avail;
@@ -1171,6 +1203,17 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb)
                        break;
                }
                if (unlikely(credits < p->csum)) {
+                       struct tx_data_wr *w = cplhdr(p);
+                       cxgb3i_log_error("TID %u got %u WR credits need %u, "
+                                        "len %u, main body %u, frags %u, "
+                                        "seq # %u, ACK una %u, ACK nxt %u, "
+                                        "WR_AVAIL %u, WRs pending %u\n",
+                                        c3cn->tid, credits, p->csum, p->len,
+                                        p->len - p->data_len,
+                                        skb_shinfo(p)->nr_frags,
+                                        ntohl(w->sndseq), snd_una,
+                                        ntohl(hdr->snd_nxt), c3cn->wr_avail,
+                                        count_pending_wrs(c3cn) - credits);
                        p->csum -= credits;
                        break;
                } else {
@@ -1180,15 +1223,24 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb)
                }
        }
 
-       if (unlikely(before(snd_una, c3cn->snd_una)))
+       check_wr_invariants(c3cn);
+
+       if (unlikely(before(snd_una, c3cn->snd_una))) {
+               cxgb3i_log_error("TID %u, unexpected sequence # %u in WR_ACK "
+                                "snd_una %u\n",
+                                c3cn->tid, snd_una, c3cn->snd_una);
                goto out_free;
+       }
 
        if (c3cn->snd_una != snd_una) {
                c3cn->snd_una = snd_una;
                dst_confirm(c3cn->dst_cache);
        }
 
-       if (skb_queue_len(&c3cn->write_queue) && c3cn_push_tx_frames(c3cn, 0))
+       if (skb_queue_len(&c3cn->write_queue)) {
+               if (c3cn_push_tx_frames(c3cn, 0))
+                       cxgb3i_conn_tx_open(c3cn);
+       } else
                cxgb3i_conn_tx_open(c3cn);
 out_free:
        __kfree_skb(skb);
@@ -1452,7 +1504,7 @@ static void init_offload_conn(struct s3_conn *c3cn,
                              struct dst_entry *dst)
 {
        BUG_ON(c3cn->cdev != cdev);
-       c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs;
+       c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs - 1;
        c3cn->wr_unacked = 0;
        c3cn->mss_idx = select_mss(c3cn, dst_mtu(dst));
 
@@ -1671,9 +1723,17 @@ int cxgb3i_c3cn_send_pdus(struct s3_conn *c3cn, struct sk_buff *skb)
                goto out_err;
        }
 
-       err = -EPIPE;
        if (c3cn->err) {
                c3cn_tx_debug("c3cn 0x%p, err %d.\n", c3cn, c3cn->err);
+               err = -EPIPE;
+               goto out_err;
+       }
+
+       if (c3cn->write_seq - c3cn->snd_una >= cxgb3_snd_win) {
+               c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n",
+                               c3cn, c3cn->write_seq, c3cn->snd_una,
+                               cxgb3_snd_win);
+               err = -EAGAIN;
                goto out_err;
        }
 
index d23156907ffdce1b8bb58dee792e2ee7204b4f8a..6344b9eb2589cfe42c8e33ff5606e5ae0e6b53f4 100644 (file)
@@ -178,25 +178,33 @@ void cxgb3i_c3cn_release(struct s3_conn *);
  * @flag:      see C3CB_FLAG_* below
  * @ulp_mode:  ULP mode/submode of sk_buff
  * @seq:       tcp sequence number
- * @ddigest:   pdu data digest
- * @pdulen:    recovered pdu length
- * @wr_data:   scratch area for tx wr
  */
+struct cxgb3_skb_rx_cb {
+       __u32 ddigest;                  /* data digest */
+       __u32 pdulen;                   /* recovered pdu length */
+};
+
+struct cxgb3_skb_tx_cb {
+       struct sk_buff *wr_next;        /* next wr */
+};
+
 struct cxgb3_skb_cb {
        __u8 flags;
        __u8 ulp_mode;
        __u32 seq;
-       __u32 ddigest;
-       __u32 pdulen;
-       struct sk_buff *wr_data;
+       union {
+               struct cxgb3_skb_rx_cb rx;
+               struct cxgb3_skb_tx_cb tx;
+       };
 };
 
 #define CXGB3_SKB_CB(skb)      ((struct cxgb3_skb_cb *)&((skb)->cb[0]))
-
+#define skb_flags(skb)         (CXGB3_SKB_CB(skb)->flags)
 #define skb_ulp_mode(skb)      (CXGB3_SKB_CB(skb)->ulp_mode)
-#define skb_ulp_ddigest(skb)   (CXGB3_SKB_CB(skb)->ddigest)
-#define skb_ulp_pdulen(skb)    (CXGB3_SKB_CB(skb)->pdulen)
-#define skb_wr_data(skb)       (CXGB3_SKB_CB(skb)->wr_data)
+#define skb_tcp_seq(skb)       (CXGB3_SKB_CB(skb)->seq)
+#define skb_rx_ddigest(skb)    (CXGB3_SKB_CB(skb)->rx.ddigest)
+#define skb_rx_pdulen(skb)     (CXGB3_SKB_CB(skb)->rx.pdulen)
+#define skb_tx_wr_next(skb)    (CXGB3_SKB_CB(skb)->tx.wr_next)
 
 enum c3cb_flags {
        C3CB_FLAG_NEED_HDR = 1 << 0,    /* packet needs a TX_DATA_WR header */
@@ -217,6 +225,7 @@ struct sge_opaque_hdr {
 /* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */
 #define TX_HEADER_LEN \
                (sizeof(struct tx_data_wr) + sizeof(struct sge_opaque_hdr))
+#define SKB_TX_HEADROOM                SKB_MAX_HEAD(TX_HEADER_LEN)
 
 /*
  * get and set private ip for iscsi traffic
index ce7ce8c6094c549e44079079557ebb2d1f49791b..17115c230d6582ca8d8522166f774a999727ed3f 100644 (file)
 #define cxgb3i_tx_debug(fmt...)
 #endif
 
+/* always allocate rooms for AHS */
+#define SKB_TX_PDU_HEADER_LEN  \
+       (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE)
+static unsigned int skb_extra_headroom;
 static struct page *pad_page;
 
 /*
@@ -146,12 +150,13 @@ static inline void tx_skb_setmode(struct sk_buff *skb, int hcrc, int dcrc)
 
 void cxgb3i_conn_cleanup_task(struct iscsi_task *task)
 {
-       struct iscsi_tcp_task *tcp_task = task->dd_data;
+       struct cxgb3i_task_data *tdata = task->dd_data +
+                                       sizeof(struct iscsi_tcp_task);
 
        /* never reached the xmit task callout */
-       if (tcp_task->dd_data)
-               kfree_skb(tcp_task->dd_data);
-       tcp_task->dd_data = NULL;
+       if (tdata->skb)
+               __kfree_skb(tdata->skb);
+       memset(tdata, 0, sizeof(struct cxgb3i_task_data));
 
        /* MNC - Do we need a check in case this is called but
         * cxgb3i_conn_alloc_pdu has never been called on the task */
@@ -159,28 +164,102 @@ void cxgb3i_conn_cleanup_task(struct iscsi_task *task)
        iscsi_tcp_cleanup_task(task);
 }
 
-/*
- * We do not support ahs yet
- */
+static int sgl_seek_offset(struct scatterlist *sgl, unsigned int sgcnt,
+                               unsigned int offset, unsigned int *off,
+                               struct scatterlist **sgp)
+{
+       int i;
+       struct scatterlist *sg;
+
+       for_each_sg(sgl, sg, sgcnt, i) {
+               if (offset < sg->length) {
+                       *off = offset;
+                       *sgp = sg;
+                       return 0;
+               }
+               offset -= sg->length;
+       }
+       return -EFAULT;
+}
+
+static int sgl_read_to_frags(struct scatterlist *sg, unsigned int sgoffset,
+                               unsigned int dlen, skb_frag_t *frags,
+                               int frag_max)
+{
+       unsigned int datalen = dlen;
+       unsigned int sglen = sg->length - sgoffset;
+       struct page *page = sg_page(sg);
+       int i;
+
+       i = 0;
+       do {
+               unsigned int copy;
+
+               if (!sglen) {
+                       sg = sg_next(sg);
+                       if (!sg) {
+                               cxgb3i_log_error("%s, sg NULL, len %u/%u.\n",
+                                                __func__, datalen, dlen);
+                               return -EINVAL;
+                       }
+                       sgoffset = 0;
+                       sglen = sg->length;
+                       page = sg_page(sg);
+
+               }
+               copy = min(datalen, sglen);
+               if (i && page == frags[i - 1].page &&
+                   sgoffset + sg->offset ==
+                       frags[i - 1].page_offset + frags[i - 1].size) {
+                       frags[i - 1].size += copy;
+               } else {
+                       if (i >= frag_max) {
+                               cxgb3i_log_error("%s, too many pages %u, "
+                                                "dlen %u.\n", __func__,
+                                                frag_max, dlen);
+                               return -EINVAL;
+                       }
+
+                       frags[i].page = page;
+                       frags[i].page_offset = sg->offset + sgoffset;
+                       frags[i].size = copy;
+                       i++;
+               }
+               datalen -= copy;
+               sgoffset += copy;
+               sglen -= copy;
+       } while (datalen);
+
+       return i;
+}
+
 int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode)
 {
+       struct iscsi_conn *conn = task->conn;
        struct iscsi_tcp_task *tcp_task = task->dd_data;
-       struct sk_buff *skb;
+       struct cxgb3i_task_data *tdata = task->dd_data + sizeof(*tcp_task);
+       struct scsi_cmnd *sc = task->sc;
+       int headroom = SKB_TX_PDU_HEADER_LEN;
 
+       tcp_task->dd_data = tdata;
        task->hdr = NULL;
-       /* always allocate rooms for AHS */
-       skb = alloc_skb(sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE +
-                       TX_HEADER_LEN,  GFP_ATOMIC);
-       if (!skb)
+
+       /* write command, need to send data pdus */
+       if (skb_extra_headroom && (opcode == ISCSI_OP_SCSI_DATA_OUT ||
+           (opcode == ISCSI_OP_SCSI_CMD &&
+           (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_TO_DEVICE))))
+               headroom += min(skb_extra_headroom, conn->max_xmit_dlength);
+
+       tdata->skb = alloc_skb(TX_HEADER_LEN + headroom, GFP_ATOMIC);
+       if (!tdata->skb)
                return -ENOMEM;
+       skb_reserve(tdata->skb, TX_HEADER_LEN);
 
        cxgb3i_tx_debug("task 0x%p, opcode 0x%x, skb 0x%p.\n",
-                       task, opcode, skb);
+                       task, opcode, tdata->skb);
 
-       tcp_task->dd_data = skb;
-       skb_reserve(skb, TX_HEADER_LEN);
-       task->hdr = (struct iscsi_hdr *)skb->data;
-       task->hdr_max = sizeof(struct iscsi_hdr);
+       task->hdr = (struct iscsi_hdr *)tdata->skb->data;
+       task->hdr_max = SKB_TX_PDU_HEADER_LEN;
 
        /* data_out uses scsi_cmd's itt */
        if (opcode != ISCSI_OP_SCSI_DATA_OUT)
@@ -192,13 +271,13 @@ int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode)
 int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
                              unsigned int count)
 {
-       struct iscsi_tcp_task *tcp_task = task->dd_data;
-       struct sk_buff *skb = tcp_task->dd_data;
        struct iscsi_conn *conn = task->conn;
-       struct page *pg;
+       struct iscsi_tcp_task *tcp_task = task->dd_data;
+       struct cxgb3i_task_data *tdata = tcp_task->dd_data;
+       struct sk_buff *skb = tdata->skb;
        unsigned int datalen = count;
        int i, padlen = iscsi_padding(count);
-       skb_frag_t *frag;
+       struct page *pg;
 
        cxgb3i_tx_debug("task 0x%p,0x%p, offset %u, count %u, skb 0x%p.\n",
                        task, task->sc, offset, count, skb);
@@ -209,90 +288,94 @@ int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
                return 0;
 
        if (task->sc) {
-               struct scatterlist *sg;
-               struct scsi_data_buffer *sdb;
-               unsigned int sgoffset = offset;
-               struct page *sgpg;
-               unsigned int sglen;
-
-               sdb = scsi_out(task->sc);
-               sg = sdb->table.sgl;
-
-               for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) {
-                       cxgb3i_tx_debug("sg %d, page 0x%p, len %u offset %u\n",
-                                       i, sg_page(sg), sg->length, sg->offset);
-
-                       if (sgoffset < sg->length)
-                               break;
-                       sgoffset -= sg->length;
+               struct scsi_data_buffer *sdb = scsi_out(task->sc);
+               struct scatterlist *sg = NULL;
+               int err;
+
+               tdata->offset = offset;
+               tdata->count = count;
+               err = sgl_seek_offset(sdb->table.sgl, sdb->table.nents,
+                                       tdata->offset, &tdata->sgoffset, &sg);
+               if (err < 0) {
+                       cxgb3i_log_warn("tpdu, sgl %u, bad offset %u/%u.\n",
+                                       sdb->table.nents, tdata->offset,
+                                       sdb->length);
+                       return err;
                }
-               sgpg = sg_page(sg);
-               sglen = sg->length - sgoffset;
-
-               do {
-                       int j = skb_shinfo(skb)->nr_frags;
-                       unsigned int copy;
-
-                       if (!sglen) {
-                               sg = sg_next(sg);
-                               sgpg = sg_page(sg);
-                               sgoffset = 0;
-                               sglen = sg->length;
-                               ++i;
+               err = sgl_read_to_frags(sg, tdata->sgoffset, tdata->count,
+                                       tdata->frags, MAX_PDU_FRAGS);
+               if (err < 0) {
+                       cxgb3i_log_warn("tpdu, sgl %u, bad offset %u + %u.\n",
+                                       sdb->table.nents, tdata->offset,
+                                       tdata->count);
+                       return err;
+               }
+               tdata->nr_frags = err;
+
+               if (tdata->nr_frags > MAX_SKB_FRAGS ||
+                   (padlen && tdata->nr_frags == MAX_SKB_FRAGS)) {
+                       char *dst = skb->data + task->hdr_len;
+                       skb_frag_t *frag = tdata->frags;
+
+                       /* data fits in the skb's headroom */
+                       for (i = 0; i < tdata->nr_frags; i++, frag++) {
+                               char *src = kmap_atomic(frag->page,
+                                                       KM_SOFTIRQ0);
+
+                               memcpy(dst, src+frag->page_offset, frag->size);
+                               dst += frag->size;
+                               kunmap_atomic(src, KM_SOFTIRQ0);
                        }
-                       copy = min(sglen, datalen);
-                       if (j && skb_can_coalesce(skb, j, sgpg,
-                                                 sg->offset + sgoffset)) {
-                               skb_shinfo(skb)->frags[j - 1].size += copy;
-                       } else {
-                               get_page(sgpg);
-                               skb_fill_page_desc(skb, j, sgpg,
-                                                  sg->offset + sgoffset, copy);
+                       if (padlen) {
+                               memset(dst, 0, padlen);
+                               padlen = 0;
                        }
-                       sgoffset += copy;
-                       sglen -= copy;
-                       datalen -= copy;
-               } while (datalen);
+                       skb_put(skb, count + padlen);
+               } else {
+                       /* data fit into frag_list */
+                       for (i = 0; i < tdata->nr_frags; i++)
+                               get_page(tdata->frags[i].page);
+
+                       memcpy(skb_shinfo(skb)->frags, tdata->frags,
+                               sizeof(skb_frag_t) * tdata->nr_frags);
+                       skb_shinfo(skb)->nr_frags = tdata->nr_frags;
+                       skb->len += count;
+                       skb->data_len += count;
+                       skb->truesize += count;
+               }
+
        } else {
                pg = virt_to_page(task->data);
 
-               while (datalen) {
-                       i = skb_shinfo(skb)->nr_frags;
-                       frag = &skb_shinfo(skb)->frags[i];
-
-                       get_page(pg);
-                       frag->page = pg;
-                       frag->page_offset = 0;
-                       frag->size = min((unsigned int)PAGE_SIZE, datalen);
-
-                       skb_shinfo(skb)->nr_frags++;
-                       datalen -= frag->size;
-                       pg++;
-               }
+               get_page(pg);
+               skb_fill_page_desc(skb, 0, pg, offset_in_page(task->data),
+                                       count);
+               skb->len += count;
+               skb->data_len += count;
+               skb->truesize += count;
        }
 
        if (padlen) {
                i = skb_shinfo(skb)->nr_frags;
-               frag = &skb_shinfo(skb)->frags[i];
-               frag->page = pad_page;
-               frag->page_offset = 0;
-               frag->size = padlen;
-               skb_shinfo(skb)->nr_frags++;
+               get_page(pad_page);
+               skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, pad_page, 0,
+                                padlen);
+
+               skb->data_len += padlen;
+               skb->truesize += padlen;
+               skb->len += padlen;
        }
 
-       datalen = count + padlen;
-       skb->data_len += datalen;
-       skb->truesize += datalen;
-       skb->len += datalen;
        return 0;
 }
 
 int cxgb3i_conn_xmit_pdu(struct iscsi_task *task)
 {
-       struct iscsi_tcp_task *tcp_task = task->dd_data;
-       struct sk_buff *skb = tcp_task->dd_data;
        struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data;
        struct cxgb3i_conn *cconn = tcp_conn->dd_data;
+       struct iscsi_tcp_task *tcp_task = task->dd_data;
+       struct cxgb3i_task_data *tdata = tcp_task->dd_data;
+       struct sk_buff *skb = tdata->skb;
        unsigned int datalen;
        int err;
 
@@ -300,13 +383,14 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task)
                return 0;
 
        datalen = skb->data_len;
-       tcp_task->dd_data = NULL;
+       tdata->skb = NULL;
        err = cxgb3i_c3cn_send_pdus(cconn->cep->c3cn, skb);
-       cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n",
-                       task, skb, skb->len, skb->data_len, err);
        if (err > 0) {
                int pdulen = err;
 
+       cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n",
+                       task, skb, skb->len, skb->data_len, err);
+
                if (task->conn->hdrdgst_en)
                        pdulen += ISCSI_DIGEST_SIZE;
                if (datalen && task->conn->datadgst_en)
@@ -325,12 +409,14 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task)
                return err;
        }
        /* reset skb to send when we are called again */
-       tcp_task->dd_data = skb;
+       tdata->skb = skb;
        return -EAGAIN;
 }
 
 int cxgb3i_pdu_init(void)
 {
+       if (SKB_TX_HEADROOM > (512 * MAX_SKB_FRAGS))
+               skb_extra_headroom = SKB_TX_HEADROOM;
        pad_page = alloc_page(GFP_KERNEL);
        if (!pad_page)
                return -ENOMEM;
@@ -366,7 +452,9 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn)
        skb = skb_peek(&c3cn->receive_queue);
        while (!err && skb) {
                __skb_unlink(skb, &c3cn->receive_queue);
-               read += skb_ulp_pdulen(skb);
+               read += skb_rx_pdulen(skb);
+               cxgb3i_rx_debug("conn 0x%p, cn 0x%p, rx skb 0x%p, pdulen %u.\n",
+                               conn, c3cn, skb, skb_rx_pdulen(skb));
                err = cxgb3i_conn_read_pdu_skb(conn, skb);
                __kfree_skb(skb);
                skb = skb_peek(&c3cn->receive_queue);
@@ -377,6 +465,11 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn)
                cxgb3i_c3cn_rx_credits(c3cn, read);
        }
        conn->rxdata_octets += read;
+
+       if (err) {
+               cxgb3i_log_info("conn 0x%p rx failed err %d.\n", conn, err);
+               iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+       }
 }
 
 void cxgb3i_conn_tx_open(struct s3_conn *c3cn)
index a3f685cc236299521aa54e4e8207b974875b3aee..0770b23d90da1a704019e6d538a8aae2640f21d4 100644 (file)
@@ -53,7 +53,7 @@ struct cpl_rx_data_ddp_norss {
 #define ULP2_FLAG_DCRC_ERROR           0x20
 #define ULP2_FLAG_PAD_ERROR            0x40
 
-void cxgb3i_conn_closing(struct s3_conn *);
+void cxgb3i_conn_closing(struct s3_conn *c3cn);
 void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn);
 void cxgb3i_conn_tx_open(struct s3_conn *c3cn);
 #endif
index a48e4990fe12fc79f06d649faa5dac4887f0a65e..34be88d7afa53da88fc2910ede911bfe9b758550 100644 (file)
@@ -1251,6 +1251,7 @@ static struct pci_device_id hptiop_id_table[] = {
        { PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops },
        { PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops },
        { PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops },
+       { PCI_VDEVICE(TTI, 0x4321), (kernel_ulong_t)&hptiop_itl_ops },
        { PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops },
        { PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops },
        { PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops },
index 940dc32ff0dc731523c0e02849e3772950260ef0..b82ffd90632e256ca0ce5c7d478dae715f3e8318 100644 (file)
@@ -1040,12 +1040,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                                action = ACTION_FAIL;
                        break;
                case ABORTED_COMMAND:
+                       action = ACTION_FAIL;
                        if (sshdr.asc == 0x10) { /* DIF */
                                description = "Target Data Integrity Failure";
-                               action = ACTION_FAIL;
                                error = -EILSEQ;
-                       } else
-                               action = ACTION_RETRY;
+                       }
                        break;
                case NOT_READY:
                        /* If the device is in the process of becoming
index d57566b8be0ad9f095a0ef0525b5c265b61e8b2c..55310dbc10a669f6b9cbf3bb5627d9bf8badc171 100644 (file)
@@ -107,6 +107,7 @@ static void scsi_disk_release(struct device *cdev);
 static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
 static void sd_print_result(struct scsi_disk *, int);
 
+static DEFINE_SPINLOCK(sd_index_lock);
 static DEFINE_IDA(sd_index_ida);
 
 /* This semaphore is used to mediate the 0->1 reference get in the
@@ -1914,7 +1915,9 @@ static int sd_probe(struct device *dev)
                if (!ida_pre_get(&sd_index_ida, GFP_KERNEL))
                        goto out_put;
 
+               spin_lock(&sd_index_lock);
                error = ida_get_new(&sd_index_ida, &index);
+               spin_unlock(&sd_index_lock);
        } while (error == -EAGAIN);
 
        if (error)
@@ -1936,7 +1939,9 @@ static int sd_probe(struct device *dev)
        return 0;
 
  out_free_index:
+       spin_lock(&sd_index_lock);
        ida_remove(&sd_index_ida, index);
+       spin_unlock(&sd_index_lock);
  out_put:
        put_disk(gd);
  out_free:
@@ -1986,7 +1991,9 @@ static void scsi_disk_release(struct device *dev)
        struct scsi_disk *sdkp = to_scsi_disk(dev);
        struct gendisk *disk = sdkp->disk;
        
+       spin_lock(&sd_index_lock);
        ida_remove(&sd_index_ida, sdkp->index);
+       spin_unlock(&sd_index_lock);
 
        disk->private_data = NULL;
        put_disk(disk);
index 38bc735c67ad2ebfe79a4d64d35e6ad01117c8d6..dc20db348679d9f300f68af931b4e9b3a0019752 100644 (file)
@@ -69,10 +69,12 @@ obj-$(CONFIG_DLM)           += dlm/
 # Do not add any filesystems before this line
 obj-$(CONFIG_REISERFS_FS)      += reiserfs/
 obj-$(CONFIG_EXT3_FS)          += ext3/ # Before ext2 so root fs can be ext3
-obj-$(CONFIG_EXT4_FS)          += ext4/ # Before ext2 so root fs can be ext4
+obj-$(CONFIG_EXT2_FS)          += ext2/
+# We place ext4 after ext2 so plain ext2 root fs's are mounted using ext2
+# unless explicitly requested by rootfstype
+obj-$(CONFIG_EXT4_FS)          += ext4/
 obj-$(CONFIG_JBD)              += jbd/
 obj-$(CONFIG_JBD2)             += jbd2/
-obj-$(CONFIG_EXT2_FS)          += ext2/
 obj-$(CONFIG_CRAMFS)           += cramfs/
 obj-$(CONFIG_SQUASHFS)         += squashfs/
 obj-y                          += ramfs/
index 9a50b8052dcfab2865d34aebf54b459ec81e54b7..de9459b4cb943205c4bb40b442a486c657855f5e 100644 (file)
@@ -609,7 +609,9 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi,
  */
 int ext4_should_retry_alloc(struct super_block *sb, int *retries)
 {
-       if (!ext4_has_free_blocks(EXT4_SB(sb), 1) || (*retries)++ > 3)
+       if (!ext4_has_free_blocks(EXT4_SB(sb), 1) ||
+           (*retries)++ > 3 ||
+           !EXT4_SB(sb)->s_journal)
                return 0;
 
        jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
index 51cdd13e1c31832243a38324b1d7ea3d7fd3c080..c7fed5b1874532ca17d1c1a2724f19096bda6c7e 100644 (file)
@@ -2544,7 +2544,7 @@ retry:
 
                ext4_journal_stop(handle);
 
-               if (mpd.retval == -ENOSPC) {
+               if ((mpd.retval == -ENOSPC) && sbi->s_journal) {
                        /* commit the transaction which would
                         * free blocks released in the transaction
                         * and try again
index a5732c58f676747554a7b1c6da9a0c5e6787eb7b..39d1993cfa1370c3718dffd95231660f3dc606b4 100644 (file)
@@ -3091,7 +3091,6 @@ static int ext4_freeze(struct super_block *sb)
 
                /* Journal blocked and flushed, clear needs_recovery flag. */
                EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
-               ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
                error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
                if (error)
                        goto out;
index b97cdc516a8fcb078e29f1b2745db7f6040a880a..106c3ba50844459b463c4fcaea0cad40a9baf026 100644 (file)
@@ -52,6 +52,7 @@ header-y += const.h
 header-y += cgroupstats.h
 header-y += cramfs_fs.h
 header-y += cycx_cfm.h
+header-y += dcbnl.h
 header-y += dlmconstants.h
 header-y += dlm_device.h
 header-y += dlm_netlink.h
index b0ef274e00319d575082168ef3bb763fdf6447b9..7d2e10006188415694e16bcbba545f6fd28381de 100644 (file)
 #ifndef __LINUX_DCBNL_H__
 #define __LINUX_DCBNL_H__
 
+#include <linux/types.h>
+
 #define DCB_PROTO_VERSION 1
 
 struct dcbmsg {
-       unsigned char      dcb_family;
+       __u8               dcb_family;
        __u8               cmd;
        __u16              dcb_pad;
 };
diff --git a/include/linux/decompress/bunzip2.h b/include/linux/decompress/bunzip2.h
new file mode 100644 (file)
index 0000000..1152721
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef DECOMPRESS_BUNZIP2_H
+#define DECOMPRESS_BUNZIP2_H
+
+int bunzip2(unsigned char *inbuf, int len,
+           int(*fill)(void*, unsigned int),
+           int(*flush)(void*, unsigned int),
+           unsigned char *output,
+           int *pos,
+           void(*error)(char *x));
+#endif
diff --git a/include/linux/decompress/generic.h b/include/linux/decompress/generic.h
new file mode 100644 (file)
index 0000000..6dfb856
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef DECOMPRESS_GENERIC_H
+#define DECOMPRESS_GENERIC_H
+
+/* Minimal chunksize to be read.
+ *Bzip2 prefers at least 4096
+ *Lzma prefers 0x10000 */
+#define COMPR_IOBUF_SIZE       4096
+
+typedef int (*decompress_fn) (unsigned char *inbuf, int len,
+                             int(*fill)(void*, unsigned int),
+                             int(*writebb)(void*, unsigned int),
+                             unsigned char *output,
+                             int *posp,
+                             void(*error)(char *x));
+
+/* inbuf   - input buffer
+ *len     - len of pre-read data in inbuf
+ *fill    - function to fill inbuf if empty
+ *writebb - function to write out outbug
+ *posp    - if non-null, input position (number of bytes read) will be
+ *       returned here
+ *
+ *If len != 0, the inbuf is initialized (with as much data), and fill
+ *should not be called
+ *If len = 0, the inbuf is allocated, but empty. Its size is IOBUF_SIZE
+ *fill should be called (repeatedly...) to read data, at most IOBUF_SIZE
+ */
+
+/* Utility routine to detect the decompression method */
+decompress_fn decompress_method(const unsigned char *inbuf, int len,
+                               const char **name);
+
+#endif
diff --git a/include/linux/decompress/inflate.h b/include/linux/decompress/inflate.h
new file mode 100644 (file)
index 0000000..f9b06cc
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef INFLATE_H
+#define INFLATE_H
+
+/* Other housekeeping constants */
+#define INBUFSIZ 4096
+
+int gunzip(unsigned char *inbuf, int len,
+          int(*fill)(void*, unsigned int),
+          int(*flush)(void*, unsigned int),
+          unsigned char *output,
+          int *pos,
+          void(*error_fn)(char *x));
+#endif
diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h
new file mode 100644 (file)
index 0000000..12ff8c3
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * linux/compr_mm.h
+ *
+ * Memory management for pre-boot and ramdisk uncompressors
+ *
+ * Authors: Alain Knaff <alain@knaff.lu>
+ *
+ */
+
+#ifndef DECOMPR_MM_H
+#define DECOMPR_MM_H
+
+#ifdef STATIC
+
+/* Code active when included from pre-boot environment: */
+
+/* A trivial malloc implementation, adapted from
+ *  malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ */
+static unsigned long malloc_ptr;
+static int malloc_count;
+
+static void *malloc(int size)
+{
+       void *p;
+
+       if (size < 0)
+               error("Malloc error");
+       if (!malloc_ptr)
+               malloc_ptr = free_mem_ptr;
+
+       malloc_ptr = (malloc_ptr + 3) & ~3;     /* Align */
+
+       p = (void *)malloc_ptr;
+       malloc_ptr += size;
+
+       if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
+               error("Out of memory");
+
+       malloc_count++;
+       return p;
+}
+
+static void free(void *where)
+{
+       malloc_count--;
+       if (!malloc_count)
+               malloc_ptr = free_mem_ptr;
+}
+
+#define large_malloc(a) malloc(a)
+#define large_free(a) free(a)
+
+#define set_error_fn(x)
+
+#define INIT
+
+#else /* STATIC */
+
+/* Code active when compiled standalone for use when loading ramdisk: */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
+
+/* Use defines rather than static inline in order to avoid spurious
+ * warnings when not needed (indeed large_malloc / large_free are not
+ * needed by inflate */
+
+#define malloc(a) kmalloc(a, GFP_KERNEL)
+#define free(a) kfree(a)
+
+#define large_malloc(a) vmalloc(a)
+#define large_free(a) vfree(a)
+
+static void(*error)(char *m);
+#define set_error_fn(x) error = x;
+
+#define INIT __init
+#define STATIC
+
+#include <linux/init.h>
+
+#endif /* STATIC */
+
+#endif /* DECOMPR_MM_H */
diff --git a/include/linux/decompress/unlzma.h b/include/linux/decompress/unlzma.h
new file mode 100644 (file)
index 0000000..7796538
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef DECOMPRESS_UNLZMA_H
+#define DECOMPRESS_UNLZMA_H
+
+int unlzma(unsigned char *, int,
+          int(*fill)(void*, unsigned int),
+          int(*flush)(void*, unsigned int),
+          unsigned char *output,
+          int *posp,
+          void(*error)(char *x)
+       );
+
+#endif
index cbc2f0cd631ba1f58b4c5f937dbcffecab48a36a..0adb0f91568c1cfd407b1e88c1dce5b39d0080d5 100644 (file)
@@ -91,8 +91,11 @@ io_mapping_unmap_atomic(void *vaddr)
 static inline void *
 io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)
 {
+       resource_size_t phys_addr;
+
        BUG_ON(offset >= mapping->size);
-       resource_size_t phys_addr = mapping->base + offset;
+       phys_addr = mapping->base + offset;
+
        return ioremap_wc(phys_addr, PAGE_SIZE);
 }
 
index cdcd0ed58f7aced31dd8f909452a9d7e2dcb1bd8..4b36aeb46a102a14f7b261cbbd00819243e920da 100644 (file)
@@ -2,7 +2,7 @@
 #define _XT_NFLOG_TARGET
 
 #define XT_NFLOG_DEFAULT_GROUP         0x1
-#define XT_NFLOG_DEFAULT_THRESHOLD     1
+#define XT_NFLOG_DEFAULT_THRESHOLD     0
 
 #define XT_NFLOG_MASK                  0x0
 
index 6f3c603b0d6714acbb55e5ef1d107ea66ee1d02a..6b58367d145e8735eaebbf16bfec0733406389fb 100644 (file)
@@ -41,13 +41,13 @@ static inline void pagefault_enable(void)
 #ifndef ARCH_HAS_NOCACHE_UACCESS
 
 static inline unsigned long __copy_from_user_inatomic_nocache(void *to,
-               const void __user *from, unsigned long n, unsigned long total)
+                               const void __user *from, unsigned long n)
 {
        return __copy_from_user_inatomic(to, from, n);
 }
 
 static inline unsigned long __copy_from_user_nocache(void *to,
-               const void __user *from, unsigned long n, unsigned long total)
+                               const void __user *from, unsigned long n)
 {
        return __copy_from_user(to, from, n);
 }
index e78afe7f28e35ad48204b83bd43dfc5d710d2f1c..c25068e385169b3aee21594df68446696756ad91 100644 (file)
@@ -59,7 +59,7 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)
        struct nf_conn *ct = (struct nf_conn *)skb->nfct;
        int ret = NF_ACCEPT;
 
-       if (ct) {
+       if (ct && ct != &nf_conntrack_untracked) {
                if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
                        ret = __nf_conntrack_confirm(skb);
                nf_ct_deliver_cached_events(ct);
index f068071fcc5d952a0a6c7d745797ea094d7b3999..95a66131403a522651f6a0974a0c5538b8127945 100644 (file)
@@ -101,6 +101,66 @@ config LOCALVERSION_AUTO
 
          which is done within the script "scripts/setlocalversion".)
 
+config HAVE_KERNEL_GZIP
+       bool
+
+config HAVE_KERNEL_BZIP2
+       bool
+
+config HAVE_KERNEL_LZMA
+       bool
+
+choice
+       prompt "Kernel compression mode"
+       default KERNEL_GZIP
+       depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA
+       help
+         The linux kernel is a kind of self-extracting executable.
+         Several compression algorithms are available, which differ
+         in efficiency, compression and decompression speed.
+         Compression speed is only relevant when building a kernel.
+         Decompression speed is relevant at each boot.
+
+         If you have any problems with bzip2 or lzma compressed
+         kernels, mail me (Alain Knaff) <alain@knaff.lu>. (An older
+         version of this functionality (bzip2 only), for 2.4, was
+         supplied by Christian Ludwig)
+
+         High compression options are mostly useful for users, who
+         are low on disk space (embedded systems), but for whom ram
+         size matters less.
+
+         If in doubt, select 'gzip'
+
+config KERNEL_GZIP
+       bool "Gzip"
+       depends on HAVE_KERNEL_GZIP
+       help
+         The old and tried gzip compression. Its compression ratio is
+         the poorest among the 3 choices; however its speed (both
+         compression and decompression) is the fastest.
+
+config KERNEL_BZIP2
+       bool "Bzip2"
+       depends on HAVE_KERNEL_BZIP2
+       help
+         Its compression ratio and speed is intermediate.
+         Decompression speed is slowest among the three.  The kernel
+         size is about 10% smaller with bzip2, in comparison to gzip.
+         Bzip2 uses a large amount of memory. For modern kernels you
+         will need at least 8MB RAM or more for booting.
+
+config KERNEL_LZMA
+       bool "LZMA"
+       depends on HAVE_KERNEL_LZMA
+       help
+         The most recent compression algorithm.
+         Its ratio is best, decompression speed is between the other
+         two. Compression is slowest.  The kernel size is about 33%
+         smaller with LZMA in comparison to gzip.
+
+endchoice
+
 config SWAP
        bool "Support for paging of anonymous memory (swap)"
        depends on MMU && BLOCK
index 0f0f0cf3ba9aa97c34d88824fbf4644ca76b0fac..027a402708de6c7fa505f989b6151f5ea5bf1935 100644 (file)
@@ -11,6 +11,9 @@
 #include "do_mounts.h"
 #include "../fs/squashfs/squashfs_fs.h"
 
+#include <linux/decompress/generic.h>
+
+
 int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
 
 static int __init prompt_ramdisk(char *str)
@@ -29,7 +32,7 @@ static int __init ramdisk_start_setup(char *str)
 }
 __setup("ramdisk_start=", ramdisk_start_setup);
 
-static int __init crd_load(int in_fd, int out_fd);
+static int __init crd_load(int in_fd, int out_fd, decompress_fn deco);
 
 /*
  * This routine tries to find a RAM disk image to load, and returns the
@@ -38,15 +41,15 @@ static int __init crd_load(int in_fd, int out_fd);
  * numbers could not be found.
  *
  * We currently check for the following magic numbers:
- *     minix
- *     ext2
+ *     minix
+ *     ext2
  *     romfs
  *     cramfs
  *     squashfs
- *     gzip
+ *     gzip
  */
-static int __init 
-identify_ramdisk_image(int fd, int start_block)
+static int __init
+identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor)
 {
        const int size = 512;
        struct minix_super_block *minixsb;
@@ -56,6 +59,7 @@ identify_ramdisk_image(int fd, int start_block)
        struct squashfs_super_block *squashfsb;
        int nblocks = -1;
        unsigned char *buf;
+       const char *compress_name;
 
        buf = kmalloc(size, GFP_KERNEL);
        if (!buf)
@@ -69,18 +73,19 @@ identify_ramdisk_image(int fd, int start_block)
        memset(buf, 0xe5, size);
 
        /*
-        * Read block 0 to test for gzipped kernel
+        * Read block 0 to test for compressed kernel
         */
        sys_lseek(fd, start_block * BLOCK_SIZE, 0);
        sys_read(fd, buf, size);
 
-       /*
-        * If it matches the gzip magic numbers, return 0
-        */
-       if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
-               printk(KERN_NOTICE
-                      "RAMDISK: Compressed image found at block %d\n",
-                      start_block);
+       *decompressor = decompress_method(buf, size, &compress_name);
+       if (compress_name) {
+               printk(KERN_NOTICE "RAMDISK: %s image found at block %d\n",
+                      compress_name, start_block);
+               if (!*decompressor)
+                       printk(KERN_EMERG
+                              "RAMDISK: %s decompressor not configured!\n",
+                              compress_name);
                nblocks = 0;
                goto done;
        }
@@ -142,7 +147,7 @@ identify_ramdisk_image(int fd, int start_block)
        printk(KERN_NOTICE
               "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
               start_block);
-       
+
 done:
        sys_lseek(fd, start_block * BLOCK_SIZE, 0);
        kfree(buf);
@@ -157,6 +162,7 @@ int __init rd_load_image(char *from)
        int nblocks, i, disk;
        char *buf = NULL;
        unsigned short rotate = 0;
+       decompress_fn decompressor = NULL;
 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
        char rotator[4] = { '|' , '/' , '-' , '\\' };
 #endif
@@ -169,12 +175,12 @@ int __init rd_load_image(char *from)
        if (in_fd < 0)
                goto noclose_input;
 
-       nblocks = identify_ramdisk_image(in_fd, rd_image_start);
+       nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor);
        if (nblocks < 0)
                goto done;
 
        if (nblocks == 0) {
-               if (crd_load(in_fd, out_fd) == 0)
+               if (crd_load(in_fd, out_fd, decompressor) == 0)
                        goto successful_load;
                goto done;
        }
@@ -200,7 +206,7 @@ int __init rd_load_image(char *from)
                       nblocks, rd_blocks);
                goto done;
        }
-               
+
        /*
         * OK, time to copy in the data
         */
@@ -273,138 +279,48 @@ int __init rd_load_disk(int n)
        return rd_load_image("/dev/root");
 }
 
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-
-#ifndef memzero
-#define memzero(s, n)     memset ((s), 0, (n))
-#endif
-
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-#define INBUFSIZ 4096
-#define WSIZE 0x8000    /* window size--must be a power of two, and */
-                       /*  at least 32K for zip's deflate method */
-
-static uch *inbuf;
-static uch *window;
-
-static unsigned insize;  /* valid bytes in inbuf */
-static unsigned inptr;   /* index of next byte to be processed in inbuf */
-static unsigned outcnt;  /* bytes in output buffer */
 static int exit_code;
-static int unzip_error;
-static long bytes_out;
+static int decompress_error;
 static int crd_infd, crd_outfd;
 
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-               
-/* Diagnostic functions (stubbed out) */
-#define Assert(cond,msg)
-#define Trace(x)
-#define Tracev(x)
-#define Tracevv(x)
-#define Tracec(c,x)
-#define Tracecv(c,x)
-
-#define STATIC static
-#define INIT __init
-
-static int  __init fill_inbuf(void);
-static void __init flush_window(void);
-static void __init error(char *m);
-
-#define NO_INFLATE_MALLOC
-
-#include "../lib/inflate.c"
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- * Returning -1 does not guarantee that gunzip() will ever return.
- */
-static int __init fill_inbuf(void)
+static int __init compr_fill(void *buf, unsigned int len)
 {
-       if (exit_code) return -1;
-       
-       insize = sys_read(crd_infd, inbuf, INBUFSIZ);
-       if (insize == 0) {
-               error("RAMDISK: ran out of compressed data");
-               return -1;
-       }
-
-       inptr = 1;
-
-       return inbuf[0];
+       int r = sys_read(crd_infd, buf, len);
+       if (r < 0)
+               printk(KERN_ERR "RAMDISK: error while reading compressed data");
+       else if (r == 0)
+               printk(KERN_ERR "RAMDISK: EOF while reading compressed data");
+       return r;
 }
 
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void __init flush_window(void)
+static int __init compr_flush(void *window, unsigned int outcnt)
 {
-    ulg c = crc;         /* temporary variable */
-    unsigned n, written;
-    uch *in, ch;
-    
-    written = sys_write(crd_outfd, window, outcnt);
-    if (written != outcnt && unzip_error == 0) {
-       printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
-              written, outcnt, bytes_out);
-       unzip_error = 1;
-    }
-    in = window;
-    for (n = 0; n < outcnt; n++) {
-           ch = *in++;
-           c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-    }
-    crc = c;
-    bytes_out += (ulg)outcnt;
-    outcnt = 0;
+       int written = sys_write(crd_outfd, window, outcnt);
+       if (written != outcnt) {
+               if (decompress_error == 0)
+                       printk(KERN_ERR
+                              "RAMDISK: incomplete write (%d != %d)\n",
+                              written, outcnt);
+               decompress_error = 1;
+               return -1;
+       }
+       return outcnt;
 }
 
 static void __init error(char *x)
 {
        printk(KERN_ERR "%s\n", x);
        exit_code = 1;
-       unzip_error = 1;
+       decompress_error = 1;
 }
 
-static int __init crd_load(int in_fd, int out_fd)
+static int __init crd_load(int in_fd, int out_fd, decompress_fn deco)
 {
        int result;
-
-       insize = 0;             /* valid bytes in inbuf */
-       inptr = 0;              /* index of next byte to be processed in inbuf */
-       outcnt = 0;             /* bytes in output buffer */
-       exit_code = 0;
-       bytes_out = 0;
-       crc = (ulg)0xffffffffL; /* shift register contents */
-
        crd_infd = in_fd;
        crd_outfd = out_fd;
-       inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
-       if (!inbuf) {
-               printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
-               return -1;
-       }
-       window = kmalloc(WSIZE, GFP_KERNEL);
-       if (!window) {
-               printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
-               kfree(inbuf);
-               return -1;
-       }
-       makecrc();
-       result = gunzip();
-       if (unzip_error)
+       result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error);
+       if (decompress_error)
                result = 1;
-       kfree(inbuf);
-       kfree(window);
        return result;
 }
index d9c941c0c3cacd26fb051059540673b5e011d967..7dcde7ea660306801958857fdce54c7ee56bce9b 100644 (file)
@@ -390,11 +390,13 @@ static int __init write_buffer(char *buf, unsigned len)
        return len - count;
 }
 
-static void __init flush_buffer(char *buf, unsigned len)
+static int __init flush_buffer(void *bufv, unsigned len)
 {
+       char *buf = (char *) bufv;
        int written;
+       int origLen = len;
        if (message)
-               return;
+               return -1;
        while ((written = write_buffer(buf, len)) < len && !message) {
                char c = buf[written];
                if (c == '0') {
@@ -408,84 +410,28 @@ static void __init flush_buffer(char *buf, unsigned len)
                } else
                        error("junk in compressed archive");
        }
+       return origLen;
 }
 
-/*
- * gzip declarations
- */
+static unsigned my_inptr;   /* index of next byte to be processed in inbuf */
 
-#define OF(args)  args
-
-#ifndef memzero
-#define memzero(s, n)     memset ((s), 0, (n))
-#endif
-
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-#define WSIZE 0x8000    /* window size--must be a power of two, and */
-                       /*  at least 32K for zip's deflate method */
-
-static uch *inbuf;
-static uch *window;
-
-static unsigned insize;  /* valid bytes in inbuf */
-static unsigned inptr;   /* index of next byte to be processed in inbuf */
-static unsigned outcnt;  /* bytes in output buffer */
-static long bytes_out;
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : -1)
-               
-/* Diagnostic functions (stubbed out) */
-#define Assert(cond,msg)
-#define Trace(x)
-#define Tracev(x)
-#define Tracevv(x)
-#define Tracec(c,x)
-#define Tracecv(c,x)
-
-#define STATIC static
-#define INIT __init
-
-static void __init flush_window(void);
-static void __init error(char *m);
-
-#define NO_INFLATE_MALLOC
-
-#include "../lib/inflate.c"
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void __init flush_window(void)
-{
-       ulg c = crc;         /* temporary variable */
-       unsigned n;
-       uch *in, ch;
-
-       flush_buffer(window, outcnt);
-       in = window;
-       for (n = 0; n < outcnt; n++) {
-               ch = *in++;
-               c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-       }
-       crc = c;
-       bytes_out += (ulg)outcnt;
-       outcnt = 0;
-}
+#include <linux/decompress/generic.h>
 
 static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
 {
        int written;
+       decompress_fn decompress;
+       const char *compress_name;
+       static __initdata char msg_buf[64];
+
        dry_run = check_only;
        header_buf = kmalloc(110, GFP_KERNEL);
        symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
        name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
-       window = kmalloc(WSIZE, GFP_KERNEL);
-       if (!window || !header_buf || !symlink_buf || !name_buf)
+
+       if (!header_buf || !symlink_buf || !name_buf)
                panic("can't allocate buffers");
+
        state = Start;
        this_header = 0;
        message = NULL;
@@ -505,22 +451,25 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
                        continue;
                }
                this_header = 0;
-               insize = len;
-               inbuf = buf;
-               inptr = 0;
-               outcnt = 0;             /* bytes in output buffer */
-               bytes_out = 0;
-               crc = (ulg)0xffffffffL; /* shift register contents */
-               makecrc();
-               gunzip();
+               decompress = decompress_method(buf, len, &compress_name);
+               if (decompress)
+                       decompress(buf, len, NULL, flush_buffer, NULL,
+                                  &my_inptr, error);
+               else if (compress_name) {
+                       if (!message) {
+                               snprintf(msg_buf, sizeof msg_buf,
+                                        "compression method %s not configured",
+                                        compress_name);
+                               message = msg_buf;
+                       }
+               }
                if (state != Reset)
-                       error("junk in gzipped archive");
-               this_header = saved_offset + inptr;
-               buf += inptr;
-               len -= inptr;
+                       error("junk in compressed archive");
+               this_header = saved_offset + my_inptr;
+               buf += my_inptr;
+               len -= my_inptr;
        }
        dir_utime();
-       kfree(window);
        kfree(name_buf);
        kfree(symlink_buf);
        kfree(header_buf);
@@ -579,7 +528,7 @@ static int __init populate_rootfs(void)
        char *err = unpack_to_rootfs(__initramfs_start,
                         __initramfs_end - __initramfs_start, 0);
        if (err)
-               panic(err);
+               panic(err);     /* Failed to decompress INTERNAL initramfs */
        if (initrd_start) {
 #ifdef CONFIG_BLK_DEV_RAM
                int fd;
@@ -605,9 +554,12 @@ static int __init populate_rootfs(void)
                printk(KERN_INFO "Unpacking initramfs...");
                err = unpack_to_rootfs((char *)initrd_start,
                        initrd_end - initrd_start, 0);
-               if (err)
-                       panic(err);
-               printk(" done\n");
+               if (err) {
+                       printk(" failed!\n");
+                       printk(KERN_EMERG "%s\n", err);
+               } else {
+                       printk(" done\n");
+               }
                free_initrd();
 #endif
        }
index ad64fcb731f231d22e539d0e1b094cdd59c7d759..57d4b13b631de36161349feb99ae6f76a2984b06 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/seccomp.h>
 #include <linux/sched.h>
+#include <linux/compat.h>
 
 /* #define SECCOMP_DEBUG 1 */
 #define NR_SECCOMP_MODES 1
@@ -22,7 +23,7 @@ static int mode1_syscalls[] = {
        0, /* null terminated */
 };
 
-#ifdef TIF_32BIT
+#ifdef CONFIG_COMPAT
 static int mode1_syscalls_32[] = {
        __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32,
        0, /* null terminated */
@@ -37,8 +38,8 @@ void __secure_computing(int this_syscall)
        switch (mode) {
        case 1:
                syscall = mode1_syscalls;
-#ifdef TIF_32BIT
-               if (test_thread_flag(TIF_32BIT))
+#ifdef CONFIG_COMPAT
+               if (is_compat_task())
                        syscall = mode1_syscalls_32;
 #endif
                do {
index 03c2c24b9083c17aff9372224ec2b22912691ffb..daa481824d9c9a68438d097ec4bedd9c2114dc2e 100644 (file)
@@ -97,6 +97,20 @@ config LZO_COMPRESS
 config LZO_DECOMPRESS
        tristate
 
+#
+# These all provide a common interface (hence the apparent duplication with
+# ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.)
+#
+config DECOMPRESS_GZIP
+       select ZLIB_INFLATE
+       tristate
+
+config DECOMPRESS_BZIP2
+       tristate
+
+config DECOMPRESS_LZMA
+       tristate
+
 #
 # Generic allocator support is selected if needed
 #
index 32b0e64ded27d7c1f614fdc974d0857abfc19bbc..790de7c25d0d01eac70dcfce6327ca100919da5a 100644 (file)
@@ -11,7 +11,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
         rbtree.o radix-tree.o dump_stack.o \
         idr.o int_sqrt.o extable.o prio_tree.o \
         sha1.o irq_regs.o reciprocal_div.o argv_split.o \
-        proportions.o prio_heap.o ratelimit.o show_mem.o is_single_threaded.o
+        proportions.o prio_heap.o ratelimit.o show_mem.o \
+        is_single_threaded.o decompress.o
 
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
@@ -65,6 +66,10 @@ obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
 obj-$(CONFIG_LZO_COMPRESS) += lzo/
 obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
 
+lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
+lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
+lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
+
 obj-$(CONFIG_TEXTSEARCH) += textsearch.o
 obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
 obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o
diff --git a/lib/decompress.c b/lib/decompress.c
new file mode 100644 (file)
index 0000000..d2842f5
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * decompress.c
+ *
+ * Detect the decompression method based on magic number
+ */
+
+#include <linux/decompress/generic.h>
+
+#include <linux/decompress/bunzip2.h>
+#include <linux/decompress/unlzma.h>
+#include <linux/decompress/inflate.h>
+
+#include <linux/types.h>
+#include <linux/string.h>
+
+#ifndef CONFIG_DECOMPRESS_GZIP
+# define gunzip NULL
+#endif
+#ifndef CONFIG_DECOMPRESS_BZIP2
+# define bunzip2 NULL
+#endif
+#ifndef CONFIG_DECOMPRESS_LZMA
+# define unlzma NULL
+#endif
+
+static const struct compress_format {
+       unsigned char magic[2];
+       const char *name;
+       decompress_fn decompressor;
+} compressed_formats[] = {
+       { {037, 0213}, "gzip", gunzip },
+       { {037, 0236}, "gzip", gunzip },
+       { {0x42, 0x5a}, "bzip2", bunzip2 },
+       { {0x5d, 0x00}, "lzma", unlzma },
+       { {0, 0}, NULL, NULL }
+};
+
+decompress_fn decompress_method(const unsigned char *inbuf, int len,
+                               const char **name)
+{
+       const struct compress_format *cf;
+
+       if (len < 2)
+               return NULL;    /* Need at least this much... */
+
+       for (cf = compressed_formats; cf->name; cf++) {
+               if (!memcmp(inbuf, cf->magic, 2))
+                       break;
+
+       }
+       if (name)
+               *name = cf->name;
+       return cf->decompressor;
+}
diff --git a/lib/decompress_bunzip2.c b/lib/decompress_bunzip2.c
new file mode 100644 (file)
index 0000000..5d3ddb5
--- /dev/null
@@ -0,0 +1,735 @@
+/* vi: set sw = 4 ts = 4: */
+/*     Small bzip2 deflate implementation, by Rob Landley (rob@landley.net).
+
+       Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
+       which also acknowledges contributions by Mike Burrows, David Wheeler,
+       Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
+       Robert Sedgewick, and Jon L. Bentley.
+
+       This code is licensed under the LGPLv2:
+               LGPL (http://www.gnu.org/copyleft/lgpl.html
+*/
+
+/*
+       Size and speed optimizations by Manuel Novoa III  (mjn3@codepoet.org).
+
+       More efficient reading of Huffman codes, a streamlined read_bunzip()
+       function, and various other tweaks.  In (limited) tests, approximately
+       20% faster than bzcat on x86 and about 10% faster on arm.
+
+       Note that about 2/3 of the time is spent in read_unzip() reversing
+       the Burrows-Wheeler transformation.  Much of that time is delay
+       resulting from cache misses.
+
+       I would ask that anyone benefiting from this work, especially those
+       using it in commercial products, consider making a donation to my local
+       non-profit hospice organization in the name of the woman I loved, who
+       passed away Feb. 12, 2003.
+
+               In memory of Toni W. Hagan
+
+               Hospice of Acadiana, Inc.
+               2600 Johnston St., Suite 200
+               Lafayette, LA 70503-3240
+
+               Phone (337) 232-1234 or 1-800-738-2226
+               Fax   (337) 232-1297
+
+               http://www.hospiceacadiana.com/
+
+       Manuel
+ */
+
+/*
+       Made it fit for running in Linux Kernel by Alain Knaff (alain@knaff.lu)
+*/
+
+
+#ifndef STATIC
+#include <linux/decompress/bunzip2.h>
+#endif /* !STATIC */
+
+#include <linux/decompress/mm.h>
+
+#ifndef INT_MAX
+#define INT_MAX 0x7fffffff
+#endif
+
+/* Constants for Huffman coding */
+#define MAX_GROUPS             6
+#define GROUP_SIZE             50      /* 64 would have been more efficient */
+#define MAX_HUFCODE_BITS       20      /* Longest Huffman code allowed */
+#define MAX_SYMBOLS            258     /* 256 literals + RUNA + RUNB */
+#define SYMBOL_RUNA            0
+#define SYMBOL_RUNB            1
+
+/* Status return values */
+#define RETVAL_OK                      0
+#define RETVAL_LAST_BLOCK              (-1)
+#define RETVAL_NOT_BZIP_DATA           (-2)
+#define RETVAL_UNEXPECTED_INPUT_EOF    (-3)
+#define RETVAL_UNEXPECTED_OUTPUT_EOF   (-4)
+#define RETVAL_DATA_ERROR              (-5)
+#define RETVAL_OUT_OF_MEMORY           (-6)
+#define RETVAL_OBSOLETE_INPUT          (-7)
+
+/* Other housekeeping constants */
+#define BZIP2_IOBUF_SIZE               4096
+
+/* This is what we know about each Huffman coding group */
+struct group_data {
+       /* We have an extra slot at the end of limit[] for a sentinal value. */
+       int limit[MAX_HUFCODE_BITS+1];
+       int base[MAX_HUFCODE_BITS];
+       int permute[MAX_SYMBOLS];
+       int minLen, maxLen;
+};
+
+/* Structure holding all the housekeeping data, including IO buffers and
+   memory that persists between calls to bunzip */
+struct bunzip_data {
+       /* State for interrupting output loop */
+       int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent;
+       /* I/O tracking data (file handles, buffers, positions, etc.) */
+       int (*fill)(void*, unsigned int);
+       int inbufCount, inbufPos /*, outbufPos*/;
+       unsigned char *inbuf /*,*outbuf*/;
+       unsigned int inbufBitCount, inbufBits;
+       /* The CRC values stored in the block header and calculated from the
+       data */
+       unsigned int crc32Table[256], headerCRC, totalCRC, writeCRC;
+       /* Intermediate buffer and its size (in bytes) */
+       unsigned int *dbuf, dbufSize;
+       /* These things are a bit too big to go on the stack */
+       unsigned char selectors[32768];         /* nSelectors = 15 bits */
+       struct group_data groups[MAX_GROUPS];   /* Huffman coding tables */
+       int io_error;                   /* non-zero if we have IO error */
+};
+
+
+/* Return the next nnn bits of input.  All reads from the compressed input
+   are done through this function.  All reads are big endian */
+static unsigned int INIT get_bits(struct bunzip_data *bd, char bits_wanted)
+{
+       unsigned int bits = 0;
+
+       /* If we need to get more data from the byte buffer, do so.
+          (Loop getting one byte at a time to enforce endianness and avoid
+          unaligned access.) */
+       while (bd->inbufBitCount < bits_wanted) {
+               /* If we need to read more data from file into byte buffer, do
+                  so */
+               if (bd->inbufPos == bd->inbufCount) {
+                       if (bd->io_error)
+                               return 0;
+                       bd->inbufCount = bd->fill(bd->inbuf, BZIP2_IOBUF_SIZE);
+                       if (bd->inbufCount <= 0) {
+                               bd->io_error = RETVAL_UNEXPECTED_INPUT_EOF;
+                               return 0;
+                       }
+                       bd->inbufPos = 0;
+               }
+               /* Avoid 32-bit overflow (dump bit buffer to top of output) */
+               if (bd->inbufBitCount >= 24) {
+                       bits = bd->inbufBits&((1 << bd->inbufBitCount)-1);
+                       bits_wanted -= bd->inbufBitCount;
+                       bits <<= bits_wanted;
+                       bd->inbufBitCount = 0;
+               }
+               /* Grab next 8 bits of input from buffer. */
+               bd->inbufBits = (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++];
+               bd->inbufBitCount += 8;
+       }
+       /* Calculate result */
+       bd->inbufBitCount -= bits_wanted;
+       bits |= (bd->inbufBits >> bd->inbufBitCount)&((1 << bits_wanted)-1);
+
+       return bits;
+}
+
+/* Unpacks the next block and sets up for the inverse burrows-wheeler step. */
+
+static int INIT get_next_block(struct bunzip_data *bd)
+{
+       struct group_data *hufGroup = NULL;
+       int *base = NULL;
+       int *limit = NULL;
+       int dbufCount, nextSym, dbufSize, groupCount, selector,
+               i, j, k, t, runPos, symCount, symTotal, nSelectors,
+               byteCount[256];
+       unsigned char uc, symToByte[256], mtfSymbol[256], *selectors;
+       unsigned int *dbuf, origPtr;
+
+       dbuf = bd->dbuf;
+       dbufSize = bd->dbufSize;
+       selectors = bd->selectors;
+
+       /* Read in header signature and CRC, then validate signature.
+          (last block signature means CRC is for whole file, return now) */
+       i = get_bits(bd, 24);
+       j = get_bits(bd, 24);
+       bd->headerCRC = get_bits(bd, 32);
+       if ((i == 0x177245) && (j == 0x385090))
+               return RETVAL_LAST_BLOCK;
+       if ((i != 0x314159) || (j != 0x265359))
+               return RETVAL_NOT_BZIP_DATA;
+       /* We can add support for blockRandomised if anybody complains.
+          There was some code for this in busybox 1.0.0-pre3, but nobody ever
+          noticed that it didn't actually work. */
+       if (get_bits(bd, 1))
+               return RETVAL_OBSOLETE_INPUT;
+       origPtr = get_bits(bd, 24);
+       if (origPtr > dbufSize)
+               return RETVAL_DATA_ERROR;
+       /* mapping table: if some byte values are never used (encoding things
+          like ascii text), the compression code removes the gaps to have fewer
+          symbols to deal with, and writes a sparse bitfield indicating which
+          values were present.  We make a translation table to convert the
+          symbols back to the corresponding bytes. */
+       t = get_bits(bd, 16);
+       symTotal = 0;
+       for (i = 0; i < 16; i++) {
+               if (t&(1 << (15-i))) {
+                       k = get_bits(bd, 16);
+                       for (j = 0; j < 16; j++)
+                               if (k&(1 << (15-j)))
+                                       symToByte[symTotal++] = (16*i)+j;
+               }
+       }
+       /* How many different Huffman coding groups does this block use? */
+       groupCount = get_bits(bd, 3);
+       if (groupCount < 2 || groupCount > MAX_GROUPS)
+               return RETVAL_DATA_ERROR;
+       /* nSelectors: Every GROUP_SIZE many symbols we select a new
+          Huffman coding group.  Read in the group selector list,
+          which is stored as MTF encoded bit runs.  (MTF = Move To
+          Front, as each value is used it's moved to the start of the
+          list.) */
+       nSelectors = get_bits(bd, 15);
+       if (!nSelectors)
+               return RETVAL_DATA_ERROR;
+       for (i = 0; i < groupCount; i++)
+               mtfSymbol[i] = i;
+       for (i = 0; i < nSelectors; i++) {
+               /* Get next value */
+               for (j = 0; get_bits(bd, 1); j++)
+                       if (j >= groupCount)
+                               return RETVAL_DATA_ERROR;
+               /* Decode MTF to get the next selector */
+               uc = mtfSymbol[j];
+               for (; j; j--)
+                       mtfSymbol[j] = mtfSymbol[j-1];
+               mtfSymbol[0] = selectors[i] = uc;
+       }
+       /* Read the Huffman coding tables for each group, which code
+          for symTotal literal symbols, plus two run symbols (RUNA,
+          RUNB) */
+       symCount = symTotal+2;
+       for (j = 0; j < groupCount; j++) {
+               unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1];
+               int     minLen, maxLen, pp;
+               /* Read Huffman code lengths for each symbol.  They're
+                  stored in a way similar to mtf; record a starting
+                  value for the first symbol, and an offset from the
+                  previous value for everys symbol after that.
+                  (Subtracting 1 before the loop and then adding it
+                  back at the end is an optimization that makes the
+                  test inside the loop simpler: symbol length 0
+                  becomes negative, so an unsigned inequality catches
+                  it.) */
+               t = get_bits(bd, 5)-1;
+               for (i = 0; i < symCount; i++) {
+                       for (;;) {
+                               if (((unsigned)t) > (MAX_HUFCODE_BITS-1))
+                                       return RETVAL_DATA_ERROR;
+
+                               /* If first bit is 0, stop.  Else
+                                  second bit indicates whether to
+                                  increment or decrement the value.
+                                  Optimization: grab 2 bits and unget
+                                  the second if the first was 0. */
+
+                               k = get_bits(bd, 2);
+                               if (k < 2) {
+                                       bd->inbufBitCount++;
+                                       break;
+                               }
+                               /* Add one if second bit 1, else
+                                * subtract 1.  Avoids if/else */
+                               t += (((k+1)&2)-1);
+                       }
+                       /* Correct for the initial -1, to get the
+                        * final symbol length */
+                       length[i] = t+1;
+               }
+               /* Find largest and smallest lengths in this group */
+               minLen = maxLen = length[0];
+
+               for (i = 1; i < symCount; i++) {
+                       if (length[i] > maxLen)
+                               maxLen = length[i];
+                       else if (length[i] < minLen)
+                               minLen = length[i];
+               }
+
+               /* Calculate permute[], base[], and limit[] tables from
+                * length[].
+                *
+                * permute[] is the lookup table for converting
+                * Huffman coded symbols into decoded symbols.  base[]
+                * is the amount to subtract from the value of a
+                * Huffman symbol of a given length when using
+                * permute[].
+                *
+                * limit[] indicates the largest numerical value a
+                * symbol with a given number of bits can have.  This
+                * is how the Huffman codes can vary in length: each
+                * code with a value > limit[length] needs another
+                * bit.
+                */
+               hufGroup = bd->groups+j;
+               hufGroup->minLen = minLen;
+               hufGroup->maxLen = maxLen;
+               /* Note that minLen can't be smaller than 1, so we
+                  adjust the base and limit array pointers so we're
+                  not always wasting the first entry.  We do this
+                  again when using them (during symbol decoding).*/
+               base = hufGroup->base-1;
+               limit = hufGroup->limit-1;
+               /* Calculate permute[].  Concurently, initialize
+                * temp[] and limit[]. */
+               pp = 0;
+               for (i = minLen; i <= maxLen; i++) {
+                       temp[i] = limit[i] = 0;
+                       for (t = 0; t < symCount; t++)
+                               if (length[t] == i)
+                                       hufGroup->permute[pp++] = t;
+               }
+               /* Count symbols coded for at each bit length */
+               for (i = 0; i < symCount; i++)
+                       temp[length[i]]++;
+               /* Calculate limit[] (the largest symbol-coding value
+                *at each bit length, which is (previous limit <<
+                *1)+symbols at this level), and base[] (number of
+                *symbols to ignore at each bit length, which is limit
+                *minus the cumulative count of symbols coded for
+                *already). */
+               pp = t = 0;
+               for (i = minLen; i < maxLen; i++) {
+                       pp += temp[i];
+                       /* We read the largest possible symbol size
+                          and then unget bits after determining how
+                          many we need, and those extra bits could be
+                          set to anything.  (They're noise from
+                          future symbols.)  At each level we're
+                          really only interested in the first few
+                          bits, so here we set all the trailing
+                          to-be-ignored bits to 1 so they don't
+                          affect the value > limit[length]
+                          comparison. */
+                       limit[i] = (pp << (maxLen - i)) - 1;
+                       pp <<= 1;
+                       base[i+1] = pp-(t += temp[i]);
+               }
+               limit[maxLen+1] = INT_MAX; /* Sentinal value for
+                                           * reading next sym. */
+               limit[maxLen] = pp+temp[maxLen]-1;
+               base[minLen] = 0;
+       }
+       /* We've finished reading and digesting the block header.  Now
+          read this block's Huffman coded symbols from the file and
+          undo the Huffman coding and run length encoding, saving the
+          result into dbuf[dbufCount++] = uc */
+
+       /* Initialize symbol occurrence counters and symbol Move To
+        * Front table */
+       for (i = 0; i < 256; i++) {
+               byteCount[i] = 0;
+               mtfSymbol[i] = (unsigned char)i;
+       }
+       /* Loop through compressed symbols. */
+       runPos = dbufCount = symCount = selector = 0;
+       for (;;) {
+               /* Determine which Huffman coding group to use. */
+               if (!(symCount--)) {
+                       symCount = GROUP_SIZE-1;
+                       if (selector >= nSelectors)
+                               return RETVAL_DATA_ERROR;
+                       hufGroup = bd->groups+selectors[selector++];
+                       base = hufGroup->base-1;
+                       limit = hufGroup->limit-1;
+               }
+               /* Read next Huffman-coded symbol. */
+               /* Note: It is far cheaper to read maxLen bits and
+                  back up than it is to read minLen bits and then an
+                  additional bit at a time, testing as we go.
+                  Because there is a trailing last block (with file
+                  CRC), there is no danger of the overread causing an
+                  unexpected EOF for a valid compressed file.  As a
+                  further optimization, we do the read inline
+                  (falling back to a call to get_bits if the buffer
+                  runs dry).  The following (up to got_huff_bits:) is
+                  equivalent to j = get_bits(bd, hufGroup->maxLen);
+                */
+               while (bd->inbufBitCount < hufGroup->maxLen) {
+                       if (bd->inbufPos == bd->inbufCount) {
+                               j = get_bits(bd, hufGroup->maxLen);
+                               goto got_huff_bits;
+                       }
+                       bd->inbufBits =
+                               (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++];
+                       bd->inbufBitCount += 8;
+               };
+               bd->inbufBitCount -= hufGroup->maxLen;
+               j = (bd->inbufBits >> bd->inbufBitCount)&
+                       ((1 << hufGroup->maxLen)-1);
+got_huff_bits:
+               /* Figure how how many bits are in next symbol and
+                * unget extras */
+               i = hufGroup->minLen;
+               while (j > limit[i])
+                       ++i;
+               bd->inbufBitCount += (hufGroup->maxLen - i);
+               /* Huffman decode value to get nextSym (with bounds checking) */
+               if ((i > hufGroup->maxLen)
+                       || (((unsigned)(j = (j>>(hufGroup->maxLen-i))-base[i]))
+                               >= MAX_SYMBOLS))
+                       return RETVAL_DATA_ERROR;
+               nextSym = hufGroup->permute[j];
+               /* We have now decoded the symbol, which indicates
+                  either a new literal byte, or a repeated run of the
+                  most recent literal byte.  First, check if nextSym
+                  indicates a repeated run, and if so loop collecting
+                  how many times to repeat the last literal. */
+               if (((unsigned)nextSym) <= SYMBOL_RUNB) { /* RUNA or RUNB */
+                       /* If this is the start of a new run, zero out
+                        * counter */
+                       if (!runPos) {
+                               runPos = 1;
+                               t = 0;
+                       }
+                       /* Neat trick that saves 1 symbol: instead of
+                          or-ing 0 or 1 at each bit position, add 1
+                          or 2 instead.  For example, 1011 is 1 << 0
+                          + 1 << 1 + 2 << 2.  1010 is 2 << 0 + 2 << 1
+                          + 1 << 2.  You can make any bit pattern
+                          that way using 1 less symbol than the basic
+                          or 0/1 method (except all bits 0, which
+                          would use no symbols, but a run of length 0
+                          doesn't mean anything in this context).
+                          Thus space is saved. */
+                       t += (runPos << nextSym);
+                       /* +runPos if RUNA; +2*runPos if RUNB */
+
+                       runPos <<= 1;
+                       continue;
+               }
+               /* When we hit the first non-run symbol after a run,
+                  we now know how many times to repeat the last
+                  literal, so append that many copies to our buffer
+                  of decoded symbols (dbuf) now.  (The last literal
+                  used is the one at the head of the mtfSymbol
+                  array.) */
+               if (runPos) {
+                       runPos = 0;
+                       if (dbufCount+t >= dbufSize)
+                               return RETVAL_DATA_ERROR;
+
+                       uc = symToByte[mtfSymbol[0]];
+                       byteCount[uc] += t;
+                       while (t--)
+                               dbuf[dbufCount++] = uc;
+               }
+               /* Is this the terminating symbol? */
+               if (nextSym > symTotal)
+                       break;
+               /* At this point, nextSym indicates a new literal
+                  character.  Subtract one to get the position in the
+                  MTF array at which this literal is currently to be
+                  found.  (Note that the result can't be -1 or 0,
+                  because 0 and 1 are RUNA and RUNB.  But another
+                  instance of the first symbol in the mtf array,
+                  position 0, would have been handled as part of a
+                  run above.  Therefore 1 unused mtf position minus 2
+                  non-literal nextSym values equals -1.) */
+               if (dbufCount >= dbufSize)
+                       return RETVAL_DATA_ERROR;
+               i = nextSym - 1;
+               uc = mtfSymbol[i];
+               /* Adjust the MTF array.  Since we typically expect to
+                *move only a small number of symbols, and are bound
+                *by 256 in any case, using memmove here would
+                *typically be bigger and slower due to function call
+                *overhead and other assorted setup costs. */
+               do {
+                       mtfSymbol[i] = mtfSymbol[i-1];
+               } while (--i);
+               mtfSymbol[0] = uc;
+               uc = symToByte[uc];
+               /* We have our literal byte.  Save it into dbuf. */
+               byteCount[uc]++;
+               dbuf[dbufCount++] = (unsigned int)uc;
+       }
+       /* At this point, we've read all the Huffman-coded symbols
+          (and repeated runs) for this block from the input stream,
+          and decoded them into the intermediate buffer.  There are
+          dbufCount many decoded bytes in dbuf[].  Now undo the
+          Burrows-Wheeler transform on dbuf.  See
+          http://dogma.net/markn/articles/bwt/bwt.htm
+        */
+       /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
+       j = 0;
+       for (i = 0; i < 256; i++) {
+               k = j+byteCount[i];
+               byteCount[i] = j;
+               j = k;
+       }
+       /* Figure out what order dbuf would be in if we sorted it. */
+       for (i = 0; i < dbufCount; i++) {
+               uc = (unsigned char)(dbuf[i] & 0xff);
+               dbuf[byteCount[uc]] |= (i << 8);
+               byteCount[uc]++;
+       }
+       /* Decode first byte by hand to initialize "previous" byte.
+          Note that it doesn't get output, and if the first three
+          characters are identical it doesn't qualify as a run (hence
+          writeRunCountdown = 5). */
+       if (dbufCount) {
+               if (origPtr >= dbufCount)
+                       return RETVAL_DATA_ERROR;
+               bd->writePos = dbuf[origPtr];
+               bd->writeCurrent = (unsigned char)(bd->writePos&0xff);
+               bd->writePos >>= 8;
+               bd->writeRunCountdown = 5;
+       }
+       bd->writeCount = dbufCount;
+
+       return RETVAL_OK;
+}
+
+/* Undo burrows-wheeler transform on intermediate buffer to produce output.
+   If start_bunzip was initialized with out_fd =-1, then up to len bytes of
+   data are written to outbuf.  Return value is number of bytes written or
+   error (all errors are negative numbers).  If out_fd!=-1, outbuf and len
+   are ignored, data is written to out_fd and return is RETVAL_OK or error.
+*/
+
+static int INIT read_bunzip(struct bunzip_data *bd, char *outbuf, int len)
+{
+       const unsigned int *dbuf;
+       int pos, xcurrent, previous, gotcount;
+
+       /* If last read was short due to end of file, return last block now */
+       if (bd->writeCount < 0)
+               return bd->writeCount;
+
+       gotcount = 0;
+       dbuf = bd->dbuf;
+       pos = bd->writePos;
+       xcurrent = bd->writeCurrent;
+
+       /* We will always have pending decoded data to write into the output
+          buffer unless this is the very first call (in which case we haven't
+          Huffman-decoded a block into the intermediate buffer yet). */
+
+       if (bd->writeCopies) {
+               /* Inside the loop, writeCopies means extra copies (beyond 1) */
+               --bd->writeCopies;
+               /* Loop outputting bytes */
+               for (;;) {
+                       /* If the output buffer is full, snapshot
+                        * state and return */
+                       if (gotcount >= len) {
+                               bd->writePos = pos;
+                               bd->writeCurrent = xcurrent;
+                               bd->writeCopies++;
+                               return len;
+                       }
+                       /* Write next byte into output buffer, updating CRC */
+                       outbuf[gotcount++] = xcurrent;
+                       bd->writeCRC = (((bd->writeCRC) << 8)
+                               ^bd->crc32Table[((bd->writeCRC) >> 24)
+                               ^xcurrent]);
+                       /* Loop now if we're outputting multiple
+                        * copies of this byte */
+                       if (bd->writeCopies) {
+                               --bd->writeCopies;
+                               continue;
+                       }
+decode_next_byte:
+                       if (!bd->writeCount--)
+                               break;
+                       /* Follow sequence vector to undo
+                        * Burrows-Wheeler transform */
+                       previous = xcurrent;
+                       pos = dbuf[pos];
+                       xcurrent = pos&0xff;
+                       pos >>= 8;
+                       /* After 3 consecutive copies of the same
+                          byte, the 4th is a repeat count.  We count
+                          down from 4 instead *of counting up because
+                          testing for non-zero is faster */
+                       if (--bd->writeRunCountdown) {
+                               if (xcurrent != previous)
+                                       bd->writeRunCountdown = 4;
+                       } else {
+                               /* We have a repeated run, this byte
+                                * indicates the count */
+                               bd->writeCopies = xcurrent;
+                               xcurrent = previous;
+                               bd->writeRunCountdown = 5;
+                               /* Sometimes there are just 3 bytes
+                                * (run length 0) */
+                               if (!bd->writeCopies)
+                                       goto decode_next_byte;
+                               /* Subtract the 1 copy we'd output
+                                * anyway to get extras */
+                               --bd->writeCopies;
+                       }
+               }
+               /* Decompression of this block completed successfully */
+               bd->writeCRC = ~bd->writeCRC;
+               bd->totalCRC = ((bd->totalCRC << 1) |
+                               (bd->totalCRC >> 31)) ^ bd->writeCRC;
+               /* If this block had a CRC error, force file level CRC error. */
+               if (bd->writeCRC != bd->headerCRC) {
+                       bd->totalCRC = bd->headerCRC+1;
+                       return RETVAL_LAST_BLOCK;
+               }
+       }
+
+       /* Refill the intermediate buffer by Huffman-decoding next
+        * block of input */
+       /* (previous is just a convenient unused temp variable here) */
+       previous = get_next_block(bd);
+       if (previous) {
+               bd->writeCount = previous;
+               return (previous != RETVAL_LAST_BLOCK) ? previous : gotcount;
+       }
+       bd->writeCRC = 0xffffffffUL;
+       pos = bd->writePos;
+       xcurrent = bd->writeCurrent;
+       goto decode_next_byte;
+}
+
+static int INIT nofill(void *buf, unsigned int len)
+{
+       return -1;
+}
+
+/* Allocate the structure, read file header.  If in_fd ==-1, inbuf must contain
+   a complete bunzip file (len bytes long).  If in_fd!=-1, inbuf and len are
+   ignored, and data is read from file handle into temporary buffer. */
+static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len,
+                            int (*fill)(void*, unsigned int))
+{
+       struct bunzip_data *bd;
+       unsigned int i, j, c;
+       const unsigned int BZh0 =
+               (((unsigned int)'B') << 24)+(((unsigned int)'Z') << 16)
+               +(((unsigned int)'h') << 8)+(unsigned int)'0';
+
+       /* Figure out how much data to allocate */
+       i = sizeof(struct bunzip_data);
+
+       /* Allocate bunzip_data.  Most fields initialize to zero. */
+       bd = *bdp = malloc(i);
+       memset(bd, 0, sizeof(struct bunzip_data));
+       /* Setup input buffer */
+       bd->inbuf = inbuf;
+       bd->inbufCount = len;
+       if (fill != NULL)
+               bd->fill = fill;
+       else
+               bd->fill = nofill;
+
+       /* Init the CRC32 table (big endian) */
+       for (i = 0; i < 256; i++) {
+               c = i << 24;
+               for (j = 8; j; j--)
+                       c = c&0x80000000 ? (c << 1)^0x04c11db7 : (c << 1);
+               bd->crc32Table[i] = c;
+       }
+
+       /* Ensure that file starts with "BZh['1'-'9']." */
+       i = get_bits(bd, 32);
+       if (((unsigned int)(i-BZh0-1)) >= 9)
+               return RETVAL_NOT_BZIP_DATA;
+
+       /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
+          uncompressed data.  Allocate intermediate buffer for block. */
+       bd->dbufSize = 100000*(i-BZh0);
+
+       bd->dbuf = large_malloc(bd->dbufSize * sizeof(int));
+       return RETVAL_OK;
+}
+
+/* Example usage: decompress src_fd to dst_fd.  (Stops at end of bzip2 data,
+   not end of file.) */
+STATIC int INIT bunzip2(unsigned char *buf, int len,
+                       int(*fill)(void*, unsigned int),
+                       int(*flush)(void*, unsigned int),
+                       unsigned char *outbuf,
+                       int *pos,
+                       void(*error_fn)(char *x))
+{
+       struct bunzip_data *bd;
+       int i = -1;
+       unsigned char *inbuf;
+
+       set_error_fn(error_fn);
+       if (flush)
+               outbuf = malloc(BZIP2_IOBUF_SIZE);
+       else
+               len -= 4; /* Uncompressed size hack active in pre-boot
+                            environment */
+       if (!outbuf) {
+               error("Could not allocate output bufer");
+               return -1;
+       }
+       if (buf)
+               inbuf = buf;
+       else
+               inbuf = malloc(BZIP2_IOBUF_SIZE);
+       if (!inbuf) {
+               error("Could not allocate input bufer");
+               goto exit_0;
+       }
+       i = start_bunzip(&bd, inbuf, len, fill);
+       if (!i) {
+               for (;;) {
+                       i = read_bunzip(bd, outbuf, BZIP2_IOBUF_SIZE);
+                       if (i <= 0)
+                               break;
+                       if (!flush)
+                               outbuf += i;
+                       else
+                               if (i != flush(outbuf, i)) {
+                                       i = RETVAL_UNEXPECTED_OUTPUT_EOF;
+                                       break;
+                               }
+               }
+       }
+       /* Check CRC and release memory */
+       if (i == RETVAL_LAST_BLOCK) {
+               if (bd->headerCRC != bd->totalCRC)
+                       error("Data integrity error when decompressing.");
+               else
+                       i = RETVAL_OK;
+       } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) {
+               error("Compressed file ends unexpectedly");
+       }
+       if (bd->dbuf)
+               large_free(bd->dbuf);
+       if (pos)
+               *pos = bd->inbufPos;
+       free(bd);
+       if (!buf)
+               free(inbuf);
+exit_0:
+       if (flush)
+               free(outbuf);
+       return i;
+}
+
+#define decompress bunzip2
diff --git a/lib/decompress_inflate.c b/lib/decompress_inflate.c
new file mode 100644 (file)
index 0000000..839a329
--- /dev/null
@@ -0,0 +1,167 @@
+#ifdef STATIC
+/* Pre-boot environment: included */
+
+/* prevent inclusion of _LINUX_KERNEL_H in pre-boot environment: lots
+ * errors about console_printk etc... on ARM */
+#define _LINUX_KERNEL_H
+
+#include "zlib_inflate/inftrees.c"
+#include "zlib_inflate/inffast.c"
+#include "zlib_inflate/inflate.c"
+
+#else /* STATIC */
+/* initramfs et al: linked */
+
+#include <linux/zutil.h>
+
+#include "zlib_inflate/inftrees.h"
+#include "zlib_inflate/inffast.h"
+#include "zlib_inflate/inflate.h"
+
+#include "zlib_inflate/infutil.h"
+
+#endif /* STATIC */
+
+#include <linux/decompress/mm.h>
+
+#define INBUF_LEN (16*1024)
+
+/* Included from initramfs et al code */
+STATIC int INIT gunzip(unsigned char *buf, int len,
+                      int(*fill)(void*, unsigned int),
+                      int(*flush)(void*, unsigned int),
+                      unsigned char *out_buf,
+                      int *pos,
+                      void(*error_fn)(char *x)) {
+       u8 *zbuf;
+       struct z_stream_s *strm;
+       int rc;
+       size_t out_len;
+
+       set_error_fn(error_fn);
+       rc = -1;
+       if (flush) {
+               out_len = 0x8000; /* 32 K */
+               out_buf = malloc(out_len);
+       } else {
+               out_len = 0x7fffffff; /* no limit */
+       }
+       if (!out_buf) {
+               error("Out of memory while allocating output buffer");
+               goto gunzip_nomem1;
+       }
+
+       if (buf)
+               zbuf = buf;
+       else {
+               zbuf = malloc(INBUF_LEN);
+               len = 0;
+       }
+       if (!zbuf) {
+               error("Out of memory while allocating input buffer");
+               goto gunzip_nomem2;
+       }
+
+       strm = malloc(sizeof(*strm));
+       if (strm == NULL) {
+               error("Out of memory while allocating z_stream");
+               goto gunzip_nomem3;
+       }
+
+       strm->workspace = malloc(flush ? zlib_inflate_workspacesize() :
+                                sizeof(struct inflate_state));
+       if (strm->workspace == NULL) {
+               error("Out of memory while allocating workspace");
+               goto gunzip_nomem4;
+       }
+
+       if (len == 0)
+               len = fill(zbuf, INBUF_LEN);
+
+       /* verify the gzip header */
+       if (len < 10 ||
+          zbuf[0] != 0x1f || zbuf[1] != 0x8b || zbuf[2] != 0x08) {
+               if (pos)
+                       *pos = 0;
+               error("Not a gzip file");
+               goto gunzip_5;
+       }
+
+       /* skip over gzip header (1f,8b,08... 10 bytes total +
+        * possible asciz filename)
+        */
+       strm->next_in = zbuf + 10;
+       /* skip over asciz filename */
+       if (zbuf[3] & 0x8) {
+               while (strm->next_in[0])
+                       strm->next_in++;
+               strm->next_in++;
+       }
+       strm->avail_in = len - (strm->next_in - zbuf);
+
+       strm->next_out = out_buf;
+       strm->avail_out = out_len;
+
+       rc = zlib_inflateInit2(strm, -MAX_WBITS);
+
+       if (!flush) {
+               WS(strm)->inflate_state.wsize = 0;
+               WS(strm)->inflate_state.window = NULL;
+       }
+
+       while (rc == Z_OK) {
+               if (strm->avail_in == 0) {
+                       /* TODO: handle case where both pos and fill are set */
+                       len = fill(zbuf, INBUF_LEN);
+                       if (len < 0) {
+                               rc = -1;
+                               error("read error");
+                               break;
+                       }
+                       strm->next_in = zbuf;
+                       strm->avail_in = len;
+               }
+               rc = zlib_inflate(strm, 0);
+
+               /* Write any data generated */
+               if (flush && strm->next_out > out_buf) {
+                       int l = strm->next_out - out_buf;
+                       if (l != flush(out_buf, l)) {
+                               rc = -1;
+                               error("write error");
+                               break;
+                       }
+                       strm->next_out = out_buf;
+                       strm->avail_out = out_len;
+               }
+
+               /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
+               if (rc == Z_STREAM_END) {
+                       rc = 0;
+                       break;
+               } else if (rc != Z_OK) {
+                       error("uncompression error");
+                       rc = -1;
+               }
+       }
+
+       zlib_inflateEnd(strm);
+       if (pos)
+               /* add + 8 to skip over trailer */
+               *pos = strm->next_in - zbuf+8;
+
+gunzip_5:
+       free(strm->workspace);
+gunzip_nomem4:
+       free(strm);
+gunzip_nomem3:
+       if (!buf)
+               free(zbuf);
+gunzip_nomem2:
+       if (flush)
+               free(out_buf);
+gunzip_nomem1:
+       return rc; /* returns Z_OK (0) if successful */
+}
+
+#define decompress gunzip
diff --git a/lib/decompress_unlzma.c b/lib/decompress_unlzma.c
new file mode 100644 (file)
index 0000000..546f2f4
--- /dev/null
@@ -0,0 +1,647 @@
+/* Lzma decompressor for Linux kernel. Shamelessly snarfed
+ *from busybox 1.1.1
+ *
+ *Linux kernel adaptation
+ *Copyright (C) 2006  Alain < alain@knaff.lu >
+ *
+ *Based on small lzma deflate implementation/Small range coder
+ *implementation for lzma.
+ *Copyright (C) 2006  Aurelien Jacobs < aurel@gnuage.org >
+ *
+ *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
+ *Copyright (C) 1999-2005  Igor Pavlov
+ *
+ *Copyrights of the parts, see headers below.
+ *
+ *
+ *This program is free software; you can redistribute it and/or
+ *modify it under the terms of the GNU Lesser General Public
+ *License as published by the Free Software Foundation; either
+ *version 2.1 of the License, or (at your option) any later version.
+ *
+ *This 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
+ *Lesser General Public License for more details.
+ *
+ *You should have received a copy of the GNU Lesser General Public
+ *License along with this library; if not, write to the Free Software
+ *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef STATIC
+#include <linux/decompress/unlzma.h>
+#endif /* STATIC */
+
+#include <linux/decompress/mm.h>
+
+#define        MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+static long long INIT read_int(unsigned char *ptr, int size)
+{
+       int i;
+       long long ret = 0;
+
+       for (i = 0; i < size; i++)
+               ret = (ret << 8) | ptr[size-i-1];
+       return ret;
+}
+
+#define ENDIAN_CONVERT(x) \
+  x = (typeof(x))read_int((unsigned char *)&x, sizeof(x))
+
+
+/* Small range coder implementation for lzma.
+ *Copyright (C) 2006  Aurelien Jacobs < aurel@gnuage.org >
+ *
+ *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
+ *Copyright (c) 1999-2005  Igor Pavlov
+ */
+
+#include <linux/compiler.h>
+
+#define LZMA_IOBUF_SIZE        0x10000
+
+struct rc {
+       int (*fill)(void*, unsigned int);
+       uint8_t *ptr;
+       uint8_t *buffer;
+       uint8_t *buffer_end;
+       int buffer_size;
+       uint32_t code;
+       uint32_t range;
+       uint32_t bound;
+};
+
+
+#define RC_TOP_BITS 24
+#define RC_MOVE_BITS 5
+#define RC_MODEL_TOTAL_BITS 11
+
+
+/* Called twice: once at startup and once in rc_normalize() */
+static void INIT rc_read(struct rc *rc)
+{
+       rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE);
+       if (rc->buffer_size <= 0)
+               error("unexpected EOF");
+       rc->ptr = rc->buffer;
+       rc->buffer_end = rc->buffer + rc->buffer_size;
+}
+
+/* Called once */
+static inline void INIT rc_init(struct rc *rc,
+                                      int (*fill)(void*, unsigned int),
+                                      char *buffer, int buffer_size)
+{
+       rc->fill = fill;
+       rc->buffer = (uint8_t *)buffer;
+       rc->buffer_size = buffer_size;
+       rc->buffer_end = rc->buffer + rc->buffer_size;
+       rc->ptr = rc->buffer;
+
+       rc->code = 0;
+       rc->range = 0xFFFFFFFF;
+}
+
+static inline void INIT rc_init_code(struct rc *rc)
+{
+       int i;
+
+       for (i = 0; i < 5; i++) {
+               if (rc->ptr >= rc->buffer_end)
+                       rc_read(rc);
+               rc->code = (rc->code << 8) | *rc->ptr++;
+       }
+}
+
+
+/* Called once. TODO: bb_maybe_free() */
+static inline void INIT rc_free(struct rc *rc)
+{
+       free(rc->buffer);
+}
+
+/* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */
+static void INIT rc_do_normalize(struct rc *rc)
+{
+       if (rc->ptr >= rc->buffer_end)
+               rc_read(rc);
+       rc->range <<= 8;
+       rc->code = (rc->code << 8) | *rc->ptr++;
+}
+static inline void INIT rc_normalize(struct rc *rc)
+{
+       if (rc->range < (1 << RC_TOP_BITS))
+               rc_do_normalize(rc);
+}
+
+/* Called 9 times */
+/* Why rc_is_bit_0_helper exists?
+ *Because we want to always expose (rc->code < rc->bound) to optimizer
+ */
+static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p)
+{
+       rc_normalize(rc);
+       rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
+       return rc->bound;
+}
+static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p)
+{
+       uint32_t t = rc_is_bit_0_helper(rc, p);
+       return rc->code < t;
+}
+
+/* Called ~10 times, but very small, thus inlined */
+static inline void INIT rc_update_bit_0(struct rc *rc, uint16_t *p)
+{
+       rc->range = rc->bound;
+       *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS;
+}
+static inline void rc_update_bit_1(struct rc *rc, uint16_t *p)
+{
+       rc->range -= rc->bound;
+       rc->code -= rc->bound;
+       *p -= *p >> RC_MOVE_BITS;
+}
+
+/* Called 4 times in unlzma loop */
+static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol)
+{
+       if (rc_is_bit_0(rc, p)) {
+               rc_update_bit_0(rc, p);
+               *symbol *= 2;
+               return 0;
+       } else {
+               rc_update_bit_1(rc, p);
+               *symbol = *symbol * 2 + 1;
+               return 1;
+       }
+}
+
+/* Called once */
+static inline int INIT rc_direct_bit(struct rc *rc)
+{
+       rc_normalize(rc);
+       rc->range >>= 1;
+       if (rc->code >= rc->range) {
+               rc->code -= rc->range;
+               return 1;
+       }
+       return 0;
+}
+
+/* Called twice */
+static inline void INIT
+rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol)
+{
+       int i = num_levels;
+
+       *symbol = 1;
+       while (i--)
+               rc_get_bit(rc, p + *symbol, symbol);
+       *symbol -= 1 << num_levels;
+}
+
+
+/*
+ * Small lzma deflate implementation.
+ * Copyright (C) 2006  Aurelien Jacobs < aurel@gnuage.org >
+ *
+ * Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
+ * Copyright (C) 1999-2005  Igor Pavlov
+ */
+
+
+struct lzma_header {
+       uint8_t pos;
+       uint32_t dict_size;
+       uint64_t dst_size;
+} __attribute__ ((packed)) ;
+
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_NUM_POS_BITS_MAX 4
+
+#define LZMA_LEN_NUM_LOW_BITS 3
+#define LZMA_LEN_NUM_MID_BITS 3
+#define LZMA_LEN_NUM_HIGH_BITS 8
+
+#define LZMA_LEN_CHOICE 0
+#define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1)
+#define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1)
+#define LZMA_LEN_MID (LZMA_LEN_LOW \
+                     + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS)))
+#define LZMA_LEN_HIGH (LZMA_LEN_MID \
+                      +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS)))
+#define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS))
+
+#define LZMA_NUM_STATES 12
+#define LZMA_NUM_LIT_STATES 7
+
+#define LZMA_START_POS_MODEL_INDEX 4
+#define LZMA_END_POS_MODEL_INDEX 14
+#define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1))
+
+#define LZMA_NUM_POS_SLOT_BITS 6
+#define LZMA_NUM_LEN_TO_POS_STATES 4
+
+#define LZMA_NUM_ALIGN_BITS 4
+
+#define LZMA_MATCH_MIN_LEN 2
+
+#define LZMA_IS_MATCH 0
+#define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
+#define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES)
+#define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES)
+#define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES)
+#define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES)
+#define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \
+                      + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
+#define LZMA_SPEC_POS (LZMA_POS_SLOT \
+                      +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS))
+#define LZMA_ALIGN (LZMA_SPEC_POS \
+                   + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX)
+#define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS))
+#define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS)
+#define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS)
+
+
+struct writer {
+       uint8_t *buffer;
+       uint8_t previous_byte;
+       size_t buffer_pos;
+       int bufsize;
+       size_t global_pos;
+       int(*flush)(void*, unsigned int);
+       struct lzma_header *header;
+};
+
+struct cstate {
+       int state;
+       uint32_t rep0, rep1, rep2, rep3;
+};
+
+static inline size_t INIT get_pos(struct writer *wr)
+{
+       return
+               wr->global_pos + wr->buffer_pos;
+}
+
+static inline uint8_t INIT peek_old_byte(struct writer *wr,
+                                               uint32_t offs)
+{
+       if (!wr->flush) {
+               int32_t pos;
+               while (offs > wr->header->dict_size)
+                       offs -= wr->header->dict_size;
+               pos = wr->buffer_pos - offs;
+               return wr->buffer[pos];
+       } else {
+               uint32_t pos = wr->buffer_pos - offs;
+               while (pos >= wr->header->dict_size)
+                       pos += wr->header->dict_size;
+               return wr->buffer[pos];
+       }
+
+}
+
+static inline void INIT write_byte(struct writer *wr, uint8_t byte)
+{
+       wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte;
+       if (wr->flush && wr->buffer_pos == wr->header->dict_size) {
+               wr->buffer_pos = 0;
+               wr->global_pos += wr->header->dict_size;
+               wr->flush((char *)wr->buffer, wr->header->dict_size);
+       }
+}
+
+
+static inline void INIT copy_byte(struct writer *wr, uint32_t offs)
+{
+       write_byte(wr, peek_old_byte(wr, offs));
+}
+
+static inline void INIT copy_bytes(struct writer *wr,
+                                        uint32_t rep0, int len)
+{
+       do {
+               copy_byte(wr, rep0);
+               len--;
+       } while (len != 0 && wr->buffer_pos < wr->header->dst_size);
+}
+
+static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
+                                    struct cstate *cst, uint16_t *p,
+                                    int pos_state, uint16_t *prob,
+                                    int lc, uint32_t literal_pos_mask) {
+       int mi = 1;
+       rc_update_bit_0(rc, prob);
+       prob = (p + LZMA_LITERAL +
+               (LZMA_LIT_SIZE
+                * (((get_pos(wr) & literal_pos_mask) << lc)
+                   + (wr->previous_byte >> (8 - lc))))
+               );
+
+       if (cst->state >= LZMA_NUM_LIT_STATES) {
+               int match_byte = peek_old_byte(wr, cst->rep0);
+               do {
+                       int bit;
+                       uint16_t *prob_lit;
+
+                       match_byte <<= 1;
+                       bit = match_byte & 0x100;
+                       prob_lit = prob + 0x100 + bit + mi;
+                       if (rc_get_bit(rc, prob_lit, &mi)) {
+                               if (!bit)
+                                       break;
+                       } else {
+                               if (bit)
+                                       break;
+                       }
+               } while (mi < 0x100);
+       }
+       while (mi < 0x100) {
+               uint16_t *prob_lit = prob + mi;
+               rc_get_bit(rc, prob_lit, &mi);
+       }
+       write_byte(wr, mi);
+       if (cst->state < 4)
+               cst->state = 0;
+       else if (cst->state < 10)
+               cst->state -= 3;
+       else
+               cst->state -= 6;
+}
+
+static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
+                                           struct cstate *cst, uint16_t *p,
+                                           int pos_state, uint16_t *prob) {
+  int offset;
+       uint16_t *prob_len;
+       int num_bits;
+       int len;
+
+       rc_update_bit_1(rc, prob);
+       prob = p + LZMA_IS_REP + cst->state;
+       if (rc_is_bit_0(rc, prob)) {
+               rc_update_bit_0(rc, prob);
+               cst->rep3 = cst->rep2;
+               cst->rep2 = cst->rep1;
+               cst->rep1 = cst->rep0;
+               cst->state = cst->state < LZMA_NUM_LIT_STATES ? 0 : 3;
+               prob = p + LZMA_LEN_CODER;
+       } else {
+               rc_update_bit_1(rc, prob);
+               prob = p + LZMA_IS_REP_G0 + cst->state;
+               if (rc_is_bit_0(rc, prob)) {
+                       rc_update_bit_0(rc, prob);
+                       prob = (p + LZMA_IS_REP_0_LONG
+                               + (cst->state <<
+                                  LZMA_NUM_POS_BITS_MAX) +
+                               pos_state);
+                       if (rc_is_bit_0(rc, prob)) {
+                               rc_update_bit_0(rc, prob);
+
+                               cst->state = cst->state < LZMA_NUM_LIT_STATES ?
+                                       9 : 11;
+                               copy_byte(wr, cst->rep0);
+                               return;
+                       } else {
+                               rc_update_bit_1(rc, prob);
+                       }
+               } else {
+                       uint32_t distance;
+
+                       rc_update_bit_1(rc, prob);
+                       prob = p + LZMA_IS_REP_G1 + cst->state;
+                       if (rc_is_bit_0(rc, prob)) {
+                               rc_update_bit_0(rc, prob);
+                               distance = cst->rep1;
+                       } else {
+                               rc_update_bit_1(rc, prob);
+                               prob = p + LZMA_IS_REP_G2 + cst->state;
+                               if (rc_is_bit_0(rc, prob)) {
+                                       rc_update_bit_0(rc, prob);
+                                       distance = cst->rep2;
+                               } else {
+                                       rc_update_bit_1(rc, prob);
+                                       distance = cst->rep3;
+                                       cst->rep3 = cst->rep2;
+                               }
+                               cst->rep2 = cst->rep1;
+                       }
+                       cst->rep1 = cst->rep0;
+                       cst->rep0 = distance;
+               }
+               cst->state = cst->state < LZMA_NUM_LIT_STATES ? 8 : 11;
+               prob = p + LZMA_REP_LEN_CODER;
+       }
+
+       prob_len = prob + LZMA_LEN_CHOICE;
+       if (rc_is_bit_0(rc, prob_len)) {
+               rc_update_bit_0(rc, prob_len);
+               prob_len = (prob + LZMA_LEN_LOW
+                           + (pos_state <<
+                              LZMA_LEN_NUM_LOW_BITS));
+               offset = 0;
+               num_bits = LZMA_LEN_NUM_LOW_BITS;
+       } else {
+               rc_update_bit_1(rc, prob_len);
+               prob_len = prob + LZMA_LEN_CHOICE_2;
+               if (rc_is_bit_0(rc, prob_len)) {
+                       rc_update_bit_0(rc, prob_len);
+                       prob_len = (prob + LZMA_LEN_MID
+                                   + (pos_state <<
+                                      LZMA_LEN_NUM_MID_BITS));
+                       offset = 1 << LZMA_LEN_NUM_LOW_BITS;
+                       num_bits = LZMA_LEN_NUM_MID_BITS;
+               } else {
+                       rc_update_bit_1(rc, prob_len);
+                       prob_len = prob + LZMA_LEN_HIGH;
+                       offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
+                                 + (1 << LZMA_LEN_NUM_MID_BITS));
+                       num_bits = LZMA_LEN_NUM_HIGH_BITS;
+               }
+       }
+
+       rc_bit_tree_decode(rc, prob_len, num_bits, &len);
+       len += offset;
+
+       if (cst->state < 4) {
+               int pos_slot;
+
+               cst->state += LZMA_NUM_LIT_STATES;
+               prob =
+                       p + LZMA_POS_SLOT +
+                       ((len <
+                         LZMA_NUM_LEN_TO_POS_STATES ? len :
+                         LZMA_NUM_LEN_TO_POS_STATES - 1)
+                        << LZMA_NUM_POS_SLOT_BITS);
+               rc_bit_tree_decode(rc, prob,
+                                  LZMA_NUM_POS_SLOT_BITS,
+                                  &pos_slot);
+               if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
+                       int i, mi;
+                       num_bits = (pos_slot >> 1) - 1;
+                       cst->rep0 = 2 | (pos_slot & 1);
+                       if (pos_slot < LZMA_END_POS_MODEL_INDEX) {
+                               cst->rep0 <<= num_bits;
+                               prob = p + LZMA_SPEC_POS +
+                                       cst->rep0 - pos_slot - 1;
+                       } else {
+                               num_bits -= LZMA_NUM_ALIGN_BITS;
+                               while (num_bits--)
+                                       cst->rep0 = (cst->rep0 << 1) |
+                                               rc_direct_bit(rc);
+                               prob = p + LZMA_ALIGN;
+                               cst->rep0 <<= LZMA_NUM_ALIGN_BITS;
+                               num_bits = LZMA_NUM_ALIGN_BITS;
+                       }
+                       i = 1;
+                       mi = 1;
+                       while (num_bits--) {
+                               if (rc_get_bit(rc, prob + mi, &mi))
+                                       cst->rep0 |= i;
+                               i <<= 1;
+                       }
+               } else
+                       cst->rep0 = pos_slot;
+               if (++(cst->rep0) == 0)
+                       return;
+       }
+
+       len += LZMA_MATCH_MIN_LEN;
+
+       copy_bytes(wr, cst->rep0, len);
+}
+
+
+
+STATIC inline int INIT unlzma(unsigned char *buf, int in_len,
+                             int(*fill)(void*, unsigned int),
+                             int(*flush)(void*, unsigned int),
+                             unsigned char *output,
+                             int *posp,
+                             void(*error_fn)(char *x)
+       )
+{
+       struct lzma_header header;
+       int lc, pb, lp;
+       uint32_t pos_state_mask;
+       uint32_t literal_pos_mask;
+       uint16_t *p;
+       int num_probs;
+       struct rc rc;
+       int i, mi;
+       struct writer wr;
+       struct cstate cst;
+       unsigned char *inbuf;
+       int ret = -1;
+
+       set_error_fn(error_fn);
+       if (!flush)
+               in_len -= 4; /* Uncompressed size hack active in pre-boot
+                               environment */
+       if (buf)
+               inbuf = buf;
+       else
+               inbuf = malloc(LZMA_IOBUF_SIZE);
+       if (!inbuf) {
+               error("Could not allocate input bufer");
+               goto exit_0;
+       }
+
+       cst.state = 0;
+       cst.rep0 = cst.rep1 = cst.rep2 = cst.rep3 = 1;
+
+       wr.header = &header;
+       wr.flush = flush;
+       wr.global_pos = 0;
+       wr.previous_byte = 0;
+       wr.buffer_pos = 0;
+
+       rc_init(&rc, fill, inbuf, in_len);
+
+       for (i = 0; i < sizeof(header); i++) {
+               if (rc.ptr >= rc.buffer_end)
+                       rc_read(&rc);
+               ((unsigned char *)&header)[i] = *rc.ptr++;
+       }
+
+       if (header.pos >= (9 * 5 * 5))
+               error("bad header");
+
+       mi = 0;
+       lc = header.pos;
+       while (lc >= 9) {
+               mi++;
+               lc -= 9;
+       }
+       pb = 0;
+       lp = mi;
+       while (lp >= 5) {
+               pb++;
+               lp -= 5;
+       }
+       pos_state_mask = (1 << pb) - 1;
+       literal_pos_mask = (1 << lp) - 1;
+
+       ENDIAN_CONVERT(header.dict_size);
+       ENDIAN_CONVERT(header.dst_size);
+
+       if (header.dict_size == 0)
+               header.dict_size = 1;
+
+       if (output)
+               wr.buffer = output;
+       else {
+               wr.bufsize = MIN(header.dst_size, header.dict_size);
+               wr.buffer = large_malloc(wr.bufsize);
+       }
+       if (wr.buffer == NULL)
+               goto exit_1;
+
+       num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
+       p = (uint16_t *) large_malloc(num_probs * sizeof(*p));
+       if (p == 0)
+               goto exit_2;
+       num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp));
+       for (i = 0; i < num_probs; i++)
+               p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
+
+       rc_init_code(&rc);
+
+       while (get_pos(&wr) < header.dst_size) {
+               int pos_state = get_pos(&wr) & pos_state_mask;
+               uint16_t *prob = p + LZMA_IS_MATCH +
+                       (cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state;
+               if (rc_is_bit_0(&rc, prob))
+                       process_bit0(&wr, &rc, &cst, p, pos_state, prob,
+                                    lc, literal_pos_mask);
+               else {
+                       process_bit1(&wr, &rc, &cst, p, pos_state, prob);
+                       if (cst.rep0 == 0)
+                               break;
+               }
+       }
+
+       if (posp)
+               *posp = rc.ptr-rc.buffer;
+       if (wr.flush)
+               wr.flush(wr.buffer, wr.buffer_pos);
+       ret = 0;
+       large_free(p);
+exit_2:
+       if (!output)
+               large_free(wr.buffer);
+exit_1:
+       if (!buf)
+               free(inbuf);
+exit_0:
+       return ret;
+}
+
+#define decompress unlzma
index df8a6c92052df2c49888504af7277e1cfdfecfd6..3d17b3d1b21f1fc1a5609a77367d25997f351790 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef INFLATE_H
+#define INFLATE_H
+
 /* inflate.h -- internal inflate state definition
  * Copyright (C) 1995-2004 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
@@ -105,3 +108,4 @@ struct inflate_state {
     unsigned short work[288];   /* work area for code table building */
     code codes[ENOUGH];         /* space for code tables */
 };
+#endif
index 5f5219b1240e58c7b5eb2c7a9e2a3a7add446ef8..b70b4731ac7a6e4ff32f48f84253881ad85c90e9 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef INFTREES_H
+#define INFTREES_H
+
 /* inftrees.h -- header to use inftrees.c
  * Copyright (C) 1995-2005 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
@@ -53,3 +56,4 @@ typedef enum {
 extern int zlib_inflate_table (codetype type, unsigned short *lens,
                              unsigned codes, code **table,
                              unsigned *bits, unsigned short *work);
+#endif
index 60fd56772cc68435c5646e0def07365f53b6f4f6..126d3973b3d1f3be7a3f5e4f42630725c796f31f 100644 (file)
@@ -1816,14 +1816,14 @@ EXPORT_SYMBOL(file_remove_suid);
 static size_t __iovec_copy_from_user_inatomic(char *vaddr,
                        const struct iovec *iov, size_t base, size_t bytes)
 {
-       size_t copied = 0, left = 0, total = bytes;
+       size_t copied = 0, left = 0;
 
        while (bytes) {
                char __user *buf = iov->iov_base + base;
                int copy = min(bytes, iov->iov_len - base);
 
                base = 0;
-               left = __copy_from_user_inatomic_nocache(vaddr, buf, copy, total);
+               left = __copy_from_user_inatomic(vaddr, buf, copy);
                copied += copy;
                bytes -= copy;
                vaddr += copy;
@@ -1851,9 +1851,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page,
        if (likely(i->nr_segs == 1)) {
                int left;
                char __user *buf = i->iov->iov_base + i->iov_offset;
-
-               left = __copy_from_user_inatomic_nocache(kaddr + offset,
-                                                       buf, bytes, bytes);
+               left = __copy_from_user_inatomic(kaddr + offset, buf, bytes);
                copied = bytes - left;
        } else {
                copied = __iovec_copy_from_user_inatomic(kaddr + offset,
@@ -1881,8 +1879,7 @@ size_t iov_iter_copy_from_user(struct page *page,
        if (likely(i->nr_segs == 1)) {
                int left;
                char __user *buf = i->iov->iov_base + i->iov_offset;
-
-               left = __copy_from_user_nocache(kaddr + offset, buf, bytes, bytes);
+               left = __copy_from_user(kaddr + offset, buf, bytes);
                copied = bytes - left;
        } else {
                copied = __iovec_copy_from_user_inatomic(kaddr + offset,
index bf54f8a2cf1df63172706477d666f8bbea6b0268..0c04615651b7e8b412e85cdeee26365ddee7515c 100644 (file)
@@ -354,7 +354,7 @@ __xip_file_write(struct file *filp, const char __user *buf,
                        break;
 
                copied = bytes -
-                       __copy_from_user_nocache(xip_mem + offset, buf, bytes, bytes);
+                       __copy_from_user_nocache(xip_mem + offset, buf, bytes);
 
                if (likely(copied > 0)) {
                        status = copied;
index e9db889d6222c466e6ad2a896dcdcdfd8d7d2d94..2886d2fb9ab5d84dc8177a01778606a82904d6b5 100644 (file)
@@ -1,12 +1,16 @@
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/if_vlan.h>
+#include <linux/netpoll.h>
 #include "vlan.h"
 
 /* VLAN rx hw acceleration helper.  This acts like netif_{rx,receive_skb}(). */
 int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
                      u16 vlan_tci, int polling)
 {
+       if (netpoll_rx(skb))
+               return NET_RX_DROP;
+
        if (skb_bond_should_drop(skb))
                goto drop;
 
@@ -100,6 +104,9 @@ int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
 {
        int err = NET_RX_SUCCESS;
 
+       if (netpoll_receive_skb(skb))
+               return NET_RX_DROP;
+
        switch (vlan_gro_common(napi, grp, vlan_tci, skb)) {
        case -1:
                return netif_receive_skb(skb);
@@ -126,6 +133,9 @@ int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
        if (!skb)
                goto out;
 
+       if (netpoll_receive_skb(skb))
+               goto out;
+
        err = NET_RX_SUCCESS;
 
        switch (vlan_gro_common(napi, grp, vlan_tci, skb)) {
index a17e00662363ad04fc432fe08be012cd9433fb23..72b0d26fd46d037e9a4016a810e06d940df5431a 100644 (file)
@@ -2488,6 +2488,9 @@ static int __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 
 int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 {
+       if (netpoll_receive_skb(skb))
+               return NET_RX_DROP;
+
        switch (__napi_gro_receive(napi, skb)) {
        case -1:
                return netif_receive_skb(skb);
@@ -2558,6 +2561,9 @@ int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info)
        if (!skb)
                goto out;
 
+       if (netpoll_receive_skb(skb))
+               goto out;
+
        err = NET_RX_SUCCESS;
 
        switch (__napi_gro_receive(napi, skb)) {
index a6961d75c7ea6b744d699602bfbdf547694764fe..c28976a7e59641501782f44c84eec1714694c59a 100644 (file)
@@ -1374,7 +1374,8 @@ static u8 tcp_sacktag_one(struct sk_buff *skb, struct sock *sk,
 
 static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,
                           struct tcp_sacktag_state *state,
-                          unsigned int pcount, int shifted, int mss)
+                          unsigned int pcount, int shifted, int mss,
+                          int dup_sack)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *prev = tcp_write_queue_prev(sk, skb);
@@ -1410,7 +1411,7 @@ static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,
        }
 
        /* We discard results */
-       tcp_sacktag_one(skb, sk, state, 0, pcount);
+       tcp_sacktag_one(skb, sk, state, dup_sack, pcount);
 
        /* Difference in this won't matter, both ACKed by the same cumul. ACK */
        TCP_SKB_CB(prev)->sacked |= (TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS);
@@ -1561,7 +1562,7 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb,
 
        if (!skb_shift(prev, skb, len))
                goto fallback;
-       if (!tcp_shifted_skb(sk, skb, state, pcount, len, mss))
+       if (!tcp_shifted_skb(sk, skb, state, pcount, len, mss, dup_sack))
                goto out;
 
        /* Hole filled allows collapsing with the next as well, this is very
@@ -1580,7 +1581,7 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb,
        len = skb->len;
        if (skb_shift(prev, skb, len)) {
                pcount += tcp_skb_pcount(skb);
-               tcp_shifted_skb(sk, skb, state, tcp_skb_pcount(skb), len, mss);
+               tcp_shifted_skb(sk, skb, state, tcp_skb_pcount(skb), len, mss, 0);
        }
 
 out:
index 2747ec7bfb63e885fdc286836f41f5e157f6ded8..4660b088a8ce4abe86ef64b18d4f007926b7424a 100644 (file)
@@ -1,6 +1,6 @@
 /* Tom Kelly's Scalable TCP
  *
- * See htt://www-lce.eng.cam.ac.uk/~ctk21/scalable/
+ * See http://www.deneholme.net/tom/scalable/
  *
  * John Heffner <jheffner@sc.edu>
  */
index 8fe267feb81e2af5e110f97e67916345df0493a1..1bcc3431859ede58e1166a9efaa101461e1cc8e6 100644 (file)
@@ -258,11 +258,11 @@ unique:
 
        if (twp != NULL) {
                *twp = tw;
-               NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_TIMEWAITRECYCLED);
+               NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED);
        } else if (tw != NULL) {
                /* Silly. Should hash-dance instead... */
                inet_twsk_deschedule(tw, death_row);
-               NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_TIMEWAITRECYCLED);
+               NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED);
 
                inet_twsk_put(tw);
        }
index c323643ffcf964214bcffb522c518cb6546bc38c..72dbb6d1a6b3e1b97eb3514c9b44a28688c09d43 100644 (file)
@@ -201,8 +201,9 @@ icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
 
        if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
            nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
-               nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
-                             "nf_ct_icmpv6: ICMPv6 checksum failed\n");
+               if (LOG_INVALID(net, IPPROTO_ICMPV6))
+                       nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
+                                     "nf_ct_icmpv6: ICMPv6 checksum failed ");
                return -NF_ACCEPT;
        }
 
index fa49dc7fe100ffb0cd7a48e1b626c87019903197..c712e9fc6bba2d3c1fca0a2e578067d3963a341e 100644 (file)
@@ -39,7 +39,7 @@
 #endif
 
 #define NFULNL_NLBUFSIZ_DEFAULT        NLMSG_GOODSIZE
-#define NFULNL_TIMEOUT_DEFAULT         HZ      /* every second */
+#define NFULNL_TIMEOUT_DEFAULT         100     /* every second */
 #define NFULNL_QTHRESH_DEFAULT         100     /* 100 packets */
 #define NFULNL_COPY_RANGE_MAX  0xFFFF  /* max packet size is limited by 16-bit struct nfattr nfa_len field */
 
@@ -590,8 +590,10 @@ nfulnl_log_packet(u_int8_t pf,
 
        qthreshold = inst->qthreshold;
        /* per-rule qthreshold overrides per-instance */
-       if (qthreshold > li->u.ulog.qthreshold)
-               qthreshold = li->u.ulog.qthreshold;
+       if (li->u.ulog.qthreshold)
+               if (qthreshold > li->u.ulog.qthreshold)
+                       qthreshold = li->u.ulog.qthreshold;
+
 
        switch (inst->copy_mode) {
        case NFULNL_COPY_META:
index bfbf521f6ea5a4bba99387781d9033cba0ff30a1..5baccfa5a0deb53657424ffd9b6c78713b57a8a1 100644 (file)
@@ -827,59 +827,143 @@ static const struct file_operations xt_table_ops = {
        .release = seq_release_net,
 };
 
-static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos)
+/*
+ * Traverse state for ip{,6}_{tables,matches} for helping crossing
+ * the multi-AF mutexes.
+ */
+struct nf_mttg_trav {
+       struct list_head *head, *curr;
+       uint8_t class, nfproto;
+};
+
+enum {
+       MTTG_TRAV_INIT,
+       MTTG_TRAV_NFP_UNSPEC,
+       MTTG_TRAV_NFP_SPEC,
+       MTTG_TRAV_DONE,
+};
+
+static void *xt_mttg_seq_next(struct seq_file *seq, void *v, loff_t *ppos,
+    bool is_target)
 {
-       struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
-       u_int16_t af = (unsigned long)pde->data;
+       static const uint8_t next_class[] = {
+               [MTTG_TRAV_NFP_UNSPEC] = MTTG_TRAV_NFP_SPEC,
+               [MTTG_TRAV_NFP_SPEC]   = MTTG_TRAV_DONE,
+       };
+       struct nf_mttg_trav *trav = seq->private;
+
+       switch (trav->class) {
+       case MTTG_TRAV_INIT:
+               trav->class = MTTG_TRAV_NFP_UNSPEC;
+               mutex_lock(&xt[NFPROTO_UNSPEC].mutex);
+               trav->head = trav->curr = is_target ?
+                       &xt[NFPROTO_UNSPEC].target : &xt[NFPROTO_UNSPEC].match;
+               break;
+       case MTTG_TRAV_NFP_UNSPEC:
+               trav->curr = trav->curr->next;
+               if (trav->curr != trav->head)
+                       break;
+               mutex_unlock(&xt[NFPROTO_UNSPEC].mutex);
+               mutex_lock(&xt[trav->nfproto].mutex);
+               trav->head = trav->curr = is_target ?
+                       &xt[trav->nfproto].target : &xt[trav->nfproto].match;
+               trav->class = next_class[trav->class];
+               break;
+       case MTTG_TRAV_NFP_SPEC:
+               trav->curr = trav->curr->next;
+               if (trav->curr != trav->head)
+                       break;
+               /* fallthru, _stop will unlock */
+       default:
+               return NULL;
+       }
 
-       mutex_lock(&xt[af].mutex);
-       return seq_list_start(&xt[af].match, *pos);
+       if (ppos != NULL)
+               ++*ppos;
+       return trav;
 }
 
-static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+static void *xt_mttg_seq_start(struct seq_file *seq, loff_t *pos,
+    bool is_target)
 {
-       struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
-       u_int16_t af = (unsigned long)pde->data;
+       struct nf_mttg_trav *trav = seq->private;
+       unsigned int j;
 
-       return seq_list_next(v, &xt[af].match, pos);
+       trav->class = MTTG_TRAV_INIT;
+       for (j = 0; j < *pos; ++j)
+               if (xt_mttg_seq_next(seq, NULL, NULL, is_target) == NULL)
+                       return NULL;
+       return trav;
 }
 
-static void xt_match_seq_stop(struct seq_file *seq, void *v)
+static void xt_mttg_seq_stop(struct seq_file *seq, void *v)
 {
-       struct proc_dir_entry *pde = seq->private;
-       u_int16_t af = (unsigned long)pde->data;
+       struct nf_mttg_trav *trav = seq->private;
+
+       switch (trav->class) {
+       case MTTG_TRAV_NFP_UNSPEC:
+               mutex_unlock(&xt[NFPROTO_UNSPEC].mutex);
+               break;
+       case MTTG_TRAV_NFP_SPEC:
+               mutex_unlock(&xt[trav->nfproto].mutex);
+               break;
+       }
+}
 
-       mutex_unlock(&xt[af].mutex);
+static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       return xt_mttg_seq_start(seq, pos, false);
 }
 
-static int xt_match_seq_show(struct seq_file *seq, void *v)
+static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *ppos)
 {
-       struct xt_match *match = list_entry(v, struct xt_match, list);
+       return xt_mttg_seq_next(seq, v, ppos, false);
+}
 
-       if (strlen(match->name))
-               return seq_printf(seq, "%s\n", match->name);
-       else
-               return 0;
+static int xt_match_seq_show(struct seq_file *seq, void *v)
+{
+       const struct nf_mttg_trav *trav = seq->private;
+       const struct xt_match *match;
+
+       switch (trav->class) {
+       case MTTG_TRAV_NFP_UNSPEC:
+       case MTTG_TRAV_NFP_SPEC:
+               if (trav->curr == trav->head)
+                       return 0;
+               match = list_entry(trav->curr, struct xt_match, list);
+               return (*match->name == '\0') ? 0 :
+                      seq_printf(seq, "%s\n", match->name);
+       }
+       return 0;
 }
 
 static const struct seq_operations xt_match_seq_ops = {
        .start  = xt_match_seq_start,
        .next   = xt_match_seq_next,
-       .stop   = xt_match_seq_stop,
+       .stop   = xt_mttg_seq_stop,
        .show   = xt_match_seq_show,
 };
 
 static int xt_match_open(struct inode *inode, struct file *file)
 {
+       struct seq_file *seq;
+       struct nf_mttg_trav *trav;
        int ret;
 
-       ret = seq_open(file, &xt_match_seq_ops);
-       if (!ret) {
-               struct seq_file *seq = file->private_data;
+       trav = kmalloc(sizeof(*trav), GFP_KERNEL);
+       if (trav == NULL)
+               return -ENOMEM;
 
-               seq->private = PDE(inode);
+       ret = seq_open(file, &xt_match_seq_ops);
+       if (ret < 0) {
+               kfree(trav);
+               return ret;
        }
-       return ret;
+
+       seq = file->private_data;
+       seq->private = trav;
+       trav->nfproto = (unsigned long)PDE(inode)->data;
+       return 0;
 }
 
 static const struct file_operations xt_match_ops = {
@@ -887,62 +971,63 @@ static const struct file_operations xt_match_ops = {
        .open    = xt_match_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release,
+       .release = seq_release_private,
 };
 
 static void *xt_target_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
-       u_int16_t af = (unsigned long)pde->data;
-
-       mutex_lock(&xt[af].mutex);
-       return seq_list_start(&xt[af].target, *pos);
+       return xt_mttg_seq_start(seq, pos, true);
 }
 
-static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *ppos)
 {
-       struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
-       u_int16_t af = (unsigned long)pde->data;
-
-       return seq_list_next(v, &xt[af].target, pos);
-}
-
-static void xt_target_seq_stop(struct seq_file *seq, void *v)
-{
-       struct proc_dir_entry *pde = seq->private;
-       u_int16_t af = (unsigned long)pde->data;
-
-       mutex_unlock(&xt[af].mutex);
+       return xt_mttg_seq_next(seq, v, ppos, true);
 }
 
 static int xt_target_seq_show(struct seq_file *seq, void *v)
 {
-       struct xt_target *target = list_entry(v, struct xt_target, list);
-
-       if (strlen(target->name))
-               return seq_printf(seq, "%s\n", target->name);
-       else
-               return 0;
+       const struct nf_mttg_trav *trav = seq->private;
+       const struct xt_target *target;
+
+       switch (trav->class) {
+       case MTTG_TRAV_NFP_UNSPEC:
+       case MTTG_TRAV_NFP_SPEC:
+               if (trav->curr == trav->head)
+                       return 0;
+               target = list_entry(trav->curr, struct xt_target, list);
+               return (*target->name == '\0') ? 0 :
+                      seq_printf(seq, "%s\n", target->name);
+       }
+       return 0;
 }
 
 static const struct seq_operations xt_target_seq_ops = {
        .start  = xt_target_seq_start,
        .next   = xt_target_seq_next,
-       .stop   = xt_target_seq_stop,
+       .stop   = xt_mttg_seq_stop,
        .show   = xt_target_seq_show,
 };
 
 static int xt_target_open(struct inode *inode, struct file *file)
 {
+       struct seq_file *seq;
+       struct nf_mttg_trav *trav;
        int ret;
 
-       ret = seq_open(file, &xt_target_seq_ops);
-       if (!ret) {
-               struct seq_file *seq = file->private_data;
+       trav = kmalloc(sizeof(*trav), GFP_KERNEL);
+       if (trav == NULL)
+               return -ENOMEM;
 
-               seq->private = PDE(inode);
+       ret = seq_open(file, &xt_target_seq_ops);
+       if (ret < 0) {
+               kfree(trav);
+               return ret;
        }
-       return ret;
+
+       seq = file->private_data;
+       seq->private = trav;
+       trav->nfproto = (unsigned long)PDE(inode)->data;
+       return 0;
 }
 
 static const struct file_operations xt_target_ops = {
@@ -950,7 +1035,7 @@ static const struct file_operations xt_target_ops = {
        .open    = xt_target_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release,
+       .release = seq_release_private,
 };
 
 #define FORMAT_TABLES  "_tables_names"
index fe80b614a40033014f48cfe1fad26f3806af85c2..791e030ea9031358d8d19f6da099554fb090b304 100644 (file)
@@ -542,7 +542,7 @@ recent_mt_proc_write(struct file *file, const char __user *input,
        struct recent_entry *e;
        char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")];
        const char *c = buf;
-       union nf_inet_addr addr;
+       union nf_inet_addr addr = {};
        u_int16_t family;
        bool add, succ;
 
index f6b4fa97df70e353b58ed04ba4a74f50f4c8fbcf..e36e94ab4e100a9b3d971c016734ec7f3f21ed2c 100644 (file)
@@ -66,11 +66,15 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 {
        struct drr_sched *q = qdisc_priv(sch);
        struct drr_class *cl = (struct drr_class *)*arg;
+       struct nlattr *opt = tca[TCA_OPTIONS];
        struct nlattr *tb[TCA_DRR_MAX + 1];
        u32 quantum;
        int err;
 
-       err = nla_parse_nested(tb, TCA_DRR_MAX, tca[TCA_OPTIONS], drr_policy);
+       if (!opt)
+               return -EINVAL;
+
+       err = nla_parse_nested(tb, TCA_DRR_MAX, opt, drr_policy);
        if (err < 0)
                return err;
 
index e06365775bdfe16f5c0242f5bb4464a3c72c0c8c..3b949a354470e7022cd71769351324b155d307e1 100644 (file)
@@ -186,3 +186,17 @@ quiet_cmd_gzip = GZIP    $@
 cmd_gzip = gzip -f -9 < $< > $@
 
 
+# Bzip2
+# ---------------------------------------------------------------------------
+
+# Bzip2 does not include size in file... so we have to fake that
+size_append=$(CONFIG_SHELL) $(srctree)/scripts/bin_size
+
+quiet_cmd_bzip2 = BZIP2    $@
+cmd_bzip2 = (bzip2 -9 < $< && $(size_append) $<) > $@ || (rm -f $@ ; false)
+
+# Lzma
+# ---------------------------------------------------------------------------
+
+quiet_cmd_lzma = LZMA    $@
+cmd_lzma = (lzma -9 -c $< && $(size_append) $<) >$@ || (rm -f $@ ; false)
diff --git a/scripts/bin_size b/scripts/bin_size
new file mode 100644 (file)
index 0000000..43e1b36
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if [ $# = 0 ] ; then
+   echo Usage: $0 file
+fi
+
+size_dec=`stat -c "%s" $1`
+size_hex_echo_string=`printf "%08x" $size_dec |
+     sed 's/\(..\)\(..\)\(..\)\(..\)/\\\\x\4\\\\x\3\\\\x\2\\\\x\1/g'`
+/bin/echo -ne $size_hex_echo_string
index 5f3415f28736a386d84b77ae4fa9e2f179958221..3eea8f15131bcde957bc0fc9699bd5f47934f62a 100644 (file)
@@ -5,7 +5,7 @@
 # Released under the terms of the GNU GPL
 #
 # Generate a cpio packed initramfs. It uses gen_init_cpio to generate
-# the cpio archive, and gzip to pack it.
+# the cpio archive, and then compresses it.
 # The script may also be used to generate the inputfile used for gen_init_cpio
 # This script assumes that gen_init_cpio is located in usr/ directory
 
@@ -16,8 +16,8 @@ usage() {
 cat << EOF
 Usage:
 $0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
-       -o <file>      Create gzipped initramfs file named <file> using
-                      gen_init_cpio and gzip
+       -o <file>      Create compressed initramfs file named <file> using
+                      gen_init_cpio and compressor depending on the extension
        -u <uid>       User ID to map to user ID 0 (root).
                       <uid> is only meaningful if <cpio_source> is a
                       directory.  "squash" forces all files to uid 0.
@@ -225,6 +225,7 @@ cpio_list=
 output="/dev/stdout"
 output_file=""
 is_cpio_compressed=
+compr="gzip -9 -f"
 
 arg="$1"
 case "$arg" in
@@ -233,11 +234,15 @@ case "$arg" in
                echo "deps_initramfs := \\"
                shift
                ;;
-       "-o")   # generate gzipped cpio image named $1
+       "-o")   # generate compressed cpio image named $1
                shift
                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 "\.cpio$" && compr="cat"
                shift
                ;;
 esac
@@ -274,7 +279,7 @@ while [ $# -gt 0 ]; do
        esac
 done
 
-# If output_file is set we will generate cpio archive and gzip it
+# If output_file is set we will generate cpio archive and compress it
 # we are carefull to delete tmp files
 if [ ! -z ${output_file} ]; then
        if [ -z ${cpio_file} ]; then
@@ -287,7 +292,8 @@ if [ ! -z ${output_file} ]; then
        if [ "${is_cpio_compressed}" = "compressed" ]; then
                cat ${cpio_tfile} > ${output_file}
        else
-               cat ${cpio_tfile} | gzip -f -9 - > ${output_file}
+               (cat ${cpio_tfile} | ${compr}  - > ${output_file}) \
+               || (rm -f ${output_file} ; false)
        fi
        [ -z ${cpio_file} ] && rm ${cpio_tfile}
 fi
index 3f4b26647386f58d5932e8e1b78f0e57f8752bf6..350794ab9b4212d7e50b07f3c778bb42bb81aa3a 100644 (file)
@@ -386,11 +386,12 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask)
        if (!S_ISSOCK(inode->i_mode) ||
            ((mask & (MAY_WRITE | MAY_APPEND)) == 0))
                return 0;
-
        sock = SOCKET_I(inode);
        sk = sock->sk;
+       if (sk == NULL)
+               return 0;
        sksec = sk->sk_security;
-       if (sksec->nlbl_state != NLBL_REQUIRE)
+       if (sksec == NULL || sksec->nlbl_state != NLBL_REQUIRE)
                return 0;
 
        local_bh_disable();
index c8d9178f47e59bf327b17433017d24460620a5e5..5e909e0da04b4b64d18ee9979f38cbaaa853e354 100644 (file)
@@ -2095,6 +2095,8 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01),
        /* including bogus ALC268 in slot#2 that conflicts with ALC888 */
        SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
+       /* conflict of ALC268 in slot#3 (digital I/O); a temporary fix */
+       SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba laptop", 0x03),
        {}
 };
 
index a680be0d45340858f70c96989fd4e9b13088502c..6c26afcb82622d7b0e994f69c334cec8ef90bf33 100644 (file)
@@ -10557,6 +10557,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
        SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
        SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
+       SND_PCI_QUIRK(0x103c, 0x170b, "HP xw*", ALC262_HP_BPC),
        SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
        SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
        SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
index 8027edf3c8f2ab2d13848b45ab3a66495ceb2e81..3bc427645da8ef1411400990b67c9fc181e4cece 100644 (file)
@@ -4989,7 +4989,7 @@ again:
        case STAC_DELL_M4_3:
                spec->num_dmics = 1;
                spec->num_smuxes = 0;
-               spec->num_dmuxes = 0;
+               spec->num_dmuxes = 1;
                break;
        default:
                spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
index 86cecb59dd0759ffedf3b551dd50f0a96fd3d2c7..43a3a0fe8f29b3637bcd49eb0d3824d5da67d2a6 100644 (file)
@@ -44,3 +44,92 @@ config INITRAMFS_ROOT_GID
          owned by group root in the initial ramdisk image.
 
          If you are not sure, leave it set to "0".
+
+config RD_GZIP
+       bool "Initial ramdisk compressed using gzip"
+       default y
+       depends on BLK_DEV_INITRD=y
+       select DECOMPRESS_GZIP
+       help
+         Support loading of a gzip encoded initial ramdisk or cpio buffer.
+         If unsure, say Y.
+
+config RD_BZIP2
+       bool "Initial ramdisk compressed using bzip2"
+       default n
+       depends on BLK_DEV_INITRD=y
+       select DECOMPRESS_BZIP2
+       help
+         Support loading of a bzip2 encoded initial ramdisk or cpio buffer
+         If unsure, say N.
+
+config RD_LZMA
+       bool "Initial ramdisk compressed using lzma"
+       default n
+       depends on BLK_DEV_INITRD=y
+       select DECOMPRESS_LZMA
+       help
+         Support loading of a lzma encoded initial ramdisk or cpio buffer
+         If unsure, say N.
+
+choice
+       prompt "Built-in initramfs compression mode"
+       help
+         This setting is only meaningful if the INITRAMFS_SOURCE is
+         set. It decides by which algorithm the INITRAMFS_SOURCE will
+         be compressed.
+         Several compression algorithms are available, which differ
+         in efficiency, compression and decompression speed.
+         Compression speed is only relevant when building a kernel.
+         Decompression speed is relevant at each boot.
+
+         If you have any problems with bzip2 or lzma compressed
+         initramfs, mail me (Alain Knaff) <alain@knaff.lu>.
+
+         High compression options are mostly useful for users who
+         are low on disk space (embedded systems), but for whom ram
+         size matters less.
+
+         If in doubt, select 'gzip'
+
+config INITRAMFS_COMPRESSION_NONE
+       bool "None"
+       help
+         Do not compress the built-in initramfs at all. This may
+         sound wasteful in space, but, you should be aware that the
+         built-in initramfs will be compressed at a later stage
+         anyways along with the rest of the kernel, on those
+         architectures that support this.
+         However, not compressing the initramfs may lead to slightly
+         higher memory consumption during a short time at boot, while
+         both the cpio image and the unpacked filesystem image will
+         be present in memory simultaneously
+
+config INITRAMFS_COMPRESSION_GZIP
+       bool "Gzip"
+       depends on RD_GZIP
+       help
+         The old and tried gzip compression. Its compression ratio is
+         the poorest among the 3 choices; however its speed (both
+         compression and decompression) is the fastest.
+
+config INITRAMFS_COMPRESSION_BZIP2
+       bool "Bzip2"
+       depends on RD_BZIP2
+       help
+         Its compression ratio and speed is intermediate.
+         Decompression speed is slowest among the three.  The initramfs
+         size is about 10% smaller with bzip2, in comparison to gzip.
+         Bzip2 uses a large amount of memory. For modern kernels you
+         will need at least 8MB RAM or more for booting.
+
+config INITRAMFS_COMPRESSION_LZMA
+       bool "LZMA"
+       depends on RD_LZMA
+       help
+         The most recent compression algorithm.
+         Its ratio is best, decompression speed is between the other
+         two. Compression is slowest.  The initramfs size is about 33%
+         smaller with LZMA in comparison to gzip.
+
+endchoice
index 201f27f8cbaf1c6b266b68f3a915c3edce50b67b..b84894b3929d4ad4b2e029b17370cef2c7332836 100644 (file)
@@ -6,13 +6,25 @@ klibcdirs:;
 PHONY += klibcdirs
 
 
+# No compression
+suffix_$(CONFIG_INITRAMFS_COMPRESSION_NONE)   =
+
+# Gzip, but no bzip2
+suffix_$(CONFIG_INITRAMFS_COMPRESSION_GZIP)   = .gz
+
+# Bzip2
+suffix_$(CONFIG_INITRAMFS_COMPRESSION_BZIP2)  = .bz2
+
+# Lzma
+suffix_$(CONFIG_INITRAMFS_COMPRESSION_LZMA)   = .lzma
+
 # Generate builtin.o based on initramfs_data.o
-obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o
+obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data$(suffix_y).o
 
-# initramfs_data.o contains the initramfs_data.cpio.gz image.
+# initramfs_data.o contains the compressed initramfs_data.cpio image.
 # The image is included using .incbin, a dependency which is not
 # tracked automatically.
-$(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio.gz FORCE
+$(obj)/initramfs_data$(suffix_y).o: $(obj)/initramfs_data.cpio$(suffix_y) FORCE
 
 #####
 # Generate the initramfs cpio archive
@@ -25,28 +37,28 @@ ramfs-args  := \
         $(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \
         $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID))
 
-# .initramfs_data.cpio.gz.d is used to identify all files included
+# .initramfs_data.cpio.d is used to identify all files included
 # in initramfs and to detect if any files are added/removed.
 # Removed files are identified by directory timestamp being updated
 # The dependency list is generated by gen_initramfs.sh -l
-ifneq ($(wildcard $(obj)/.initramfs_data.cpio.gz.d),)
-       include $(obj)/.initramfs_data.cpio.gz.d
+ifneq ($(wildcard $(obj)/.initramfs_data.cpio.d),)
+       include $(obj)/.initramfs_data.cpio.d
 endif
 
 quiet_cmd_initfs = GEN     $@
       cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input)
 
-targets := initramfs_data.cpio.gz
+targets := initramfs_data.cpio.gz initramfs_data.cpio.bz2 initramfs_data.cpio.lzma initramfs_data.cpio
 # do not try to update files included in initramfs
 $(deps_initramfs): ;
 
 $(deps_initramfs): klibcdirs
-# We rebuild initramfs_data.cpio.gz if:
-# 1) Any included file is newer then initramfs_data.cpio.gz
+# We rebuild initramfs_data.cpio if:
+# 1) Any included file is newer then initramfs_data.cpio
 # 2) There are changes in which files are included (added or deleted)
-# 3) If gen_init_cpio are newer than initramfs_data.cpio.gz
+# 3) If gen_init_cpio are newer than initramfs_data.cpio
 # 4) arguments to gen_initramfs.sh changes
-$(obj)/initramfs_data.cpio.gz: $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs
-       $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.gz.d
+$(obj)/initramfs_data.cpio$(suffix_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs
+       $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.d
        $(call if_changed,initfs)
 
index c2e1ad424f4a41ce7d69f52f58b3ee681762a39d..7c6973d8d829e76101e112c7ab021d5c28dbcbad 100644 (file)
@@ -26,5 +26,5 @@ SECTIONS
 */
 
 .section .init.ramfs,"a"
-.incbin "usr/initramfs_data.cpio.gz"
+.incbin "usr/initramfs_data.cpio"
 
diff --git a/usr/initramfs_data.bz2.S b/usr/initramfs_data.bz2.S
new file mode 100644 (file)
index 0000000..bc54d09
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+  initramfs_data includes the compressed binary that is the
+  filesystem used for early user space.
+  Note: Older versions of "as" (prior to binutils 2.11.90.0.23
+  released on 2001-07-14) dit not support .incbin.
+  If you are forced to use older binutils than that then the
+  following trick can be applied to create the resulting binary:
+
+
+  ld -m elf_i386  --format binary --oformat elf32-i386 -r \
+  -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
+   ld -m elf_i386  -r -o built-in.o initramfs_data.o
+
+  initramfs_data.scr looks like this:
+SECTIONS
+{
+       .init.ramfs : { *(.data) }
+}
+
+  The above example is for i386 - the parameters vary from architectures.
+  Eventually look up LDFLAGS_BLOB in an older version of the
+  arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
+
+  Using .incbin has the advantage over ld that the correct flags are set
+  in the ELF header, as required by certain architectures.
+*/
+
+.section .init.ramfs,"a"
+.incbin "usr/initramfs_data.cpio.bz2"
diff --git a/usr/initramfs_data.gz.S b/usr/initramfs_data.gz.S
new file mode 100644 (file)
index 0000000..890c8dd
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+  initramfs_data includes the compressed binary that is the
+  filesystem used for early user space.
+  Note: Older versions of "as" (prior to binutils 2.11.90.0.23
+  released on 2001-07-14) dit not support .incbin.
+  If you are forced to use older binutils than that then the
+  following trick can be applied to create the resulting binary:
+
+
+  ld -m elf_i386  --format binary --oformat elf32-i386 -r \
+  -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
+   ld -m elf_i386  -r -o built-in.o initramfs_data.o
+
+  initramfs_data.scr looks like this:
+SECTIONS
+{
+       .init.ramfs : { *(.data) }
+}
+
+  The above example is for i386 - the parameters vary from architectures.
+  Eventually look up LDFLAGS_BLOB in an older version of the
+  arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
+
+  Using .incbin has the advantage over ld that the correct flags are set
+  in the ELF header, as required by certain architectures.
+*/
+
+.section .init.ramfs,"a"
+.incbin "usr/initramfs_data.cpio.gz"
diff --git a/usr/initramfs_data.lzma.S b/usr/initramfs_data.lzma.S
new file mode 100644 (file)
index 0000000..e11469e
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+  initramfs_data includes the compressed binary that is the
+  filesystem used for early user space.
+  Note: Older versions of "as" (prior to binutils 2.11.90.0.23
+  released on 2001-07-14) dit not support .incbin.
+  If you are forced to use older binutils than that then the
+  following trick can be applied to create the resulting binary:
+
+
+  ld -m elf_i386  --format binary --oformat elf32-i386 -r \
+  -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
+   ld -m elf_i386  -r -o built-in.o initramfs_data.o
+
+  initramfs_data.scr looks like this:
+SECTIONS
+{
+       .init.ramfs : { *(.data) }
+}
+
+  The above example is for i386 - the parameters vary from architectures.
+  Eventually look up LDFLAGS_BLOB in an older version of the
+  arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
+
+  Using .incbin has the advantage over ld that the correct flags are set
+  in the ELF header, as required by certain architectures.
+*/
+
+.section .init.ramfs,"a"
+.incbin "usr/initramfs_data.cpio.lzma"