]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'fixes-jgarzik' of git://git.kernel.org/pub/scm/linux/kernel/git/linvill...
authorJeff Garzik <jeff@garzik.org>
Fri, 18 Jan 2008 19:40:47 +0000 (14:40 -0500)
committerJeff Garzik <jeff@garzik.org>
Fri, 18 Jan 2008 19:40:47 +0000 (14:40 -0500)
38 files changed:
Documentation/local_ops.txt
arch/alpha/math-emu/math.c
arch/cris/arch-v10/vmlinux.lds.S
arch/sparc64/kernel/sun4v_tlb_miss.S
arch/sparc64/kernel/traps.c
arch/x86/kernel/traps_32.c
arch/x86/kernel/traps_64.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_userspace.c
drivers/input/mouse/alps.c
drivers/input/mouse/lifebook.c
drivers/input/mouse/psmouse-base.c
drivers/input/mousedev.c
drivers/input/touchscreen/usbtouchscreen.c
drivers/media/video/saa7134/saa7134-core.c
drivers/net/Kconfig
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
drivers/net/bonding/bonding.h
drivers/net/e1000/e1000_main.c
drivers/net/e1000e/netdev.c
drivers/net/ipg.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/niu.c
drivers/pnp/pnpacpi/rsparser.c
drivers/video/modedb.c
fs/hfs/btree.c
fs/jbd/transaction.c
fs/sysfs/dir.c
include/asm-cris/page.h
include/linux/workqueue.h
kernel/kmod.c
kernel/lockdep.c
kernel/workqueue.c
mm/memory.c
mm/page_alloc.c

index 1a45f11e645e978f445ba7396f0c5411a1695e06..4269a1105b378fafcc689435a2531b9d9d4287db 100644 (file)
@@ -45,29 +45,6 @@ long fails. The definition looks like :
 typedef struct { atomic_long_t a; } local_t;
 
 
-* Rules to follow when using local atomic operations
-
-- Variables touched by local ops must be per cpu variables.
-- _Only_ the CPU owner of these variables must write to them.
-- This CPU can use local ops from any context (process, irq, softirq, nmi, ...)
-  to update its local_t variables.
-- Preemption (or interrupts) must be disabled when using local ops in
-  process context to   make sure the process won't be migrated to a
-  different CPU between getting the per-cpu variable and doing the
-  actual local op.
-- When using local ops in interrupt context, no special care must be
-  taken on a mainline kernel, since they will run on the local CPU with
-  preemption already disabled. I suggest, however, to explicitly
-  disable preemption anyway to make sure it will still work correctly on
-  -rt kernels.
-- Reading the local cpu variable will provide the current copy of the
-  variable.
-- Reads of these variables can be done from any CPU, because updates to
-  "long", aligned, variables are always atomic. Since no memory
-  synchronization is done by the writer CPU, an outdated copy of the
-  variable can be read when reading some _other_ cpu's variables.
-
-
 * Rules to follow when using local atomic operations
 
 - Variables touched by local ops must be per cpu variables.
index ae79dd970b021ff84ca59d3b5f6b14a4b19ce25f..58c2669a1dd4fa431f32ecbe8416c24a540525ba 100644 (file)
@@ -225,7 +225,7 @@ alpha_fp_emul (unsigned long pc)
                                FP_UNPACK_SP(SB, &vb);
                                DR_c = DB_c;
                                DR_s = DB_s;
-                               DR_e = DB_e;
+                               DR_e = DB_e + (1024 - 128);
                                DR_f = SB_f << (52 - 23);
                                goto pack_d;
                        }
index 9859d49d088bfb0c714bc71180279df06babf8b6..97a7876ed6819061fec0a9be042f60be1d260d77 100644 (file)
@@ -9,7 +9,8 @@
  */    
 
 #include <asm-generic/vmlinux.lds.h>
-               
+#include <asm/page.h>
+
 jiffies = jiffies_64;
 SECTIONS
 {
@@ -23,7 +24,7 @@ SECTIONS
        _stext = .;
        __stext = .;
        .text : {
-               *(.text)
+               TEXT_TEXT
                SCHED_TEXT
                LOCK_TEXT
                *(.fixup)
@@ -49,10 +50,10 @@ SECTIONS
        __edata = . ;                 /* End of data section */
        _edata = . ;
 
-       . = ALIGN(8192);              /* init_task and stack, must be aligned */
+       . = ALIGN(PAGE_SIZE);   /* init_task and stack, must be aligned */
        .data.init_task : { *(.data.init_task) }
 
-       . = ALIGN(8192);              /* Init code and data */
+       . = ALIGN(PAGE_SIZE);   /* Init code and data */
        __init_begin = .;
        .init.text : { 
                   _sinittext = .;
@@ -66,13 +67,7 @@ SECTIONS
        __setup_end = .;
        .initcall.init : {
                __initcall_start = .;
-               *(.initcall1.init);
-               *(.initcall2.init);
-               *(.initcall3.init);
-               *(.initcall4.init);
-               *(.initcall5.init);
-               *(.initcall6.init);
-               *(.initcall7.init);
+               INITCALLS
                __initcall_end = .;     
        }
 
@@ -88,16 +83,18 @@ SECTIONS
                __initramfs_start = .;
                *(.init.ramfs)
                __initramfs_end = .;
-               /* We fill to the next page, so we can discard all init
-                  pages without needing to consider what payload might be
-                  appended to the kernel image.  */
-               FILL (0); 
-               . = ALIGN (8192);
        }
 #endif
-       
        __vmlinux_end = .;            /* last address of the physical file */
-       __init_end = .;
+
+       /*
+        * We fill to the next page, so we can discard all init
+        * pages without needing to consider what payload might be
+        * appended to the kernel image.
+        */
+       . = ALIGN(PAGE_SIZE);
+
+       __init_end = .;
 
        __data_end = . ;              /* Move to _edata ? */
        __bss_start = .;              /* BSS */
index 9871dbb1ab42579a10e22e892a4049711bb3e941..fd9430562e0be4c20f558fd9a903db6e2f212013 100644 (file)
@@ -215,6 +215,7 @@ sun4v_itlb_error:
 
 1:     ba,pt   %xcc, etrap
 2:      or     %g7, %lo(2b), %g7
+       mov     %l4, %o1
        call    sun4v_itlb_error_report
         add    %sp, PTREGS_OFF, %o0
 
@@ -241,6 +242,7 @@ sun4v_dtlb_error:
 
 1:     ba,pt   %xcc, etrap
 2:      or     %g7, %lo(2b), %g7
+       mov     %l4, %o1
        call    sun4v_dtlb_error_report
         add    %sp, PTREGS_OFF, %o0
 
index 04998388259fcfe7597843c0dd9cb72166b448db..2b6abf633343f3e76df9d08711e8593b9507d604 100644 (file)
@@ -1950,6 +1950,8 @@ void sun4v_itlb_error_report(struct pt_regs *regs, int tl)
        printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n",
               regs->tpc, tl);
        print_symbol(KERN_EMERG "SUN4V-ITLB: TPC<%s>\n", regs->tpc);
+       printk(KERN_EMERG "SUN4V-ITLB: O7[%lx]\n", regs->u_regs[UREG_I7]);
+       print_symbol(KERN_EMERG "SUN4V-ITLB: O7<%s>\n", regs->u_regs[UREG_I7]);
        printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] "
               "pte[%lx] error[%lx]\n",
               sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx,
@@ -1971,6 +1973,8 @@ void sun4v_dtlb_error_report(struct pt_regs *regs, int tl)
        printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n",
               regs->tpc, tl);
        print_symbol(KERN_EMERG "SUN4V-DTLB: TPC<%s>\n", regs->tpc);
+       printk(KERN_EMERG "SUN4V-DTLB: O7[%lx]\n", regs->u_regs[UREG_I7]);
+       print_symbol(KERN_EMERG "SUN4V-DTLB: O7<%s>\n", regs->u_regs[UREG_I7]);
        printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] "
               "pte[%lx] error[%lx]\n",
               sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx,
index c88bbffcaa03ed9485dddc721f6bf611c6982ae2..02d1e1e58e819211fed1813113d945b0baeb0e9d 100644 (file)
@@ -541,6 +541,7 @@ fastcall void do_##name(struct pt_regs * regs, long error_code) \
        info.si_errno = 0; \
        info.si_code = sicode; \
        info.si_addr = (void __user *)siaddr; \
+       trace_hardirqs_fixup(); \
        if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
                                                == NOTIFY_STOP) \
                return; \
index d11525ad81b40676cd99736cf729329993b580ab..cc68b92316cd3813fc049874562f28eed81d9c60 100644 (file)
@@ -635,6 +635,7 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
        info.si_errno = 0; \
        info.si_code = sicode; \
        info.si_addr = (void __user *)siaddr; \
+       trace_hardirqs_fixup(); \
        if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
                                                        == NOTIFY_STOP) \
                return; \
index 1bba99747f5b3da806fea25aa991d3ac151673be..5d3a04ba6ad2c38aaf18d443b508511206bfac0c 100644 (file)
@@ -603,5 +603,9 @@ MODULE_DESCRIPTION ("'cpufreq_conservative' - A dynamic cpufreq governor for "
                "optimised for use in a battery environment");
 MODULE_LICENSE ("GPL");
 
+#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
+fs_initcall(cpufreq_gov_dbs_init);
+#else
 module_init(cpufreq_gov_dbs_init);
+#endif
 module_exit(cpufreq_gov_dbs_exit);
index 369f44595150f7e568fff7802d8047ca645f0ffd..d2af20dda3827919d218d9dc592aeb8ca0fd8f03 100644 (file)
@@ -610,6 +610,9 @@ MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for "
                    "Low Latency Frequency Transition capable processors");
 MODULE_LICENSE("GPL");
 
+#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
+fs_initcall(cpufreq_gov_dbs_init);
+#else
 module_init(cpufreq_gov_dbs_init);
+#endif
 module_exit(cpufreq_gov_dbs_exit);
-
index 51bedab6c808da57dd2b26e896021613d2540655..f8cdde4bf6cd86030a8f829d00fdac862d5847f2 100644 (file)
@@ -231,5 +231,9 @@ MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>, Russell King <rmk@arm.linux.
 MODULE_DESCRIPTION ("CPUfreq policy governor 'userspace'");
 MODULE_LICENSE ("GPL");
 
+#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
 fs_initcall(cpufreq_gov_userspace_init);
+#else
+module_init(cpufreq_gov_userspace_init);
+#endif
 module_exit(cpufreq_gov_userspace_exit);
index 2b5ed119c9a90e9b5d66245eebfe9fcc1e11a197..b346a3b418ea78d60d4a129b911d7fe7a37035cb 100644 (file)
@@ -54,7 +54,7 @@ static const struct alps_model_info alps_model_data[] = {
        { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
        { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
        { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
-       { { 0x73, 0x02, 0x50 }, 0xcf, 0xff, ALPS_FW_BK_1 } /* Dell Vostro 1400 */
+       { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */
 };
 
 /*
index 9ec57d80186e43b7f776ec3b9aed0c7c385ce625..df81b0aaa9f88911fa335d506f284161c5e24d70 100644 (file)
@@ -225,8 +225,13 @@ static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolu
 
 static void lifebook_disconnect(struct psmouse *psmouse)
 {
+       struct lifebook_data *priv = psmouse->private;
+
        psmouse_reset(psmouse);
-       kfree(psmouse->private);
+       if (priv) {
+               input_unregister_device(priv->dev2);
+               kfree(priv);
+       }
        psmouse->private = NULL;
 }
 
index 21a9c0b69a1f461befa62691f0a35baaa99641a6..b8628252e10c5832c0f61c88244200064f5de169 100644 (file)
@@ -1247,6 +1247,8 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
  err_pt_deactivate:
        if (parent && parent->pt_deactivate)
                parent->pt_deactivate(parent);
+       input_unregister_device(psmouse->dev);
+       input_dev = NULL; /* so we don't try to free it below */
  err_protocol_disconnect:
        if (psmouse->disconnect)
                psmouse->disconnect(psmouse);
index 78c3ea75da2a056b2799045c6c2329f5834a8705..be83516c776c8566b832c842ee40b7048129e6f1 100644 (file)
@@ -1029,6 +1029,15 @@ static const struct input_device_id mousedev_ids[] = {
                                BIT_MASK(ABS_PRESSURE) |
                                BIT_MASK(ABS_TOOL_WIDTH) },
        },      /* A touchpad */
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+                       INPUT_DEVICE_ID_MATCH_KEYBIT |
+                       INPUT_DEVICE_ID_MATCH_ABSBIT,
+               .evbit = { BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_SYN) },
+               .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
+               .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
+       },      /* Mouse-like device with absolute X and Y but ordinary
+                  clicks, like hp ILO2 High Performance mouse */
 
        { },    /* Terminating entry */
 };
index 19055e7381f8423b52e14763c43281b7672ccb09..63f9664a066f8465398f4526ca07ee4fbbbf4684 100644 (file)
@@ -11,6 +11,7 @@
  *  - DMC TSC-10/25
  *  - IRTOUCHSYSTEMS/UNITOP
  *  - IdealTEK URTC1000
+ *  - General Touch
  *  - GoTop Super_Q2/GogoPen/PenPower tablets
  *
  * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
@@ -50,7 +51,7 @@
 #include <linux/usb/input.h>
 
 
-#define DRIVER_VERSION         "v0.5"
+#define DRIVER_VERSION         "v0.6"
 #define DRIVER_AUTHOR          "Daniel Ritz <daniel.ritz@gmx.ch>"
 #define DRIVER_DESC            "USB Touchscreen Driver"
 
@@ -65,17 +66,21 @@ struct usbtouch_device_info {
        int min_yc, max_yc;
        int min_press, max_press;
        int rept_size;
-       int flags;
 
        void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len);
+
+       /*
+        * used to get the packet len. possible return values:
+        * > 0: packet len
+        * = 0: skip one byte
+        * < 0: -return value more bytes needed
+        */
        int  (*get_pkt_len) (unsigned char *pkt, int len);
+
        int  (*read_data)   (struct usbtouch_usb *usbtouch, unsigned char *pkt);
        int  (*init)        (struct usbtouch_usb *usbtouch);
 };
 
-#define USBTOUCH_FLG_BUFFER    0x01
-
-
 /* a usbtouch device */
 struct usbtouch_usb {
        unsigned char *data;
@@ -94,15 +99,6 @@ struct usbtouch_usb {
 };
 
 
-#if defined(CONFIG_TOUCHSCREEN_USB_EGALAX) || defined(CONFIG_TOUCHSCREEN_USB_ETURBO) || defined(CONFIG_TOUCHSCREEN_USB_IDEALTEK)
-#define MULTI_PACKET
-#endif
-
-#ifdef MULTI_PACKET
-static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
-                                   unsigned char *pkt, int len);
-#endif
-
 /* device types */
 enum {
        DEVTPYE_DUMMY = -1,
@@ -186,6 +182,10 @@ static struct usb_device_id usbtouch_devices[] = {
 
 #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
 
+#ifndef MULTI_PACKET
+#define MULTI_PACKET
+#endif
+
 #define EGALAX_PKT_TYPE_MASK           0xFE
 #define EGALAX_PKT_TYPE_REPT           0x80
 #define EGALAX_PKT_TYPE_DIAG           0x0A
@@ -323,6 +323,9 @@ static int itm_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
  * eTurboTouch part
  */
 #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO
+#ifndef MULTI_PACKET
+#define MULTI_PACKET
+#endif
 static int eturbo_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 {
        unsigned int shift;
@@ -461,6 +464,9 @@ static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
  * IdealTEK URTC1000 Part
  */
 #ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK
+#ifndef MULTI_PACKET
+#define MULTI_PACKET
+#endif
 static int idealtek_get_pkt_len(unsigned char *buf, int len)
 {
        if (buf[0] & 0x80)
@@ -525,6 +531,11 @@ static int gotop_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 /*****************************************************************************
  * the different device descriptors
  */
+#ifdef MULTI_PACKET
+static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
+                                  unsigned char *pkt, int len);
+#endif
+
 static struct usbtouch_device_info usbtouch_dev_info[] = {
 #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
        [DEVTYPE_EGALAX] = {
@@ -533,7 +544,6 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
                .min_yc         = 0x0,
                .max_yc         = 0x07ff,
                .rept_size      = 16,
-               .flags          = USBTOUCH_FLG_BUFFER,
                .process_pkt    = usbtouch_process_multi,
                .get_pkt_len    = egalax_get_pkt_len,
                .read_data      = egalax_read_data,
@@ -582,7 +592,6 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
                .min_yc         = 0x0,
                .max_yc         = 0x07ff,
                .rept_size      = 8,
-               .flags          = USBTOUCH_FLG_BUFFER,
                .process_pkt    = usbtouch_process_multi,
                .get_pkt_len    = eturbo_get_pkt_len,
                .read_data      = eturbo_read_data,
@@ -630,7 +639,6 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
                .min_yc         = 0x0,
                .max_yc         = 0x0fff,
                .rept_size      = 8,
-               .flags          = USBTOUCH_FLG_BUFFER,
                .process_pkt    = usbtouch_process_multi,
                .get_pkt_len    = idealtek_get_pkt_len,
                .read_data      = idealtek_read_data,
@@ -738,11 +746,14 @@ static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
        pos = 0;
        while (pos < buf_len) {
                /* get packet len */
-               pkt_len = usbtouch->type->get_pkt_len(buffer + pos, len);
+               pkt_len = usbtouch->type->get_pkt_len(buffer + pos,
+                                                       buf_len - pos);
 
-               /* unknown packet: drop everything */
-               if (unlikely(!pkt_len))
-                       goto out_flush_buf;
+               /* unknown packet: skip one byte */
+               if (unlikely(!pkt_len)) {
+                       pos++;
+                       continue;
+               }
 
                /* full packet: process */
                if (likely((pkt_len > 0) && (pkt_len <= buf_len - pos))) {
@@ -857,7 +868,7 @@ static int usbtouch_probe(struct usb_interface *intf,
        if (!usbtouch->data)
                goto out_free;
 
-       if (type->flags & USBTOUCH_FLG_BUFFER) {
+       if (type->get_pkt_len) {
                usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL);
                if (!usbtouch->buffer)
                        goto out_free_buffers;
index 4fd187ac9d7088378498f408c1b2efa2e732c142..4f0a9157ecb15d158d24ca8df77d6e6eb3a2855a 100644 (file)
@@ -1202,9 +1202,8 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
 
 static int saa7134_resume(struct pci_dev *pci_dev)
 {
-
        struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
-       unsigned int flags;
+       unsigned long flags;
 
        pci_restore_state(pci_dev);
        pci_set_power_state(pci_dev, PCI_D0);
index 114771a2a133888c6021dfce0aee9f7f2e83287f..9ae3166e3162fae25fb4235d7434b422da319753 100644 (file)
@@ -1976,9 +1976,6 @@ config E1000E
 
          <http://support.intel.com>
 
-         More specific information on configuring the driver is in
-         <file:Documentation/networking/e1000e.txt>.
-
          To compile this driver as a module, choose M here. The module
          will be called e1000e.
 
index 25b8dbf6cfd73c0193fd12add9da4d4906956926..b57bc9467dbe7a22d1c609fffa1ca5154daf9382 100644 (file)
@@ -979,7 +979,7 @@ static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct
 /*
  * Send learning packets after MAC address swap.
  *
- * Called with RTNL and bond->lock held for read.
+ * Called with RTNL and no other locks
  */
 static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
                                struct slave *slave2)
@@ -987,6 +987,8 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
        int slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
        struct slave *disabled_slave = NULL;
 
+       ASSERT_RTNL();
+
        /* fasten the change in the switch */
        if (SLAVE_IS_OK(slave1)) {
                alb_send_learning_packets(slave1, slave1->dev->dev_addr);
@@ -1031,7 +1033,7 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
  * a slave that has @slave's permanet address as its current address.
  * We'll make sure that that slave no longer uses @slave's permanent address.
  *
- * Caller must hold bond lock
+ * Caller must hold RTNL and no other locks
  */
 static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
 {
@@ -1542,7 +1544,12 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
        return 0;
 }
 
-/* Caller must hold bond lock for write */
+/*
+ * Remove slave from tlb and rlb hash tables, and fix up MAC addresses
+ * if necessary.
+ *
+ * Caller must hold RTNL and no other locks
+ */
 void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
 {
        if (bond->slave_cnt > 1) {
@@ -1601,9 +1608,6 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
        struct slave *swap_slave;
        int i;
 
-       if (new_slave)
-               ASSERT_RTNL();
-
        if (bond->curr_active_slave == new_slave) {
                return;
        }
@@ -1649,6 +1653,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
        write_unlock_bh(&bond->curr_slave_lock);
        read_unlock(&bond->lock);
 
+       ASSERT_RTNL();
+
        /* curr_active_slave must be set before calling alb_swap_mac_addr */
        if (swap_slave) {
                /* swap mac address */
@@ -1659,12 +1665,11 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
                                       bond->alb_info.rlb_enabled);
        }
 
-       read_lock(&bond->lock);
-
        if (swap_slave) {
                alb_fasten_mac_swap(bond, swap_slave, new_slave);
+               read_lock(&bond->lock);
        } else {
-               /* fasten bond mac on new current slave */
+               read_lock(&bond->lock);
                alb_send_learning_packets(new_slave, bond->dev->dev_addr);
        }
 
index b0b26036266b51fc381e5e2eede8cf3de2cc270d..49a198206e3de901a74f34fc40694bb056ad922c 100644 (file)
@@ -1746,7 +1746,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
                 * has been cleared (if our_slave == old_current),
                 * but before a new active slave is selected.
                 */
+               write_unlock_bh(&bond->lock);
                bond_alb_deinit_slave(bond, slave);
+               write_lock_bh(&bond->lock);
        }
 
        if (oldcurrent == slave) {
@@ -1905,6 +1907,12 @@ static int bond_release_all(struct net_device *bond_dev)
                slave_dev = slave->dev;
                bond_detach_slave(bond, slave);
 
+               /* now that the slave is detached, unlock and perform
+                * all the undo steps that should not be called from
+                * within a lock.
+                */
+               write_unlock_bh(&bond->lock);
+
                if ((bond->params.mode == BOND_MODE_TLB) ||
                    (bond->params.mode == BOND_MODE_ALB)) {
                        /* must be called only after the slave
@@ -1915,12 +1923,6 @@ static int bond_release_all(struct net_device *bond_dev)
 
                bond_compute_features(bond);
 
-               /* now that the slave is detached, unlock and perform
-                * all the undo steps that should not be called from
-                * within a lock.
-                */
-               write_unlock_bh(&bond->lock);
-
                bond_destroy_slave_symlinks(bond_dev, slave_dev);
                bond_del_vlans_from_slave(bond, slave_dev);
 
@@ -2384,7 +2386,9 @@ void bond_mii_monitor(struct work_struct *work)
                rtnl_lock();
                read_lock(&bond->lock);
                __bond_mii_monitor(bond, 1);
-               rtnl_unlock();
+               read_unlock(&bond->lock);
+               rtnl_unlock();  /* might sleep, hold no other locks */
+               read_lock(&bond->lock);
        }
 
        delay = ((bond->params.miimon * HZ) / 1000) ? : 1;
@@ -3399,9 +3403,7 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond
        case NETDEV_CHANGENAME:
                return bond_event_changename(event_bond);
        case NETDEV_UNREGISTER:
-               /*
-                * TODO: remove a bond from the list?
-                */
+               bond_release_all(event_bond->dev);
                break;
        default:
                break;
@@ -4540,18 +4542,27 @@ static void bond_free_all(void)
 
 /*
  * Convert string input module parms.  Accept either the
- * number of the mode or its string name.
+ * number of the mode or its string name.  A bit complicated because
+ * some mode names are substrings of other names, and calls from sysfs
+ * may have whitespace in the name (trailing newlines, for example).
  */
-int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
+int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl)
 {
-       int i;
+       int mode = -1, i, rv;
+       char modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
+
+       rv = sscanf(buf, "%d", &mode);
+       if (!rv) {
+               rv = sscanf(buf, "%20s", modestr);
+               if (!rv)
+                       return -1;
+       }
 
        for (i = 0; tbl[i].modename; i++) {
-               if ((isdigit(*mode_arg) &&
-                    tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
-                   (strcmp(mode_arg, tbl[i].modename) == 0)) {
+               if (mode == tbl[i].mode)
+                       return tbl[i].mode;
+               if (strcmp(modestr, tbl[i].modename) == 0)
                        return tbl[i].mode;
-               }
        }
 
        return -1;
@@ -4865,9 +4876,22 @@ static struct lock_class_key bonding_netdev_xmit_lock_key;
 int bond_create(char *name, struct bond_params *params, struct bonding **newbond)
 {
        struct net_device *bond_dev;
+       struct bonding *bond, *nxt;
        int res;
 
        rtnl_lock();
+       down_write(&bonding_rwsem);
+
+       /* Check to see if the bond already exists. */
+       list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+               if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
+                       printk(KERN_ERR DRV_NAME
+                              ": cannot add bond %s; it already exists\n",
+                              name);
+                       res = -EPERM;
+                       goto out_rtnl;
+               }
+
        bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
                                ether_setup);
        if (!bond_dev) {
@@ -4906,10 +4930,12 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
 
        netif_carrier_off(bond_dev);
 
+       up_write(&bonding_rwsem);
        rtnl_unlock(); /* allows sysfs registration of net device */
        res = bond_create_sysfs_entry(bond_dev->priv);
        if (res < 0) {
                rtnl_lock();
+               down_write(&bonding_rwsem);
                goto out_bond;
        }
 
@@ -4920,6 +4946,7 @@ out_bond:
 out_netdev:
        free_netdev(bond_dev);
 out_rtnl:
+       up_write(&bonding_rwsem);
        rtnl_unlock();
        return res;
 }
@@ -4940,6 +4967,9 @@ static int __init bonding_init(void)
 #ifdef CONFIG_PROC_FS
        bond_create_proc_dir();
 #endif
+
+       init_rwsem(&bonding_rwsem);
+
        for (i = 0; i < max_bonds; i++) {
                res = bond_create(NULL, &bonding_defaults, NULL);
                if (res)
index 11b76b352415f6dedad302133b97e952728032dd..90a1f31e8e637bd104a09490b8d05db80b0b5acc 100644 (file)
@@ -109,11 +109,10 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
 {
        char command[IFNAMSIZ + 1] = {0, };
        char *ifname;
-       int res = count;
+       int rv, res = count;
        struct bonding *bond;
        struct bonding *nxt;
 
-       down_write(&(bonding_rwsem));
        sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
        ifname = command + 1;
        if ((strlen(command) <= 1) ||
@@ -121,39 +120,28 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
                goto err_no_cmd;
 
        if (command[0] == '+') {
-
-               /* Check to see if the bond already exists. */
-               list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
-                       if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
-                               printk(KERN_ERR DRV_NAME
-                                       ": cannot add bond %s; it already exists\n",
-                                       ifname);
-                               res = -EPERM;
-                               goto out;
-                       }
-
                printk(KERN_INFO DRV_NAME
                        ": %s is being created...\n", ifname);
-               if (bond_create(ifname, &bonding_defaults, &bond)) {
-                       printk(KERN_INFO DRV_NAME
-                       ": %s interface already exists. Bond creation failed.\n",
-                       ifname);
-                       res = -EPERM;
+               rv = bond_create(ifname, &bonding_defaults, &bond);
+               if (rv) {
+                       printk(KERN_INFO DRV_NAME ": Bond creation failed.\n");
+                       res = rv;
                }
                goto out;
        }
 
        if (command[0] == '-') {
+               rtnl_lock();
+               down_write(&bonding_rwsem);
+
                list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
                        if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
-                               rtnl_lock();
                                /* check the ref count on the bond's kobject.
                                 * If it's > expected, then there's a file open,
                                 * and we have to fail.
                                 */
                                if (atomic_read(&bond->dev->dev.kobj.kref.refcount)
                                                        > expected_refcount){
-                                       rtnl_unlock();
                                        printk(KERN_INFO DRV_NAME
                                                ": Unable remove bond %s due to open references.\n",
                                                ifname);
@@ -164,6 +152,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
                                        ": %s is being deleted...\n",
                                        bond->dev->name);
                                bond_destroy(bond);
+                               up_write(&bonding_rwsem);
                                rtnl_unlock();
                                goto out;
                        }
@@ -171,6 +160,8 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
                printk(KERN_ERR DRV_NAME
                        ": unable to delete non-existent bond %s\n", ifname);
                res = -ENODEV;
+               up_write(&bonding_rwsem);
+               rtnl_unlock();
                goto out;
        }
 
@@ -183,7 +174,6 @@ err_no_cmd:
         * get called forever, which is bad.
         */
 out:
-       up_write(&(bonding_rwsem));
        return res;
 }
 /* class attribute for bond_masters file.  This ends up in /sys/class/net */
@@ -271,6 +261,9 @@ static ssize_t bonding_store_slaves(struct device *d,
 
        /* Note:  We can't hold bond->lock here, as bond_create grabs it. */
 
+       rtnl_lock();
+       down_write(&(bonding_rwsem));
+
        sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
        ifname = command + 1;
        if ((strlen(command) <= 1) ||
@@ -336,12 +329,10 @@ static ssize_t bonding_store_slaves(struct device *d,
                                dev->mtu = bond->dev->mtu;
                        }
                }
-               rtnl_lock();
                res = bond_enslave(bond->dev, dev);
                bond_for_each_slave(bond, slave, i)
                        if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
                                slave->original_mtu = original_mtu;
-               rtnl_unlock();
                if (res) {
                        ret = res;
                }
@@ -359,12 +350,10 @@ static ssize_t bonding_store_slaves(struct device *d,
                if (dev) {
                        printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
                                bond->dev->name, dev->name);
-                       rtnl_lock();
                        if (bond->setup_by_slave)
                                res = bond_release_and_destroy(bond->dev, dev);
                        else
                                res = bond_release(bond->dev, dev);
-                       rtnl_unlock();
                        if (res) {
                                ret = res;
                                goto out;
@@ -389,6 +378,8 @@ err_no_cmd:
        ret = -EPERM;
 
 out:
+       up_write(&(bonding_rwsem));
+       rtnl_unlock();
        return ret;
 }
 
@@ -423,7 +414,7 @@ static ssize_t bonding_store_mode(struct device *d,
                goto out;
        }
 
-       new_value = bond_parse_parm((char *)buf, bond_mode_tbl);
+       new_value = bond_parse_parm(buf, bond_mode_tbl);
        if (new_value < 0)  {
                printk(KERN_ERR DRV_NAME
                       ": %s: Ignoring invalid mode value %.*s.\n",
@@ -478,7 +469,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
                goto out;
        }
 
-       new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl);
+       new_value = bond_parse_parm(buf, xmit_hashtype_tbl);
        if (new_value < 0)  {
                printk(KERN_ERR DRV_NAME
                       ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
@@ -518,7 +509,7 @@ static ssize_t bonding_store_arp_validate(struct device *d,
        int new_value;
        struct bonding *bond = to_bond(d);
 
-       new_value = bond_parse_parm((char *)buf, arp_validate_tbl);
+       new_value = bond_parse_parm(buf, arp_validate_tbl);
        if (new_value < 0) {
                printk(KERN_ERR DRV_NAME
                       ": %s: Ignoring invalid arp_validate value %s\n",
@@ -941,7 +932,7 @@ static ssize_t bonding_store_lacp(struct device *d,
                goto out;
        }
 
-       new_value = bond_parse_parm((char *)buf, bond_lacp_tbl);
+       new_value = bond_parse_parm(buf, bond_lacp_tbl);
 
        if ((new_value == 1) || (new_value == 0)) {
                bond->params.lacp_fast = new_value;
@@ -1075,7 +1066,10 @@ static ssize_t bonding_store_primary(struct device *d,
        struct slave *slave;
        struct bonding *bond = to_bond(d);
 
-       write_lock_bh(&bond->lock);
+       rtnl_lock();
+       read_lock(&bond->lock);
+       write_lock_bh(&bond->curr_slave_lock);
+
        if (!USES_PRIMARY(bond->params.mode)) {
                printk(KERN_INFO DRV_NAME
                       ": %s: Unable to set primary slave; %s is in mode %d\n",
@@ -1109,8 +1103,8 @@ static ssize_t bonding_store_primary(struct device *d,
                }
        }
 out:
-       write_unlock_bh(&bond->lock);
-
+       write_unlock_bh(&bond->curr_slave_lock);
+       read_unlock(&bond->lock);
        rtnl_unlock();
 
        return count;
@@ -1190,7 +1184,8 @@ static ssize_t bonding_store_active_slave(struct device *d,
        struct bonding *bond = to_bond(d);
 
        rtnl_lock();
-       write_lock_bh(&bond->lock);
+       read_lock(&bond->lock);
+       write_lock_bh(&bond->curr_slave_lock);
 
        if (!USES_PRIMARY(bond->params.mode)) {
                printk(KERN_INFO DRV_NAME
@@ -1247,7 +1242,8 @@ static ssize_t bonding_store_active_slave(struct device *d,
                }
        }
 out:
-       write_unlock_bh(&bond->lock);
+       write_unlock_bh(&bond->curr_slave_lock);
+       read_unlock(&bond->lock);
        rtnl_unlock();
 
        return count;
@@ -1418,8 +1414,6 @@ int bond_create_sysfs(void)
        int ret = 0;
        struct bonding *firstbond;
 
-       init_rwsem(&bonding_rwsem);
-
        /* get the netdev class pointer */
        firstbond = container_of(bond_dev_list.next, struct bonding, bond_list);
        if (!firstbond)
index e1e4734e23ce7191d0ddb23809c5a710bafa3190..6d83be49899a496fe5125ad3e95d081634a7c269 100644 (file)
@@ -141,6 +141,8 @@ struct bond_parm_tbl {
        int mode;
 };
 
+#define BOND_MAX_MODENAME_LEN 20
+
 struct vlan_entry {
        struct list_head vlan_list;
        __be32 vlan_ip;
@@ -314,7 +316,7 @@ void bond_mii_monitor(struct work_struct *);
 void bond_loadbalance_arp_mon(struct work_struct *);
 void bond_activebackup_arp_mon(struct work_struct *);
 void bond_set_mode_ops(struct bonding *bond, int mode);
-int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
+int bond_parse_parm(const char *mode_arg, struct bond_parm_tbl *tbl);
 void bond_select_active_slave(struct bonding *bond);
 void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
 void bond_register_arp(struct bonding *);
index 13d57b0a88fa0936a02273b8e292baa6262ecca8..0c9a6f7104d2803b4072f5e6bf788df0a98e3aca 100644 (file)
@@ -3919,7 +3919,7 @@ e1000_clean(struct napi_struct *napi, int budget)
 {
        struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
        struct net_device *poll_dev = adapter->netdev;
-       int work_done = 0;
+       int tx_cleaned = 0, work_done = 0;
 
        /* Must NOT use netdev_priv macro here. */
        adapter = poll_dev->priv;
@@ -3929,14 +3929,17 @@ e1000_clean(struct napi_struct *napi, int budget)
         * simultaneously.  A failure obtaining the lock means
         * tx_ring[0] is currently being cleaned anyway. */
        if (spin_trylock(&adapter->tx_queue_lock)) {
-               e1000_clean_tx_irq(adapter,
-                                  &adapter->tx_ring[0]);
+               tx_cleaned = e1000_clean_tx_irq(adapter,
+                                               &adapter->tx_ring[0]);
                spin_unlock(&adapter->tx_queue_lock);
        }
 
        adapter->clean_rx(adapter, &adapter->rx_ring[0],
                          &work_done, budget);
 
+       if (tx_cleaned)
+               work_done = budget;
+
        /* If budget not fully consumed, exit the polling mode */
        if (work_done < budget) {
                if (likely(adapter->itr_setting & 3))
index 4a6fc745377637e85a5784524bd7da58106cd7e5..2ab3bfbb8a63380b2505756fdfe301374123b569 100644 (file)
@@ -1384,7 +1384,7 @@ static int e1000_clean(struct napi_struct *napi, int budget)
 {
        struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
        struct net_device *poll_dev = adapter->netdev;
-       int work_done = 0;
+       int tx_cleaned = 0, work_done = 0;
 
        /* Must NOT use netdev_priv macro here. */
        adapter = poll_dev->priv;
@@ -1394,12 +1394,15 @@ static int e1000_clean(struct napi_struct *napi, int budget)
         * simultaneously.  A failure obtaining the lock means
         * tx_ring is currently being cleaned anyway. */
        if (spin_trylock(&adapter->tx_queue_lock)) {
-               e1000_clean_tx_irq(adapter);
+               tx_cleaned = e1000_clean_tx_irq(adapter);
                spin_unlock(&adapter->tx_queue_lock);
        }
 
        adapter->clean_rx(adapter, &work_done, budget);
 
+       if (tx_cleaned)
+               work_done = budget;
+
        /* If budget not fully consumed, exit the polling mode */
        if (work_done < budget) {
                if (adapter->itr_setting & 3)
index dbd23bb65d1ec4cc634704f75db7e35f199cf06b..50f0c17451b10cccbafbb77d7c03bc55d9a70f91 100644 (file)
@@ -857,21 +857,14 @@ static void init_tfdlist(struct net_device *dev)
 static void ipg_nic_txfree(struct net_device *dev)
 {
        struct ipg_nic_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->ioaddr;
-       unsigned int curr;
-       u64 txd_map;
-       unsigned int released, pending;
-
-       txd_map = (u64)sp->txd_map;
-       curr = ipg_r32(TFD_LIST_PTR_0) -
-               do_div(txd_map, sizeof(struct ipg_tx)) - 1;
+       unsigned int released, pending, dirty;
 
        IPG_DEBUG_MSG("_nic_txfree\n");
 
        pending = sp->tx_current - sp->tx_dirty;
+       dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH;
 
        for (released = 0; released < pending; released++) {
-               unsigned int dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH;
                struct sk_buff *skb = sp->TxBuff[dirty];
                struct ipg_tx *txfd = sp->txd + dirty;
 
@@ -882,11 +875,8 @@ static void ipg_nic_txfree(struct net_device *dev)
                 * If the TFDDone bit is set, free the associated
                 * buffer.
                 */
-               if (dirty == curr)
-                       break;
-
-               /* Setup TFDDONE for compatible issue. */
-               txfd->tfc |= cpu_to_le64(IPG_TFC_TFDDONE);
+               if (!(txfd->tfc & cpu_to_le64(IPG_TFC_TFDDONE)))
+                        break;
 
                /* Free the transmit buffer. */
                if (skb) {
@@ -898,6 +888,7 @@ static void ipg_nic_txfree(struct net_device *dev)
 
                        sp->TxBuff[dirty] = NULL;
                }
+               dirty = (dirty + 1) % IPG_TFDLIST_LENGTH;
        }
 
        sp->tx_dirty += released;
@@ -1630,6 +1621,8 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
 #ifdef JUMBO_FRAME
        ipg_nic_rxrestore(dev);
 #endif
+       spin_lock(&sp->lock);
+
        /* Get interrupt source information, and acknowledge
         * some (i.e. TxDMAComplete, RxDMAComplete, RxEarly,
         * IntRequested, MacControlFrame, LinkEvent) interrupts
@@ -1647,9 +1640,7 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
        handled = 1;
 
        if (unlikely(!netif_running(dev)))
-               goto out;
-
-       spin_lock(&sp->lock);
+               goto out_unlock;
 
        /* If RFDListEnd interrupt, restore all used RFDs. */
        if (status & IPG_IS_RFD_LIST_END) {
@@ -1733,9 +1724,9 @@ out_enable:
        ipg_w16(IPG_IE_TX_DMA_COMPLETE | IPG_IE_RX_DMA_COMPLETE |
                IPG_IE_HOST_ERROR | IPG_IE_INT_REQUESTED | IPG_IE_TX_COMPLETE |
                IPG_IE_LINK_EVENT | IPG_IE_UPDATE_STATS, INT_ENABLE);
-
+out_unlock:
        spin_unlock(&sp->lock);
-out:
+
        return IRQ_RETVAL(handled);
 }
 
@@ -1943,10 +1934,7 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
         */
        if (sp->tenmbpsmode)
                txfd->tfc |= cpu_to_le64(IPG_TFC_TXINDICATE);
-       else if (!((sp->tx_current - sp->tx_dirty + 1) >
-           IPG_FRAMESBETWEENTXDMACOMPLETES)) {
-               txfd->tfc |= cpu_to_le64(IPG_TFC_TXDMAINDICATE);
-       }
+       txfd->tfc |= cpu_to_le64(IPG_TFC_TXDMAINDICATE);
        /* Based on compilation option, determine if FCS is to be
         * appended to transmit frame by IPG.
         */
@@ -2003,7 +1991,7 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        ipg_w32(IPG_DC_TX_DMA_POLL_NOW, DMA_CTRL);
 
        if (sp->tx_current == (sp->tx_dirty + IPG_TFDLIST_LENGTH))
-               netif_wake_queue(dev);
+               netif_stop_queue(dev);
 
        spin_unlock_irqrestore(&sp->lock, flags);
 
index a56491617661cffef3fd4d370519a169b64da1fc..de3f45e4c5ae382b5e7feb9995d07a38e1e47fa9 100644 (file)
@@ -1468,13 +1468,16 @@ static int ixgbe_clean(struct napi_struct *napi, int budget)
        struct ixgbe_adapter *adapter = container_of(napi,
                                        struct ixgbe_adapter, napi);
        struct net_device *netdev = adapter->netdev;
-       int work_done = 0;
+       int tx_cleaned = 0, work_done = 0;
 
        /* In non-MSIX case, there is no multi-Tx/Rx queue */
-       ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
+       tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
        ixgbe_clean_rx_irq(adapter, &adapter->rx_ring[0], &work_done,
                           budget);
 
+       if (tx_cleaned)
+               work_done = budget;
+
        /* If budget not fully consumed, exit the polling mode */
        if (work_done < budget) {
                netif_rx_complete(netdev, napi);
index 3bbcea11329fae91de2941d1299f40f41721d8b2..5f6beabf2d179d71e399d85a0f75af84c36b189a 100644 (file)
@@ -1319,6 +1319,7 @@ static int link_status_10g(struct niu *np, int *link_up_p)
 
 static int link_status_1g(struct niu *np, int *link_up_p)
 {
+       struct niu_link_config *lp = &np->link_config;
        u16 current_speed, bmsr;
        unsigned long flags;
        u8 current_duplex;
@@ -1386,6 +1387,8 @@ static int link_status_1g(struct niu *np, int *link_up_p)
                                link_up = 0;
                }
        }
+       lp->active_speed = current_speed;
+       lp->active_duplex = current_duplex;
        err = 0;
 
 out:
index f7b8648acbfa4bf863d0cdd16c5769e544e3d199..6b9840cce0f4a8cdf9b1a2a51c48e186e53015f2 100644 (file)
@@ -215,6 +215,7 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
        } else if (!warned) {
                printk(KERN_ERR "pnpacpi: exceeded the max number of IO "
                                "resources: %d \n", PNP_MAX_PORT);
+               warned = 1;
        }
 }
 
@@ -242,6 +243,7 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res,
        } else if (!warned) {
                printk(KERN_ERR "pnpacpi: exceeded the max number of mem "
                                "resources: %d\n", PNP_MAX_MEM);
+               warned = 1;
        }
 }
 
index 8d81ef019c6c6f8de6a5eeb6013b061de650a649..08d07255223343c13487d31162f009a89e95e172 100644 (file)
@@ -259,6 +259,10 @@ static const struct fb_videomode modedb[] = {
        /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
        NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
        0, FB_VMODE_NONINTERLACED
+   }, {
+       /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
+       NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
+       0, FB_VMODE_NONINTERLACED
     },
 };
 
index 31284c77bba87b8a393d5cc78789cd13f2e02b31..110dd3515dc89b27e226a9a65867f338df18de69 100644 (file)
@@ -61,7 +61,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
        mapping = tree->inode->i_mapping;
        page = read_mapping_page(mapping, 0, NULL);
        if (IS_ERR(page))
-               goto free_tree;
+               goto free_inode;
 
        /* Load the header */
        head = (struct hfs_btree_header_rec *)(kmap(page) + sizeof(struct hfs_bnode_desc));
@@ -99,11 +99,12 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
        page_cache_release(page);
        return tree;
 
- fail_page:
+fail_page:
        page_cache_release(page);
- free_tree:
+free_inode:
        tree->inode->i_mapping->a_ops = &hfs_aops;
        iput(tree->inode);
+free_tree:
        kfree(tree);
        return NULL;
 }
index 08ff6c7028cc585b13cab54d01abb8ca1c6ea15d..038ed743619911799dfff8e27623e75f593fc60c 100644 (file)
@@ -288,10 +288,12 @@ handle_t *journal_start(journal_t *journal, int nblocks)
                jbd_free_handle(handle);
                current->journal_info = NULL;
                handle = ERR_PTR(err);
+               goto out;
        }
 
        lock_acquire(&handle->h_lockdep_map, 0, 0, 0, 2, _THIS_IP_);
 
+out:
        return handle;
 }
 
index 337162935d2173964538a190b7ed6e8433823f35..f281cc6584b0bca1f14fab02d464e027f31aabe0 100644 (file)
@@ -678,8 +678,10 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
        sd = sysfs_find_dirent(parent_sd, dentry->d_name.name);
 
        /* no such entry */
-       if (!sd)
+       if (!sd) {
+               ret = ERR_PTR(-ENOENT);
                goto out_unlock;
+       }
 
        /* attach dentry and inode */
        inode = sysfs_get_inode(sd);
@@ -781,6 +783,7 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
        old_dentry = sysfs_get_dentry(sd);
        if (IS_ERR(old_dentry)) {
                error = PTR_ERR(old_dentry);
+               old_dentry = NULL;
                goto out;
        }
 
@@ -848,6 +851,7 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
        old_dentry = sysfs_get_dentry(sd);
        if (IS_ERR(old_dentry)) {
                error = PTR_ERR(old_dentry);
+               old_dentry = NULL;
                goto out;
        }
        old_parent = old_dentry->d_parent;
@@ -855,6 +859,7 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
        new_parent = sysfs_get_dentry(new_parent_sd);
        if (IS_ERR(new_parent)) {
                error = PTR_ERR(new_parent);
+               new_parent = NULL;
                goto out;
        }
 
@@ -878,7 +883,6 @@ again:
        error = 0;
        d_add(new_dentry, NULL);
        d_move(old_dentry, new_dentry);
-       dput(new_dentry);
 
        /* Remove from old parent's list and insert into new parent's list. */
        sysfs_unlink_sibling(sd);
index 0648e3153f81f2d1f49d8633d5b72d59aa3ba117..b84353ef6998459ccf3b40da3777254cadcfe1fe 100644 (file)
@@ -4,14 +4,11 @@
 #ifdef __KERNEL__
 
 #include <asm/arch/page.h>
+#include <linux/const.h>
 
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT     13
-#ifndef __ASSEMBLY__
-#define PAGE_SIZE      (1UL << PAGE_SHIFT)
-#else
-#define PAGE_SIZE      (1 << PAGE_SHIFT)
-#endif
+#define PAGE_SIZE      (_AC(1, UL) << PAGE_SHIFT)
 #define PAGE_MASK      (~(PAGE_SIZE-1))
 
 #define clear_page(page)        memset((void *)(page), 0, PAGE_SIZE)
index 7daafdc2514b9657a0e0d9d0325785cc65c934b2..7f28c32d9aca26ebb055fee881c7e28e3fdba2c2 100644 (file)
@@ -149,19 +149,27 @@ struct execute_work {
 
 extern struct workqueue_struct *
 __create_workqueue_key(const char *name, int singlethread,
-                      int freezeable, struct lock_class_key *key);
+                      int freezeable, struct lock_class_key *key,
+                      const char *lock_name);
 
 #ifdef CONFIG_LOCKDEP
 #define __create_workqueue(name, singlethread, freezeable)     \
 ({                                                             \
        static struct lock_class_key __key;                     \
+       const char *__lock_name;                                \
+                                                               \
+       if (__builtin_constant_p(name))                         \
+               __lock_name = (name);                           \
+       else                                                    \
+               __lock_name = #name;                            \
                                                                \
        __create_workqueue_key((name), (singlethread),          \
-                              (freezeable), &__key);           \
+                              (freezeable), &__key,            \
+                              __lock_name);                    \
 })
 #else
 #define __create_workqueue(name, singlethread, freezeable)     \
-       __create_workqueue_key((name), (singlethread), (freezeable), NULL)
+       __create_workqueue_key((name), (singlethread), (freezeable), NULL, NULL)
 #endif
 
 #define create_workqueue(name) __create_workqueue((name), 0, 0)
index c6a4f8aebeba5c8a74a6bfc063e4ad08c3f14792..bb7df2a28bd719d07978593cb10f7264b6f43f3b 100644 (file)
@@ -451,13 +451,11 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
                             enum umh_wait wait)
 {
        DECLARE_COMPLETION_ONSTACK(done);
-       int retval;
+       int retval = 0;
 
        helper_lock();
-       if (sub_info->path[0] == '\0') {
-               retval = 0;
+       if (sub_info->path[0] == '\0')
                goto out;
-       }
 
        if (!khelper_wq || usermodehelper_disabled) {
                retval = -EBUSY;
@@ -468,13 +466,14 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
        sub_info->wait = wait;
 
        queue_work(khelper_wq, &sub_info->work);
-       if (wait == UMH_NO_WAIT) /* task has freed sub_info */
-               return 0;
+       if (wait == UMH_NO_WAIT)        /* task has freed sub_info */
+               goto unlock;
        wait_for_completion(&done);
        retval = sub_info->retval;
 
-  out:
+out:
        call_usermodehelper_freeinfo(sub_info);
+unlock:
        helper_unlock();
        return retval;
 }
index 723bd9f9255687f7820b0e151ae23a3d5ca81e7b..4335f12a27c6367e8e264a1128050ea3df6e8415 100644 (file)
@@ -2943,9 +2943,10 @@ void lockdep_free_key_range(void *start, unsigned long size)
        struct list_head *head;
        unsigned long flags;
        int i;
+       int locked;
 
        raw_local_irq_save(flags);
-       graph_lock();
+       locked = graph_lock();
 
        /*
         * Unhash all classes that were created by this module:
@@ -2959,7 +2960,8 @@ void lockdep_free_key_range(void *start, unsigned long size)
                                zap_class(class);
        }
 
-       graph_unlock();
+       if (locked)
+               graph_unlock();
        raw_local_irq_restore(flags);
 }
 
@@ -2969,6 +2971,7 @@ void lockdep_reset_lock(struct lockdep_map *lock)
        struct list_head *head;
        unsigned long flags;
        int i, j;
+       int locked;
 
        raw_local_irq_save(flags);
 
@@ -2987,7 +2990,7 @@ void lockdep_reset_lock(struct lockdep_map *lock)
         * Debug check: in the end all mapped classes should
         * be gone.
         */
-       graph_lock();
+       locked = graph_lock();
        for (i = 0; i < CLASSHASH_SIZE; i++) {
                head = classhash_table + i;
                if (list_empty(head))
@@ -3000,7 +3003,8 @@ void lockdep_reset_lock(struct lockdep_map *lock)
                        }
                }
        }
-       graph_unlock();
+       if (locked)
+               graph_unlock();
 
 out_restore:
        raw_local_irq_restore(flags);
index 52d5e7c9a8e6e82e68a0cb88ba0cdbad508eded5..8db0b597509e5bd2d8e630911137ea50aae42030 100644 (file)
@@ -722,7 +722,8 @@ static void start_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
 struct workqueue_struct *__create_workqueue_key(const char *name,
                                                int singlethread,
                                                int freezeable,
-                                               struct lock_class_key *key)
+                                               struct lock_class_key *key,
+                                               const char *lock_name)
 {
        struct workqueue_struct *wq;
        struct cpu_workqueue_struct *cwq;
@@ -739,7 +740,7 @@ struct workqueue_struct *__create_workqueue_key(const char *name,
        }
 
        wq->name = name;
-       lockdep_init_map(&wq->lockdep_map, name, key, 0);
+       lockdep_init_map(&wq->lockdep_map, lock_name, key, 0);
        wq->singlethread = singlethread;
        wq->freezeable = freezeable;
        INIT_LIST_HEAD(&wq->list);
index 4bf0b6d0eb2a675bbd1083099448d54979dff304..6dd1cd88bfb67411767b28e0cdc11a35b52fc92a 100644 (file)
@@ -392,6 +392,7 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_
                        return NULL;
        }
 
+#ifdef CONFIG_DEBUG_VM
        /*
         * Add some anal sanity checks for now. Eventually,
         * we should just do "return pfn_to_page(pfn)", but
@@ -402,6 +403,7 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_
                print_bad_pte(vma, pte, addr);
                return NULL;
        }
+#endif
 
        /*
         * NOTE! We still have PageReserved() pages in the page 
index e1028fae3ebbd2644628316cc08f94fa55ae0dad..b2838c24e582c11b8e0680ca5d5b5f97389145ba 100644 (file)
@@ -2566,7 +2566,7 @@ static void __meminit zone_init_free_lists(struct pglist_data *pgdat,
        memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY)
 #endif
 
-static int __devinit zone_batchsize(struct zone *zone)
+static int zone_batchsize(struct zone *zone)
 {
        int batch;