diff --git a/debian/patches/bugfix/all/patch-2.6.24-rc8-git5 b/debian/patches/bugfix/all/patch-2.6.24-rc8-git5 new file mode 100644 index 000000000..e9cf8e9f8 --- /dev/null +++ b/debian/patches/bugfix/all/patch-2.6.24-rc8-git5 @@ -0,0 +1,4066 @@ +diff --git a/Documentation/local_ops.txt b/Documentation/local_ops.txt +index 1a45f11..4269a11 100644 +--- a/Documentation/local_ops.txt ++++ b/Documentation/local_ops.txt +@@ -68,29 +68,6 @@ typedef struct { atomic_long_t a; } local_t; + 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. +-- _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. +- +- + * How to use local atomic operations + + #include +diff --git a/Documentation/networking/driver.txt b/Documentation/networking/driver.txt +index 4f7da5a..ea72d2e 100644 +--- a/Documentation/networking/driver.txt ++++ b/Documentation/networking/driver.txt +@@ -61,7 +61,10 @@ Transmit path guidelines: + 2) Do not forget to update netdev->trans_start to jiffies after + each new tx packet is given to the hardware. + +-3) Do not forget that once you return 0 from your hard_start_xmit ++3) A hard_start_xmit method must not modify the shared parts of a ++ cloned SKB. ++ ++4) Do not forget that once you return 0 from your hard_start_xmit + method, it is your driver's responsibility to free up the SKB + and in some finite amount of time. + +diff --git a/Documentation/watchdog/watchdog-api.txt b/Documentation/watchdog/watchdog-api.txt +index bb7cb1d..4cc4ba9 100644 +--- a/Documentation/watchdog/watchdog-api.txt ++++ b/Documentation/watchdog/watchdog-api.txt +@@ -42,23 +42,27 @@ like this source file: see Documentation/watchdog/src/watchdog-simple.c + A more advanced driver could for example check that a HTTP server is + still responding before doing the write call to ping the watchdog. + +-When the device is closed, the watchdog is disabled. This is not +-always such a good idea, since if there is a bug in the watchdog +-daemon and it crashes the system will not reboot. Because of this, +-some of the drivers support the configuration option "Disable watchdog +-shutdown on close", CONFIG_WATCHDOG_NOWAYOUT. If it is set to Y when +-compiling the kernel, there is no way of disabling the watchdog once +-it has been started. So, if the watchdog daemon crashes, the system +-will reboot after the timeout has passed. Watchdog devices also usually +-support the nowayout module parameter so that this option can be controlled +-at runtime. +- +-Drivers will not disable the watchdog, unless a specific magic character 'V' +-has been sent /dev/watchdog just before closing the file. If the userspace +-daemon closes the file without sending this special character, the driver +-will assume that the daemon (and userspace in general) died, and will stop +-pinging the watchdog without disabling it first. This will then cause a +-reboot if the watchdog is not re-opened in sufficient time. ++When the device is closed, the watchdog is disabled, unless the "Magic ++Close" feature is supported (see below). This is not always such a ++good idea, since if there is a bug in the watchdog daemon and it ++crashes the system will not reboot. Because of this, some of the ++drivers support the configuration option "Disable watchdog shutdown on ++close", CONFIG_WATCHDOG_NOWAYOUT. If it is set to Y when compiling ++the kernel, there is no way of disabling the watchdog once it has been ++started. So, if the watchdog daemon crashes, the system will reboot ++after the timeout has passed. Watchdog devices also usually support ++the nowayout module parameter so that this option can be controlled at ++runtime. ++ ++Magic Close feature: ++ ++If a driver supports "Magic Close", the driver will not disable the ++watchdog unless a specific magic character 'V' has been sent to ++/dev/watchdog just before closing the file. If the userspace daemon ++closes the file without sending this special character, the driver ++will assume that the daemon (and userspace in general) died, and will ++stop pinging the watchdog without disabling it first. This will then ++cause a reboot if the watchdog is not re-opened in sufficient time. + + The ioctl API: + +diff --git a/Makefile b/Makefile +index 713f685..a22cac5 100644 +--- a/Makefile ++++ b/Makefile +@@ -12,7 +12,7 @@ NAME = Arr Matey! A Hairy Bilge Rat! + + # Do not: + # o use make's built-in rules and variables +-# (this increases performance and avoid hard-to-debug behavour); ++# (this increases performance and avoids hard-to-debug behaviour); + # o print "Entering directory ..."; + MAKEFLAGS += -rR --no-print-directory + +@@ -1329,7 +1329,7 @@ else + ALLINCLUDE_ARCHS := $(SRCARCH) + endif + else +-#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behavour. ++#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behaviour. + ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS) + endif + +diff --git a/arch/.gitignore b/arch/.gitignore +new file mode 100644 +index 0000000..7414689 +--- /dev/null ++++ b/arch/.gitignore +@@ -0,0 +1,2 @@ ++i386 ++x86_64 +diff --git a/arch/alpha/math-emu/math.c b/arch/alpha/math-emu/math.c +index ae79dd9..58c2669 100644 +--- a/arch/alpha/math-emu/math.c ++++ b/arch/alpha/math-emu/math.c +@@ -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; + } +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 3a75a0b..a04f507 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -1072,6 +1072,8 @@ source "drivers/rtc/Kconfig" + + source "drivers/dma/Kconfig" + ++source "drivers/dca/Kconfig" ++ + endmenu + + source "fs/Kconfig" +diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c +index f65baa9..d5f6ea1 100644 +--- a/arch/arm/mach-omap1/board-fsample.c ++++ b/arch/arm/mach-omap1/board-fsample.c +@@ -40,31 +40,29 @@ static int fsample_keymap[] = { + KEY(0,1,KEY_RIGHT), + KEY(0,2,KEY_LEFT), + KEY(0,3,KEY_DOWN), +- KEY(0,4,KEY_CENTER), +- KEY(0,5,KEY_0_5), +- KEY(1,0,KEY_SOFT2), ++ KEY(0,4,KEY_ENTER), ++ KEY(1,0,KEY_F10), + KEY(1,1,KEY_SEND), + KEY(1,2,KEY_END), + KEY(1,3,KEY_VOLUMEDOWN), + KEY(1,4,KEY_VOLUMEUP), + KEY(1,5,KEY_RECORD), +- KEY(2,0,KEY_SOFT1), ++ KEY(2,0,KEY_F9), + KEY(2,1,KEY_3), + KEY(2,2,KEY_6), + KEY(2,3,KEY_9), +- KEY(2,4,KEY_SHARP), +- KEY(2,5,KEY_2_5), ++ KEY(2,4,KEY_KPDOT), + KEY(3,0,KEY_BACK), + KEY(3,1,KEY_2), + KEY(3,2,KEY_5), + KEY(3,3,KEY_8), + KEY(3,4,KEY_0), +- KEY(3,5,KEY_HEADSETHOOK), ++ KEY(3,5,KEY_KPSLASH), + KEY(4,0,KEY_HOME), + KEY(4,1,KEY_1), + KEY(4,2,KEY_4), + KEY(4,3,KEY_7), +- KEY(4,4,KEY_STAR), ++ KEY(4,4,KEY_KPASTERISK), + KEY(4,5,KEY_POWER), + 0 + }; +diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c +index 22db19a..182a98a 100644 +--- a/arch/arm/mach-omap1/board-nokia770.c ++++ b/arch/arm/mach-omap1/board-nokia770.c +@@ -36,8 +36,6 @@ + #include + #include + +-#include "../plat-omap/dsp/dsp_common.h" +- + #define ADS7846_PENDOWN_GPIO 15 + + static void __init omap_nokia770_init_irq(void) +@@ -318,6 +316,8 @@ static __init int omap_dsp_init(void) + out: + return ret; + } ++#else ++#define omap_dsp_init() do {} while (0) + #endif /* CONFIG_OMAP_DSP */ + + static void __init omap_nokia770_init(void) +diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c +index 1d5c8d5..e44437e 100644 +--- a/arch/arm/mach-omap1/board-perseus2.c ++++ b/arch/arm/mach-omap1/board-perseus2.c +@@ -39,31 +39,29 @@ static int p2_keymap[] = { + KEY(0,1,KEY_RIGHT), + KEY(0,2,KEY_LEFT), + KEY(0,3,KEY_DOWN), +- KEY(0,4,KEY_CENTER), +- KEY(0,5,KEY_0_5), +- KEY(1,0,KEY_SOFT2), ++ KEY(0,4,KEY_ENTER), ++ KEY(1,0,KEY_F10), + KEY(1,1,KEY_SEND), + KEY(1,2,KEY_END), + KEY(1,3,KEY_VOLUMEDOWN), + KEY(1,4,KEY_VOLUMEUP), + KEY(1,5,KEY_RECORD), +- KEY(2,0,KEY_SOFT1), ++ KEY(2,0,KEY_F9), + KEY(2,1,KEY_3), + KEY(2,2,KEY_6), + KEY(2,3,KEY_9), +- KEY(2,4,KEY_SHARP), +- KEY(2,5,KEY_2_5), ++ KEY(2,4,KEY_KPDOT), + KEY(3,0,KEY_BACK), + KEY(3,1,KEY_2), + KEY(3,2,KEY_5), + KEY(3,3,KEY_8), + KEY(3,4,KEY_0), +- KEY(3,5,KEY_HEADSETHOOK), ++ KEY(3,5,KEY_KPSLASH), + KEY(4,0,KEY_HOME), + KEY(4,1,KEY_1), + KEY(4,2,KEY_4), + KEY(4,3,KEY_7), +- KEY(4,4,KEY_STAR), ++ KEY(4,4,KEY_KPASTERISK), + KEY(4,5,KEY_POWER), + 0 + }; +diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S +index aff71fe..d044772 100644 +--- a/arch/arm/mach-pxa/sleep.S ++++ b/arch/arm/mach-pxa/sleep.S +@@ -43,11 +43,11 @@ pxa_cpu_save_cp: + pxa_cpu_save_sp: + @ preserve phys address of stack + mov r0, sp +- mov r2, lr ++ str lr, [sp, #-4]! + bl sleep_phys_sp + ldr r1, =sleep_save_sp + str r0, [r1] +- mov pc, r2 ++ ldr pc, [sp], #4 + + /* + * pxa27x_cpu_suspend() +@@ -270,5 +270,3 @@ resume_after_mmu: + mar acc0, r2, r3 + #endif + ldmfd sp!, {r4 - r12, pc} @ return to caller +- +- +diff --git a/arch/cris/arch-v10/kernel/io_interface_mux.c b/arch/cris/arch-v10/kernel/io_interface_mux.c +index 3a9114e..f3b327d 100644 +--- a/arch/cris/arch-v10/kernel/io_interface_mux.c ++++ b/arch/cris/arch-v10/kernel/io_interface_mux.c +@@ -392,6 +392,7 @@ int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id + if (((interfaces[ioif].gpio_g_in & gpio_in_pins) != interfaces[ioif].gpio_g_in) || + ((interfaces[ioif].gpio_g_out & gpio_out_pins) != interfaces[ioif].gpio_g_out) || + ((interfaces[ioif].gpio_b & gpio_pb_pins) != interfaces[ioif].gpio_b)) { ++ local_irq_restore(flags); + printk(KERN_CRIT "cris_request_io_interface: Could not get required pins for interface %u\n", + ioif); + return -EBUSY; +diff --git a/arch/cris/arch-v10/vmlinux.lds.S b/arch/cris/arch-v10/vmlinux.lds.S +index 9859d49..97a7876 100644 +--- a/arch/cris/arch-v10/vmlinux.lds.S ++++ b/arch/cris/arch-v10/vmlinux.lds.S +@@ -9,7 +9,8 @@ + */ + + #include +- ++#include ++ + 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 */ +diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c +index 9a2636e..bc43a5c 100644 +--- a/arch/mips/mips-boards/malta/malta_setup.c ++++ b/arch/mips/mips-boards/malta/malta_setup.c +@@ -149,7 +149,7 @@ void __init plat_mem_setup(void) + /* Check PCI clock */ + { + unsigned int __iomem *jmpr_p = (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int)); +- int jmpr = (readw(jmpr_p) >> 2) & 0x07; ++ int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07; + static const int pciclocks[] __initdata = { + 33, 20, 25, 30, 12, 16, 37, 10 + }; +diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c +index 4a81523..632e5d2 100644 +--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c ++++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c +@@ -598,8 +598,8 @@ static int __init rbtx4938_ethaddr_init(void) + printk(KERN_WARNING "seeprom: bad checksum.\n"); + } + for (i = 0; i < 2; i++) { +- unsigned int slot = TX4938_PCIC_IDSEL_AD_TO_SLOT(31 - i); +- unsigned int id = (1 << 8) | PCI_DEVFN(slot, 0); /* bus 1 */ ++ unsigned int id = ++ TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0); + struct platform_device *pdev; + if (!(tx4938_ccfgptr->pcfg & + (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL))) +diff --git a/arch/sparc64/kernel/sun4v_tlb_miss.S b/arch/sparc64/kernel/sun4v_tlb_miss.S +index 9871dbb..fd94305 100644 +--- a/arch/sparc64/kernel/sun4v_tlb_miss.S ++++ b/arch/sparc64/kernel/sun4v_tlb_miss.S +@@ -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 + +diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c +index 0499838..2b6abf6 100644 +--- a/arch/sparc64/kernel/traps.c ++++ b/arch/sparc64/kernel/traps.c +@@ -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, +diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c +index c88bbff..02d1e1e 100644 +--- a/arch/x86/kernel/traps_32.c ++++ b/arch/x86/kernel/traps_32.c +@@ -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; \ +diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c +index d11525a..cc68b92 100644 +--- a/arch/x86/kernel/traps_64.c ++++ b/arch/x86/kernel/traps_64.c +@@ -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; \ +diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c +index 2d0eeac..944bbcd 100644 +--- a/arch/x86/oprofile/nmi_int.c ++++ b/arch/x86/oprofile/nmi_int.c +@@ -380,7 +380,7 @@ static int __init ppro_init(char ** cpu_type) + + if (cpu_model == 14) + *cpu_type = "i386/core"; +- else if (cpu_model == 15) ++ else if (cpu_model == 15 || cpu_model == 23) + *cpu_type = "i386/core_2"; + else if (cpu_model > 0xd) + return 0; +diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c +index 8f28156..6c9689b 100644 +--- a/drivers/ata/pata_pdc202xx_old.c ++++ b/drivers/ata/pata_pdc202xx_old.c +@@ -244,6 +244,24 @@ static int pdc2026x_port_start(struct ata_port *ap) + return ata_sff_port_start(ap); + } + ++/** ++ * pdc2026x_check_atapi_dma - Check whether ATAPI DMA can be supported for this command ++ * @qc: Metadata associated with taskfile to check ++ * ++ * Just say no - not supported on older Promise. ++ * ++ * LOCKING: ++ * None (inherited from caller). ++ * ++ * RETURNS: 0 when ATAPI DMA can be used ++ * 1 otherwise ++ */ ++ ++static int pdc2026x_check_atapi_dma(struct ata_queued_cmd *qc) ++{ ++ return 1; ++} ++ + static struct scsi_host_template pdc202xx_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, +@@ -311,6 +329,7 @@ static struct ata_port_operations pdc2026x_port_ops = { + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = pdc2026x_cable_detect, + ++ .check_atapi_dma= pdc2026x_check_atapi_dma, + .bmdma_setup = ata_bmdma_setup, + .bmdma_start = pdc2026x_bmdma_start, + .bmdma_stop = pdc2026x_bmdma_stop, +diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c +index 0bd657f..84672dc 100644 +--- a/drivers/atm/idt77105.c ++++ b/drivers/atm/idt77105.c +@@ -357,7 +357,7 @@ static const struct atmphy_ops idt77105_ops = { + }; + + +-int __devinit idt77105_init(struct atm_dev *dev) ++int idt77105_init(struct atm_dev *dev) + { + dev->phy = &idt77105_ops; + return 0; +diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c +index f04f39c..b1d063c 100644 +--- a/drivers/atm/suni.c ++++ b/drivers/atm/suni.c +@@ -289,7 +289,7 @@ static const struct atmphy_ops suni_ops = { + }; + + +-int __devinit suni_init(struct atm_dev *dev) ++int suni_init(struct atm_dev *dev) + { + unsigned char mri; + +diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c +index 1bba997..5d3a04b 100644 +--- a/drivers/cpufreq/cpufreq_conservative.c ++++ b/drivers/cpufreq/cpufreq_conservative.c +@@ -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); +diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c +index 369f445..d2af20d 100644 +--- a/drivers/cpufreq/cpufreq_ondemand.c ++++ b/drivers/cpufreq/cpufreq_ondemand.c +@@ -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); +- +diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c +index 51bedab..f8cdde4 100644 +--- a/drivers/cpufreq/cpufreq_userspace.c ++++ b/drivers/cpufreq/cpufreq_userspace.c +@@ -231,5 +231,9 @@ MODULE_AUTHOR ("Dominik Brodowski , Russell King bth[0]) >> 24; ++ if (qp->ibqp.qp_num > 1 && ++ opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) { ++ if (header_in_data) { ++ wc.imm_data = *(__be32 *) data; ++ data += sizeof(__be32); ++ } else ++ wc.imm_data = ohdr->u.ud.imm_data; ++ wc.wc_flags = IB_WC_WITH_IMM; ++ hdrsize += sizeof(u32); ++ } else if (opcode == IB_OPCODE_UD_SEND_ONLY) { ++ wc.imm_data = 0; ++ wc.wc_flags = 0; ++ } else { ++ dev->n_pkt_drops++; ++ goto bail; ++ } ++ + /* Get the number of bytes the message was padded by. */ + pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; + if (unlikely(tlen < (hdrsize + pad + 4))) { +@@ -482,28 +504,6 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, + wc.byte_len = tlen + sizeof(struct ib_grh); + + /* +- * The opcode is in the low byte when its in network order +- * (top byte when in host order). +- */ +- opcode = be32_to_cpu(ohdr->bth[0]) >> 24; +- if (qp->ibqp.qp_num > 1 && +- opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) { +- if (header_in_data) { +- wc.imm_data = *(__be32 *) data; +- data += sizeof(__be32); +- } else +- wc.imm_data = ohdr->u.ud.imm_data; +- wc.wc_flags = IB_WC_WITH_IMM; +- hdrsize += sizeof(u32); +- } else if (opcode == IB_OPCODE_UD_SEND_ONLY) { +- wc.imm_data = 0; +- wc.wc_flags = 0; +- } else { +- dev->n_pkt_drops++; +- goto bail; +- } +- +- /* + * Get the next work request entry to find where to put the data. + */ + if (qp->r_reuse_sge) +diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c +index 2b5ed11..b346a3b 100644 +--- a/drivers/input/mouse/alps.c ++++ b/drivers/input/mouse/alps.c +@@ -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 */ + }; + + /* +diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c +index 9ec57d8..df81b0a 100644 +--- a/drivers/input/mouse/lifebook.c ++++ b/drivers/input/mouse/lifebook.c +@@ -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; + } + +diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c +index 21a9c0b..b862825 100644 +--- a/drivers/input/mouse/psmouse-base.c ++++ b/drivers/input/mouse/psmouse-base.c +@@ -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); +diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c +index 78c3ea7..be83516 100644 +--- a/drivers/input/mousedev.c ++++ b/drivers/input/mousedev.c +@@ -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 */ + }; +diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c +index 19055e7..63f9664 100644 +--- a/drivers/input/touchscreen/usbtouchscreen.c ++++ b/drivers/input/touchscreen/usbtouchscreen.c +@@ -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 +@@ -50,7 +51,7 @@ + #include + + +-#define DRIVER_VERSION "v0.5" ++#define DRIVER_VERSION "v0.6" + #define DRIVER_AUTHOR "Daniel Ritz " + #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; +diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig +index 7eb9ecf..6b8dbb9 100644 +--- a/drivers/lguest/Kconfig ++++ b/drivers/lguest/Kconfig +@@ -10,10 +10,3 @@ config LGUEST + not "rustyvisor". See Documentation/lguest/lguest.txt. + + If unsure, say N. If curious, say M. If masochistic, say Y. +- +-config LGUEST_GUEST +- bool +- help +- The guest needs code built-in, even if the host has lguest +- support as a module. The drivers are tiny, so we build them +- in too. +diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c +index 4fd187a..4f0a915 100644 +--- a/drivers/media/video/saa7134/saa7134-core.c ++++ b/drivers/media/video/saa7134/saa7134-core.c +@@ -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); +diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c +index 275e751..684bab7 100644 +--- a/drivers/net/3c515.c ++++ b/drivers/net/3c515.c +@@ -243,14 +243,16 @@ enum eeprom_offset { + enum Window3 { /* Window 3: MAC/config bits. */ + Wn3_Config = 0, Wn3_MAC_Ctrl = 6, Wn3_Options = 8, + }; +-union wn3_config { +- int i; +- struct w3_config_fields { +- unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2; +- int pad8:8; +- unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1; +- int pad24:7; +- } u; ++enum wn3_config { ++ Ram_size = 7, ++ Ram_width = 8, ++ Ram_speed = 0x30, ++ Rom_size = 0xc0, ++ Ram_split_shift = 16, ++ Ram_split = 3 << Ram_split_shift, ++ Xcvr_shift = 20, ++ Xcvr = 7 << Xcvr_shift, ++ Autoselect = 0x1000000, + }; + + enum Window4 { +@@ -614,7 +616,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr, + /* Read the station address from the EEPROM. */ + EL3WINDOW(0); + for (i = 0; i < 0x18; i++) { +- short *phys_addr = (short *) dev->dev_addr; ++ __be16 *phys_addr = (__be16 *) dev->dev_addr; + int timer; + outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd); + /* Pause for at least 162 us. for the read to take place. */ +@@ -646,22 +648,22 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr, + + { + char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" }; +- union wn3_config config; ++ __u32 config; + EL3WINDOW(3); + vp->available_media = inw(ioaddr + Wn3_Options); +- config.i = inl(ioaddr + Wn3_Config); ++ config = inl(ioaddr + Wn3_Config); + if (corkscrew_debug > 1) + printk(KERN_INFO " Internal config register is %4.4x, transceivers %#x.\n", +- config.i, inw(ioaddr + Wn3_Options)); ++ config, inw(ioaddr + Wn3_Options)); + printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n", +- 8 << config.u.ram_size, +- config.u.ram_width ? "word" : "byte", +- ram_split[config.u.ram_split], +- config.u.autoselect ? "autoselect/" : "", +- media_tbl[config.u.xcvr].name); +- dev->if_port = config.u.xcvr; +- vp->default_media = config.u.xcvr; +- vp->autoselect = config.u.autoselect; ++ 8 << config & Ram_size, ++ config & Ram_width ? "word" : "byte", ++ ram_split[(config & Ram_split) >> Ram_split_shift], ++ config & Autoselect ? "autoselect/" : "", ++ media_tbl[(config & Xcvr) >> Xcvr_shift].name); ++ vp->default_media = (config & Xcvr) >> Xcvr_shift; ++ vp->autoselect = config & Autoselect ? 1 : 0; ++ dev->if_port = vp->default_media; + } + if (vp->media_override != 7) { + printk(KERN_INFO " Media override to transceiver type %d (%s).\n", +@@ -694,14 +696,14 @@ static int corkscrew_open(struct net_device *dev) + { + int ioaddr = dev->base_addr; + struct corkscrew_private *vp = netdev_priv(dev); +- union wn3_config config; ++ __u32 config; + int i; + + /* Before initializing select the active media port. */ + EL3WINDOW(3); + if (vp->full_duplex) + outb(0x20, ioaddr + Wn3_MAC_Ctrl); /* Set the full-duplex bit. */ +- config.i = inl(ioaddr + Wn3_Config); ++ config = inl(ioaddr + Wn3_Config); + + if (vp->media_override != 7) { + if (corkscrew_debug > 1) +@@ -727,12 +729,12 @@ static int corkscrew_open(struct net_device *dev) + } else + dev->if_port = vp->default_media; + +- config.u.xcvr = dev->if_port; +- outl(config.i, ioaddr + Wn3_Config); ++ config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift); ++ outl(config, ioaddr + Wn3_Config); + + if (corkscrew_debug > 1) { + printk("%s: corkscrew_open() InternalConfig %8.8x.\n", +- dev->name, config.i); ++ dev->name, config); + } + + outw(TxReset, ioaddr + EL3_CMD); +@@ -901,7 +903,7 @@ static void corkscrew_timer(unsigned long data) + ok = 1; + } + if (!ok) { +- union wn3_config config; ++ __u32 config; + + do { + dev->if_port = +@@ -928,9 +930,9 @@ static void corkscrew_timer(unsigned long data) + ioaddr + Wn4_Media); + + EL3WINDOW(3); +- config.i = inl(ioaddr + Wn3_Config); +- config.u.xcvr = dev->if_port; +- outl(config.i, ioaddr + Wn3_Config); ++ config = inl(ioaddr + Wn3_Config); ++ config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift); ++ outl(config, ioaddr + Wn3_Config); + + outw(dev->if_port == 3 ? StartCoax : StopCoax, + ioaddr + EL3_CMD); +diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig +index 114771a..9ae3166 100644 +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -1976,9 +1976,6 @@ config E1000E + + + +- More specific information on configuring the driver is in +- . +- + To compile this driver as a module, choose M here. The module + will be called e1000e. + +diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c +index 35b0a7d..9200ee5 100644 +--- a/drivers/net/atl1/atl1_main.c ++++ b/drivers/net/atl1/atl1_main.c +@@ -120,7 +120,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter) + struct atl1_hw *hw = &adapter->hw; + struct net_device *netdev = adapter->netdev; + +- hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; ++ hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; + hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; + + adapter->wol = 0; +@@ -688,7 +688,7 @@ static int atl1_change_mtu(struct net_device *netdev, int new_mtu) + { + struct atl1_adapter *adapter = netdev_priv(netdev); + int old_mtu = netdev->mtu; +- int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; ++ int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; + + if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || + (max_frame > MAX_JUMBO_FRAME_SIZE)) { +@@ -853,8 +853,8 @@ static u32 atl1_configure(struct atl1_adapter *adapter) + /* set Interrupt Clear Timer */ + iowrite16(adapter->ict, hw->hw_addr + REG_CMBDISDMA_TIMER); + +- /* set MTU, 4 : VLAN */ +- iowrite32(hw->max_frame_size + 4, hw->hw_addr + REG_MTU); ++ /* set max frame size hw will accept */ ++ iowrite32(hw->max_frame_size, hw->hw_addr + REG_MTU); + + /* jumbo size & rrd retirement timer */ + value = (((u32) hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK) +diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c +index 25b8dbf..b57bc94 100644 +--- a/drivers/net/bonding/bond_alb.c ++++ b/drivers/net/bonding/bond_alb.c +@@ -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); + } + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index b0b2603..49a1982 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -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) +diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c +index 11b76b3..90a1f31 100644 +--- a/drivers/net/bonding/bond_sysfs.c ++++ b/drivers/net/bonding/bond_sysfs.c +@@ -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) +diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h +index e1e4734..6d83be4 100644 +--- a/drivers/net/bonding/bonding.h ++++ b/drivers/net/bonding/bonding.h +@@ -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 *); +diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c +index 6fd95a2..6e12d48 100644 +--- a/drivers/net/cpmac.c ++++ b/drivers/net/cpmac.c +@@ -459,7 +459,7 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev) + return NETDEV_TX_OK; + + len = max(skb->len, ETH_ZLEN); +- queue = skb->queue_mapping; ++ queue = skb_get_queue_mapping(skb); + #ifdef CONFIG_NETDEVICES_MULTIQUEUE + netif_stop_subqueue(dev, queue); + #else +diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c +index 47cce9c..e233d04 100644 +--- a/drivers/net/dl2k.c ++++ b/drivers/net/dl2k.c +@@ -1316,9 +1316,10 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) + ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x", + i, + (u32) (np->tx_ring_dma + i * sizeof (*desc)), +- (u32) desc->next_desc, +- (u32) desc->status, (u32) (desc->fraginfo >> 32), +- (u32) desc->fraginfo); ++ (u32)le64_to_cpu(desc->next_desc), ++ (u32)le64_to_cpu(desc->status), ++ (u32)(le64_to_cpu(desc->fraginfo) >> 32), ++ (u32)le64_to_cpu(desc->fraginfo)); + printk ("\n"); + } + printk ("\n"); +@@ -1435,7 +1436,7 @@ mii_write (struct net_device *dev, int phy_addr, int reg_num, u16 data) + static int + mii_wait_link (struct net_device *dev, int wait) + { +- BMSR_t bmsr; ++ __u16 bmsr; + int phy_addr; + struct netdev_private *np; + +@@ -1443,8 +1444,8 @@ mii_wait_link (struct net_device *dev, int wait) + phy_addr = np->phy_addr; + + do { +- bmsr.image = mii_read (dev, phy_addr, MII_BMSR); +- if (bmsr.bits.link_status) ++ bmsr = mii_read (dev, phy_addr, MII_BMSR); ++ if (bmsr & MII_BMSR_LINK_STATUS) + return 0; + mdelay (1); + } while (--wait > 0); +@@ -1453,70 +1454,72 @@ mii_wait_link (struct net_device *dev, int wait) + static int + mii_get_media (struct net_device *dev) + { +- ANAR_t negotiate; +- BMSR_t bmsr; +- BMCR_t bmcr; +- MSCR_t mscr; +- MSSR_t mssr; ++ __u16 negotiate; ++ __u16 bmsr; ++ __u16 mscr; ++ __u16 mssr; + int phy_addr; + struct netdev_private *np; + + np = netdev_priv(dev); + phy_addr = np->phy_addr; + +- bmsr.image = mii_read (dev, phy_addr, MII_BMSR); ++ bmsr = mii_read (dev, phy_addr, MII_BMSR); + if (np->an_enable) { +- if (!bmsr.bits.an_complete) { ++ if (!(bmsr & MII_BMSR_AN_COMPLETE)) { + /* Auto-Negotiation not completed */ + return -1; + } +- negotiate.image = mii_read (dev, phy_addr, MII_ANAR) & ++ negotiate = mii_read (dev, phy_addr, MII_ANAR) & + mii_read (dev, phy_addr, MII_ANLPAR); +- mscr.image = mii_read (dev, phy_addr, MII_MSCR); +- mssr.image = mii_read (dev, phy_addr, MII_MSSR); +- if (mscr.bits.media_1000BT_FD & mssr.bits.lp_1000BT_FD) { ++ mscr = mii_read (dev, phy_addr, MII_MSCR); ++ mssr = mii_read (dev, phy_addr, MII_MSSR); ++ if (mscr & MII_MSCR_1000BT_FD && mssr & MII_MSSR_LP_1000BT_FD) { + np->speed = 1000; + np->full_duplex = 1; + printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n"); +- } else if (mscr.bits.media_1000BT_HD & mssr.bits.lp_1000BT_HD) { ++ } else if (mscr & MII_MSCR_1000BT_HD && mssr & MII_MSSR_LP_1000BT_HD) { + np->speed = 1000; + np->full_duplex = 0; + printk (KERN_INFO "Auto 1000 Mbps, Half duplex\n"); +- } else if (negotiate.bits.media_100BX_FD) { ++ } else if (negotiate & MII_ANAR_100BX_FD) { + np->speed = 100; + np->full_duplex = 1; + printk (KERN_INFO "Auto 100 Mbps, Full duplex\n"); +- } else if (negotiate.bits.media_100BX_HD) { ++ } else if (negotiate & MII_ANAR_100BX_HD) { + np->speed = 100; + np->full_duplex = 0; + printk (KERN_INFO "Auto 100 Mbps, Half duplex\n"); +- } else if (negotiate.bits.media_10BT_FD) { ++ } else if (negotiate & MII_ANAR_10BT_FD) { + np->speed = 10; + np->full_duplex = 1; + printk (KERN_INFO "Auto 10 Mbps, Full duplex\n"); +- } else if (negotiate.bits.media_10BT_HD) { ++ } else if (negotiate & MII_ANAR_10BT_HD) { + np->speed = 10; + np->full_duplex = 0; + printk (KERN_INFO "Auto 10 Mbps, Half duplex\n"); + } +- if (negotiate.bits.pause) { ++ if (negotiate & MII_ANAR_PAUSE) { + np->tx_flow &= 1; + np->rx_flow &= 1; +- } else if (negotiate.bits.asymmetric) { ++ } else if (negotiate & MII_ANAR_ASYMMETRIC) { + np->tx_flow = 0; + np->rx_flow &= 1; + } + /* else tx_flow, rx_flow = user select */ + } else { +- bmcr.image = mii_read (dev, phy_addr, MII_BMCR); +- if (bmcr.bits.speed100 == 1 && bmcr.bits.speed1000 == 0) { ++ __u16 bmcr = mii_read (dev, phy_addr, MII_BMCR); ++ switch (bmcr & (MII_BMCR_SPEED_100 | MII_BMCR_SPEED_1000)) { ++ case MII_BMCR_SPEED_1000: ++ printk (KERN_INFO "Operating at 1000 Mbps, "); ++ break; ++ case MII_BMCR_SPEED_100: + printk (KERN_INFO "Operating at 100 Mbps, "); +- } else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 0) { ++ break; ++ case 0: + printk (KERN_INFO "Operating at 10 Mbps, "); +- } else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 1) { +- printk (KERN_INFO "Operating at 1000 Mbps, "); + } +- if (bmcr.bits.duplex_mode) { ++ if (bmcr & MII_BMCR_DUPLEX_MODE) { + printk ("Full duplex\n"); + } else { + printk ("Half duplex\n"); +@@ -1537,10 +1540,10 @@ mii_get_media (struct net_device *dev) + static int + mii_set_media (struct net_device *dev) + { +- PHY_SCR_t pscr; +- BMCR_t bmcr; +- BMSR_t bmsr; +- ANAR_t anar; ++ __u16 pscr; ++ __u16 bmcr; ++ __u16 bmsr; ++ __u16 anar; + int phy_addr; + struct netdev_private *np; + np = netdev_priv(dev); +@@ -1549,76 +1552,77 @@ mii_set_media (struct net_device *dev) + /* Does user set speed? */ + if (np->an_enable) { + /* Advertise capabilities */ +- bmsr.image = mii_read (dev, phy_addr, MII_BMSR); +- anar.image = mii_read (dev, phy_addr, MII_ANAR); +- anar.bits.media_100BX_FD = bmsr.bits.media_100BX_FD; +- anar.bits.media_100BX_HD = bmsr.bits.media_100BX_HD; +- anar.bits.media_100BT4 = bmsr.bits.media_100BT4; +- anar.bits.media_10BT_FD = bmsr.bits.media_10BT_FD; +- anar.bits.media_10BT_HD = bmsr.bits.media_10BT_HD; +- anar.bits.pause = 1; +- anar.bits.asymmetric = 1; +- mii_write (dev, phy_addr, MII_ANAR, anar.image); ++ bmsr = mii_read (dev, phy_addr, MII_BMSR); ++ anar = mii_read (dev, phy_addr, MII_ANAR) & ++ ~MII_ANAR_100BX_FD & ++ ~MII_ANAR_100BX_HD & ++ ~MII_ANAR_100BT4 & ++ ~MII_ANAR_10BT_FD & ++ ~MII_ANAR_10BT_HD; ++ if (bmsr & MII_BMSR_100BX_FD) ++ anar |= MII_ANAR_100BX_FD; ++ if (bmsr & MII_BMSR_100BX_HD) ++ anar |= MII_ANAR_100BX_HD; ++ if (bmsr & MII_BMSR_100BT4) ++ anar |= MII_ANAR_100BT4; ++ if (bmsr & MII_BMSR_10BT_FD) ++ anar |= MII_ANAR_10BT_FD; ++ if (bmsr & MII_BMSR_10BT_HD) ++ anar |= MII_ANAR_10BT_HD; ++ anar |= MII_ANAR_PAUSE | MII_ANAR_ASYMMETRIC; ++ mii_write (dev, phy_addr, MII_ANAR, anar); + + /* Enable Auto crossover */ +- pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR); +- pscr.bits.mdi_crossover_mode = 3; /* 11'b */ +- mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image); ++ pscr = mii_read (dev, phy_addr, MII_PHY_SCR); ++ pscr |= 3 << 5; /* 11'b */ ++ mii_write (dev, phy_addr, MII_PHY_SCR, pscr); + + /* Soft reset PHY */ + mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET); +- bmcr.image = 0; +- bmcr.bits.an_enable = 1; +- bmcr.bits.restart_an = 1; +- bmcr.bits.reset = 1; +- mii_write (dev, phy_addr, MII_BMCR, bmcr.image); ++ bmcr = MII_BMCR_AN_ENABLE | MII_BMCR_RESTART_AN | MII_BMCR_RESET; ++ mii_write (dev, phy_addr, MII_BMCR, bmcr); + mdelay(1); + } else { + /* Force speed setting */ + /* 1) Disable Auto crossover */ +- pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR); +- pscr.bits.mdi_crossover_mode = 0; +- mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image); ++ pscr = mii_read (dev, phy_addr, MII_PHY_SCR); ++ pscr &= ~(3 << 5); ++ mii_write (dev, phy_addr, MII_PHY_SCR, pscr); + + /* 2) PHY Reset */ +- bmcr.image = mii_read (dev, phy_addr, MII_BMCR); +- bmcr.bits.reset = 1; +- mii_write (dev, phy_addr, MII_BMCR, bmcr.image); ++ bmcr = mii_read (dev, phy_addr, MII_BMCR); ++ bmcr |= MII_BMCR_RESET; ++ mii_write (dev, phy_addr, MII_BMCR, bmcr); + + /* 3) Power Down */ +- bmcr.image = 0x1940; /* must be 0x1940 */ +- mii_write (dev, phy_addr, MII_BMCR, bmcr.image); ++ bmcr = 0x1940; /* must be 0x1940 */ ++ mii_write (dev, phy_addr, MII_BMCR, bmcr); + mdelay (100); /* wait a certain time */ + + /* 4) Advertise nothing */ + mii_write (dev, phy_addr, MII_ANAR, 0); + + /* 5) Set media and Power Up */ +- bmcr.image = 0; +- bmcr.bits.power_down = 1; ++ bmcr = MII_BMCR_POWER_DOWN; + if (np->speed == 100) { +- bmcr.bits.speed100 = 1; +- bmcr.bits.speed1000 = 0; ++ bmcr |= MII_BMCR_SPEED_100; + printk (KERN_INFO "Manual 100 Mbps, "); + } else if (np->speed == 10) { +- bmcr.bits.speed100 = 0; +- bmcr.bits.speed1000 = 0; + printk (KERN_INFO "Manual 10 Mbps, "); + } + if (np->full_duplex) { +- bmcr.bits.duplex_mode = 1; ++ bmcr |= MII_BMCR_DUPLEX_MODE; + printk ("Full duplex\n"); + } else { +- bmcr.bits.duplex_mode = 0; + printk ("Half duplex\n"); + } + #if 0 + /* Set 1000BaseT Master/Slave setting */ +- mscr.image = mii_read (dev, phy_addr, MII_MSCR); +- mscr.bits.cfg_enable = 1; +- mscr.bits.cfg_value = 0; ++ mscr = mii_read (dev, phy_addr, MII_MSCR); ++ mscr |= MII_MSCR_CFG_ENABLE; ++ mscr &= ~MII_MSCR_CFG_VALUE = 0; + #endif +- mii_write (dev, phy_addr, MII_BMCR, bmcr.image); ++ mii_write (dev, phy_addr, MII_BMCR, bmcr); + mdelay(10); + } + return 0; +@@ -1627,43 +1631,42 @@ mii_set_media (struct net_device *dev) + static int + mii_get_media_pcs (struct net_device *dev) + { +- ANAR_PCS_t negotiate; +- BMSR_t bmsr; +- BMCR_t bmcr; ++ __u16 negotiate; ++ __u16 bmsr; + int phy_addr; + struct netdev_private *np; + + np = netdev_priv(dev); + phy_addr = np->phy_addr; + +- bmsr.image = mii_read (dev, phy_addr, PCS_BMSR); ++ bmsr = mii_read (dev, phy_addr, PCS_BMSR); + if (np->an_enable) { +- if (!bmsr.bits.an_complete) { ++ if (!(bmsr & MII_BMSR_AN_COMPLETE)) { + /* Auto-Negotiation not completed */ + return -1; + } +- negotiate.image = mii_read (dev, phy_addr, PCS_ANAR) & ++ negotiate = mii_read (dev, phy_addr, PCS_ANAR) & + mii_read (dev, phy_addr, PCS_ANLPAR); + np->speed = 1000; +- if (negotiate.bits.full_duplex) { ++ if (negotiate & PCS_ANAR_FULL_DUPLEX) { + printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n"); + np->full_duplex = 1; + } else { + printk (KERN_INFO "Auto 1000 Mbps, half duplex\n"); + np->full_duplex = 0; + } +- if (negotiate.bits.pause) { ++ if (negotiate & PCS_ANAR_PAUSE) { + np->tx_flow &= 1; + np->rx_flow &= 1; +- } else if (negotiate.bits.asymmetric) { ++ } else if (negotiate & PCS_ANAR_ASYMMETRIC) { + np->tx_flow = 0; + np->rx_flow &= 1; + } + /* else tx_flow, rx_flow = user select */ + } else { +- bmcr.image = mii_read (dev, phy_addr, PCS_BMCR); ++ __u16 bmcr = mii_read (dev, phy_addr, PCS_BMCR); + printk (KERN_INFO "Operating at 1000 Mbps, "); +- if (bmcr.bits.duplex_mode) { ++ if (bmcr & MII_BMCR_DUPLEX_MODE) { + printk ("Full duplex\n"); + } else { + printk ("Half duplex\n"); +@@ -1684,9 +1687,9 @@ mii_get_media_pcs (struct net_device *dev) + static int + mii_set_media_pcs (struct net_device *dev) + { +- BMCR_t bmcr; +- ESR_t esr; +- ANAR_PCS_t anar; ++ __u16 bmcr; ++ __u16 esr; ++ __u16 anar; + int phy_addr; + struct netdev_private *np; + np = netdev_priv(dev); +@@ -1695,41 +1698,37 @@ mii_set_media_pcs (struct net_device *dev) + /* Auto-Negotiation? */ + if (np->an_enable) { + /* Advertise capabilities */ +- esr.image = mii_read (dev, phy_addr, PCS_ESR); +- anar.image = mii_read (dev, phy_addr, MII_ANAR); +- anar.bits.half_duplex = +- esr.bits.media_1000BT_HD | esr.bits.media_1000BX_HD; +- anar.bits.full_duplex = +- esr.bits.media_1000BT_FD | esr.bits.media_1000BX_FD; +- anar.bits.pause = 1; +- anar.bits.asymmetric = 1; +- mii_write (dev, phy_addr, MII_ANAR, anar.image); ++ esr = mii_read (dev, phy_addr, PCS_ESR); ++ anar = mii_read (dev, phy_addr, MII_ANAR) & ++ ~PCS_ANAR_HALF_DUPLEX & ++ ~PCS_ANAR_FULL_DUPLEX; ++ if (esr & (MII_ESR_1000BT_HD | MII_ESR_1000BX_HD)) ++ anar |= PCS_ANAR_HALF_DUPLEX; ++ if (esr & (MII_ESR_1000BT_FD | MII_ESR_1000BX_FD)) ++ anar |= PCS_ANAR_FULL_DUPLEX; ++ anar |= PCS_ANAR_PAUSE | PCS_ANAR_ASYMMETRIC; ++ mii_write (dev, phy_addr, MII_ANAR, anar); + + /* Soft reset PHY */ + mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET); +- bmcr.image = 0; +- bmcr.bits.an_enable = 1; +- bmcr.bits.restart_an = 1; +- bmcr.bits.reset = 1; +- mii_write (dev, phy_addr, MII_BMCR, bmcr.image); ++ bmcr = MII_BMCR_AN_ENABLE | MII_BMCR_RESTART_AN | ++ MII_BMCR_RESET; ++ mii_write (dev, phy_addr, MII_BMCR, bmcr); + mdelay(1); + } else { + /* Force speed setting */ + /* PHY Reset */ +- bmcr.image = 0; +- bmcr.bits.reset = 1; +- mii_write (dev, phy_addr, MII_BMCR, bmcr.image); ++ bmcr = MII_BMCR_RESET; ++ mii_write (dev, phy_addr, MII_BMCR, bmcr); + mdelay(10); +- bmcr.image = 0; +- bmcr.bits.an_enable = 0; + if (np->full_duplex) { +- bmcr.bits.duplex_mode = 1; ++ bmcr = MII_BMCR_DUPLEX_MODE; + printk (KERN_INFO "Manual full duplex\n"); + } else { +- bmcr.bits.duplex_mode = 0; ++ bmcr = 0; + printk (KERN_INFO "Manual half duplex\n"); + } +- mii_write (dev, phy_addr, MII_BMCR, bmcr.image); ++ mii_write (dev, phy_addr, MII_BMCR, bmcr); + mdelay(10); + + /* Advertise nothing */ +diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h +index 014b77c..d66c605 100644 +--- a/drivers/net/dl2k.h ++++ b/drivers/net/dl2k.h +@@ -298,23 +298,6 @@ enum _pcs_reg { + }; + + /* Basic Mode Control Register */ +-typedef union t_MII_BMCR { +- u16 image; +- struct { +- u16 _bit_5_0:6; // bit 5:0 +- u16 speed1000:1; // bit 6 +- u16 col_test_enable:1; // bit 7 +- u16 duplex_mode:1; // bit 8 +- u16 restart_an:1; // bit 9 +- u16 isolate:1; // bit 10 +- u16 power_down:1; // bit 11 +- u16 an_enable:1; // bit 12 +- u16 speed100:1; // bit 13 +- u16 loopback:1; // bit 14 +- u16 reset:1; // bit 15 +- } bits; +-} BMCR_t, *PBMCR_t; +- + enum _mii_bmcr { + MII_BMCR_RESET = 0x8000, + MII_BMCR_LOOP_BACK = 0x4000, +@@ -333,28 +316,6 @@ enum _mii_bmcr { + }; + + /* Basic Mode Status Register */ +-typedef union t_MII_BMSR { +- u16 image; +- struct { +- u16 ext_capability:1; // bit 0 +- u16 japper_detect:1; // bit 1 +- u16 link_status:1; // bit 2 +- u16 an_ability:1; // bit 3 +- u16 remote_fault:1; // bit 4 +- u16 an_complete:1; // bit 5 +- u16 preamble_supp:1; // bit 6 +- u16 _bit_7:1; // bit 7 +- u16 ext_status:1; // bit 8 +- u16 media_100BT2_HD:1; // bit 9 +- u16 media_100BT2_FD:1; // bit 10 +- u16 media_10BT_HD:1; // bit 11 +- u16 media_10BT_FD:1; // bit 12 +- u16 media_100BX_HD:1; // bit 13 +- u16 media_100BX_FD:1; // bit 14 +- u16 media_100BT4:1; // bit 15 +- } bits; +-} BMSR_t, *PBMSR_t; +- + enum _mii_bmsr { + MII_BMSR_100BT4 = 0x8000, + MII_BMSR_100BX_FD = 0x4000, +@@ -374,24 +335,6 @@ enum _mii_bmsr { + }; + + /* ANAR */ +-typedef union t_MII_ANAR { +- u16 image; +- struct { +- u16 selector:5; // bit 4:0 +- u16 media_10BT_HD:1; // bit 5 +- u16 media_10BT_FD:1; // bit 6 +- u16 media_100BX_HD:1; // bit 7 +- u16 media_100BX_FD:1; // bit 8 +- u16 media_100BT4:1; // bit 9 +- u16 pause:1; // bit 10 +- u16 asymmetric:1; // bit 11 +- u16 _bit12:1; // bit 12 +- u16 remote_fault:1; // bit 13 +- u16 _bit14:1; // bit 14 +- u16 next_page:1; // bit 15 +- } bits; +-} ANAR_t, *PANAR_t; +- + enum _mii_anar { + MII_ANAR_NEXT_PAGE = 0x8000, + MII_ANAR_REMOTE_FAULT = 0x4000, +@@ -407,24 +350,6 @@ enum _mii_anar { + }; + + /* ANLPAR */ +-typedef union t_MII_ANLPAR { +- u16 image; +- struct { +- u16 selector:5; // bit 4:0 +- u16 media_10BT_HD:1; // bit 5 +- u16 media_10BT_FD:1; // bit 6 +- u16 media_100BX_HD:1; // bit 7 +- u16 media_100BX_FD:1; // bit 8 +- u16 media_100BT4:1; // bit 9 +- u16 pause:1; // bit 10 +- u16 asymmetric:1; // bit 11 +- u16 _bit12:1; // bit 12 +- u16 remote_fault:1; // bit 13 +- u16 _bit14:1; // bit 14 +- u16 next_page:1; // bit 15 +- } bits; +-} ANLPAR_t, *PANLPAR_t; +- + enum _mii_anlpar { + MII_ANLPAR_NEXT_PAGE = MII_ANAR_NEXT_PAGE, + MII_ANLPAR_REMOTE_FAULT = MII_ANAR_REMOTE_FAULT, +@@ -439,18 +364,6 @@ enum _mii_anlpar { + }; + + /* Auto-Negotiation Expansion Register */ +-typedef union t_MII_ANER { +- u16 image; +- struct { +- u16 lp_negotiable:1; // bit 0 +- u16 page_received:1; // bit 1 +- u16 nextpagable:1; // bit 2 +- u16 lp_nextpagable:1; // bit 3 +- u16 pdetect_fault:1; // bit 4 +- u16 _bit15_5:11; // bit 15:5 +- } bits; +-} ANER_t, *PANER_t; +- + enum _mii_aner { + MII_ANER_PAR_DETECT_FAULT = 0x0010, + MII_ANER_LP_NEXTPAGABLE = 0x0008, +@@ -460,19 +373,6 @@ enum _mii_aner { + }; + + /* MASTER-SLAVE Control Register */ +-typedef union t_MII_MSCR { +- u16 image; +- struct { +- u16 _bit_7_0:8; // bit 7:0 +- u16 media_1000BT_HD:1; // bit 8 +- u16 media_1000BT_FD:1; // bit 9 +- u16 port_type:1; // bit 10 +- u16 cfg_value:1; // bit 11 +- u16 cfg_enable:1; // bit 12 +- u16 test_mode:3; // bit 15:13 +- } bits; +-} MSCR_t, *PMSCR_t; +- + enum _mii_mscr { + MII_MSCR_TEST_MODE = 0xe000, + MII_MSCR_CFG_ENABLE = 0x1000, +@@ -483,20 +383,6 @@ enum _mii_mscr { + }; + + /* MASTER-SLAVE Status Register */ +-typedef union t_MII_MSSR { +- u16 image; +- struct { +- u16 idle_err_count:8; // bit 7:0 +- u16 _bit_9_8:2; // bit 9:8 +- u16 lp_1000BT_HD:1; // bit 10 +- u16 lp_1000BT_FD:1; // bit 11 +- u16 remote_rcv_status:1; // bit 12 +- u16 local_rcv_status:1; // bit 13 +- u16 cfg_resolution:1; // bit 14 +- u16 cfg_fault:1; // bit 15 +- } bits; +-} MSSR_t, *PMSSR_t; +- + enum _mii_mssr { + MII_MSSR_CFG_FAULT = 0x8000, + MII_MSSR_CFG_RES = 0x4000, +@@ -508,17 +394,6 @@ enum _mii_mssr { + }; + + /* IEEE Extened Status Register */ +-typedef union t_MII_ESR { +- u16 image; +- struct { +- u16 _bit_11_0:12; // bit 11:0 +- u16 media_1000BT_HD:2; // bit 12 +- u16 media_1000BT_FD:1; // bit 13 +- u16 media_1000BX_HD:1; // bit 14 +- u16 media_1000BX_FD:1; // bit 15 +- } bits; +-} ESR_t, *PESR_t; +- + enum _mii_esr { + MII_ESR_1000BX_FD = 0x8000, + MII_ESR_1000BX_HD = 0x4000, +@@ -526,6 +401,7 @@ enum _mii_esr { + MII_ESR_1000BT_HD = 0x1000, + }; + /* PHY Specific Control Register */ ++#if 0 + typedef union t_MII_PHY_SCR { + u16 image; + struct { +@@ -543,6 +419,7 @@ typedef union t_MII_PHY_SCR { + u16 xmit_fifo_depth:2; // bit 15:14 + } bits; + } PHY_SCR_t, *PPHY_SCR_t; ++#endif + + typedef enum t_MII_ADMIN_STATUS { + adm_reset, +@@ -556,21 +433,6 @@ typedef enum t_MII_ADMIN_STATUS { + /* PCS control and status registers bitmap as the same as MII */ + /* PCS Extended Status register bitmap as the same as MII */ + /* PCS ANAR */ +-typedef union t_PCS_ANAR { +- u16 image; +- struct { +- u16 _bit_4_0:5; // bit 4:0 +- u16 full_duplex:1; // bit 5 +- u16 half_duplex:1; // bit 6 +- u16 asymmetric:1; // bit 7 +- u16 pause:1; // bit 8 +- u16 _bit_11_9:3; // bit 11:9 +- u16 remote_fault:2; // bit 13:12 +- u16 _bit_14:1; // bit 14 +- u16 next_page:1; // bit 15 +- } bits; +-} ANAR_PCS_t, *PANAR_PCS_t; +- + enum _pcs_anar { + PCS_ANAR_NEXT_PAGE = 0x8000, + PCS_ANAR_REMOTE_FAULT = 0x3000, +@@ -580,21 +442,6 @@ enum _pcs_anar { + PCS_ANAR_FULL_DUPLEX = 0x0020, + }; + /* PCS ANLPAR */ +-typedef union t_PCS_ANLPAR { +- u16 image; +- struct { +- u16 _bit_4_0:5; // bit 4:0 +- u16 full_duplex:1; // bit 5 +- u16 half_duplex:1; // bit 6 +- u16 asymmetric:1; // bit 7 +- u16 pause:1; // bit 8 +- u16 _bit_11_9:3; // bit 11:9 +- u16 remote_fault:2; // bit 13:12 +- u16 _bit_14:1; // bit 14 +- u16 next_page:1; // bit 15 +- } bits; +-} ANLPAR_PCS_t, *PANLPAR_PCS_t; +- + enum _pcs_anlpar { + PCS_ANLPAR_NEXT_PAGE = PCS_ANAR_NEXT_PAGE, + PCS_ANLPAR_REMOTE_FAULT = PCS_ANAR_REMOTE_FAULT, +diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c +index 13d57b0..76c0fa6 100644 +--- a/drivers/net/e1000/e1000_main.c ++++ b/drivers/net/e1000/e1000_main.c +@@ -632,6 +632,7 @@ e1000_down(struct e1000_adapter *adapter) + + #ifdef CONFIG_E1000_NAPI + napi_disable(&adapter->napi); ++ atomic_set(&adapter->irq_sem, 0); + #endif + e1000_irq_disable(adapter); + +@@ -3919,7 +3920,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 +3930,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)) +diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c +index 4a6fc74..9cc5a6b 100644 +--- a/drivers/net/e1000e/netdev.c ++++ b/drivers/net/e1000e/netdev.c +@@ -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) +@@ -2180,6 +2183,7 @@ void e1000e_down(struct e1000_adapter *adapter) + msleep(10); + + napi_disable(&adapter->napi); ++ atomic_set(&adapter->irq_sem, 0); + e1000_irq_disable(adapter); + + del_timer_sync(&adapter->watchdog_timer); +diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c +index dbd23bb..50f0c17 100644 +--- a/drivers/net/ipg.c ++++ b/drivers/net/ipg.c +@@ -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); + +diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c +index d2fb88d..4f63839 100644 +--- a/drivers/net/ixgb/ixgb_main.c ++++ b/drivers/net/ixgb/ixgb_main.c +@@ -296,6 +296,11 @@ ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog) + { + struct net_device *netdev = adapter->netdev; + ++#ifdef CONFIG_IXGB_NAPI ++ napi_disable(&adapter->napi); ++ atomic_set(&adapter->irq_sem, 0); ++#endif ++ + ixgb_irq_disable(adapter); + free_irq(adapter->pdev->irq, netdev); + +@@ -304,9 +309,7 @@ ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog) + + if(kill_watchdog) + del_timer_sync(&adapter->watchdog_timer); +-#ifdef CONFIG_IXGB_NAPI +- napi_disable(&adapter->napi); +-#endif ++ + adapter->link_speed = 0; + adapter->link_duplex = 0; + netif_carrier_off(netdev); +diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c +index a564916..a4265bc 100644 +--- a/drivers/net/ixgbe/ixgbe_main.c ++++ b/drivers/net/ixgbe/ixgbe_main.c +@@ -1409,9 +1409,11 @@ void ixgbe_down(struct ixgbe_adapter *adapter) + IXGBE_WRITE_FLUSH(&adapter->hw); + msleep(10); + ++ napi_disable(&adapter->napi); ++ atomic_set(&adapter->irq_sem, 0); ++ + ixgbe_irq_disable(adapter); + +- napi_disable(&adapter->napi); + del_timer_sync(&adapter->watchdog_timer); + + netif_carrier_off(netdev); +@@ -1468,13 +1470,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); +diff --git a/drivers/net/niu.c b/drivers/net/niu.c +index 3bbcea1..5f6beab 100644 +--- a/drivers/net/niu.c ++++ b/drivers/net/niu.c +@@ -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: +diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c +index 2881777..36a7ba3 100644 +--- a/drivers/net/pcmcia/3c574_cs.c ++++ b/drivers/net/pcmcia/3c574_cs.c +@@ -187,14 +187,16 @@ enum Window1 { + enum Window3 { /* Window 3: MAC/config bits. */ + Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8, + }; +-union wn3_config { +- int i; +- struct w3_config_fields { +- unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2; +- int pad8:8; +- unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1; +- int pad24:7; +- } u; ++enum wn3_config { ++ Ram_size = 7, ++ Ram_width = 8, ++ Ram_speed = 0x30, ++ Rom_size = 0xc0, ++ Ram_split_shift = 16, ++ Ram_split = 3 << Ram_split_shift, ++ Xcvr_shift = 20, ++ Xcvr = 7 << Xcvr_shift, ++ Autoselect = 0x1000000, + }; + + enum Window4 { /* Window 4: Xcvr/media bits. */ +@@ -342,7 +344,7 @@ static int tc574_config(struct pcmcia_device *link) + kio_addr_t ioaddr; + __be16 *phys_addr; + char *cardname; +- union wn3_config config; ++ __u32 config; + DECLARE_MAC_BUF(mac); + + phys_addr = (__be16 *)dev->dev_addr; +@@ -401,9 +403,9 @@ static int tc574_config(struct pcmcia_device *link) + outw(0<<11, ioaddr + RunnerRdCtrl); + printk(KERN_INFO " ASIC rev %d,", mcr>>3); + EL3WINDOW(3); +- config.i = inl(ioaddr + Wn3_Config); +- lp->default_media = config.u.xcvr; +- lp->autoselect = config.u.autoselect; ++ config = inl(ioaddr + Wn3_Config); ++ lp->default_media = (config & Xcvr) >> Xcvr_shift; ++ lp->autoselect = config & Autoselect ? 1 : 0; + } + + init_timer(&lp->media); +@@ -464,8 +466,9 @@ static int tc574_config(struct pcmcia_device *link) + dev->name, cardname, dev->base_addr, dev->irq, + print_mac(mac, dev->dev_addr)); + printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n", +- 8 << config.u.ram_size, ram_split[config.u.ram_split], +- config.u.autoselect ? "autoselect " : ""); ++ 8 << config & Ram_size, ++ ram_split[(config & Ram_split) >> Ram_split_shift], ++ config & Autoselect ? "autoselect " : ""); + + return 0; + +diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c +index fa57c49..f2ba944 100644 +--- a/drivers/net/s2io.c ++++ b/drivers/net/s2io.c +@@ -84,7 +84,7 @@ + #include "s2io.h" + #include "s2io-regs.h" + +-#define DRV_VERSION "2.0.26.10" ++#define DRV_VERSION "2.0.26.17" + + /* S2io Driver name & version. */ + static char s2io_driver_name[] = "Neterion"; +@@ -3848,8 +3848,6 @@ static int s2io_open(struct net_device *dev) + netif_carrier_off(dev); + sp->last_link_state = 0; + +- napi_enable(&sp->napi); +- + if (sp->config.intr_type == MSI_X) { + int ret = s2io_enable_msi_x(sp); + +@@ -3892,7 +3890,6 @@ static int s2io_open(struct net_device *dev) + return 0; + + hw_init_failed: +- napi_disable(&sp->napi); + if (sp->config.intr_type == MSI_X) { + if (sp->entries) { + kfree(sp->entries); +@@ -3932,7 +3929,6 @@ static int s2io_close(struct net_device *dev) + return 0; + + netif_stop_queue(dev); +- napi_disable(&sp->napi); + /* Reset card, kill tasklet and free Tx and Rx buffers. */ + s2io_card_down(sp); + +@@ -6796,6 +6792,8 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) + struct XENA_dev_config __iomem *bar0 = sp->bar0; + unsigned long flags; + register u64 val64 = 0; ++ struct config_param *config; ++ config = &sp->config; + + if (!is_s2io_card_up(sp)) + return; +@@ -6807,6 +6805,10 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) + } + clear_bit(__S2IO_STATE_CARD_UP, &sp->state); + ++ /* Disable napi */ ++ if (config->napi) ++ napi_disable(&sp->napi); ++ + /* disable Tx and Rx traffic on the NIC */ + if (do_io) + stop_nic(sp); +@@ -6900,6 +6902,11 @@ static int s2io_card_up(struct s2io_nic * sp) + DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i, + atomic_read(&sp->rx_bufs_left[i])); + } ++ ++ /* Initialise napi */ ++ if (config->napi) ++ napi_enable(&sp->napi); ++ + /* Maintain the state prior to the open */ + if (sp->promisc_flg) + sp->promisc_flg = 0; +diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c +index 7023bbe..bc15940 100644 +--- a/drivers/net/sky2.c ++++ b/drivers/net/sky2.c +@@ -3949,7 +3949,7 @@ static __exit void sky2_debug_cleanup(void) + /* Initialize network device */ + static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, + unsigned port, +- int highmem) ++ int highmem, int wol) + { + struct sky2_port *sky2; + struct net_device *dev = alloc_etherdev(sizeof(*sky2)); +@@ -3989,7 +3989,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, + sky2->speed = -1; + sky2->advertising = sky2_supported_modes(hw); + sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL); +- sky2->wol = sky2_wol_supported(hw) & WAKE_MAGIC; ++ sky2->wol = wol; + + spin_lock_init(&sky2->phy_lock); + sky2->tx_pending = TX_DEF_PENDING; +@@ -4086,12 +4086,24 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) + return err; + } + ++static int __devinit pci_wake_enabled(struct pci_dev *dev) ++{ ++ int pm = pci_find_capability(dev, PCI_CAP_ID_PM); ++ u16 value; ++ ++ if (!pm) ++ return 0; ++ if (pci_read_config_word(dev, pm + PCI_PM_CTRL, &value)) ++ return 0; ++ return value & PCI_PM_CTRL_PME_ENABLE; ++} ++ + static int __devinit sky2_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { + struct net_device *dev; + struct sky2_hw *hw; +- int err, using_dac = 0; ++ int err, using_dac = 0, wol_default; + + err = pci_enable_device(pdev); + if (err) { +@@ -4124,6 +4136,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev, + } + } + ++ wol_default = pci_wake_enabled(pdev) ? WAKE_MAGIC : 0; ++ + err = -ENOMEM; + hw = kzalloc(sizeof(*hw), GFP_KERNEL); + if (!hw) { +@@ -4167,7 +4181,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, + + sky2_reset(hw); + +- dev = sky2_init_netdev(hw, 0, using_dac); ++ dev = sky2_init_netdev(hw, 0, using_dac, wol_default); + if (!dev) { + err = -ENOMEM; + goto err_out_free_pci; +@@ -4204,7 +4218,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, + if (hw->ports > 1) { + struct net_device *dev1; + +- dev1 = sky2_init_netdev(hw, 1, using_dac); ++ dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default); + if (!dev1) + dev_warn(&pdev->dev, "allocation for second device failed\n"); + else if ((err = register_netdev(dev1))) { +diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c +index d887c05..370d329 100644 +--- a/drivers/net/tc35815.c ++++ b/drivers/net/tc35815.c +@@ -611,7 +611,7 @@ static int __devinit tc35815_mac_match(struct device *dev, void *data) + { + struct platform_device *plat_dev = to_platform_device(dev); + struct pci_dev *pci_dev = data; +- unsigned int id = (pci_dev->bus->number << 8) | pci_dev->devfn; ++ unsigned int id = pci_dev->irq; + return !strcmp(plat_dev->name, "tc35815-mac") && plat_dev->id == id; + } + +diff --git a/drivers/net/veth.c b/drivers/net/veth.c +index 43af9e9..3f67a29 100644 +--- a/drivers/net/veth.c ++++ b/drivers/net/veth.c +@@ -459,19 +459,7 @@ static __init int veth_init(void) + + static __exit void veth_exit(void) + { +- struct veth_priv *priv, *next; +- +- rtnl_lock(); +- /* +- * cannot trust __rtnl_link_unregister() to unregister all +- * devices, as each ->dellink call will remove two devices +- * from the list at once. +- */ +- list_for_each_entry_safe(priv, next, &veth_list, list) +- veth_dellink(priv->dev); +- +- __rtnl_link_unregister(&veth_link_ops); +- rtnl_unlock(); ++ rtnl_link_unregister(&veth_link_ops); + } + + module_init(veth_init); +diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c +index 33dc713..c6f26e2 100644 +--- a/drivers/net/wan/dscc4.c ++++ b/drivers/net/wan/dscc4.c +@@ -139,19 +139,21 @@ struct thingie { + }; + + struct TxFD { +- u32 state; +- u32 next; +- u32 data; +- u32 complete; ++ __le32 state; ++ __le32 next; ++ __le32 data; ++ __le32 complete; + u32 jiffies; /* Allows sizeof(TxFD) == sizeof(RxFD) + extra hack */ ++ /* FWIW, datasheet calls that "dummy" and says that card ++ * never looks at it; neither does the driver */ + }; + + struct RxFD { +- u32 state1; +- u32 next; +- u32 data; +- u32 state2; +- u32 end; ++ __le32 state1; ++ __le32 next; ++ __le32 data; ++ __le32 state2; ++ __le32 end; + }; + + #define DUMMY_SKB_SIZE 64 +@@ -181,7 +183,7 @@ struct RxFD { + #define SCC_REG_START(dpriv) (SCC_START+(dpriv->dev_id)*SCC_OFFSET) + + struct dscc4_pci_priv { +- u32 *iqcfg; ++ __le32 *iqcfg; + int cfg_cur; + spinlock_t lock; + struct pci_dev *pdev; +@@ -197,8 +199,8 @@ struct dscc4_dev_priv { + + struct RxFD *rx_fd; + struct TxFD *tx_fd; +- u32 *iqrx; +- u32 *iqtx; ++ __le32 *iqrx; ++ __le32 *iqtx; + + /* FIXME: check all the volatile are required */ + volatile u32 tx_current; +@@ -298,7 +300,7 @@ struct dscc4_dev_priv { + #define BrrExpMask 0x00000f00 + #define BrrMultMask 0x0000003f + #define EncodingMask 0x00700000 +-#define Hold 0x40000000 ++#define Hold cpu_to_le32(0x40000000) + #define SccBusy 0x10000000 + #define PowerUp 0x80000000 + #define Vis 0x00001000 +@@ -307,14 +309,14 @@ struct dscc4_dev_priv { + #define FrameRdo 0x40 + #define FrameCrc 0x20 + #define FrameRab 0x10 +-#define FrameAborted 0x00000200 +-#define FrameEnd 0x80000000 +-#define DataComplete 0x40000000 ++#define FrameAborted cpu_to_le32(0x00000200) ++#define FrameEnd cpu_to_le32(0x80000000) ++#define DataComplete cpu_to_le32(0x40000000) + #define LengthCheck 0x00008000 + #define SccEvt 0x02000000 + #define NoAck 0x00000200 + #define Action 0x00000001 +-#define HiDesc 0x20000000 ++#define HiDesc cpu_to_le32(0x20000000) + + /* SCC events */ + #define RxEvt 0xf0000000 +@@ -489,8 +491,8 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv) + skbuff = dpriv->tx_skbuff; + for (i = 0; i < TX_RING_SIZE; i++) { + if (*skbuff) { +- pci_unmap_single(pdev, tx_fd->data, (*skbuff)->len, +- PCI_DMA_TODEVICE); ++ pci_unmap_single(pdev, le32_to_cpu(tx_fd->data), ++ (*skbuff)->len, PCI_DMA_TODEVICE); + dev_kfree_skb(*skbuff); + } + skbuff++; +@@ -500,7 +502,7 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv) + skbuff = dpriv->rx_skbuff; + for (i = 0; i < RX_RING_SIZE; i++) { + if (*skbuff) { +- pci_unmap_single(pdev, rx_fd->data, ++ pci_unmap_single(pdev, le32_to_cpu(rx_fd->data), + RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE); + dev_kfree_skb(*skbuff); + } +@@ -522,10 +524,10 @@ static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv, + dpriv->rx_skbuff[dirty] = skb; + if (skb) { + skb->protocol = hdlc_type_trans(skb, dev); +- rx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data, +- len, PCI_DMA_FROMDEVICE); ++ rx_fd->data = cpu_to_le32(pci_map_single(dpriv->pci_priv->pdev, ++ skb->data, len, PCI_DMA_FROMDEVICE)); + } else { +- rx_fd->data = (u32) NULL; ++ rx_fd->data = 0; + ret = -1; + } + return ret; +@@ -587,7 +589,7 @@ static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv) + + do { + if (!(dpriv->flags & (NeedIDR | NeedIDT)) || +- (dpriv->iqtx[cur] & Xpr)) ++ (dpriv->iqtx[cur] & cpu_to_le32(Xpr))) + break; + smp_rmb(); + schedule_timeout_uninterruptible(10); +@@ -650,8 +652,9 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv, + printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __FUNCTION__); + goto refill; + } +- pkt_len = TO_SIZE(rx_fd->state2); +- pci_unmap_single(pdev, rx_fd->data, RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE); ++ pkt_len = TO_SIZE(le32_to_cpu(rx_fd->state2)); ++ pci_unmap_single(pdev, le32_to_cpu(rx_fd->data), ++ RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE); + if ((skb->data[--pkt_len] & FrameOk) == FrameOk) { + stats->rx_packets++; + stats->rx_bytes += pkt_len; +@@ -679,7 +682,7 @@ refill: + } + dscc4_rx_update(dpriv, dev); + rx_fd->state2 = 0x00000000; +- rx_fd->end = 0xbabeface; ++ rx_fd->end = cpu_to_le32(0xbabeface); + } + + static void dscc4_free1(struct pci_dev *pdev) +@@ -772,8 +775,8 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, + } + /* Global interrupt queue */ + writel((u32)(((IRQ_RING_SIZE >> 5) - 1) << 20), ioaddr + IQLENR1); +- priv->iqcfg = (u32 *) pci_alloc_consistent(pdev, +- IRQ_RING_SIZE*sizeof(u32), &priv->iqcfg_dma); ++ priv->iqcfg = (__le32 *) pci_alloc_consistent(pdev, ++ IRQ_RING_SIZE*sizeof(__le32), &priv->iqcfg_dma); + if (!priv->iqcfg) + goto err_free_irq_5; + writel(priv->iqcfg_dma, ioaddr + IQCFG); +@@ -786,7 +789,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, + */ + for (i = 0; i < dev_per_card; i++) { + dpriv = priv->root + i; +- dpriv->iqtx = (u32 *) pci_alloc_consistent(pdev, ++ dpriv->iqtx = (__le32 *) pci_alloc_consistent(pdev, + IRQ_RING_SIZE*sizeof(u32), &dpriv->iqtx_dma); + if (!dpriv->iqtx) + goto err_free_iqtx_6; +@@ -794,7 +797,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, + } + for (i = 0; i < dev_per_card; i++) { + dpriv = priv->root + i; +- dpriv->iqrx = (u32 *) pci_alloc_consistent(pdev, ++ dpriv->iqrx = (__le32 *) pci_alloc_consistent(pdev, + IRQ_RING_SIZE*sizeof(u32), &dpriv->iqrx_dma); + if (!dpriv->iqrx) + goto err_free_iqrx_7; +@@ -1156,8 +1159,8 @@ static int dscc4_start_xmit(struct sk_buff *skb, struct net_device *dev) + dpriv->tx_skbuff[next] = skb; + tx_fd = dpriv->tx_fd + next; + tx_fd->state = FrameEnd | TO_STATE_TX(skb->len); +- tx_fd->data = pci_map_single(ppriv->pdev, skb->data, skb->len, +- PCI_DMA_TODEVICE); ++ tx_fd->data = cpu_to_le32(pci_map_single(ppriv->pdev, skb->data, skb->len, ++ PCI_DMA_TODEVICE)); + tx_fd->complete = 0x00000000; + tx_fd->jiffies = jiffies; + mb(); +@@ -1508,7 +1511,7 @@ static irqreturn_t dscc4_irq(int irq, void *token) + if (state & Cfg) { + if (debug > 0) + printk(KERN_DEBUG "%s: CfgIV\n", DRV_NAME); +- if (priv->iqcfg[priv->cfg_cur++%IRQ_RING_SIZE] & Arf) ++ if (priv->iqcfg[priv->cfg_cur++%IRQ_RING_SIZE] & cpu_to_le32(Arf)) + printk(KERN_ERR "%s: %s failed\n", dev->name, "CFG"); + if (!(state &= ~Cfg)) + goto out; +@@ -1541,7 +1544,7 @@ static void dscc4_tx_irq(struct dscc4_pci_priv *ppriv, + + try: + cur = dpriv->iqtx_current%IRQ_RING_SIZE; +- state = dpriv->iqtx[cur]; ++ state = le32_to_cpu(dpriv->iqtx[cur]); + if (!state) { + if (debug > 4) + printk(KERN_DEBUG "%s: Tx ISR = 0x%08x\n", dev->name, +@@ -1580,7 +1583,7 @@ try: + tx_fd = dpriv->tx_fd + cur; + skb = dpriv->tx_skbuff[cur]; + if (skb) { +- pci_unmap_single(ppriv->pdev, tx_fd->data, ++ pci_unmap_single(ppriv->pdev, le32_to_cpu(tx_fd->data), + skb->len, PCI_DMA_TODEVICE); + if (tx_fd->state & FrameEnd) { + stats->tx_packets++; +@@ -1711,7 +1714,7 @@ static void dscc4_rx_irq(struct dscc4_pci_priv *priv, + + try: + cur = dpriv->iqrx_current%IRQ_RING_SIZE; +- state = dpriv->iqrx[cur]; ++ state = le32_to_cpu(dpriv->iqrx[cur]); + if (!state) + return; + dpriv->iqrx[cur] = 0; +@@ -1755,7 +1758,7 @@ try: + goto try; + rx_fd->state1 &= ~Hold; + rx_fd->state2 = 0x00000000; +- rx_fd->end = 0xbabeface; ++ rx_fd->end = cpu_to_le32(0xbabeface); + //} + goto try; + } +@@ -1834,7 +1837,7 @@ try: + hdlc_stats(dev)->rx_over_errors++; + rx_fd->state1 |= Hold; + rx_fd->state2 = 0x00000000; +- rx_fd->end = 0xbabeface; ++ rx_fd->end = cpu_to_le32(0xbabeface); + } else + dscc4_rx_skb(dpriv, dev); + } while (1); +@@ -1904,8 +1907,9 @@ static struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv) + skb_copy_to_linear_data(skb, version, + strlen(version) % DUMMY_SKB_SIZE); + tx_fd->state = FrameEnd | TO_STATE_TX(DUMMY_SKB_SIZE); +- tx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data, +- DUMMY_SKB_SIZE, PCI_DMA_TODEVICE); ++ tx_fd->data = cpu_to_le32(pci_map_single(dpriv->pci_priv->pdev, ++ skb->data, DUMMY_SKB_SIZE, ++ PCI_DMA_TODEVICE)); + dpriv->tx_skbuff[last] = skb; + } + return skb; +@@ -1937,8 +1941,8 @@ static int dscc4_init_ring(struct net_device *dev) + tx_fd->state = FrameEnd | TO_STATE_TX(2*DUMMY_SKB_SIZE); + tx_fd->complete = 0x00000000; + /* FIXME: NULL should be ok - to be tried */ +- tx_fd->data = dpriv->tx_fd_dma; +- (tx_fd++)->next = (u32)(dpriv->tx_fd_dma + ++ tx_fd->data = cpu_to_le32(dpriv->tx_fd_dma); ++ (tx_fd++)->next = cpu_to_le32(dpriv->tx_fd_dma + + (++i%TX_RING_SIZE)*sizeof(*tx_fd)); + } while (i < TX_RING_SIZE); + +@@ -1951,12 +1955,12 @@ static int dscc4_init_ring(struct net_device *dev) + /* size set by the host. Multiple of 4 bytes please */ + rx_fd->state1 = HiDesc; + rx_fd->state2 = 0x00000000; +- rx_fd->end = 0xbabeface; ++ rx_fd->end = cpu_to_le32(0xbabeface); + rx_fd->state1 |= TO_STATE_RX(HDLC_MAX_MRU); + // FIXME: return value verifiee mais traitement suspect + if (try_get_rx_skb(dpriv, dev) >= 0) + dpriv->rx_dirty++; +- (rx_fd++)->next = (u32)(dpriv->rx_fd_dma + ++ (rx_fd++)->next = cpu_to_le32(dpriv->rx_fd_dma + + (++i%RX_RING_SIZE)*sizeof(*rx_fd)); + } while (i < RX_RING_SIZE); + +diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c +index 574737b..c9c878c 100644 +--- a/drivers/net/wan/lmc/lmc_media.c ++++ b/drivers/net/wan/lmc/lmc_media.c +@@ -890,16 +890,8 @@ write_av9110 (lmc_softc_t * sc, u_int32_t n, u_int32_t m, u_int32_t v, + static void + lmc_ssi_watchdog (lmc_softc_t * const sc) + { +- u_int16_t mii17; +- struct ssicsr2 +- { +- unsigned short dtr:1, dsr:1, rts:1, cable:3, crc:1, led0:1, led1:1, +- led2:1, led3:1, fifo:1, ll:1, rl:1, tm:1, loop:1; +- }; +- struct ssicsr2 *ssicsr; +- mii17 = lmc_mii_readreg (sc, 0, 17); +- ssicsr = (struct ssicsr2 *) &mii17; +- if (ssicsr->cable == 7) ++ u_int16_t mii17 = lmc_mii_readreg (sc, 0, 17); ++ if (((mii17 >> 3) & 7) == 7) + { + lmc_led_off (sc, LMC_MII16_LED2); + } +diff --git a/drivers/net/wan/sbni.h b/drivers/net/wan/sbni.h +index 27715e7..8426451 100644 +--- a/drivers/net/wan/sbni.h ++++ b/drivers/net/wan/sbni.h +@@ -44,9 +44,15 @@ enum { + #define PR_RES 0x80 + + struct sbni_csr1 { +- unsigned rxl : 5; +- unsigned rate : 2; +- unsigned : 1; ++#ifdef __LITTLE_ENDIAN_BITFIELD ++ u8 rxl : 5; ++ u8 rate : 2; ++ u8 : 1; ++#else ++ u8 : 1; ++ u8 rate : 2; ++ u8 rxl : 5; ++#endif + }; + + /* fields in frame header */ +diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c +index 98cf70c..11f53cb 100644 +--- a/drivers/net/wireless/b43/rfkill.c ++++ b/drivers/net/wireless/b43/rfkill.c +@@ -138,8 +138,11 @@ void b43_rfkill_init(struct b43_wldev *dev) + rfk->rfkill->user_claim_unsupported = 1; + + rfk->poll_dev = input_allocate_polled_device(); +- if (!rfk->poll_dev) +- goto err_free_rfk; ++ if (!rfk->poll_dev) { ++ rfkill_free(rfk->rfkill); ++ goto err_freed_rfk; ++ } ++ + rfk->poll_dev->private = dev; + rfk->poll_dev->poll = b43_rfkill_poll; + rfk->poll_dev->poll_interval = 1000; /* msecs */ +@@ -175,8 +178,7 @@ err_unreg_rfk: + err_free_polldev: + input_free_polled_device(rfk->poll_dev); + rfk->poll_dev = NULL; +-err_free_rfk: +- rfkill_free(rfk->rfkill); ++err_freed_rfk: + rfk->rfkill = NULL; + out_error: + rfk->registered = 0; +@@ -195,6 +197,5 @@ void b43_rfkill_exit(struct b43_wldev *dev) + rfkill_unregister(rfk->rfkill); + input_free_polled_device(rfk->poll_dev); + rfk->poll_dev = NULL; +- rfkill_free(rfk->rfkill); + rfk->rfkill = NULL; + } +diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c +index 040dc3e..cbf15d7 100644 +--- a/drivers/net/wireless/hostap/hostap_plx.c ++++ b/drivers/net/wireless/hostap/hostap_plx.c +@@ -608,7 +608,7 @@ static void prism2_plx_remove(struct pci_dev *pdev) + + MODULE_DEVICE_TABLE(pci, prism2_plx_id_table); + +-static struct pci_driver prism2_plx_drv_id = { ++static struct pci_driver prism2_plx_driver = { + .name = "hostap_plx", + .id_table = prism2_plx_id_table, + .probe = prism2_plx_probe, +@@ -618,13 +618,13 @@ static struct pci_driver prism2_plx_drv_id = { + + static int __init init_prism2_plx(void) + { +- return pci_register_driver(&prism2_plx_drv_id); ++ return pci_register_driver(&prism2_plx_driver); + } + + + static void __exit exit_prism2_plx(void) + { +- pci_unregister_driver(&prism2_plx_drv_id); ++ pci_unregister_driver(&prism2_plx_driver); + } + + +diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c +index 88062c1..003f73f 100644 +--- a/drivers/net/wireless/ipw2200.c ++++ b/drivers/net/wireless/ipw2200.c +@@ -4935,7 +4935,7 @@ static int ipw_queue_reset(struct ipw_priv *priv) + /** + * Reclaim Tx queue entries no more used by NIC. + * +- * When FW adwances 'R' index, all entries between old and ++ * When FW advances 'R' index, all entries between old and + * new 'R' index need to be reclaimed. As result, some free space + * forms. If there is enough free space (> low mark), wake Tx queue. + * +diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c +index b24425f..4f1efb1 100644 +--- a/drivers/net/wireless/libertas/if_sdio.c ++++ b/drivers/net/wireless/libertas/if_sdio.c +@@ -871,6 +871,10 @@ static int if_sdio_probe(struct sdio_func *func, + if (sscanf(func->card->info[i], + "ID: %x", &model) == 1) + break; ++ if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) { ++ model = 4; ++ break; ++ } + } + + if (i == func->card->num_info) { +diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c +index 6d5d9ab..04663eb 100644 +--- a/drivers/net/wireless/rt2x00/rt2x00pci.c ++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c +@@ -149,7 +149,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) + * The data behind the ieee80211 header must be + * aligned on a 4 byte boundary. + */ +- align = NET_IP_ALIGN + (2 * (header_size % 4 == 0)); ++ align = header_size % 4; + + /* + * Allocate the sk_buffer, initialize it and copy +diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c +index ab4797e..568d738 100644 +--- a/drivers/net/wireless/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/rt2x00/rt2x00usb.c +@@ -245,13 +245,20 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) + * Allocate a new sk buffer to replace the current one. + * If allocation fails, we should drop the current frame + * so we can recycle the existing sk buffer for the new frame. ++ * As alignment we use 2 and not NET_IP_ALIGN because we need ++ * to be sure we have 2 bytes room in the head. (NET_IP_ALIGN ++ * can be 0 on some hardware). We use these 2 bytes for frame ++ * alignment later, we assume that the chance that ++ * header_size % 4 == 2 is bigger then header_size % 2 == 0 ++ * and thus optimize alignment by reserving the 2 bytes in ++ * advance. + */ + frame_size = entry->ring->data_size + entry->ring->desc_size; +- skb = dev_alloc_skb(frame_size + NET_IP_ALIGN); ++ skb = dev_alloc_skb(frame_size + 2); + if (!skb) + goto skip_entry; + +- skb_reserve(skb, NET_IP_ALIGN); ++ skb_reserve(skb, 2); + skb_put(skb, frame_size); + + /* +diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c +index f7b8648..6b9840c 100644 +--- a/drivers/pnp/pnpacpi/rsparser.c ++++ b/drivers/pnp/pnpacpi/rsparser.c +@@ -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; + } + } + +diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c +index feba967..7c069a0 100644 +--- a/drivers/usb/serial/keyspan.c ++++ b/drivers/usb/serial/keyspan.c +@@ -447,7 +447,7 @@ static void usa26_indat_callback(struct urb *urb) + + port = (struct usb_serial_port *) urb->context; + tty = port->tty; +- if (urb->actual_length) { ++ if (tty && urb->actual_length) { + /* 0x80 bit is error flag */ + if ((data[0] & 0x80) == 0) { + /* no errors on individual bytes, only possible overrun err*/ +diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c +index 8d81ef0..08d0725 100644 +--- a/drivers/video/modedb.c ++++ b/drivers/video/modedb.c +@@ -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 + }, + }; + +diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c +index ad35033..b3c31d9 100644 +--- a/drivers/video/s3c2410fb.c ++++ b/drivers/video/s3c2410fb.c +@@ -488,7 +488,7 @@ static int s3c2410fb_set_par(struct fb_info *info) + break; + } + +- info->fix.line_length = (var->width * var->bits_per_pixel) / 8; ++ info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; + + /* activate this new configuration */ + +diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c +index 6ea125e..c622a0e 100644 +--- a/drivers/watchdog/w83697hf_wdt.c ++++ b/drivers/watchdog/w83697hf_wdt.c +@@ -382,10 +382,8 @@ wdt_init(void) + /* we will autodetect the W83697HF/HG watchdog */ + for (i = 0; ((!found) && (w83697hf_ioports[i] != 0)); i++) { + wdt_io = w83697hf_ioports[i]; +- if (!w83697hf_check_wdt()) { ++ if (!w83697hf_check_wdt()) + found++; +- break; +- } + } + } else { + if (!w83697hf_check_wdt()) +diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c +index 31284c7..110dd35 100644 +--- a/fs/hfs/btree.c ++++ b/fs/hfs/btree.c +@@ -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; + } +diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c +index 08ff6c7..038ed74 100644 +--- a/fs/jbd/transaction.c ++++ b/fs/jbd/transaction.c +@@ -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; + } + +diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c +index 3371629..f281cc6 100644 +--- a/fs/sysfs/dir.c ++++ b/fs/sysfs/dir.c +@@ -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); +diff --git a/include/asm-cris/page.h b/include/asm-cris/page.h +index 0648e31..b84353e 100644 +--- a/include/asm-cris/page.h ++++ b/include/asm-cris/page.h +@@ -4,14 +4,11 @@ + #ifdef __KERNEL__ + + #include ++#include + + /* 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) +diff --git a/include/asm-mips/smtc_ipi.h b/include/asm-mips/smtc_ipi.h +index e09131a..8ce5175 100644 +--- a/include/asm-mips/smtc_ipi.h ++++ b/include/asm-mips/smtc_ipi.h +@@ -49,7 +49,7 @@ struct smtc_ipi_q { + + static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p) + { +- long flags; ++ unsigned long flags; + + spin_lock_irqsave(&q->lock, flags); + if (q->head == NULL) +@@ -98,7 +98,7 @@ static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q) + + static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p) + { +- long flags; ++ unsigned long flags; + + spin_lock_irqsave(&q->lock, flags); + if (q->head == NULL) { +@@ -114,7 +114,7 @@ static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p) + + static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q) + { +- long flags; ++ unsigned long flags; + int retval; + + spin_lock_irqsave(&q->lock, flags); +diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h +index 7daafdc..7f28c32 100644 +--- a/include/linux/workqueue.h ++++ b/include/linux/workqueue.h +@@ -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) +diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c +index e65dd0b..f994bb8 100644 +--- a/kernel/hrtimer.c ++++ b/kernel/hrtimer.c +@@ -1378,7 +1378,7 @@ sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) + /* + * Functions related to boot-time initialization: + */ +-static void __devinit init_hrtimers_cpu(int cpu) ++static void __cpuinit init_hrtimers_cpu(int cpu) + { + struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu); + int i; +diff --git a/kernel/kmod.c b/kernel/kmod.c +index c6a4f8a..bb7df2a 100644 +--- a/kernel/kmod.c ++++ b/kernel/kmod.c +@@ -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; + } +diff --git a/kernel/lockdep.c b/kernel/lockdep.c +index 723bd9f..4335f12 100644 +--- a/kernel/lockdep.c ++++ b/kernel/lockdep.c +@@ -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); +diff --git a/kernel/timer.c b/kernel/timer.c +index 26671f4..2a00c22 100644 +--- a/kernel/timer.c ++++ b/kernel/timer.c +@@ -1289,7 +1289,7 @@ static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head) + } + } + +-static void __devinit migrate_timers(int cpu) ++static void __cpuinit migrate_timers(int cpu) + { + tvec_base_t *old_base; + tvec_base_t *new_base; +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 52d5e7c..8db0b59 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -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); +diff --git a/mm/memory.c b/mm/memory.c +index 4bf0b6d..6dd1cd8 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -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 +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index e1028fa..b2838c2 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -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; + +diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c +index 5d8b939..9f78a69 100644 +--- a/net/bridge/br_netfilter.c ++++ b/net/bridge/br_netfilter.c +@@ -142,6 +142,23 @@ static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) + return skb->nf_bridge; + } + ++static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb) ++{ ++ struct nf_bridge_info *nf_bridge = skb->nf_bridge; ++ ++ if (atomic_read(&nf_bridge->use) > 1) { ++ struct nf_bridge_info *tmp = nf_bridge_alloc(skb); ++ ++ if (tmp) { ++ memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info)); ++ atomic_set(&tmp->use, 1); ++ nf_bridge_put(nf_bridge); ++ } ++ nf_bridge = tmp; ++ } ++ return nf_bridge; ++} ++ + static inline void nf_bridge_push_encap_header(struct sk_buff *skb) + { + unsigned int len = nf_bridge_encap_header_len(skb); +@@ -637,6 +654,11 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, + if (!skb->nf_bridge) + return NF_ACCEPT; + ++ /* Need exclusive nf_bridge_info since we might have multiple ++ * different physoutdevs. */ ++ if (!nf_bridge_unshare(skb)) ++ return NF_DROP; ++ + parent = bridge_parent(out); + if (!parent) + return NF_DROP; +@@ -718,6 +740,11 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff *skb, + if (!skb->nf_bridge) + return NF_ACCEPT; + ++ /* Need exclusive nf_bridge_info since we might have multiple ++ * different physoutdevs. */ ++ if (!nf_bridge_unshare(skb)) ++ return NF_DROP; ++ + nf_bridge = skb->nf_bridge; + if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT)) + return NF_ACCEPT; +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index cc8a2f1..29b8ee4 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -1316,6 +1316,8 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) + *p = parms->next; + parms->dead = 1; + write_unlock_bh(&tbl->lock); ++ if (parms->dev) ++ dev_put(parms->dev); + call_rcu(&parms->rcu_head, neigh_rcu_free_parms); + return; + } +@@ -1326,8 +1328,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) + + void neigh_parms_destroy(struct neigh_parms *parms) + { +- if (parms->dev) +- dev_put(parms->dev); + kfree(parms); + } + +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index e1ba26f..fed95a3 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -308,9 +308,12 @@ void __rtnl_link_unregister(struct rtnl_link_ops *ops) + struct net *net; + + for_each_net(net) { ++restart: + for_each_netdev_safe(net, dev, n) { +- if (dev->rtnl_link_ops == ops) ++ if (dev->rtnl_link_ops == ops) { + ops->dellink(dev); ++ goto restart; ++ } + } + } + list_del(&ops->list); +diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c +index 527a6e0..0dfee27 100644 +--- a/net/ipv4/fib_hash.c ++++ b/net/ipv4/fib_hash.c +@@ -444,6 +444,9 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) + struct fib_info *fi_drop; + u8 state; + ++ if (fi->fib_treeref > 1) ++ goto out; ++ + write_lock_bh(&fib_hash_lock); + fi_drop = fa->fa_info; + fa->fa_info = fi; +@@ -718,19 +721,18 @@ fn_hash_dump_zone(struct sk_buff *skb, struct netlink_callback *cb, + { + int h, s_h; + ++ if (fz->fz_hash == NULL) ++ return skb->len; + s_h = cb->args[3]; +- for (h=0; h < fz->fz_divisor; h++) { +- if (h < s_h) continue; +- if (h > s_h) +- memset(&cb->args[4], 0, +- sizeof(cb->args) - 4*sizeof(cb->args[0])); +- if (fz->fz_hash == NULL || +- hlist_empty(&fz->fz_hash[h])) ++ for (h = s_h; h < fz->fz_divisor; h++) { ++ if (hlist_empty(&fz->fz_hash[h])) + continue; +- if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h])<0) { ++ if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h]) < 0) { + cb->args[3] = h; + return -1; + } ++ memset(&cb->args[4], 0, ++ sizeof(cb->args) - 4*sizeof(cb->args[0])); + } + cb->args[3] = h; + return skb->len; +@@ -746,14 +748,13 @@ static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, struct netlin + read_lock(&fib_hash_lock); + for (fz = table->fn_zone_list, m=0; fz; fz = fz->fz_next, m++) { + if (m < s_m) continue; +- if (m > s_m) +- memset(&cb->args[3], 0, +- sizeof(cb->args) - 3*sizeof(cb->args[0])); + if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) { + cb->args[2] = m; + read_unlock(&fib_hash_lock); + return -1; + } ++ memset(&cb->args[3], 0, ++ sizeof(cb->args) - 3*sizeof(cb->args[0])); + } + read_unlock(&fib_hash_lock); + cb->args[2] = m; +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index 8d8c291..1010b46 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -1214,6 +1214,9 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) + struct fib_info *fi_drop; + u8 state; + ++ if (fi->fib_treeref > 1) ++ goto out; ++ + err = -ENOBUFS; + new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); + if (new_fa == NULL) +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index 233de06..82baea0 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -540,7 +540,6 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) + icmp_param.data.icmph.checksum = 0; + icmp_param.skb = skb_in; + icmp_param.offset = skb_network_offset(skb_in); +- icmp_out_count(icmp_param.data.icmph.type); + inet_sk(icmp_socket->sk)->tos = tos; + ipc.addr = iph->saddr; + ipc.opt = &icmp_param.replyopts; +diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c +index 9bb031f..f124068 100644 +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -458,8 +458,6 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, + } + err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr)); + +- ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); +- + out_put: + if (likely(idev != NULL)) + in6_dev_put(idev); +diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c +index adc73ad..0765d8b 100644 +--- a/net/ipv6/inet6_hashtables.c ++++ b/net/ipv6/inet6_hashtables.c +@@ -193,7 +193,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, + sk2->sk_family == PF_INET6 && + ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) && + ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) && +- sk2->sk_bound_dev_if == sk->sk_bound_dev_if) { ++ (!sk2->sk_bound_dev_if || sk2->sk_bound_dev_if == dif)) { + if (twsk_unique(sk, sk2, twp)) + goto unique; + else +diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c +index 8631ed7..4493761 100644 +--- a/net/ipv6/proc.c ++++ b/net/ipv6/proc.c +@@ -88,7 +88,7 @@ static char *icmp6type2name[256] = { + [ICMPV6_PKT_TOOBIG] = "PktTooBigs", + [ICMPV6_TIME_EXCEED] = "TimeExcds", + [ICMPV6_PARAMPROB] = "ParmProblems", +- [ICMPV6_ECHO_REQUEST] = "EchoRequest", ++ [ICMPV6_ECHO_REQUEST] = "Echos", + [ICMPV6_ECHO_REPLY] = "EchoReplies", + [ICMPV6_MGM_QUERY] = "GroupMembQueries", + [ICMPV6_MGM_REPORT] = "GroupMembResponses", +@@ -98,7 +98,7 @@ static char *icmp6type2name[256] = { + [NDISC_ROUTER_SOLICITATION] = "RouterSolicits", + [NDISC_NEIGHBOUR_ADVERTISEMENT] = "NeighborAdvertisements", + [NDISC_NEIGHBOUR_SOLICITATION] = "NeighborSolicits", +- [NDISC_REDIRECT] = "NeighborRedirects", ++ [NDISC_REDIRECT] = "Redirects", + }; + + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 6ecb5e6..20083e0 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -329,7 +329,7 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif) + static inline int rt6_check_neigh(struct rt6_info *rt) + { + struct neighbour *neigh = rt->rt6i_nexthop; +- int m = 0; ++ int m; + if (rt->rt6i_flags & RTF_NONEXTHOP || + !(rt->rt6i_flags & RTF_GATEWAY)) + m = 1; +@@ -337,10 +337,15 @@ static inline int rt6_check_neigh(struct rt6_info *rt) + read_lock_bh(&neigh->lock); + if (neigh->nud_state & NUD_VALID) + m = 2; +- else if (!(neigh->nud_state & NUD_FAILED)) ++#ifdef CONFIG_IPV6_ROUTER_PREF ++ else if (neigh->nud_state & NUD_FAILED) ++ m = 0; ++#endif ++ else + m = 1; + read_unlock_bh(&neigh->lock); +- } ++ } else ++ m = 0; + return m; + } + +diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c +index d5e4dd7..07dfa7f 100644 +--- a/net/irda/af_irda.c ++++ b/net/irda/af_irda.c +@@ -802,12 +802,18 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + } + #endif /* CONFIG_IRDA_ULTRA */ + ++ self->ias_obj = irias_new_object(addr->sir_name, jiffies); ++ if (self->ias_obj == NULL) ++ return -ENOMEM; ++ + err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); +- if (err < 0) ++ if (err < 0) { ++ kfree(self->ias_obj->name); ++ kfree(self->ias_obj); + return err; ++ } + + /* Register with LM-IAS */ +- self->ias_obj = irias_new_object(addr->sir_name, jiffies); + irias_add_integer_attrib(self->ias_obj, "IrDA:TinyTP:LsapSel", + self->stsap_sel, IAS_KERNEL_ATTR); + irias_insert_object(self->ias_obj); +@@ -1825,7 +1831,7 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, + struct irda_ias_set *ias_opt; + struct ias_object *ias_obj; + struct ias_attrib * ias_attr; /* Attribute in IAS object */ +- int opt; ++ int opt, free_ias = 0; + + IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self); + +@@ -1881,11 +1887,20 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, + /* Create a new object */ + ias_obj = irias_new_object(ias_opt->irda_class_name, + jiffies); ++ if (ias_obj == NULL) { ++ kfree(ias_opt); ++ return -ENOMEM; ++ } ++ free_ias = 1; + } + + /* Do we have the attribute already ? */ + if(irias_find_attrib(ias_obj, ias_opt->irda_attrib_name)) { + kfree(ias_opt); ++ if (free_ias) { ++ kfree(ias_obj->name); ++ kfree(ias_obj); ++ } + return -EINVAL; + } + +@@ -1904,6 +1919,11 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, + if(ias_opt->attribute.irda_attrib_octet_seq.len > + IAS_MAX_OCTET_STRING) { + kfree(ias_opt); ++ if (free_ias) { ++ kfree(ias_obj->name); ++ kfree(ias_obj); ++ } ++ + return -EINVAL; + } + /* Add an octet sequence attribute */ +@@ -1932,6 +1952,10 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, + break; + default : + kfree(ias_opt); ++ if (free_ias) { ++ kfree(ias_obj->name); ++ kfree(ias_obj); ++ } + return -EINVAL; + } + irias_insert_object(ias_obj); +diff --git a/net/key/af_key.c b/net/key/af_key.c +index 26d5e63..76dcd88 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -3593,27 +3593,29 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, + /* old ipsecrequest */ + int mode = pfkey_mode_from_xfrm(mp->mode); + if (mode < 0) +- return -EINVAL; ++ goto err; + if (set_ipsecrequest(skb, mp->proto, mode, + (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), + mp->reqid, mp->old_family, +- &mp->old_saddr, &mp->old_daddr) < 0) { +- return -EINVAL; +- } ++ &mp->old_saddr, &mp->old_daddr) < 0) ++ goto err; + + /* new ipsecrequest */ + if (set_ipsecrequest(skb, mp->proto, mode, + (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), + mp->reqid, mp->new_family, +- &mp->new_saddr, &mp->new_daddr) < 0) { +- return -EINVAL; +- } ++ &mp->new_saddr, &mp->new_daddr) < 0) ++ goto err; + } + + /* broadcast migrate message to sockets */ + pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL); + + return 0; ++ ++err: ++ kfree_skb(skb); ++ return -EINVAL; + } + #else + static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, +diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c +index 4469a7b..d06d338 100644 +--- a/net/rfkill/rfkill.c ++++ b/net/rfkill/rfkill.c +@@ -392,11 +392,14 @@ int rfkill_register(struct rfkill *rfkill) + rfkill_led_trigger_register(rfkill); + + error = rfkill_add_switch(rfkill); +- if (error) ++ if (error) { ++ rfkill_led_trigger_unregister(rfkill); + return error; ++ } + + error = device_add(dev); + if (error) { ++ rfkill_led_trigger_unregister(rfkill); + rfkill_remove_switch(rfkill); + return error; + } +diff --git a/security/commoncap.c b/security/commoncap.c +index 5bc1895..ea61bc7 100644 +--- a/security/commoncap.c ++++ b/security/commoncap.c +@@ -59,6 +59,12 @@ int cap_netlink_recv(struct sk_buff *skb, int cap) + + EXPORT_SYMBOL(cap_netlink_recv); + ++/* ++ * NOTE WELL: cap_capable() cannot be used like the kernel's capable() ++ * function. That is, it has the reverse semantics: cap_capable() ++ * returns 0 when a task has a capability, but the kernel's capable() ++ * returns 1 for this case. ++ */ + int cap_capable (struct task_struct *tsk, int cap) + { + /* Derived from include/linux/sched.h:capable. */ +@@ -107,10 +113,11 @@ static inline int cap_block_setpcap(struct task_struct *target) + static inline int cap_inh_is_capped(void) + { + /* +- * return 1 if changes to the inheritable set are limited +- * to the old permitted set. ++ * Return 1 if changes to the inheritable set are limited ++ * to the old permitted set. That is, if the current task ++ * does *not* possess the CAP_SETPCAP capability. + */ +- return !cap_capable(current, CAP_SETPCAP); ++ return (cap_capable(current, CAP_SETPCAP) != 0); + } + + #else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */ +diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c +index d243ddc..66e013d 100644 +--- a/security/selinux/netlabel.c ++++ b/security/selinux/netlabel.c +@@ -53,10 +53,11 @@ static int selinux_netlbl_sock_setsid(struct sock *sk, u32 sid) + struct sk_security_struct *sksec = sk->sk_security; + struct netlbl_lsm_secattr secattr; + ++ netlbl_secattr_init(&secattr); ++ + rc = security_netlbl_sid_to_secattr(sid, &secattr); + if (rc != 0) +- return rc; +- ++ goto sock_setsid_return; + rc = netlbl_sock_setattr(sk, &secattr); + if (rc == 0) { + spin_lock_bh(&sksec->nlbl_lock); +@@ -64,6 +65,8 @@ static int selinux_netlbl_sock_setsid(struct sock *sk, u32 sid) + spin_unlock_bh(&sksec->nlbl_lock); + } + ++sock_setsid_return: ++ netlbl_secattr_destroy(&secattr); + return rc; + } + +diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c +index d572dc9..f83b19d 100644 +--- a/security/selinux/ss/services.c ++++ b/security/selinux/ss/services.c +@@ -2606,8 +2606,6 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) + int rc = -ENOENT; + struct context *ctx; + +- netlbl_secattr_init(secattr); +- + if (!ss_initialized) + return 0; + diff --git a/debian/patches/series/1~experimental.2 b/debian/patches/series/1~experimental.2 index 6c45253e0..16a4d4c7a 100644 --- a/debian/patches/series/1~experimental.2 +++ b/debian/patches/series/1~experimental.2 @@ -1 +1,2 @@ + bugfix/arm/disable-ath5k.patch ++ bugfix/all/patch-2.6.24-rc8-git5