Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Mon, 8 May 2006 16:28:35 +0000 (09:28 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 8 May 2006 16:28:35 +0000 (09:28 -0700)
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6:
  [IA64] remove asm-ia64/bitops.h self-inclusion
  [IA64] strcpy returns NULL pointer and not destination pointer

43 files changed:
Makefile
arch/arm/kernel/asm-offsets.c
arch/arm/kernel/head-nommu.S
arch/arm/kernel/head.S
arch/arm/mach-aaec2000/aaed2000.c
arch/arm/mach-aaec2000/core.c
arch/arm/mach-aaec2000/core.h
arch/arm/mach-imx/mx1ads.c
arch/arm/mach-pxa/dma.c
arch/arm/mach-sa1100/irq.c
arch/arm/vfp/vfpmodule.c
block/genhd.c
drivers/base/class.c
drivers/net/irda/irda-usb.c
drivers/rtc/rtc-sa1100.c
drivers/video/logo/Makefile
fs/locks.c
include/asm-arm/arch-aaec2000/debug-macro.S
include/asm-arm/arch-aaec2000/entry-macro.S
include/asm-arm/arch-imx/debug-macro.S
include/asm-arm/arch-pxa/dma.h
include/asm-arm/bug.h
include/asm-arm/unistd.h
include/linux/device.h
include/linux/netdevice.h
include/net/sctp/structs.h
kernel/ptrace.c
net/bridge/br_input.c
net/core/dev.c
net/core/net-sysfs.c
net/dccp/proto.c
net/ipv4/ip_input.c
net/ipv4/tcp_highspeed.c
net/netrom/af_netrom.c
net/rose/af_rose.c
net/sctp/inqueue.c
net/sctp/sm_statefuns.c
net/sctp/sm_statetable.c
net/sctp/ulpqueue.c
scripts/gen_initramfs_list.sh
scripts/mkmakefile
scripts/mod/modpost.c
scripts/mod/modpost.h

index 6bf99624bd4c5705b4b5bd6f96385a012dc0a736..9e4c5692a32f2e89cdd0533b1abff532938dcb52 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -344,16 +344,14 @@ scripts_basic:
 scripts/basic/%: scripts_basic ;
 
 PHONY += outputmakefile
-# outputmakefile generate a Makefile to be placed in output directory, if
-# using a seperate output directory. This allows convinient use
-# of make in output directory
+# outputmakefile generates a Makefile in the output directory, if using a
+# separate output directory. This allows convenient use of make in the
+# output directory.
 outputmakefile:
-       $(Q)if test ! $(srctree) -ef $(objtree); then \
-       $(CONFIG_SHELL) $(srctree)/scripts/mkmakefile              \
-           $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)         \
-           > $(objtree)/Makefile;                                 \
-           echo '  GEN    $(objtree)/Makefile';                   \
-       fi
+ifneq ($(KBUILD_SRC),)
+       $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
+           $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
+endif
 
 # To make sure we do not include .config for any of the *config targets
 # catch them early, and hand them over to scripts/kconfig/Makefile
@@ -796,8 +794,8 @@ prepare2: prepare3 outputmakefile
 prepare1: prepare2 include/linux/version.h include/asm \
                    include/config/MARKER
 ifneq ($(KBUILD_MODULES),)
-       $(Q)rm -rf $(MODVERDIR)
        $(Q)mkdir -p $(MODVERDIR)
+       $(Q)rm -f $(MODVERDIR)/*
 endif
 
 archprepare: prepare1 scripts_basic
@@ -1086,8 +1084,8 @@ else # KBUILD_EXTMOD
 KBUILD_MODULES := 1
 PHONY += crmodverdir
 crmodverdir:
-       $(Q)rm -rf $(MODVERDIR)
        $(Q)mkdir -p $(MODVERDIR)
+       $(Q)rm -f $(MODVERDIR)/*
 
 PHONY += $(objtree)/Module.symvers
 $(objtree)/Module.symvers:
index b324dcac1c561c8564d1473a0a8113b4733f2cdc..45fdf4a51a2ad0a7d1d127ff9dc75898a3aa6369 100644 (file)
@@ -95,5 +95,11 @@ int main(void)
   DEFINE(SYS_ERROR0,           0x9f0000);
   BLANK();
   DEFINE(SIZEOF_MACHINE_DESC,  sizeof(struct machine_desc));
+  DEFINE(MACHINFO_TYPE,                offsetof(struct machine_desc, nr));
+  DEFINE(MACHINFO_NAME,                offsetof(struct machine_desc, name));
+  DEFINE(MACHINFO_PHYSIO,      offsetof(struct machine_desc, phys_io));
+  DEFINE(MACHINFO_PGOFFIO,     offsetof(struct machine_desc, io_pg_offst));
+  DEFINE(PROCINFO_INITFUNC,    offsetof(struct proc_info_list, __cpu_flush));
+  DEFINE(PROCINFO_MMUFLAGS,    offsetof(struct proc_info_list, __cpu_mmu_flags));
   return 0; 
 }
index 0bea65864051a28b2babe2f4ac42b123f66566b8..adf62e5eaad7a7f8ba120a76b9c39c00bc64d458 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/procinfo.h>
 #include <asm/ptrace.h>
+#include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
 #include <asm/system.h>
 
-#define PROCINFO_INITFUNC       12
-#define MACHINFO_TYPE          0
-
 /*
  * Kernel startup entry point.
  * ---------------------------
index 04b66a9328ef8fbeeb51d7eed141b1cc0f1353ff..04f7344e356a30b12b5b7b7b4d8695c222960d55 100644 (file)
 #include <asm/thread_info.h>
 #include <asm/system.h>
 
-#define PROCINFO_MMUFLAGS      8
-#define PROCINFO_INITFUNC      12
-
-#define MACHINFO_TYPE          0
-#define MACHINFO_PHYSIO                4
-#define MACHINFO_PGOFFIO       8
-#define MACHINFO_NAME          12
-
 #define KERNEL_RAM_ADDR        (PAGE_OFFSET + TEXT_OFFSET)
 
 /*
index dc5fa8e5ebefa35121f5cc5aa6d5e65bc1f974a7..83f57da3184cceea1dd3ba64bd860b1fb9435993 100644 (file)
@@ -79,7 +79,12 @@ static void __init aaed2000_init(void)
 }
 
 static struct map_desc aaed2000_io_desc[] __initdata = {
-  { EXT_GPIO_VBASE, EXT_GPIO_PBASE, EXT_GPIO_LENGTH, MT_DEVICE }, /* Ext GPIO */
+       {
+               .virtual        = EXT_GPIO_VBASE,
+               .pfn            = __phys_to_pfn(EXT_GPIO_PBASE),
+               .length         = EXT_GPIO_LENGTH,
+               .type           = MT_DEVICE
+       },
 };
 
 static void __init aaed2000_map_io(void)
index dce4815cf53cd6c808cea279e58954d12f0db5bc..65be5efd633c7b618c71f1a2e478ea8501b3c110 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/interrupt.h>
 #include <linux/timex.h>
 #include <linux/signal.h>
-#include <linux/amba/bus.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
 static struct map_desc standard_io_desc[] __initdata = {
        {
                .virtual        = VIO_APB_BASE,
-               .physical       = __phys_to_pfn(PIO_APB_BASE),
+               .pfn            = __phys_to_pfn(PIO_APB_BASE),
                .length         = IO_APB_LENGTH,
                .type           = MT_DEVICE
        }, {
                .virtual        = VIO_AHB_BASE,
-               .physical       = __phys_to_pfn(PIO_AHB_BASE),
+               .pfn            = __phys_to_pfn(PIO_AHB_BASE),
                .length         = IO_AHB_LENGTH,
                .type           = MT_DEVICE
        }
index b6029a95f19cfe9dfaec885e9c61f1aefd439969..59501b5731674b5a99c5119916b335fec7300c85 100644 (file)
@@ -9,6 +9,7 @@
  *
  */
 
+#include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
 
 struct sys_timer;
index e1f6c0bbe1e74ce586d743bc091066be260e803e..da893c80d471550c59a51acbeeb31d97437c730b 100644 (file)
@@ -161,7 +161,7 @@ mx1ads_map_io(void)
 MACHINE_START(MX1ADS, "Motorola MX1ADS")
        /* Maintainer: Sascha Hauer, Pengutronix */
        .phys_io        = 0x00200000,
-       .io_pg_offst    = ((0xe0200000) >> 18) & 0xfffc,
+       .io_pg_offst    = ((0xe0000000) >> 18) & 0xfffc,
        .boot_params    = 0x08000100,
        .map_io         = mx1ads_map_io,
        .init_irq       = imx_init_irq,
index 458112b21e25df5008783edab1d288d51e338dd5..7d8c85486c669065554d1857b4359ce94ee9b6c8 100644 (file)
@@ -45,23 +45,16 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
 
        local_irq_save(flags);
 
-       /* try grabbing a DMA channel with the requested priority */
-       for (i = prio; i < prio + PXA_DMA_NBCH(prio); i++) {
-               if (!dma_channels[i].name) {
-                       found = 1;
-                       break;
-               }
-       }
-
-       if (!found) {
-               /* requested prio group is full, try hier priorities */
-               for (i = prio-1; i >= 0; i--) {
+       do {
+               /* try grabbing a DMA channel with the requested priority */
+               pxa_for_each_dma_prio (i, prio) {
                        if (!dma_channels[i].name) {
                                found = 1;
                                break;
                        }
                }
-       }
+               /* if requested prio group is full, try a hier priority */
+       } while (!found && prio--);
 
        if (found) {
                DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
index c131a5201b5ba885ba9448381cfaab27ab345634..b3a56024182ee6ac15cc3e679e815661ee7095f4 100644 (file)
@@ -199,10 +199,26 @@ static void sa1100_unmask_irq(unsigned int irq)
        ICMR |= (1 << irq);
 }
 
+/*
+ * Apart form GPIOs, only the RTC alarm can be a wakeup event.
+ */
+static int sa1100_set_wake(unsigned int irq, unsigned int on)
+{
+       if (irq == IRQ_RTCAlrm) {
+               if (on)
+                       PWER |= PWER_RTC;
+               else
+                       PWER &= ~PWER_RTC;
+               return 0;
+       }
+       return -EINVAL;
+}
+
 static struct irqchip sa1100_normal_chip = {
        .ack            = sa1100_mask_irq,
        .mask           = sa1100_mask_irq,
        .unmask         = sa1100_unmask_irq,
+       .set_wake       = sa1100_set_wake,
 };
 
 static struct resource irq_resource = {
index 37ff8145b5b50bf52ea9f22f5212068764167e5f..03486be04193e0497f8258d45d4be1ef02656258 100644 (file)
@@ -245,7 +245,7 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
         */
        barrier();
        trigger = fmrx(FPINST2);
-       fpscr = fmrx(FPSCR);
+       orig_fpscr = fpscr = fmrx(FPSCR);
 
  emulate:
        exceptions = vfp_emulate_instruction(trigger, fpscr, regs);
index 5a8d3bf02f1715702fe94515339f1cdfbfd3d088..d96572589621e10ecae8107616459f227e3be111 100644 (file)
@@ -182,6 +182,7 @@ static int exact_lock(dev_t dev, void *data)
  */
 void add_disk(struct gendisk *disk)
 {
+       get_device(disk->driverfs_dev);
        disk->flags |= GENHD_FL_UP;
        blk_register_region(MKDEV(disk->major, disk->first_minor),
                            disk->minors, NULL, exact_match, exact_lock, disk);
@@ -427,6 +428,7 @@ static struct attribute * default_attrs[] = {
 static void disk_release(struct kobject * kobj)
 {
        struct gendisk *disk = to_disk(kobj);
+       put_device(disk->driverfs_dev);
        kfree(disk->random);
        kfree(disk->part);
        free_disk_stats(disk);
index 0e71dff327cd896509060a66f9fe348972253460..b1ea4df85c7dde7fc3289e27529bf1b85e785dda 100644 (file)
@@ -456,6 +456,35 @@ static void class_device_remove_attrs(struct class_device * cd)
        }
 }
 
+static int class_device_add_groups(struct class_device * cd)
+{
+       int i;
+       int error = 0;
+
+       if (cd->groups) {
+               for (i = 0; cd->groups[i]; i++) {
+                       error = sysfs_create_group(&cd->kobj, cd->groups[i]);
+                       if (error) {
+                               while (--i >= 0)
+                                       sysfs_remove_group(&cd->kobj, cd->groups[i]);
+                               goto out;
+                       }
+               }
+       }
+out:
+       return error;
+}
+
+static void class_device_remove_groups(struct class_device * cd)
+{
+       int i;
+       if (cd->groups) {
+               for (i = 0; cd->groups[i]; i++) {
+                       sysfs_remove_group(&cd->kobj, cd->groups[i]);
+               }
+       }
+}
+
 static ssize_t show_dev(struct class_device *class_dev, char *buf)
 {
        return print_dev_t(buf, class_dev->devt);
@@ -559,6 +588,8 @@ int class_device_add(struct class_device *class_dev)
                                  class_name);
        }
 
+       class_device_add_groups(class_dev);
+
        kobject_uevent(&class_dev->kobj, KOBJ_ADD);
 
        /* notify any interfaces this device is now here */
@@ -672,6 +703,7 @@ void class_device_del(struct class_device *class_dev)
        if (class_dev->devt_attr)
                class_device_remove_file(class_dev, class_dev->devt_attr);
        class_device_remove_attrs(class_dev);
+       class_device_remove_groups(class_dev);
 
        kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
        kobject_del(&class_dev->kobj);
index 96bdb73c2283bb3cbcd8bcdc964062f660b5f15d..cd87593e4e8ae6cfe464a5926c91d1db9469b5e0 100644 (file)
@@ -1778,7 +1778,7 @@ static int irda_usb_probe(struct usb_interface *intf,
 
        if (self->needspatch) {
                ret = usb_control_msg (self->usbdev, usb_sndctrlpipe (self->usbdev, 0),
-                                      0x02, 0x40, 0, 0, 0, 0, msecs_to_jiffies(500));
+                                      0x02, 0x40, 0, 0, NULL, 0, 500);
                if (ret < 0) {
                        IRDA_DEBUG (0, "usb_control_msg failed %d\n", ret);
                        goto err_out_3;
index a23ec54989f6dbad436d1d91397b542511136346..2bc8aad47219180f58799a4b89523a9cf8298234 100644 (file)
@@ -178,9 +178,9 @@ static int sa1100_rtc_open(struct device *dev)
        return 0;
 
  fail_pi:
-       free_irq(IRQ_RTCAlrm, NULL);
+       free_irq(IRQ_RTCAlrm, dev);
  fail_ai:
-       free_irq(IRQ_RTC1Hz, NULL);
+       free_irq(IRQ_RTC1Hz, dev);
  fail_ui:
        return ret;
 }
@@ -295,7 +295,7 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
 {
-       seq_printf(seq, "trim/divider\t: 0x%08x\n", RTTR);
+       seq_printf(seq, "trim/divider\t: 0x%08lx\n", RTTR);
        seq_printf(seq, "alarm_IRQ\t: %s\n",
                        (RTSR & RTSR_ALE) ? "yes" : "no" );
        seq_printf(seq, "update_IRQ\t: %s\n",
index 4ef5cd19609d650623890238e1b9055ab8699712..b985dfad6c63fb369c812e1d198e5d66c5f30670 100644 (file)
@@ -34,7 +34,7 @@ extra-y += $(call logo-cfiles,_clut224,ppm)
 extra-y += $(call logo-cfiles,_gray256,pgm)
 
 # Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..."
-quiet_cmd_logo = LOGO  $@
+quiet_cmd_logo = LOGO    $@
        cmd_logo = scripts/pnmtologo \
                        -t $(patsubst $*_%,%,$(notdir $(basename $<))) \
                        -n $(notdir $(basename $<)) -o $@ $<
index efad798824dc19913b7aace09dbee47b8c6ca6a7..6f99c0a6f83629fbaa3eaaaf853fb6b7b9a9cfcc 100644 (file)
@@ -446,15 +446,14 @@ static struct lock_manager_operations lease_manager_ops = {
  */
 static int lease_init(struct file *filp, int type, struct file_lock *fl)
  {
+       if (assign_type(fl, type) != 0)
+               return -EINVAL;
+
        fl->fl_owner = current->files;
        fl->fl_pid = current->tgid;
 
        fl->fl_file = filp;
        fl->fl_flags = FL_LEASE;
-       if (assign_type(fl, type) != 0) {
-               locks_free_lock(fl);
-               return -EINVAL;
-       }
        fl->fl_start = 0;
        fl->fl_end = OFFSET_MAX;
        fl->fl_ops = NULL;
@@ -466,16 +465,19 @@ static int lease_init(struct file *filp, int type, struct file_lock *fl)
 static int lease_alloc(struct file *filp, int type, struct file_lock **flp)
 {
        struct file_lock *fl = locks_alloc_lock();
-       int error;
+       int error = -ENOMEM;
 
        if (fl == NULL)
-               return -ENOMEM;
+               goto out;
 
        error = lease_init(filp, type, fl);
-       if (error)
-               return error;
+       if (error) {
+               locks_free_lock(fl);
+               fl = NULL;
+       }
+out:
        *flp = fl;
-       return 0;
+       return error;
 }
 
 /* Check if two locks overlap each other.
@@ -1372,6 +1374,7 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp)
                goto out;
 
        if (my_before != NULL) {
+               *flp = *my_before;
                error = lease->fl_lmops->fl_change(my_before, arg);
                goto out;
        }
index e4f1fa539a7434ccb8bf4e3339130fe16d9cb30e..7b1fce021d8a6c497c1817cb21750cf563c8d6f7 100644 (file)
@@ -9,6 +9,7 @@
  *  published by the Free Software Foundation.
  */
 
+#include "hardware.h"
                .macro  addruart,rx
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
index df31313ab07eee1a0ab1435570db35f02b0d6009..1eb3503bd16e1a78303a610eb4723422cde8988a 100644 (file)
@@ -10,6 +10,7 @@
  *  published by the Free Software Foundation.
  *
  */
+#include <asm/arch/irqs.h>
 
                .macro  disable_fiq
                .endm
index 83f552f7bcc142eddd9b850575a38d1ac5c3690b..c611871643a287ea08f1a37a151f765329d35b6b 100644 (file)
@@ -16,7 +16,7 @@
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x00000000        @ physical
                movne   \rx, #0xe0000000        @ virtual
-               orr     \rx, \rx, #0x00200000
+               orreq   \rx, \rx, #0x00200000   @ physical
                orr     \rx, \rx, #0x00006000   @ UART1 offset
                .endm
 
index 3e88a2a02a0fdd01186107439eed4711d38b9a7f..a008150abc59f2775e8ce25e03b3bb0f2b1476ec 100644 (file)
@@ -24,27 +24,29 @@ typedef struct pxa_dma_desc {
        volatile u32 dcmd;      /* DCMD value for the current transfer */
 } pxa_dma_desc;
 
+typedef enum {
+       DMA_PRIO_HIGH = 0,
+       DMA_PRIO_MEDIUM = 1,
+       DMA_PRIO_LOW = 2
+} pxa_dma_prio;
+
 #if defined(CONFIG_PXA27x)
 
 #define PXA_DMA_CHANNELS       32
-#define PXA_DMA_NBCH(prio)     ((prio == DMA_PRIO_LOW) ? 16 : 8)
 
-typedef enum {
-       DMA_PRIO_HIGH = 0,
-       DMA_PRIO_MEDIUM = 8,
-       DMA_PRIO_LOW = 16
-} pxa_dma_prio;
+#define pxa_for_each_dma_prio(ch, prio)                                        \
+for (                                                                  \
+       ch = prio * 4;                                                  \
+       ch != (4 << prio) + 16;                                         \
+       ch = (ch + 1 == (4 << prio)) ? (prio * 4 + 16) : (ch + 1)       \
+)
 
 #elif defined(CONFIG_PXA25x)
 
 #define PXA_DMA_CHANNELS       16
-#define PXA_DMA_NBCH(prio)     ((prio == DMA_PRIO_LOW) ? 8 : 4)
 
-typedef enum {
-       DMA_PRIO_HIGH = 0,
-       DMA_PRIO_MEDIUM = 4,
-       DMA_PRIO_LOW = 8
-} pxa_dma_prio;
+#define pxa_for_each_dma_prio(ch, prio)                                        \
+       for (ch = prio * 4; ch != (4 << prio); ch++)
 
 #endif
 
index 7fb02138f585985dd810407a82a8643bb3874d9f..5ab8216f5204aa7f204cd5b34fffb228428ff618 100644 (file)
@@ -2,6 +2,7 @@
 #define _ASMARM_BUG_H
 
 #include <linux/config.h>
+#include <linux/stddef.h>
 
 #ifdef CONFIG_BUG
 #ifdef CONFIG_DEBUG_BUGVERBOSE
index 26f2f4828e03f323cbfbba8aaee686c1e4442fef..cbf39a56dbe768db84f96396ebf77823cc525c3d 100644 (file)
 /*
  * The following syscalls are obsolete and no longer available for EABI.
  */
-#if defined(__ARM_EABI__)
+#if defined(__ARM_EABI__) && !defined(__KERNEL__)
 #undef __NR_time
 #undef __NR_umount
 #undef __NR_stime
index f6e72a65a3f21c1f6b8cb92b32c6542ab4537753..e8e53b9accc67345908ecbb27c947b6035438e4f 100644 (file)
@@ -200,6 +200,7 @@ extern int class_device_create_file(struct class_device *,
  * @node: for internal use by the driver core only.
  * @kobj: for internal use by the driver core only.
  * @devt_attr: for internal use by the driver core only.
+ * @groups: optional additional groups to be created
  * @dev: if set, a symlink to the struct device is created in the sysfs
  * directory for this struct class device.
  * @class_data: pointer to whatever you want to store here for this struct
@@ -228,6 +229,7 @@ struct class_device {
        struct device           * dev;          /* not necessary, but nice to have */
        void                    * class_data;   /* class-specific data */
        struct class_device     *parent;        /* parent of this child device, if there is one */
+       struct attribute_group  ** groups;      /* optional groups */
 
        void    (*release)(struct class_device *dev);
        int     (*uevent)(struct class_device *dev, char **envp,
index 01db7b88a2b1c626f668085364ca6181ba9ca641..309f9190a922db8f164536f91069f97dbe70d211 100644 (file)
@@ -506,6 +506,8 @@ struct net_device
 
        /* class/net/name entry */
        struct class_device     class_dev;
+       /* space for optional statistics and wireless sysfs groups */
+       struct attribute_group  *sysfs_groups[3];
 };
 
 #define        NETDEV_ALIGN            32
index eba99f375517ac5ea0e56058feb89f5238ac67af..7f4fea173fb1a5bf1c11eb4099f3558c01be2220 100644 (file)
@@ -712,6 +712,7 @@ struct sctp_chunk {
        __u8 tsn_gap_acked;     /* Is this chunk acked by a GAP ACK? */
        __s8 fast_retransmit;    /* Is this chunk fast retransmitted? */
        __u8 tsn_missing_report; /* Data chunk missing counter. */
+       __u8 data_accepted;     /* At least 1 chunk in this packet accepted */
 };
 
 void sctp_chunk_hold(struct sctp_chunk *);
index 4e0f0ec003f751a0aa91e2d8388365f042f072d9..b0f8da80d7d487665b2cbf9b4f34ac8b011ae64a 100644 (file)
@@ -148,12 +148,16 @@ int ptrace_may_attach(struct task_struct *task)
 int ptrace_attach(struct task_struct *task)
 {
        int retval;
-       task_lock(task);
+
        retval = -EPERM;
        if (task->pid <= 1)
-               goto bad;
+               goto out;
        if (task->tgid == current->tgid)
-               goto bad;
+               goto out;
+
+       write_lock_irq(&tasklist_lock);
+       task_lock(task);
+
        /* the same process cannot be attached many times */
        if (task->ptrace & PT_PTRACED)
                goto bad;
@@ -166,17 +170,15 @@ int ptrace_attach(struct task_struct *task)
                                      ? PT_ATTACHED : 0);
        if (capable(CAP_SYS_PTRACE))
                task->ptrace |= PT_PTRACE_CAP;
-       task_unlock(task);
 
-       write_lock_irq(&tasklist_lock);
        __ptrace_link(task, current);
-       write_unlock_irq(&tasklist_lock);
 
        force_sig_specific(SIGSTOP, task);
-       return 0;
 
 bad:
+       write_unlock_irq(&tasklist_lock);
        task_unlock(task);
+out:
        return retval;
 }
 
@@ -417,21 +419,22 @@ int ptrace_request(struct task_struct *child, long request,
  */
 int ptrace_traceme(void)
 {
-       int ret;
+       int ret = -EPERM;
 
        /*
         * Are we already being traced?
         */
-       if (current->ptrace & PT_PTRACED)
-               return -EPERM;
-       ret = security_ptrace(current->parent, current);
-       if (ret)
-               return -EPERM;
-       /*
-        * Set the ptrace bit in the process ptrace flags.
-        */
-       current->ptrace |= PT_PTRACED;
-       return 0;
+       task_lock(current);
+       if (!(current->ptrace & PT_PTRACED)) {
+               ret = security_ptrace(current->parent, current);
+               /*
+                * Set the ptrace bit in the process ptrace flags.
+                */
+               if (!ret)
+                       current->ptrace |= PT_PTRACED;
+       }
+       task_unlock(current);
+       return ret;
 }
 
 /**
index b0b7f55c1edd38f2901cfc450ac638ca6589dd80..bfa4d8c333f7b727946e40c4c33e159d4fdbfe2f 100644 (file)
@@ -66,6 +66,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
        }
 
        if (is_multicast_ether_addr(dest)) {
+               br->statistics.multicast++;
                br_flood_forward(br, skb, !passedup);
                if (!passedup)
                        br_pass_frame_up(br, skb);
index 3bad1afc89fa48b505c001a24da094de18f14cab..9ab3cfa58466d2c9580a14dfb6b5b9014558a540 100644 (file)
@@ -3043,11 +3043,11 @@ void netdev_run_todo(void)
 
                switch(dev->reg_state) {
                case NETREG_REGISTERING:
-                       dev->reg_state = NETREG_REGISTERED;
                        err = netdev_register_sysfs(dev);
                        if (err)
                                printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
                                       dev->name, err);
+                       dev->reg_state = NETREG_REGISTERED;
                        break;
 
                case NETREG_UNREGISTERING:
index c12990c9c603ebb0403ffaab710139409cde81de..47a6fceb6771b00943ee9d845aff91c1ea9e5977 100644 (file)
@@ -29,7 +29,7 @@ static const char fmt_ulong[] = "%lu\n";
 
 static inline int dev_isalive(const struct net_device *dev) 
 {
-       return dev->reg_state == NETREG_REGISTERED;
+       return dev->reg_state <= NETREG_REGISTERED;
 }
 
 /* use same locking rules as GIF* ioctl's */
@@ -445,58 +445,33 @@ static struct class net_class = {
 
 void netdev_unregister_sysfs(struct net_device * net)
 {
-       struct class_device * class_dev = &(net->class_dev);
-
-       if (net->get_stats)
-               sysfs_remove_group(&class_dev->kobj, &netstat_group);
-
-#ifdef WIRELESS_EXT
-       if (net->get_wireless_stats || (net->wireless_handlers &&
-                       net->wireless_handlers->get_wireless_stats))
-               sysfs_remove_group(&class_dev->kobj, &wireless_group);
-#endif
-       class_device_del(class_dev);
-
+       class_device_del(&(net->class_dev));
 }
 
 /* Create sysfs entries for network device. */
 int netdev_register_sysfs(struct net_device *net)
 {
        struct class_device *class_dev = &(net->class_dev);
-       int ret;
+       struct attribute_group **groups = net->sysfs_groups;
 
+       class_device_initialize(class_dev);
        class_dev->class = &net_class;
        class_dev->class_data = net;
+       class_dev->groups = groups;
 
+       BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ);
        strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE);
-       if ((ret = class_device_register(class_dev)))
-               goto out;
 
-       if (net->get_stats &&
-           (ret = sysfs_create_group(&class_dev->kobj, &netstat_group)))
-               goto out_unreg; 
+       if (net->get_stats)
+               *groups++ = &netstat_group;
 
 #ifdef WIRELESS_EXT
-       if (net->get_wireless_stats || (net->wireless_handlers &&
-                       net->wireless_handlers->get_wireless_stats)) {
-               ret = sysfs_create_group(&class_dev->kobj, &wireless_group);
-               if (ret)
-                       goto out_cleanup;
-       }
-       return 0;
-out_cleanup:
-       if (net->get_stats)
-               sysfs_remove_group(&class_dev->kobj, &netstat_group);
-#else
-       return 0;
+       if (net->get_wireless_stats
+           || (net->wireless_handlers && net->wireless_handlers->get_wireless_stats))
+               *groups++ = &wireless_group;
 #endif
 
-out_unreg:
-       printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n",
-              net->name, ret);
-       class_device_unregister(class_dev);
-out:
-       return ret;
+       return class_device_add(class_dev);
 }
 
 int netdev_sysfs_init(void)
index 1ff7328b0e170bf137819ab03a76b3a4acdd9572..2e0ee8355c415d24d13644e20ecb6d8e837d10c1 100644 (file)
@@ -848,6 +848,7 @@ static int dccp_close_state(struct sock *sk)
 void dccp_close(struct sock *sk, long timeout)
 {
        struct sk_buff *skb;
+       int state;
 
        lock_sock(sk);
 
@@ -882,6 +883,11 @@ void dccp_close(struct sock *sk, long timeout)
        sk_stream_wait_close(sk, timeout);
 
 adjudge_to_death:
+       state = sk->sk_state;
+       sock_hold(sk);
+       sock_orphan(sk);
+       atomic_inc(sk->sk_prot->orphan_count);
+
        /*
         * It is the last release_sock in its life. It will remove backlog.
         */
@@ -894,8 +900,9 @@ adjudge_to_death:
        bh_lock_sock(sk);
        BUG_TRAP(!sock_owned_by_user(sk));
 
-       sock_hold(sk);
-       sock_orphan(sk);
+       /* Have we already been destroyed by a softirq or backlog? */
+       if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED)
+               goto out;
 
        /*
         * The last release_sock may have processed the CLOSE or RESET
@@ -915,12 +922,12 @@ adjudge_to_death:
 #endif
        }
 
-       atomic_inc(sk->sk_prot->orphan_count);
        if (sk->sk_state == DCCP_CLOSED)
                inet_csk_destroy_sock(sk);
 
        /* Otherwise, socket is reprieved until protocol close. */
 
+out:
        bh_unlock_sock(sk);
        local_bh_enable();
        sock_put(sk);
index 18d7fad474d72510e18177837912e5ff26ea4acb..c9026dbf4c9342cca958490aed1dec45aa36abfa 100644 (file)
@@ -337,7 +337,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb)
         *      Initialise the virtual path cache for the packet. It describes
         *      how the packet travels inside Linux networking.
         */ 
-       if (likely(skb->dst == NULL)) {
+       if (skb->dst == NULL) {
                int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
                                         skb->dev);
                if (unlikely(err)) {
index e0e9d1383c7c7e894a1019c3e2ce28785aea5dc4..b72fa55dfb84d114484bf6f7d1b4751449d9c4e3 100644 (file)
@@ -137,8 +137,8 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt,
                if (tp->snd_cwnd < tp->snd_cwnd_clamp) {
                        tp->snd_cwnd_cnt += ca->ai;
                        if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
-                               tp->snd_cwnd++;
                                tp->snd_cwnd_cnt -= tp->snd_cwnd;
+                               tp->snd_cwnd++;
                        }
                }
        }
index ecd288beca7ce84c57fe43feeffb7580d288ed93..3669cb953e6e7d49c05eb82c39ba1d43e80f9e3d 100644 (file)
@@ -1370,8 +1370,6 @@ static struct notifier_block nr_dev_notifier = {
 
 static struct net_device **dev_nr;
 
-static char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n";
-
 static int __init nr_proto_init(void)
 {
        int i;
@@ -1419,7 +1417,6 @@ static int __init nr_proto_init(void)
        }
                
        register_netdevice_notifier(&nr_dev_notifier);
-       printk(banner);
 
        ax25_protocol_register(AX25_P_NETROM, nr_route_frame);
        ax25_linkfail_register(nr_link_failed);
index ef4538ac84f0965edf03446b51466198a3809ad2..55564efccf1153fc051df3e8b9b26a7d515fa32c 100644 (file)
@@ -1469,8 +1469,6 @@ static struct notifier_block rose_dev_notifier = {
 
 static struct net_device **dev_rose;
 
-static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62 for AX25.037 Linux 2.4\n";
-
 static int __init rose_proto_init(void)
 {
        int i;
@@ -1519,7 +1517,6 @@ static int __init rose_proto_init(void)
 
        sock_register(&rose_family_ops);
        register_netdevice_notifier(&rose_dev_notifier);
-       printk(banner);
 
        ax25_protocol_register(AX25_P_ROSE, rose_route_frame);
        ax25_linkfail_register(rose_link_failed);
index 297b8951463e80293da9a029384607e5f094c121..cf0c767d43ae34835c5dd4ccca70e3629fcdd182 100644 (file)
@@ -149,6 +149,7 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
                /* This is the first chunk in the packet.  */
                chunk->singleton = 1;
                ch = (sctp_chunkhdr_t *) chunk->skb->data;
+               chunk->data_accepted = 0;
        }
 
         chunk->chunk_hdr = ch;
index 2b9a832b29a70bdbb46d0ce401d680c9a0121654..8cdba51ec0766a4d333ddc30e7ba4b756fe7802f 100644 (file)
@@ -636,8 +636,9 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
         */
         chunk->subh.cookie_hdr =
                (struct sctp_signed_cookie *)chunk->skb->data;
-       skb_pull(chunk->skb,
-                ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t));
+       if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
+                                        sizeof(sctp_chunkhdr_t)))
+               goto nomem;
 
        /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint
         * "Z" will reply with a COOKIE ACK chunk after building a TCB
@@ -965,7 +966,8 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,
         */
        chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data;
        paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
-       skb_pull(chunk->skb, paylen);
+       if (!pskb_pull(chunk->skb, paylen))
+               goto nomem;
 
        reply = sctp_make_heartbeat_ack(asoc, chunk,
                                        chunk->subh.hb_hdr, paylen);
@@ -1860,8 +1862,9 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
         * are in good shape.
         */
         chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data;
-       skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
-                sizeof(sctp_chunkhdr_t));
+       if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
+                                       sizeof(sctp_chunkhdr_t)))
+               goto nomem;
 
        /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie
         * of a duplicate COOKIE ECHO match the Verification Tags of the
@@ -5151,7 +5154,9 @@ static int sctp_eat_data(const struct sctp_association *asoc,
        int tmp;
        __u32 tsn;
        int account_value;
+       struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
        struct sock *sk = asoc->base.sk;
+       int rcvbuf_over = 0;
 
        data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data;
        skb_pull(chunk->skb, sizeof(sctp_datahdr_t));
@@ -5162,10 +5167,16 @@ static int sctp_eat_data(const struct sctp_association *asoc,
        /* ASSERT:  Now skb->data is really the user data.  */
 
        /*
-        * if we are established, and we have used up our receive
-        * buffer memory, drop the frame
-        */
-       if (asoc->state == SCTP_STATE_ESTABLISHED) {
+        * If we are established, and we have used up our receive buffer
+        * memory, think about droping the frame.
+        * Note that we have an opportunity to improve performance here.
+        * If we accept one chunk from an skbuff, we have to keep all the
+        * memory of that skbuff around until the chunk is read into user
+        * space. Therefore, once we accept 1 chunk we may as well accept all
+        * remaining chunks in the skbuff. The data_accepted flag helps us do
+        * that.
+        */
+       if ((asoc->state == SCTP_STATE_ESTABLISHED) && (!chunk->data_accepted)) {
                /*
                 * If the receive buffer policy is 1, then each
                 * association can allocate up to sk_rcvbuf bytes
@@ -5176,9 +5187,25 @@ static int sctp_eat_data(const struct sctp_association *asoc,
                        account_value = atomic_read(&asoc->rmem_alloc);
                else
                        account_value = atomic_read(&sk->sk_rmem_alloc);
-
-               if (account_value > sk->sk_rcvbuf)
-                       return SCTP_IERROR_IGNORE_TSN;
+               if (account_value > sk->sk_rcvbuf) {
+                       /*
+                        * We need to make forward progress, even when we are
+                        * under memory pressure, so we always allow the
+                        * next tsn after the ctsn ack point to be accepted.
+                        * This lets us avoid deadlocks in which we have to
+                        * drop frames that would otherwise let us drain the
+                        * receive queue.
+                        */
+                       if ((sctp_tsnmap_get_ctsn(map) + 1) != tsn)
+                               return SCTP_IERROR_IGNORE_TSN;
+
+                       /*
+                        * We're going to accept the frame but we should renege
+                        * to make space for it. This will send us down that
+                        * path later in this function.
+                        */
+                       rcvbuf_over = 1;
+               }
        }
 
        /* Process ECN based congestion.
@@ -5226,6 +5253,7 @@ static int sctp_eat_data(const struct sctp_association *asoc,
        datalen -= sizeof(sctp_data_chunk_t);
 
        deliver = SCTP_CMD_CHUNK_ULP;
+       chunk->data_accepted = 1;
 
        /* Think about partial delivery. */
        if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) {
@@ -5242,7 +5270,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
         * large spill over.
         */
        if (!asoc->rwnd || asoc->rwnd_over ||
-           (datalen > asoc->rwnd + asoc->frag_point)) {
+           (datalen > asoc->rwnd + asoc->frag_point) ||
+           rcvbuf_over) {
 
                /* If this is the next TSN, consider reneging to make
                 * room.   Note: Playing nice with a confused sender.  A
@@ -5250,8 +5279,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
                 * space and in the future we may want to detect and
                 * do more drastic reneging.
                 */
-               if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) &&
-                   (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) {
+               if (sctp_tsnmap_has_gap(map) &&
+                   (sctp_tsnmap_get_ctsn(map) + 1) == tsn) {
                        SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn);
                        deliver = SCTP_CMD_RENEGE;
                } else {
index 75ef10408764247ec5999ad662dfc022a2660303..8bcca5676151b346d1fb1e9cc96d5dce1aa1340d 100644 (file)
@@ -366,9 +366,9 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
        /* SCTP_STATE_EMPTY */ \
        {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
        /* SCTP_STATE_CLOSED */ \
-       {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+       {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
        /* SCTP_STATE_COOKIE_WAIT */ \
-       {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+       {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
        /* SCTP_STATE_COOKIE_ECHOED */ \
        {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
        /* SCTP_STATE_ESTABLISHED */ \
@@ -380,7 +380,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
        /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
        {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
        /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-       {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+       {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 } /* TYPE_SCTP_ECN_ECNE */
 
 #define TYPE_SCTP_ECN_CWR { \
@@ -401,7 +401,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
        /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
        {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
        /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-       {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+       {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 } /* TYPE_SCTP_ECN_CWR */
 
 #define TYPE_SCTP_SHUTDOWN_COMPLETE { \
@@ -647,7 +647,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
        /* SCTP_STATE_EMPTY */ \
        {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
        /* SCTP_STATE_CLOSED */ \
-       {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+       {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
        /* SCTP_STATE_COOKIE_WAIT */ \
        {.fn = sctp_sf_do_prm_requestheartbeat,               \
         .name = "sctp_sf_do_prm_requestheartbeat"},          \
index 2080b2d28c98e97297fae432fc1a3a97a68f2646..575e556aeb3eb58c30dd80f86c6158defb3c664f 100644 (file)
@@ -279,6 +279,7 @@ static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq,
 static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag)
 {
        struct sk_buff *pos;
+       struct sk_buff *new = NULL;
        struct sctp_ulpevent *event;
        struct sk_buff *pnext, *last;
        struct sk_buff *list = skb_shinfo(f_frag)->frag_list;
@@ -297,11 +298,33 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *qu
         */
        if (last)
                last->next = pos;
-       else
-               skb_shinfo(f_frag)->frag_list = pos;
+       else {
+               if (skb_cloned(f_frag)) {
+                       /* This is a cloned skb, we can't just modify
+                        * the frag_list.  We need a new skb to do that.
+                        * Instead of calling skb_unshare(), we'll do it
+                        * ourselves since we need to delay the free.
+                        */
+                       new = skb_copy(f_frag, GFP_ATOMIC);
+                       if (!new)
+                               return NULL;    /* try again later */
+
+                       new->sk = f_frag->sk;
+
+                       skb_shinfo(new)->frag_list = pos;
+               } else
+                       skb_shinfo(f_frag)->frag_list = pos;
+       }
 
        /* Remove the first fragment from the reassembly queue.  */
        __skb_unlink(f_frag, queue);
+
+       /* if we did unshare, then free the old skb and re-assign */
+       if (new) {
+               kfree_skb(f_frag);
+               f_frag = new;
+       }
+
        while (pos) {
 
                pnext = pos->next;
index 56b3bed1108f4132b297eee6dbc5255ce81d028c..331c079f029b7c516fe4c32510d445defc3a6c53 100644 (file)
@@ -200,7 +200,11 @@ input_file() {
                        print_mtime "$1" >> ${output}
                        cat "$1"         >> ${output}
                else
-                       grep ^file "$1" | cut -d ' ' -f 3
+                       cat "$1" | while read type dir file perm ; do
+                               if [ "$type" == "file" ]; then
+                                       echo "$file \\";
+                               fi
+                       done
                fi
        elif [ -d "$1" ]; then
                dir_filelist "$1"
index a22cbedd3b3ec0738379c283d4fb2df5b33209ec..7f9d544f9b6c07339021bdb80762feeb7b95f9bf 100644 (file)
 # $4 - patchlevel
 
 
-cat << EOF
+test ! -r $2/Makefile -o -O $2/Makefile || exit 0
+echo "  GEN     $2/Makefile"
+
+cat << EOF > $2/Makefile
 # Automatically generated by $0: don't edit
 
 VERSION = $3
index cd00e9f0758995e5d027ff9dc96835256b10860c..b36e884f5f967dae578955bc0df37e8b4cb1c7e0 100644 (file)
@@ -487,14 +487,14 @@ static int strrcmp(const char *s, const char *sub)
  *   atsym   =__param*
  *
  * Pattern 2:
- *   Many drivers utilise a *_driver container with references to
+ *   Many drivers utilise a *driver container with references to
  *   add, remove, probe functions etc.
  *   These functions may often be marked __init and we do not want to
  *   warn here.
  *   the pattern is identified by:
  *   tosec   = .init.text | .exit.text | .init.data
  *   fromsec = .data
- *   atsym = *_driver, *_template, *_sht, *_ops, *_probe, *probe_one
+ *   atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one
  **/
 static int secref_whitelist(const char *tosec, const char *fromsec,
                            const char *atsym)
@@ -502,7 +502,7 @@ static int secref_whitelist(const char *tosec, const char *fromsec,
        int f1 = 1, f2 = 1;
        const char **s;
        const char *pat2sym[] = {
-               "_driver",
+               "driver",
                "_template", /* scsi uses *_template a lot */
                "_sht",      /* scsi also used *_sht to some extent */
                "_ops",
@@ -709,10 +709,17 @@ static void check_sec_ref(struct module *mod, const char *modname,
                for (rela = start; rela < stop; rela++) {
                        Elf_Rela r;
                        const char *secname;
+                       unsigned int r_sym;
                        r.r_offset = TO_NATIVE(rela->r_offset);
-                       r.r_info   = TO_NATIVE(rela->r_info);
+                       if (hdr->e_ident[EI_CLASS] == ELFCLASS64 &&
+                           hdr->e_machine == EM_MIPS) {
+                               r_sym = ELF64_MIPS_R_SYM(rela->r_info);
+                               r_sym = TO_NATIVE(r_sym);
+                       } else {
+                               r_sym = ELF_R_SYM(TO_NATIVE(rela->r_info));
+                       }
                        r.r_addend = TO_NATIVE(rela->r_addend);
-                       sym = elf->symtab_start + ELF_R_SYM(r.r_info);
+                       sym = elf->symtab_start + r_sym;
                        /* Skip special sections */
                        if (sym->st_shndx >= SHN_LORESERVE)
                                continue;
index b14255c72a375edcfe6da9f61589ba2e433deb94..89b96c6d8ef587f3995d9975ca67e9ee2971ea18 100644 (file)
 #define ELF_R_TYPE  ELF64_R_TYPE
 #endif
 
+/* The 64-bit MIPS ELF ABI uses an unusual reloc format. */
+typedef struct
+{
+  Elf32_Word    r_sym;         /* Symbol index */
+  unsigned char r_ssym;                /* Special symbol for 2nd relocation */
+  unsigned char r_type3;       /* 3rd relocation type */
+  unsigned char r_type2;       /* 2nd relocation type */
+  unsigned char r_type1;       /* 1st relocation type */
+} _Elf64_Mips_R_Info;
+
+typedef union
+{
+  Elf64_Xword  r_info_number;
+  _Elf64_Mips_R_Info r_info_fields;
+} _Elf64_Mips_R_Info_union;
+
+#define ELF64_MIPS_R_SYM(i) \
+  ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
+
 #if KERNEL_ELFDATA != HOST_ELFDATA
 
 static inline void __endian(const void *src, void *dest, unsigned int size)