Merge remote branch 'intel/drm-intel-fixes' of /ssd/git/drm-next into drm-fixes
* 'intel/drm-intel-fixes' of /ssd/git/drm-next:
drm/i915/bios: Reverse order of 100/120 Mhz SSC clocks
agp/intel: Fix missed cached memory flags setting in i965_write_entry()
drm/i915/sdvo: Only use the SDVO pin if it is in the valid range
drm/i915/ringbuffer: Handle wrapping of the autoreported HEAD
drm/i915/dp: Fix I2C/EDID handling with active DisplayPort to DVI converter
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index a91f308..b6426f1 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -173,12 +173,13 @@
sector_t (*bmap)(struct address_space *, sector_t);
int (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, int);
+ void (*freepage)(struct page *);
int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
int (*launder_page) (struct page *);
locking rules:
- All except set_page_dirty may block
+ All except set_page_dirty and freepage may block
BKL PageLocked(page) i_mutex
writepage: no yes, unlocks (see below)
@@ -193,6 +194,7 @@
bmap: no
invalidatepage: no yes
releasepage: no yes
+freepage: no yes
direct_IO: no
launder_page: no yes
@@ -288,6 +290,9 @@
indicate that the buffers are (or may be) freeable. If ->releasepage is zero,
the kernel assumes that the fs has no private interest in the buffers.
+ ->freepage() is called when the kernel is done dropping the page
+from the page cache.
+
->launder_page() may be called prior to releasing a page if
it is still found to be dirty. It returns zero if the page was successfully
cleaned, or an error value if not. Note that in order to prevent the page
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 55c28b7..20899e0 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -534,6 +534,7 @@
sector_t (*bmap)(struct address_space *, sector_t);
int (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, int);
+ void (*freepage)(struct page *);
ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
struct page* (*get_xip_page)(struct address_space *, sector_t,
@@ -678,6 +679,12 @@
need to ensure this. Possibly it can clear the PageUptodate
bit if it cannot free private data yet.
+ freepage: freepage is called once the page is no longer visible in
+ the page cache in order to allow the cleanup of any private
+ data. Since it may be called by the memory reclaimer, it
+ should not assume that the original address_space mapping still
+ exists, and it should not block.
+
direct_IO: called by the generic read/write routines to perform
direct_IO - that is IO requests which bypass the page cache
and transfer data directly between the storage and the
diff --git a/MAINTAINERS b/MAINTAINERS
index 1a1c27b..6a58887 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -559,14 +559,14 @@
S: Maintained
ARM/BCMRING ARM ARCHITECTURE
-M: Leo Chen <leochen@broadcom.com>
+M: Jiandong Zheng <jdzheng@broadcom.com>
M: Scott Branden <sbranden@broadcom.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-bcmring
ARM/BCMRING MTD NAND DRIVER
-M: Leo Chen <leochen@broadcom.com>
+M: Jiandong Zheng <jdzheng@broadcom.com>
M: Scott Branden <sbranden@broadcom.com>
L: linux-mtd@lists.infradead.org
S: Maintained
@@ -815,7 +815,7 @@
F: drivers/mmc/host/msm_sdcc.h
F: drivers/serial/msm_serial.h
F: drivers/serial/msm_serial.c
-T: git git://codeaurora.org/quic/kernel/dwalker/linux-msm.git
+T: git git://codeaurora.org/quic/kernel/davidb/linux-msm.git
S: Maintained
ARM/TOSA MACHINE SUPPORT
@@ -5932,7 +5932,6 @@
TULIP NETWORK DRIVERS
M: Grant Grundler <grundler@parisc-linux.org>
-M: Kyle McMartin <kyle@mcmartin.ca>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/tulip/
@@ -6584,6 +6583,15 @@
F: include/sound/wm????.h
F: sound/soc/codecs/wm*
+WORKQUEUE
+M: Tejun Heo <tj@kernel.org>
+L: linux-kernel@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git
+S: Maintained
+F: include/linux/workqueue.h
+F: kernel/workqueue.c
+F: Documentation/workqueue.txt
+
X.25 NETWORK LAYER
M: Andrew Hendry <andrew.hendry@gmail.com>
L: linux-x25@vger.kernel.org
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f1d9297..d56d21c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1311,7 +1311,7 @@
config THUMB2_KERNEL
bool "Compile the kernel in Thumb-2 mode"
- depends on CPU_V7 && EXPERIMENTAL
+ depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL
select AEABI
select ARM_ASM_UNIFIED
help
@@ -1759,7 +1759,7 @@
config FPE_NWFPE
bool "NWFPE math emulation"
- depends on !AEABI || OABI_COMPAT
+ depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL
---help---
Say Y to include the NWFPE floating point emulator in the kernel.
This is necessary to run most binaries. Linux does not currently
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index daf3993..2e3dd08 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -126,7 +126,6 @@
static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000);
static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000);
static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000);
-static APBC_CLK(rtc, MMP2_RTC, 0, 32768);
static APMU_CLK(nand, NAND, 0xbf, 100000000);
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 86c9b21..9db9203 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -216,7 +216,7 @@
{
.name = "wl1271",
.mmc = 3,
- .caps = MMC_CAP_4_BIT_DATA,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
.gpio_wp = -EINVAL,
.gpio_cd = -EINVAL,
.nonremovable = true,
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 40562dd..a1939b1 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -297,7 +297,7 @@
return 0;
dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
- if (!dpll3_m2_ck)
+ if (IS_ERR(dpll3_m2_ck))
return -EINVAL;
rate = clk_get_rate(dpll3_m2_ck);
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 5e81517..a8afb61 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -161,6 +161,23 @@
printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
}
+void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
+{
+ u32 tick_rate, cycles;
+
+ if (!seconds && !milliseconds)
+ return;
+
+ tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
+ cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
+ omap_dm_timer_stop(gptimer_wakeup);
+ omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
+
+ pr_info("PM: Resume timer in %u.%03u secs"
+ " (%d ticks at %d ticks/sec.)\n",
+ seconds, milliseconds, cycles, tick_rate);
+}
+
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/seq_file.h>
@@ -354,23 +371,6 @@
pwrdm->timer = t;
}
-void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
-{
- u32 tick_rate, cycles;
-
- if (!seconds && !milliseconds)
- return;
-
- tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
- cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
- omap_dm_timer_stop(gptimer_wakeup);
- omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
-
- pr_info("PM: Resume timer in %u.%03u secs"
- " (%d ticks at %d ticks/sec.)\n",
- seconds, milliseconds, cycles, tick_rate);
-}
-
static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
{
struct seq_file *s = (struct seq_file *)user;
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index c85923e..aaeea49 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -53,6 +53,19 @@
#include <plat/powerdomain.h>
#include <plat/clockdomain.h>
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+ return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+ return false;
+}
+#endif
+
static void (*omap2_sram_idle)(void);
static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
void __iomem *sdrc_power);
@@ -120,8 +133,9 @@
goto no_sleep;
/* Block console output in case it is on one of the OMAP UARTs */
- if (try_acquire_console_sem())
- goto no_sleep;
+ if (!is_suspending())
+ if (try_acquire_console_sem())
+ goto no_sleep;
omap_uart_prepare_idle(0);
omap_uart_prepare_idle(1);
@@ -136,7 +150,8 @@
omap_uart_resume_idle(1);
omap_uart_resume_idle(0);
- release_console_sem();
+ if (!is_suspending())
+ release_console_sem();
no_sleep:
if (omap2_pm_debug) {
@@ -284,6 +299,12 @@
local_irq_enable();
}
+static int omap2_pm_begin(suspend_state_t state)
+{
+ suspend_state = state;
+ return 0;
+}
+
static int omap2_pm_prepare(void)
{
/* We cannot sleep in idle until we have resumed */
@@ -333,10 +354,17 @@
enable_hlt();
}
+static void omap2_pm_end(void)
+{
+ suspend_state = PM_SUSPEND_ON;
+}
+
static struct platform_suspend_ops omap_pm_ops = {
+ .begin = omap2_pm_begin,
.prepare = omap2_pm_prepare,
.enter = omap2_pm_enter,
.finish = omap2_pm_finish,
+ .end = omap2_pm_end,
.valid = suspend_valid_only_mem,
};
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 0ec8a04..648b8c5 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -50,6 +50,19 @@
#include "sdrc.h"
#include "control.h"
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+ return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+ return false;
+}
+#endif
+
/* Scratchpad offsets */
#define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4
#define OMAP343X_TABLE_VALUE_OFFSET 0xc0
@@ -387,10 +400,11 @@
}
/* Block console output in case it is on one of the OMAP UARTs */
- if (per_next_state < PWRDM_POWER_ON ||
- core_next_state < PWRDM_POWER_ON)
- if (try_acquire_console_sem())
- goto console_still_active;
+ if (!is_suspending())
+ if (per_next_state < PWRDM_POWER_ON ||
+ core_next_state < PWRDM_POWER_ON)
+ if (try_acquire_console_sem())
+ goto console_still_active;
/* PER */
if (per_next_state < PWRDM_POWER_ON) {
@@ -470,7 +484,8 @@
omap_uart_resume_idle(3);
}
- release_console_sem();
+ if (!is_suspending())
+ release_console_sem();
console_still_active:
/* Disable IO-PAD and IO-CHAIN wakeup */
@@ -514,8 +529,6 @@
}
#ifdef CONFIG_SUSPEND
-static suspend_state_t suspend_state;
-
static int omap3_pm_prepare(void)
{
disable_hlt();
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 298a22a..f81acee 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -243,13 +243,14 @@
#define OMAP24XX_EN_GPT1_MASK (1 << 0)
/* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */
-#define OMAP24XX_ST_GPIOS_SHIFT (1 << 2)
-#define OMAP24XX_ST_GPIOS_MASK 2
-#define OMAP24XX_ST_GPT1_SHIFT (1 << 0)
-#define OMAP24XX_ST_GPT1_MASK 0
+#define OMAP24XX_ST_GPIOS_SHIFT 2
+#define OMAP24XX_ST_GPIOS_MASK (1 << 2)
+#define OMAP24XX_ST_GPT1_SHIFT 0
+#define OMAP24XX_ST_GPT1_MASK (1 << 0)
/* CM_IDLEST_MDM and PM_WKST_MDM shared bits */
-#define OMAP2430_ST_MDM_SHIFT (1 << 0)
+#define OMAP2430_ST_MDM_SHIFT 0
+#define OMAP2430_ST_MDM_MASK (1 << 0)
/* 3430 register bits shared between CM & PRM registers */
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index d2060a1..e5c9932 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -241,7 +241,8 @@
/******************************************************************************
* NAND Flash
******************************************************************************/
-#if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE)
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+ defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 99fa688..c96fa1b 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -203,6 +203,10 @@
* - end - virtual end address of region
*/
v6_dma_inv_range:
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrb r2, [r0] @ read for ownership
+ strb r2, [r0] @ write for ownership
+#endif
tst r0, #D_CACHE_LINE_SIZE - 1
bic r0, r0, #D_CACHE_LINE_SIZE - 1
#ifdef HARVARD_CACHE
@@ -211,6 +215,10 @@
mcrne p15, 0, r0, c7, c11, 1 @ clean unified line
#endif
tst r1, #D_CACHE_LINE_SIZE - 1
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrneb r2, [r1, #-1] @ read for ownership
+ strneb r2, [r1, #-1] @ write for ownership
+#endif
bic r1, r1, #D_CACHE_LINE_SIZE - 1
#ifdef HARVARD_CACHE
mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line
@@ -218,10 +226,6 @@
mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line
#endif
1:
-#ifdef CONFIG_DMA_CACHE_RWFO
- ldr r2, [r0] @ read for ownership
- str r2, [r0] @ write for ownership
-#endif
#ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c6, 1 @ invalidate D line
#else
@@ -229,6 +233,10 @@
#endif
add r0, r0, #D_CACHE_LINE_SIZE
cmp r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrlo r2, [r0] @ read for ownership
+ strlo r2, [r0] @ write for ownership
+#endif
blo 1b
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
@@ -263,12 +271,12 @@
* - end - virtual end address of region
*/
ENTRY(v6_dma_flush_range)
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrb r2, [r0] @ read for ownership
+ strb r2, [r0] @ write for ownership
+#endif
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
-#ifdef CONFIG_DMA_CACHE_RWFO
- ldr r2, [r0] @ read for ownership
- str r2, [r0] @ write for ownership
-#endif
#ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
#else
@@ -276,6 +284,10 @@
#endif
add r0, r0, #D_CACHE_LINE_SIZE
cmp r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrlob r2, [r0] @ read for ownership
+ strlob r2, [r0] @ write for ownership
+#endif
blo 1b
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index a3ebf7a..6136e68 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -173,15 +173,22 @@
UNWIND(.fnstart )
dcache_line_size r2, r3
sub r3, r2, #1
- bic r0, r0, r3
+ bic r12, r0, r3
1:
- USER( mcr p15, 0, r0, c7, c11, 1 ) @ clean D line to the point of unification
- dsb
- USER( mcr p15, 0, r0, c7, c5, 1 ) @ invalidate I line
- add r0, r0, r2
-2:
- cmp r0, r1
+ USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification
+ add r12, r12, r2
+ cmp r12, r1
blo 1b
+ dsb
+ icache_line_size r2, r3
+ sub r3, r2, #1
+ bic r12, r0, r3
+2:
+ USER( mcr p15, 0, r12, c7, c5, 1 ) @ invalidate I line
+ add r12, r12, r2
+ cmp r12, r1
+ blo 2b
+3:
mov r0, #0
ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable
ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB
@@ -194,10 +201,10 @@
* isn't mapped, just try the next page.
*/
9001:
- mov r0, r0, lsr #12
- mov r0, r0, lsl #12
- add r0, r0, #4096
- b 2b
+ mov r12, r12, lsr #12
+ mov r12, r12, lsl #12
+ add r12, r12, #4096
+ b 3b
UNWIND(.fnend )
ENDPROC(v7_coherent_kern_range)
ENDPROC(v7_coherent_user_range)
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 7d63bea..b795afd 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -61,17 +61,27 @@
.endm
/*
- * cache_line_size - get the cache line size from the CSIDR register
- * (available on ARMv7+). It assumes that the CSSR register was configured
- * to access the L1 data cache CSIDR.
+ * dcache_line_size - get the minimum D-cache line size from the CTR register
+ * on ARMv7.
*/
.macro dcache_line_size, reg, tmp
- mrc p15, 1, \tmp, c0, c0, 0 @ read CSIDR
- and \tmp, \tmp, #7 @ cache line size encoding
- mov \reg, #16 @ size offset
+ mrc p15, 0, \tmp, c0, c0, 1 @ read ctr
+ lsr \tmp, \tmp, #16
+ and \tmp, \tmp, #0xf @ cache line size encoding
+ mov \reg, #4 @ bytes per word
mov \reg, \reg, lsl \tmp @ actual cache line size
.endm
+/*
+ * icache_line_size - get the minimum I-cache line size from the CTR register
+ * on ARMv7.
+ */
+ .macro icache_line_size, reg, tmp
+ mrc p15, 0, \tmp, c0, c0, 1 @ read ctr
+ and \tmp, \tmp, #0xf @ cache line size encoding
+ mov \reg, #4 @ bytes per word
+ mov \reg, \reg, lsl \tmp @ actual cache line size
+ .endm
/*
* Sanity check the PTE configuration for the code below - which makes
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index 155fe43..8722a13 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/err.h>
#include <plat/common.h>
#include <plat/board.h>
@@ -164,7 +165,7 @@
return -ENODEV;
sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
- if (sync_32k_ick)
+ if (!IS_ERR(sync_32k_ick))
clk_enable(sync_32k_ick);
clocksource_32k.mult = clocksource_hz2mult(32768,
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index e2c8eeb..74dac41 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -166,7 +166,7 @@
cpu_is_omap1710())
omap_sram_size = 0x4000; /* 16K */
else if (cpu_is_omap1611())
- omap_sram_size = 0x3e800; /* 250K */
+ omap_sram_size = SZ_256K;
else {
printk(KERN_ERR "Could not detect SRAM size\n");
omap_sram_size = 0x4000;
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 55590a4..2fea897 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
#
# http://www.arm.linux.org.uk/developer/machines/?action=new
#
-# Last update: Thu Sep 9 22:43:01 2010
+# Last update: Sun Dec 12 23:24:27 2010
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -2321,7 +2321,7 @@
u380 MACH_U380 U380 2333
oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334
npcmx50 MACH_NPCMX50 NPCMX50 2335
-mx51_lange51 MACH_MX51_LANGE51 MX51_LANGE51 2336
+mx51_efikamx MACH_MX51_EFIKAMX MX51_EFIKAMX 2336
mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337
riom MACH_RIOM RIOM 2338
comcas MACH_COMCAS COMCAS 2339
@@ -2355,7 +2355,7 @@
csb732 MACH_CSB732 CSB732 2367
u8500 MACH_U8500 U8500 2368
huqiu MACH_HUQIU HUQIU 2369
-mx51_kunlun MACH_MX51_KUNLUN MX51_KUNLUN 2370
+mx51_efikasb MACH_MX51_EFIKASB MX51_EFIKASB 2370
pmt1g MACH_PMT1G PMT1G 2371
htcelf MACH_HTCELF HTCELF 2372
armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373
@@ -2971,7 +2971,7 @@
wasabi MACH_WASABI WASABI 2986
vivow MACH_VIVOW VIVOW 2987
mx50_rdp MACH_MX50_RDP MX50_RDP 2988
-universal MACH_UNIVERSAL UNIVERSAL 2989
+universal_c210 MACH_UNIVERSAL_C210 UNIVERSAL_C210 2989
real6410 MACH_REAL6410 REAL6410 2990
spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991
ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992
@@ -3044,3 +3044,178 @@
msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060
spear900 MACH_SPEAR900 SPEAR900 3061
pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062
+rdstor MACH_RDSTOR RDSTOR 3063
+usdloader MACH_USDLOADER USDLOADER 3064
+tsoploader MACH_TSOPLOADER TSOPLOADER 3065
+kronos MACH_KRONOS KRONOS 3066
+ffcore MACH_FFCORE FFCORE 3067
+mone MACH_MONE MONE 3068
+unit2s MACH_UNIT2S UNIT2S 3069
+acer_a5 MACH_ACER_A5 ACER_A5 3070
+etherpro_isp MACH_ETHERPRO_ISP ETHERPRO_ISP 3071
+stretchs7000 MACH_STRETCHS7000 STRETCHS7000 3072
+p87_smartsim MACH_P87_SMARTSIM P87_SMARTSIM 3073
+tulip MACH_TULIP TULIP 3074
+sunflower MACH_SUNFLOWER SUNFLOWER 3075
+rib MACH_RIB RIB 3076
+clod MACH_CLOD CLOD 3077
+rump MACH_RUMP RUMP 3078
+tenderloin MACH_TENDERLOIN TENDERLOIN 3079
+shortloin MACH_SHORTLOIN SHORTLOIN 3080
+crespo MACH_CRESPO CRESPO 3081
+antares MACH_ANTARES ANTARES 3082
+wb40n MACH_WB40N WB40N 3083
+herring MACH_HERRING HERRING 3084
+naxy400 MACH_NAXY400 NAXY400 3085
+naxy1200 MACH_NAXY1200 NAXY1200 3086
+vpr200 MACH_VPR200 VPR200 3087
+bug20 MACH_BUG20 BUG20 3088
+goflexnet MACH_GOFLEXNET GOFLEXNET 3089
+torbreck MACH_TORBRECK TORBRECK 3090
+saarb_mg1 MACH_SAARB_MG1 SAARB_MG1 3091
+callisto MACH_CALLISTO CALLISTO 3092
+multhsu MACH_MULTHSU MULTHSU 3093
+saluda MACH_SALUDA SALUDA 3094
+pemp_omap3_apollo MACH_PEMP_OMAP3_APOLLO PEMP_OMAP3_APOLLO 3095
+vc0718 MACH_VC0718 VC0718 3096
+mvblx MACH_MVBLX MVBLX 3097
+inhand_apeiron MACH_INHAND_APEIRON INHAND_APEIRON 3098
+inhand_fury MACH_INHAND_FURY INHAND_FURY 3099
+inhand_siren MACH_INHAND_SIREN INHAND_SIREN 3100
+hdnvp MACH_HDNVP HDNVP 3101
+softwinner MACH_SOFTWINNER SOFTWINNER 3102
+prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103
+nas6210 MACH_NAS6210 NAS6210 3104
+unisdev MACH_UNISDEV UNISDEV 3105
+sbca11 MACH_SBCA11 SBCA11 3106
+saga MACH_SAGA SAGA 3107
+ns_k330 MACH_NS_K330 NS_K330 3108
+tanna MACH_TANNA TANNA 3109
+imate8502 MACH_IMATE8502 IMATE8502 3110
+aspen MACH_ASPEN ASPEN 3111
+daintree_cwac MACH_DAINTREE_CWAC DAINTREE_CWAC 3112
+zmx25 MACH_ZMX25 ZMX25 3113
+maple1 MACH_MAPLE1 MAPLE1 3114
+qsd8x72_surf MACH_QSD8X72_SURF QSD8X72_SURF 3115
+qsd8x72_ffa MACH_QSD8X72_FFA QSD8X72_FFA 3116
+abilene MACH_ABILENE ABILENE 3117
+eigen_ttr MACH_EIGEN_TTR EIGEN_TTR 3118
+iomega_ix2_200 MACH_IOMEGA_IX2_200 IOMEGA_IX2_200 3119
+coretec_vcx7400 MACH_CORETEC_VCX7400 CORETEC_VCX7400 3120
+santiago MACH_SANTIAGO SANTIAGO 3121
+mx257sol MACH_MX257SOL MX257SOL 3122
+strasbourg MACH_STRASBOURG STRASBOURG 3123
+msm8x60_fluid MACH_MSM8X60_FLUID MSM8X60_FLUID 3124
+smartqv5 MACH_SMARTQV5 SMARTQV5 3125
+smartqv3 MACH_SMARTQV3 SMARTQV3 3126
+smartqv7 MACH_SMARTQV7 SMARTQV7 3127
+paz00 MACH_PAZ00 PAZ00 3128
+acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129
+htcwillow MACH_HTCWILLOW HTCWILLOW 3130
+fwbd_0404 MACH_FWBD_0404 FWBD_0404 3131
+hdgu MACH_HDGU HDGU 3132
+pyramid MACH_PYRAMID PYRAMID 3133
+epiphan MACH_EPIPHAN EPIPHAN 3134
+omap_bender MACH_OMAP_BENDER OMAP_BENDER 3135
+gurnard MACH_GURNARD GURNARD 3136
+gtl_it5100 MACH_GTL_IT5100 GTL_IT5100 3137
+bcm2708 MACH_BCM2708 BCM2708 3138
+mx51_ggc MACH_MX51_GGC MX51_GGC 3139
+sharespace MACH_SHARESPACE SHARESPACE 3140
+haba_knx_explorer MACH_HABA_KNX_EXPLORER HABA_KNX_EXPLORER 3141
+simtec_kirkmod MACH_SIMTEC_KIRKMOD SIMTEC_KIRKMOD 3142
+crux MACH_CRUX CRUX 3143
+mx51_bravo MACH_MX51_BRAVO MX51_BRAVO 3144
+charon MACH_CHARON CHARON 3145
+picocom3 MACH_PICOCOM3 PICOCOM3 3146
+picocom4 MACH_PICOCOM4 PICOCOM4 3147
+serrano MACH_SERRANO SERRANO 3148
+doubleshot MACH_DOUBLESHOT DOUBLESHOT 3149
+evsy MACH_EVSY EVSY 3150
+huashan MACH_HUASHAN HUASHAN 3151
+lausanne MACH_LAUSANNE LAUSANNE 3152
+emerald MACH_EMERALD EMERALD 3153
+tqma35 MACH_TQMA35 TQMA35 3154
+marvel MACH_MARVEL MARVEL 3155
+manuae MACH_MANUAE MANUAE 3156
+chacha MACH_CHACHA CHACHA 3157
+lemon MACH_LEMON LEMON 3158
+csc MACH_CSC CSC 3159
+gira_knxip_router MACH_GIRA_KNXIP_ROUTER GIRA_KNXIP_ROUTER 3160
+t20 MACH_T20 T20 3161
+hdmini MACH_HDMINI HDMINI 3162
+sciphone_g2 MACH_SCIPHONE_G2 SCIPHONE_G2 3163
+express MACH_EXPRESS EXPRESS 3164
+express_kt MACH_EXPRESS_KT EXPRESS_KT 3165
+maximasp MACH_MAXIMASP MAXIMASP 3166
+nitrogen_imx51 MACH_NITROGEN_IMX51 NITROGEN_IMX51 3167
+nitrogen_imx53 MACH_NITROGEN_IMX53 NITROGEN_IMX53 3168
+sunfire MACH_SUNFIRE SUNFIRE 3169
+arowana MACH_AROWANA AROWANA 3170
+tegra_daytona MACH_TEGRA_DAYTONA TEGRA_DAYTONA 3171
+tegra_swordfish MACH_TEGRA_SWORDFISH TEGRA_SWORDFISH 3172
+edison MACH_EDISON EDISON 3173
+svp8500v1 MACH_SVP8500V1 SVP8500V1 3174
+svp8500v2 MACH_SVP8500V2 SVP8500V2 3175
+svp5500 MACH_SVP5500 SVP5500 3176
+b5500 MACH_B5500 B5500 3177
+s5500 MACH_S5500 S5500 3178
+icon MACH_ICON ICON 3179
+elephant MACH_ELEPHANT ELEPHANT 3180
+msm8x60_fusion MACH_MSM8X60_FUSION MSM8X60_FUSION 3181
+shooter MACH_SHOOTER SHOOTER 3182
+spade_lte MACH_SPADE_LTE SPADE_LTE 3183
+philhwani MACH_PHILHWANI PHILHWANI 3184
+gsncomm MACH_GSNCOMM GSNCOMM 3185
+strasbourg_a2 MACH_STRASBOURG_A2 STRASBOURG_A2 3186
+mmm MACH_MMM MMM 3187
+davinci_dm365_bv MACH_DAVINCI_DM365_BV DAVINCI_DM365_BV 3188
+ag5evm MACH_AG5EVM AG5EVM 3189
+sc575plc MACH_SC575PLC SC575PLC 3190
+sc575hmi MACH_SC575IPC SC575IPC 3191
+omap3_tdm3730 MACH_OMAP3_TDM3730 OMAP3_TDM3730 3192
+g7 MACH_G7 G7 3193
+top9000_eval MACH_TOP9000_EVAL TOP9000_EVAL 3194
+top9000_su MACH_TOP9000_SU TOP9000_SU 3195
+utm300 MACH_UTM300 UTM300 3196
+tsunagi MACH_TSUNAGI TSUNAGI 3197
+ts75xx MACH_TS75XX TS75XX 3198
+msm8x60_fusn_ffa MACH_MSM8X60_FUSN_FFA MSM8X60_FUSN_FFA 3199
+ts47xx MACH_TS47XX TS47XX 3200
+da850_k5 MACH_DA850_K5 DA850_K5 3201
+ax502 MACH_AX502 AX502 3202
+igep0032 MACH_IGEP0032 IGEP0032 3203
+antero MACH_ANTERO ANTERO 3204
+synergy MACH_SYNERGY SYNERGY 3205
+ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206
+wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207
+punica MACH_PUNICA PUNICA 3208
+sbc_nt250 MACH_SBC_NT250 SBC_NT250 3209
+mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210
+mackerel MACH_MACKEREL MACKEREL 3211
+fa9x27 MACH_FA9X27 FA9X27 3213
+ns2816tb MACH_NS2816TB NS2816TB 3214
+ns2816_ntpad MACH_NS2816_NTPAD NS2816_NTPAD 3215
+ns2816_ntnb MACH_NS2816_NTNB NS2816_NTNB 3216
+kaen MACH_KAEN KAEN 3217
+nv1000 MACH_NV1000 NV1000 3218
+nuc950ts MACH_NUC950TS NUC950TS 3219
+nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220
+ast2200 MACH_AST2200 AST2200 3221
+lead MACH_LEAD LEAD 3222
+unino1 MACH_UNINO1 UNINO1 3223
+greeco MACH_GREECO GREECO 3224
+verdi MACH_VERDI VERDI 3225
+dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226
+quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227
+abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228
+svcid MACH_SVCID SVCID 3229
+msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230
+msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231
+icon_g MACH_ICON_G ICON_G 3232
+mb3 MACH_MB3 MB3 3233
+gsia18s MACH_GSIA18S GSIA18S 3234
+pivicc MACH_PIVICC PIVICC 3235
+pcm048 MACH_PCM048 PCM048 3236
+dds MACH_DDS DDS 3237
+chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 7f217b3..2e9d78d 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -22,7 +22,8 @@
select HAVE_SPARSE_IRQ
select RTC_LIB
select GENERIC_ATOMIC64
- select GENERIC_HARDIRQS_NO_DEPRECATED
+ # Support the deprecated APIs until MFD and GPIOLIB catch up.
+ select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h
index 903cd618e..d6741fc 100644
--- a/arch/sh/include/asm/unistd_32.h
+++ b/arch/sh/include/asm/unistd_32.h
@@ -368,8 +368,9 @@
#define __NR_sendmsg 355
#define __NR_recvmsg 356
#define __NR_recvmmsg 357
+#define __NR_accept4 358
-#define NR_syscalls 358
+#define NR_syscalls 359
#ifdef __KERNEL__
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S
index e872e81..6fc347e 100644
--- a/arch/sh/kernel/syscalls_32.S
+++ b/arch/sh/kernel/syscalls_32.S
@@ -375,3 +375,4 @@
.long sys_sendmsg /* 355 */
.long sys_recvmsg
.long sys_recvmmsg
+ .long sys_accept4
diff --git a/arch/sparc/include/asm/openprom.h b/arch/sparc/include/asm/openprom.h
index 81cd434..47eaafa 100644
--- a/arch/sparc/include/asm/openprom.h
+++ b/arch/sparc/include/asm/openprom.h
@@ -39,7 +39,7 @@
int (*v2_dev_open)(char *devpath);
void (*v2_dev_close)(int d);
int (*v2_dev_read)(int d, char *buf, int nbytes);
- int (*v2_dev_write)(int d, char *buf, int nbytes);
+ int (*v2_dev_write)(int d, const char *buf, int nbytes);
int (*v2_dev_seek)(int d, int hi, int lo);
/* Never issued (multistage load support) */
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h
index 51296a6..9e5c640 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -60,25 +60,6 @@
extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
-/* Device operations. */
-
-/* Open the device described by the passed string. Note, that the format
- * of the string is different on V0 vs. V2->higher proms. The caller must
- * know what he/she is doing! Returns the device descriptor, an int.
- */
-extern int prom_devopen(char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
- unsigned int seek_lowval);
-
/* Miscellaneous routines, don't really fit in any category per se. */
/* Reboot the machine with the command line passed. */
@@ -121,19 +102,8 @@
/* Get the prom firmware revision. */
extern int prom_getprev(void);
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
/* Prom's internal routines, don't use in kernel/boot code. */
extern void prom_printf(const char *fmt, ...);
@@ -238,7 +208,6 @@
extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
int value_size);
-extern phandle prom_pathtoinode(char *path);
extern phandle prom_inst2pkg(int);
/* Dorking with Bus ranges... */
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h
index c9cc078..8cd0df3 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -67,27 +67,6 @@
/* Boot argument acquisition, returns the boot command line string. */
extern char *prom_getbootargs(void);
-/* Device utilities. */
-
-/* Device operations. */
-
-/* Open the device described by the passed string. Note, that the format
- * of the string is different on V0 vs. V2->higher proms. The caller must
- * know what he/she is doing! Returns the device descriptor, an int.
- */
-extern int prom_devopen(const char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
- unsigned int seek_lowval);
-
/* Miscellaneous routines, don't really fit in any category per se. */
/* Reboot the machine with the command line passed. */
@@ -109,33 +88,14 @@
/* Halt and power-off the machine. */
extern void prom_halt_power_off(void) __attribute__ ((noreturn));
-/* Set the PROM 'sync' callback function to the passed function pointer.
- * When the user gives the 'sync' command at the prom prompt while the
- * kernel is still active, the prom will call this routine.
- *
- */
-typedef int (*callback_func_t)(long *cmd);
-extern void prom_setcallback(callback_func_t func_ptr);
-
/* Acquire the IDPROM of the root node in the prom device tree. This
* gets passed a buffer where you would like it stuffed. The return value
* is the format type of this idprom or 0xff on error.
*/
extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
/* Prom's internal routines, don't use in kernel/boot code. */
extern void prom_printf(const char *fmt, ...);
@@ -279,9 +239,7 @@
extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
int value_size);
-extern phandle prom_pathtoinode(const char *path);
extern phandle prom_inst2pkg(int);
-extern int prom_service_exists(const char *service_name);
extern void prom_sun4v_guest_soft_state(void);
extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 2d51527..f01c426 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -114,7 +114,7 @@
if (leon3_gptimer_regs && leon3_irqctrl_regs) {
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
- (((1000000 / 100) - 1)));
+ (((1000000 / HZ) - 1)));
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
#ifdef CONFIG_SMP
@@ -128,7 +128,7 @@
}
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0);
- LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1)));
+ LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1)));
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
# endif
diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile
index 1b8c073..816c0fa 100644
--- a/arch/sparc/prom/Makefile
+++ b/arch/sparc/prom/Makefile
@@ -6,7 +6,6 @@
lib-y := bootstr_$(BITS).o
lib-$(CONFIG_SPARC32) += devmap.o
-lib-y += devops_$(BITS).o
lib-y += init_$(BITS).o
lib-$(CONFIG_SPARC32) += memory.o
lib-y += misc_$(BITS).o
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c
index 5340264..4886310 100644
--- a/arch/sparc/prom/console_32.c
+++ b/arch/sparc/prom/console_32.c
@@ -16,63 +16,26 @@
extern void restore_current(void);
-/* Non blocking get character from console input device, returns -1
- * if no input was taken. This can be used for polling.
- */
-int
-prom_nbgetchar(void)
-{
- static char inc;
- int i = -1;
- unsigned long flags;
-
- spin_lock_irqsave(&prom_lock, flags);
- switch(prom_vers) {
- case PROM_V0:
- i = (*(romvec->pv_nbgetchar))();
- break;
- case PROM_V2:
- case PROM_V3:
- if( (*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin , &inc, 0x1) == 1) {
- i = inc;
- } else {
- i = -1;
- }
- break;
- default:
- i = -1;
- break;
- };
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
- return i; /* Ugh, we could spin forever on unsupported proms ;( */
-}
-
/* Non blocking put character to console device, returns -1 if
* unsuccessful.
*/
-int
-prom_nbputchar(char c)
+static int prom_nbputchar(const char *buf)
{
- static char outc;
unsigned long flags;
int i = -1;
spin_lock_irqsave(&prom_lock, flags);
switch(prom_vers) {
case PROM_V0:
- i = (*(romvec->pv_nbputchar))(c);
+ i = (*(romvec->pv_nbputchar))(*buf);
break;
case PROM_V2:
case PROM_V3:
- outc = c;
- if( (*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 0x1) == 1)
+ if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout,
+ buf, 0x1) == 1)
i = 0;
- else
- i = -1;
break;
default:
- i = -1;
break;
};
restore_current();
@@ -80,18 +43,14 @@
return i; /* Ugh, we could spin forever on unsupported proms ;( */
}
-/* Blocking version of get character routine above. */
-char
-prom_getchar(void)
+void prom_console_write_buf(const char *buf, int len)
{
- int character;
- while((character = prom_nbgetchar()) == -1) ;
- return (char) character;
+ while (len) {
+ int n = prom_nbputchar(buf);
+ if (n)
+ continue;
+ len--;
+ buf++;
+ }
}
-/* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
-{
- while(prom_nbputchar(c) == -1) ;
-}
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c
index 10322dc..ed39e75 100644
--- a/arch/sparc/prom/console_64.c
+++ b/arch/sparc/prom/console_64.c
@@ -15,85 +15,34 @@
extern int prom_stdin, prom_stdout;
-/* Non blocking get character from console input device, returns -1
- * if no input was taken. This can be used for polling.
- */
-inline int
-prom_nbgetchar(void)
+static int __prom_console_write_buf(const char *buf, int len)
{
unsigned long args[7];
- char inc;
-
- args[0] = (unsigned long) "read";
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) prom_stdin;
- args[4] = (unsigned long) &inc;
- args[5] = 1;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- if (args[6] == 1)
- return inc;
- return -1;
-}
-
-/* Non blocking put character to console device, returns -1 if
- * unsuccessful.
- */
-inline int
-prom_nbputchar(char c)
-{
- unsigned long args[7];
- char outc;
-
- outc = c;
+ int ret;
args[0] = (unsigned long) "write";
args[1] = 3;
args[2] = 1;
args[3] = (unsigned int) prom_stdout;
- args[4] = (unsigned long) &outc;
- args[5] = 1;
+ args[4] = (unsigned long) buf;
+ args[5] = (unsigned int) len;
args[6] = (unsigned long) -1;
p1275_cmd_direct(args);
- if (args[6] == 1)
- return 0;
- else
+ ret = (int) args[6];
+ if (ret < 0)
return -1;
+ return ret;
}
-/* Blocking version of get character routine above. */
-char
-prom_getchar(void)
+void prom_console_write_buf(const char *buf, int len)
{
- int character;
- while((character = prom_nbgetchar()) == -1) ;
- return (char) character;
-}
-
-/* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
-{
- prom_nbputchar(c);
-}
-
-void
-prom_puts(const char *s, int len)
-{
- unsigned long args[7];
-
- args[0] = (unsigned long) "write";
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) prom_stdout;
- args[4] = (unsigned long) s;
- args[5] = len;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
+ while (len) {
+ int n = __prom_console_write_buf(buf, len);
+ if (n < 0)
+ continue;
+ len -= n;
+ buf += len;
+ }
}
diff --git a/arch/sparc/prom/devops_32.c b/arch/sparc/prom/devops_32.c
deleted file mode 100644
index 9c5d468..0000000
--- a/arch/sparc/prom/devops_32.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * devops.c: Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-extern void restore_current(void);
-
-/* Open the device described by the string 'dstr'. Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns -1 on failure.
- */
-int
-prom_devopen(char *dstr)
-{
- int handle;
- unsigned long flags;
- spin_lock_irqsave(&prom_lock, flags);
- switch(prom_vers) {
- case PROM_V0:
- handle = (*(romvec->pv_v0devops.v0_devopen))(dstr);
- if(handle == 0) handle = -1;
- break;
- case PROM_V2:
- case PROM_V3:
- handle = (*(romvec->pv_v2devops.v2_dev_open))(dstr);
- break;
- default:
- handle = -1;
- break;
- };
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
-
- return handle;
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
- unsigned long flags;
- spin_lock_irqsave(&prom_lock, flags);
- switch(prom_vers) {
- case PROM_V0:
- (*(romvec->pv_v0devops.v0_devclose))(dhandle);
- break;
- case PROM_V2:
- case PROM_V3:
- (*(romvec->pv_v2devops.v2_dev_close))(dhandle);
- break;
- default:
- break;
- };
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
- return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
- unsigned long flags;
- spin_lock_irqsave(&prom_lock, flags);
- switch(prom_vers) {
- case PROM_V0:
- (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo);
- break;
- case PROM_V2:
- case PROM_V3:
- (*(romvec->pv_v2devops.v2_dev_seek))(dhandle, seekhi, seeklo);
- break;
- default:
- break;
- };
- restore_current();
- spin_unlock_irqrestore(&prom_lock, flags);
-}
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c
deleted file mode 100644
index a017119..0000000
--- a/arch/sparc/prom/devops_64.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * devops.c: Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-/* Open the device described by the string 'dstr'. Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns 0 on failure.
- */
-int
-prom_devopen(const char *dstr)
-{
- unsigned long args[5];
-
- args[0] = (unsigned long) "open";
- args[1] = 1;
- args[2] = 1;
- args[3] = (unsigned long) dstr;
- args[4] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-
- return (int) args[4];
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
- unsigned long args[4];
-
- args[0] = (unsigned long) "close";
- args[1] = 1;
- args[2] = 0;
- args[3] = (unsigned int) dhandle;
-
- p1275_cmd_direct(args);
-
- return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
- unsigned long args[7];
-
- args[0] = (unsigned long) "seek";
- args[1] = 3;
- args[2] = 1;
- args[3] = (unsigned int) dhandle;
- args[4] = seekhi;
- args[5] = seeklo;
- args[6] = (unsigned long) -1;
-
- p1275_cmd_direct(args);
-}
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c
index d24bc44..e4f31d4 100644
--- a/arch/sparc/prom/misc_64.c
+++ b/arch/sparc/prom/misc_64.c
@@ -18,7 +18,7 @@
#include <asm/system.h>
#include <asm/ldc.h>
-int prom_service_exists(const char *service_name)
+static int prom_service_exists(const char *service_name)
{
unsigned long args[5];
@@ -150,20 +150,6 @@
prom_halt();
}
-/* Set prom sync handler to call function 'funcp'. */
-void prom_setcallback(callback_func_t funcp)
-{
- unsigned long args[5];
- if (!funcp)
- return;
- args[0] = (unsigned long) "set-callback";
- args[1] = 1;
- args[2] = 1;
- args[3] = (unsigned long) funcp;
- args[4] = (unsigned long) -1;
- p1275_cmd_direct(args);
-}
-
/* Get the idprom and stuff it into buffer 'idbuf'. Returns the
* format type. 'num_bytes' is the number of bytes that your idbuf
* has space for. Returns 0xff on error.
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c
index ca86926..d9682f0 100644
--- a/arch/sparc/prom/printf.c
+++ b/arch/sparc/prom/printf.c
@@ -15,22 +15,45 @@
#include <linux/kernel.h>
#include <linux/compiler.h>
+#include <linux/spinlock.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
+#define CONSOLE_WRITE_BUF_SIZE 1024
+
static char ppbuf[1024];
+static char console_write_buf[CONSOLE_WRITE_BUF_SIZE];
+static DEFINE_RAW_SPINLOCK(console_write_lock);
void notrace prom_write(const char *buf, unsigned int n)
{
- char ch;
+ unsigned int dest_len;
+ unsigned long flags;
+ char *dest;
- while (n != 0) {
- --n;
- if ((ch = *buf++) == '\n')
- prom_putchar('\r');
- prom_putchar(ch);
+ dest = console_write_buf;
+ raw_spin_lock_irqsave(&console_write_lock, flags);
+
+ dest_len = 0;
+ while (n-- != 0) {
+ char ch = *buf++;
+ if (ch == '\n') {
+ *dest++ = '\r';
+ dest_len++;
+ }
+ *dest++ = ch;
+ dest_len++;
+ if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) {
+ prom_console_write_buf(console_write_buf, dest_len);
+ dest = console_write_buf;
+ dest_len = 0;
+ }
}
+ if (dest_len)
+ prom_console_write_buf(console_write_buf, dest_len);
+
+ raw_spin_unlock_irqrestore(&console_write_lock, flags);
}
void notrace prom_printf(const char *fmt, ...)
diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c
index 63e08e1..535e2e6 100644
--- a/arch/sparc/prom/tree_32.c
+++ b/arch/sparc/prom/tree_32.c
@@ -342,19 +342,3 @@
if (node == -1) return 0;
return node;
}
-
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-phandle prom_pathtoinode(char *path)
-{
- phandle node;
- int inst;
-
- inst = prom_devopen (path);
- if (inst == -1) return 0;
- node = prom_inst2pkg (inst);
- prom_devclose (inst);
- if (node == -1) return 0;
- return node;
-}
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c
index 691be68..d936600 100644
--- a/arch/sparc/prom/tree_64.c
+++ b/arch/sparc/prom/tree_64.c
@@ -374,24 +374,6 @@
return node;
}
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-phandle prom_pathtoinode(const char *path)
-{
- phandle node;
- int inst;
-
- inst = prom_devopen (path);
- if (inst == 0)
- return 0;
- node = prom_inst2pkg(inst);
- prom_devclose(inst);
- if (node == -1)
- return 0;
- return node;
-}
-
int prom_ihandle2path(int handle, char *buffer, int bufsize)
{
unsigned long args[7];
diff --git a/block/bsg.c b/block/bsg.c
index f20d6a7..0c8b64a 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -250,6 +250,14 @@
int ret, rw;
unsigned int dxfer_len;
void *dxferp = NULL;
+ struct bsg_class_device *bcd = &q->bsg_dev;
+
+ /* if the LLD has been removed then the bsg_unregister_queue will
+ * eventually be called and the class_dev was freed, so we can no
+ * longer use this request_queue. Return no such address.
+ */
+ if (!bcd->class_dev)
+ return ERR_PTR(-ENXIO);
dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp,
hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp,
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index ba9afea..25d3aae 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -100,24 +100,7 @@
.release = single_release,
};
#endif
-static int get_ac_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct acpi_ac *ac = to_acpi_ac(psy);
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = ac->state;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-static enum power_supply_property ac_props[] = {
- POWER_SUPPLY_PROP_ONLINE,
-};
/* --------------------------------------------------------------------------
AC Adapter Management
-------------------------------------------------------------------------- */
@@ -140,6 +123,35 @@
return 0;
}
+/* --------------------------------------------------------------------------
+ sysfs I/F
+ -------------------------------------------------------------------------- */
+static int get_ac_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct acpi_ac *ac = to_acpi_ac(psy);
+
+ if (!ac)
+ return -ENODEV;
+
+ if (acpi_ac_get_state(ac))
+ return -ENODEV;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = ac->state;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static enum power_supply_property ac_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
#ifdef CONFIG_ACPI_PROCFS_POWER
/* --------------------------------------------------------------------------
FS Interface (/proc)
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 1211c03..5850d32 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -86,7 +86,7 @@
* It is used to provide exclusive accessing for ERST Error Log
* Address Range too.
*/
-static DEFINE_SPINLOCK(erst_lock);
+static DEFINE_RAW_SPINLOCK(erst_lock);
static inline int erst_errno(int command_status)
{
@@ -421,9 +421,9 @@
if (erst_disable)
return -ENODEV;
- spin_lock_irqsave(&erst_lock, flags);
+ raw_spin_lock_irqsave(&erst_lock, flags);
count = __erst_get_record_count();
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return count;
}
@@ -456,9 +456,9 @@
if (erst_disable)
return -ENODEV;
- spin_lock_irqsave(&erst_lock, flags);
+ raw_spin_lock_irqsave(&erst_lock, flags);
rc = __erst_get_next_record_id(record_id);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
@@ -624,17 +624,17 @@
return -EINVAL;
if (erst_erange.attr & ERST_RANGE_NVRAM) {
- if (!spin_trylock_irqsave(&erst_lock, flags))
+ if (!raw_spin_trylock_irqsave(&erst_lock, flags))
return -EBUSY;
rc = __erst_write_to_nvram(record);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
if (record->record_length > erst_erange.size)
return -EINVAL;
- if (!spin_trylock_irqsave(&erst_lock, flags))
+ if (!raw_spin_trylock_irqsave(&erst_lock, flags))
return -EBUSY;
memcpy(erst_erange.vaddr, record, record->record_length);
rcd_erange = erst_erange.vaddr;
@@ -642,7 +642,7 @@
memcpy(&rcd_erange->persistence_information, "ER", 2);
rc = __erst_write_to_storage(0);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
@@ -696,9 +696,9 @@
if (erst_disable)
return -ENODEV;
- spin_lock_irqsave(&erst_lock, flags);
+ raw_spin_lock_irqsave(&erst_lock, flags);
len = __erst_read(record_id, record, buflen);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return len;
}
EXPORT_SYMBOL_GPL(erst_read);
@@ -719,20 +719,20 @@
if (erst_disable)
return -ENODEV;
- spin_lock_irqsave(&erst_lock, flags);
+ raw_spin_lock_irqsave(&erst_lock, flags);
rc = __erst_get_next_record_id(&record_id);
if (rc) {
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
/* no more record */
if (record_id == APEI_ERST_INVALID_RECORD_ID) {
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return 0;
}
len = __erst_read(record_id, record, buflen);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return len;
}
@@ -746,12 +746,12 @@
if (erst_disable)
return -ENODEV;
- spin_lock_irqsave(&erst_lock, flags);
+ raw_spin_lock_irqsave(&erst_lock, flags);
if (erst_erange.attr & ERST_RANGE_NVRAM)
rc = __erst_clear_from_nvram(record_id);
else
rc = __erst_clear_from_storage(record_id);
- spin_unlock_irqrestore(&erst_lock, flags);
+ raw_spin_unlock_irqrestore(&erst_lock, flags);
return rc;
}
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index 1a3508a..daa7bc6 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -46,9 +46,9 @@
/* HEST table parsing */
-static struct acpi_table_hest *hest_tab;
+static struct acpi_table_hest *__read_mostly hest_tab;
-static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
+static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
[ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */
[ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1,
[ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi),
@@ -126,7 +126,7 @@
unsigned int count;
};
-static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
+static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
{
int *count = data;
@@ -135,7 +135,7 @@
return 0;
}
-static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
+static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
{
struct platform_device *ghes_dev;
struct ghes_arr *ghes_arr = data;
@@ -165,7 +165,7 @@
return rc;
}
-static int hest_ghes_dev_register(unsigned int ghes_count)
+static int __init hest_ghes_dev_register(unsigned int ghes_count)
{
int rc, i;
struct ghes_arr ghes_arr;
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 95649d3..9fb9d5a 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -130,6 +130,8 @@
unsigned long flags;
};
+static int acpi_battery_update(struct acpi_battery *battery);
+
#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
inline int acpi_battery_present(struct acpi_battery *battery)
@@ -184,6 +186,9 @@
int ret = 0;
struct acpi_battery *battery = to_acpi_battery(psy);
+ if (acpi_battery_update(battery))
+ return -ENODEV;
+
if (acpi_battery_present(battery)) {
/* run battery update only if it is present */
acpi_battery_get_state(battery);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 372ff80..302b31e 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -934,6 +934,9 @@
ec_flag_msi, "MSI hardware", {
DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL},
{
+ ec_flag_msi, "MSI hardware", {
+ DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL},
+ {
ec_validate_ecdt, "ASUS hardware", {
DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
{},
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 966fedd..055d7b7 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -110,9 +110,6 @@
static LIST_HEAD(acpi_ioremaps);
static DEFINE_SPINLOCK(acpi_ioremap_lock);
-#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
-static char osi_setup_string[OSI_STRING_LENGTH_MAX];
-
static void __init acpi_osi_setup_late(void);
/*
@@ -152,8 +149,7 @@
unsigned int enable:1;
unsigned int dmi:1;
unsigned int cmdline:1;
- unsigned int known:1;
-} osi_linux = { 0, 0, 0, 0};
+} osi_linux = {0, 0, 0};
static u32 acpi_osi_handler(acpi_string interface, u32 supported)
{
@@ -1055,13 +1051,53 @@
__setup("acpi_os_name=", acpi_os_name_setup);
+#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
+#define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */
+
+struct osi_setup_entry {
+ char string[OSI_STRING_LENGTH_MAX];
+ bool enable;
+};
+
+static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX];
+
+void __init acpi_osi_setup(char *str)
+{
+ struct osi_setup_entry *osi;
+ bool enable = true;
+ int i;
+
+ if (!acpi_gbl_create_osi_method)
+ return;
+
+ if (str == NULL || *str == '\0') {
+ printk(KERN_INFO PREFIX "_OSI method disabled\n");
+ acpi_gbl_create_osi_method = FALSE;
+ return;
+ }
+
+ if (*str == '!') {
+ str++;
+ enable = false;
+ }
+
+ for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+ osi = &osi_setup_entries[i];
+ if (!strcmp(osi->string, str)) {
+ osi->enable = enable;
+ break;
+ } else if (osi->string[0] == '\0') {
+ osi->enable = enable;
+ strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
+ break;
+ }
+ }
+}
+
static void __init set_osi_linux(unsigned int enable)
{
- if (osi_linux.enable != enable) {
+ if (osi_linux.enable != enable)
osi_linux.enable = enable;
- printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
- enable ? "Add": "Delet");
- }
if (osi_linux.enable)
acpi_osi_setup("Linux");
@@ -1073,7 +1109,8 @@
static void __init acpi_cmdline_osi_linux(unsigned int enable)
{
- osi_linux.cmdline = 1; /* cmdline set the default */
+ osi_linux.cmdline = 1; /* cmdline set the default and override DMI */
+ osi_linux.dmi = 0;
set_osi_linux(enable);
return;
@@ -1081,15 +1118,12 @@
void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
{
- osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
-
printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
if (enable == -1)
return;
- osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */
-
+ osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
set_osi_linux(enable);
return;
@@ -1104,37 +1138,44 @@
*/
static void __init acpi_osi_setup_late(void)
{
- char *str = osi_setup_string;
+ struct osi_setup_entry *osi;
+ char *str;
+ int i;
+ acpi_status status;
- if (*str == '\0')
- return;
+ for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+ osi = &osi_setup_entries[i];
+ str = osi->string;
- if (!strcmp("!Linux", str)) {
- acpi_cmdline_osi_linux(0); /* !enable */
- } else if (*str == '!') {
- if (acpi_remove_interface(++str) == AE_OK)
- printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
- } else if (!strcmp("Linux", str)) {
- acpi_cmdline_osi_linux(1); /* enable */
- } else {
- if (acpi_install_interface(str) == AE_OK)
- printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+ if (*str == '\0')
+ break;
+ if (osi->enable) {
+ status = acpi_install_interface(str);
+
+ if (ACPI_SUCCESS(status))
+ printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+ } else {
+ status = acpi_remove_interface(str);
+
+ if (ACPI_SUCCESS(status))
+ printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
+ }
}
}
-int __init acpi_osi_setup(char *str)
+static int __init osi_setup(char *str)
{
- if (str == NULL || *str == '\0') {
- printk(KERN_INFO PREFIX "_OSI method disabled\n");
- acpi_gbl_create_osi_method = FALSE;
- } else {
- strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX);
- }
+ if (str && !strcmp("Linux", str))
+ acpi_cmdline_osi_linux(1);
+ else if (str && !strcmp("!Linux", str))
+ acpi_cmdline_osi_linux(0);
+ else
+ acpi_osi_setup(str);
return 1;
}
-__setup("acpi_osi=", acpi_osi_setup);
+__setup("acpi_osi=", osi_setup);
/* enable serialization to combat AE_ALREADY_EXISTS errors */
static int __init acpi_serialize_setup(char *str)
@@ -1530,7 +1571,7 @@
return AE_OK;
}
-acpi_status acpi_os_initialize1(void)
+acpi_status __init acpi_os_initialize1(void)
{
kacpid_wq = create_workqueue("kacpid");
kacpi_notify_wq = create_workqueue("kacpi_notify");
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 67dedee..4c9c2fb 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -213,11 +213,13 @@
resource->name));
} else {
result = __acpi_power_on(resource);
+ if (result)
+ resource->ref_count--;
}
mutex_unlock(&resource->resource_lock);
- return 0;
+ return result;
}
static int acpi_power_off_device(acpi_handle handle)
@@ -465,10 +467,12 @@
struct acpi_handle_list *tl = NULL; /* Target Resources */
int i = 0;
-
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
return -EINVAL;
+ if (device->power.state == state)
+ return 0;
+
if ((device->power.state < ACPI_STATE_D0)
|| (device->power.state > ACPI_STATE_D3))
return -ENODEV;
@@ -488,10 +492,6 @@
goto end;
}
- if (device->power.state == state) {
- goto end;
- }
-
/*
* Then we dereference all power resources used in the current list.
*/
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index fde49b9..79cb653 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -156,15 +156,6 @@
return 0;
}
-static int acpi_thermal_cpufreq_increase(unsigned int cpu)
-{
- return -ENODEV;
-}
-static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
-{
- return -ENODEV;
-}
-
#endif
int acpi_processor_get_limit_info(struct acpi_processor *pr)
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 721d93b..febb153 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -27,8 +27,6 @@
static u8 sleep_states[ACPI_S_STATE_COUNT];
-static u32 acpi_target_sleep_state = ACPI_STATE_S0;
-
static void acpi_sleep_tts_switch(u32 acpi_state)
{
union acpi_object in_arg = { ACPI_TYPE_INTEGER };
@@ -81,6 +79,8 @@
}
#ifdef CONFIG_ACPI_SLEEP
+static u32 acpi_target_sleep_state = ACPI_STATE_S0;
+
/*
* The ACPI specification wants us to save NVS memory regions during hibernation
* and to restore them during the subsequent resume. Windows does that also for
@@ -427,6 +427,14 @@
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
},
},
+ {
+ .callback = init_nvs_nosave,
+ .ident = "Sony Vaio VGN-NW130D",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
+ },
+ },
{},
};
#endif /* CONFIG_SUSPEND */
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c
index 46b9476..f9b983a 100644
--- a/drivers/atm/adummy.c
+++ b/drivers/atm/adummy.c
@@ -154,7 +154,7 @@
err = -ENOMEM;
goto out;
}
- atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
+ atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL);
if (!atm_dev) {
printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
err = -ENODEV;
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index a33896a..ffe9b65 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -2244,7 +2244,8 @@
goto out_reset;
}
- dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL);
+ dev->atm_dev = atm_dev_register (DEV_LABEL, &pci_dev->dev, &amb_ops, -1,
+ NULL);
if (!dev->atm_dev) {
PRINTD (DBG_ERR, "failed to register Madge ATM adapter");
err = -EINVAL;
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
index b910181..2b464b6 100644
--- a/drivers/atm/atmtcp.c
+++ b/drivers/atm/atmtcp.c
@@ -366,7 +366,7 @@
if (!dev_data)
return -ENOMEM;
- dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL);
+ dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL);
if (!dev) {
kfree(dev_data);
return itf == -1 ? -ENOMEM : -EBUSY;
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 97c5898..c495fae 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -2244,7 +2244,7 @@
&zeroes);
if (!cpu_zeroes) goto out1;
}
- dev = atm_dev_register(DEV_LABEL,&ops,-1,NULL);
+ dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
if (!dev) goto out2;
pci_set_drvdata(pci_dev, dev);
eni_dev->pci_dev = pci_dev;
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 5d86bb8..7d912baf 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1911,7 +1911,7 @@
fs_dev, sizeof (struct fs_dev));
if (!fs_dev)
goto err_out;
- atm_dev = atm_dev_register("fs", &ops, -1, NULL);
+ atm_dev = atm_dev_register("fs", &pci_dev->dev, &ops, -1, NULL);
if (!atm_dev)
goto err_out_free_fs_dev;
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index c8fc69c..962c309 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -2567,14 +2567,14 @@
static int __devinit
-fore200e_register(struct fore200e* fore200e)
+fore200e_register(struct fore200e* fore200e, struct device *parent)
{
struct atm_dev* atm_dev;
DPRINTK(2, "device %s being registered\n", fore200e->name);
- atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1,
- NULL);
+ atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops,
+ -1, NULL);
if (atm_dev == NULL) {
printk(FORE200E "unable to register device %s\n", fore200e->name);
return -ENODEV;
@@ -2594,9 +2594,9 @@
static int __devinit
-fore200e_init(struct fore200e* fore200e)
+fore200e_init(struct fore200e* fore200e, struct device *parent)
{
- if (fore200e_register(fore200e) < 0)
+ if (fore200e_register(fore200e, parent) < 0)
return -ENODEV;
if (fore200e->bus->configure(fore200e) < 0)
@@ -2662,7 +2662,7 @@
sprintf(fore200e->name, "%s-%d", bus->model_name, index);
- err = fore200e_init(fore200e);
+ err = fore200e_init(fore200e, &op->dev);
if (err < 0) {
fore200e_shutdown(fore200e);
kfree(fore200e);
@@ -2740,7 +2740,7 @@
sprintf(fore200e->name, "%s-%d", bus->model_name, index);
- err = fore200e_init(fore200e);
+ err = fore200e_init(fore200e, &pci_dev->dev);
if (err < 0) {
fore200e_shutdown(fore200e);
goto out_free;
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 801e8b6..6cf59bf 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -366,7 +366,7 @@
goto init_one_failure;
}
- atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, NULL);
+ atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &he_ops, -1, NULL);
if (!atm_dev) {
err = -ENODEV;
goto init_one_failure;
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index a957904..24761e1 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -2733,7 +2733,8 @@
PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p",
iobase, irq, membase);
- dev->atm_dev = atm_dev_register(DEV_LABEL, &hrz_ops, -1, NULL);
+ dev->atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &hrz_ops, -1,
+ NULL);
if (!(dev->atm_dev)) {
PRINTD(DBG_ERR, "failed to register Madge ATM adapter");
err = -EINVAL;
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index bce5732..bfb7fee 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -3698,7 +3698,8 @@
goto err_out_iounmap;
}
- dev = atm_dev_register("idt77252", &idt77252_ops, -1, NULL);
+ dev = atm_dev_register("idt77252", &pcidev->dev, &idt77252_ops, -1,
+ NULL);
if (!dev) {
printk("%s: can't register atm device\n", card->name);
err = -EIO;
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index 9309d47..7292540 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -3172,7 +3172,7 @@
ret = -ENODEV;
goto err_out_free_iadev;
}
- dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+ dev = atm_dev_register(DEV_LABEL, &pdev->dev, &ops, -1, NULL);
if (!dev) {
ret = -ENOMEM;
goto err_out_disable_dev;
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index cbe15a8..a395c9a 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -2591,7 +2591,7 @@
return -ENOMEM;
}
- atmdev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+ atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL);
if (atmdev == NULL) {
printk(KERN_ERR DEV_LABEL
": couldn't register atm device!\n");
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 2f3516b..6b313ee 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -771,7 +771,8 @@
}
/* Register device */
- card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL);
+ card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops,
+ -1, NULL);
if (card->atmdev == NULL) {
printk("nicstar%d: can't register device.\n", i);
error = 17;
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 2e08c99..73fb1c4 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -166,7 +166,7 @@
static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
static int list_vccs(int vci);
static void release_vccs(struct atm_dev *dev);
-static int atm_init(struct solos_card *);
+static int atm_init(struct solos_card *, struct device *);
static void atm_remove(struct solos_card *);
static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
static void solos_bh(unsigned long);
@@ -1210,7 +1210,7 @@
if (db_firmware_upgrade)
flash_upgrade(card, 3);
- err = atm_init(card);
+ err = atm_init(card, &dev->dev);
if (err)
goto out_free_irq;
@@ -1233,7 +1233,7 @@
return err;
}
-static int atm_init(struct solos_card *card)
+static int atm_init(struct solos_card *card, struct device *parent)
{
int i;
@@ -1244,7 +1244,7 @@
skb_queue_head_init(&card->tx_queue[i]);
skb_queue_head_init(&card->cli_queue[i]);
- card->atmdev[i] = atm_dev_register("solos-pci", &fpga_ops, -1, NULL);
+ card->atmdev[i] = atm_dev_register("solos-pci", parent, &fpga_ops, -1, NULL);
if (!card->atmdev[i]) {
dev_err(&card->dev->dev, "Could not register ATM device %d\n", i);
atm_remove(card);
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 4e885d2..6249179 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1597,7 +1597,7 @@
goto out;
}
- dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+ dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
if (!dev)
goto out_free;
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 4f9e22f..657873e 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -72,7 +72,7 @@
static DEFINE_MUTEX(blkfront_mutex);
static const struct block_device_operations xlvbd_block_fops;
-#define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE)
+#define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE)
/*
* We have one of these per vbd, whether ide, scsi or 'other'. They
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 128cae4..949ed09 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -35,6 +35,10 @@
static struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 */
{ USB_DEVICE(0x0CF3, 0x3000) },
+
+ /* Atheros AR3011 with sflash firmware*/
+ { USB_DEVICE(0x0CF3, 0x3002) },
+
{ } /* Terminating entry */
};
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index ab3894f..1da773f8 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -99,6 +99,9 @@
/* Broadcom BCM2033 without firmware */
{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },
+ /* Atheros 3011 with sflash firmware */
+ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
+
/* Broadcom BCM2035 */
{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
@@ -239,7 +242,8 @@
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- BT_ERR("%s urb %p failed to resubmit (%d)",
+ if (err != -EPERM)
+ BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
}
@@ -323,7 +327,8 @@
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- BT_ERR("%s urb %p failed to resubmit (%d)",
+ if (err != -EPERM)
+ BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
}
@@ -412,7 +417,8 @@
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- BT_ERR("%s urb %p failed to resubmit (%d)",
+ if (err != -EPERM)
+ BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
}
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index e16c3fa..05117f1 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -36,6 +36,7 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR);
static struct cn_dev cdev;
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index a8a84f4..64b21f5 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -1,8 +1,8 @@
ifeq ($(CONFIG_DMADEVICES_DEBUG),y)
- EXTRA_CFLAGS += -DDEBUG
+ ccflags-y += -DDEBUG
endif
ifeq ($(CONFIG_DMADEVICES_VDEBUG),y)
- EXTRA_CFLAGS += -DVERBOSE_DEBUG
+ ccflags-y += -DVERBOSE_DEBUG
endif
obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index a0f3e6a0..ea0ee81 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -722,7 +722,7 @@
desc->lli.daddr = mem;
desc->lli.ctrla = ctrla
| ATC_DST_WIDTH(mem_width)
- | len >> mem_width;
+ | len >> reg_width;
desc->lli.ctrlb = ctrlb;
if (!first) {
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 286c3ac..e5e172d2 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -50,9 +50,11 @@
* EIE - Error interrupt enable
* EOSIE - End of segments interrupt enable (basic mode)
* EOLNIE - End of links interrupt enable
+ * BWC - Bandwidth sharing among channels
*/
- DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EIE
- | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32);
+ DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_BWC
+ | FSL_DMA_MR_EIE | FSL_DMA_MR_EOLNIE
+ | FSL_DMA_MR_EOSIE, 32);
break;
case FSL_DMA_IP_83XX:
/* Set the channel to below modes:
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index cb4d6ff..ba9f403 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved.
*
* Author:
* Zhang Wei <wei.zhang@freescale.com>, Jul 2007
@@ -36,6 +36,13 @@
#define FSL_DMA_MR_DAHE 0x00002000
#define FSL_DMA_MR_SAHE 0x00001000
+/*
+ * Bandwidth/pause control determines how many bytes a given
+ * channel is allowed to transfer before the DMA engine pauses
+ * the current channel and switches to the next channel
+ */
+#define FSL_DMA_MR_BWC 0x08000000
+
/* Special MR definition for MPC8349 */
#define FSL_DMA_MR_EOTIE 0x00000080
#define FSL_DMA_MR_PRC_RM 0x00000800
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index f629e49..e53d438 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -379,7 +379,7 @@
return 0;
err_init:
- while (i-- >= 0) {
+ while (--i >= 0) {
struct imxdma_channel *imxdmac = &imxdma->channel[i];
imx_dma_free(imxdmac->imxdma_channel);
}
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 0834323..d0602dd 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -951,7 +951,7 @@
struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
int param;
- bd->buffer_addr = sgl->dma_address;
+ bd->buffer_addr = sg->dma_address;
count = sg->length;
@@ -1385,7 +1385,7 @@
{
return platform_driver_probe(&sdma_driver, sdma_probe);
}
-subsys_initcall(sdma_module_init);
+module_init(sdma_module_init);
MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>");
MODULE_DESCRIPTION("i.MX SDMA driver");
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index 338bc4e..3109bd9 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -1075,7 +1075,6 @@
if (NULL == dma->dma_pool) {
pr_err("ERR_MDMA:pci_pool_create failed\n");
err = -ENOMEM;
- kfree(dma);
goto err_dma_pool;
}
@@ -1186,7 +1185,6 @@
free_irq(pdev->irq, dma);
err_irq:
pci_pool_destroy(dma->dma_pool);
- kfree(dma);
err_dma_pool:
pr_err("ERR_MDMA:setup_dma failed: %d\n", err);
return err;
@@ -1413,7 +1411,7 @@
.runtime_idle = dma_runtime_idle,
};
-static struct pci_driver intel_mid_dma_pci = {
+static struct pci_driver intel_mid_dma_pci_driver = {
.name = "Intel MID DMA",
.id_table = intel_mid_dma_ids,
.probe = intel_mid_dma_probe,
@@ -1431,13 +1429,13 @@
{
pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n",
INTEL_MID_DMA_DRIVER_VERSION);
- return pci_register_driver(&intel_mid_dma_pci);
+ return pci_register_driver(&intel_mid_dma_pci_driver);
}
fs_initcall(intel_mid_dma_init);
static void __exit intel_mid_dma_exit(void)
{
- pci_unregister_driver(&intel_mid_dma_pci);
+ pci_unregister_driver(&intel_mid_dma_pci_driver);
}
module_exit(intel_mid_dma_exit);
diff --git a/drivers/dma/ioat/Makefile b/drivers/dma/ioat/Makefile
index 8997d3f..0ff7270 100644
--- a/drivers/dma/ioat/Makefile
+++ b/drivers/dma/ioat/Makefile
@@ -1,2 +1,2 @@
obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
-ioatdma-objs := pci.o dma.o dma_v2.o dma_v3.o dca.o
+ioatdma-y := pci.o dma.o dma_v2.o dma_v3.o dca.o
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 92b6790..c064c89 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -259,11 +259,6 @@
return;
}
- channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr);
- channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr);
- channel_writel(pd_chan, SIZE, desc->regs.size);
- channel_writel(pd_chan, NEXT, desc->regs.next);
-
dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n",
pd_chan->chan.chan_id, desc->regs.dev_addr);
dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n",
@@ -273,10 +268,16 @@
dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n",
pd_chan->chan.chan_id, desc->regs.next);
- if (list_empty(&desc->tx_list))
+ if (list_empty(&desc->tx_list)) {
+ channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr);
+ channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr);
+ channel_writel(pd_chan, SIZE, desc->regs.size);
+ channel_writel(pd_chan, NEXT, desc->regs.next);
pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT);
- else
+ } else {
+ channel_writel(pd_chan, NEXT, desc->txd.phys);
pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG);
+ }
val = dma_readl(pd, CTL2);
val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id);
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index 0d58a4a..cef5845 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -4449,9 +4449,8 @@
if (!request_mem_region(res.start, resource_size(&res),
dev_driver_string(&ofdev->dev))) {
- dev_err(&ofdev->dev, "failed to request memory region "
- "(0x%016llx-0x%016llx)\n",
- (u64)res.start, (u64)res.end);
+ dev_err(&ofdev->dev, "failed to request memory region %pR\n",
+ &res);
initcode = PPC_ADMA_INIT_MEMREG;
ret = -EBUSY;
goto out;
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 8521401..eca9ba1 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -1572,7 +1572,7 @@
debugf1(" HoleOffset=0x%x HoleValid=0x%x IntlvSel=0x%x\n",
hole_off, hole_valid, intlv_sel);
- if (intlv_en ||
+ if (intlv_en &&
(intlv_sel != ((sys_addr >> 12) & intlv_en)))
return -EINVAL;
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index d7ca43a..251440c 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -41,10 +41,10 @@
#define MC_PROC_NAME_MAX_LEN 7
#if PAGE_SHIFT < 20
-#define PAGES_TO_MiB( pages ) ( ( pages ) >> ( 20 - PAGE_SHIFT ) )
-#define MiB_TO_PAGES(mb) ((mb) >> (20 - PAGE_SHIFT))
+#define PAGES_TO_MiB(pages) ((pages) >> (20 - PAGE_SHIFT))
+#define MiB_TO_PAGES(mb) ((mb) << (20 - PAGE_SHIFT))
#else /* PAGE_SHIFT > 20 */
-#define PAGES_TO_MiB( pages ) ( ( pages ) << ( PAGE_SHIFT - 20 ) )
+#define PAGES_TO_MiB(pages) ((pages) << (PAGE_SHIFT - 20))
#define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20))
#endif
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index ba6586a..795ea69c 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -586,14 +586,16 @@
return NULL;
}
- /* marking MCI offline */
- mci->op_state = OP_OFFLINE;
-
del_mc_from_global_list(mci);
mutex_unlock(&mem_ctls_mutex);
- /* flush workq processes and remove sysfs */
+ /* flush workq processes */
edac_mc_workq_teardown(mci);
+
+ /* marking MCI offline */
+ mci->op_state = OP_OFFLINE;
+
+ /* remove from sysfs */
edac_remove_sysfs_mci_device(mci);
edac_printk(KERN_INFO, EDAC_MC,
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 84eb607..e3c8b60 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -242,6 +242,7 @@
static char ohci_driver_name[] = KBUILD_MODNAME;
+#define PCI_DEVICE_ID_AGERE_FW643 0x5901
#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
@@ -253,18 +254,34 @@
/* In case of multiple matches in ohci_quirks[], only the first one is used. */
static const struct {
- unsigned short vendor, device, flags;
+ unsigned short vendor, device, revision, flags;
} ohci_quirks[] = {
- {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER |
- QUIRK_RESET_PACKET |
- QUIRK_NO_1394A},
- {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET},
- {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
- {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI},
- {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
- {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
- {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
- {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS},
+ {PCI_VENDOR_ID_AL, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER},
+
+ {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, PCI_ANY_ID,
+ QUIRK_BE_HEADERS},
+
+ {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
+ QUIRK_NO_MSI},
+
+ {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID,
+ QUIRK_NO_MSI},
+
+ {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER},
+
+ {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER},
+
+ {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A},
+
+ {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_RESET_PACKET},
+
+ {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
};
/* This overrides anything that was found in ohci_quirks[]. */
@@ -2927,9 +2944,11 @@
}
for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++)
- if (ohci_quirks[i].vendor == dev->vendor &&
- (ohci_quirks[i].device == dev->device ||
- ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) {
+ if ((ohci_quirks[i].vendor == dev->vendor) &&
+ (ohci_quirks[i].device == (unsigned short)PCI_ANY_ID ||
+ ohci_quirks[i].device == dev->device) &&
+ (ohci_quirks[i].revision == (unsigned short)PCI_ANY_ID ||
+ ohci_quirks[i].revision >= dev->revision)) {
ohci->quirks = ohci_quirks[i].flags;
break;
}
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 6985cb1..2baa670 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -156,12 +156,12 @@
{ DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
{ DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
{ DRM_MODE_CONNECTOR_Component, "Component", 0 },
- { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 },
- { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
- { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
- { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
+ { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 },
+ { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 },
+ { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 },
+ { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
{ DRM_MODE_CONNECTOR_TV, "TV", 0 },
- { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 },
+ { DRM_MODE_CONNECTOR_eDP, "eDP", 0 },
};
static struct drm_prop_enum_list drm_encoder_enum_list[] =
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 722700d..16d5155 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -628,7 +628,7 @@
if ((seq - vblwait->request.sequence) <= (1 << 23)) {
e->event.tv_sec = now.tv_sec;
e->event.tv_usec = now.tv_usec;
- drm_vblank_put(dev, e->pipe);
+ drm_vblank_put(dev, pipe);
list_add_tail(&e->base.link, &e->base.file_priv->event_list);
wake_up_interruptible(&e->base.file_priv->event_wait);
trace_drm_vblank_event_delivered(current->pid, pipe,
@@ -645,7 +645,7 @@
spin_unlock_irqrestore(&dev->event_lock, flags);
kfree(e);
err_put:
- drm_vblank_put(dev, e->pipe);
+ drm_vblank_put(dev, pipe);
return ret;
}
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index a322d4f..4d7a2e1 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -878,12 +878,15 @@
u32 tmp;
/* flush hdp cache so updates hit vram */
- if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
+ if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
+ !(rdev->flags & RADEON_IS_AGP)) {
void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
u32 tmp;
/* r7xx hw bug. write to HDP_DEBUG1 followed by fb read
* rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+ * This seems to cause problems on some AGP cards. Just use the old
+ * method for them.
*/
WREG32(HDP_DEBUG1, 0);
tmp = readl((void __iomem *)ptr);
@@ -3485,10 +3488,12 @@
void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
{
/* r7xx hw bug. write to HDP_DEBUG1 followed by fb read
- * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+ * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL.
+ * This seems to cause problems on some AGP cards. Just use the old
+ * method for them.
*/
if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
- rdev->vram_scratch.ptr) {
+ rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) {
void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
u32 tmp;
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index 4bf969c..be0fdd5 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -916,27 +916,27 @@
int nr = sensor_attr->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val, orig_div, new_div, shift;
+ int val, orig_div, new_div;
val = simple_strtol(buf, NULL, 10);
new_div = DIV_TO_REG(val);
- if (new_div == 0) {
- return -EINVAL;
- }
+
mutex_lock(&data->update_lock);
orig_div = data->fan_div[nr];
data->fan_div[nr] = DIV_FROM_REG(new_div);
if (nr < 4) { /* 0 <= nr < 4 */
- shift = 2 * nr;
adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3,
- ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) |
- (new_div << shift)));
+ (DIV_TO_REG(data->fan_div[0]) << 0) |
+ (DIV_TO_REG(data->fan_div[1]) << 2) |
+ (DIV_TO_REG(data->fan_div[2]) << 4) |
+ (DIV_TO_REG(data->fan_div[3]) << 6));
} else { /* 3 < nr < 8 */
- shift = 2 * (nr - 4);
adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7,
- ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) |
- (new_div << shift)));
+ (DIV_TO_REG(data->fan_div[4]) << 0) |
+ (DIV_TO_REG(data->fan_div[5]) << 2) |
+ (DIV_TO_REG(data->fan_div[6]) << 4) |
+ (DIV_TO_REG(data->fan_div[7]) << 6));
}
if (data->fan_div[nr] != orig_div) {
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 14a5d98..a428a92 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -187,6 +187,7 @@
#define IT87_REG_FAN_MAIN_CTRL 0x13
#define IT87_REG_FAN_CTL 0x14
#define IT87_REG_PWM(nr) (0x15 + (nr))
+#define IT87_REG_PWM_DUTY(nr) (0x63 + (nr) * 8)
#define IT87_REG_VIN(nr) (0x20 + (nr))
#define IT87_REG_TEMP(nr) (0x29 + (nr))
@@ -251,12 +252,16 @@
u8 fan_main_ctrl; /* Register value */
u8 fan_ctl; /* Register value */
- /* The following 3 arrays correspond to the same registers. The
- * meaning of bits 6-0 depends on the value of bit 7, and we want
- * to preserve settings on mode changes, so we have to track all
- * values separately. */
+ /* The following 3 arrays correspond to the same registers up to
+ * the IT8720F. The meaning of bits 6-0 depends on the value of bit
+ * 7, and we want to preserve settings on mode changes, so we have
+ * to track all values separately.
+ * Starting with the IT8721F, the manual PWM duty cycles are stored
+ * in separate registers (8-bit values), so the separate tracking
+ * is no longer needed, but it is still done to keep the driver
+ * simple. */
u8 pwm_ctrl[3]; /* Register value */
- u8 pwm_duty[3]; /* Manual PWM value set by user (bit 6-0) */
+ u8 pwm_duty[3]; /* Manual PWM value set by user */
u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */
/* Automatic fan speed control registers */
@@ -832,7 +837,9 @@
data->fan_main_ctrl);
} else {
if (val == 1) /* Manual mode */
- data->pwm_ctrl[nr] = data->pwm_duty[nr];
+ data->pwm_ctrl[nr] = data->type == it8721 ?
+ data->pwm_temp_map[nr] :
+ data->pwm_duty[nr];
else /* Automatic mode */
data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
@@ -858,12 +865,25 @@
return -EINVAL;
mutex_lock(&data->update_lock);
- data->pwm_duty[nr] = pwm_to_reg(data, val);
- /* If we are in manual mode, write the duty cycle immediately;
- * otherwise, just store it for later use. */
- if (!(data->pwm_ctrl[nr] & 0x80)) {
- data->pwm_ctrl[nr] = data->pwm_duty[nr];
- it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
+ if (data->type == it8721) {
+ /* If we are in automatic mode, the PWM duty cycle register
+ * is read-only so we can't write the value */
+ if (data->pwm_ctrl[nr] & 0x80) {
+ mutex_unlock(&data->update_lock);
+ return -EBUSY;
+ }
+ data->pwm_duty[nr] = pwm_to_reg(data, val);
+ it87_write_value(data, IT87_REG_PWM_DUTY(nr),
+ data->pwm_duty[nr]);
+ } else {
+ data->pwm_duty[nr] = pwm_to_reg(data, val);
+ /* If we are in manual mode, write the duty cycle immediately;
+ * otherwise, just store it for later use. */
+ if (!(data->pwm_ctrl[nr] & 0x80)) {
+ data->pwm_ctrl[nr] = data->pwm_duty[nr];
+ it87_write_value(data, IT87_REG_PWM(nr),
+ data->pwm_ctrl[nr]);
+ }
}
mutex_unlock(&data->update_lock);
return count;
@@ -1958,7 +1978,10 @@
* channels to use when later setting to automatic mode later.
* Use a 1:1 mapping by default (we are clueless.)
* In both cases, the value can (and should) be changed by the user
- * prior to switching to a different mode. */
+ * prior to switching to a different mode.
+ * Note that this is no longer needed for the IT8721F and later, as
+ * these have separate registers for the temperature mapping and the
+ * manual duty cycle. */
for (i = 0; i < 3; i++) {
data->pwm_temp_map[i] = i;
data->pwm_duty[i] = 0x7f; /* Full speed */
@@ -2034,10 +2057,16 @@
static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
{
data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr));
- if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
+ if (data->type == it8721) {
data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
- else /* Manual mode */
- data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+ data->pwm_duty[nr] = it87_read_value(data,
+ IT87_REG_PWM_DUTY(nr));
+ } else {
+ if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
+ data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
+ else /* Manual mode */
+ data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+ }
if (has_old_autopwm(data)) {
int i;
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
index 00d975e..c7e6d8e 100644
--- a/drivers/hwmon/ltc4215.c
+++ b/drivers/hwmon/ltc4215.c
@@ -205,7 +205,6 @@
/* Power (virtual) */
LTC4215_POWER(power1_input);
-LTC4215_ALARM(power1_alarm, (1 << 3), LTC4215_STATUS);
/* Input Voltage */
LTC4215_VOLTAGE(in1_input, LTC4215_ADIN);
@@ -214,6 +213,7 @@
/* Output Voltage */
LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE);
+LTC4215_ALARM(in2_min_alarm, (1 << 3), LTC4215_STATUS);
/* Finally, construct an array of pointers to members of the above objects,
* as required for sysfs_create_group()
@@ -223,13 +223,13 @@
&sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
&sensor_dev_attr_power1_input.dev_attr.attr,
- &sensor_dev_attr_power1_alarm.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in1_max_alarm.dev_attr.attr,
&sensor_dev_attr_in1_min_alarm.dev_attr.attr,
&sensor_dev_attr_in2_input.dev_attr.attr,
+ &sensor_dev_attr_in2_min_alarm.dev_attr.attr,
NULL,
};
diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c
index 80f70d3..c714927 100644
--- a/drivers/i2c/busses/i2c-intel-mid.c
+++ b/drivers/i2c/busses/i2c-intel-mid.c
@@ -999,7 +999,7 @@
/* Initialize struct members */
snprintf(mrst->adap.name, sizeof(mrst->adap.name),
- "MRST/Medfield I2C at %lx", start);
+ "Intel MID I2C at %lx", start);
mrst->adap.owner = THIS_MODULE;
mrst->adap.algo = &intel_mid_i2c_algorithm;
mrst->adap.dev.parent = &dev->dev;
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 41665d2..c131d58 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -273,8 +273,6 @@
pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
- if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
- lapic_timer_reliable_states = 0xFFFFFFFF;
if (boot_cpu_data.x86 != 6) /* family 6 */
return -ENODEV;
@@ -286,8 +284,6 @@
case 0x1F: /* Core i7 and i5 Processor - Nehalem */
case 0x2E: /* Nehalem-EX Xeon */
case 0x2F: /* Westmere-EX Xeon */
- lapic_timer_reliable_states = (1 << 1); /* C1 */
-
case 0x25: /* Westmere */
case 0x2C: /* Westmere */
cpuidle_state_table = nehalem_cstates;
@@ -295,7 +291,6 @@
case 0x1C: /* 28 - Atom Processor */
case 0x26: /* 38 - Lincroft Atom Processor */
- lapic_timer_reliable_states = (1 << 1); /* C1 */
cpuidle_state_table = atom_cstates;
break;
@@ -303,10 +298,6 @@
case 0x2D: /* SNB Xeon */
cpuidle_state_table = snb_cstates;
break;
-#ifdef FUTURE_USE
- case 0x17: /* 23 - Core 2 Duo */
- lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */
-#endif
default:
pr_debug(PREFIX "does not run on family %d model %d\n",
@@ -314,6 +305,9 @@
return -ENODEV;
}
+ if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
+ lapic_timer_reliable_states = 0xFFFFFFFF;
+
pr_debug(PREFIX "v" INTEL_IDLE_VERSION
" model 0x%X\n", boot_cpu_data.x86_model);
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index b342248..c426992 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -893,68 +893,81 @@
return ret ? ret : in_len;
}
+static int copy_wc_to_user(void __user *dest, struct ib_wc *wc)
+{
+ struct ib_uverbs_wc tmp;
+
+ tmp.wr_id = wc->wr_id;
+ tmp.status = wc->status;
+ tmp.opcode = wc->opcode;
+ tmp.vendor_err = wc->vendor_err;
+ tmp.byte_len = wc->byte_len;
+ tmp.ex.imm_data = (__u32 __force) wc->ex.imm_data;
+ tmp.qp_num = wc->qp->qp_num;
+ tmp.src_qp = wc->src_qp;
+ tmp.wc_flags = wc->wc_flags;
+ tmp.pkey_index = wc->pkey_index;
+ tmp.slid = wc->slid;
+ tmp.sl = wc->sl;
+ tmp.dlid_path_bits = wc->dlid_path_bits;
+ tmp.port_num = wc->port_num;
+ tmp.reserved = 0;
+
+ if (copy_to_user(dest, &tmp, sizeof tmp))
+ return -EFAULT;
+
+ return 0;
+}
+
ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
{
struct ib_uverbs_poll_cq cmd;
- struct ib_uverbs_poll_cq_resp *resp;
+ struct ib_uverbs_poll_cq_resp resp;
+ u8 __user *header_ptr;
+ u8 __user *data_ptr;
struct ib_cq *cq;
- struct ib_wc *wc;
- int ret = 0;
- int i;
- int rsize;
+ struct ib_wc wc;
+ int ret;
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
- wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL);
- if (!wc)
- return -ENOMEM;
-
- rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc);
- resp = kmalloc(rsize, GFP_KERNEL);
- if (!resp) {
- ret = -ENOMEM;
- goto out_wc;
- }
-
cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
- if (!cq) {
- ret = -EINVAL;
- goto out;
+ if (!cq)
+ return -EINVAL;
+
+ /* we copy a struct ib_uverbs_poll_cq_resp to user space */
+ header_ptr = (void __user *)(unsigned long) cmd.response;
+ data_ptr = header_ptr + sizeof resp;
+
+ memset(&resp, 0, sizeof resp);
+ while (resp.count < cmd.ne) {
+ ret = ib_poll_cq(cq, 1, &wc);
+ if (ret < 0)
+ goto out_put;
+ if (!ret)
+ break;
+
+ ret = copy_wc_to_user(data_ptr, &wc);
+ if (ret)
+ goto out_put;
+
+ data_ptr += sizeof(struct ib_uverbs_wc);
+ ++resp.count;
}
- resp->count = ib_poll_cq(cq, cmd.ne, wc);
-
- put_cq_read(cq);
-
- for (i = 0; i < resp->count; i++) {
- resp->wc[i].wr_id = wc[i].wr_id;
- resp->wc[i].status = wc[i].status;
- resp->wc[i].opcode = wc[i].opcode;
- resp->wc[i].vendor_err = wc[i].vendor_err;
- resp->wc[i].byte_len = wc[i].byte_len;
- resp->wc[i].ex.imm_data = (__u32 __force) wc[i].ex.imm_data;
- resp->wc[i].qp_num = wc[i].qp->qp_num;
- resp->wc[i].src_qp = wc[i].src_qp;
- resp->wc[i].wc_flags = wc[i].wc_flags;
- resp->wc[i].pkey_index = wc[i].pkey_index;
- resp->wc[i].slid = wc[i].slid;
- resp->wc[i].sl = wc[i].sl;
- resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits;
- resp->wc[i].port_num = wc[i].port_num;
- }
-
- if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize))
+ if (copy_to_user(header_ptr, &resp, sizeof resp)) {
ret = -EFAULT;
+ goto out_put;
+ }
-out:
- kfree(resp);
+ ret = in_len;
-out_wc:
- kfree(wc);
- return ret ? ret : in_len;
+out_put:
+ put_cq_read(cq);
+ return ret;
}
ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 84c46a1..e71c5fa 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -371,10 +371,15 @@
bio_put(bio);
}
-static void submit_flushes(mddev_t *mddev)
+static void md_submit_flush_data(struct work_struct *ws);
+
+static void submit_flushes(struct work_struct *ws)
{
+ mddev_t *mddev = container_of(ws, mddev_t, flush_work);
mdk_rdev_t *rdev;
+ INIT_WORK(&mddev->flush_work, md_submit_flush_data);
+ atomic_set(&mddev->flush_pending, 1);
rcu_read_lock();
list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
if (rdev->raid_disk >= 0 &&
@@ -397,6 +402,8 @@
rdev_dec_pending(rdev, mddev);
}
rcu_read_unlock();
+ if (atomic_dec_and_test(&mddev->flush_pending))
+ queue_work(md_wq, &mddev->flush_work);
}
static void md_submit_flush_data(struct work_struct *ws)
@@ -404,8 +411,6 @@
mddev_t *mddev = container_of(ws, mddev_t, flush_work);
struct bio *bio = mddev->flush_bio;
- atomic_set(&mddev->flush_pending, 1);
-
if (bio->bi_size == 0)
/* an empty barrier - all done */
bio_endio(bio, 0);
@@ -414,10 +419,9 @@
if (mddev->pers->make_request(mddev, bio))
generic_make_request(bio);
}
- if (atomic_dec_and_test(&mddev->flush_pending)) {
- mddev->flush_bio = NULL;
- wake_up(&mddev->sb_wait);
- }
+
+ mddev->flush_bio = NULL;
+ wake_up(&mddev->sb_wait);
}
void md_flush_request(mddev_t *mddev, struct bio *bio)
@@ -429,13 +433,8 @@
mddev->flush_bio = bio;
spin_unlock_irq(&mddev->write_lock);
- atomic_set(&mddev->flush_pending, 1);
- INIT_WORK(&mddev->flush_work, md_submit_flush_data);
-
- submit_flushes(mddev);
-
- if (atomic_dec_and_test(&mddev->flush_pending))
- queue_work(md_wq, &mddev->flush_work);
+ INIT_WORK(&mddev->flush_work, submit_flushes);
+ queue_work(md_wq, &mddev->flush_work);
}
EXPORT_SYMBOL(md_flush_request);
@@ -5160,7 +5159,7 @@
PTR_ERR(rdev));
return PTR_ERR(rdev);
}
- /* set save_raid_disk if appropriate */
+ /* set saved_raid_disk if appropriate */
if (!mddev->persistent) {
if (info->state & (1<<MD_DISK_SYNC) &&
info->raid_disk < mddev->raid_disks)
@@ -5170,7 +5169,10 @@
} else
super_types[mddev->major_version].
validate_super(mddev, rdev);
- rdev->saved_raid_disk = rdev->raid_disk;
+ if (test_bit(In_sync, &rdev->flags))
+ rdev->saved_raid_disk = rdev->raid_disk;
+ else
+ rdev->saved_raid_disk = -1;
clear_bit(In_sync, &rdev->flags); /* just to be sure */
if (info->state & (1<<MD_DISK_WRITEMOSTLY))
@@ -6042,9 +6044,8 @@
|| kthread_should_stop(),
thread->timeout);
- clear_bit(THREAD_WAKEUP, &thread->flags);
-
- thread->run(thread->mddev);
+ if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags))
+ thread->run(thread->mddev);
}
return 0;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c67aa54..0641674 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2397,13 +2397,13 @@
return 0;
out_free_conf:
+ md_unregister_thread(mddev->thread);
if (conf->r10bio_pool)
mempool_destroy(conf->r10bio_pool);
safe_put_page(conf->tmppage);
kfree(conf->mirrors);
kfree(conf);
mddev->private = NULL;
- md_unregister_thread(mddev->thread);
out:
return -EIO;
}
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index dd90880..d8ae634 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -51,7 +51,7 @@
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-static int __init pxa2xx_flash_probe(struct platform_device *pdev)
+static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
{
struct flash_platform_data *flash = pdev->dev.platform_data;
struct pxa2xx_flash_info *info;
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index cd41c58..15682ec 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -7,7 +7,6 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#define CONFIG_MTD_NAND_OMAP_HWECC
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index c6e8631..2e2b762 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -381,11 +381,11 @@
__b44_set_flow_ctrl(bp, pause_enab);
}
-#ifdef SSB_DRIVER_MIPS
-extern char *nvram_get(char *name);
+#ifdef CONFIG_BCM47XX
+#include <asm/mach-bcm47xx/nvram.h>
static void b44_wap54g10_workaround(struct b44 *bp)
{
- const char *str;
+ char buf[20];
u32 val;
int err;
@@ -394,10 +394,9 @@
* see https://dev.openwrt.org/ticket/146
* check and reset bit "isolate"
*/
- str = nvram_get("boardnum");
- if (!str)
+ if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0)
return;
- if (simple_strtoul(str, NULL, 0) == 2) {
+ if (simple_strtoul(buf, NULL, 0) == 2) {
err = __b44_readphy(bp, 0, MII_BMCR, &val);
if (err)
goto error;
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 36eca1c..e4465d2 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -1235,7 +1235,7 @@
i = 0;
netdev_for_each_mc_addr(ha, netdev)
- memcpy(req->mac[i].byte, ha->addr, ETH_ALEN);
+ memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN);
} else {
req->promiscuous = 1;
}
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 863e73a..d255428 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -20,8 +20,8 @@
* (you will need to reboot afterwards) */
/* #define BNX2X_STOP_ON_ERROR */
-#define DRV_MODULE_VERSION "1.60.00-4"
-#define DRV_MODULE_RELDATE "2010/11/01"
+#define DRV_MODULE_VERSION "1.60.01-0"
+#define DRV_MODULE_RELDATE "2010/11/12"
#define BNX2X_BC_VER 0x040200
#define BNX2X_MULTI_QUEUE
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 94d5f59..0af361e 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -1782,15 +1782,15 @@
}
#endif
-static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb,
- struct eth_tx_parse_bd_e2 *pbd,
- u32 xmit_type)
+static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
+ u32 xmit_type)
{
- pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) <<
- ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT;
+ *parsing_data |= (skb_shinfo(skb)->gso_size <<
+ ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) &
+ ETH_TX_PARSE_BD_E2_LSO_MSS;
if ((xmit_type & XMIT_GSO_V6) &&
(ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6))
- pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
+ *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
}
/**
@@ -1835,15 +1835,15 @@
* @return header len
*/
static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
- struct eth_tx_parse_bd_e2 *pbd,
- u32 xmit_type)
+ u32 *parsing_data, u32 xmit_type)
{
- pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) <<
- ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT;
+ *parsing_data |= ((tcp_hdrlen(skb)/4) <<
+ ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) &
+ ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW;
- pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) -
- skb->data) / 2) <<
- ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT;
+ *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) <<
+ ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) &
+ ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W;
return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data;
}
@@ -1912,6 +1912,7 @@
struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL;
struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
struct eth_tx_parse_bd_e2 *pbd_e2 = NULL;
+ u32 pbd_e2_parsing_data = 0;
u16 pkt_prod, bd_prod;
int nbd, fp_index;
dma_addr_t mapping;
@@ -2033,8 +2034,9 @@
memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
/* Set PBD in checksum offload case */
if (xmit_type & XMIT_CSUM)
- hlen = bnx2x_set_pbd_csum_e2(bp,
- skb, pbd_e2, xmit_type);
+ hlen = bnx2x_set_pbd_csum_e2(bp, skb,
+ &pbd_e2_parsing_data,
+ xmit_type);
} else {
pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x;
memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
@@ -2076,10 +2078,18 @@
bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd,
hlen, bd_prod, ++nbd);
if (CHIP_IS_E2(bp))
- bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type);
+ bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
+ xmit_type);
else
bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type);
}
+
+ /* Set the PBD's parsing_data field if not zero
+ * (for the chips newer than 57711).
+ */
+ if (pbd_e2_parsing_data)
+ pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data);
+
tx_data_bd = (struct eth_tx_bd *)tx_start_bd;
/* Handle fragmented skb */
diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h
index a306b0e..66df29f 100644
--- a/drivers/net/bnx2x/bnx2x_init_ops.h
+++ b/drivers/net/bnx2x/bnx2x_init_ops.h
@@ -838,7 +838,7 @@
/****************************************************************************
* SRC initializations
****************************************************************************/
-
+#ifdef BCM_CNIC
/* called during init func stage */
static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
dma_addr_t t2_mapping, int src_cid_count)
@@ -862,5 +862,5 @@
U64_HI((u64)t2_mapping +
(src_cid_count-1) * sizeof(struct src_ent)));
}
-
+#endif
#endif /* BNX2X_INIT_OPS_H */
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 71a1697..d0ea760 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -171,7 +171,7 @@
/*----------------------------- Global variables ----------------------------*/
#ifdef CONFIG_NET_POLL_CONTROLLER
-cpumask_var_t netpoll_block_tx;
+atomic_t netpoll_block_tx = ATOMIC_INIT(0);
#endif
static const char * const version =
@@ -1576,7 +1576,7 @@
/* If this is the first slave, then we need to set the master's hardware
* address to be the same as the slave's. */
- if (bond->slave_cnt == 0)
+ if (is_zero_ether_addr(bond->dev->dev_addr))
memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
slave_dev->addr_len);
@@ -5299,13 +5299,6 @@
if (res)
goto out;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) {
- res = -ENOMEM;
- goto out;
- }
-#endif
-
res = register_pernet_subsys(&bond_net_ops);
if (res)
goto out;
@@ -5334,9 +5327,6 @@
rtnl_link_unregister(&bond_link_ops);
err_link:
unregister_pernet_subsys(&bond_net_ops);
-#ifdef CONFIG_NET_POLL_CONTROLLER
- free_cpumask_var(netpoll_block_tx);
-#endif
goto out;
}
@@ -5353,7 +5343,10 @@
unregister_pernet_subsys(&bond_net_ops);
#ifdef CONFIG_NET_POLL_CONTROLLER
- free_cpumask_var(netpoll_block_tx);
+ /*
+ * Make sure we don't have an imbalance on our netpoll blocking
+ */
+ WARN_ON(atomic_read(&netpoll_block_tx));
#endif
}
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 4eedb12..c2f08135 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -119,26 +119,22 @@
#ifdef CONFIG_NET_POLL_CONTROLLER
-extern cpumask_var_t netpoll_block_tx;
+extern atomic_t netpoll_block_tx;
static inline void block_netpoll_tx(void)
{
- preempt_disable();
- BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(),
- netpoll_block_tx));
+ atomic_inc(&netpoll_block_tx);
}
static inline void unblock_netpoll_tx(void)
{
- BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(),
- netpoll_block_tx));
- preempt_enable();
+ atomic_dec(&netpoll_block_tx);
}
static inline int is_netpoll_tx_blocked(struct net_device *dev)
{
if (unlikely(dev->priv_flags & IFF_IN_NETPOLL))
- return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx);
+ return atomic_read(&netpoll_block_tx);
return 0;
}
#else
diff --git a/drivers/net/caif/caif_shm_u5500.c b/drivers/net/caif/caif_shm_u5500.c
index 1cd90da..32b1c6f 100644
--- a/drivers/net/caif/caif_shm_u5500.c
+++ b/drivers/net/caif/caif_shm_u5500.c
@@ -5,7 +5,7 @@
* License terms: GNU General Public License (GPL) version 2
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
#include <linux/version.h>
#include <linux/init.h>
diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c
index 19f9c06..8051116 100644
--- a/drivers/net/caif/caif_shmcore.c
+++ b/drivers/net/caif/caif_shmcore.c
@@ -6,7 +6,7 @@
* License terms: GNU General Public License (GPL) version 2
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
#include <linux/spinlock.h>
#include <linux/sched.h>
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c
index bb813d9..e97521c 100644
--- a/drivers/net/cxgb4/t4_hw.c
+++ b/drivers/net/cxgb4/t4_hw.c
@@ -2408,7 +2408,7 @@
if (index < NEXACT_MAC)
ret++;
else if (hash)
- *hash |= (1 << hash_mac_addr(addr[i]));
+ *hash |= (1ULL << hash_mac_addr(addr[i]));
}
return ret;
}
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
index d887a76..6bf464a 100644
--- a/drivers/net/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
@@ -2269,6 +2269,7 @@
{
struct sge *s = &adapter->sge;
int q10g, n10g, qidx, pidx, qs;
+ size_t iqe_size;
/*
* We should not be called till we know how many Queue Sets we can
@@ -2313,6 +2314,13 @@
s->ethqsets = qidx;
/*
+ * The Ingress Queue Entry Size for our various Response Queues needs
+ * to be big enough to accommodate the largest message we can receive
+ * from the chip/firmware; which is 64 bytes ...
+ */
+ iqe_size = 64;
+
+ /*
* Set up default Queue Set parameters ... Start off with the
* shortest interrupt holdoff timer.
*/
@@ -2320,7 +2328,7 @@
struct sge_eth_rxq *rxq = &s->ethrxq[qs];
struct sge_eth_txq *txq = &s->ethtxq[qs];
- init_rspq(&rxq->rspq, 0, 0, 1024, L1_CACHE_BYTES);
+ init_rspq(&rxq->rspq, 0, 0, 1024, iqe_size);
rxq->fl.size = 72;
txq->q.size = 1024;
}
@@ -2329,8 +2337,7 @@
* The firmware event queue is used for link state changes and
* notifications of TX DMA completions.
*/
- init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512,
- L1_CACHE_BYTES);
+ init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, iqe_size);
/*
* The forwarded interrupt queue is used when we're in MSI interrupt
@@ -2346,7 +2353,7 @@
* any time ...
*/
init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1,
- L1_CACHE_BYTES);
+ iqe_size);
}
/*
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c
index 75b099c..1f37ee6 100644
--- a/drivers/net/ehea/ehea_ethtool.c
+++ b/drivers/net/ehea/ehea_ethtool.c
@@ -261,6 +261,13 @@
}
+static int ehea_set_flags(struct net_device *dev, u32 data)
+{
+ return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO
+ | ETH_FLAG_TXVLAN
+ | ETH_FLAG_RXVLAN);
+}
+
const struct ethtool_ops ehea_ethtool_ops = {
.get_settings = ehea_get_settings,
.get_drvinfo = ehea_get_drvinfo,
@@ -273,6 +280,8 @@
.get_ethtool_stats = ehea_get_ethtool_stats,
.get_rx_csum = ehea_get_rx_csum,
.set_settings = ehea_set_settings,
+ .get_flags = ethtool_op_get_flags,
+ .set_flags = ehea_set_flags,
.nway_reset = ehea_nway_reset, /* Restart autonegotiation */
};
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 3d0af08..b95f087cd 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -683,7 +683,7 @@
int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) &&
pr->port->vgrp);
- if (use_lro) {
+ if (skb->dev->features & NETIF_F_LRO) {
if (vlan_extracted)
lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb,
pr->port->vgrp,
@@ -787,7 +787,7 @@
}
cqe = ehea_poll_rq1(qp, &wqe_index);
}
- if (use_lro)
+ if (dev->features & NETIF_F_LRO)
lro_flush_all(&pr->lro_mgr);
pr->rx_packets += processed;
@@ -3278,6 +3278,9 @@
| NETIF_F_LLTX;
dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
+ if (use_lro)
+ dev->features |= NETIF_F_LRO;
+
INIT_WORK(&port->reset_task, ehea_reset_port);
ret = register_netdev(dev);
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index a466ef9..aa28b27 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1962,7 +1962,8 @@
case VNIC_DEV_INTR_MODE_MSIX:
for (i = 0; i < enic->rq_count; i++) {
intr = enic_msix_rq_intr(enic, i);
- enic_isr_msix_rq(enic->msix_entry[intr].vector, enic);
+ enic_isr_msix_rq(enic->msix_entry[intr].vector,
+ &enic->napi[i]);
}
intr = enic_msix_wq_intr(enic, i);
enic_isr_msix_wq(enic->msix_entry[intr].vector, enic);
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index ab9f675..fe337bd 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -104,6 +104,8 @@
rcu_read_unlock();
dev_kfree_skb(skb);
stats->tx_dropped++;
+ if (skb_queue_len(&dp->tq) != 0)
+ goto resched;
break;
}
rcu_read_unlock();
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index fbad4d8..eee0b29 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -4771,6 +4771,9 @@
adapter->rx_ring[i] = NULL;
}
+ adapter->num_tx_queues = 0;
+ adapter->num_rx_queues = 0;
+
ixgbe_free_q_vectors(adapter);
ixgbe_reset_interrupt_capability(adapter);
}
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index cb3d13e..35fda5a 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -64,7 +64,7 @@
config ICPLUS_PHY
tristate "Drivers for ICPlus PHYs"
---help---
- Currently supports the IP175C PHY.
+ Currently supports the IP175C and IP1001 PHYs.
config REALTEK_PHY
tristate "Drivers for Realtek PHYs"
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index c1d2d25..9a09e24 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -30,7 +30,7 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
-MODULE_DESCRIPTION("ICPlus IP175C PHY driver");
+MODULE_DESCRIPTION("ICPlus IP175C/IC1001 PHY drivers");
MODULE_AUTHOR("Michael Barkowski");
MODULE_LICENSE("GPL");
@@ -89,6 +89,33 @@
return 0;
}
+static int ip1001_config_init(struct phy_device *phydev)
+{
+ int err, value;
+
+ /* Software Reset PHY */
+ value = phy_read(phydev, MII_BMCR);
+ value |= BMCR_RESET;
+ err = phy_write(phydev, MII_BMCR, value);
+ if (err < 0)
+ return err;
+
+ do {
+ value = phy_read(phydev, MII_BMCR);
+ } while (value & BMCR_RESET);
+
+ /* Additional delay (2ns) used to adjust RX clock phase
+ * at GMII/ RGMII interface */
+ value = phy_read(phydev, 16);
+ value |= 0x3;
+
+ err = phy_write(phydev, 16, value);
+ if (err < 0)
+ return err;
+
+ return err;
+}
+
static int ip175c_read_status(struct phy_device *phydev)
{
if (phydev->addr == 4) /* WAN port */
@@ -121,21 +148,43 @@
.driver = { .owner = THIS_MODULE,},
};
-static int __init ip175c_init(void)
+static struct phy_driver ip1001_driver = {
+ .phy_id = 0x02430d90,
+ .name = "ICPlus IP1001",
+ .phy_id_mask = 0x0ffffff0,
+ .features = PHY_GBIT_FEATURES | SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause,
+ .config_init = &ip1001_config_init,
+ .config_aneg = &genphy_config_aneg,
+ .read_status = &genphy_read_status,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .driver = { .owner = THIS_MODULE,},
+};
+
+static int __init icplus_init(void)
{
+ int ret = 0;
+
+ ret = phy_driver_register(&ip1001_driver);
+ if (ret < 0)
+ return -ENODEV;
+
return phy_driver_register(&ip175c_driver);
}
-static void __exit ip175c_exit(void)
+static void __exit icplus_exit(void)
{
+ phy_driver_unregister(&ip1001_driver);
phy_driver_unregister(&ip175c_driver);
}
-module_init(ip175c_init);
-module_exit(ip175c_exit);
+module_init(icplus_init);
+module_exit(icplus_exit);
static struct mdio_device_id __maybe_unused icplus_tbl[] = {
{ 0x02430d80, 0x0ffffff0 },
+ { 0x02430d90, 0x0ffffff0 },
{ }
};
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index d72fb05..78c0e3c 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -948,7 +948,7 @@
abort:
kfree_skb(skb);
- return 0;
+ return 1;
}
/************************************************************************
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 2282139..9787dff 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -2083,6 +2083,7 @@
u32 mailbox_in;
u32 mailbox_out;
struct mbox_params idc_mbc;
+ struct mutex mpi_mutex;
int tx_ring_size;
int rx_ring_size;
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 528eaef..2555b1d 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -4629,6 +4629,7 @@
INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log);
init_completion(&qdev->ide_completion);
+ mutex_init(&qdev->mpi_mutex);
if (!cards_found) {
dev_info(&pdev->dev, "%s\n", DRV_STRING);
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 0e7c7c7..a2e919b 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -534,6 +534,7 @@
int status;
unsigned long count;
+ mutex_lock(&qdev->mpi_mutex);
/* Begin polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
@@ -603,6 +604,7 @@
end:
/* End polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
+ mutex_unlock(&qdev->mpi_mutex);
return status;
}
@@ -1099,9 +1101,7 @@
static int ql_set_port_cfg(struct ql_adapter *qdev)
{
int status;
- rtnl_lock();
status = ql_mb_set_port_cfg(qdev);
- rtnl_unlock();
if (status)
return status;
status = ql_idc_wait(qdev);
@@ -1122,9 +1122,7 @@
container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
int status;
- rtnl_lock();
status = ql_mb_get_port_cfg(qdev);
- rtnl_unlock();
if (status) {
netif_err(qdev, drv, qdev->ndev,
"Bug: Failed to get port config data.\n");
@@ -1167,7 +1165,6 @@
u32 aen;
int timeout;
- rtnl_lock();
aen = mbcp->mbox_out[1] >> 16;
timeout = (mbcp->mbox_out[1] >> 8) & 0xf;
@@ -1231,7 +1228,6 @@
}
break;
}
- rtnl_unlock();
}
void ql_mpi_work(struct work_struct *work)
@@ -1242,7 +1238,7 @@
struct mbox_params *mbcp = &mbc;
int err = 0;
- rtnl_lock();
+ mutex_lock(&qdev->mpi_mutex);
/* Begin polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
@@ -1259,7 +1255,7 @@
/* End polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
- rtnl_unlock();
+ mutex_unlock(&qdev->mpi_mutex);
ql_enable_completion_interrupt(qdev, 0);
}
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 7d33ef4..53b13de 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -744,26 +744,36 @@
mdio_write(ioaddr, MII_BMCR, val & 0xffff);
}
-static void rtl8169_check_link_status(struct net_device *dev,
+static void __rtl8169_check_link_status(struct net_device *dev,
struct rtl8169_private *tp,
- void __iomem *ioaddr)
+ void __iomem *ioaddr,
+ bool pm)
{
unsigned long flags;
spin_lock_irqsave(&tp->lock, flags);
if (tp->link_ok(ioaddr)) {
/* This is to cancel a scheduled suspend if there's one. */
- pm_request_resume(&tp->pci_dev->dev);
+ if (pm)
+ pm_request_resume(&tp->pci_dev->dev);
netif_carrier_on(dev);
netif_info(tp, ifup, dev, "link up\n");
} else {
netif_carrier_off(dev);
netif_info(tp, ifdown, dev, "link down\n");
- pm_schedule_suspend(&tp->pci_dev->dev, 100);
+ if (pm)
+ pm_schedule_suspend(&tp->pci_dev->dev, 100);
}
spin_unlock_irqrestore(&tp->lock, flags);
}
+static void rtl8169_check_link_status(struct net_device *dev,
+ struct rtl8169_private *tp,
+ void __iomem *ioaddr)
+{
+ __rtl8169_check_link_status(dev, tp, ioaddr, false);
+}
+
#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
@@ -4600,7 +4610,7 @@
}
if (status & LinkChg)
- rtl8169_check_link_status(dev, tp, ioaddr);
+ __rtl8169_check_link_status(dev, tp, ioaddr, true);
/* We need to see the lastest version of tp->intr_mask to
* avoid ignoring an MSI interrupt and having to wait for
@@ -4890,11 +4900,7 @@
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
- if (!tp->TxDescArray)
- return 0;
-
- rtl8169_check_link_status(dev, tp, tp->mmio_addr);
- return -EBUSY;
+ return tp->TxDescArray ? -EBUSY : 0;
}
static const struct dev_pm_ops rtl8169_pm_ops = {
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 05df20e..fb83cdd 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -197,7 +197,9 @@
static void efx_remove_channels(struct efx_nic *efx);
static void efx_remove_port(struct efx_nic *efx);
+static void efx_init_napi(struct efx_nic *efx);
static void efx_fini_napi(struct efx_nic *efx);
+static void efx_fini_napi_channel(struct efx_channel *channel);
static void efx_fini_struct(struct efx_nic *efx);
static void efx_start_all(struct efx_nic *efx);
static void efx_stop_all(struct efx_nic *efx);
@@ -335,8 +337,10 @@
/* Disable interrupts and wait for ISRs to complete */
efx_nic_disable_interrupts(efx);
- if (efx->legacy_irq)
+ if (efx->legacy_irq) {
synchronize_irq(efx->legacy_irq);
+ efx->legacy_irq_enabled = false;
+ }
if (channel->irq)
synchronize_irq(channel->irq);
@@ -351,6 +355,8 @@
efx_channel_processed(channel);
napi_enable(&channel->napi_str);
+ if (efx->legacy_irq)
+ efx->legacy_irq_enabled = true;
efx_nic_enable_interrupts(efx);
}
@@ -426,6 +432,7 @@
*channel = *old_channel;
+ channel->napi_dev = NULL;
memset(&channel->eventq, 0, sizeof(channel->eventq));
rx_queue = &channel->rx_queue;
@@ -736,9 +743,13 @@
if (rc)
goto rollback;
+ efx_init_napi(efx);
+
/* Destroy old channels */
- for (i = 0; i < efx->n_channels; i++)
+ for (i = 0; i < efx->n_channels; i++) {
+ efx_fini_napi_channel(other_channel[i]);
efx_remove_channel(other_channel[i]);
+ }
out:
/* Free unused channel structures */
for (i = 0; i < efx->n_channels; i++)
@@ -1400,6 +1411,8 @@
efx_start_channel(channel);
}
+ if (efx->legacy_irq)
+ efx->legacy_irq_enabled = true;
efx_nic_enable_interrupts(efx);
/* Switch to event based MCDI completions after enabling interrupts.
@@ -1460,8 +1473,10 @@
/* Disable interrupts and wait for ISR to complete */
efx_nic_disable_interrupts(efx);
- if (efx->legacy_irq)
+ if (efx->legacy_irq) {
synchronize_irq(efx->legacy_irq);
+ efx->legacy_irq_enabled = false;
+ }
efx_for_each_channel(channel, efx) {
if (channel->irq)
synchronize_irq(channel->irq);
@@ -1593,7 +1608,7 @@
*
**************************************************************************/
-static int efx_init_napi(struct efx_nic *efx)
+static void efx_init_napi(struct efx_nic *efx)
{
struct efx_channel *channel;
@@ -1602,18 +1617,21 @@
netif_napi_add(channel->napi_dev, &channel->napi_str,
efx_poll, napi_weight);
}
- return 0;
+}
+
+static void efx_fini_napi_channel(struct efx_channel *channel)
+{
+ if (channel->napi_dev)
+ netif_napi_del(&channel->napi_str);
+ channel->napi_dev = NULL;
}
static void efx_fini_napi(struct efx_nic *efx)
{
struct efx_channel *channel;
- efx_for_each_channel(channel, efx) {
- if (channel->napi_dev)
- netif_napi_del(&channel->napi_str);
- channel->napi_dev = NULL;
- }
+ efx_for_each_channel(channel, efx)
+ efx_fini_napi_channel(channel);
}
/**************************************************************************
@@ -2335,9 +2353,7 @@
if (rc)
goto fail1;
- rc = efx_init_napi(efx);
- if (rc)
- goto fail2;
+ efx_init_napi(efx);
rc = efx->type->init(efx);
if (rc) {
@@ -2368,7 +2384,6 @@
efx->type->fini(efx);
fail3:
efx_fini_napi(efx);
- fail2:
efx_remove_all(efx);
fail1:
return rc;
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 0a7e26d..b137c88 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -621,6 +621,7 @@
* @pci_dev: The PCI device
* @type: Controller type attributes
* @legacy_irq: IRQ number
+ * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)?
* @workqueue: Workqueue for port reconfigures and the HW monitor.
* Work items do not hold and must not acquire RTNL.
* @workqueue_name: Name of workqueue
@@ -709,6 +710,7 @@
struct pci_dev *pci_dev;
const struct efx_nic_type *type;
int legacy_irq;
+ bool legacy_irq_enabled;
struct workqueue_struct *workqueue;
char workqueue_name[16];
struct work_struct reset_work;
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index 41c36b9..67cb0c9 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -1418,6 +1418,12 @@
u32 queues;
int syserr;
+ /* Could this be ours? If interrupts are disabled then the
+ * channel state may not be valid.
+ */
+ if (!efx->legacy_irq_enabled)
+ return result;
+
/* Read the ISR which also ACKs the interrupts */
efx_readd(efx, ®, FR_BZ_INT_ISR0);
queues = EFX_EXTRACT_DWORD(reg, 0, 31);
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index 06bc603..2114837 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -1509,6 +1509,8 @@
pr_warning("\tno valid MAC address;"
"please, use ifconfig or nwhwconfig!\n");
+ spin_lock_init(&priv->lock);
+
ret = register_netdev(dev);
if (ret) {
pr_err("%s: ERROR %i registering the device\n",
@@ -1520,8 +1522,6 @@
dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
(dev->features & NETIF_F_HW_CSUM) ? "on" : "off");
- spin_lock_init(&priv->lock);
-
return ret;
}
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index a9f7d5d..7064e03 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -688,9 +688,6 @@
DMFE_DBUG(0, "dmfe_start_xmit", 0);
- /* Resource flag check */
- netif_stop_queue(dev);
-
/* Too large packet check */
if (skb->len > MAX_PACKET_SIZE) {
pr_err("big packet = %d\n", (u16)skb->len);
@@ -698,6 +695,9 @@
return NETDEV_TX_OK;
}
+ /* Resource flag check */
+ netif_stop_queue(dev);
+
spin_lock_irqsave(&db->lock, flags);
/* No Tx resource check, it never happen nromally */
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 62e9e8d..812edf8 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -958,10 +958,6 @@
/* Packet is complete. Inject into stack. */
/* We have IP packet here */
odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP);
- /* don't check it */
- odev->skb_rx_buf->ip_summed =
- CHECKSUM_UNNECESSARY;
-
skb_reset_mac_header(odev->skb_rx_buf);
/* Ship it off to the kernel */
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c
index ea476cb..e305274 100644
--- a/drivers/net/wan/hd64572.c
+++ b/drivers/net/wan/hd64572.c
@@ -293,6 +293,7 @@
struct net_device *dev = port->netdev;
card_t* card = port->card;
u8 stat;
+ unsigned count = 0;
spin_lock(&port->lock);
@@ -316,10 +317,12 @@
dev->stats.tx_bytes += readw(&desc->len);
}
writeb(0, &desc->stat); /* Free descriptor */
+ count++;
port->txlast = (port->txlast + 1) % card->tx_ring_buffers;
}
- netif_wake_queue(dev);
+ if (count)
+ netif_wake_queue(dev);
spin_unlock(&port->lock);
}
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 8251946..42ed923 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1917,7 +1917,8 @@
sc->bmisscount = 0;
}
- if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
+ if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) ||
+ sc->opmode == NL80211_IFTYPE_MESH_POINT) {
u64 tsf = ath5k_hw_get_tsf64(ah);
u32 tsftu = TSF_TO_TU(tsf);
int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
@@ -1949,8 +1950,9 @@
/* NB: hw still stops DMA, so proceed */
}
- /* refresh the beacon for AP mode */
- if (sc->opmode == NL80211_IFTYPE_AP)
+ /* refresh the beacon for AP or MESH mode */
+ if (sc->opmode == NL80211_IFTYPE_AP ||
+ sc->opmode == NL80211_IFTYPE_MESH_POINT)
ath5k_beacon_update(sc->hw, vif);
ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
@@ -2851,7 +2853,8 @@
/* Assign the vap/adhoc to a beacon xmit slot. */
if ((avf->opmode == NL80211_IFTYPE_AP) ||
- (avf->opmode == NL80211_IFTYPE_ADHOC)) {
+ (avf->opmode == NL80211_IFTYPE_ADHOC) ||
+ (avf->opmode == NL80211_IFTYPE_MESH_POINT)) {
int slot;
WARN_ON(list_empty(&sc->bcbuf));
@@ -2870,7 +2873,7 @@
sc->bslot[avf->bslot] = vif;
if (avf->opmode == NL80211_IFTYPE_AP)
sc->num_ap_vifs++;
- else
+ else if (avf->opmode == NL80211_IFTYPE_ADHOC)
sc->num_adhoc_vifs++;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index c418235..a7b82f0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -55,6 +55,8 @@
#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
+#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
+
static const struct ar9300_eeprom ar9300_default = {
.eepromVersion = 2,
.templateVersion = 2,
@@ -290,20 +292,21 @@
}
},
.ctlPowerData_2G = {
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
- { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
- { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+ { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
- { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
- { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
- { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+ { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
},
.modalHeader5G = {
/* 4 idle,t1,t2,b (4 bits per setting) */
@@ -568,56 +571,56 @@
.ctlPowerData_5G = {
{
{
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
- {60, 1}, {60, 1}, {60, 1}, {60, 0},
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
}
},
{
{
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
- {60, 1}, {60, 1}, {60, 1}, {60, 0},
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
}
},
{
{
- {60, 0}, {60, 1}, {60, 0}, {60, 1},
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
+ CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
}
},
{
{
- {60, 0}, {60, 1}, {60, 1}, {60, 0},
- {60, 1}, {60, 0}, {60, 0}, {60, 0},
+ CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
}
},
{
{
- {60, 1}, {60, 1}, {60, 1}, {60, 0},
- {60, 0}, {60, 0}, {60, 0}, {60, 0},
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+ CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
}
},
{
{
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
- {60, 1}, {60, 0}, {60, 0}, {60, 0},
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
}
},
{
{
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
- {60, 1}, {60, 1}, {60, 1}, {60, 1},
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
}
},
{
{
- {60, 1}, {60, 1}, {60, 0}, {60, 1},
- {60, 1}, {60, 1}, {60, 1}, {60, 0},
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
}
},
{
{
- {60, 1}, {60, 0}, {60, 1}, {60, 1},
- {60, 1}, {60, 1}, {60, 0}, {60, 1},
+ CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+ CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
}
},
}
@@ -1827,9 +1830,9 @@
struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
if (is2GHz)
- return ctl_2g[idx].ctlEdges[edge].tPower;
+ return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
else
- return ctl_5g[idx].ctlEdges[edge].tPower;
+ return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
}
static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
@@ -1847,12 +1850,12 @@
if (is2GHz) {
if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
- ctl_2g[idx].ctlEdges[edge - 1].flag)
- return ctl_2g[idx].ctlEdges[edge - 1].tPower;
+ CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
+ return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
} else {
if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
- ctl_5g[idx].ctlEdges[edge - 1].flag)
- return ctl_5g[idx].ctlEdges[edge - 1].tPower;
+ CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
+ return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
}
return AR9300_MAX_RATE_POWER;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 3c533bb..655b303 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -261,17 +261,12 @@
u8 tPow2x[14];
} __packed;
-struct cal_ctl_edge_pwr {
- u8 tPower:6,
- flag:2;
-} __packed;
-
struct cal_ctl_data_2g {
- struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G];
+ u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G];
} __packed;
struct cal_ctl_data_5g {
- struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
+ u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G];
} __packed;
struct ar9300_eeprom {
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 170d44a..0963071 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -21,6 +21,7 @@
#include <linux/device.h>
#include <linux/leds.h>
#include <linux/completion.h>
+#include <linux/pm_qos_params.h>
#include "debug.h"
#include "common.h"
@@ -328,7 +329,7 @@
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
int ath_tx_setup(struct ath_softc *sc, int haltype);
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
+bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
void ath_draintxq(struct ath_softc *sc,
struct ath_txq *txq, bool retry_tx);
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
@@ -646,6 +647,8 @@
struct ath_descdma txsdma;
struct ath_ant_comb ant_comb;
+
+ struct pm_qos_request_list pm_qos_req;
};
struct ath_wiphy {
@@ -675,7 +678,6 @@
}
extern struct ieee80211_ops ath9k_ops;
-extern struct pm_qos_request_list ath9k_pm_qos_req;
extern int modparam_nohwcrypt;
extern int led_blink;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 1266333..2bbf94d 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -240,16 +240,16 @@
for (i = 0; (i < num_band_edges) &&
(pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
- twiceMaxEdgePower = pRdEdgesPower[i].tPower;
+ twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl);
break;
} else if ((i > 0) &&
(freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
is2GHz))) {
if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
is2GHz) < freq &&
- pRdEdgesPower[i - 1].flag) {
+ CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) {
twiceMaxEdgePower =
- pRdEdgesPower[i - 1].tPower;
+ CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl);
}
break;
}
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index dacb45e..dd59f09 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -233,6 +233,18 @@
#define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1)
+#define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f)
+#define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03)
+
+#define LNA_CTL_BUF_MODE BIT(0)
+#define LNA_CTL_ISEL_LO BIT(1)
+#define LNA_CTL_ISEL_HI BIT(2)
+#define LNA_CTL_BUF_IN BIT(3)
+#define LNA_CTL_FEM_BAND BIT(4)
+#define LNA_CTL_LOCAL_BIAS BIT(5)
+#define LNA_CTL_FORCE_XPA BIT(6)
+#define LNA_CTL_USE_ANT1 BIT(7)
+
enum eeprom_param {
EEP_NFTHRESH_5,
EEP_NFTHRESH_2,
@@ -378,10 +390,7 @@
u8 xatten2Margin[AR5416_MAX_CHAINS];
u8 ob_ch1;
u8 db_ch1;
- u8 useAnt1:1,
- force_xpaon:1,
- local_bias:1,
- femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
+ u8 lna_ctl;
u8 miscBits;
u16 xpaBiasLvlFreq[3];
u8 futureModal[6];
@@ -535,18 +544,10 @@
u8 tPow2x[8];
} __packed;
-
-#ifdef __BIG_ENDIAN_BITFIELD
struct cal_ctl_edges {
u8 bChannel;
- u8 flag:2, tPower:6;
+ u8 ctl;
} __packed;
-#else
-struct cal_ctl_edges {
- u8 bChannel;
- u8 tPower:6, flag:2;
-} __packed;
-#endif
struct cal_data_op_loop_ar9287 {
u8 pwrPdg[2][5];
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 76b4d65..a3ccb1b 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -451,9 +451,10 @@
ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
AR_AN_TOP2_LOCALBIAS,
AR_AN_TOP2_LOCALBIAS_S,
- pModal->local_bias);
+ !!(pModal->lna_ctl &
+ LNA_CTL_LOCAL_BIAS));
REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
- pModal->force_xpaon);
+ !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA));
}
REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
@@ -1062,15 +1063,19 @@
case 1:
break;
case 2:
- scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+ if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
+ scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+ else
+ scaledPower = 0;
break;
case 3:
- scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+ if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
+ scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+ else
+ scaledPower = 0;
break;
}
- scaledPower = max((u16)0, scaledPower);
-
if (IS_CHAN_2GHZ(chan)) {
numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
SUB_NUM_CTL_MODES_AT_2G_40;
@@ -1428,9 +1433,9 @@
num_ant_config = 1;
- if (pBase->version >= 0x0E0D)
- if (pModal->useAnt1)
- num_ant_config += 1;
+ if (pBase->version >= 0x0E0D &&
+ (pModal->lna_ctl & LNA_CTL_USE_ANT1))
+ num_ant_config += 1;
return num_ant_config;
}
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index dfb6560..0de3c3d 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -1024,6 +1024,13 @@
struct hif_device_usb *hif_dev =
(struct hif_device_usb *) usb_get_intfdata(interface);
+ /*
+ * The device has to be set to FULLSLEEP mode in case no
+ * interface is up.
+ */
+ if (!(hif_dev->flags & HIF_USB_START))
+ ath9k_htc_suspend(hif_dev->htc_handle);
+
ath9k_hif_usb_dealloc_urbs(hif_dev);
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 75ecf6a..c3b561d 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -455,6 +455,8 @@
void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv);
void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv);
void ath9k_ps_work(struct work_struct *work);
+bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
+ enum ath9k_power_mode mode);
void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
void ath9k_init_leds(struct ath9k_htc_priv *priv);
@@ -464,6 +466,7 @@
u16 devid, char *product);
void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
#ifdef CONFIG_PM
+void ath9k_htc_suspend(struct htc_target *htc_handle);
int ath9k_htc_resume(struct htc_target *htc_handle);
#endif
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 7c8a38d..8776f49 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -891,6 +891,12 @@
}
#ifdef CONFIG_PM
+
+void ath9k_htc_suspend(struct htc_target *htc_handle)
+{
+ ath9k_htc_setpower(htc_handle->drv_priv, ATH9K_PM_FULL_SLEEP);
+}
+
int ath9k_htc_resume(struct htc_target *htc_handle)
{
int ret;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 9a3be8d..51977ca 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -63,8 +63,8 @@
return mode;
}
-static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
- enum ath9k_power_mode mode)
+bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
+ enum ath9k_power_mode mode)
{
bool ret;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 6ebc68b..c7fbe25 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2044,7 +2044,8 @@
val = REG_READ(ah, AR7010_GPIO_IN);
return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0;
} else if (AR_SREV_9300_20_OR_LATER(ah))
- return MS_REG_READ(AR9300, gpio) != 0;
+ return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) &
+ AR_GPIO_BIT(gpio)) != 0;
else if (AR_SREV_9271(ah))
return MS_REG_READ(AR9271, gpio) != 0;
else if (AR_SREV_9287_11_OR_LATER(ah))
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 92bc5c5..14b8ab3 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -15,7 +15,6 @@
*/
#include <linux/slab.h>
-#include <linux/pm_qos_params.h>
#include "ath9k.h"
@@ -180,8 +179,6 @@
.write = ath9k_iowrite32,
};
-struct pm_qos_request_list ath9k_pm_qos_req;
-
/**************************/
/* Initialization */
/**************************/
@@ -664,6 +661,8 @@
hw->flags |= IEEE80211_HW_MFP_CAPABLE;
hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_P2P_GO) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_WDS) |
BIT(NL80211_IFTYPE_STATION) |
@@ -759,7 +758,7 @@
ath_init_leds(sc);
ath_start_rfkill_poll(sc);
- pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+ pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
PM_QOS_DEFAULT_VALUE);
return 0;
@@ -830,7 +829,7 @@
}
ieee80211_unregister_hw(hw);
- pm_qos_remove_request(&ath9k_pm_qos_req);
+ pm_qos_remove_request(&sc->pm_qos_req);
ath_rx_cleanup(sc);
ath_tx_cleanup(sc);
ath9k_deinit_softc(sc);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 8c13479..c996963 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -703,8 +703,7 @@
rs->rs_phyerr = phyerr;
} else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
rs->rs_status |= ATH9K_RXERR_DECRYPT;
- else if ((ads.ds_rxstatus8 & AR_MichaelErr) &&
- rs->rs_keyix != ATH9K_RXKEYIX_INVALID)
+ else if (ads.ds_rxstatus8 & AR_MichaelErr)
rs->rs_status |= ATH9K_RXERR_MIC;
else if (ads.ds_rxstatus8 & AR_KeyMiss)
rs->rs_status |= ATH9K_RXERR_DECRYPT;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 25d3ef4..c0c3464 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -15,7 +15,6 @@
*/
#include <linux/nl80211.h>
-#include <linux/pm_qos_params.h>
#include "ath9k.h"
#include "btcoex.h"
@@ -245,11 +244,12 @@
* the relevant bits of the h/w.
*/
ath9k_hw_set_interrupts(ah, 0);
- ath_drain_all_txq(sc, false);
+ stopped = ath_drain_all_txq(sc, false);
spin_lock_bh(&sc->rx.pcu_lock);
- stopped = ath_stoprecv(sc);
+ if (!ath_stoprecv(sc))
+ stopped = false;
/* XXX: do not flush receive queue here. We don't want
* to flush data frames already in queue because of
@@ -1244,7 +1244,7 @@
ath9k_btcoex_timer_resume(sc);
}
- pm_qos_update_request(&ath9k_pm_qos_req, 55);
+ pm_qos_update_request(&sc->pm_qos_req, 55);
mutex_unlock:
mutex_unlock(&sc->mutex);
@@ -1423,7 +1423,7 @@
sc->sc_flags |= SC_OP_INVALID;
- pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE);
+ pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE);
mutex_unlock(&sc->mutex);
@@ -1520,7 +1520,6 @@
struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_vif *avp = (void *)vif->drv_priv;
- int i;
ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
@@ -1534,21 +1533,24 @@
if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
+ /* Disable SWBA interrupt */
+ sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
ath9k_ps_wakeup(sc);
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
ath9k_ps_restore(sc);
+ tasklet_kill(&sc->bcon_tasklet);
}
ath_beacon_return(sc, avp);
sc->sc_flags &= ~SC_OP_BEACONS;
- for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
- if (sc->beacon.bslot[i] == vif) {
- printk(KERN_DEBUG "%s: vif had allocated beacon "
- "slot\n", __func__);
- sc->beacon.bslot[i] = NULL;
- sc->beacon.bslot_aphy[i] = NULL;
- }
+ if (sc->nbcnvifs) {
+ /* Re-enable SWBA interrupt */
+ sc->sc_ah->imask |= ATH9K_INT_SWBA;
+ ath9k_ps_wakeup(sc);
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
+ ath9k_ps_restore(sc);
}
sc->nvifs--;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 1a62e35..fdc2ec5 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -838,6 +838,10 @@
struct ath_rx_status *rx_stats,
bool *decrypt_error)
{
+#define is_mc_or_valid_tkip_keyix ((is_mc || \
+ (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \
+ test_bit(rx_stats->rs_keyix, common->tkip_keymap))))
+
struct ath_hw *ah = common->ah;
__le16 fc;
u8 rx_status_len = ah->caps.rx_status_len;
@@ -879,15 +883,18 @@
if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
*decrypt_error = true;
} else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
+ bool is_mc;
/*
* The MIC error bit is only valid if the frame
* is not a control frame or fragment, and it was
* decrypted using a valid TKIP key.
*/
+ is_mc = !!is_multicast_ether_addr(hdr->addr1);
+
if (!ieee80211_is_ctl(fc) &&
!ieee80211_has_morefrags(fc) &&
!(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
- test_bit(rx_stats->rs_keyix, common->tkip_keymap))
+ is_mc_or_valid_tkip_keyix)
rxs->flag |= RX_FLAG_MMIC_ERROR;
else
rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index dddf579..2c6a22f 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -984,11 +984,13 @@
#define AR9287_GPIO_IN_VAL_S 11
#define AR9271_GPIO_IN_VAL 0xFFFF0000
#define AR9271_GPIO_IN_VAL_S 16
-#define AR9300_GPIO_IN_VAL 0x0001FFFF
-#define AR9300_GPIO_IN_VAL_S 0
#define AR7010_GPIO_IN_VAL 0x0000FFFF
#define AR7010_GPIO_IN_VAL_S 0
+#define AR_GPIO_IN 0x404c
+#define AR9300_GPIO_IN_VAL 0x0001FFFF
+#define AR9300_GPIO_IN_VAL_S 0
+
#define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
#define AR_GPIO_OE_OUT_DRV 0x3
#define AR_GPIO_OE_OUT_DRV_NO 0x0
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index f2ade24..aff0478 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1120,7 +1120,7 @@
}
}
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -1128,7 +1128,7 @@
int i, npend = 0;
if (sc->sc_flags & SC_OP_INVALID)
- return;
+ return true;
/* Stop beacon queue */
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
@@ -1142,25 +1142,15 @@
}
}
- if (npend) {
- int r;
-
- ath_print(common, ATH_DBG_FATAL,
- "Failed to stop TX DMA. Resetting hardware!\n");
-
- spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
- if (r)
- ath_print(common, ATH_DBG_FATAL,
- "Unable to reset hardware; reset status %d\n",
- r);
- spin_unlock_bh(&sc->sc_resetlock);
- }
+ if (npend)
+ ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA!\n");
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i))
ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
}
+
+ return !npend;
}
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
index ae6c006..546b4e4 100644
--- a/drivers/net/wireless/ath/carl9170/fw.c
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -291,7 +291,8 @@
if (SUPP(CARL9170FW_WLANTX_CAB)) {
ar->hw->wiphy->interface_modes |=
- BIT(NL80211_IFTYPE_AP);
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_GO);
}
}
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index a314c2c..dc7b30b 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -1631,7 +1631,8 @@
* supports these modes. The code which will add the
* additional interface_modes is in fw.c.
*/
- hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT);
hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index b575c86..7e6506a 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -810,7 +810,7 @@
mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
AR9170_TX_MAC_BACKOFF);
- mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &&
+ mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &
AR9170_TX_MAC_QOS);
no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK);
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index e5685dc..b4de0ca 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -1170,7 +1170,6 @@
lbs_deb_sdio("call remove card\n");
lbs_stop_card(card->priv);
lbs_remove_card(card->priv);
- card->priv->surpriseremoved = 1;
flush_workqueue(card->workqueue);
destroy_workqueue(card->workqueue);
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 79bcb4e5..ecd4d04 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -1055,7 +1055,6 @@
lbs_stop_card(priv);
lbs_remove_card(priv); /* will call free_netdev */
- priv->surpriseremoved = 1;
free_irq(spi->irq, card);
if_spi_terminate_spi_thread(card);
if (card->pdata->teardown)
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 46b88b1..fcd1bbf 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -915,8 +915,6 @@
lbs_free_adapter(priv);
lbs_cfg_free(priv);
-
- priv->dev = NULL;
free_netdev(dev);
lbs_deb_leave(LBS_DEB_MAIN);
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index e8e2d0f..f3d396e 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -1392,10 +1392,9 @@
orinoco_add_hostscan_results(priv, buf, len);
kfree(buf);
- } else if (priv->scan_request) {
+ } else {
/* Either abort or complete the scan */
- cfg80211_scan_done(priv->scan_request, (len < 0));
- priv->scan_request = NULL;
+ orinoco_scan_done(priv, (len < 0));
}
spin_lock_irqsave(&priv->scan_lock, flags);
@@ -1684,6 +1683,8 @@
hermes_write_regn(hw, EVACK, 0xffff);
}
+ orinoco_scan_done(priv, true);
+
/* firmware will have to reassociate */
netif_carrier_off(dev);
priv->last_linkstatus = 0xffff;
@@ -1762,10 +1763,7 @@
orinoco_unlock(priv, &flags);
/* Scanning support: Notify scan cancellation */
- if (priv->scan_request) {
- cfg80211_scan_done(priv->scan_request, 1);
- priv->scan_request = NULL;
- }
+ orinoco_scan_done(priv, true);
if (priv->hard_reset) {
err = (*priv->hard_reset)(priv);
@@ -1813,6 +1811,12 @@
struct net_device *dev = priv->ndev;
int err = 0;
+ /* If we've called commit, we are reconfiguring or bringing the
+ * interface up. Maintaining countermeasures across this would
+ * be confusing, so note that we've disabled them. The port will
+ * be enabled later in orinoco_commit or __orinoco_up. */
+ priv->tkip_cm_active = 0;
+
err = orinoco_hw_program_rids(priv);
/* FIXME: what about netif_tx_lock */
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index 71b3d68..32954c4 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -151,20 +151,20 @@
goto failed;
}
- ret = pcmcia_request_irq(link, orinoco_interrupt);
- if (ret)
- goto failed;
-
- /* We initialize the hermes structure before completing PCMCIA
- * configuration just in case the interrupt handler gets
- * called. */
mem = ioport_map(link->resource[0]->start,
resource_size(link->resource[0]));
if (!mem)
goto failed;
+ /* We initialize the hermes structure before completing PCMCIA
+ * configuration just in case the interrupt handler gets
+ * called. */
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
+ ret = pcmcia_request_irq(link, orinoco_interrupt);
+ if (ret)
+ goto failed;
+
ret = pcmcia_enable_device(link);
if (ret)
goto failed;
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
index 4300d9d..86cb54c 100644
--- a/drivers/net/wireless/orinoco/scan.c
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -229,3 +229,11 @@
priv->scan_request = NULL;
}
}
+
+void orinoco_scan_done(struct orinoco_private *priv, bool abort)
+{
+ if (priv->scan_request) {
+ cfg80211_scan_done(priv->scan_request, abort);
+ priv->scan_request = NULL;
+ }
+}
diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h
index 2dc4e04..27281fb 100644
--- a/drivers/net/wireless/orinoco/scan.h
+++ b/drivers/net/wireless/orinoco/scan.h
@@ -16,5 +16,6 @@
void orinoco_add_hostscan_results(struct orinoco_private *dev,
unsigned char *buf,
size_t len);
+void orinoco_scan_done(struct orinoco_private *priv, bool abort);
#endif /* _ORINOCO_SCAN_H_ */
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index fb859a5..db34c28 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -214,21 +214,21 @@
goto failed;
}
- ret = pcmcia_request_irq(link, orinoco_interrupt);
- if (ret)
- goto failed;
-
- /* We initialize the hermes structure before completing PCMCIA
- * configuration just in case the interrupt handler gets
- * called. */
mem = ioport_map(link->resource[0]->start,
resource_size(link->resource[0]));
if (!mem)
goto failed;
+ /* We initialize the hermes structure before completing PCMCIA
+ * configuration just in case the interrupt handler gets
+ * called. */
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
hw->eeprom_pda = true;
+ ret = pcmcia_request_irq(link, orinoco_interrupt);
+ if (ret)
+ goto failed;
+
ret = pcmcia_enable_device(link);
if (ret)
goto failed;
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 93505f9..e5afabe 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -911,10 +911,10 @@
*/
if (param->value) {
priv->tkip_cm_active = 1;
- ret = hermes_enable_port(hw, 0);
+ ret = hermes_disable_port(hw, 0);
} else {
priv->tkip_cm_active = 0;
- ret = hermes_disable_port(hw, 0);
+ ret = hermes_enable_port(hw, 0);
}
break;
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 458bb57..cdbeec9 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -66,8 +66,8 @@
#define GRANT_INVALID_REF 0
-#define NET_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE)
-#define NET_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE)
+#define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
+#define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
#define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
struct netfront_info {
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 2d73dfc..57313f4 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -180,7 +180,7 @@
};
EXPORT_SYMBOL(pnpacpi_protocol);
-static char *pnpacpi_get_id(struct acpi_device *device)
+static char *__init pnpacpi_get_id(struct acpi_device *device)
{
struct acpi_hardware_id *id;
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c
index 51237fb..6d20b04 100644
--- a/drivers/regulator/tps6586x-regulator.c
+++ b/drivers/regulator/tps6586x-regulator.c
@@ -231,8 +231,7 @@
};
#define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \
- ereg0, ebit0, ereg1, ebit1, goreg, gobit) \
-{ \
+ ereg0, ebit0, ereg1, ebit1) \
.desc = { \
.name = "REG-" #_id, \
.ops = &tps6586x_regulator_##_ops, \
@@ -248,18 +247,26 @@
.enable_bit[0] = (ebit0), \
.enable_reg[1] = TPS6586X_SUPPLY##ereg1, \
.enable_bit[1] = (ebit1), \
- .voltages = tps6586x_##vdata##_voltages, \
-}
+ .voltages = tps6586x_##vdata##_voltages,
+
+#define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \
+ .go_reg = TPS6586X_##goreg, \
+ .go_bit = (gobit),
#define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1) \
+{ \
TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \
- ereg0, ebit0, ereg1, ebit1, 0, 0)
+ ereg0, ebit0, ereg1, ebit1) \
+}
#define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1, goreg, gobit) \
+{ \
TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \
- ereg0, ebit0, ereg1, ebit1, goreg, gobit)
+ ereg0, ebit0, ereg1, ebit1) \
+ TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \
+}
static struct tps6586x_regulator tps6586x_regulator[] = {
TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0),
@@ -267,11 +274,11 @@
TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6),
TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4),
TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5),
- TPS6586X_LDO(LDO_8, ldo, SUPPLYV1, 5, 3, ENC, 6, END, 6),
+ TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6),
TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7),
- TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, ENE, 7, ENE, 7),
+ TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1),
- TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 1, END, 1),
+ TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6),
TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6),
@@ -290,6 +297,10 @@
uint8_t val1, val2;
int ret;
+ if (ri->enable_reg[0] == ri->enable_reg[1] &&
+ ri->enable_bit[0] == ri->enable_bit[1])
+ return 0;
+
ret = tps6586x_read(parent, ri->enable_reg[0], &val1);
if (ret)
return ret;
@@ -298,14 +309,14 @@
if (ret)
return ret;
- if (!(val2 & ri->enable_bit[1]))
+ if (!(val2 & (1 << ri->enable_bit[1])))
return 0;
/*
* The regulator is on, but it's enabled with the bit we don't
* want to use, so we switch the enable bits
*/
- if (!(val1 & ri->enable_bit[0])) {
+ if (!(val1 & (1 << ri->enable_bit[0]))) {
ret = tps6586x_set_bits(parent, ri->enable_reg[0],
1 << ri->enable_bit[0]);
if (ret)
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index d37c733..0bcd580 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -156,6 +156,8 @@
if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) ||
a_status & ZFCP_STATUS_COMMON_ERP_FAILED)
return 0;
+ if (p_status & ZFCP_STATUS_COMMON_NOESC)
+ return need;
if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED))
need = ZFCP_ERP_ACTION_REOPEN_ADAPTER;
/* fall through */
@@ -188,6 +190,9 @@
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
&zfcp_sdev->status);
erp_action = &zfcp_sdev->erp_action;
+ memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+ erp_action->port = port;
+ erp_action->sdev = sdev;
if (!(atomic_read(&zfcp_sdev->status) &
ZFCP_STATUS_COMMON_RUNNING))
act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -200,6 +205,8 @@
zfcp_erp_action_dismiss_port(port);
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
erp_action = &port->erp_action;
+ memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+ erp_action->port = port;
if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING))
act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
break;
@@ -209,6 +216,7 @@
zfcp_erp_action_dismiss_adapter(adapter);
atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
erp_action = &adapter->erp_action;
+ memset(erp_action, 0, sizeof(struct zfcp_erp_action));
if (!(atomic_read(&adapter->status) &
ZFCP_STATUS_COMMON_RUNNING))
act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -218,10 +226,7 @@
return NULL;
}
- memset(erp_action, 0, sizeof(struct zfcp_erp_action));
erp_action->adapter = adapter;
- erp_action->port = port;
- erp_action->sdev = sdev;
erp_action->action = need;
erp_action->status = act_status;
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index be03174..2eb7dd5 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -851,7 +851,7 @@
zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
- req->data = zfcp_sdev;
+ req->data = sdev;
req->handler = zfcp_fsf_abort_fcp_command_handler;
req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
req->qtcb->header.port_handle = zfcp_sdev->port->handle;
@@ -2069,8 +2069,6 @@
struct fcp_resp_with_ext *fcp_rsp;
unsigned long flags;
- zfcp_fsf_fcp_handler_common(req);
-
read_lock_irqsave(&req->adapter->abort_lock, flags);
scpnt = req->data;
@@ -2079,6 +2077,8 @@
return;
}
+ zfcp_fsf_fcp_handler_common(req);
+
if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
goto skip_fsfstatus;
@@ -2170,12 +2170,13 @@
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
struct zfcp_qdio *qdio = adapter->qdio;
struct fsf_qtcb_bottom_io *io;
+ unsigned long flags;
if (unlikely(!(atomic_read(&zfcp_sdev->status) &
ZFCP_STATUS_COMMON_UNBLOCKED)))
return -EBUSY;
- spin_lock(&qdio->req_q_lock);
+ spin_lock_irqsave(&qdio->req_q_lock, flags);
if (atomic_read(&qdio->req_q_free) <= 0) {
atomic_inc(&qdio->req_q_full);
goto out;
@@ -2239,7 +2240,7 @@
zfcp_fsf_req_free(req);
scsi_cmnd->host_scribble = NULL;
out:
- spin_unlock(&qdio->req_q_lock);
+ spin_unlock_irqrestore(&qdio->req_q_lock, flags);
return retval;
}
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 6bd2dbc..63529ed 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -76,8 +76,8 @@
scpnt->scsi_done(scpnt);
}
-static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
- void (*done) (struct scsi_cmnd *))
+static
+int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt)
{
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
@@ -87,7 +87,6 @@
/* reset the status for this request */
scpnt->result = 0;
scpnt->host_scribble = NULL;
- scpnt->scsi_done = done;
scsi_result = fc_remote_port_chkready(rport);
if (unlikely(scsi_result)) {
@@ -127,8 +126,6 @@
return ret;
}
-static DEF_SCSI_QCMD(zfcp_scsi_queuecommand)
-
static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
{
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index b2fb2b2..a6dea08 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -90,11 +90,7 @@
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254},
-#define PCI_DEVICE_ID_HP_CISSF 0x333f
- {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x333F},
- {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
- {PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
{0,}
};
@@ -113,8 +109,6 @@
{0x3249103C, "Smart Array P812", &SA5_access},
{0x324a103C, "Smart Array P712m", &SA5_access},
{0x324b103C, "Smart Array P711m", &SA5_access},
- {0x3233103C, "StorageWorks P1210m", &SA5_access},
- {0x333F103C, "StorageWorks P1210m", &SA5_access},
{0x3250103C, "Smart Array", &SA5_access},
{0x3250113C, "Smart Array", &SA5_access},
{0x3250123C, "Smart Array", &SA5_access},
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 0433ea6..b37c8a3 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -951,8 +951,8 @@
/* create a bio for continuation segment */
bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes,
GFP_KERNEL);
- if (unlikely(!bio))
- return -ENOMEM;
+ if (IS_ERR(bio))
+ return PTR_ERR(bio);
bio->bi_rw |= REQ_WRITE;
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 5e76a62..300d59f 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -62,6 +62,7 @@
static unsigned int pmcraid_debug_log;
static unsigned int pmcraid_disable_aen;
static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST;
+static unsigned int pmcraid_enable_msix;
/*
* Data structures to support multiple adapters by the LLD.
@@ -4691,7 +4692,8 @@
int rc;
struct pci_dev *pdev = pinstance->pdev;
- if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
+ if ((pmcraid_enable_msix) &&
+ (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) {
int num_hrrq = PMCRAID_NUM_MSIX_VECTORS;
struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS];
int i;
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
index 1134279..4db210d 100644
--- a/drivers/scsi/pmcraid.h
+++ b/drivers/scsi/pmcraid.h
@@ -42,7 +42,7 @@
*/
#define PMCRAID_DRIVER_NAME "PMC MaxRAID"
#define PMCRAID_DEVFILE "pmcsas"
-#define PMCRAID_DRIVER_VERSION "2.0.3"
+#define PMCRAID_DRIVER_VERSION "1.0.3"
#define PMCRAID_DRIVER_DATE __DATE__
#define PMCRAID_FW_VERSION_1 0x002
@@ -333,11 +333,9 @@
__u8 lun[PMCRAID_LUN_LEN];
} __attribute__((packed, aligned(4)));
-/* extended configuration table sizes are of 64 bytes in size */
-#define PMCRAID_CFGTE_EXT_SIZE 32
+/* extended configuration table sizes are also of 32 bytes in size */
struct pmcraid_config_table_entry_ext {
struct pmcraid_config_table_entry cfgte;
- __u8 cfgte_ext[PMCRAID_CFGTE_EXT_SIZE];
};
/* resource types (config_table_entry.resource_type values) */
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 3a22eff..9ce539d 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2409,7 +2409,6 @@
uint32_t enable_target_reset :1;
uint32_t enable_lip_full_login :1;
uint32_t enable_led_scheme :1;
- uint32_t inta_enabled :1;
uint32_t msi_enabled :1;
uint32_t msix_enabled :1;
uint32_t disable_serdes :1;
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 5f94430..4c1ba62 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -1061,6 +1061,7 @@
fcp_cmnd->additional_cdb_len |= 2;
int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun);
+ host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun));
memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len);
cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32(
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 1f06ddd..7f77898 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -2491,14 +2491,15 @@
skip_msi:
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
- IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
+ ha->flags.msi_enabled ? 0 : IRQF_SHARED,
+ QLA2XXX_DRIVER_NAME, rsp);
if (ret) {
qla_printk(KERN_WARNING, ha,
"Failed to reserve interrupt %d already in use.\n",
ha->pdev->irq);
goto fail;
}
- ha->flags.inta_enabled = 1;
+
clear_risc_ints:
/*
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 8d9edfb..ae2acac 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -2749,6 +2749,7 @@
goto queuing_error_fcp_cmnd;
int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
+ host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
/* build FCP_CMND IU */
memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 1644eab..2c0876c 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -829,7 +829,7 @@
{
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
srb_t *sp;
- int ret;
+ int ret = SUCCESS;
unsigned int id, lun;
unsigned long flags;
int wait = 0;
@@ -2064,6 +2064,7 @@
ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
ha->gid_list_info_size = 8;
ha->optrom_size = OPTROM_SIZE_82XX;
+ ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
ha->isp_ops = &qla82xx_isp_ops;
ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 8edbccb..cf0075a 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.04-k0"
+#define QLA2XXX_VERSION "8.03.05-k0"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
-#define QLA_DRIVER_PATCH_VER 4
+#define QLA_DRIVER_PATCH_VER 5
#define QLA_DRIVER_BETA_VER 0
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 824b8fc..30ac116 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -615,7 +615,7 @@
return rtn;
}
-static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
+static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
{
if (!scmd->device->host->hostt->eh_abort_handler)
return FAILED;
@@ -623,31 +623,9 @@
return scmd->device->host->hostt->eh_abort_handler(scmd);
}
-/**
- * scsi_try_to_abort_cmd - Ask host to abort a running command.
- * @scmd: SCSI cmd to abort from Lower Level.
- *
- * Notes:
- * This function will not return until the user's completion function
- * has been called. there is no timeout on this operation. if the
- * author of the low-level driver wishes this operation to be timed,
- * they can provide this facility themselves. helper functions in
- * scsi_error.c can be supplied to make this easier to do.
- */
-static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
-{
- /*
- * scsi_done was called just after the command timed out and before
- * we had a chance to process it. (db)
- */
- if (scmd->serial_number == 0)
- return SUCCESS;
- return __scsi_try_to_abort_cmd(scmd);
-}
-
static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
{
- if (__scsi_try_to_abort_cmd(scmd) != SUCCESS)
+ if (scsi_try_to_abort_cmd(scmd) != SUCCESS)
if (scsi_try_bus_device_reset(scmd) != SUCCESS)
if (scsi_try_target_reset(scmd) != SUCCESS)
if (scsi_try_bus_reset(scmd) != SUCCESS)
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index eafeeda..5b6bbae 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1403,11 +1403,6 @@
INIT_LIST_HEAD(&cmd->eh_entry);
- /*
- * Set the serial numbers back to zero
- */
- cmd->serial_number = 0;
-
atomic_inc(&cmd->device->iodone_cnt);
if (cmd->result)
atomic_inc(&cmd->device->ioerr_cnt);
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index 3374618..25a8bc5 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -90,7 +90,8 @@
static void kgdboc_restore_input(void)
{
- schedule_work(&kgdboc_restore_input_work);
+ if (likely(system_state == SYSTEM_RUNNING))
+ schedule_work(&kgdboc_restore_input_work);
}
static int kgdboc_register_kbd(char **cptr)
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c
index 9043931..0838c79 100644
--- a/drivers/spi/dw_spi.c
+++ b/drivers/spi/dw_spi.c
@@ -413,6 +413,11 @@
{
while (dws->write(dws))
dws->read(dws);
+ /*
+ * There is a possibility that the last word of a transaction
+ * will be lost if data is not ready. Re-read to solve this issue.
+ */
+ dws->read(dws);
transfer_complete(dws);
}
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 05bf5a2..989e16e 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -951,7 +951,9 @@
* condition: callbacks we register can be executed at once, before we have
* initialized the struct atm_dev. To protect against this, all callbacks
* abort if atm_dev->dev_data is NULL. */
- atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL);
+ atm_dev = atm_dev_register(instance->driver_name,
+ &instance->usb_intf->dev, &usbatm_atm_devops,
+ -1, NULL);
if (!atm_dev) {
usb_err(instance, "%s: failed to register ATM device!\n", __func__);
return -1;
@@ -966,14 +968,6 @@
/* temp init ATM device, set to 128kbit */
atm_dev->link_rate = 128 * 1000 / 424;
- ret = sysfs_create_link(&atm_dev->class_dev.kobj,
- &instance->usb_intf->dev.kobj, "device");
- if (ret) {
- atm_err(instance, "%s: sysfs_create_link failed: %d\n",
- __func__, ret);
- goto fail_sysfs;
- }
-
if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) {
atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret);
goto fail;
@@ -992,8 +986,6 @@
return 0;
fail:
- sysfs_remove_link(&atm_dev->class_dev.kobj, "device");
- fail_sysfs:
instance->atm_dev = NULL;
atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */
return ret;
@@ -1329,7 +1321,6 @@
/* ATM finalize */
if (instance->atm_dev) {
- sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device");
atm_dev_deregister(instance->atm_dev);
instance->atm_dev = NULL;
}
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 94701ff..159c77a 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -884,6 +884,7 @@
int r;
if (!write_length)
return 0;
+ write_length += write_address % VHOST_PAGE_SIZE;
write_address /= VHOST_PAGE_SIZE;
for (;;) {
u64 base = (u64)(unsigned long)log_base;
@@ -897,7 +898,7 @@
if (write_length <= VHOST_PAGE_SIZE)
break;
write_length -= VHOST_PAGE_SIZE;
- write_address += VHOST_PAGE_SIZE;
+ write_address += 1;
}
return r;
}
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 0a4dbdc..de450c1 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -855,6 +855,7 @@
abs(cmode->yres - mode->yres);
if (diff > d) {
diff = d;
+ diff_refresh = abs(cmode->refresh - mode->refresh);
best = cmode;
} else if (diff == d) {
d = abs(cmode->refresh - mode->refresh);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index c547cca..51d2e4d 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -696,6 +696,7 @@
__btree_submit_bio_done);
}
+#ifdef CONFIG_MIGRATION
static int btree_migratepage(struct address_space *mapping,
struct page *newpage, struct page *page)
{
@@ -712,12 +713,9 @@
if (page_has_private(page) &&
!try_to_release_page(page, GFP_KERNEL))
return -EAGAIN;
-#ifdef CONFIG_MIGRATION
return migrate_page(mapping, newpage, page);
-#else
- return -ENOSYS;
-#endif
}
+#endif
static int btree_writepage(struct page *page, struct writeback_control *wbc)
{
@@ -1009,7 +1007,10 @@
blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
blocksize, generation);
- BUG_ON(!root->node);
+ if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
+ free_extent_buffer(root->node);
+ return -EIO;
+ }
root->commit_root = btrfs_root_node(root);
return 0;
}
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index bcd59c7..227e581 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -429,6 +429,7 @@
static int cache_block_group(struct btrfs_block_group_cache *cache,
struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
int load_cache_only)
{
struct btrfs_fs_info *fs_info = cache->fs_info;
@@ -442,9 +443,12 @@
/*
* We can't do the read from on-disk cache during a commit since we need
- * to have the normal tree locking.
+ * to have the normal tree locking. Also if we are currently trying to
+ * allocate blocks for the tree root we can't do the fast caching since
+ * we likely hold important locks.
*/
- if (!trans->transaction->in_commit) {
+ if (!trans->transaction->in_commit &&
+ (root && root != root->fs_info->tree_root)) {
spin_lock(&cache->lock);
if (cache->cached != BTRFS_CACHE_NO) {
spin_unlock(&cache->lock);
@@ -2741,6 +2745,7 @@
struct btrfs_root *root = block_group->fs_info->tree_root;
struct inode *inode = NULL;
u64 alloc_hint = 0;
+ int dcs = BTRFS_DC_ERROR;
int num_pages = 0;
int retries = 0;
int ret = 0;
@@ -2795,6 +2800,8 @@
spin_lock(&block_group->lock);
if (block_group->cached != BTRFS_CACHE_FINISHED) {
+ /* We're not cached, don't bother trying to write stuff out */
+ dcs = BTRFS_DC_WRITTEN;
spin_unlock(&block_group->lock);
goto out_put;
}
@@ -2821,6 +2828,8 @@
ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages,
num_pages, num_pages,
&alloc_hint);
+ if (!ret)
+ dcs = BTRFS_DC_SETUP;
btrfs_free_reserved_data_space(inode, num_pages);
out_put:
iput(inode);
@@ -2828,10 +2837,7 @@
btrfs_release_path(root, path);
out:
spin_lock(&block_group->lock);
- if (ret)
- block_group->disk_cache_state = BTRFS_DC_ERROR;
- else
- block_group->disk_cache_state = BTRFS_DC_SETUP;
+ block_group->disk_cache_state = dcs;
spin_unlock(&block_group->lock);
return ret;
@@ -3037,7 +3043,13 @@
u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
{
- u64 num_devices = root->fs_info->fs_devices->rw_devices;
+ /*
+ * we add in the count of missing devices because we want
+ * to make sure that any RAID levels on a degraded FS
+ * continue to be honored.
+ */
+ u64 num_devices = root->fs_info->fs_devices->rw_devices +
+ root->fs_info->fs_devices->missing_devices;
if (num_devices == 1)
flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0);
@@ -4080,7 +4092,7 @@
* space back to the block group, otherwise we will leak space.
*/
if (!alloc && cache->cached == BTRFS_CACHE_NO)
- cache_block_group(cache, trans, 1);
+ cache_block_group(cache, trans, NULL, 1);
byte_in_group = bytenr - cache->key.objectid;
WARN_ON(byte_in_group > cache->key.offset);
@@ -4930,11 +4942,31 @@
btrfs_get_block_group(block_group);
search_start = block_group->key.objectid;
+ /*
+ * this can happen if we end up cycling through all the
+ * raid types, but we want to make sure we only allocate
+ * for the proper type.
+ */
+ if (!block_group_bits(block_group, data)) {
+ u64 extra = BTRFS_BLOCK_GROUP_DUP |
+ BTRFS_BLOCK_GROUP_RAID1 |
+ BTRFS_BLOCK_GROUP_RAID10;
+
+ /*
+ * if they asked for extra copies and this block group
+ * doesn't provide them, bail. This does allow us to
+ * fill raid0 from raid1.
+ */
+ if ((data & extra) && !(block_group->flags & extra))
+ goto loop;
+ }
+
have_block_group:
if (unlikely(block_group->cached == BTRFS_CACHE_NO)) {
u64 free_percent;
- ret = cache_block_group(block_group, trans, 1);
+ ret = cache_block_group(block_group, trans,
+ orig_root, 1);
if (block_group->cached == BTRFS_CACHE_FINISHED)
goto have_block_group;
@@ -4958,7 +4990,8 @@
if (loop > LOOP_CACHING_NOWAIT ||
(loop > LOOP_FIND_IDEAL &&
atomic_read(&space_info->caching_threads) < 2)) {
- ret = cache_block_group(block_group, trans, 0);
+ ret = cache_block_group(block_group, trans,
+ orig_root, 0);
BUG_ON(ret);
}
found_uncached_bg = true;
@@ -5515,7 +5548,7 @@
u64 num_bytes = ins->offset;
block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid);
- cache_block_group(block_group, trans, 0);
+ cache_block_group(block_group, trans, NULL, 0);
caching_ctl = get_caching_control(block_group);
if (!caching_ctl) {
@@ -6300,9 +6333,13 @@
NULL, NULL);
BUG_ON(ret < 0);
if (ret > 0) {
- ret = btrfs_del_orphan_item(trans, tree_root,
- root->root_key.objectid);
- BUG_ON(ret);
+ /* if we fail to delete the orphan item this time
+ * around, it'll get picked up the next time.
+ *
+ * The most common failure here is just -ENOENT.
+ */
+ btrfs_del_orphan_item(trans, tree_root,
+ root->root_key.objectid);
}
}
@@ -7878,7 +7915,14 @@
u64 stripped = BTRFS_BLOCK_GROUP_RAID0 |
BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10;
- num_devices = root->fs_info->fs_devices->rw_devices;
+ /*
+ * we add in the count of missing devices because we want
+ * to make sure that any RAID levels on a degraded FS
+ * continue to be honored.
+ */
+ num_devices = root->fs_info->fs_devices->rw_devices +
+ root->fs_info->fs_devices->missing_devices;
+
if (num_devices == 1) {
stripped |= BTRFS_BLOCK_GROUP_DUP;
stripped = flags & ~stripped;
@@ -8247,7 +8291,6 @@
break;
if (ret != 0)
goto error;
-
leaf = path->nodes[0];
btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
cache = kzalloc(sizeof(*cache), GFP_NOFS);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index c1faded..66836d8 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -48,30 +48,34 @@
struct page **prepared_pages,
struct iov_iter *i)
{
- size_t copied;
+ size_t copied = 0;
int pg = 0;
int offset = pos & (PAGE_CACHE_SIZE - 1);
+ int total_copied = 0;
while (write_bytes > 0) {
size_t count = min_t(size_t,
PAGE_CACHE_SIZE - offset, write_bytes);
struct page *page = prepared_pages[pg];
-again:
- if (unlikely(iov_iter_fault_in_readable(i, count)))
- return -EFAULT;
-
- /* Copy data from userspace to the current page */
- copied = iov_iter_copy_from_user(page, i, offset, count);
+ /*
+ * Copy data from userspace to the current page
+ *
+ * Disable pagefault to avoid recursive lock since
+ * the pages are already locked
+ */
+ pagefault_disable();
+ copied = iov_iter_copy_from_user_atomic(page, i, offset, count);
+ pagefault_enable();
/* Flush processor's dcache for this page */
flush_dcache_page(page);
iov_iter_advance(i, copied);
write_bytes -= copied;
+ total_copied += copied;
+ /* Return to btrfs_file_aio_write to fault page */
if (unlikely(copied == 0)) {
- count = min_t(size_t, PAGE_CACHE_SIZE - offset,
- iov_iter_single_seg_count(i));
- goto again;
+ break;
}
if (unlikely(copied < PAGE_CACHE_SIZE - offset)) {
@@ -81,7 +85,7 @@
offset = 0;
}
}
- return 0;
+ return total_copied;
}
/*
@@ -854,6 +858,8 @@
unsigned long last_index;
int will_write;
int buffered = 0;
+ int copied = 0;
+ int dirty_pages = 0;
will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) ||
(file->f_flags & O_DIRECT));
@@ -970,7 +976,17 @@
WARN_ON(num_pages > nrptrs);
memset(pages, 0, sizeof(struct page *) * nrptrs);
- ret = btrfs_delalloc_reserve_space(inode, write_bytes);
+ /*
+ * Fault pages before locking them in prepare_pages
+ * to avoid recursive lock
+ */
+ if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ret = btrfs_delalloc_reserve_space(inode,
+ num_pages << PAGE_CACHE_SHIFT);
if (ret)
goto out;
@@ -978,37 +994,49 @@
pos, first_index, last_index,
write_bytes);
if (ret) {
- btrfs_delalloc_release_space(inode, write_bytes);
+ btrfs_delalloc_release_space(inode,
+ num_pages << PAGE_CACHE_SHIFT);
goto out;
}
- ret = btrfs_copy_from_user(pos, num_pages,
+ copied = btrfs_copy_from_user(pos, num_pages,
write_bytes, pages, &i);
- if (ret == 0) {
+ dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >>
+ PAGE_CACHE_SHIFT;
+
+ if (num_pages > dirty_pages) {
+ if (copied > 0)
+ atomic_inc(
+ &BTRFS_I(inode)->outstanding_extents);
+ btrfs_delalloc_release_space(inode,
+ (num_pages - dirty_pages) <<
+ PAGE_CACHE_SHIFT);
+ }
+
+ if (copied > 0) {
dirty_and_release_pages(NULL, root, file, pages,
- num_pages, pos, write_bytes);
+ dirty_pages, pos, copied);
}
btrfs_drop_pages(pages, num_pages);
- if (ret) {
- btrfs_delalloc_release_space(inode, write_bytes);
- goto out;
+
+ if (copied > 0) {
+ if (will_write) {
+ filemap_fdatawrite_range(inode->i_mapping, pos,
+ pos + copied - 1);
+ } else {
+ balance_dirty_pages_ratelimited_nr(
+ inode->i_mapping,
+ dirty_pages);
+ if (dirty_pages <
+ (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
+ btrfs_btree_balance_dirty(root, 1);
+ btrfs_throttle(root);
+ }
}
- if (will_write) {
- filemap_fdatawrite_range(inode->i_mapping, pos,
- pos + write_bytes - 1);
- } else {
- balance_dirty_pages_ratelimited_nr(inode->i_mapping,
- num_pages);
- if (num_pages <
- (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
- btrfs_btree_balance_dirty(root, 1);
- btrfs_throttle(root);
- }
-
- pos += write_bytes;
- num_written += write_bytes;
+ pos += copied;
+ num_written += copied;
cond_resched();
}
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 22ee0dc..60d6842 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -290,7 +290,7 @@
(unsigned long long)BTRFS_I(inode)->generation,
(unsigned long long)generation,
(unsigned long long)block_group->key.objectid);
- goto out;
+ goto free_cache;
}
if (!num_entries)
@@ -524,6 +524,12 @@
return 0;
}
+ node = rb_first(&block_group->free_space_offset);
+ if (!node) {
+ iput(inode);
+ return 0;
+ }
+
last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
filemap_write_and_wait(inode->i_mapping);
btrfs_wait_ordered_range(inode, inode->i_size &
@@ -543,10 +549,6 @@
*/
first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64);
- node = rb_first(&block_group->free_space_offset);
- if (!node)
- goto out_free;
-
/*
* Lock all pages first so we can lock the extent safely.
*
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8039390..72f31ec 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -495,7 +495,7 @@
add_async_extent(async_cow, start, num_bytes,
total_compressed, pages, nr_pages_ret);
- if (start + num_bytes < end && start + num_bytes < actual_end) {
+ if (start + num_bytes < end) {
start += num_bytes;
pages = NULL;
cond_resched();
@@ -5712,9 +5712,9 @@
if (err) {
printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu "
- "disk_bytenr %lu len %u err no %d\n",
- dip->inode->i_ino, bio->bi_rw, bio->bi_sector,
- bio->bi_size, err);
+ "sector %#Lx len %u err no %d\n",
+ dip->inode->i_ino, bio->bi_rw,
+ (unsigned long long)bio->bi_sector, bio->bi_size, err);
dip->errors = 1;
/*
@@ -5934,8 +5934,7 @@
*/
if (write) {
struct btrfs_ordered_extent *ordered;
- ordered = btrfs_lookup_ordered_extent(inode,
- dip->logical_offset);
+ ordered = btrfs_lookup_ordered_extent(inode, file_offset);
if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) &&
!test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags))
btrfs_free_reserved_extent(root, ordered->start,
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index f1c9bb4..f87552a 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -947,23 +947,42 @@
static noinline int btrfs_ioctl_snap_create(struct file *file,
void __user *arg, int subvol,
- int async)
+ int v2)
{
struct btrfs_ioctl_vol_args *vol_args = NULL;
- struct btrfs_ioctl_async_vol_args *async_vol_args = NULL;
+ struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL;
char *name;
u64 fd;
- u64 transid = 0;
int ret;
- if (async) {
- async_vol_args = memdup_user(arg, sizeof(*async_vol_args));
- if (IS_ERR(async_vol_args))
- return PTR_ERR(async_vol_args);
+ if (v2) {
+ u64 transid = 0;
+ u64 *ptr = NULL;
- name = async_vol_args->name;
- fd = async_vol_args->fd;
- async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0';
+ vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2));
+ if (IS_ERR(vol_args_v2))
+ return PTR_ERR(vol_args_v2);
+
+ if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ name = vol_args_v2->name;
+ fd = vol_args_v2->fd;
+ vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
+
+ if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC)
+ ptr = &transid;
+
+ ret = btrfs_ioctl_snap_create_transid(file, name, fd,
+ subvol, ptr);
+
+ if (ret == 0 && ptr &&
+ copy_to_user(arg +
+ offsetof(struct btrfs_ioctl_vol_args_v2,
+ transid), ptr, sizeof(*ptr)))
+ ret = -EFAULT;
} else {
vol_args = memdup_user(arg, sizeof(*vol_args));
if (IS_ERR(vol_args))
@@ -971,20 +990,13 @@
name = vol_args->name;
fd = vol_args->fd;
vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
+
+ ret = btrfs_ioctl_snap_create_transid(file, name, fd,
+ subvol, NULL);
}
-
- ret = btrfs_ioctl_snap_create_transid(file, name, fd,
- subvol, &transid);
-
- if (!ret && async) {
- if (copy_to_user(arg +
- offsetof(struct btrfs_ioctl_async_vol_args,
- transid), &transid, sizeof(transid)))
- return -EFAULT;
- }
-
+out:
kfree(vol_args);
- kfree(async_vol_args);
+ kfree(vol_args_v2);
return ret;
}
@@ -2246,7 +2258,7 @@
return btrfs_ioctl_getversion(file, argp);
case BTRFS_IOC_SNAP_CREATE:
return btrfs_ioctl_snap_create(file, argp, 0, 0);
- case BTRFS_IOC_SNAP_CREATE_ASYNC:
+ case BTRFS_IOC_SNAP_CREATE_V2:
return btrfs_ioctl_snap_create(file, argp, 0, 1);
case BTRFS_IOC_SUBVOL_CREATE:
return btrfs_ioctl_snap_create(file, argp, 1, 0);
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index 17c99eb..c344d12 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -30,11 +30,15 @@
char name[BTRFS_PATH_NAME_MAX + 1];
};
-#define BTRFS_SNAPSHOT_NAME_MAX 4079
-struct btrfs_ioctl_async_vol_args {
+#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0)
+
+#define BTRFS_SUBVOL_NAME_MAX 4039
+struct btrfs_ioctl_vol_args_v2 {
__s64 fd;
__u64 transid;
- char name[BTRFS_SNAPSHOT_NAME_MAX + 1];
+ __u64 flags;
+ __u64 unused[4];
+ char name[BTRFS_SUBVOL_NAME_MAX + 1];
};
#define BTRFS_INO_LOOKUP_PATH_MAX 4080
@@ -187,6 +191,6 @@
struct btrfs_ioctl_space_args)
#define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64)
#define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
-#define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \
- struct btrfs_ioctl_async_vol_args)
+#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \
+ struct btrfs_ioctl_vol_args_v2)
#endif
diff --git a/fs/btrfs/orphan.c b/fs/btrfs/orphan.c
index 79cba5f..f8be250 100644
--- a/fs/btrfs/orphan.c
+++ b/fs/btrfs/orphan.c
@@ -56,8 +56,12 @@
return -ENOMEM;
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
- if (ret)
+ if (ret < 0)
goto out;
+ if (ret) {
+ ret = -ENOENT;
+ goto out;
+ }
ret = btrfs_del_item(trans, root, path);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index dbb51ea..883c6fa 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -685,9 +685,9 @@
mutex_unlock(&root->d_inode->i_mutex);
if (IS_ERR(new_root)) {
+ dput(root);
deactivate_locked_super(s);
error = PTR_ERR(new_root);
- dput(root);
goto error_free_subvol_name;
}
if (!new_root->d_inode) {
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index cc04dc1..6b98845 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -412,12 +412,16 @@
device->fs_devices = fs_devices;
fs_devices->num_devices++;
- } else if (strcmp(device->name, path)) {
+ } else if (!device->name || strcmp(device->name, path)) {
name = kstrdup(path, GFP_NOFS);
if (!name)
return -ENOMEM;
kfree(device->name);
device->name = name;
+ if (device->missing) {
+ fs_devices->missing_devices--;
+ device->missing = 0;
+ }
}
if (found_transid > fs_devices->latest_trans) {
@@ -1236,6 +1240,9 @@
device->fs_devices->num_devices--;
+ if (device->missing)
+ root->fs_info->fs_devices->missing_devices--;
+
next_device = list_entry(root->fs_info->fs_devices->devices.next,
struct btrfs_device, dev_list);
if (device->bdev == root->fs_info->sb->s_bdev)
@@ -3080,7 +3087,9 @@
device->devid = devid;
device->work.func = pending_bios_fn;
device->fs_devices = fs_devices;
+ device->missing = 1;
fs_devices->num_devices++;
+ fs_devices->missing_devices++;
spin_lock_init(&device->io_lock);
INIT_LIST_HEAD(&device->dev_alloc_list);
memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE);
@@ -3278,6 +3287,15 @@
device = add_missing_dev(root, devid, dev_uuid);
if (!device)
return -ENOMEM;
+ } else if (!device->missing) {
+ /*
+ * this happens when a device that was properly setup
+ * in the device info lists suddenly goes bad.
+ * device->bdev is NULL, and so we have to set
+ * device->missing to one here
+ */
+ root->fs_info->fs_devices->missing_devices++;
+ device->missing = 1;
}
}
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 2b638b6..2740db49 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -44,6 +44,7 @@
int writeable;
int in_fs_metadata;
+ int missing;
spinlock_t io_lock;
@@ -93,6 +94,7 @@
u64 num_devices;
u64 open_devices;
u64 rw_devices;
+ u64 missing_devices;
u64 total_rw_bytes;
struct block_device *latest_bdev;
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 7d447af..158c700 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -114,8 +114,8 @@
spin_lock(&dcache_lock);
/* start at beginning? */
- if (filp->f_pos == 2 || (last &&
- filp->f_pos < ceph_dentry(last)->offset)) {
+ if (filp->f_pos == 2 || last == NULL ||
+ filp->f_pos < ceph_dentry(last)->offset) {
if (list_empty(&parent->d_subdirs))
goto out_unlock;
p = parent->d_subdirs.prev;
diff --git a/fs/ceph/ioctl.h b/fs/ceph/ioctl.h
index a6ce54e..52e8fd7 100644
--- a/fs/ceph/ioctl.h
+++ b/fs/ceph/ioctl.h
@@ -4,7 +4,7 @@
#include <linux/ioctl.h>
#include <linux/types.h>
-#define CEPH_IOCTL_MAGIC 0x98
+#define CEPH_IOCTL_MAGIC 0x97
/* just use u64 to align sanely on all archs */
struct ceph_ioctl_layout {
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c
index 40abde9..476b329 100644
--- a/fs/ceph/locks.c
+++ b/fs/ceph/locks.c
@@ -11,40 +11,68 @@
* Implement fcntl and flock locking functions.
*/
static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
- u64 pid, u64 pid_ns,
- int cmd, u64 start, u64 length, u8 wait)
+ int cmd, u8 wait, struct file_lock *fl)
{
struct inode *inode = file->f_dentry->d_inode;
struct ceph_mds_client *mdsc =
ceph_sb_to_client(inode->i_sb)->mdsc;
struct ceph_mds_request *req;
int err;
+ u64 length = 0;
req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS);
if (IS_ERR(req))
return PTR_ERR(req);
req->r_inode = igrab(inode);
+ /* mds requires start and length rather than start and end */
+ if (LLONG_MAX == fl->fl_end)
+ length = 0;
+ else
+ length = fl->fl_end - fl->fl_start + 1;
+
dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
"length: %llu, wait: %d, type`: %d", (int)lock_type,
- (int)operation, pid, start, length, wait, cmd);
+ (int)operation, (u64)fl->fl_pid, fl->fl_start,
+ length, wait, fl->fl_type);
+
req->r_args.filelock_change.rule = lock_type;
req->r_args.filelock_change.type = cmd;
- req->r_args.filelock_change.pid = cpu_to_le64(pid);
+ req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid);
/* This should be adjusted, but I'm not sure if
namespaces actually get id numbers*/
req->r_args.filelock_change.pid_namespace =
- cpu_to_le64((u64)pid_ns);
- req->r_args.filelock_change.start = cpu_to_le64(start);
+ cpu_to_le64((u64)(unsigned long)fl->fl_nspid);
+ req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start);
req->r_args.filelock_change.length = cpu_to_le64(length);
req->r_args.filelock_change.wait = wait;
err = ceph_mdsc_do_request(mdsc, inode, req);
+
+ if ( operation == CEPH_MDS_OP_GETFILELOCK){
+ fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid);
+ if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type)
+ fl->fl_type = F_RDLCK;
+ else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type)
+ fl->fl_type = F_WRLCK;
+ else
+ fl->fl_type = F_UNLCK;
+
+ fl->fl_start = le64_to_cpu(req->r_reply_info.filelock_reply->start);
+ length = le64_to_cpu(req->r_reply_info.filelock_reply->start) +
+ le64_to_cpu(req->r_reply_info.filelock_reply->length);
+ if (length >= 1)
+ fl->fl_end = length -1;
+ else
+ fl->fl_end = 0;
+
+ }
ceph_mdsc_put_request(req);
dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
- "length: %llu, wait: %d, type`: %d err code %d", (int)lock_type,
- (int)operation, pid, start, length, wait, cmd, err);
+ "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type,
+ (int)operation, (u64)fl->fl_pid, fl->fl_start,
+ length, wait, fl->fl_type, err);
return err;
}
@@ -54,7 +82,6 @@
*/
int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
{
- u64 length;
u8 lock_cmd;
int err;
u8 wait = 0;
@@ -76,29 +103,20 @@
else
lock_cmd = CEPH_LOCK_UNLOCK;
- if (LLONG_MAX == fl->fl_end)
- length = 0;
- else
- length = fl->fl_end - fl->fl_start + 1;
-
- err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
- (u64)fl->fl_pid,
- (u64)(unsigned long)fl->fl_nspid,
- lock_cmd, fl->fl_start,
- length, wait);
+ err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl);
if (!err) {
- dout("mds locked, locking locally");
- err = posix_lock_file(file, fl, NULL);
- if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
- /* undo! This should only happen if the kernel detects
- * local deadlock. */
- ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
- (u64)fl->fl_pid,
- (u64)(unsigned long)fl->fl_nspid,
- CEPH_LOCK_UNLOCK, fl->fl_start,
- length, 0);
- dout("got %d on posix_lock_file, undid lock", err);
+ if ( op != CEPH_MDS_OP_GETFILELOCK ){
+ dout("mds locked, locking locally");
+ err = posix_lock_file(file, fl, NULL);
+ if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
+ /* undo! This should only happen if the kernel detects
+ * local deadlock. */
+ ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
+ CEPH_LOCK_UNLOCK, 0, fl);
+ dout("got %d on posix_lock_file, undid lock", err);
+ }
}
+
} else {
dout("mds returned error code %d", err);
}
@@ -107,7 +125,6 @@
int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
{
- u64 length;
u8 lock_cmd;
int err;
u8 wait = 1;
@@ -127,26 +144,15 @@
lock_cmd = CEPH_LOCK_EXCL;
else
lock_cmd = CEPH_LOCK_UNLOCK;
- /* mds requires start and length rather than start and end */
- if (LLONG_MAX == fl->fl_end)
- length = 0;
- else
- length = fl->fl_end - fl->fl_start + 1;
err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
- file, (u64)fl->fl_pid,
- (u64)(unsigned long)fl->fl_nspid,
- lock_cmd, fl->fl_start,
- length, wait);
+ file, lock_cmd, wait, fl);
if (!err) {
err = flock_lock_file_wait(file, fl);
if (err) {
ceph_lock_message(CEPH_LOCK_FLOCK,
CEPH_MDS_OP_SETFILELOCK,
- file, (u64)fl->fl_pid,
- (u64)(unsigned long)fl->fl_nspid,
- CEPH_LOCK_UNLOCK, fl->fl_start,
- length, 0);
+ file, CEPH_LOCK_UNLOCK, 0, fl);
dout("got %d on flock_lock_file_wait, undid lock", err);
}
} else {
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 098b185..38800ea 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -202,6 +202,38 @@
}
/*
+ * parse fcntl F_GETLK results
+ */
+static int parse_reply_info_filelock(void **p, void *end,
+ struct ceph_mds_reply_info_parsed *info)
+{
+ if (*p + sizeof(*info->filelock_reply) > end)
+ goto bad;
+
+ info->filelock_reply = *p;
+ *p += sizeof(*info->filelock_reply);
+
+ if (unlikely(*p != end))
+ goto bad;
+ return 0;
+
+bad:
+ return -EIO;
+}
+
+/*
+ * parse extra results
+ */
+static int parse_reply_info_extra(void **p, void *end,
+ struct ceph_mds_reply_info_parsed *info)
+{
+ if (info->head->op == CEPH_MDS_OP_GETFILELOCK)
+ return parse_reply_info_filelock(p, end, info);
+ else
+ return parse_reply_info_dir(p, end, info);
+}
+
+/*
* parse entire mds reply
*/
static int parse_reply_info(struct ceph_msg *msg,
@@ -223,10 +255,10 @@
goto out_bad;
}
- /* dir content */
+ /* extra */
ceph_decode_32_safe(&p, end, len, bad);
if (len > 0) {
- err = parse_reply_info_dir(&p, p+len, info);
+ err = parse_reply_info_extra(&p, p+len, info);
if (err < 0)
goto out_bad;
}
@@ -2074,7 +2106,7 @@
mutex_lock(&session->s_mutex);
if (err < 0) {
- pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds);
+ pr_err("mdsc_handle_reply got corrupt reply mds%d(tid:%lld)\n", mds, tid);
ceph_msg_dump(msg);
goto out_err;
}
@@ -2094,7 +2126,8 @@
mutex_lock(&req->r_fill_mutex);
err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session);
if (err == 0) {
- if (result == 0 && rinfo->dir_nr)
+ if (result == 0 && req->r_op != CEPH_MDS_OP_GETFILELOCK &&
+ rinfo->dir_nr)
ceph_readdir_prepopulate(req, req->r_session);
ceph_unreserve_caps(mdsc, &req->r_caps_reservation);
}
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 9341fd4..aabe563b 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -42,26 +42,37 @@
};
/*
- * parsed info about an mds reply, including information about the
- * target inode and/or its parent directory and dentry, and directory
- * contents (for readdir results).
+ * parsed info about an mds reply, including information about
+ * either: 1) the target inode and/or its parent directory and dentry,
+ * and directory contents (for readdir results), or
+ * 2) the file range lock info (for fcntl F_GETLK results).
*/
struct ceph_mds_reply_info_parsed {
struct ceph_mds_reply_head *head;
+ /* trace */
struct ceph_mds_reply_info_in diri, targeti;
struct ceph_mds_reply_dirfrag *dirfrag;
char *dname;
u32 dname_len;
struct ceph_mds_reply_lease *dlease;
- struct ceph_mds_reply_dirfrag *dir_dir;
- int dir_nr;
- char **dir_dname;
- u32 *dir_dname_len;
- struct ceph_mds_reply_lease **dir_dlease;
- struct ceph_mds_reply_info_in *dir_in;
- u8 dir_complete, dir_end;
+ /* extra */
+ union {
+ /* for fcntl F_GETLK results */
+ struct ceph_filelock *filelock_reply;
+
+ /* for readdir results */
+ struct {
+ struct ceph_mds_reply_dirfrag *dir_dir;
+ int dir_nr;
+ char **dir_dname;
+ u32 *dir_dname_len;
+ struct ceph_mds_reply_lease **dir_dlease;
+ struct ceph_mds_reply_info_in *dir_in;
+ u8 dir_complete, dir_end;
+ };
+ };
/* encoded blob describing snapshot contexts for certain
operations (e.g., open) */
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index adefa60..43b19dd 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -6,7 +6,9 @@
cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
- readdir.o ioctl.o sess.o export.o cifsacl.o
+ readdir.o ioctl.o sess.o export.o
+
+cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
diff --git a/fs/cifs/README b/fs/cifs/README
index ee68d10..46af99a 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -337,6 +337,15 @@
wsize default write size (default 57344)
maximum wsize currently allowed by CIFS is 57344 (fourteen
4096 byte pages)
+ actimeo=n attribute cache timeout in seconds (default 1 second).
+ After this timeout, the cifs client requests fresh attribute
+ information from the server. This option allows to tune the
+ attribute cache timeout to suit the workload needs. Shorter
+ timeouts mean better the cache coherency, but increased number
+ of calls to the server. Longer timeouts mean reduced number
+ of calls to the server at the expense of less stricter cache
+ coherency checks (i.e. incorrect attribute cache for a short
+ period of time).
rw mount the network share read-write (note that the
server may still consider the share read-only)
ro mount network share read-only
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index e9a393c..7852cd6 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -48,6 +48,7 @@
struct nls_table *local_nls;
unsigned int rsize;
unsigned int wsize;
+ unsigned long actimeo; /* attribute cache timeout (jiffies) */
atomic_t active;
uid_t mnt_uid;
gid_t mnt_gid;
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index c6ebea0..a437ec3 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -30,8 +30,6 @@
#include "cifs_debug.h"
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
{{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
{{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
@@ -774,4 +772,3 @@
return rc;
}
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index 6c8096c..c4ae7d0 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -74,11 +74,7 @@
char sidname[SIDNAMELENGTH];
} __attribute__((packed));
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
extern int match_sid(struct cifs_sid *);
extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
-
#endif /* _CIFSACL_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 76c8a90..3936aa7 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -463,6 +463,8 @@
seq_printf(s, ",rsize=%d", cifs_sb->rsize);
seq_printf(s, ",wsize=%d", cifs_sb->wsize);
+ /* convert actimeo and display it in seconds */
+ seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
return 0;
}
@@ -935,7 +937,6 @@
GlobalCurrentXid = 0;
GlobalTotalActiveXid = 0;
GlobalMaxActiveXid = 0;
- memset(Local_System_Name, 0, 15);
spin_lock_init(&cifs_tcp_ses_lock);
spin_lock_init(&cifs_file_list_lock);
spin_lock_init(&GlobalMid_Lock);
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index b577bf0..7136c0c 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -45,6 +45,16 @@
#define CIFS_MIN_RCV_POOL 4
/*
+ * default attribute cache timeout (jiffies)
+ */
+#define CIFS_DEF_ACTIMEO (1 * HZ)
+
+/*
+ * max attribute cache timeout (jiffies) - 2^30
+ */
+#define CIFS_MAX_ACTIMEO (1 << 30)
+
+/*
* MAX_REQ is the maximum number of requests that WE will send
* on one socket concurrently. It also matches the most common
* value of max multiplex returned by servers. We may
@@ -746,8 +756,6 @@
GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */
/* on midQ entries */
-GLOBAL_EXTERN char Local_System_Name[15];
-
/*
* Global counters, updated atomically
*/
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index db961dc..e6d1481 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -54,7 +54,8 @@
__func__, curr_xid, (int)rc); \
} while (0)
extern char *build_path_from_dentry(struct dentry *);
-extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb);
+extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
+ struct cifsTconInfo *tcon);
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
extern char *cifs_compose_mount_options(const char *sb_mountdata,
const char *fullpath, const struct dfs_info3_param *ref,
@@ -79,9 +80,7 @@
struct TCP_Server_Info *);
extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
-#endif
extern unsigned int smbCalcSize(struct smb_hdr *ptr);
extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
extern int decode_negTokenInit(unsigned char *security_blob, int length,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 2f2632b..67acfb3 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2478,95 +2478,6 @@
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
-/* Initialize NT TRANSACT SMB into small smb request buffer.
- This assumes that all NT TRANSACTS that we init here have
- total parm and data under about 400 bytes (to fit in small cifs
- buffer size), which is the case so far, it easily fits. NB:
- Setup words themselves and ByteCount
- MaxSetupCount (size of returned setup area) and
- MaxParameterCount (returned parms size) must be set by caller */
-static int
-smb_init_nttransact(const __u16 sub_command, const int setup_count,
- const int parm_len, struct cifsTconInfo *tcon,
- void **ret_buf)
-{
- int rc;
- __u32 temp_offset;
- struct smb_com_ntransact_req *pSMB;
-
- rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
- (void **)&pSMB);
- if (rc)
- return rc;
- *ret_buf = (void *)pSMB;
- pSMB->Reserved = 0;
- pSMB->TotalParameterCount = cpu_to_le32(parm_len);
- pSMB->TotalDataCount = 0;
- pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
- MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->DataCount = pSMB->TotalDataCount;
- temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
- (setup_count * 2) - 4 /* for rfc1001 length itself */;
- pSMB->ParameterOffset = cpu_to_le32(temp_offset);
- pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
- pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
- pSMB->SubCommand = cpu_to_le16(sub_command);
- return 0;
-}
-
-static int
-validate_ntransact(char *buf, char **ppparm, char **ppdata,
- __u32 *pparmlen, __u32 *pdatalen)
-{
- char *end_of_smb;
- __u32 data_count, data_offset, parm_count, parm_offset;
- struct smb_com_ntransact_rsp *pSMBr;
-
- *pdatalen = 0;
- *pparmlen = 0;
-
- if (buf == NULL)
- return -EINVAL;
-
- pSMBr = (struct smb_com_ntransact_rsp *)buf;
-
- /* ByteCount was converted from little endian in SendReceive */
- end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
- (char *)&pSMBr->ByteCount;
-
- data_offset = le32_to_cpu(pSMBr->DataOffset);
- data_count = le32_to_cpu(pSMBr->DataCount);
- parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
- parm_count = le32_to_cpu(pSMBr->ParameterCount);
-
- *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
- *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
-
- /* should we also check that parm and data areas do not overlap? */
- if (*ppparm > end_of_smb) {
- cFYI(1, "parms start after end of smb");
- return -EINVAL;
- } else if (parm_count + *ppparm > end_of_smb) {
- cFYI(1, "parm end after end of smb");
- return -EINVAL;
- } else if (*ppdata > end_of_smb) {
- cFYI(1, "data starts after end of smb");
- return -EINVAL;
- } else if (data_count + *ppdata > end_of_smb) {
- cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
- *ppdata, data_count, (data_count + *ppdata),
- end_of_smb, pSMBr);
- return -EINVAL;
- } else if (parm_count + data_count > pSMBr->ByteCount) {
- cFYI(1, "parm count and data count larger than SMB");
- return -EINVAL;
- }
- *pdatalen = data_count;
- *pparmlen = parm_count;
- return 0;
-}
-
int
CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
@@ -3056,7 +2967,97 @@
#endif /* CONFIG_POSIX */
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
+/*
+ * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
+ * all NT TRANSACTS that we init here have total parm and data under about 400
+ * bytes (to fit in small cifs buffer size), which is the case so far, it
+ * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
+ * returned setup area) and MaxParameterCount (returned parms size) must be set
+ * by caller
+ */
+static int
+smb_init_nttransact(const __u16 sub_command, const int setup_count,
+ const int parm_len, struct cifsTconInfo *tcon,
+ void **ret_buf)
+{
+ int rc;
+ __u32 temp_offset;
+ struct smb_com_ntransact_req *pSMB;
+
+ rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
+ (void **)&pSMB);
+ if (rc)
+ return rc;
+ *ret_buf = (void *)pSMB;
+ pSMB->Reserved = 0;
+ pSMB->TotalParameterCount = cpu_to_le32(parm_len);
+ pSMB->TotalDataCount = 0;
+ pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
+ MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
+ pSMB->ParameterCount = pSMB->TotalParameterCount;
+ pSMB->DataCount = pSMB->TotalDataCount;
+ temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
+ (setup_count * 2) - 4 /* for rfc1001 length itself */;
+ pSMB->ParameterOffset = cpu_to_le32(temp_offset);
+ pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
+ pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
+ pSMB->SubCommand = cpu_to_le16(sub_command);
+ return 0;
+}
+
+static int
+validate_ntransact(char *buf, char **ppparm, char **ppdata,
+ __u32 *pparmlen, __u32 *pdatalen)
+{
+ char *end_of_smb;
+ __u32 data_count, data_offset, parm_count, parm_offset;
+ struct smb_com_ntransact_rsp *pSMBr;
+
+ *pdatalen = 0;
+ *pparmlen = 0;
+
+ if (buf == NULL)
+ return -EINVAL;
+
+ pSMBr = (struct smb_com_ntransact_rsp *)buf;
+
+ /* ByteCount was converted from little endian in SendReceive */
+ end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
+ (char *)&pSMBr->ByteCount;
+
+ data_offset = le32_to_cpu(pSMBr->DataOffset);
+ data_count = le32_to_cpu(pSMBr->DataCount);
+ parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
+ parm_count = le32_to_cpu(pSMBr->ParameterCount);
+
+ *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
+ *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
+
+ /* should we also check that parm and data areas do not overlap? */
+ if (*ppparm > end_of_smb) {
+ cFYI(1, "parms start after end of smb");
+ return -EINVAL;
+ } else if (parm_count + *ppparm > end_of_smb) {
+ cFYI(1, "parm end after end of smb");
+ return -EINVAL;
+ } else if (*ppdata > end_of_smb) {
+ cFYI(1, "data starts after end of smb");
+ return -EINVAL;
+ } else if (data_count + *ppdata > end_of_smb) {
+ cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
+ *ppdata, data_count, (data_count + *ppdata),
+ end_of_smb, pSMBr);
+ return -EINVAL;
+ } else if (parm_count + data_count > pSMBr->ByteCount) {
+ cFYI(1, "parm count and data count larger than SMB");
+ return -EINVAL;
+ }
+ *pdatalen = data_count;
+ *pparmlen = parm_count;
+ return 0;
+}
+
/* Get Security Descriptor (by handle) from remote server for a file or dir */
int
CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
@@ -3214,7 +3215,7 @@
return (rc);
}
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
+#endif /* CONFIG_CIFS_ACL */
/* Legacy Query Path Information call for lookup to old servers such
as Win9x/WinME */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 32fa4d9..cc1a860 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -105,6 +105,7 @@
unsigned int wsize;
bool sockopt_tcp_nodelay:1;
unsigned short int port;
+ unsigned long actimeo; /* attribute cache timeout (jiffies) */
char *prepath;
struct sockaddr_storage srcaddr; /* allow binding to a local IP */
struct nls_table *local_nls;
@@ -806,23 +807,20 @@
short int override_gid = -1;
bool uid_specified = false;
bool gid_specified = false;
+ char *nodename = utsname()->nodename;
separator[0] = ',';
separator[1] = 0;
- if (Local_System_Name[0] != 0)
- memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
- else {
- char *nodename = utsname()->nodename;
- int n = strnlen(nodename, 15);
- memset(vol->source_rfc1001_name, 0x20, 15);
- for (i = 0; i < n; i++) {
- /* does not have to be perfect mapping since field is
- informational, only used for servers that do not support
- port 445 and it can be overridden at mount time */
- vol->source_rfc1001_name[i] = toupper(nodename[i]);
- }
- }
+ /*
+ * does not have to be perfect mapping since field is
+ * informational, only used for servers that do not support
+ * port 445 and it can be overridden at mount time
+ */
+ memset(vol->source_rfc1001_name, 0x20, 15);
+ for (i = 0; i < strnlen(nodename, 15); i++)
+ vol->source_rfc1001_name[i] = toupper(nodename[i]);
+
vol->source_rfc1001_name[15] = 0;
/* null target name indicates to use *SMBSERVR default called name
if we end up sending RFC1001 session initialize */
@@ -840,6 +838,8 @@
/* default to using server inode numbers where available */
vol->server_ino = 1;
+ vol->actimeo = CIFS_DEF_ACTIMEO;
+
if (!options)
return 1;
@@ -1214,6 +1214,16 @@
printk(KERN_WARNING "CIFS: server net"
"biosname longer than 15 truncated.\n");
}
+ } else if (strnicmp(data, "actimeo", 7) == 0) {
+ if (value && *value) {
+ vol->actimeo = HZ * simple_strtoul(value,
+ &value, 0);
+ if (vol->actimeo > CIFS_MAX_ACTIMEO) {
+ cERROR(1, "CIFS: attribute cache"
+ "timeout too large");
+ return 1;
+ }
+ }
} else if (strnicmp(data, "credentials", 4) == 0) {
/* ignore */
} else if (strnicmp(data, "version", 3) == 0) {
@@ -2571,6 +2581,8 @@
cFYI(1, "file mode: 0x%x dir mode: 0x%x",
cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
+ cifs_sb->actimeo = pvolume_info->actimeo;
+
if (pvolume_info->noperm)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
if (pvolume_info->setuids)
@@ -2821,13 +2833,13 @@
/* check if a whole path (including prepath) is not remote */
if (!rc && cifs_sb->prepathlen && tcon) {
/* build_path_to_root works only when we have a valid tcon */
- full_path = cifs_build_path_to_root(cifs_sb);
+ full_path = cifs_build_path_to_root(cifs_sb, tcon);
if (full_path == NULL) {
rc = -ENOMEM;
goto mount_fail_check;
}
rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
- if (rc != -EREMOTE) {
+ if (rc != 0 && rc != -EREMOTE) {
kfree(full_path);
goto mount_fail_check;
}
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index b857ce5..5a28660 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1108,7 +1108,6 @@
return total_written;
}
-#ifdef CONFIG_CIFS_EXPERIMENTAL
struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
bool fsuid_only)
{
@@ -1142,7 +1141,6 @@
spin_unlock(&cifs_file_list_lock);
return NULL;
}
-#endif
struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
bool fsuid_only)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 28cb6e7..589f3e3 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -686,7 +686,7 @@
cFYI(1, "cifs_sfu_type failed: %d", tmprc);
}
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
/* fill in 0777 bits from ACL */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
@@ -697,7 +697,7 @@
goto cgii_exit;
}
}
-#endif
+#endif /* CONFIG_CIFS_ACL */
/* fill in remaining high mode bits e.g. SUID, VTX */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
@@ -728,12 +728,12 @@
.lookup = cifs_lookup,
};
-char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
+char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
+ struct cifsTconInfo *tcon)
{
int pplen = cifs_sb->prepathlen;
int dfsplen;
char *full_path = NULL;
- struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
/* if no prefix path, simply set path to the root of share to "" */
if (pplen == 0) {
@@ -875,7 +875,7 @@
char *full_path;
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
- full_path = cifs_build_path_to_root(cifs_sb);
+ full_path = cifs_build_path_to_root(cifs_sb, tcon);
if (full_path == NULL)
return ERR_PTR(-ENOMEM);
@@ -1653,6 +1653,7 @@
cifs_inode_needs_reval(struct inode *inode)
{
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
if (cifs_i->clientCanCacheRead)
return false;
@@ -1663,12 +1664,12 @@
if (cifs_i->time == 0)
return true;
- /* FIXME: the actimeo should be tunable */
- if (time_after_eq(jiffies, cifs_i->time + HZ))
+ if (!time_in_range(jiffies, cifs_i->time,
+ cifs_i->time + cifs_sb->actimeo))
return true;
/* hardlinked files w/ noserverino get "special" treatment */
- if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
+ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
S_ISREG(inode->i_mode) && inode->i_nlink != 1)
return true;
@@ -2121,7 +2122,7 @@
if (attrs->ia_valid & ATTR_MODE) {
rc = 0;
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
rc = mode_to_cifs_acl(inode, full_path, mode);
if (rc) {
@@ -2130,7 +2131,7 @@
goto cifs_setattr_exit;
}
} else
-#endif
+#endif /* CONFIG_CIFS_ACL */
if (((mode & S_IWUGO) == 0) &&
(cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 32d300e..a73eb9f 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -759,18 +759,6 @@
rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
ino, fattr.cf_dtype);
- /*
- * we can not return filldir errors to the caller since they are
- * "normal" when the stat blocksize is too small - we return remapped
- * error instead
- *
- * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above
- * case already. Why should we be clobbering other errors from it?
- */
- if (rc) {
- cFYI(1, "filldir rc = %d", rc);
- rc = -EOVERFLOW;
- }
dput(tmp_dentry);
return rc;
}
diff --git a/fs/exec.c b/fs/exec.c
index d68c378..c62efcb 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -275,6 +275,11 @@
vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
INIT_LIST_HEAD(&vma->anon_vma_chain);
+
+ err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+ if (err)
+ goto err;
+
err = insert_vm_struct(mm, vma);
if (err)
goto err;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 6a5edea..94ce3d7 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -910,6 +910,7 @@
#define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */
#define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
#define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */
+#define EXT4_MOUNT_MBLK_IO_SUBMIT 0x4000000 /* multi-block io submits */
#define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */
#define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */
#define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index bdbe699..e659597 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2125,9 +2125,12 @@
*/
if (unlikely(journal_data && PageChecked(page)))
err = __ext4_journalled_writepage(page, len);
- else
+ else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT))
err = ext4_bio_write_page(&io_submit, page,
len, mpd->wbc);
+ else
+ err = block_write_full_page(page,
+ noalloc_get_block_write, mpd->wbc);
if (!err)
mpd->pages_written++;
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 92203b8..dc40e75 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -872,7 +872,7 @@
if (namelen > EXT4_NAME_LEN)
return NULL;
if ((namelen <= 2) && (name[0] == '.') &&
- (name[1] == '.' || name[1] == '0')) {
+ (name[1] == '.' || name[1] == '\0')) {
/*
* "." or ".." will only be in the first block
* NFS may look up ".."; "." should be handled by the VFS
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index e32195d..fb15c9c 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1026,6 +1026,8 @@
!(def_mount_opts & EXT4_DEFM_NODELALLOC))
seq_puts(seq, ",nodelalloc");
+ if (test_opt(sb, MBLK_IO_SUBMIT))
+ seq_puts(seq, ",mblk_io_submit");
if (sbi->s_stripe)
seq_printf(seq, ",stripe=%lu", sbi->s_stripe);
/*
@@ -1239,8 +1241,8 @@
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
- Opt_stripe, Opt_delalloc, Opt_nodelalloc,
- Opt_block_validity, Opt_noblock_validity,
+ Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
+ Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
Opt_inode_readahead_blks, Opt_journal_ioprio,
Opt_dioread_nolock, Opt_dioread_lock,
Opt_discard, Opt_nodiscard,
@@ -1304,6 +1306,8 @@
{Opt_resize, "resize"},
{Opt_delalloc, "delalloc"},
{Opt_nodelalloc, "nodelalloc"},
+ {Opt_mblk_io_submit, "mblk_io_submit"},
+ {Opt_nomblk_io_submit, "nomblk_io_submit"},
{Opt_block_validity, "block_validity"},
{Opt_noblock_validity, "noblock_validity"},
{Opt_inode_readahead_blks, "inode_readahead_blks=%u"},
@@ -1725,6 +1729,12 @@
case Opt_nodelalloc:
clear_opt(sbi->s_mount_opt, DELALLOC);
break;
+ case Opt_mblk_io_submit:
+ set_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT);
+ break;
+ case Opt_nomblk_io_submit:
+ clear_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT);
+ break;
case Opt_stripe:
if (match_int(&args[0], &option))
return 0;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 9242d29..8b984a2 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/module.h>
+#include <linux/compat.h>
static const struct file_operations fuse_direct_io_file_operations;
@@ -1628,6 +1629,58 @@
}
/*
+ * CUSE servers compiled on 32bit broke on 64bit kernels because the
+ * ABI was defined to be 'struct iovec' which is different on 32bit
+ * and 64bit. Fortunately we can determine which structure the server
+ * used from the size of the reply.
+ */
+static int fuse_copy_ioctl_iovec(struct iovec *dst, void *src,
+ size_t transferred, unsigned count,
+ bool is_compat)
+{
+#ifdef CONFIG_COMPAT
+ if (count * sizeof(struct compat_iovec) == transferred) {
+ struct compat_iovec *ciov = src;
+ unsigned i;
+
+ /*
+ * With this interface a 32bit server cannot support
+ * non-compat (i.e. ones coming from 64bit apps) ioctl
+ * requests
+ */
+ if (!is_compat)
+ return -EINVAL;
+
+ for (i = 0; i < count; i++) {
+ dst[i].iov_base = compat_ptr(ciov[i].iov_base);
+ dst[i].iov_len = ciov[i].iov_len;
+ }
+ return 0;
+ }
+#endif
+
+ if (count * sizeof(struct iovec) != transferred)
+ return -EIO;
+
+ memcpy(dst, src, transferred);
+ return 0;
+}
+
+/* Make sure iov_length() won't overflow */
+static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
+{
+ size_t n;
+ u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
+
+ for (n = 0; n < count; n++) {
+ if (iov->iov_len > (size_t) max)
+ return -ENOMEM;
+ max -= iov->iov_len;
+ }
+ return 0;
+}
+
+/*
* For ioctls, there is no generic way to determine how much memory
* needs to be read and/or written. Furthermore, ioctls are allowed
* to dereference the passed pointer, so the parameter requires deep
@@ -1808,18 +1861,25 @@
in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV)
goto out;
- err = -EIO;
- if ((in_iovs + out_iovs) * sizeof(struct iovec) != transferred)
- goto out;
-
- /* okay, copy in iovs and retry */
vaddr = kmap_atomic(pages[0], KM_USER0);
- memcpy(page_address(iov_page), vaddr, transferred);
+ err = fuse_copy_ioctl_iovec(page_address(iov_page), vaddr,
+ transferred, in_iovs + out_iovs,
+ (flags & FUSE_IOCTL_COMPAT) != 0);
kunmap_atomic(vaddr, KM_USER0);
+ if (err)
+ goto out;
in_iov = page_address(iov_page);
out_iov = in_iov + in_iovs;
+ err = fuse_verify_ioctl_iov(in_iov, in_iovs);
+ if (err)
+ goto out;
+
+ err = fuse_verify_ioctl_iov(out_iov, out_iovs);
+ if (err)
+ goto out;
+
goto retry;
}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index f0a384e..996dd89 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -57,7 +57,7 @@
struct inode *, struct dentry *);
static int nfs_fsync_dir(struct file *, int);
static loff_t nfs_llseek_dir(struct file *, loff_t, int);
-static int nfs_readdir_clear_array(struct page*, gfp_t);
+static void nfs_readdir_clear_array(struct page*);
const struct file_operations nfs_dir_operations = {
.llseek = nfs_llseek_dir,
@@ -83,8 +83,8 @@
.setattr = nfs_setattr,
};
-const struct address_space_operations nfs_dir_addr_space_ops = {
- .releasepage = nfs_readdir_clear_array,
+const struct address_space_operations nfs_dir_aops = {
+ .freepage = nfs_readdir_clear_array,
};
#ifdef CONFIG_NFS_V3
@@ -178,6 +178,7 @@
struct page *page;
unsigned long page_index;
u64 *dir_cookie;
+ u64 last_cookie;
loff_t current_index;
decode_dirent_t decode;
@@ -213,17 +214,15 @@
* we are freeing strings created by nfs_add_to_readdir_array()
*/
static
-int nfs_readdir_clear_array(struct page *page, gfp_t mask)
+void nfs_readdir_clear_array(struct page *page)
{
- struct nfs_cache_array *array = nfs_readdir_get_array(page);
+ struct nfs_cache_array *array;
int i;
- if (IS_ERR(array))
- return PTR_ERR(array);
+ array = kmap_atomic(page, KM_USER0);
for (i = 0; i < array->size; i++)
kfree(array->array[i].string.name);
- nfs_readdir_release_array(page);
- return 0;
+ kunmap_atomic(array, KM_USER0);
}
/*
@@ -272,7 +271,7 @@
goto out;
array->last_cookie = entry->cookie;
array->size++;
- if (entry->eof == 1)
+ if (entry->eof != 0)
array->eof_index = array->size;
out:
nfs_readdir_release_array(page);
@@ -312,15 +311,14 @@
for (i = 0; i < array->size; i++) {
if (array->array[i].cookie == *desc->dir_cookie) {
desc->cache_entry_index = i;
- status = 0;
- goto out;
+ return 0;
}
}
- if (i == array->eof_index) {
- desc->eof = 1;
+ if (array->eof_index >= 0) {
status = -EBADCOOKIE;
+ if (*desc->dir_cookie == array->last_cookie)
+ desc->eof = 1;
}
-out:
return status;
}
@@ -328,10 +326,7 @@
int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
{
struct nfs_cache_array *array;
- int status = -EBADCOOKIE;
-
- if (desc->dir_cookie == NULL)
- goto out;
+ int status;
array = nfs_readdir_get_array(desc->page);
if (IS_ERR(array)) {
@@ -344,6 +339,10 @@
else
status = nfs_readdir_search_for_cookie(array, desc);
+ if (status == -EAGAIN) {
+ desc->last_cookie = array->last_cookie;
+ desc->page_index++;
+ }
nfs_readdir_release_array(desc->page);
out:
return status;
@@ -490,7 +489,7 @@
count++;
- if (desc->plus == 1)
+ if (desc->plus != 0)
nfs_prime_dcache(desc->file->f_path.dentry, entry);
status = nfs_readdir_add_to_array(entry, page);
@@ -498,7 +497,7 @@
break;
} while (!entry->eof);
- if (count == 0 || (status == -EBADCOOKIE && entry->eof == 1)) {
+ if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) {
array = nfs_readdir_get_array(page);
if (!IS_ERR(array)) {
array->eof_index = array->size;
@@ -563,7 +562,7 @@
unsigned int array_size = ARRAY_SIZE(pages);
entry.prev_cookie = 0;
- entry.cookie = *desc->dir_cookie;
+ entry.cookie = desc->last_cookie;
entry.eof = 0;
entry.fh = nfs_alloc_fhandle();
entry.fattr = nfs_alloc_fattr();
@@ -636,6 +635,8 @@
static
void cache_page_release(nfs_readdir_descriptor_t *desc)
{
+ if (!desc->page->mapping)
+ nfs_readdir_clear_array(desc->page);
page_cache_release(desc->page);
desc->page = NULL;
}
@@ -660,9 +661,8 @@
return PTR_ERR(desc->page);
res = nfs_readdir_search_array(desc);
- if (res == 0)
- return 0;
- cache_page_release(desc);
+ if (res != 0)
+ cache_page_release(desc);
return res;
}
@@ -672,22 +672,16 @@
{
int res;
- if (desc->page_index == 0)
+ if (desc->page_index == 0) {
desc->current_index = 0;
- while (1) {
- res = find_cache_page(desc);
- if (res != -EAGAIN)
- break;
- desc->page_index++;
+ desc->last_cookie = 0;
}
+ do {
+ res = find_cache_page(desc);
+ } while (res == -EAGAIN);
return res;
}
-static inline unsigned int dt_type(struct inode *inode)
-{
- return (inode->i_mode >> 12) & 15;
-}
-
/*
* Once we've found the start of the dirent within a page: fill 'er up...
*/
@@ -717,13 +711,12 @@
break;
}
file->f_pos++;
- desc->cache_entry_index = i;
if (i < (array->size-1))
*desc->dir_cookie = array->array[i+1].cookie;
else
*desc->dir_cookie = array->last_cookie;
}
- if (i == array->eof_index)
+ if (array->eof_index >= 0)
desc->eof = 1;
nfs_readdir_release_array(desc->page);
@@ -764,6 +757,7 @@
}
desc->page_index = 0;
+ desc->last_cookie = *desc->dir_cookie;
desc->page = page;
status = nfs_readdir_xdr_to_array(desc, page, inode);
@@ -791,7 +785,7 @@
struct inode *inode = dentry->d_inode;
nfs_readdir_descriptor_t my_desc,
*desc = &my_desc;
- int res = -ENOMEM;
+ int res;
dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -816,7 +810,7 @@
if (res < 0)
goto out;
- while (desc->eof != 1) {
+ do {
res = readdir_search_pagecache(desc);
if (res == -EBADCOOKIE) {
@@ -844,7 +838,7 @@
res = nfs_do_filldir(desc, dirent, filldir);
if (res < 0)
break;
- }
+ } while (!desc->eof);
out:
nfs_unblock_sillyrename(dentry);
if (res > 0)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 60677f9..7bf029e 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -693,6 +693,7 @@
{
struct inode *inode = filp->f_mapping->host;
int status = 0;
+ unsigned int saved_type = fl->fl_type;
/* Try local locking first */
posix_test_lock(filp, fl);
@@ -700,6 +701,7 @@
/* found a conflict */
goto out;
}
+ fl->fl_type = saved_type;
if (nfs_have_delegation(inode, FMODE_READ))
goto out_noconflict;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 314f571..e67e31c 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -289,6 +289,7 @@
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
inode->i_fop = &nfs_dir_operations;
+ inode->i_data.a_ops = &nfs_dir_aops;
if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS))
set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
/* Deal with crossing mountpoints */
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index eceafe7..4f981f1 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -505,13 +505,13 @@
static struct rpc_version mnt_version1 = {
.number = 1,
- .nrprocs = 2,
+ .nrprocs = ARRAY_SIZE(mnt_procedures),
.procs = mnt_procedures,
};
static struct rpc_version mnt_version3 = {
.number = 3,
- .nrprocs = 2,
+ .nrprocs = ARRAY_SIZE(mnt3_procedures),
.procs = mnt3_procedures,
};
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6a653ff..4435e5e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3361,6 +3361,8 @@
ret = nfs_revalidate_inode(server, inode);
if (ret < 0)
return ret;
+ if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL)
+ nfs_zap_acl_cache(inode);
ret = nfs4_read_cached_acl(inode, buf, buflen);
if (ret != -ENOENT)
return ret;
@@ -3389,6 +3391,13 @@
nfs_inode_return_delegation(inode);
buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
ret = nfs4_call_sync(server, &msg, &arg, &res, 1);
+ /*
+ * Acl update can result in inode attribute update.
+ * so mark the attribute cache invalid.
+ */
+ spin_lock(&inode->i_lock);
+ NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
+ spin_unlock(&inode->i_lock);
nfs_access_zap_cache(inode);
nfs_zap_acl_cache(inode);
return ret;
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 137b549..b68536c 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -115,7 +115,7 @@
{
if (!nfs_lock_request_dontget(req))
return 0;
- if (req->wb_page != NULL)
+ if (test_bit(PG_MAPPED, &req->wb_flags))
radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
return 1;
}
@@ -125,7 +125,7 @@
*/
void nfs_clear_page_tag_locked(struct nfs_page *req)
{
- if (req->wb_page != NULL) {
+ if (test_bit(PG_MAPPED, &req->wb_flags)) {
struct inode *inode = req->wb_context->path.dentry->d_inode;
struct nfs_inode *nfsi = NFS_I(inode);
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index e4b62c6..aedcaa7 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -152,7 +152,6 @@
(long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
req->wb_bytes,
(long long)req_offset(req));
- nfs_clear_request(req);
nfs_release_request(req);
}
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 3c04504..4100630 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1069,12 +1069,10 @@
mnt->flags |= NFS_MOUNT_VER3;
mnt->version = 3;
break;
-#ifdef CONFIG_NFS_V4
case Opt_v4:
mnt->flags &= ~NFS_MOUNT_VER3;
mnt->version = 4;
break;
-#endif
case Opt_udp:
mnt->flags &= ~NFS_MOUNT_TCP;
mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
@@ -1286,12 +1284,10 @@
mnt->flags |= NFS_MOUNT_VER3;
mnt->version = 3;
break;
-#ifdef CONFIG_NFS_V4
case NFS4_VERSION:
mnt->flags &= ~NFS_MOUNT_VER3;
mnt->version = 4;
break;
-#endif
default:
goto out_invalid_value;
}
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 4c14c17..10d648ea 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -390,6 +390,7 @@
if (nfs_have_delegation(inode, FMODE_WRITE))
nfsi->change_attr++;
}
+ set_bit(PG_MAPPED, &req->wb_flags);
SetPagePrivate(req->wb_page);
set_page_private(req->wb_page, (unsigned long)req);
nfsi->npages++;
@@ -415,6 +416,7 @@
spin_lock(&inode->i_lock);
set_page_private(req->wb_page, 0);
ClearPagePrivate(req->wb_page);
+ clear_bit(PG_MAPPED, &req->wb_flags);
radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
nfsi->npages--;
if (!nfsi->npages) {
@@ -422,7 +424,6 @@
iput(inode);
} else
spin_unlock(&inode->i_lock);
- nfs_clear_request(req);
nfs_release_request(req);
}
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 2a533a0..7e84a85 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -260,9 +260,11 @@
err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry,
&fhp->fh_post_attr);
fhp->fh_post_change = fhp->fh_dentry->d_inode->i_version;
- if (err)
+ if (err) {
fhp->fh_post_saved = 0;
- else
+ /* Grab the ctime anyway - set_change_info might use it */
+ fhp->fh_post_attr.ctime = fhp->fh_dentry->d_inode->i_ctime;
+ } else
fhp->fh_post_saved = 1;
}
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 4d476ff..60fce3d 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -484,18 +484,17 @@
static inline void
set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
{
- BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved);
- cinfo->atomic = 1;
+ BUG_ON(!fhp->fh_pre_saved);
+ cinfo->atomic = fhp->fh_post_saved;
cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode);
- if (cinfo->change_supported) {
- cinfo->before_change = fhp->fh_pre_change;
- cinfo->after_change = fhp->fh_post_change;
- } else {
- cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
- cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
- cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
- cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
- }
+
+ cinfo->before_change = fhp->fh_pre_change;
+ cinfo->after_change = fhp->fh_post_change;
+ cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
+ cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
+ cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
+ cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
+
}
int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *);
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index d2af0a8..77a5989 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -297,6 +297,7 @@
* it and some incremental backup programs won't work without it.
*/
xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG);
+ xfs_trans_log_inode(tp, src_ip, XFS_ILOG_CORE);
/*
* Adjust the link count on src_dp. This is necessary when
diff --git a/include/acpi/video.h b/include/acpi/video.h
index 551793c..0e98e67 100644
--- a/include/acpi/video.h
+++ b/include/acpi/video.h
@@ -1,6 +1,10 @@
#ifndef __ACPI_VIDEO_H
#define __ACPI_VIDEO_H
+#include <linux/errno.h> /* for ENODEV */
+
+struct acpi_device;
+
#define ACPI_VIDEO_DISPLAY_CRT 1
#define ACPI_VIDEO_DISPLAY_TV 2
#define ACPI_VIDEO_DISPLAY_DVI 3
@@ -26,4 +30,3 @@
#endif
#endif
-
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 050a7bc..67c91b4 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -219,7 +219,7 @@
extern int acpi_blacklisted(void);
extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
-extern int acpi_osi_setup(char *str);
+extern void acpi_osi_setup(char *str);
#ifdef CONFIG_ACPI_NUMA
int acpi_get_pxm(acpi_handle handle);
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index a8e4e83..475f8c4 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -427,8 +427,10 @@
#define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb))
-struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
- int number,unsigned long *flags); /* number == -1: pick first available */
+struct atm_dev *atm_dev_register(const char *type, struct device *parent,
+ const struct atmdev_ops *ops,
+ int number, /* -1 == pick first available */
+ unsigned long *flags);
struct atm_dev *atm_dev_lookup(int number);
void atm_dev_deregister(struct atm_dev *dev);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index c9e06cc..090f0ea 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -602,6 +602,7 @@
sector_t (*bmap)(struct address_space *, sector_t);
void (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, gfp_t);
+ void (*freepage)(struct page *);
ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
int (*get_xip_mem)(struct address_space *, pgoff_t, int,
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index 5c51f36..add8a1b 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -29,7 +29,7 @@
#define WM8994_CONFIGURE_GPIO 0x8000
#define WM8994_DRC_REGS 5
-#define WM8994_EQ_REGS 19
+#define WM8994_EQ_REGS 20
/**
* DRC configurations are specified with a label and a set of register
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index c66fdb7..29d504d 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -401,6 +401,7 @@
#endif /* CONFIG_NFS_V3 */
extern const struct file_operations nfs_file_operations;
extern const struct address_space_operations nfs_file_aops;
+extern const struct address_space_operations nfs_dir_aops;
static inline struct nfs_open_context *nfs_file_open_context(struct file *filp)
{
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index f8b60e7..d55cee7 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -29,6 +29,7 @@
*/
enum {
PG_BUSY = 0,
+ PG_MAPPED,
PG_CLEAN,
PG_NEED_COMMIT,
PG_NEED_RESCHED,
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index ebb0c80..12b2b18 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -230,6 +230,7 @@
LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */
LINUX_MIB_TCPDEFERACCEPTDROP,
LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */
+ LINUX_MIB_TCPTIMEWAITOVERFLOW, /* TCPTimeWaitOverflow */
__LINUX_MIB_MAX
};
diff --git a/include/linux/video_output.h b/include/linux/video_output.h
index 2fb46bc..ed5cdeb 100644
--- a/include/linux/video_output.h
+++ b/include/linux/video_output.h
@@ -23,6 +23,7 @@
#ifndef _LINUX_VIDEO_OUTPUT_H
#define _LINUX_VIDEO_OUTPUT_H
#include <linux/device.h>
+#include <linux/err.h>
struct output_device;
struct output_properties {
int (*set_state)(struct output_device *);
@@ -34,9 +35,23 @@
struct device dev;
};
#define to_output_device(obj) container_of(obj, struct output_device, dev)
+#if defined(CONFIG_VIDEO_OUTPUT_CONTROL) || defined(CONFIG_VIDEO_OUTPUT_CONTROL_MODULE)
struct output_device *video_output_register(const char *name,
struct device *dev,
void *devdata,
struct output_properties *op);
void video_output_unregister(struct output_device *dev);
+#else
+static struct output_device *video_output_register(const char *name,
+ struct device *dev,
+ void *devdata,
+ struct output_properties *op)
+{
+ return ERR_PTR(-ENODEV);
+}
+static void video_output_unregister(struct output_device *dev)
+{
+ return;
+}
+#endif
#endif
diff --git a/include/net/sock.h b/include/net/sock.h
index a6338d0..659d968d9 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1155,6 +1155,8 @@
/* Initialise core socket variables */
extern void sock_init_data(struct socket *sock, struct sock *sk);
+extern void sk_filter_release_rcu(struct rcu_head *rcu);
+
/**
* sk_filter_release - release a socket filter
* @fp: filter to remove
@@ -1165,7 +1167,7 @@
static inline void sk_filter_release(struct sk_filter *fp)
{
if (atomic_dec_and_test(&fp->refcnt))
- kfree(fp);
+ call_rcu_bh(&fp->rcu, sk_filter_release_rcu);
}
static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h
index e8cbf43..75271b9 100644
--- a/include/xen/interface/io/ring.h
+++ b/include/xen/interface/io/ring.h
@@ -24,8 +24,15 @@
* A ring contains as many entries as will fit, rounded down to the nearest
* power of two (so we can mask with (size-1) to loop around).
*/
-#define __RING_SIZE(_s, _sz) \
- (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
+#define __CONST_RING_SIZE(_s, _sz) \
+ (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \
+ sizeof(((struct _s##_sring *)0)->ring[0])))
+
+/*
+ * The same for passing in an actual pointer instead of a name tag.
+ */
+#define __RING_SIZE(_s, _sz) \
+ (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
/*
* Macros to make the correct C datatypes for a new kind of ring.
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 90db1bd..e785b0f 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -661,7 +661,7 @@
{
struct worker *worker = kthread_data(task);
- if (likely(!(worker->flags & WORKER_NOT_RUNNING)))
+ if (!(worker->flags & WORKER_NOT_RUNNING))
atomic_inc(get_gcwq_nr_running(cpu));
}
@@ -687,7 +687,7 @@
struct global_cwq *gcwq = get_gcwq(cpu);
atomic_t *nr_running = get_gcwq_nr_running(cpu);
- if (unlikely(worker->flags & WORKER_NOT_RUNNING))
+ if (worker->flags & WORKER_NOT_RUNNING)
return NULL;
/* this can only happen on the local cpu */
@@ -3692,7 +3692,8 @@
system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0);
system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND,
WQ_UNBOUND_MAX_ACTIVE);
- BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq);
+ BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq ||
+ !system_unbound_wq);
return 0;
}
early_initcall(init_workqueues);
diff --git a/mm/filemap.c b/mm/filemap.c
index ea89840..6b9aee2 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -143,13 +143,18 @@
void remove_from_page_cache(struct page *page)
{
struct address_space *mapping = page->mapping;
+ void (*freepage)(struct page *);
BUG_ON(!PageLocked(page));
+ freepage = mapping->a_ops->freepage;
spin_lock_irq(&mapping->tree_lock);
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);
+
+ if (freepage)
+ freepage(page);
}
EXPORT_SYMBOL(remove_from_page_cache);
diff --git a/mm/mmap.c b/mm/mmap.c
index b179abb..50a4aa0 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2462,6 +2462,7 @@
unsigned long addr, unsigned long len,
unsigned long vm_flags, struct page **pages)
{
+ int ret;
struct vm_area_struct *vma;
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
@@ -2479,16 +2480,23 @@
vma->vm_ops = &special_mapping_vmops;
vma->vm_private_data = pages;
- if (unlikely(insert_vm_struct(mm, vma))) {
- kmem_cache_free(vm_area_cachep, vma);
- return -ENOMEM;
- }
+ ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+ if (ret)
+ goto out;
+
+ ret = insert_vm_struct(mm, vma);
+ if (ret)
+ goto out;
mm->total_vm += len >> PAGE_SHIFT;
perf_event_mmap(vma);
return 0;
+
+out:
+ kmem_cache_free(vm_area_cachep, vma);
+ return ret;
}
static DEFINE_MUTEX(mm_all_locks_mutex);
diff --git a/mm/truncate.c b/mm/truncate.c
index ba887bf..3c2d5dd 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -390,6 +390,10 @@
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);
+
+ if (mapping->a_ops->freepage)
+ mapping->a_ops->freepage(page);
+
page_cache_release(page); /* pagecache ref */
return 1;
failed:
diff --git a/mm/vmscan.c b/mm/vmscan.c
index d31d7ce..9ca587c 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -494,9 +494,16 @@
spin_unlock_irq(&mapping->tree_lock);
swapcache_free(swap, page);
} else {
+ void (*freepage)(struct page *);
+
+ freepage = mapping->a_ops->freepage;
+
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);
+
+ if (freepage != NULL)
+ freepage(page);
}
return 1;
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c
index 799c631..f7fa67c 100644
--- a/net/atm/atm_sysfs.c
+++ b/net/atm/atm_sysfs.c
@@ -143,12 +143,13 @@
.dev_uevent = atm_uevent,
};
-int atm_register_sysfs(struct atm_dev *adev)
+int atm_register_sysfs(struct atm_dev *adev, struct device *parent)
{
struct device *cdev = &adev->class_dev;
int i, j, err;
cdev->class = &atm_class;
+ cdev->parent = parent;
dev_set_drvdata(cdev, adev);
dev_set_name(cdev, "%s%d", adev->type, adev->number);
diff --git a/net/atm/resources.c b/net/atm/resources.c
index d29e582..23f45ce 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -74,8 +74,9 @@
}
EXPORT_SYMBOL(atm_dev_lookup);
-struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
- int number, unsigned long *flags)
+struct atm_dev *atm_dev_register(const char *type, struct device *parent,
+ const struct atmdev_ops *ops, int number,
+ unsigned long *flags)
{
struct atm_dev *dev, *inuse;
@@ -115,7 +116,7 @@
goto out_fail;
}
- if (atm_register_sysfs(dev) < 0) {
+ if (atm_register_sysfs(dev, parent) < 0) {
pr_err("atm_register_sysfs failed for dev %s\n", type);
atm_proc_dev_deregister(dev);
goto out_fail;
diff --git a/net/atm/resources.h b/net/atm/resources.h
index 126fb18..521431e 100644
--- a/net/atm/resources.h
+++ b/net/atm/resources.h
@@ -42,6 +42,6 @@
#endif /* CONFIG_PROC_FS */
-int atm_register_sysfs(struct atm_dev *adev);
+int atm_register_sysfs(struct atm_dev *adev, struct device *parent);
void atm_unregister_sysfs(struct atm_dev *adev);
#endif
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index d0927d1..66b9e5c 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -882,7 +882,7 @@
int lm = 0;
if (type != SCO_LINK && type != ESCO_LINK)
- return 0;
+ return -EINVAL;
BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
@@ -908,7 +908,7 @@
BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
- return 0;
+ return -EINVAL;
if (!status) {
struct sco_conn *conn;
@@ -927,7 +927,7 @@
BT_DBG("hcon %p reason %d", hcon, reason);
if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
- return 0;
+ return -EINVAL;
sco_conn_del(hcon, bt_err(reason));
diff --git a/net/core/filter.c b/net/core/filter.c
index c1ee800..ae21a0d 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -589,23 +589,16 @@
EXPORT_SYMBOL(sk_chk_filter);
/**
- * sk_filter_rcu_release - Release a socket filter by rcu_head
+ * sk_filter_release_rcu - Release a socket filter by rcu_head
* @rcu: rcu_head that contains the sk_filter to free
*/
-static void sk_filter_rcu_release(struct rcu_head *rcu)
+void sk_filter_release_rcu(struct rcu_head *rcu)
{
struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
- sk_filter_release(fp);
+ kfree(fp);
}
-
-static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp)
-{
- unsigned int size = sk_filter_len(fp);
-
- atomic_sub(size, &sk->sk_omem_alloc);
- call_rcu_bh(&fp->rcu, sk_filter_rcu_release);
-}
+EXPORT_SYMBOL(sk_filter_release_rcu);
/**
* sk_attach_filter - attach a socket filter
@@ -649,7 +642,7 @@
rcu_assign_pointer(sk->sk_filter, fp);
if (old_fp)
- sk_filter_delayed_uncharge(sk, old_fp);
+ sk_filter_uncharge(sk, old_fp);
return 0;
}
EXPORT_SYMBOL_GPL(sk_attach_filter);
@@ -663,7 +656,7 @@
sock_owned_by_user(sk));
if (filter) {
rcu_assign_pointer(sk->sk_filter, NULL);
- sk_filter_delayed_uncharge(sk, filter);
+ sk_filter_uncharge(sk, filter);
ret = 0;
}
return ret;
diff --git a/net/core/timestamping.c b/net/core/timestamping.c
index 0ae6c22..c19bb4e 100644
--- a/net/core/timestamping.c
+++ b/net/core/timestamping.c
@@ -96,11 +96,13 @@
struct phy_device *phydev;
unsigned int type;
- skb_push(skb, ETH_HLEN);
+ if (skb_headroom(skb) < ETH_HLEN)
+ return false;
+ __skb_push(skb, ETH_HLEN);
type = classify(skb);
- skb_pull(skb, ETH_HLEN);
+ __skb_pull(skb, ETH_HLEN);
switch (type) {
case PTP_CLASS_V1_IPV4:
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 13992e1..15dcc1a 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -661,8 +661,10 @@
err = 0;
switch (cmd) {
case SIOCSIFADDR:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
+ if (!capable(CAP_NET_ADMIN)) {
+ err = -EPERM;
+ break;
+ }
edev = dev->ec_ptr;
if (edev == NULL) {
@@ -849,9 +851,13 @@
{
struct iphdr *ip = ip_hdr(skb);
unsigned char stn = ntohl(ip->saddr) & 0xff;
+ struct dst_entry *dst = skb_dst(skb);
+ struct ec_device *edev = NULL;
struct sock *sk = NULL;
struct sk_buff *newskb;
- struct ec_device *edev = skb->dev->ec_ptr;
+
+ if (dst)
+ edev = dst->dev->ec_ptr;
if (! edev)
goto bad;
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 1b48eb1..b14ec7d 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -253,6 +253,7 @@
SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP),
SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP),
SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER),
+ SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW),
SNMP_MIB_SENTINEL
};
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 43cf901..a66735f 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -347,7 +347,7 @@
* socket up. We've got bigger problems than
* non-graceful socket closings.
*/
- LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n");
+ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW);
}
tcp_update_metrics(sk);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 05b1ecf..61c2463 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -231,11 +231,10 @@
/* when initializing use the value from init_rcv_wnd
* rather than the default from above
*/
- if (init_rcv_wnd &&
- (*rcv_wnd > init_rcv_wnd * mss))
- *rcv_wnd = init_rcv_wnd * mss;
- else if (*rcv_wnd > init_cwnd * mss)
- *rcv_wnd = init_cwnd * mss;
+ if (init_rcv_wnd)
+ *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss);
+ else
+ *rcv_wnd = min(*rcv_wnd, init_cwnd * mss);
}
/* Set the clamp no higher than max representable value */
@@ -386,27 +385,30 @@
*/
static u8 tcp_cookie_size_check(u8 desired)
{
- if (desired > 0) {
+ int cookie_size;
+
+ if (desired > 0)
/* previously specified */
return desired;
- }
- if (sysctl_tcp_cookie_size <= 0) {
+
+ cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size);
+ if (cookie_size <= 0)
/* no default specified */
return 0;
- }
- if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) {
+
+ if (cookie_size <= TCP_COOKIE_MIN)
/* value too small, specify minimum */
return TCP_COOKIE_MIN;
- }
- if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) {
+
+ if (cookie_size >= TCP_COOKIE_MAX)
/* value too large, specify maximum */
return TCP_COOKIE_MAX;
- }
- if (0x1 & sysctl_tcp_cookie_size) {
+
+ if (cookie_size & 1)
/* 8-bit multiple, illegal, fix it */
- return (u8)(sysctl_tcp_cookie_size + 0x1);
- }
- return (u8)sysctl_tcp_cookie_size;
+ cookie_size++;
+
+ return (u8)cookie_size;
}
/* Write previously computed TCP options to the packet.
@@ -1513,6 +1515,7 @@
struct tcp_sock *tp = tcp_sk(sk);
const struct inet_connection_sock *icsk = inet_csk(sk);
u32 send_win, cong_win, limit, in_flight;
+ int win_divisor;
if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN)
goto send_now;
@@ -1544,13 +1547,14 @@
if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len))
goto send_now;
- if (sysctl_tcp_tso_win_divisor) {
+ win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor);
+ if (win_divisor) {
u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache);
/* If at least some fraction of a window is available,
* just use it.
*/
- chunk /= sysctl_tcp_tso_win_divisor;
+ chunk /= win_divisor;
if (limit >= chunk)
goto send_now;
} else {
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 23cc8e1..93b7a93 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4021,11 +4021,11 @@
kfree_skb(skb);
goto errout;
}
- rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+ rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC);
return;
errout:
if (err < 0)
- rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
+ rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err);
}
static inline size_t inet6_prefix_nlmsg_size(void)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 2a59610..70e891a 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1175,6 +1175,8 @@
sizeof (struct ipv6hdr);
dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr);
+ if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+ dev->mtu-=8;
if (dev->mtu < IPV6_MIN_MTU)
dev->mtu = IPV6_MIN_MTU;
@@ -1363,12 +1365,17 @@
static void ip6_tnl_dev_setup(struct net_device *dev)
{
+ struct ip6_tnl *t;
+
dev->netdev_ops = &ip6_tnl_netdev_ops;
dev->destructor = ip6_dev_free;
dev->type = ARPHRD_TUNNEL6;
dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
+ t = netdev_priv(dev);
+ if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+ dev->mtu-=8;
dev->flags |= IFF_NOARP;
dev->addr_len = sizeof(struct in6_addr);
dev->features |= NETIF_F_NETNS_LOCAL;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index d6bfaec..8c4d00c 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -606,8 +606,9 @@
return 0;
}
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+ /* no tunnel matched, let upstream know, ipsec may handle it */
rcu_read_unlock();
+ return 1;
out:
kfree_skb(skb);
return 0;
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 0bf6a59..522e219 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -674,4 +674,8 @@
MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
MODULE_DESCRIPTION("L2TP over IP");
MODULE_VERSION("1.0");
-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, SOCK_DGRAM, IPPROTO_L2TP);
+
+/* Use the value of SOCK_DGRAM (2) directory, because __stringify does't like
+ * enums
+ */
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP);
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 5826129..e35dbe5 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -317,8 +317,9 @@
goto out;
rc = -ENODEV;
rtnl_lock();
+ rcu_read_lock();
if (sk->sk_bound_dev_if) {
- llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+ llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
if (llc->dev) {
if (!addr->sllc_arphrd)
addr->sllc_arphrd = llc->dev->type;
@@ -329,13 +330,13 @@
!llc_mac_match(addr->sllc_mac,
llc->dev->dev_addr)) {
rc = -EINVAL;
- dev_put(llc->dev);
llc->dev = NULL;
}
}
} else
llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd,
addr->sllc_mac);
+ rcu_read_unlock();
rtnl_unlock();
if (!llc->dev)
goto out;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 902b03ee..54fb4a0e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2247,6 +2247,10 @@
break;
case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+ if (is_multicast_ether_addr(mgmt->da) &&
+ !is_broadcast_ether_addr(mgmt->da))
+ return RX_DROP_MONITOR;
+
/* process only for station */
if (sdata->vif.type != NL80211_IFTYPE_STATION)
return RX_DROP_MONITOR;
@@ -2741,6 +2745,7 @@
if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
return;
+ goto out;
}
}
@@ -2780,6 +2785,7 @@
return;
}
+ out:
dev_kfree_skb(skb);
}
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 96c5943..7a637b8 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1587,7 +1587,12 @@
list) {
if (!ieee80211_sdata_running(tmp_sdata))
continue;
- if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
+ if (tmp_sdata->vif.type ==
+ NL80211_IFTYPE_MONITOR ||
+ tmp_sdata->vif.type ==
+ NL80211_IFTYPE_AP_VLAN ||
+ tmp_sdata->vif.type ==
+ NL80211_IFTYPE_WDS)
continue;
if (compare_ether_addr(tmp_sdata->vif.addr,
hdr->addr2) == 0) {
@@ -1732,15 +1737,13 @@
int nh_pos, h_pos;
struct sta_info *sta = NULL;
u32 sta_flags = 0;
+ struct sk_buff *tmp_skb;
if (unlikely(skb->len < ETH_HLEN)) {
ret = NETDEV_TX_OK;
goto fail;
}
- nh_pos = skb_network_header(skb) - skb->data;
- h_pos = skb_transport_header(skb) - skb->data;
-
/* convert Ethernet header to proper 802.11 header (based on
* operation mode) */
ethertype = (skb->data[12] << 8) | skb->data[13];
@@ -1913,6 +1916,20 @@
goto fail;
}
+ /*
+ * If the skb is shared we need to obtain our own copy.
+ */
+ if (skb_shared(skb)) {
+ tmp_skb = skb;
+ skb = skb_copy(skb, GFP_ATOMIC);
+ kfree_skb(tmp_skb);
+
+ if (!skb) {
+ ret = NETDEV_TX_OK;
+ goto fail;
+ }
+ }
+
hdr.frame_control = fc;
hdr.duration_id = 0;
hdr.seq_ctrl = 0;
@@ -1931,6 +1948,9 @@
encaps_len = 0;
}
+ nh_pos = skb_network_header(skb) - skb->data;
+ h_pos = skb_transport_header(skb) - skb->data;
+
skb_pull(skb, skip_header_bytes);
nh_pos -= skip_header_bytes;
h_pos -= skip_header_bytes;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 6bd5543..0b9ee34 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2932,6 +2932,7 @@
struct sctp_association *asoc = NULL;
struct sctp_setpeerprim prim;
struct sctp_chunk *chunk;
+ struct sctp_af *af;
int err;
sp = sctp_sk(sk);
@@ -2959,6 +2960,13 @@
if (!sctp_state(asoc, ESTABLISHED))
return -ENOTCONN;
+ af = sctp_get_af_specific(prim.sspp_addr.ss_family);
+ if (!af)
+ return -EINVAL;
+
+ if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL))
+ return -EADDRNOTAVAIL;
+
if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr))
return -EADDRNOTAVAIL;
diff --git a/net/socket.c b/net/socket.c
index 3ca2fd9..088fb3f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -732,6 +732,21 @@
return ret;
}
+/**
+ * kernel_recvmsg - Receive a message from a socket (kernel space)
+ * @sock: The socket to receive the message from
+ * @msg: Received message
+ * @vec: Input s/g array for message data
+ * @num: Size of input s/g array
+ * @size: Number of bytes to read
+ * @flags: Message flags (MSG_DONTWAIT, etc...)
+ *
+ * On return the msg structure contains the scatter/gather array passed in the
+ * vec argument. The array is modified so that it consists of the unfilled
+ * portion of the original array.
+ *
+ * The returned value is the total number of bytes received, or an error.
+ */
int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
struct kvec *vec, size_t num, size_t size, int flags)
{
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index ea2ff78..3f2c555 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -212,6 +212,7 @@
spin_lock(&svc_xprt_class_lock);
list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
struct svc_xprt *newxprt;
+ unsigned short newport;
if (strcmp(xprt_name, xcl->xcl_name))
continue;
@@ -230,8 +231,9 @@
spin_lock_bh(&serv->sv_lock);
list_add(&newxprt->xpt_list, &serv->sv_permsocks);
spin_unlock_bh(&serv->sv_lock);
+ newport = svc_xprt_local_port(newxprt);
clear_bit(XPT_BUSY, &newxprt->xpt_flags);
- return svc_xprt_local_port(newxprt);
+ return newport;
}
err:
spin_unlock(&svc_xprt_class_lock);
@@ -425,8 +427,13 @@
{
BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags));
xprt->xpt_pool = NULL;
+ /* As soon as we clear busy, the xprt could be closed and
+ * 'put', so we need a reference to call svc_xprt_enqueue with:
+ */
+ svc_xprt_get(xprt);
clear_bit(XPT_BUSY, &xprt->xpt_flags);
svc_xprt_enqueue(xprt);
+ svc_xprt_put(xprt);
}
EXPORT_SYMBOL_GPL(svc_xprt_received);
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c
index 73e7b95..b25c646 100644
--- a/net/x25/x25_link.c
+++ b/net/x25/x25_link.c
@@ -394,6 +394,7 @@
list_for_each_safe(entry, tmp, &x25_neigh_list) {
nb = list_entry(entry, struct x25_neigh, node);
__x25_remove_neigh(nb);
+ dev_put(nb->dev);
}
write_unlock_bh(&x25_neigh_list_lock);
}
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index eb96ce5..220ebc0 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1268,7 +1268,7 @@
return xc;
error:
- kfree(xc);
+ xfrm_state_put(xc);
return NULL;
}
EXPORT_SYMBOL(xfrm_state_migrate);
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index cb0c23a..4a66347 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -189,6 +189,9 @@
a->channels = GRAB_BITS(buf, 0, 0, 3);
a->channels++;
+ a->sample_bits = 0;
+ a->max_bitrate = 0;
+
a->format = GRAB_BITS(buf, 0, 3, 4);
switch (a->format) {
case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
@@ -198,7 +201,6 @@
case AUDIO_CODING_TYPE_LPCM:
val = GRAB_BITS(buf, 2, 0, 3);
- a->sample_bits = 0;
for (i = 0; i < 3; i++)
if (val & (1 << i))
a->sample_bits |= cea_sample_sizes[i + 1];
@@ -598,24 +600,19 @@
{
int i;
- pcm->rates = 0;
- pcm->formats = 0;
- pcm->maxbps = 0;
- pcm->channels_min = -1;
- pcm->channels_max = 0;
+ /* assume basic audio support (the basic audio flag is not in ELD;
+ * however, all audio capable sinks are required to support basic
+ * audio) */
+ pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
+ pcm->formats = SNDRV_PCM_FMTBIT_S16_LE;
+ pcm->maxbps = 16;
+ pcm->channels_max = 2;
for (i = 0; i < eld->sad_count; i++) {
struct cea_sad *a = &eld->sad[i];
pcm->rates |= a->rates;
- if (a->channels < pcm->channels_min)
- pcm->channels_min = a->channels;
if (a->channels > pcm->channels_max)
pcm->channels_max = a->channels;
if (a->format == AUDIO_CODING_TYPE_LPCM) {
- if (a->sample_bits & AC_SUPPCM_BITS_16) {
- pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE;
- if (pcm->maxbps < 16)
- pcm->maxbps = 16;
- }
if (a->sample_bits & AC_SUPPCM_BITS_20) {
pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE;
if (pcm->maxbps < 20)
@@ -635,7 +632,6 @@
/* restrict the parameters by the values the codec provides */
pcm->rates &= codec_pars->rates;
pcm->formats &= codec_pars->formats;
- pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min);
pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max);
pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps);
}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 21aa9b0..b030c8e 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2296,6 +2296,7 @@
*/
static struct snd_pci_quirk position_fix_list[] __devinitdata = {
SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 846d1ea..76bd58a 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -2116,8 +2116,8 @@
struct conexant_spec *spec = codec->spec;
unsigned int pinctl;
- snd_printdd("CXT5066: update speaker, hp_present=%d\n",
- spec->hp_present);
+ snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
+ spec->hp_present, spec->cur_eapd);
/* Port A (HP) */
pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
@@ -2125,11 +2125,20 @@
pinctl);
/* Port D (HP/LO) */
- pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
- ? spec->port_d_mode : 0;
- /* Mute if Port A is connected on Thinkpad */
- if (spec->thinkpad && (spec->hp_present & 1))
- pinctl = 0;
+ if (spec->dell_automute) {
+ /* DELL AIO Port Rule: PortA> PortD> IntSpk */
+ pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
+ ? PIN_OUT : 0;
+ } else if (spec->thinkpad) {
+ if (spec->cur_eapd)
+ pinctl = spec->port_d_mode;
+ /* Mute dock line-out if Port A (laptop HP) is present */
+ if (spec->hp_present& 1)
+ pinctl = 0;
+ } else {
+ pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
+ ? spec->port_d_mode : 0;
+ }
snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl);
@@ -2137,14 +2146,6 @@
pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl);
-
- if (spec->dell_automute) {
- /* DELL AIO Port Rule: PortA > PortD > IntSpk */
- pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
- ? PIN_OUT : 0;
- snd_hda_codec_write(codec, 0x1c, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
- }
}
/* turn on/off EAPD (+ mute HP) as a master switch */
@@ -3095,8 +3096,7 @@
static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
- SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
- CXT5066_DELL_LAPTOP),
+ SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
@@ -3109,6 +3109,7 @@
SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
+ SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD),
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index d3e49aa..31df774 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -834,7 +834,6 @@
return -ENODEV;
} else {
/* fallback to the codec default */
- hinfo->channels_min = codec_pars->channels_min;
hinfo->channels_max = codec_pars->channels_max;
hinfo->rates = codec_pars->rates;
hinfo->formats = codec_pars->formats;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 8fddc9d..2d7d7de 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4595,6 +4595,7 @@
SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
+ SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index a2e0ed5..879dff2 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -491,16 +491,16 @@
paifa |= 0x8;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
- paifa |= 0x10;
+ paifa |= 0x0;
paifb |= WM8580_AIF_LENGTH_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
- paifa |= 0x10;
+ paifa |= 0x0;
paifb |= WM8580_AIF_LENGTH_24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
- paifa |= 0x10;
- paifb |= WM8580_AIF_LENGTH_24;
+ paifa |= 0x0;
+ paifb |= WM8580_AIF_LENGTH_32;
break;
default:
return -EINVAL;
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index e809274..1304ca9 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3339,7 +3339,7 @@
int mask;
int active;
- mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
+ mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
active &= ~mask;
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 19ca782..0e24092 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -293,7 +293,7 @@
SOC_DOUBLE_R("Speaker ZC Switch",
WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
7, 1, 0),
-SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0,
+SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0,
spkboost_tlv),
SOC_ENUM("Speaker Reference", speaker_ref),
SOC_ENUM("Speaker Mode", speaker_mode),
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 441285a..85b7d54 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1619,12 +1619,14 @@
#ifdef CONFIG_SND_SOC_AC97_BUS
/* register any AC97 codecs */
for (i = 0; i < card->num_rtd; i++) {
- ret = soc_register_ac97_dai_link(&card->rtd[i]);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
- goto probe_dai_err;
- }
+ ret = soc_register_ac97_dai_link(&card->rtd[i]);
+ if (ret < 0) {
+ printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
+ while (--i >= 0)
+ soc_unregister_ac97_dai_link(&card->rtd[i]);
+ goto probe_dai_err;
}
+ }
#endif
card->instantiated = 1;
@@ -3072,7 +3074,9 @@
pr_debug("Registered DAI '%s'\n", dai->name);
}
+ mutex_lock(&client_mutex);
snd_soc_instantiate_cards();
+ mutex_unlock(&client_mutex);
return 0;
err: