From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id C06CF1381F3 for ; Wed, 7 Nov 2012 22:45:35 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 40C2DE05B1; Wed, 7 Nov 2012 22:45:27 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id F131FE05B1 for ; Wed, 7 Nov 2012 22:45:25 +0000 (UTC) Received: from hornbill.gentoo.org (hornbill.gentoo.org [94.100.119.163]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id C81C033D8A6 for ; Wed, 7 Nov 2012 22:45:24 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by hornbill.gentoo.org (Postfix) with ESMTP id 49AFBE5442 for ; Wed, 7 Nov 2012 22:45:23 +0000 (UTC) From: "Anthony G. Basile" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Anthony G. Basile" Message-ID: <1352328310.33fba0ea3a67831c3efb7e26d24a2389bba7ca89.blueness@gentoo> Subject: [gentoo-commits] proj/hardened-patchset:master commit in: 3.6.6/ X-VCS-Repository: proj/hardened-patchset X-VCS-Files: 3.6.6/0000_README 3.6.6/1004_linux-3.6.5.patch X-VCS-Directories: 3.6.6/ X-VCS-Committer: blueness X-VCS-Committer-Name: Anthony G. Basile X-VCS-Revision: 33fba0ea3a67831c3efb7e26d24a2389bba7ca89 X-VCS-Branch: master Date: Wed, 7 Nov 2012 22:45:23 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 4d9f306e-bbf1-44cb-a4df-1ece26accc92 X-Archives-Hash: f186d11eea2ba6e39065362ed4868e36 commit: 33fba0ea3a67831c3efb7e26d24a2389bba7ca89 Author: Anthony G. Basile gentoo org> AuthorDate: Wed Nov 7 22:45:10 2012 +0000 Commit: Anthony G. Basile gentoo org> CommitDate: Wed Nov 7 22:45:10 2012 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-patchset.git;a=commit;h=33fba0ea patch 3.6.5 and 3.6.6 are in genpatches --- 3.6.6/0000_README | 4 - 3.6.6/1004_linux-3.6.5.patch | 4649 ------------------------------------------ 2 files changed, 0 insertions(+), 4653 deletions(-) diff --git a/3.6.6/0000_README b/3.6.6/0000_README index 000533c..3c4b928 100644 --- a/3.6.6/0000_README +++ b/3.6.6/0000_README @@ -2,10 +2,6 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 1004_linux-3.6.5.patch -From: http://www.kernel.org -Desc: Linux 3.6.5 - Patch: 4420_grsecurity-2.9.1-3.6.6-201211051957.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.6.6/1004_linux-3.6.5.patch b/3.6.6/1004_linux-3.6.5.patch deleted file mode 100644 index 738b926..0000000 --- a/3.6.6/1004_linux-3.6.5.patch +++ /dev/null @@ -1,4649 +0,0 @@ -diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt -index ecc81e3..d187e9f 100644 ---- a/Documentation/devicetree/bindings/arm/atmel-at91.txt -+++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt -@@ -8,7 +8,7 @@ PIT Timer required properties: - shared across all System Controller members. - - TC/TCLIB Timer required properties: --- compatible: Should be "atmel,-pit". -+- compatible: Should be "atmel,-tcb". - can be "at91rm9200" or "at91sam9x5" - - reg: Should contain registers location and length - - interrupts: Should contain all interrupts for the TC block -diff --git a/Makefile b/Makefile -index dcf132a..6e4a00d 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 3 - PATCHLEVEL = 6 --SUBLEVEL = 4 -+SUBLEVEL = 5 - EXTRAVERSION = - NAME = Terrified Chipmunk - -diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c -index ebd8ad2..0181f7e 100644 ---- a/arch/arm/kernel/smp.c -+++ b/arch/arm/kernel/smp.c -@@ -222,18 +222,24 @@ static void percpu_timer_setup(void); - asmlinkage void __cpuinit secondary_start_kernel(void) - { - struct mm_struct *mm = &init_mm; -- unsigned int cpu = smp_processor_id(); -+ unsigned int cpu; -+ -+ /* -+ * The identity mapping is uncached (strongly ordered), so -+ * switch away from it before attempting any exclusive accesses. -+ */ -+ cpu_switch_mm(mm->pgd, mm); -+ enter_lazy_tlb(mm, current); -+ local_flush_tlb_all(); - - /* - * All kernel threads share the same mm context; grab a - * reference and switch to it. - */ -+ cpu = smp_processor_id(); - atomic_inc(&mm->mm_count); - current->active_mm = mm; - cpumask_set_cpu(cpu, mm_cpumask(mm)); -- cpu_switch_mm(mm->pgd, mm); -- enter_lazy_tlb(mm, current); -- local_flush_tlb_all(); - - printk("CPU%u: Booted secondary processor\n", cpu); - -diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c -index 01fb732..d5a4913 100644 ---- a/arch/arm/mach-at91/at91rm9200_devices.c -+++ b/arch/arm/mach-at91/at91rm9200_devices.c -@@ -463,7 +463,7 @@ static struct i2c_gpio_platform_data pdata = { - - static struct platform_device at91rm9200_twi_device = { - .name = "i2c-gpio", -- .id = -1, -+ .id = 0, - .dev.platform_data = &pdata, - }; - -diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c -index bce572a..18ca240 100644 ---- a/arch/arm/mach-at91/at91sam9260_devices.c -+++ b/arch/arm/mach-at91/at91sam9260_devices.c -@@ -471,7 +471,7 @@ static struct i2c_gpio_platform_data pdata = { - - static struct platform_device at91sam9260_twi_device = { - .name = "i2c-gpio", -- .id = -1, -+ .id = 0, - .dev.platform_data = &pdata, - }; - -diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c -index bc2590d..2495de8 100644 ---- a/arch/arm/mach-at91/at91sam9261_devices.c -+++ b/arch/arm/mach-at91/at91sam9261_devices.c -@@ -285,7 +285,7 @@ static struct i2c_gpio_platform_data pdata = { - - static struct platform_device at91sam9261_twi_device = { - .name = "i2c-gpio", -- .id = -1, -+ .id = 0, - .dev.platform_data = &pdata, - }; - -diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c -index 9b6ca73..9877963 100644 ---- a/arch/arm/mach-at91/at91sam9263_devices.c -+++ b/arch/arm/mach-at91/at91sam9263_devices.c -@@ -542,7 +542,7 @@ static struct i2c_gpio_platform_data pdata = { - - static struct platform_device at91sam9263_twi_device = { - .name = "i2c-gpio", -- .id = -1, -+ .id = 0, - .dev.platform_data = &pdata, - }; - -diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c -index b3d365d..c82a427 100644 ---- a/arch/arm/mach-at91/at91sam9rl_devices.c -+++ b/arch/arm/mach-at91/at91sam9rl_devices.c -@@ -314,7 +314,7 @@ static struct i2c_gpio_platform_data pdata = { - - static struct platform_device at91sam9rl_twi_device = { - .name = "i2c-gpio", -- .id = -1, -+ .id = 0, - .dev.platform_data = &pdata, - }; - -diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c -index 18103c5d..997d359 100644 ---- a/arch/arm/mach-at91/board-neocore926.c -+++ b/arch/arm/mach-at91/board-neocore926.c -@@ -129,7 +129,7 @@ static struct spi_board_info neocore926_spi_devices[] = { - .max_speed_hz = 125000 * 16, - .bus_num = 0, - .platform_data = &ads_info, -- .irq = AT91SAM9263_ID_IRQ1, -+ .irq = NR_IRQS_LEGACY + AT91SAM9263_ID_IRQ1, - }, - #endif - }; -diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c -index 2269be5..17659be 100644 ---- a/arch/arm/mach-at91/board-sam9261ek.c -+++ b/arch/arm/mach-at91/board-sam9261ek.c -@@ -309,7 +309,7 @@ static struct spi_board_info ek_spi_devices[] = { - .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ - .bus_num = 0, - .platform_data = &ads_info, -- .irq = AT91SAM9261_ID_IRQ0, -+ .irq = NR_IRQS_LEGACY + AT91SAM9261_ID_IRQ0, - .controller_data = (void *) AT91_PIN_PA28, /* CS pin */ - }, - #endif -diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c -index 82adf58..9e7153b 100644 ---- a/arch/arm/mach-at91/board-sam9263ek.c -+++ b/arch/arm/mach-at91/board-sam9263ek.c -@@ -132,7 +132,7 @@ static struct spi_board_info ek_spi_devices[] = { - .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ - .bus_num = 0, - .platform_data = &ads_info, -- .irq = AT91SAM9263_ID_IRQ1, -+ .irq = NR_IRQS_LEGACY + AT91SAM9263_ID_IRQ1, - }, - #endif - }; -diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h -index f496506..b62f560e 100644 ---- a/arch/arm/mach-at91/generic.h -+++ b/arch/arm/mach-at91/generic.h -@@ -26,7 +26,8 @@ extern void __init at91_dt_initialize(void); - extern void __init at91_init_irq_default(void); - extern void __init at91_init_interrupts(unsigned int priority[]); - extern void __init at91x40_init_interrupts(unsigned int priority[]); --extern void __init at91_aic_init(unsigned int priority[]); -+extern void __init at91_aic_init(unsigned int priority[], -+ unsigned int ext_irq_mask); - extern int __init at91_aic_of_init(struct device_node *node, - struct device_node *parent); - extern int __init at91_aic5_of_init(struct device_node *node, -diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c -index 1e02c0e..febc2ee 100644 ---- a/arch/arm/mach-at91/irq.c -+++ b/arch/arm/mach-at91/irq.c -@@ -502,14 +502,19 @@ int __init at91_aic5_of_init(struct device_node *node, - /* - * Initialize the AIC interrupt controller. - */ --void __init at91_aic_init(unsigned int *priority) -+void __init at91_aic_init(unsigned int *priority, unsigned int ext_irq_mask) - { - unsigned int i; - int irq_base; - -- if (at91_aic_pm_init()) -+ at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs) -+ * sizeof(*at91_extern_irq), GFP_KERNEL); -+ -+ if (at91_aic_pm_init() || at91_extern_irq == NULL) - panic("Unable to allocate bit maps\n"); - -+ *at91_extern_irq = ext_irq_mask; -+ - at91_aic_base = ioremap(AT91_AIC, 512); - if (!at91_aic_base) - panic("Unable to ioremap AIC registers\n"); -diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c -index 944bffb..bd0e88c 100644 ---- a/arch/arm/mach-at91/setup.c -+++ b/arch/arm/mach-at91/setup.c -@@ -47,7 +47,7 @@ void __init at91_init_irq_default(void) - void __init at91_init_interrupts(unsigned int *priority) - { - /* Initialize the AIC interrupt controller */ -- at91_aic_init(priority); -+ at91_aic_init(priority, at91_extern_irq); - - /* Enable GPIO interrupts */ - at91_gpio_irq_setup(); -@@ -151,7 +151,7 @@ static void __init soc_detect(u32 dbgu_base) - } - - /* at91sam9g10 */ -- if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { -+ if ((socid & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { - at91_soc_initdata.type = AT91_SOC_SAM9G10; - at91_boot_soc = at91sam9261_soc; - } -diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c -index 4eb39cd..3e02ae6 100644 ---- a/arch/arm/mach-exynos/common.c -+++ b/arch/arm/mach-exynos/common.c -@@ -47,6 +47,7 @@ - #include - #include - #include -+#include - #include - - #include "common.h" -@@ -346,6 +347,8 @@ static void __init exynos4_map_io(void) - - s5p_fb_setname(0, "exynos4-fb"); - s5p_hdmi_setname("exynos4-hdmi"); -+ -+ s3c64xx_spi_setname("exynos4210-spi"); - } - - static void __init exynos5_map_io(void) -@@ -366,6 +369,8 @@ static void __init exynos5_map_io(void) - s3c_i2c0_setname("s3c2440-i2c"); - s3c_i2c1_setname("s3c2440-i2c"); - s3c_i2c2_setname("s3c2440-i2c"); -+ -+ s3c64xx_spi_setname("exynos4210-spi"); - } - - static void __init exynos4_init_clocks(int xtal) -diff --git a/arch/arm/mach-s3c24xx/s3c2416.c b/arch/arm/mach-s3c24xx/s3c2416.c -index ed5a95ec..77ee0b7 100644 ---- a/arch/arm/mach-s3c24xx/s3c2416.c -+++ b/arch/arm/mach-s3c24xx/s3c2416.c -@@ -61,6 +61,7 @@ - #include - #include - #include -+#include - - static struct map_desc s3c2416_iodesc[] __initdata = { - IODESC_ENT(WATCHDOG), -@@ -132,6 +133,7 @@ void __init s3c2416_map_io(void) - /* initialize device information early */ - s3c2416_default_sdhci0(); - s3c2416_default_sdhci1(); -+ s3c64xx_spi_setname("s3c2443-spi"); - - iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc)); - } -diff --git a/arch/arm/mach-s3c24xx/s3c2443.c b/arch/arm/mach-s3c24xx/s3c2443.c -index ab648ad..165b6a6 100644 ---- a/arch/arm/mach-s3c24xx/s3c2443.c -+++ b/arch/arm/mach-s3c24xx/s3c2443.c -@@ -43,6 +43,7 @@ - #include - #include - #include -+#include - - static struct map_desc s3c2443_iodesc[] __initdata = { - IODESC_ENT(WATCHDOG), -@@ -100,6 +101,9 @@ void __init s3c2443_map_io(void) - s3c24xx_gpiocfg_default.set_pull = s3c2443_gpio_setpull; - s3c24xx_gpiocfg_default.get_pull = s3c2443_gpio_getpull; - -+ /* initialize device information early */ -+ s3c64xx_spi_setname("s3c2443-spi"); -+ - iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc)); - } - -diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c -index 6e6a0a9..111e404 100644 ---- a/arch/arm/mach-s5p64x0/common.c -+++ b/arch/arm/mach-s5p64x0/common.c -@@ -44,6 +44,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -179,6 +180,7 @@ void __init s5p6440_map_io(void) - /* initialize any device information early */ - s3c_adc_setname("s3c64xx-adc"); - s3c_fb_setname("s5p64x0-fb"); -+ s3c64xx_spi_setname("s5p64x0-spi"); - - s5p64x0_default_sdhci0(); - s5p64x0_default_sdhci1(); -@@ -193,6 +195,7 @@ void __init s5p6450_map_io(void) - /* initialize any device information early */ - s3c_adc_setname("s3c64xx-adc"); - s3c_fb_setname("s5p64x0-fb"); -+ s3c64xx_spi_setname("s5p64x0-spi"); - - s5p64x0_default_sdhci0(); - s5p64x0_default_sdhci1(); -diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c -index 6219086..cc6e561 100644 ---- a/arch/arm/mach-s5pc100/common.c -+++ b/arch/arm/mach-s5pc100/common.c -@@ -45,6 +45,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -165,6 +166,8 @@ void __init s5pc100_map_io(void) - s3c_onenand_setname("s5pc100-onenand"); - s3c_fb_setname("s5pc100-fb"); - s3c_cfcon_setname("s5pc100-pata"); -+ -+ s3c64xx_spi_setname("s5pc100-spi"); - } - - void __init s5pc100_init_clocks(int xtal) -diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c -index 4c9e902..a0c50ef 100644 ---- a/arch/arm/mach-s5pv210/common.c -+++ b/arch/arm/mach-s5pv210/common.c -@@ -43,6 +43,7 @@ - #include - #include - #include -+#include - #include - - #include "common.h" -@@ -196,6 +197,8 @@ void __init s5pv210_map_io(void) - - /* setup TV devices */ - s5p_hdmi_setname("s5pv210-hdmi"); -+ -+ s3c64xx_spi_setname("s5pv210-spi"); - } - - void __init s5pv210_init_clocks(int xtal) -diff --git a/arch/arm/plat-samsung/include/plat/spi-core.h b/arch/arm/plat-samsung/include/plat/spi-core.h -new file mode 100644 -index 0000000..0b9428a ---- /dev/null -+++ b/arch/arm/plat-samsung/include/plat/spi-core.h -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2012 Heiko Stuebner -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#ifndef __PLAT_S3C_SPI_CORE_H -+#define __PLAT_S3C_SPI_CORE_H -+ -+/* These functions are only for use with the core support code, such as -+ * the cpu specific initialisation code -+ */ -+ -+/* re-define device name depending on support. */ -+static inline void s3c64xx_spi_setname(char *name) -+{ -+#ifdef CONFIG_S3C64XX_DEV_SPI0 -+ s3c64xx_device_spi0.name = name; -+#endif -+#ifdef CONFIG_S3C64XX_DEV_SPI1 -+ s3c64xx_device_spi1.name = name; -+#endif -+#ifdef CONFIG_S3C64XX_DEV_SPI2 -+ s3c64xx_device_spi2.name = name; -+#endif -+} -+ -+#endif /* __PLAT_S3C_SPI_CORE_H */ -diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h -index c9dcc18..029189d 100644 ---- a/arch/x86/include/asm/efi.h -+++ b/arch/x86/include/asm/efi.h -@@ -98,6 +98,7 @@ extern void efi_set_executable(efi_memory_desc_t *md, bool executable); - extern int efi_memblock_x86_reserve_range(void); - extern void efi_call_phys_prelog(void); - extern void efi_call_phys_epilog(void); -+extern void efi_unmap_memmap(void); - - #ifndef CONFIG_EFI - /* -diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c -index ed858e9..df06ade 100644 ---- a/arch/x86/kernel/e820.c -+++ b/arch/x86/kernel/e820.c -@@ -1077,6 +1077,9 @@ void __init memblock_x86_fill(void) - memblock_add(ei->addr, ei->size); - } - -+ /* throw away partial pages */ -+ memblock_trim_memory(PAGE_SIZE); -+ - memblock_dump_all(); - } - -diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index 198e774..5cee802 100644 ---- a/arch/x86/kernel/setup.c -+++ b/arch/x86/kernel/setup.c -@@ -920,18 +920,19 @@ void __init setup_arch(char **cmdline_p) - #ifdef CONFIG_X86_64 - if (max_pfn > max_low_pfn) { - int i; -- for (i = 0; i < e820.nr_map; i++) { -- struct e820entry *ei = &e820.map[i]; -+ unsigned long start, end; -+ unsigned long start_pfn, end_pfn; - -- if (ei->addr + ei->size <= 1UL << 32) -- continue; -+ for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, -+ NULL) { - -- if (ei->type == E820_RESERVED) -+ end = PFN_PHYS(end_pfn); -+ if (end <= (1UL<<32)) - continue; - -+ start = PFN_PHYS(start_pfn); - max_pfn_mapped = init_memory_mapping( -- ei->addr < 1UL << 32 ? 1UL << 32 : ei->addr, -- ei->addr + ei->size); -+ max((1UL<<32), start), end); - } - - /* can we preseve max_low_pfn ?*/ -@@ -1047,6 +1048,18 @@ void __init setup_arch(char **cmdline_p) - mcheck_init(); - - arch_init_ideal_nops(); -+ -+#ifdef CONFIG_EFI -+ /* Once setup is done above, disable efi_enabled on mismatched -+ * firmware/kernel archtectures since there is no support for -+ * runtime services. -+ */ -+ if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) { -+ pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); -+ efi_unmap_memmap(); -+ efi_enabled = 0; -+ } -+#endif - } - - #ifdef CONFIG_X86_32 -diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c -index ab1f6a9..d7aea41 100644 ---- a/arch/x86/mm/init.c -+++ b/arch/x86/mm/init.c -@@ -35,40 +35,44 @@ struct map_range { - unsigned page_size_mask; - }; - --static void __init find_early_table_space(struct map_range *mr, unsigned long end, -- int use_pse, int use_gbpages) -+/* -+ * First calculate space needed for kernel direct mapping page tables to cover -+ * mr[0].start to mr[nr_range - 1].end, while accounting for possible 2M and 1GB -+ * pages. Then find enough contiguous space for those page tables. -+ */ -+static void __init find_early_table_space(struct map_range *mr, int nr_range) - { -- unsigned long puds, pmds, ptes, tables, start = 0, good_end = end; -+ int i; -+ unsigned long puds = 0, pmds = 0, ptes = 0, tables; -+ unsigned long start = 0, good_end; - phys_addr_t base; - -- puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; -- tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); -- -- if (use_gbpages) { -- unsigned long extra; -- -- extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT); -- pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT; -- } else -- pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; -+ for (i = 0; i < nr_range; i++) { -+ unsigned long range, extra; - -- tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); -+ range = mr[i].end - mr[i].start; -+ puds += (range + PUD_SIZE - 1) >> PUD_SHIFT; - -- if (use_pse) { -- unsigned long extra; -+ if (mr[i].page_size_mask & (1 << PG_LEVEL_1G)) { -+ extra = range - ((range >> PUD_SHIFT) << PUD_SHIFT); -+ pmds += (extra + PMD_SIZE - 1) >> PMD_SHIFT; -+ } else { -+ pmds += (range + PMD_SIZE - 1) >> PMD_SHIFT; -+ } - -- extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT); -+ if (mr[i].page_size_mask & (1 << PG_LEVEL_2M)) { -+ extra = range - ((range >> PMD_SHIFT) << PMD_SHIFT); - #ifdef CONFIG_X86_32 -- extra += PMD_SIZE; -+ extra += PMD_SIZE; - #endif -- /* The first 2/4M doesn't use large pages. */ -- if (mr->start < PMD_SIZE) -- extra += mr->end - mr->start; -- -- ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; -- } else -- ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ ptes += (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ } else { -+ ptes += (range + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ } -+ } - -+ tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); -+ tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); - tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE); - - #ifdef CONFIG_X86_32 -@@ -86,7 +90,7 @@ static void __init find_early_table_space(struct map_range *mr, unsigned long en - pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT); - - printk(KERN_DEBUG "kernel direct mapping tables up to %#lx @ [mem %#010lx-%#010lx]\n", -- end - 1, pgt_buf_start << PAGE_SHIFT, -+ mr[nr_range - 1].end - 1, pgt_buf_start << PAGE_SHIFT, - (pgt_buf_top << PAGE_SHIFT) - 1); - } - -@@ -267,7 +271,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, - * nodes are discovered. - */ - if (!after_bootmem) -- find_early_table_space(&mr[0], end, use_pse, use_gbpages); -+ find_early_table_space(mr, nr_range); - - for (i = 0; i < nr_range; i++) - ret = kernel_physical_mapping_init(mr[i].start, mr[i].end, -diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c -index 2b6b4a3..3baff25 100644 ---- a/arch/x86/mm/init_64.c -+++ b/arch/x86/mm/init_64.c -@@ -386,7 +386,8 @@ phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end, - * these mappings are more intelligent. - */ - if (pte_val(*pte)) { -- pages++; -+ if (!after_bootmem) -+ pages++; - continue; - } - -@@ -451,6 +452,8 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, - * attributes. - */ - if (page_size_mask & (1 << PG_LEVEL_2M)) { -+ if (!after_bootmem) -+ pages++; - last_map_addr = next; - continue; - } -@@ -526,6 +529,8 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end, - * attributes. - */ - if (page_size_mask & (1 << PG_LEVEL_1G)) { -+ if (!after_bootmem) -+ pages++; - last_map_addr = next; - continue; - } -diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c -index f55a4ce..72d8899 100644 ---- a/arch/x86/platform/efi/efi.c -+++ b/arch/x86/platform/efi/efi.c -@@ -69,11 +69,15 @@ EXPORT_SYMBOL(efi); - struct efi_memory_map memmap; - - bool efi_64bit; --static bool efi_native; - - static struct efi efi_phys __initdata; - static efi_system_table_t efi_systab __initdata; - -+static inline bool efi_is_native(void) -+{ -+ return IS_ENABLED(CONFIG_X86_64) == efi_64bit; -+} -+ - static int __init setup_noefi(char *arg) - { - efi_enabled = 0; -@@ -419,10 +423,21 @@ void __init efi_reserve_boot_services(void) - } - } - --static void __init efi_free_boot_services(void) -+void __init efi_unmap_memmap(void) -+{ -+ if (memmap.map) { -+ early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); -+ memmap.map = NULL; -+ } -+} -+ -+void __init efi_free_boot_services(void) - { - void *p; - -+ if (!efi_is_native()) -+ return; -+ - for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { - efi_memory_desc_t *md = p; - unsigned long long start = md->phys_addr; -@@ -438,6 +453,8 @@ static void __init efi_free_boot_services(void) - - free_bootmem_late(start, size); - } -+ -+ efi_unmap_memmap(); - } - - static int __init efi_systab_init(void *phys) -@@ -670,12 +687,10 @@ void __init efi_init(void) - return; - } - efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab; -- efi_native = !efi_64bit; - #else - efi_phys.systab = (efi_system_table_t *) - (boot_params.efi_info.efi_systab | - ((__u64)boot_params.efi_info.efi_systab_hi<<32)); -- efi_native = efi_64bit; - #endif - - if (efi_systab_init(efi_phys.systab)) { -@@ -709,7 +724,7 @@ void __init efi_init(void) - * that doesn't match the kernel 32/64-bit mode. - */ - -- if (!efi_native) -+ if (!efi_is_native()) - pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); - else if (efi_runtime_init()) { - efi_enabled = 0; -@@ -721,7 +736,7 @@ void __init efi_init(void) - return; - } - #ifdef CONFIG_X86_32 -- if (efi_native) { -+ if (efi_is_native()) { - x86_platform.get_wallclock = efi_get_time; - x86_platform.set_wallclock = efi_set_rtc_mmss; - } -@@ -787,8 +802,10 @@ void __init efi_enter_virtual_mode(void) - * non-native EFI - */ - -- if (!efi_native) -- goto out; -+ if (!efi_is_native()) { -+ efi_unmap_memmap(); -+ return; -+ } - - /* Merge contiguous regions of the same type and attribute */ - for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { -@@ -878,13 +895,6 @@ void __init efi_enter_virtual_mode(void) - } - - /* -- * Thankfully, it does seem that no runtime services other than -- * SetVirtualAddressMap() will touch boot services code, so we can -- * get rid of it all at this point -- */ -- efi_free_boot_services(); -- -- /* - * Now that EFI is in virtual mode, update the function - * pointers in the runtime service table to the new virtual addresses. - * -@@ -907,9 +917,6 @@ void __init efi_enter_virtual_mode(void) - if (__supported_pte_mask & _PAGE_NX) - runtime_code_page_mkexec(); - --out: -- early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); -- memmap.map = NULL; - kfree(new_memmap); - } - -diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c -index 758af9c..0059e26 100644 ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -141,9 +141,10 @@ static int bcma_register_cores(struct bcma_bus *bus) - - static void bcma_unregister_cores(struct bcma_bus *bus) - { -- struct bcma_device *core; -+ struct bcma_device *core, *tmp; - -- list_for_each_entry(core, &bus->cores, list) { -+ list_for_each_entry_safe(core, tmp, &bus->cores, list) { -+ list_del(&core->list); - if (core->dev_registered) - device_unregister(&core->dev); - } -diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c -index 1a40935..c671369 100644 ---- a/drivers/cpufreq/powernow-k8.c -+++ b/drivers/cpufreq/powernow-k8.c -@@ -1223,14 +1223,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, - struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, - .relation = relation }; - -- /* -- * Must run on @pol->cpu. cpufreq core is responsible for ensuring -- * that we're bound to the current CPU and pol->cpu stays online. -- */ -- if (smp_processor_id() == pol->cpu) -- return powernowk8_target_fn(&pta); -- else -- return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); -+ return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); - } - - /* Driver entry point to verify the policy and range of frequencies */ -diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c -index 5084975..8aa9113 100644 ---- a/drivers/dma/imx-dma.c -+++ b/drivers/dma/imx-dma.c -@@ -474,8 +474,10 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) - slot = i; - break; - } -- if (slot < 0) -+ if (slot < 0) { -+ spin_unlock_irqrestore(&imxdma->lock, flags); - return -EBUSY; -+ } - - imxdma->slots_2d[slot].xsr = d->x; - imxdma->slots_2d[slot].ysr = d->y; -diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c -index 434ad31..c439489 100644 ---- a/drivers/dma/sirf-dma.c -+++ b/drivers/dma/sirf-dma.c -@@ -109,7 +109,7 @@ static void sirfsoc_dma_execute(struct sirfsoc_dma_chan *schan) - sdesc = list_first_entry(&schan->queued, struct sirfsoc_dma_desc, - node); - /* Move the first queued descriptor to active list */ -- list_move_tail(&schan->queued, &schan->active); -+ list_move_tail(&sdesc->node, &schan->active); - - /* Start the DMA transfer */ - writel_relaxed(sdesc->width, sdma->base + SIRFSOC_DMA_WIDTH_0 + -@@ -428,7 +428,7 @@ static struct dma_async_tx_descriptor *sirfsoc_dma_prep_interleaved( - unsigned long iflags; - int ret; - -- if ((xt->dir != DMA_MEM_TO_DEV) || (xt->dir != DMA_DEV_TO_MEM)) { -+ if ((xt->dir != DMA_MEM_TO_DEV) && (xt->dir != DMA_DEV_TO_MEM)) { - ret = -EINVAL; - goto err_dir; - } -diff --git a/drivers/extcon/extcon_class.c b/drivers/extcon/extcon_class.c -index f6419f9..7dcfb7c 100644 ---- a/drivers/extcon/extcon_class.c -+++ b/drivers/extcon/extcon_class.c -@@ -575,6 +575,10 @@ static void extcon_cleanup(struct extcon_dev *edev, bool skip) - kfree(edev->cables); - } - -+#if defined(CONFIG_ANDROID) -+ if (switch_class) -+ class_compat_remove_link(switch_class, edev->dev, NULL); -+#endif - device_unregister(edev->dev); - put_device(edev->dev); - } -@@ -821,6 +825,9 @@ module_init(extcon_class_init); - - static void __exit extcon_class_exit(void) - { -+#if defined(CONFIG_ANDROID) -+ class_compat_unregister(switch_class); -+#endif - class_destroy(extcon_class); - } - module_exit(extcon_class_exit); -diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c -index d883b20..e932810 100644 ---- a/drivers/gpu/drm/radeon/evergreen_cs.c -+++ b/drivers/gpu/drm/radeon/evergreen_cs.c -@@ -2829,6 +2829,7 @@ static bool evergreen_vm_reg_valid(u32 reg) - case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS: - return true; - default: -+ DRM_ERROR("Invalid register 0x%x in CS\n", reg); - return false; - } - } -diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c -index 4065374..f4c3d28 100644 ---- a/drivers/hv/channel.c -+++ b/drivers/hv/channel.c -@@ -146,14 +146,14 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, - - if (ret != 0) { - err = ret; -- goto errorout; -+ goto error0; - } - - ret = hv_ringbuffer_init( - &newchannel->inbound, in, recv_ringbuffer_size); - if (ret != 0) { - err = ret; -- goto errorout; -+ goto error0; - } - - -@@ -168,7 +168,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, - - if (ret != 0) { - err = ret; -- goto errorout; -+ goto error0; - } - - /* Create and init the channel open message */ -@@ -177,7 +177,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, - GFP_KERNEL); - if (!open_info) { - err = -ENOMEM; -- goto errorout; -+ goto error0; - } - - init_completion(&open_info->waitevent); -@@ -193,7 +193,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, - - if (userdatalen > MAX_USER_DEFINED_BYTES) { - err = -EINVAL; -- goto errorout; -+ goto error0; - } - - if (userdatalen) -@@ -208,19 +208,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, - sizeof(struct vmbus_channel_open_channel)); - - if (ret != 0) -- goto cleanup; -+ goto error1; - - t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ); - if (t == 0) { - err = -ETIMEDOUT; -- goto errorout; -+ goto error1; - } - - - if (open_info->response.open_result.status) - err = open_info->response.open_result.status; - --cleanup: - spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_del(&open_info->msglistentry); - spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); -@@ -228,9 +227,12 @@ cleanup: - kfree(open_info); - return err; - --errorout: -- hv_ringbuffer_cleanup(&newchannel->outbound); -- hv_ringbuffer_cleanup(&newchannel->inbound); -+error1: -+ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); -+ list_del(&open_info->msglistentry); -+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); -+ -+error0: - free_pages((unsigned long)out, - get_order(send_ringbuffer_size + recv_ringbuffer_size)); - kfree(open_info); -diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c -index 4e2a162..4e98100 100644 ---- a/drivers/net/ethernet/tile/tilegx.c -+++ b/drivers/net/ethernet/tile/tilegx.c -@@ -1334,11 +1334,11 @@ static int tso_count_edescs(struct sk_buff *skb) - { - struct skb_shared_info *sh = skb_shinfo(skb); - unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); -- unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; -+ unsigned int data_len = skb->len - sh_len; - unsigned int p_len = sh->gso_size; - long f_id = -1; /* id of the current fragment */ -- long f_size = skb->hdr_len; /* size of the current fragment */ -- long f_used = sh_len; /* bytes used from the current fragment */ -+ long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ -+ long f_used = 0; /* bytes used from the current fragment */ - long n; /* size of the current piece of payload */ - int num_edescs = 0; - int segment; -@@ -1353,7 +1353,7 @@ static int tso_count_edescs(struct sk_buff *skb) - /* Advance as needed. */ - while (f_used >= f_size) { - f_id++; -- f_size = sh->frags[f_id].size; -+ f_size = skb_frag_size(&sh->frags[f_id]); - f_used = 0; - } - -@@ -1384,13 +1384,13 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, - struct iphdr *ih; - struct tcphdr *th; - unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); -- unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; -+ unsigned int data_len = skb->len - sh_len; - unsigned char *data = skb->data; - unsigned int ih_off, th_off, p_len; - unsigned int isum_seed, tsum_seed, id, seq; - long f_id = -1; /* id of the current fragment */ -- long f_size = skb->hdr_len; /* size of the current fragment */ -- long f_used = sh_len; /* bytes used from the current fragment */ -+ long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ -+ long f_used = 0; /* bytes used from the current fragment */ - long n; /* size of the current piece of payload */ - int segment; - -@@ -1405,7 +1405,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, - isum_seed = ((0xFFFF - ih->check) + - (0xFFFF - ih->tot_len) + - (0xFFFF - ih->id)); -- tsum_seed = th->check + (0xFFFF ^ htons(sh_len + data_len)); -+ tsum_seed = th->check + (0xFFFF ^ htons(skb->len)); - id = ntohs(ih->id); - seq = ntohl(th->seq); - -@@ -1444,7 +1444,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, - /* Advance as needed. */ - while (f_used >= f_size) { - f_id++; -- f_size = sh->frags[f_id].size; -+ f_size = skb_frag_size(&sh->frags[f_id]); - f_used = 0; - } - -@@ -1478,14 +1478,14 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, - struct tile_net_priv *priv = netdev_priv(dev); - struct skb_shared_info *sh = skb_shinfo(skb); - unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); -- unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; -+ unsigned int data_len = skb->len - sh_len; - unsigned int p_len = sh->gso_size; - gxio_mpipe_edesc_t edesc_head = { { 0 } }; - gxio_mpipe_edesc_t edesc_body = { { 0 } }; - long f_id = -1; /* id of the current fragment */ -- long f_size = skb->hdr_len; /* size of the current fragment */ -- long f_used = sh_len; /* bytes used from the current fragment */ -- void *f_data = skb->data; -+ long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ -+ long f_used = 0; /* bytes used from the current fragment */ -+ void *f_data = skb->data + sh_len; - long n; /* size of the current piece of payload */ - unsigned long tx_packets = 0, tx_bytes = 0; - unsigned int csum_start; -@@ -1516,15 +1516,18 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, - - /* Egress the payload. */ - while (p_used < p_len) { -+ void *va; - - /* Advance as needed. */ - while (f_used >= f_size) { - f_id++; -- f_size = sh->frags[f_id].size; -- f_used = 0; -+ f_size = skb_frag_size(&sh->frags[f_id]); - f_data = tile_net_frag_buf(&sh->frags[f_id]); -+ f_used = 0; - } - -+ va = f_data + f_used; -+ - /* Use bytes from the current fragment. */ - n = p_len - p_used; - if (n > f_size - f_used) -@@ -1533,7 +1536,7 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, - p_used += n; - - /* Egress a piece of the payload. */ -- edesc_body.va = va_to_tile_io_addr(f_data) + f_used; -+ edesc_body.va = va_to_tile_io_addr(va); - edesc_body.xfer_size = n; - edesc_body.bound = !(p_used < p_len); - gxio_mpipe_equeue_put_at(equeue, edesc_body, slot); -diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c -index a03de71..d012982 100644 ---- a/drivers/net/usb/cdc_ether.c -+++ b/drivers/net/usb/cdc_ether.c -@@ -592,6 +592,32 @@ static const struct usb_device_id products [] = { - .driver_info = 0, - }, - -+/* Novatel USB551L and MC551 - handled by qmi_wwan */ -+{ -+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR -+ | USB_DEVICE_ID_MATCH_PRODUCT -+ | USB_DEVICE_ID_MATCH_INT_INFO, -+ .idVendor = NOVATEL_VENDOR_ID, -+ .idProduct = 0xB001, -+ .bInterfaceClass = USB_CLASS_COMM, -+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, -+ .bInterfaceProtocol = USB_CDC_PROTO_NONE, -+ .driver_info = 0, -+}, -+ -+/* Novatel E362 - handled by qmi_wwan */ -+{ -+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR -+ | USB_DEVICE_ID_MATCH_PRODUCT -+ | USB_DEVICE_ID_MATCH_INT_INFO, -+ .idVendor = NOVATEL_VENDOR_ID, -+ .idProduct = 0x9010, -+ .bInterfaceClass = USB_CLASS_COMM, -+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, -+ .bInterfaceProtocol = USB_CDC_PROTO_NONE, -+ .driver_info = 0, -+}, -+ - /* - * WHITELIST!!! - * -@@ -604,21 +630,6 @@ static const struct usb_device_id products [] = { - * because of bugs/quirks in a given product (like Zaurus, above). - */ - { -- /* Novatel USB551L */ -- /* This match must come *before* the generic CDC-ETHER match so that -- * we get FLAG_WWAN set on the device, since it's descriptors are -- * generic CDC-ETHER. -- */ -- .match_flags = USB_DEVICE_ID_MATCH_VENDOR -- | USB_DEVICE_ID_MATCH_PRODUCT -- | USB_DEVICE_ID_MATCH_INT_INFO, -- .idVendor = NOVATEL_VENDOR_ID, -- .idProduct = 0xB001, -- .bInterfaceClass = USB_CLASS_COMM, -- .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, -- .bInterfaceProtocol = USB_CDC_PROTO_NONE, -- .driver_info = (unsigned long)&wwan_info, --}, { - /* ZTE (Vodafone) K3805-Z */ - .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_PRODUCT -diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c -index 3543c9e..3585f93 100644 ---- a/drivers/net/usb/qmi_wwan.c -+++ b/drivers/net/usb/qmi_wwan.c -@@ -364,6 +364,20 @@ static const struct usb_device_id products[] = { - USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57), - .driver_info = (unsigned long)&qmi_wwan_info, - }, -+ { /* Novatel USB551L and MC551 */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x1410, 0xb001, -+ USB_CLASS_COMM, -+ USB_CDC_SUBCLASS_ETHERNET, -+ USB_CDC_PROTO_NONE), -+ .driver_info = (unsigned long)&qmi_wwan_info, -+ }, -+ { /* Novatel E362 */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x1410, 0x9010, -+ USB_CLASS_COMM, -+ USB_CDC_SUBCLASS_ETHERNET, -+ USB_CDC_PROTO_NONE), -+ .driver_info = (unsigned long)&qmi_wwan_info, -+ }, - - /* 2. Combined interface devices matching on class+protocol */ - { /* Huawei E367 and possibly others in "Windows mode" */ -diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h -index 89bf94d..6f7cf49 100644 ---- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h -+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h -@@ -534,107 +534,107 @@ static const u32 ar9300_2p2_baseband_core[][2] = { - - static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ -- {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, -- {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, -- {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, -+ {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, -+ {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, -+ {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, - {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, -- {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202}, -- {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400}, -- {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402}, -- {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404}, -- {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603}, -- {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02}, -- {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04}, -- {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20}, -- {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20}, -- {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22}, -- {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24}, -- {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640}, -- {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660}, -- {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861}, -- {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81}, -- {0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83}, -- {0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84}, -- {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3}, -- {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5}, -- {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9}, -- {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb}, -- {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, -- {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, -- {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, -- {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, -- {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, -- {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, -- {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, -+ {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, -+ {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, -+ {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, -+ {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, -+ {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, -+ {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, -+ {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, -+ {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, -+ {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, -+ {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, -+ {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, -+ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, -+ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, -+ {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, -+ {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, -+ {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, -+ {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, -+ {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, -+ {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, -+ {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, -+ {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, -+ {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, -+ {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, -+ {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, -+ {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, -+ {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, -+ {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, -+ {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, - {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, - {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, - {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, -- {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202}, -- {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400}, -- {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402}, -- {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404}, -- {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603}, -- {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02}, -- {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04}, -- {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20}, -- {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20}, -- {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22}, -- {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24}, -- {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640}, -- {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660}, -- {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861}, -- {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81}, -- {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83}, -- {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84}, -- {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3}, -- {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5}, -- {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9}, -- {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb}, -- {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, -- {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, -- {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, -- {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, -- {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, -- {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, -- {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, -+ {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, -+ {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, -+ {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, -+ {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, -+ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, -+ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, -+ {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, -+ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, -+ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, -+ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, -+ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, -+ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, -+ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, -+ {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, -+ {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, -+ {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, -+ {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, -+ {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, -+ {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, -+ {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, -+ {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, -+ {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, -+ {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, -+ {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, -+ {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, -+ {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, -+ {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, -+ {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, -- {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, -- {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, -- {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, -- {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000}, -- {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501}, -- {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501}, -- {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03}, -- {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, -- {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04}, -- {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, -- {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, -- {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, -- {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, -- {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, -- {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, -- {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, -- {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, -+ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, -+ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, -+ {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, -+ {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, -+ {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, -+ {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, -+ {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, -+ {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, -+ {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, -+ {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, -+ {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, -+ {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, -+ {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, -+ {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, -+ {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, -+ {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, -+ {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, -- {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, -- {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, -- {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, -+ {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, -+ {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, -+ {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, - {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, -- {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, -+ {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, - {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, -- {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, -+ {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, - {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, -- {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, -+ {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, - {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - }; - -diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c -index a140165..46d9d4e 100644 ---- a/drivers/net/wireless/b43/main.c -+++ b/drivers/net/wireless/b43/main.c -@@ -5374,6 +5374,8 @@ static void b43_bcma_remove(struct bcma_device *core) - cancel_work_sync(&wldev->restart_work); - - B43_WARN_ON(!wl); -+ if (!wldev->fw.ucode.data) -+ return; /* NULL if firmware never loaded */ - if (wl->current_dev == wldev && wl->hw_registred) { - b43_leds_stop(wldev); - ieee80211_unregister_hw(wl->hw); -@@ -5448,6 +5450,8 @@ static void b43_ssb_remove(struct ssb_device *sdev) - cancel_work_sync(&wldev->restart_work); - - B43_WARN_ON(!wl); -+ if (!wldev->fw.ucode.data) -+ return; /* NULL if firmware never loaded */ - if (wl->current_dev == wldev && wl->hw_registred) { - b43_leds_stop(wldev); - ieee80211_unregister_hw(wl->hw); -diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c -index 0df4591..6d1754a 100644 ---- a/drivers/net/wireless/ipw2x00/ipw2200.c -+++ b/drivers/net/wireless/ipw2x00/ipw2200.c -@@ -10479,7 +10479,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, - } else - len = src->len; - -- dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC); -+ dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC); - if (!dst) - continue; - -diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c -index 349c205..da58620 100644 ---- a/drivers/net/wireless/iwlwifi/dvm/devices.c -+++ b/drivers/net/wireless/iwlwifi/dvm/devices.c -@@ -518,7 +518,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, - * See iwlagn_mac_channel_switch. - */ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; -- struct iwl6000_channel_switch_cmd cmd; -+ struct iwl6000_channel_switch_cmd *cmd; - u32 switch_time_in_usec, ucode_switch_time; - u16 ch; - u32 tsf_low; -@@ -527,18 +527,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, - struct ieee80211_vif *vif = ctx->vif; - struct iwl_host_cmd hcmd = { - .id = REPLY_CHANNEL_SWITCH, -- .len = { sizeof(cmd), }, -+ .len = { sizeof(*cmd), }, - .flags = CMD_SYNC, -- .data = { &cmd, }, -+ .dataflags[0] = IWL_HCMD_DFL_NOCOPY, - }; -+ int err; - -- cmd.band = priv->band == IEEE80211_BAND_2GHZ; -+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); -+ if (!cmd) -+ return -ENOMEM; -+ -+ hcmd.data[0] = cmd; -+ -+ cmd->band = priv->band == IEEE80211_BAND_2GHZ; - ch = ch_switch->channel->hw_value; - IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", - ctx->active.channel, ch); -- cmd.channel = cpu_to_le16(ch); -- cmd.rxon_flags = ctx->staging.flags; -- cmd.rxon_filter_flags = ctx->staging.filter_flags; -+ cmd->channel = cpu_to_le16(ch); -+ cmd->rxon_flags = ctx->staging.flags; -+ cmd->rxon_filter_flags = ctx->staging.filter_flags; - switch_count = ch_switch->count; - tsf_low = ch_switch->timestamp & 0x0ffffffff; - /* -@@ -554,23 +561,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, - switch_count = 0; - } - if (switch_count <= 1) -- cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); -+ cmd->switch_time = cpu_to_le32(priv->ucode_beacon_time); - else { - switch_time_in_usec = - vif->bss_conf.beacon_int * switch_count * TIME_UNIT; - ucode_switch_time = iwl_usecs_to_beacons(priv, - switch_time_in_usec, - beacon_interval); -- cmd.switch_time = iwl_add_beacon_time(priv, -- priv->ucode_beacon_time, -- ucode_switch_time, -- beacon_interval); -+ cmd->switch_time = iwl_add_beacon_time(priv, -+ priv->ucode_beacon_time, -+ ucode_switch_time, -+ beacon_interval); - } - IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", -- cmd.switch_time); -- cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; -+ cmd->switch_time); -+ cmd->expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; - -- return iwl_dvm_send_cmd(priv, &hcmd); -+ err = iwl_dvm_send_cmd(priv, &hcmd); -+ kfree(cmd); -+ return err; - } - - struct iwl_lib_ops iwl6000_lib = { -diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c -index 891cd6c..4eed510 100644 ---- a/drivers/rtc/rtc-imxdi.c -+++ b/drivers/rtc/rtc-imxdi.c -@@ -392,6 +392,8 @@ static int dryice_rtc_probe(struct platform_device *pdev) - if (imxdi->ioaddr == NULL) - return -ENOMEM; - -+ spin_lock_init(&imxdi->irq_lock); -+ - imxdi->irq = platform_get_irq(pdev, 0); - if (imxdi->irq < 0) - return imxdi->irq; -diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c -index 574e992..467d493 100644 ---- a/drivers/staging/android/binder.c -+++ b/drivers/staging/android/binder.c -@@ -655,7 +655,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, - page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; - - BUG_ON(*page); -- *page = alloc_page(GFP_KERNEL | __GFP_ZERO); -+ *page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO); - if (*page == NULL) { - pr_err("binder: %d: binder_alloc_buf failed " - "for page at %p\n", proc->pid, page_addr); -@@ -2507,14 +2507,38 @@ static void binder_release_work(struct list_head *list) - struct binder_transaction *t; - - t = container_of(w, struct binder_transaction, work); -- if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) -+ if (t->buffer->target_node && -+ !(t->flags & TF_ONE_WAY)) { - binder_send_failed_reply(t, BR_DEAD_REPLY); -+ } else { -+ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, -+ "binder: undelivered transaction %d\n", -+ t->debug_id); -+ t->buffer->transaction = NULL; -+ kfree(t); -+ binder_stats_deleted(BINDER_STAT_TRANSACTION); -+ } - } break; - case BINDER_WORK_TRANSACTION_COMPLETE: { -+ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, -+ "binder: undelivered TRANSACTION_COMPLETE\n"); - kfree(w); - binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); - } break; -+ case BINDER_WORK_DEAD_BINDER_AND_CLEAR: -+ case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: { -+ struct binder_ref_death *death; -+ -+ death = container_of(w, struct binder_ref_death, work); -+ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, -+ "binder: undelivered death notification, %p\n", -+ death->cookie); -+ kfree(death); -+ binder_stats_deleted(BINDER_STAT_DEATH); -+ } break; - default: -+ pr_err("binder: unexpected work type, %d, not freed\n", -+ w->type); - break; - } - } -@@ -2984,6 +3008,7 @@ static void binder_deferred_release(struct binder_proc *proc) - nodes++; - rb_erase(&node->rb_node, &proc->nodes); - list_del_init(&node->work.entry); -+ binder_release_work(&node->async_todo); - if (hlist_empty(&node->refs)) { - kfree(node); - binder_stats_deleted(BINDER_STAT_NODE); -@@ -3022,6 +3047,7 @@ static void binder_deferred_release(struct binder_proc *proc) - binder_delete_ref(ref); - } - binder_release_work(&proc->todo); -+ binder_release_work(&proc->delivered_death); - buffers = 0; - - while ((n = rb_first(&proc->allocated_buffers))) { -diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c -index cc8931f..aee22fd 100644 ---- a/drivers/staging/comedi/drivers/amplc_dio200.c -+++ b/drivers/staging/comedi/drivers/amplc_dio200.c -@@ -1429,6 +1429,8 @@ static void dio200_detach(struct comedi_device *dev) - const struct dio200_layout_struct *layout; - unsigned n; - -+ if (!thisboard) -+ return; - if (dev->irq) - free_irq(dev->irq, dev); - if (dev->subdevices) { -diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c -index f502879..b46e663 100644 ---- a/drivers/staging/comedi/drivers/amplc_pc236.c -+++ b/drivers/staging/comedi/drivers/amplc_pc236.c -@@ -577,10 +577,12 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, - - static void pc236_detach(struct comedi_device *dev) - { -- struct pc236_private *devpriv = dev->private; -+ const struct pc236_board *thisboard = comedi_board(dev); - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - -- if (devpriv) -+ if (!thisboard) -+ return; -+ if (dev->iobase) - pc236_intr_disable(dev); - if (dev->irq) - free_irq(dev->irq, dev); -diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c -index 8191c4e..8c0fbd1 100644 ---- a/drivers/staging/comedi/drivers/amplc_pc263.c -+++ b/drivers/staging/comedi/drivers/amplc_pc263.c -@@ -310,8 +310,11 @@ static int __devinit pc263_attach_pci(struct comedi_device *dev, - - static void pc263_detach(struct comedi_device *dev) - { -+ const struct pc263_board *thisboard = comedi_board(dev); - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - -+ if (!thisboard) -+ return; - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); -diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c -index 67a914a..d893e3b 100644 ---- a/drivers/staging/comedi/drivers/das08.c -+++ b/drivers/staging/comedi/drivers/das08.c -@@ -1028,6 +1028,8 @@ static void __maybe_unused das08_detach(struct comedi_device *dev) - const struct das08_board_struct *thisboard = comedi_board(dev); - struct das08_private_struct *devpriv = dev->private; - -+ if (!thisboard) -+ return; - das08_common_detach(dev); - if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) && - (thisboard->bustype == isa || thisboard->bustype == pc104)) { -diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c -index 83016b4..bcf6a65 100644 ---- a/drivers/staging/comedi/drivers/ni_daq_700.c -+++ b/drivers/staging/comedi/drivers/ni_daq_700.c -@@ -71,7 +71,7 @@ static int subdev_700_insn(struct comedi_device *dev, - } - - data[1] = s->state & 0xff; -- data[1] |= inb(dev->iobase + DIO_R); -+ data[1] |= inb(dev->iobase + DIO_R) << 8; - - return insn->n; - } -diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c -index ab8b787..d3a1d65 100644 ---- a/drivers/staging/comedi/drivers/ni_labpc.c -+++ b/drivers/staging/comedi/drivers/ni_labpc.c -@@ -809,6 +809,8 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot) - - void labpc_common_detach(struct comedi_device *dev) - { -+ if (!thisboard) -+ return; - if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 2); - #ifdef CONFIG_ISA_DMA_API -diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c -index 653b074..6edefde 100644 ---- a/drivers/staging/zram/zram_drv.c -+++ b/drivers/staging/zram/zram_drv.c -@@ -223,8 +223,13 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, - cmem = zs_map_object(zram->mem_pool, zram->table[index].handle, - ZS_MM_RO); - -- ret = lzo1x_decompress_safe(cmem, zram->table[index].size, -+ if (zram->table[index].size == PAGE_SIZE) { -+ memcpy(uncmem, cmem, PAGE_SIZE); -+ ret = LZO_E_OK; -+ } else { -+ ret = lzo1x_decompress_safe(cmem, zram->table[index].size, - uncmem, &clen); -+ } - - if (is_partial_io(bvec)) { - memcpy(user_mem + bvec->bv_offset, uncmem + offset, -@@ -342,8 +347,11 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, - goto out; - } - -- if (unlikely(clen > max_zpage_size)) -+ if (unlikely(clen > max_zpage_size)) { - zram_stat_inc(&zram->stats.bad_compress); -+ src = uncmem; -+ clen = PAGE_SIZE; -+ } - - handle = zs_malloc(zram->mem_pool, clen); - if (!handle) { -diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index bbff143..fe7faf0 100644 ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -730,13 +730,16 @@ static void hub_tt_work(struct work_struct *work) - int limit = 100; - - spin_lock_irqsave (&hub->tt.lock, flags); -- while (--limit && !list_empty (&hub->tt.clear_list)) { -+ while (!list_empty(&hub->tt.clear_list)) { - struct list_head *next; - struct usb_tt_clear *clear; - struct usb_device *hdev = hub->hdev; - const struct hc_driver *drv; - int status; - -+ if (!hub->quiescing && --limit < 0) -+ break; -+ - next = hub->tt.clear_list.next; - clear = list_entry (next, struct usb_tt_clear, clear_list); - list_del (&clear->clear_list); -@@ -1201,7 +1204,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) - if (hub->has_indicators) - cancel_delayed_work_sync(&hub->leds); - if (hub->tt.hub) -- cancel_work_sync(&hub->tt.clear_work); -+ flush_work_sync(&hub->tt.clear_work); - } - - /* caller has locked the hub device */ -diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c -index 966d148..39f9e4a 100644 ---- a/drivers/usb/host/pci-quirks.c -+++ b/drivers/usb/host/pci-quirks.c -@@ -545,7 +545,14 @@ static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = { - /* Pegatron Lucid (Ordissimo AIRIS) */ - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "M11JB"), -- DMI_MATCH(DMI_BIOS_VERSION, "Lucid-GE-133"), -+ DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), -+ }, -+ }, -+ { -+ /* Pegatron Lucid (Ordissimo) */ -+ .matches = { -+ DMI_MATCH(DMI_BOARD_NAME, "Ordissimo"), -+ DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), - }, - }, - { } -diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c -index a6e18b9..4f1e265 100644 ---- a/drivers/usb/host/xhci-ring.c -+++ b/drivers/usb/host/xhci-ring.c -@@ -1228,6 +1228,17 @@ static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd) - cur_seg = find_trb_seg(xhci->cmd_ring->first_seg, - xhci->cmd_ring->dequeue, &cycle_state); - -+ if (!cur_seg) { -+ xhci_warn(xhci, "Command ring mismatch, dequeue = %p %llx (dma)\n", -+ xhci->cmd_ring->dequeue, -+ (unsigned long long) -+ xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, -+ xhci->cmd_ring->dequeue)); -+ xhci_debug_ring(xhci, xhci->cmd_ring); -+ xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); -+ return; -+ } -+ - /* find the command trb matched by cd from command ring */ - for (cmd_trb = xhci->cmd_ring->dequeue; - cmd_trb != xhci->cmd_ring->enqueue; -diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c -index 0644f65..a6e910b 100644 ---- a/drivers/usb/host/xhci.c -+++ b/drivers/usb/host/xhci.c -@@ -4020,7 +4020,7 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) - static unsigned long long xhci_service_interval_to_ns( - struct usb_endpoint_descriptor *desc) - { -- return (1 << (desc->bInterval - 1)) * 125 * 1000; -+ return (1ULL << (desc->bInterval - 1)) * 125 * 1000; - } - - static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, -@@ -4141,7 +4141,7 @@ static u16 xhci_calculate_intel_u2_timeout(struct usb_device *udev, - (xhci_service_interval_to_ns(desc) > timeout_ns)) - timeout_ns = xhci_service_interval_to_ns(desc); - -- u2_del_ns = udev->bos->ss_cap->bU2DevExitLat * 1000; -+ u2_del_ns = le16_to_cpu(udev->bos->ss_cap->bU2DevExitLat) * 1000ULL; - if (u2_del_ns > timeout_ns) - timeout_ns = u2_del_ns; - -diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c -index cabd1b1..8391d30 100644 ---- a/drivers/usb/serial/ch341.c -+++ b/drivers/usb/serial/ch341.c -@@ -241,13 +241,11 @@ out: kfree(buffer); - return r; - } - --/* allocate private data */ --static int ch341_attach(struct usb_serial *serial) -+static int ch341_port_probe(struct usb_serial_port *port) - { - struct ch341_private *priv; - int r; - -- /* private data */ - priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); - if (!priv) - return -ENOMEM; -@@ -257,17 +255,27 @@ static int ch341_attach(struct usb_serial *serial) - priv->baud_rate = DEFAULT_BAUD_RATE; - priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; - -- r = ch341_configure(serial->dev, priv); -+ r = ch341_configure(port->serial->dev, priv); - if (r < 0) - goto error; - -- usb_set_serial_port_data(serial->port[0], priv); -+ usb_set_serial_port_data(port, priv); - return 0; - - error: kfree(priv); - return r; - } - -+static int ch341_port_remove(struct usb_serial_port *port) -+{ -+ struct ch341_private *priv; -+ -+ priv = usb_get_serial_port_data(port); -+ kfree(priv); -+ -+ return 0; -+} -+ - static int ch341_carrier_raised(struct usb_serial_port *port) - { - struct ch341_private *priv = usb_get_serial_port_data(port); -@@ -303,7 +311,7 @@ static void ch341_close(struct usb_serial_port *port) - static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) - { - struct usb_serial *serial = port->serial; -- struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]); -+ struct ch341_private *priv = usb_get_serial_port_data(port); - int r; - - priv->baud_rate = DEFAULT_BAUD_RATE; -@@ -606,7 +614,8 @@ static struct usb_serial_driver ch341_device = { - .tiocmget = ch341_tiocmget, - .tiocmset = ch341_tiocmset, - .read_int_callback = ch341_read_int_callback, -- .attach = ch341_attach, -+ .port_probe = ch341_port_probe, -+ .port_remove = ch341_port_remove, - .reset_resume = ch341_reset_resume, - }; - -diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c -index b5cd838..06e8bf4 100644 ---- a/drivers/usb/serial/digi_acceleport.c -+++ b/drivers/usb/serial/digi_acceleport.c -@@ -244,6 +244,8 @@ static int digi_startup_device(struct usb_serial *serial); - static int digi_startup(struct usb_serial *serial); - static void digi_disconnect(struct usb_serial *serial); - static void digi_release(struct usb_serial *serial); -+static int digi_port_probe(struct usb_serial_port *port); -+static int digi_port_remove(struct usb_serial_port *port); - static void digi_read_bulk_callback(struct urb *urb); - static int digi_read_inb_callback(struct urb *urb); - static int digi_read_oob_callback(struct urb *urb); -@@ -298,6 +300,8 @@ static struct usb_serial_driver digi_acceleport_2_device = { - .attach = digi_startup, - .disconnect = digi_disconnect, - .release = digi_release, -+ .port_probe = digi_port_probe, -+ .port_remove = digi_port_remove, - }; - - static struct usb_serial_driver digi_acceleport_4_device = { -@@ -324,6 +328,8 @@ static struct usb_serial_driver digi_acceleport_4_device = { - .attach = digi_startup, - .disconnect = digi_disconnect, - .release = digi_release, -+ .port_probe = digi_port_probe, -+ .port_remove = digi_port_remove, - }; - - static struct usb_serial_driver * const serial_drivers[] = { -@@ -1237,59 +1243,50 @@ static int digi_startup_device(struct usb_serial *serial) - return ret; - } - -- --static int digi_startup(struct usb_serial *serial) -+static int digi_port_init(struct usb_serial_port *port, unsigned port_num) - { -- -- int i; - struct digi_port *priv; -- struct digi_serial *serial_priv; - -- /* allocate the private data structures for all ports */ -- /* number of regular ports + 1 for the out-of-band port */ -- for (i = 0; i < serial->type->num_ports + 1; i++) { -- /* allocate port private structure */ -- priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL); -- if (priv == NULL) { -- while (--i >= 0) -- kfree(usb_get_serial_port_data(serial->port[i])); -- return 1; /* error */ -- } -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; - -- /* initialize port private structure */ -- spin_lock_init(&priv->dp_port_lock); -- priv->dp_port_num = i; -- priv->dp_out_buf_len = 0; -- priv->dp_write_urb_in_use = 0; -- priv->dp_modem_signals = 0; -- init_waitqueue_head(&priv->dp_modem_change_wait); -- priv->dp_transmit_idle = 0; -- init_waitqueue_head(&priv->dp_transmit_idle_wait); -- priv->dp_throttled = 0; -- priv->dp_throttle_restart = 0; -- init_waitqueue_head(&priv->dp_flush_wait); -- init_waitqueue_head(&priv->dp_close_wait); -- INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); -- priv->dp_port = serial->port[i]; -- /* initialize write wait queue for this port */ -- init_waitqueue_head(&serial->port[i]->write_wait); -- -- usb_set_serial_port_data(serial->port[i], priv); -- } -+ spin_lock_init(&priv->dp_port_lock); -+ priv->dp_port_num = port_num; -+ init_waitqueue_head(&priv->dp_modem_change_wait); -+ init_waitqueue_head(&priv->dp_transmit_idle_wait); -+ init_waitqueue_head(&priv->dp_flush_wait); -+ init_waitqueue_head(&priv->dp_close_wait); -+ INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); -+ priv->dp_port = port; - -- /* allocate serial private structure */ -- serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL); -- if (serial_priv == NULL) { -- for (i = 0; i < serial->type->num_ports + 1; i++) -- kfree(usb_get_serial_port_data(serial->port[i])); -- return 1; /* error */ -- } -+ init_waitqueue_head(&port->write_wait); -+ -+ usb_set_serial_port_data(port, priv); -+ -+ return 0; -+} -+ -+static int digi_startup(struct usb_serial *serial) -+{ -+ struct digi_serial *serial_priv; -+ int ret; -+ -+ serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL); -+ if (!serial_priv) -+ return -ENOMEM; - -- /* initialize serial private structure */ - spin_lock_init(&serial_priv->ds_serial_lock); - serial_priv->ds_oob_port_num = serial->type->num_ports; - serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; -- serial_priv->ds_device_started = 0; -+ -+ ret = digi_port_init(serial_priv->ds_oob_port, -+ serial_priv->ds_oob_port_num); -+ if (ret) { -+ kfree(serial_priv); -+ return ret; -+ } -+ - usb_set_serial_data(serial, serial_priv); - - return 0; -@@ -1310,15 +1307,35 @@ static void digi_disconnect(struct usb_serial *serial) - - static void digi_release(struct usb_serial *serial) - { -- int i; -+ struct digi_serial *serial_priv; -+ struct digi_port *priv; -+ -+ serial_priv = usb_get_serial_data(serial); -+ -+ priv = usb_get_serial_port_data(serial_priv->ds_oob_port); -+ kfree(priv); - -- /* free the private data structures for all ports */ -- /* number of regular ports + 1 for the out-of-band port */ -- for (i = 0; i < serial->type->num_ports + 1; i++) -- kfree(usb_get_serial_port_data(serial->port[i])); -- kfree(usb_get_serial_data(serial)); -+ kfree(serial_priv); - } - -+static int digi_port_probe(struct usb_serial_port *port) -+{ -+ unsigned port_num; -+ -+ port_num = port->number - port->serial->minor; -+ -+ return digi_port_init(port, port_num); -+} -+ -+static int digi_port_remove(struct usb_serial_port *port) -+{ -+ struct digi_port *priv; -+ -+ priv = usb_get_serial_port_data(port); -+ kfree(priv); -+ -+ return 0; -+} - - static void digi_read_bulk_callback(struct urb *urb) - { -diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c -index 2cb30c5..8df011f 100644 ---- a/drivers/usb/serial/ipw.c -+++ b/drivers/usb/serial/ipw.c -@@ -209,8 +209,7 @@ static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port) - return 0; - } - --/* fake probe - only to allocate data structures */ --static int ipw_probe(struct usb_serial *serial, const struct usb_device_id *id) -+static int ipw_attach(struct usb_serial *serial) - { - struct usb_wwan_intf_private *data; - -@@ -310,9 +309,9 @@ static struct usb_serial_driver ipw_device = { - .num_ports = 1, - .open = ipw_open, - .close = ipw_close, -- .probe = ipw_probe, -- .attach = usb_wwan_startup, -+ .attach = ipw_attach, - .release = ipw_release, -+ .port_probe = usb_wwan_port_probe, - .port_remove = usb_wwan_port_remove, - .dtr_rts = ipw_dtr_rts, - .write = usb_wwan_write, -diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c -index af0b70e..f6788d7 100644 ---- a/drivers/usb/serial/keyspan.c -+++ b/drivers/usb/serial/keyspan.c -@@ -1392,13 +1392,9 @@ static struct callbacks { - data in device_details */ - static void keyspan_setup_urbs(struct usb_serial *serial) - { -- int i, j; - struct keyspan_serial_private *s_priv; - const struct keyspan_device_details *d_details; -- struct usb_serial_port *port; -- struct keyspan_port_private *p_priv; - struct callbacks *cback; -- int endp; - - s_priv = usb_get_serial_data(serial); - d_details = s_priv->device_details; -@@ -1422,45 +1418,6 @@ static void keyspan_setup_urbs(struct usb_serial *serial) - (serial, d_details->glocont_endpoint, USB_DIR_OUT, - serial, s_priv->glocont_buf, GLOCONT_BUFLEN, - cback->glocont_callback); -- -- /* Setup endpoints for each port specific thing */ -- for (i = 0; i < d_details->num_ports; i++) { -- port = serial->port[i]; -- p_priv = usb_get_serial_port_data(port); -- -- /* Do indat endpoints first, once for each flip */ -- endp = d_details->indat_endpoints[i]; -- for (j = 0; j <= d_details->indat_endp_flip; ++j, ++endp) { -- p_priv->in_urbs[j] = keyspan_setup_urb -- (serial, endp, USB_DIR_IN, port, -- p_priv->in_buffer[j], 64, -- cback->indat_callback); -- } -- for (; j < 2; ++j) -- p_priv->in_urbs[j] = NULL; -- -- /* outdat endpoints also have flip */ -- endp = d_details->outdat_endpoints[i]; -- for (j = 0; j <= d_details->outdat_endp_flip; ++j, ++endp) { -- p_priv->out_urbs[j] = keyspan_setup_urb -- (serial, endp, USB_DIR_OUT, port, -- p_priv->out_buffer[j], 64, -- cback->outdat_callback); -- } -- for (; j < 2; ++j) -- p_priv->out_urbs[j] = NULL; -- -- /* inack endpoint */ -- p_priv->inack_urb = keyspan_setup_urb -- (serial, d_details->inack_endpoints[i], USB_DIR_IN, -- port, p_priv->inack_buffer, 1, cback->inack_callback); -- -- /* outcont endpoint */ -- p_priv->outcont_urb = keyspan_setup_urb -- (serial, d_details->outcont_endpoints[i], USB_DIR_OUT, -- port, p_priv->outcont_buffer, 64, -- cback->outcont_callback); -- } - } - - /* usa19 function doesn't require prescaler */ -@@ -2422,9 +2379,7 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) - static int keyspan_startup(struct usb_serial *serial) - { - int i, err; -- struct usb_serial_port *port; - struct keyspan_serial_private *s_priv; -- struct keyspan_port_private *p_priv; - const struct keyspan_device_details *d_details; - - for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i) -@@ -2448,19 +2403,6 @@ static int keyspan_startup(struct usb_serial *serial) - s_priv->device_details = d_details; - usb_set_serial_data(serial, s_priv); - -- /* Now setup per port private data */ -- for (i = 0; i < serial->num_ports; i++) { -- port = serial->port[i]; -- p_priv = kzalloc(sizeof(struct keyspan_port_private), -- GFP_KERNEL); -- if (!p_priv) { -- dbg("%s - kmalloc for keyspan_port_private (%d) failed!.", __func__, i); -- return 1; -- } -- p_priv->device_details = d_details; -- usb_set_serial_port_data(port, p_priv); -- } -- - keyspan_setup_urbs(serial); - - if (s_priv->instat_urb != NULL) { -@@ -2481,61 +2423,112 @@ static int keyspan_startup(struct usb_serial *serial) - - static void keyspan_disconnect(struct usb_serial *serial) - { -- int i, j; -- struct usb_serial_port *port; -- struct keyspan_serial_private *s_priv; -- struct keyspan_port_private *p_priv; -+ struct keyspan_serial_private *s_priv; - - s_priv = usb_get_serial_data(serial); - -- /* Stop reading/writing urbs */ - stop_urb(s_priv->instat_urb); - stop_urb(s_priv->glocont_urb); - stop_urb(s_priv->indat_urb); -- for (i = 0; i < serial->num_ports; ++i) { -- port = serial->port[i]; -- p_priv = usb_get_serial_port_data(port); -- stop_urb(p_priv->inack_urb); -- stop_urb(p_priv->outcont_urb); -- for (j = 0; j < 2; j++) { -- stop_urb(p_priv->in_urbs[j]); -- stop_urb(p_priv->out_urbs[j]); -- } -- } -+} -+ -+static void keyspan_release(struct usb_serial *serial) -+{ -+ struct keyspan_serial_private *s_priv; -+ -+ s_priv = usb_get_serial_data(serial); - -- /* Now free them */ - usb_free_urb(s_priv->instat_urb); - usb_free_urb(s_priv->indat_urb); - usb_free_urb(s_priv->glocont_urb); -- for (i = 0; i < serial->num_ports; ++i) { -- port = serial->port[i]; -- p_priv = usb_get_serial_port_data(port); -- usb_free_urb(p_priv->inack_urb); -- usb_free_urb(p_priv->outcont_urb); -- for (j = 0; j < 2; j++) { -- usb_free_urb(p_priv->in_urbs[j]); -- usb_free_urb(p_priv->out_urbs[j]); -- } -- } -+ -+ kfree(s_priv); - } - --static void keyspan_release(struct usb_serial *serial) -+static int keyspan_port_probe(struct usb_serial_port *port) - { -- int i; -- struct usb_serial_port *port; -- struct keyspan_serial_private *s_priv; -+ struct usb_serial *serial = port->serial; -+ struct keyspan_port_private *s_priv; -+ struct keyspan_port_private *p_priv; -+ const struct keyspan_device_details *d_details; -+ struct callbacks *cback; -+ int endp; -+ int port_num; -+ int i; - - s_priv = usb_get_serial_data(serial); -+ d_details = s_priv->device_details; - -- /* dbg("Freeing serial->private."); */ -- kfree(s_priv); -+ p_priv = kzalloc(sizeof(*p_priv), GFP_KERNEL); -+ if (!p_priv) -+ return -ENOMEM; - -- /* dbg("Freeing port->private."); */ -- /* Now free per port private data */ -- for (i = 0; i < serial->num_ports; i++) { -- port = serial->port[i]; -- kfree(usb_get_serial_port_data(port)); -+ s_priv = usb_get_serial_data(port->serial); -+ p_priv->device_details = d_details; -+ -+ /* Setup values for the various callback routines */ -+ cback = &keyspan_callbacks[d_details->msg_format]; -+ -+ port_num = port->number - port->serial->minor; -+ -+ /* Do indat endpoints first, once for each flip */ -+ endp = d_details->indat_endpoints[port_num]; -+ for (i = 0; i <= d_details->indat_endp_flip; ++i, ++endp) { -+ p_priv->in_urbs[i] = keyspan_setup_urb(serial, endp, -+ USB_DIR_IN, port, -+ p_priv->in_buffer[i], 64, -+ cback->indat_callback); -+ } -+ /* outdat endpoints also have flip */ -+ endp = d_details->outdat_endpoints[port_num]; -+ for (i = 0; i <= d_details->outdat_endp_flip; ++i, ++endp) { -+ p_priv->out_urbs[i] = keyspan_setup_urb(serial, endp, -+ USB_DIR_OUT, port, -+ p_priv->out_buffer[i], 64, -+ cback->outdat_callback); -+ } -+ /* inack endpoint */ -+ p_priv->inack_urb = keyspan_setup_urb(serial, -+ d_details->inack_endpoints[port_num], -+ USB_DIR_IN, port, -+ p_priv->inack_buffer, 1, -+ cback->inack_callback); -+ /* outcont endpoint */ -+ p_priv->outcont_urb = keyspan_setup_urb(serial, -+ d_details->outcont_endpoints[port_num], -+ USB_DIR_OUT, port, -+ p_priv->outcont_buffer, 64, -+ cback->outcont_callback); -+ -+ usb_set_serial_port_data(port, p_priv); -+ -+ return 0; -+} -+ -+static int keyspan_port_remove(struct usb_serial_port *port) -+{ -+ struct keyspan_port_private *p_priv; -+ int i; -+ -+ p_priv = usb_get_serial_port_data(port); -+ -+ stop_urb(p_priv->inack_urb); -+ stop_urb(p_priv->outcont_urb); -+ for (i = 0; i < 2; i++) { -+ stop_urb(p_priv->in_urbs[i]); -+ stop_urb(p_priv->out_urbs[i]); -+ } -+ -+ usb_free_urb(p_priv->inack_urb); -+ usb_free_urb(p_priv->outcont_urb); -+ for (i = 0; i < 2; i++) { -+ usb_free_urb(p_priv->in_urbs[i]); -+ usb_free_urb(p_priv->out_urbs[i]); - } -+ -+ kfree(p_priv); -+ -+ return 0; - } - - MODULE_AUTHOR(DRIVER_AUTHOR); -diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h -index fe1c5d9..90a7b36 100644 ---- a/drivers/usb/serial/keyspan.h -+++ b/drivers/usb/serial/keyspan.h -@@ -42,6 +42,8 @@ static void keyspan_dtr_rts (struct usb_serial_port *port, int on); - static int keyspan_startup (struct usb_serial *serial); - static void keyspan_disconnect (struct usb_serial *serial); - static void keyspan_release (struct usb_serial *serial); -+static int keyspan_port_probe(struct usb_serial_port *port); -+static int keyspan_port_remove(struct usb_serial_port *port); - static int keyspan_write_room (struct tty_struct *tty); - - static int keyspan_write (struct tty_struct *tty, -@@ -562,6 +564,8 @@ static struct usb_serial_driver keyspan_1port_device = { - .attach = keyspan_startup, - .disconnect = keyspan_disconnect, - .release = keyspan_release, -+ .port_probe = keyspan_port_probe, -+ .port_remove = keyspan_port_remove, - }; - - static struct usb_serial_driver keyspan_2port_device = { -@@ -584,6 +588,8 @@ static struct usb_serial_driver keyspan_2port_device = { - .attach = keyspan_startup, - .disconnect = keyspan_disconnect, - .release = keyspan_release, -+ .port_probe = keyspan_port_probe, -+ .port_remove = keyspan_port_remove, - }; - - static struct usb_serial_driver keyspan_4port_device = { -@@ -606,6 +612,8 @@ static struct usb_serial_driver keyspan_4port_device = { - .attach = keyspan_startup, - .disconnect = keyspan_disconnect, - .release = keyspan_release, -+ .port_probe = keyspan_port_probe, -+ .port_remove = keyspan_port_remove, - }; - - static struct usb_serial_driver * const serial_drivers[] = { -diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c -index a71fa0a..c088250 100644 ---- a/drivers/usb/serial/mct_u232.c -+++ b/drivers/usb/serial/mct_u232.c -@@ -51,7 +51,8 @@ static bool debug; - * Function prototypes - */ - static int mct_u232_startup(struct usb_serial *serial); --static void mct_u232_release(struct usb_serial *serial); -+static int mct_u232_port_probe(struct usb_serial_port *port); -+static int mct_u232_port_remove(struct usb_serial_port *remove); - static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port); - static void mct_u232_close(struct usb_serial_port *port); - static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); -@@ -101,7 +102,8 @@ static struct usb_serial_driver mct_u232_device = { - .tiocmget = mct_u232_tiocmget, - .tiocmset = mct_u232_tiocmset, - .attach = mct_u232_startup, -- .release = mct_u232_release, -+ .port_probe = mct_u232_port_probe, -+ .port_remove = mct_u232_port_remove, - .ioctl = mct_u232_ioctl, - .get_icount = mct_u232_get_icount, - }; -@@ -392,18 +394,8 @@ static void mct_u232_msr_to_state(unsigned int *control_state, - - static int mct_u232_startup(struct usb_serial *serial) - { -- struct mct_u232_private *priv; - struct usb_serial_port *port, *rport; - -- priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- spin_lock_init(&priv->lock); -- init_waitqueue_head(&priv->msr_wait); -- usb_set_serial_port_data(serial->port[0], priv); -- -- init_waitqueue_head(&serial->port[0]->write_wait); -- - /* Puh, that's dirty */ - port = serial->port[0]; - rport = serial->port[1]; -@@ -416,18 +408,31 @@ static int mct_u232_startup(struct usb_serial *serial) - return 0; - } /* mct_u232_startup */ - -+static int mct_u232_port_probe(struct usb_serial_port *port) -+{ -+ struct mct_u232_private *priv; -+ -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ spin_lock_init(&priv->lock); -+ init_waitqueue_head(&priv->msr_wait); -+ -+ usb_set_serial_port_data(port, priv); - --static void mct_u232_release(struct usb_serial *serial) -+ return 0; -+} -+ -+static int mct_u232_port_remove(struct usb_serial_port *port) - { - struct mct_u232_private *priv; -- int i; - -- for (i = 0; i < serial->num_ports; ++i) { -- /* My special items, the standard routines free my urbs */ -- priv = usb_get_serial_port_data(serial->port[i]); -- kfree(priv); -- } --} /* mct_u232_release */ -+ priv = usb_get_serial_port_data(port); -+ kfree(priv); -+ -+ return 0; -+} - - static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) - { -@@ -519,12 +524,14 @@ static void mct_u232_dtr_rts(struct usb_serial_port *port, int on) - - static void mct_u232_close(struct usb_serial_port *port) - { -- if (port->serial->dev) { -- /* shutdown our urbs */ -- usb_kill_urb(port->write_urb); -- usb_kill_urb(port->read_urb); -- usb_kill_urb(port->interrupt_in_urb); -- } -+ /* -+ * Must kill the read urb as it is actually an interrupt urb, which -+ * generic close thus fails to kill. -+ */ -+ usb_kill_urb(port->read_urb); -+ usb_kill_urb(port->interrupt_in_urb); -+ -+ usb_serial_generic_close(port); - } /* mct_u232_close */ - - -diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c -index d47eb06..d284fb8 100644 ---- a/drivers/usb/serial/metro-usb.c -+++ b/drivers/usb/serial/metro-usb.c -@@ -188,16 +188,13 @@ static void metrousb_cleanup(struct usb_serial_port *port) - { - dev_dbg(&port->dev, "%s\n", __func__); - -- if (port->serial->dev) { -- /* Shutdown any interrupt in urbs. */ -- if (port->interrupt_in_urb) { -- usb_unlink_urb(port->interrupt_in_urb); -- usb_kill_urb(port->interrupt_in_urb); -- } -- -- /* Send deactivate cmd to device */ -+ usb_unlink_urb(port->interrupt_in_urb); -+ usb_kill_urb(port->interrupt_in_urb); -+ -+ mutex_lock(&port->serial->disc_mutex); -+ if (!port->serial->disconnected) - metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); -- } -+ mutex_unlock(&port->serial->disc_mutex); - } - - static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) -@@ -280,51 +277,27 @@ static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int contr - return retval; - } - --static void metrousb_shutdown(struct usb_serial *serial) -+static int metrousb_port_probe(struct usb_serial_port *port) - { -- int i = 0; -+ struct metrousb_private *metro_priv; - -- dev_dbg(&serial->dev->dev, "%s\n", __func__); -+ metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL); -+ if (!metro_priv) -+ return -ENOMEM; - -- /* Stop reading and writing on all ports. */ -- for (i = 0; i < serial->num_ports; ++i) { -- /* Close any open urbs. */ -- metrousb_cleanup(serial->port[i]); -+ spin_lock_init(&metro_priv->lock); - -- /* Free memory. */ -- kfree(usb_get_serial_port_data(serial->port[i])); -- usb_set_serial_port_data(serial->port[i], NULL); -+ usb_set_serial_port_data(port, metro_priv); - -- dev_dbg(&serial->dev->dev, "%s - freed port number=%d\n", -- __func__, serial->port[i]->number); -- } -+ return 0; - } - --static int metrousb_startup(struct usb_serial *serial) -+static int metrousb_port_remove(struct usb_serial_port *port) - { - struct metrousb_private *metro_priv; -- struct usb_serial_port *port; -- int i = 0; - -- dev_dbg(&serial->dev->dev, "%s\n", __func__); -- -- /* Loop through the serial ports setting up the private structures. -- * Currently we only use one port. */ -- for (i = 0; i < serial->num_ports; ++i) { -- port = serial->port[i]; -- -- /* Declare memory. */ -- metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL); -- if (!metro_priv) -- return -ENOMEM; -- -- /* Initialize memory. */ -- spin_lock_init(&metro_priv->lock); -- usb_set_serial_port_data(port, metro_priv); -- -- dev_dbg(&serial->dev->dev, "%s - port number=%d\n ", -- __func__, port->number); -- } -+ metro_priv = usb_get_serial_port_data(port); -+ kfree(metro_priv); - - return 0; - } -@@ -423,8 +396,8 @@ static struct usb_serial_driver metrousb_device = { - .close = metrousb_cleanup, - .read_int_callback = metrousb_read_int_callback, - .write_int_callback = metrousb_write_int_callback, -- .attach = metrousb_startup, -- .release = metrousb_shutdown, -+ .port_probe = metrousb_port_probe, -+ .port_remove = metrousb_port_remove, - .throttle = metrousb_throttle, - .unthrottle = metrousb_unthrottle, - .tiocmget = metrousb_tiocmget, -diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c -index a07dd3c..eb84767 100644 ---- a/drivers/usb/serial/mos7720.c -+++ b/drivers/usb/serial/mos7720.c -@@ -2023,9 +2023,7 @@ static int mos7720_ioctl(struct tty_struct *tty, - - static int mos7720_startup(struct usb_serial *serial) - { -- struct moschip_port *mos7720_port; - struct usb_device *dev; -- int i; - char data; - u16 product; - int ret_val; -@@ -2063,29 +2061,6 @@ static int mos7720_startup(struct usb_serial *serial) - serial->port[1]->interrupt_in_buffer = NULL; - } - -- -- /* set up serial port private structures */ -- for (i = 0; i < serial->num_ports; ++i) { -- mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); -- if (mos7720_port == NULL) { -- dev_err(&dev->dev, "%s - Out of memory\n", __func__); -- return -ENOMEM; -- } -- -- /* Initialize all port interrupt end point to port 0 int -- * endpoint. Our device has only one interrupt endpoint -- * common to all ports */ -- serial->port[i]->interrupt_in_endpointAddress = -- serial->port[0]->interrupt_in_endpointAddress; -- -- mos7720_port->port = serial->port[i]; -- usb_set_serial_port_data(serial->port[i], mos7720_port); -- -- dbg("port number is %d", serial->port[i]->number); -- dbg("serial number is %d", serial->minor); -- } -- -- - /* setting configuration feature to one */ - usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); -@@ -2113,8 +2088,6 @@ static int mos7720_startup(struct usb_serial *serial) - - static void mos7720_release(struct usb_serial *serial) - { -- int i; -- - #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT - /* close the parallel port */ - -@@ -2153,9 +2126,36 @@ static void mos7720_release(struct usb_serial *serial) - kref_put(&mos_parport->ref_count, destroy_mos_parport); - } - #endif -- /* free private structure allocated for serial port */ -- for (i = 0; i < serial->num_ports; ++i) -- kfree(usb_get_serial_port_data(serial->port[i])); -+} -+ -+static int mos7720_port_probe(struct usb_serial_port *port) -+{ -+ struct moschip_port *mos7720_port; -+ -+ mos7720_port = kzalloc(sizeof(*mos7720_port), GFP_KERNEL); -+ if (!mos7720_port) -+ return -ENOMEM; -+ -+ /* Initialize all port interrupt end point to port 0 int endpoint. -+ * Our device has only one interrupt endpoint common to all ports. -+ */ -+ port->interrupt_in_endpointAddress = -+ port->serial->port[0]->interrupt_in_endpointAddress; -+ mos7720_port->port = port; -+ -+ usb_set_serial_port_data(port, mos7720_port); -+ -+ return 0; -+} -+ -+static int mos7720_port_remove(struct usb_serial_port *port) -+{ -+ struct moschip_port *mos7720_port; -+ -+ mos7720_port = usb_get_serial_port_data(port); -+ kfree(mos7720_port); -+ -+ return 0; - } - - static struct usb_serial_driver moschip7720_2port_driver = { -@@ -2173,6 +2173,8 @@ static struct usb_serial_driver moschip7720_2port_driver = { - .probe = mos77xx_probe, - .attach = mos7720_startup, - .release = mos7720_release, -+ .port_probe = mos7720_port_probe, -+ .port_remove = mos7720_port_remove, - .ioctl = mos7720_ioctl, - .tiocmget = mos7720_tiocmget, - .tiocmset = mos7720_tiocmset, -diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c -index 2f6da1e..52e5ca7 100644 ---- a/drivers/usb/serial/mos7840.c -+++ b/drivers/usb/serial/mos7840.c -@@ -218,12 +218,10 @@ struct moschip_port { - int port_num; /*Actual port number in the device(1,2,etc) */ - struct urb *write_urb; /* write URB for this port */ - struct urb *read_urb; /* read URB for this port */ -- struct urb *int_urb; - __u8 shadowLCR; /* last LCR value received */ - __u8 shadowMCR; /* last MCR value received */ - char open; - char open_ports; -- char zombie; - wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ - wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ - int delta_msr_cond; -@@ -493,7 +491,6 @@ static void mos7840_control_callback(struct urb *urb) - unsigned char *data; - struct moschip_port *mos7840_port; - __u8 regval = 0x0; -- int result = 0; - int status = urb->status; - - mos7840_port = urb->context; -@@ -512,7 +509,7 @@ static void mos7840_control_callback(struct urb *urb) - default: - dbg("%s - nonzero urb status received: %d", __func__, - status); -- goto exit; -+ return; - } - - dbg("%s urb buffer size is %d", __func__, urb->actual_length); -@@ -525,17 +522,6 @@ static void mos7840_control_callback(struct urb *urb) - mos7840_handle_new_msr(mos7840_port, regval); - else if (mos7840_port->MsrLsr == 1) - mos7840_handle_new_lsr(mos7840_port, regval); -- --exit: -- spin_lock(&mos7840_port->pool_lock); -- if (!mos7840_port->zombie) -- result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC); -- spin_unlock(&mos7840_port->pool_lock); -- if (result) { -- dev_err(&urb->dev->dev, -- "%s - Error %d submitting interrupt urb\n", -- __func__, result); -- } - } - - static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, -@@ -704,14 +690,7 @@ static void mos7840_interrupt_callback(struct urb *urb) - wreg = MODEM_STATUS_REGISTER; - break; - } -- spin_lock(&mos7840_port->pool_lock); -- if (!mos7840_port->zombie) { -- rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); -- } else { -- spin_unlock(&mos7840_port->pool_lock); -- return; -- } -- spin_unlock(&mos7840_port->pool_lock); -+ rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); - } - } - } -@@ -2684,7 +2663,6 @@ error: - kfree(mos7840_port->ctrl_buf); - usb_free_urb(mos7840_port->control_urb); - kfree(mos7840_port); -- serial->port[i] = NULL; - } - return status; - } -@@ -2714,9 +2692,6 @@ static void mos7840_disconnect(struct usb_serial *serial) - mos7840_port = mos7840_get_port_private(serial->port[i]); - dbg ("mos7840_port %d = %p", i, mos7840_port); - if (mos7840_port) { -- spin_lock_irqsave(&mos7840_port->pool_lock, flags); -- mos7840_port->zombie = 1; -- spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); - usb_kill_urb(mos7840_port->control_urb); - } - } -@@ -2754,6 +2729,7 @@ static void mos7840_release(struct usb_serial *serial) - del_timer_sync(&mos7840_port->led_timer1); - del_timer_sync(&mos7840_port->led_timer2); - } -+ usb_free_urb(mos7840_port->control_urb); - kfree(mos7840_port->ctrl_buf); - kfree(mos7840_port->dr); - kfree(mos7840_port); -diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c -index 6f3d705..27c9d06 100644 ---- a/drivers/usb/serial/omninet.c -+++ b/drivers/usb/serial/omninet.c -@@ -46,8 +46,8 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); - static int omninet_write_room(struct tty_struct *tty); - static void omninet_disconnect(struct usb_serial *serial); --static void omninet_release(struct usb_serial *serial); --static int omninet_attach(struct usb_serial *serial); -+static int omninet_port_probe(struct usb_serial_port *port); -+static int omninet_port_remove(struct usb_serial_port *port); - - static const struct usb_device_id id_table[] = { - { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, -@@ -64,7 +64,8 @@ static struct usb_serial_driver zyxel_omninet_device = { - .description = "ZyXEL - omni.net lcd plus usb", - .id_table = id_table, - .num_ports = 1, -- .attach = omninet_attach, -+ .port_probe = omninet_port_probe, -+ .port_remove = omninet_port_remove, - .open = omninet_open, - .close = omninet_close, - .write = omninet_write, -@@ -72,7 +73,6 @@ static struct usb_serial_driver zyxel_omninet_device = { - .read_bulk_callback = omninet_read_bulk_callback, - .write_bulk_callback = omninet_write_bulk_callback, - .disconnect = omninet_disconnect, -- .release = omninet_release, - }; - - static struct usb_serial_driver * const serial_drivers[] = { -@@ -114,18 +114,26 @@ struct omninet_data { - __u8 od_outseq; /* Sequence number for bulk_out URBs */ - }; - --static int omninet_attach(struct usb_serial *serial) -+static int omninet_port_probe(struct usb_serial_port *port) - { - struct omninet_data *od; -- struct usb_serial_port *port = serial->port[0]; - - od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL); -- if (!od) { -- dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", -- __func__, sizeof(struct omninet_data)); -+ if (!od) - return -ENOMEM; -- } -+ - usb_set_serial_port_data(port, od); -+ -+ return 0; -+} -+ -+static int omninet_port_remove(struct usb_serial_port *port) -+{ -+ struct omninet_data *od; -+ -+ od = usb_get_serial_port_data(port); -+ kfree(od); -+ - return 0; - } - -@@ -291,14 +299,6 @@ static void omninet_disconnect(struct usb_serial *serial) - usb_kill_urb(wport->write_urb); - } - -- --static void omninet_release(struct usb_serial *serial) --{ -- struct usb_serial_port *port = serial->port[0]; -- -- kfree(usb_get_serial_port_data(port)); --} -- - module_usb_serial_driver(serial_drivers, id_table); - - MODULE_AUTHOR(DRIVER_AUTHOR); -diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c -index 02cb1b7..623358a 100644 ---- a/drivers/usb/serial/opticon.c -+++ b/drivers/usb/serial/opticon.c -@@ -158,7 +158,11 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, - { - struct usb_serial *serial = port->serial; - int retval; -- u8 buffer[2]; -+ u8 *buffer; -+ -+ buffer = kzalloc(1, GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; - - buffer[0] = val; - /* Send the message to the vendor control endpoint -@@ -167,6 +171,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, - requesttype, - USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, - 0, 0, buffer, 1, 0); -+ kfree(buffer); - - return retval; - } -@@ -284,7 +289,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, - if (!dr) { - dev_err(&port->dev, "out of memory\n"); - count = -ENOMEM; -- goto error; -+ goto error_no_dr; - } - - dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; -@@ -314,6 +319,8 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, - - return count; - error: -+ kfree(dr); -+error_no_dr: - usb_free_urb(urb); - error_no_urb: - kfree(buffer); -diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c -index a0542ca..76a48e4 100644 ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -47,6 +47,7 @@ - /* Function prototypes */ - static int option_probe(struct usb_serial *serial, - const struct usb_device_id *id); -+static int option_attach(struct usb_serial *serial); - static void option_release(struct usb_serial *serial); - static int option_send_setup(struct usb_serial_port *port); - static void option_instat_callback(struct urb *urb); -@@ -1288,8 +1289,9 @@ static struct usb_serial_driver option_1port_device = { - .tiocmget = usb_wwan_tiocmget, - .tiocmset = usb_wwan_tiocmset, - .ioctl = usb_wwan_ioctl, -- .attach = usb_wwan_startup, -+ .attach = option_attach, - .release = option_release, -+ .port_probe = usb_wwan_port_probe, - .port_remove = usb_wwan_port_remove, - .read_int_callback = option_instat_callback, - #ifdef CONFIG_PM -@@ -1337,8 +1339,6 @@ static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, - static int option_probe(struct usb_serial *serial, - const struct usb_device_id *id) - { -- struct usb_wwan_intf_private *data; -- struct option_private *priv; - struct usb_interface_descriptor *iface_desc = - &serial->interface->cur_altsetting->desc; - struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; -@@ -1376,6 +1376,19 @@ static int option_probe(struct usb_serial *serial, - iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) - return -ENODEV; - -+ /* Store device id so we can use it during attach. */ -+ usb_set_serial_data(serial, (void *)id); -+ -+ return 0; -+} -+ -+static int option_attach(struct usb_serial *serial) -+{ -+ struct usb_interface_descriptor *iface_desc; -+ const struct usb_device_id *id; -+ struct usb_wwan_intf_private *data; -+ struct option_private *priv; -+ - data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); - if (!data) - return -ENOMEM; -@@ -1386,6 +1399,10 @@ static int option_probe(struct usb_serial *serial, - return -ENOMEM; - } - -+ /* Retrieve device id stored at probe. */ -+ id = usb_get_serial_data(serial); -+ iface_desc = &serial->interface->cur_altsetting->desc; -+ - priv->bInterfaceNumber = iface_desc->bInterfaceNumber; - data->private = priv; - -diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c -index bfd5077..93232ca 100644 ---- a/drivers/usb/serial/qcserial.c -+++ b/drivers/usb/serial/qcserial.c -@@ -140,7 +140,6 @@ MODULE_DEVICE_TABLE(usb, id_table); - - static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) - { -- struct usb_wwan_intf_private *data; - struct usb_host_interface *intf = serial->interface->cur_altsetting; - struct device *dev = &serial->dev->dev; - int retval = -ENODEV; -@@ -156,13 +155,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) - ifnum = intf->desc.bInterfaceNumber; - dev_dbg(dev, "This Interface = %d\n", ifnum); - -- data = kzalloc(sizeof(struct usb_wwan_intf_private), -- GFP_KERNEL); -- if (!data) -- return -ENOMEM; -- -- spin_lock_init(&data->susp_lock); -- - if (nintf == 1) { - /* QDL mode */ - /* Gobi 2000 has a single altsetting, older ones have two */ -@@ -255,20 +247,28 @@ done: - } - } - -- /* Set serial->private if not returning error */ -- if (retval == 0) -- usb_set_serial_data(serial, data); -- else -- kfree(data); -- - return retval; - } - -+static int qc_attach(struct usb_serial *serial) -+{ -+ struct usb_wwan_intf_private *data; -+ -+ data = kzalloc(sizeof(*data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ spin_lock_init(&data->susp_lock); -+ -+ usb_set_serial_data(serial, data); -+ -+ return 0; -+} -+ - static void qc_release(struct usb_serial *serial) - { - struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); - -- /* Free the private data allocated in qcprobe */ - usb_set_serial_data(serial, NULL); - kfree(priv); - } -@@ -287,8 +287,9 @@ static struct usb_serial_driver qcdevice = { - .write = usb_wwan_write, - .write_room = usb_wwan_write_room, - .chars_in_buffer = usb_wwan_chars_in_buffer, -- .attach = usb_wwan_startup, -+ .attach = qc_attach, - .release = qc_release, -+ .port_probe = usb_wwan_port_probe, - .port_remove = usb_wwan_port_remove, - #ifdef CONFIG_PM - .suspend = usb_wwan_suspend, -diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c -index 151670b..ea69301 100644 ---- a/drivers/usb/serial/quatech2.c -+++ b/drivers/usb/serial/quatech2.c -@@ -145,12 +145,12 @@ static void qt2_read_bulk_callback(struct urb *urb); - - static void qt2_release(struct usb_serial *serial) - { -- int i; -+ struct qt2_serial_private *serial_priv; - -- kfree(usb_get_serial_data(serial)); -+ serial_priv = usb_get_serial_data(serial); - -- for (i = 0; i < serial->num_ports; i++) -- kfree(usb_get_serial_port_data(serial->port[i])); -+ usb_free_urb(serial_priv->read_urb); -+ kfree(serial_priv); - } - - static inline int calc_baud_divisor(int baudrate) -@@ -425,11 +425,16 @@ static void qt2_close(struct usb_serial_port *port) - port_priv->is_open = false; - - spin_lock_irqsave(&port_priv->urb_lock, flags); -- if (port_priv->write_urb->status == -EINPROGRESS) -- usb_kill_urb(port_priv->write_urb); -+ usb_kill_urb(port_priv->write_urb); - port_priv->urb_in_use = false; - spin_unlock_irqrestore(&port_priv->urb_lock, flags); - -+ mutex_lock(&port->serial->disc_mutex); -+ if (port->serial->disconnected) { -+ mutex_unlock(&port->serial->disc_mutex); -+ return; -+ } -+ - /* flush the port transmit buffer */ - i = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), -@@ -461,26 +466,14 @@ static void qt2_close(struct usb_serial_port *port) - dev_err(&port->dev, "%s - close port failed %i\n", - __func__, i); - -+ mutex_unlock(&port->serial->disc_mutex); - } - - static void qt2_disconnect(struct usb_serial *serial) - { - struct qt2_serial_private *serial_priv = usb_get_serial_data(serial); -- struct qt2_port_private *port_priv; -- int i; -- -- if (serial_priv->read_urb->status == -EINPROGRESS) -- usb_kill_urb(serial_priv->read_urb); -- -- usb_free_urb(serial_priv->read_urb); - -- for (i = 0; i < serial->num_ports; i++) { -- port_priv = usb_get_serial_port_data(serial->port[i]); -- -- if (port_priv->write_urb->status == -EINPROGRESS) -- usb_kill_urb(port_priv->write_urb); -- usb_free_urb(port_priv->write_urb); -- } -+ usb_kill_urb(serial_priv->read_urb); - } - - static int get_serial_info(struct usb_serial_port *port, -@@ -775,11 +768,9 @@ static void qt2_read_bulk_callback(struct urb *urb) - - static int qt2_setup_urbs(struct usb_serial *serial) - { -- struct usb_serial_port *port; - struct usb_serial_port *port0; - struct qt2_serial_private *serial_priv; -- struct qt2_port_private *port_priv; -- int pcount, status; -+ int status; - - port0 = serial->port[0]; - -@@ -797,46 +788,21 @@ static int qt2_setup_urbs(struct usb_serial *serial) - sizeof(serial_priv->read_buffer), - qt2_read_bulk_callback, serial); - -- /* setup write_urb for each port */ -- for (pcount = 0; pcount < serial->num_ports; pcount++) { -- -- port = serial->port[pcount]; -- port_priv = usb_get_serial_port_data(port); -- -- port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); -- if (!port_priv->write_urb) { -- dev_err(&serial->dev->dev, -- "failed to alloc write_urb for port %i\n", -- pcount); -- return -ENOMEM; -- } -- -- usb_fill_bulk_urb(port_priv->write_urb, -- serial->dev, -- usb_sndbulkpipe(serial->dev, -- port0-> -- bulk_out_endpointAddress), -- port_priv->write_buffer, -- sizeof(port_priv->write_buffer), -- qt2_write_bulk_callback, port); -- } -- - status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); - if (status != 0) { - dev_err(&serial->dev->dev, - "%s - submit read urb failed %i\n", __func__, status); -+ usb_free_urb(serial_priv->read_urb); - return status; - } - - return 0; -- - } - - static int qt2_attach(struct usb_serial *serial) - { - struct qt2_serial_private *serial_priv; -- struct qt2_port_private *port_priv; -- int status, pcount; -+ int status; - - /* power on unit */ - status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), -@@ -856,26 +822,6 @@ static int qt2_attach(struct usb_serial *serial) - - usb_set_serial_data(serial, serial_priv); - -- for (pcount = 0; pcount < serial->num_ports; pcount++) { -- port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); -- if (!port_priv) { -- dev_err(&serial->dev->dev, -- "%s- kmalloc(%Zd) failed.\n", __func__, -- sizeof(*port_priv)); -- pcount--; -- status = -ENOMEM; -- goto attach_failed; -- } -- -- spin_lock_init(&port_priv->lock); -- spin_lock_init(&port_priv->urb_lock); -- init_waitqueue_head(&port_priv->delta_msr_wait); -- -- port_priv->port = serial->port[pcount]; -- -- usb_set_serial_port_data(serial->port[pcount], port_priv); -- } -- - status = qt2_setup_urbs(serial); - if (status != 0) - goto attach_failed; -@@ -883,14 +829,53 @@ static int qt2_attach(struct usb_serial *serial) - return 0; - - attach_failed: -- for (/* empty */; pcount >= 0; pcount--) { -- port_priv = usb_get_serial_port_data(serial->port[pcount]); -- kfree(port_priv); -- } - kfree(serial_priv); - return status; - } - -+static int qt2_port_probe(struct usb_serial_port *port) -+{ -+ struct usb_serial *serial = port->serial; -+ struct qt2_port_private *port_priv; -+ u8 bEndpointAddress; -+ -+ port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); -+ if (!port_priv) -+ return -ENOMEM; -+ -+ spin_lock_init(&port_priv->lock); -+ spin_lock_init(&port_priv->urb_lock); -+ init_waitqueue_head(&port_priv->delta_msr_wait); -+ port_priv->port = port; -+ -+ port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); -+ if (!port_priv->write_urb) { -+ kfree(port_priv); -+ return -ENOMEM; -+ } -+ bEndpointAddress = serial->port[0]->bulk_out_endpointAddress; -+ usb_fill_bulk_urb(port_priv->write_urb, serial->dev, -+ usb_sndbulkpipe(serial->dev, bEndpointAddress), -+ port_priv->write_buffer, -+ sizeof(port_priv->write_buffer), -+ qt2_write_bulk_callback, port); -+ -+ usb_set_serial_port_data(port, port_priv); -+ -+ return 0; -+} -+ -+static int qt2_port_remove(struct usb_serial_port *port) -+{ -+ struct qt2_port_private *port_priv; -+ -+ port_priv = usb_get_serial_port_data(port); -+ usb_free_urb(port_priv->write_urb); -+ kfree(port_priv); -+ -+ return 0; -+} -+ - static int qt2_tiocmget(struct tty_struct *tty) - { - struct usb_serial_port *port = tty->driver_data; -@@ -1129,6 +1114,8 @@ static struct usb_serial_driver qt2_device = { - .attach = qt2_attach, - .release = qt2_release, - .disconnect = qt2_disconnect, -+ .port_probe = qt2_port_probe, -+ .port_remove = qt2_port_remove, - .dtr_rts = qt2_dtr_rts, - .break_ctl = qt2_break_ctl, - .tiocmget = qt2_tiocmget, -diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c -index 0274710..cf6d149 100644 ---- a/drivers/usb/serial/sierra.c -+++ b/drivers/usb/serial/sierra.c -@@ -162,7 +162,6 @@ static int sierra_probe(struct usb_serial *serial, - { - int result = 0; - struct usb_device *udev; -- struct sierra_intf_private *data; - u8 ifnum; - - udev = serial->dev; -@@ -189,11 +188,6 @@ static int sierra_probe(struct usb_serial *serial, - return -ENODEV; - } - -- data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL); -- if (!data) -- return -ENOMEM; -- spin_lock_init(&data->susp_lock); -- - return result; - } - -@@ -886,11 +880,15 @@ static void sierra_dtr_rts(struct usb_serial_port *port, int on) - - static int sierra_startup(struct usb_serial *serial) - { -- struct usb_serial_port *port; -- struct sierra_port_private *portdata; -- struct sierra_iface_info *himemoryp = NULL; -- int i; -- u8 ifnum; -+ struct sierra_intf_private *intfdata; -+ -+ intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL); -+ if (!intfdata) -+ return -ENOMEM; -+ -+ spin_lock_init(&intfdata->susp_lock); -+ -+ usb_set_serial_data(serial, intfdata); - - /* Set Device mode to D0 */ - sierra_set_power_state(serial->dev, 0x0000); -@@ -899,68 +897,71 @@ static int sierra_startup(struct usb_serial *serial) - if (nmea) - sierra_vsc_set_nmea(serial->dev, 1); - -- /* Now setup per port private data */ -- for (i = 0; i < serial->num_ports; i++) { -- port = serial->port[i]; -- portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); -- if (!portdata) { -- dev_dbg(&port->dev, "%s: kmalloc for " -- "sierra_port_private (%d) failed!\n", -- __func__, i); -- return -ENOMEM; -- } -- spin_lock_init(&portdata->lock); -- init_usb_anchor(&portdata->active); -- init_usb_anchor(&portdata->delayed); -- ifnum = i; -- /* Assume low memory requirements */ -- portdata->num_out_urbs = N_OUT_URB; -- portdata->num_in_urbs = N_IN_URB; -- -- /* Determine actual memory requirements */ -- if (serial->num_ports == 1) { -- /* Get interface number for composite device */ -- ifnum = sierra_calc_interface(serial); -- himemoryp = -- (struct sierra_iface_info *)&typeB_interface_list; -- if (is_himemory(ifnum, himemoryp)) { -- portdata->num_out_urbs = N_OUT_URB_HM; -- portdata->num_in_urbs = N_IN_URB_HM; -- } -- } -- else { -- himemoryp = -- (struct sierra_iface_info *)&typeA_interface_list; -- if (is_himemory(i, himemoryp)) { -- portdata->num_out_urbs = N_OUT_URB_HM; -- portdata->num_in_urbs = N_IN_URB_HM; -- } -- } -- dev_dbg(&serial->dev->dev, -- "Memory usage (urbs) interface #%d, in=%d, out=%d\n", -- ifnum,portdata->num_in_urbs, portdata->num_out_urbs ); -- /* Set the port private data pointer */ -- usb_set_serial_port_data(port, portdata); -- } -- - return 0; - } - - static void sierra_release(struct usb_serial *serial) - { -- int i; -- struct usb_serial_port *port; -+ struct sierra_intf_private *intfdata; -+ -+ intfdata = usb_get_serial_data(serial); -+ kfree(intfdata); -+} -+ -+static int sierra_port_probe(struct usb_serial_port *port) -+{ -+ struct usb_serial *serial = port->serial; - struct sierra_port_private *portdata; -+ const struct sierra_iface_info *himemoryp; -+ u8 ifnum; - -- for (i = 0; i < serial->num_ports; ++i) { -- port = serial->port[i]; -- if (!port) -- continue; -- portdata = usb_get_serial_port_data(port); -- if (!portdata) -- continue; -- kfree(portdata); -+ portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); -+ if (!portdata) -+ return -ENOMEM; -+ -+ spin_lock_init(&portdata->lock); -+ init_usb_anchor(&portdata->active); -+ init_usb_anchor(&portdata->delayed); -+ -+ /* Assume low memory requirements */ -+ portdata->num_out_urbs = N_OUT_URB; -+ portdata->num_in_urbs = N_IN_URB; -+ -+ /* Determine actual memory requirements */ -+ if (serial->num_ports == 1) { -+ /* Get interface number for composite device */ -+ ifnum = sierra_calc_interface(serial); -+ himemoryp = &typeB_interface_list; -+ } else { -+ /* This is really the usb-serial port number of the interface -+ * rather than the interface number. -+ */ -+ ifnum = port->number - serial->minor; -+ himemoryp = &typeA_interface_list; - } -+ -+ if (is_himemory(ifnum, himemoryp)) { -+ portdata->num_out_urbs = N_OUT_URB_HM; -+ portdata->num_in_urbs = N_IN_URB_HM; -+ } -+ -+ dev_dbg(&port->dev, -+ "Memory usage (urbs) interface #%d, in=%d, out=%d\n", -+ ifnum, portdata->num_in_urbs, portdata->num_out_urbs); -+ -+ usb_set_serial_port_data(port, portdata); -+ -+ return 0; -+} -+ -+static int sierra_port_remove(struct usb_serial_port *port) -+{ -+ struct sierra_port_private *portdata; -+ -+ portdata = usb_get_serial_port_data(port); -+ kfree(portdata); -+ -+ return 0; - } - - #ifdef CONFIG_PM -@@ -1064,6 +1065,8 @@ static struct usb_serial_driver sierra_device = { - .tiocmset = sierra_tiocmset, - .attach = sierra_startup, - .release = sierra_release, -+ .port_probe = sierra_port_probe, -+ .port_remove = sierra_port_remove, - .suspend = sierra_suspend, - .resume = sierra_resume, - .read_int_callback = sierra_instat_callback, -diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h -index 1f034d2..684739b 100644 ---- a/drivers/usb/serial/usb-wwan.h -+++ b/drivers/usb/serial/usb-wwan.h -@@ -8,7 +8,7 @@ - extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); - extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); - extern void usb_wwan_close(struct usb_serial_port *port); --extern int usb_wwan_startup(struct usb_serial *serial); -+extern int usb_wwan_port_probe(struct usb_serial_port *port); - extern int usb_wwan_port_remove(struct usb_serial_port *port); - extern int usb_wwan_write_room(struct tty_struct *tty); - extern void usb_wwan_set_termios(struct tty_struct *tty, -diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c -index 6855d5e..2f2d074 100644 ---- a/drivers/usb/serial/usb_wwan.c -+++ b/drivers/usb/serial/usb_wwan.c -@@ -447,10 +447,12 @@ void usb_wwan_close(struct usb_serial_port *port) - EXPORT_SYMBOL(usb_wwan_close); - - /* Helper functions used by usb_wwan_setup_urbs */ --static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, -+static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, -+ int endpoint, - int dir, void *ctx, char *buf, int len, - void (*callback) (struct urb *)) - { -+ struct usb_serial *serial = port->serial; - struct urb *urb; - - if (endpoint == -1) -@@ -470,100 +472,74 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, - return urb; - } - --/* Setup urbs */ --static void usb_wwan_setup_urbs(struct usb_serial *serial) -+int usb_wwan_port_probe(struct usb_serial_port *port) - { -- int i, j; -- struct usb_serial_port *port; - struct usb_wwan_port_private *portdata; -+ struct urb *urb; -+ u8 *buffer; -+ int err; -+ int i; - -- for (i = 0; i < serial->num_ports; i++) { -- port = serial->port[i]; -- portdata = usb_get_serial_port_data(port); -- -- /* Do indat endpoints first */ -- for (j = 0; j < N_IN_URB; ++j) { -- portdata->in_urbs[j] = usb_wwan_setup_urb(serial, -- port-> -- bulk_in_endpointAddress, -- USB_DIR_IN, -- port, -- portdata-> -- in_buffer[j], -- IN_BUFLEN, -- usb_wwan_indat_callback); -- } -- -- /* outdat endpoints */ -- for (j = 0; j < N_OUT_URB; ++j) { -- portdata->out_urbs[j] = usb_wwan_setup_urb(serial, -- port-> -- bulk_out_endpointAddress, -- USB_DIR_OUT, -- port, -- portdata-> -- out_buffer -- [j], -- OUT_BUFLEN, -- usb_wwan_outdat_callback); -- } -- } --} -+ portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); -+ if (!portdata) -+ return -ENOMEM; - --int usb_wwan_startup(struct usb_serial *serial) --{ -- int i, j, err; -- struct usb_serial_port *port; -- struct usb_wwan_port_private *portdata; -- u8 *buffer; -+ init_usb_anchor(&portdata->delayed); - -- /* Now setup per port private data */ -- for (i = 0; i < serial->num_ports; i++) { -- port = serial->port[i]; -- portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); -- if (!portdata) { -- dbg("%s: kmalloc for usb_wwan_port_private (%d) failed!.", -- __func__, i); -- return 1; -- } -- init_usb_anchor(&portdata->delayed); -+ for (i = 0; i < N_IN_URB; i++) { -+ buffer = (u8 *)__get_free_page(GFP_KERNEL); -+ if (!buffer) -+ goto bail_out_error; -+ portdata->in_buffer[i] = buffer; -+ -+ urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress, -+ USB_DIR_IN, port, -+ buffer, IN_BUFLEN, -+ usb_wwan_indat_callback); -+ portdata->in_urbs[i] = urb; -+ } -+ for (i = 0; i < N_OUT_URB; i++) { -+ if (port->bulk_out_endpointAddress == -1) -+ continue; - -- for (j = 0; j < N_IN_URB; j++) { -- buffer = (u8 *) __get_free_page(GFP_KERNEL); -- if (!buffer) -- goto bail_out_error; -- portdata->in_buffer[j] = buffer; -- } -+ buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); -+ if (!buffer) -+ goto bail_out_error2; -+ portdata->out_buffer[i] = buffer; - -- for (j = 0; j < N_OUT_URB; j++) { -- buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); -- if (!buffer) -- goto bail_out_error2; -- portdata->out_buffer[j] = buffer; -- } -+ urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress, -+ USB_DIR_OUT, port, -+ buffer, OUT_BUFLEN, -+ usb_wwan_outdat_callback); -+ portdata->out_urbs[i] = urb; -+ } - -- usb_set_serial_port_data(port, portdata); -+ usb_set_serial_port_data(port, portdata); - -- if (!port->interrupt_in_urb) -- continue; -+ if (port->interrupt_in_urb) { - err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (err) -- dbg("%s: submit irq_in urb failed %d", __func__, err); -+ dev_dbg(&port->dev, "%s: submit irq_in urb failed %d\n", -+ __func__, err); - } -- usb_wwan_setup_urbs(serial); -+ - return 0; - - bail_out_error2: -- for (j = 0; j < N_OUT_URB; j++) -- kfree(portdata->out_buffer[j]); -+ for (i = 0; i < N_OUT_URB; i++) { -+ usb_free_urb(portdata->out_urbs[i]); -+ kfree(portdata->out_buffer[i]); -+ } - bail_out_error: -- for (j = 0; j < N_IN_URB; j++) -- if (portdata->in_buffer[j]) -- free_page((unsigned long)portdata->in_buffer[j]); -+ for (i = 0; i < N_IN_URB; i++) { -+ usb_free_urb(portdata->in_urbs[i]); -+ free_page((unsigned long)portdata->in_buffer[i]); -+ } - kfree(portdata); -- return 1; -+ -+ return -ENOMEM; - } --EXPORT_SYMBOL(usb_wwan_startup); -+EXPORT_SYMBOL_GPL(usb_wwan_port_probe); - - int usb_wwan_port_remove(struct usb_serial_port *port) - { -diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c -index 473635e..bd36321 100644 ---- a/drivers/usb/serial/whiteheat.c -+++ b/drivers/usb/serial/whiteheat.c -@@ -86,6 +86,8 @@ static int whiteheat_firmware_attach(struct usb_serial *serial); - /* function prototypes for the Connect Tech WhiteHEAT serial converter */ - static int whiteheat_attach(struct usb_serial *serial); - static void whiteheat_release(struct usb_serial *serial); -+static int whiteheat_port_probe(struct usb_serial_port *port); -+static int whiteheat_port_remove(struct usb_serial_port *port); - static int whiteheat_open(struct tty_struct *tty, - struct usb_serial_port *port); - static void whiteheat_close(struct usb_serial_port *port); -@@ -120,6 +122,8 @@ static struct usb_serial_driver whiteheat_device = { - .num_ports = 4, - .attach = whiteheat_attach, - .release = whiteheat_release, -+ .port_probe = whiteheat_port_probe, -+ .port_remove = whiteheat_port_remove, - .open = whiteheat_open, - .close = whiteheat_close, - .ioctl = whiteheat_ioctl, -@@ -290,15 +294,12 @@ static int whiteheat_attach(struct usb_serial *serial) - { - struct usb_serial_port *command_port; - struct whiteheat_command_private *command_info; -- struct usb_serial_port *port; -- struct whiteheat_private *info; - struct whiteheat_hw_info *hw_info; - int pipe; - int ret; - int alen; - __u8 *command; - __u8 *result; -- int i; - - command_port = serial->port[COMMAND_PORT]; - -@@ -357,22 +358,6 @@ static int whiteheat_attach(struct usb_serial *serial) - serial->type->description, - hw_info->sw_major_rev, hw_info->sw_minor_rev); - -- for (i = 0; i < serial->num_ports; i++) { -- port = serial->port[i]; -- -- info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); -- if (info == NULL) { -- dev_err(&port->dev, -- "%s: Out of memory for port structures\n", -- serial->type->description); -- goto no_private; -- } -- -- info->mcr = 0; -- -- usb_set_serial_port_data(port, info); -- } -- - command_info = kmalloc(sizeof(struct whiteheat_command_private), - GFP_KERNEL); - if (command_info == NULL) { -@@ -405,16 +390,10 @@ no_firmware: - "%s: please contact support@connecttech.com\n", - serial->type->description); - kfree(result); -+ kfree(command); - return -ENODEV; - - no_command_private: -- for (i = serial->num_ports - 1; i >= 0; i--) { -- port = serial->port[i]; -- info = usb_get_serial_port_data(port); -- kfree(info); --no_private: -- ; -- } - kfree(result); - no_result_buffer: - kfree(command); -@@ -422,21 +401,36 @@ no_command_buffer: - return -ENOMEM; - } - -- - static void whiteheat_release(struct usb_serial *serial) - { - struct usb_serial_port *command_port; -- struct whiteheat_private *info; -- int i; - - /* free up our private data for our command port */ - command_port = serial->port[COMMAND_PORT]; - kfree(usb_get_serial_port_data(command_port)); -+} - -- for (i = 0; i < serial->num_ports; i++) { -- info = usb_get_serial_port_data(serial->port[i]); -- kfree(info); -- } -+static int whiteheat_port_probe(struct usb_serial_port *port) -+{ -+ struct whiteheat_private *info; -+ -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) -+ return -ENOMEM; -+ -+ usb_set_serial_port_data(port, info); -+ -+ return 0; -+} -+ -+static int whiteheat_port_remove(struct usb_serial_port *port) -+{ -+ struct whiteheat_private *info; -+ -+ info = usb_get_serial_port_data(port); -+ kfree(info); -+ -+ return 0; - } - - static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port) -diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h -index 62a31be..8f98c9a 100644 ---- a/drivers/usb/storage/unusual_devs.h -+++ b/drivers/usb/storage/unusual_devs.h -@@ -1004,6 +1004,12 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999, - USB_SC_8070, USB_PR_CB, NULL, - US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), - -+/* Submitted by Oleksandr Chumachenko */ -+UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100, -+ "Casio", -+ "EX-N1 DigitalCamera", -+ USB_SC_8070, USB_PR_DEVICE, NULL, 0), -+ - /* Submitted by Hartmut Wahl */ - UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, - "Samsung", -diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c -index 072cbba..7f93f34 100644 ---- a/drivers/vhost/net.c -+++ b/drivers/vhost/net.c -@@ -379,7 +379,8 @@ static void handle_rx(struct vhost_net *net) - .hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE - }; - size_t total_len = 0; -- int err, headcount, mergeable; -+ int err, mergeable; -+ s16 headcount; - size_t vhost_hlen, sock_hlen; - size_t vhost_len, sock_len; - /* TODO: check that we are running from vhost_worker? */ -diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c -index debdfe0..5d2069f 100644 ---- a/fs/compat_ioctl.c -+++ b/fs/compat_ioctl.c -@@ -210,6 +210,8 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, - - err = get_user(palp, &up->palette); - err |= get_user(length, &up->length); -+ if (err) -+ return -EFAULT; - - up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); - err = put_user(compat_ptr(palp), &up_native->palette); -diff --git a/fs/exec.c b/fs/exec.c -index 574cf4d..fab2c6d 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -1110,7 +1110,8 @@ int flush_old_exec(struct linux_binprm * bprm) - bprm->mm = NULL; /* We're using it now */ - - set_fs(USER_DS); -- current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD); -+ current->flags &= -+ ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | PF_NOFREEZE); - flush_thread(); - current->personality &= ~bprm->per_clear; - -diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c -index e4fb3ba..3d7e09b 100644 ---- a/fs/lockd/mon.c -+++ b/fs/lockd/mon.c -@@ -85,29 +85,38 @@ static struct rpc_clnt *nsm_create(struct net *net) - return rpc_create(&args); - } - -+static struct rpc_clnt *nsm_client_set(struct lockd_net *ln, -+ struct rpc_clnt *clnt) -+{ -+ spin_lock(&ln->nsm_clnt_lock); -+ if (ln->nsm_users == 0) { -+ if (clnt == NULL) -+ goto out; -+ ln->nsm_clnt = clnt; -+ } -+ clnt = ln->nsm_clnt; -+ ln->nsm_users++; -+out: -+ spin_unlock(&ln->nsm_clnt_lock); -+ return clnt; -+} -+ - static struct rpc_clnt *nsm_client_get(struct net *net) - { -- static DEFINE_MUTEX(nsm_create_mutex); -- struct rpc_clnt *clnt; -+ struct rpc_clnt *clnt, *new; - struct lockd_net *ln = net_generic(net, lockd_net_id); - -- spin_lock(&ln->nsm_clnt_lock); -- if (ln->nsm_users) { -- ln->nsm_users++; -- clnt = ln->nsm_clnt; -- spin_unlock(&ln->nsm_clnt_lock); -+ clnt = nsm_client_set(ln, NULL); -+ if (clnt != NULL) - goto out; -- } -- spin_unlock(&ln->nsm_clnt_lock); - -- mutex_lock(&nsm_create_mutex); -- clnt = nsm_create(net); -- if (!IS_ERR(clnt)) { -- ln->nsm_clnt = clnt; -- smp_wmb(); -- ln->nsm_users = 1; -- } -- mutex_unlock(&nsm_create_mutex); -+ clnt = new = nsm_create(net); -+ if (IS_ERR(clnt)) -+ goto out; -+ -+ clnt = nsm_client_set(ln, new); -+ if (clnt != new) -+ rpc_shutdown_client(new); - out: - return clnt; - } -@@ -115,18 +124,16 @@ out: - static void nsm_client_put(struct net *net) - { - struct lockd_net *ln = net_generic(net, lockd_net_id); -- struct rpc_clnt *clnt = ln->nsm_clnt; -- int shutdown = 0; -+ struct rpc_clnt *clnt = NULL; - - spin_lock(&ln->nsm_clnt_lock); -- if (ln->nsm_users) { -- if (--ln->nsm_users) -- ln->nsm_clnt = NULL; -- shutdown = !ln->nsm_users; -+ ln->nsm_users--; -+ if (ln->nsm_users == 0) { -+ clnt = ln->nsm_clnt; -+ ln->nsm_clnt = NULL; - } - spin_unlock(&ln->nsm_clnt_lock); -- -- if (shutdown) -+ if (clnt != NULL) - rpc_shutdown_client(clnt); - } - -diff --git a/fs/namei.c b/fs/namei.c -index 81bd546..091c4b7 100644 ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -651,8 +651,8 @@ static inline void put_link(struct nameidata *nd, struct path *link, void *cooki - path_put(link); - } - --int sysctl_protected_symlinks __read_mostly = 1; --int sysctl_protected_hardlinks __read_mostly = 1; -+int sysctl_protected_symlinks __read_mostly = 0; -+int sysctl_protected_hardlinks __read_mostly = 0; - - /** - * may_follow_link - Check symlink following for unsafe situations -diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c -index f3d16ad..1093968 100644 ---- a/fs/nfs/blocklayout/blocklayout.c -+++ b/fs/nfs/blocklayout/blocklayout.c -@@ -242,14 +242,6 @@ bl_end_par_io_read(void *data, int unused) - schedule_work(&rdata->task.u.tk_work); - } - --static bool --bl_check_alignment(u64 offset, u32 len, unsigned long blkmask) --{ -- if ((offset & blkmask) || (len & blkmask)) -- return false; -- return true; --} -- - static enum pnfs_try_status - bl_read_pagelist(struct nfs_read_data *rdata) - { -@@ -260,15 +252,15 @@ bl_read_pagelist(struct nfs_read_data *rdata) - sector_t isect, extent_length = 0; - struct parallel_io *par; - loff_t f_offset = rdata->args.offset; -+ size_t bytes_left = rdata->args.count; -+ unsigned int pg_offset, pg_len; - struct page **pages = rdata->args.pages; - int pg_index = rdata->args.pgbase >> PAGE_CACHE_SHIFT; -+ const bool is_dio = (header->dreq != NULL); - - dprintk("%s enter nr_pages %u offset %lld count %u\n", __func__, - rdata->pages.npages, f_offset, (unsigned int)rdata->args.count); - -- if (!bl_check_alignment(f_offset, rdata->args.count, PAGE_CACHE_MASK)) -- goto use_mds; -- - par = alloc_parallel(rdata); - if (!par) - goto use_mds; -@@ -298,36 +290,53 @@ bl_read_pagelist(struct nfs_read_data *rdata) - extent_length = min(extent_length, cow_length); - } - } -+ -+ if (is_dio) { -+ pg_offset = f_offset & ~PAGE_CACHE_MASK; -+ if (pg_offset + bytes_left > PAGE_CACHE_SIZE) -+ pg_len = PAGE_CACHE_SIZE - pg_offset; -+ else -+ pg_len = bytes_left; -+ -+ f_offset += pg_len; -+ bytes_left -= pg_len; -+ isect += (pg_offset >> SECTOR_SHIFT); -+ } else { -+ pg_offset = 0; -+ pg_len = PAGE_CACHE_SIZE; -+ } -+ - hole = is_hole(be, isect); - if (hole && !cow_read) { - bio = bl_submit_bio(READ, bio); - /* Fill hole w/ zeroes w/o accessing device */ - dprintk("%s Zeroing page for hole\n", __func__); -- zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE); -+ zero_user_segment(pages[i], pg_offset, pg_len); - print_page(pages[i]); - SetPageUptodate(pages[i]); - } else { - struct pnfs_block_extent *be_read; - - be_read = (hole && cow_read) ? cow_read : be; -- bio = bl_add_page_to_bio(bio, rdata->pages.npages - i, -+ bio = do_add_page_to_bio(bio, rdata->pages.npages - i, - READ, - isect, pages[i], be_read, -- bl_end_io_read, par); -+ bl_end_io_read, par, -+ pg_offset, pg_len); - if (IS_ERR(bio)) { - header->pnfs_error = PTR_ERR(bio); - bio = NULL; - goto out; - } - } -- isect += PAGE_CACHE_SECTORS; -+ isect += (pg_len >> SECTOR_SHIFT); - extent_length -= PAGE_CACHE_SECTORS; - } - if ((isect << SECTOR_SHIFT) >= header->inode->i_size) { - rdata->res.eof = 1; -- rdata->res.count = header->inode->i_size - f_offset; -+ rdata->res.count = header->inode->i_size - rdata->args.offset; - } else { -- rdata->res.count = (isect << SECTOR_SHIFT) - f_offset; -+ rdata->res.count = (isect << SECTOR_SHIFT) - rdata->args.offset; - } - out: - bl_put_extent(be); -@@ -688,10 +697,13 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync) - NFS_SERVER(header->inode)->pnfs_blksize >> PAGE_CACHE_SHIFT; - - dprintk("%s enter, %Zu@%lld\n", __func__, count, offset); -- /* Check for alignment first */ -- if (!bl_check_alignment(offset, count, PAGE_CACHE_MASK)) -- goto out_mds; - -+ if (header->dreq != NULL && -+ (!IS_ALIGNED(offset, NFS_SERVER(header->inode)->pnfs_blksize) || -+ !IS_ALIGNED(count, NFS_SERVER(header->inode)->pnfs_blksize))) { -+ dprintk("pnfsblock nonblock aligned DIO writes. Resend MDS\n"); -+ goto out_mds; -+ } - /* At this point, wdata->pages is a (sequential) list of nfs_pages. - * We want to write each, and if there is an error set pnfs_error - * to have it redone using nfs. -@@ -1164,33 +1176,64 @@ bl_clear_layoutdriver(struct nfs_server *server) - return 0; - } - -+static bool -+is_aligned_req(struct nfs_page *req, unsigned int alignment) -+{ -+ return IS_ALIGNED(req->wb_offset, alignment) && -+ IS_ALIGNED(req->wb_bytes, alignment); -+} -+ - static void - bl_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) - { -- if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK)) -+ if (pgio->pg_dreq != NULL && -+ !is_aligned_req(req, SECTOR_SIZE)) - nfs_pageio_reset_read_mds(pgio); - else - pnfs_generic_pg_init_read(pgio, req); - } - --static void -+static bool -+bl_pg_test_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, -+ struct nfs_page *req) -+{ -+ if (pgio->pg_dreq != NULL && -+ !is_aligned_req(req, SECTOR_SIZE)) -+ return false; -+ -+ return pnfs_generic_pg_test(pgio, prev, req); -+} -+ -+void - bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) - { -- if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK)) -+ if (pgio->pg_dreq != NULL && -+ !is_aligned_req(req, PAGE_CACHE_SIZE)) - nfs_pageio_reset_write_mds(pgio); - else - pnfs_generic_pg_init_write(pgio, req); - } - -+static bool -+bl_pg_test_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, -+ struct nfs_page *req) -+{ -+ if (pgio->pg_dreq != NULL && -+ !is_aligned_req(req, PAGE_CACHE_SIZE)) -+ return false; -+ -+ return pnfs_generic_pg_test(pgio, prev, req); -+} -+ - static const struct nfs_pageio_ops bl_pg_read_ops = { - .pg_init = bl_pg_init_read, -- .pg_test = pnfs_generic_pg_test, -+ .pg_test = bl_pg_test_read, - .pg_doio = pnfs_generic_pg_readpages, - }; - - static const struct nfs_pageio_ops bl_pg_write_ops = { - .pg_init = bl_pg_init_write, -- .pg_test = pnfs_generic_pg_test, -+ .pg_test = bl_pg_test_write, - .pg_doio = pnfs_generic_pg_writepages, - }; - -diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c -index 6b0bb00..2fbdff6 100644 ---- a/fs/sysfs/dir.c -+++ b/fs/sysfs/dir.c -@@ -485,20 +485,18 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) - /** - * sysfs_pathname - return full path to sysfs dirent - * @sd: sysfs_dirent whose path we want -- * @path: caller allocated buffer -+ * @path: caller allocated buffer of size PATH_MAX - * - * Gives the name "/" to the sysfs_root entry; any path returned - * is relative to wherever sysfs is mounted. -- * -- * XXX: does no error checking on @path size - */ - static char *sysfs_pathname(struct sysfs_dirent *sd, char *path) - { - if (sd->s_parent) { - sysfs_pathname(sd->s_parent, path); -- strcat(path, "/"); -+ strlcat(path, "/", PATH_MAX); - } -- strcat(path, sd->s_name); -+ strlcat(path, sd->s_name, PATH_MAX); - return path; - } - -@@ -531,9 +529,11 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) - char *path = kzalloc(PATH_MAX, GFP_KERNEL); - WARN(1, KERN_WARNING - "sysfs: cannot create duplicate filename '%s'\n", -- (path == NULL) ? sd->s_name : -- strcat(strcat(sysfs_pathname(acxt->parent_sd, path), "/"), -- sd->s_name)); -+ (path == NULL) ? sd->s_name -+ : (sysfs_pathname(acxt->parent_sd, path), -+ strlcat(path, "/", PATH_MAX), -+ strlcat(path, sd->s_name, PATH_MAX), -+ path)); - kfree(path); - } - -diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h -index c78bb99..af1cbaf 100644 ---- a/include/drm/drm_pciids.h -+++ b/include/drm/drm_pciids.h -@@ -205,6 +205,8 @@ - {0x1002, 0x6788, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x678A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6790, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6791, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6792, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6798, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6799, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x679A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ -@@ -217,6 +219,7 @@ - {0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ -+ {0x1002, 0x6811, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6816, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6817, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ -diff --git a/include/linux/efi.h b/include/linux/efi.h -index ec45ccd..5782114 100644 ---- a/include/linux/efi.h -+++ b/include/linux/efi.h -@@ -496,6 +496,11 @@ extern void efi_map_pal_code (void); - extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg); - extern void efi_gettimeofday (struct timespec *ts); - extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */ -+#ifdef CONFIG_X86 -+extern void efi_free_boot_services(void); -+#else -+static inline void efi_free_boot_services(void) {} -+#endif - extern u64 efi_get_iobase (void); - extern u32 efi_mem_type (unsigned long phys_addr); - extern u64 efi_mem_attributes (unsigned long phys_addr); -diff --git a/include/linux/memblock.h b/include/linux/memblock.h -index 19dc455..c948c44 100644 ---- a/include/linux/memblock.h -+++ b/include/linux/memblock.h -@@ -57,6 +57,7 @@ int memblock_add(phys_addr_t base, phys_addr_t size); - int memblock_remove(phys_addr_t base, phys_addr_t size); - int memblock_free(phys_addr_t base, phys_addr_t size); - int memblock_reserve(phys_addr_t base, phys_addr_t size); -+void memblock_trim_memory(phys_addr_t align); - - #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP - void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, -diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h -index 3d254e1..f10553c 100644 ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -1217,6 +1217,7 @@ struct cfg80211_deauth_request { - const u8 *ie; - size_t ie_len; - u16 reason_code; -+ bool local_state_change; - }; - - /** -diff --git a/init/main.c b/init/main.c -index b286730..d61ec54 100644 ---- a/init/main.c -+++ b/init/main.c -@@ -631,6 +631,9 @@ asmlinkage void __init start_kernel(void) - acpi_early_init(); /* before LAPIC and SMP init */ - sfi_init_late(); - -+ if (efi_enabled) -+ efi_free_boot_services(); -+ - ftrace_init(); - - /* Do the rest non-__init'ed, we're now alive */ -diff --git a/lib/genalloc.c b/lib/genalloc.c -index 6bc04aa..7cb7a5d 100644 ---- a/lib/genalloc.c -+++ b/lib/genalloc.c -@@ -176,7 +176,7 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy - struct gen_pool_chunk *chunk; - int nbits = size >> pool->min_alloc_order; - int nbytes = sizeof(struct gen_pool_chunk) + -- (nbits + BITS_PER_BYTE - 1) / BITS_PER_BYTE; -+ BITS_TO_LONGS(nbits) * sizeof(long); - - chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid); - if (unlikely(chunk == NULL)) -diff --git a/mm/memblock.c b/mm/memblock.c -index 82aa349..0e490e8 100644 ---- a/mm/memblock.c -+++ b/mm/memblock.c -@@ -929,6 +929,30 @@ int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t si - return memblock_overlaps_region(&memblock.reserved, base, size) >= 0; - } - -+void __init_memblock memblock_trim_memory(phys_addr_t align) -+{ -+ int i; -+ phys_addr_t start, end, orig_start, orig_end; -+ struct memblock_type *mem = &memblock.memory; -+ -+ for (i = 0; i < mem->cnt; i++) { -+ orig_start = mem->regions[i].base; -+ orig_end = mem->regions[i].base + mem->regions[i].size; -+ start = round_up(orig_start, align); -+ end = round_down(orig_end, align); -+ -+ if (start == orig_start && end == orig_end) -+ continue; -+ -+ if (start < end) { -+ mem->regions[i].base = start; -+ mem->regions[i].size = end - start; -+ } else { -+ memblock_remove_region(mem, i); -+ i--; -+ } -+ } -+} - - void __init_memblock memblock_set_current_limit(phys_addr_t limit) - { -diff --git a/mm/rmap.c b/mm/rmap.c -index 0f3b7cd..aa95e59 100644 ---- a/mm/rmap.c -+++ b/mm/rmap.c -@@ -56,6 +56,7 @@ - #include - #include - #include -+#include - - #include - -@@ -971,11 +972,8 @@ int page_mkclean(struct page *page) - - if (page_mapped(page)) { - struct address_space *mapping = page_mapping(page); -- if (mapping) { -+ if (mapping) - ret = page_mkclean_file(mapping, page); -- if (page_test_and_clear_dirty(page_to_pfn(page), 1)) -- ret = 1; -- } - } - - return ret; -@@ -1161,6 +1159,7 @@ void page_add_file_rmap(struct page *page) - */ - void page_remove_rmap(struct page *page) - { -+ struct address_space *mapping = page_mapping(page); - bool anon = PageAnon(page); - bool locked; - unsigned long flags; -@@ -1183,8 +1182,19 @@ void page_remove_rmap(struct page *page) - * this if the page is anon, so about to be freed; but perhaps - * not if it's in swapcache - there might be another pte slot - * containing the swap entry, but page not yet written to swap. -+ * -+ * And we can skip it on file pages, so long as the filesystem -+ * participates in dirty tracking; but need to catch shm and tmpfs -+ * and ramfs pages which have been modified since creation by read -+ * fault. -+ * -+ * Note that mapping must be decided above, before decrementing -+ * mapcount (which luckily provides a barrier): once page is unmapped, -+ * it could be truncated and page->mapping reset to NULL at any moment. -+ * Note also that we are relying on page_mapping(page) to set mapping -+ * to &swapper_space when PageSwapCache(page). - */ -- if ((!anon || PageSwapCache(page)) && -+ if (mapping && !mapping_cap_account_dirty(mapping) && - page_test_and_clear_dirty(page_to_pfn(page), 1)) - set_page_dirty(page); - /* -diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c -index 8c225ef..2ac8d50 100644 ---- a/net/bluetooth/smp.c -+++ b/net/bluetooth/smp.c -@@ -32,6 +32,8 @@ - - #define SMP_TIMEOUT msecs_to_jiffies(30000) - -+#define AUTH_REQ_MASK 0x07 -+ - static inline void swap128(u8 src[16], u8 dst[16]) - { - int i; -@@ -230,7 +232,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, - req->max_key_size = SMP_MAX_ENC_KEY_SIZE; - req->init_key_dist = 0; - req->resp_key_dist = dist_keys; -- req->auth_req = authreq; -+ req->auth_req = (authreq & AUTH_REQ_MASK); - return; - } - -@@ -239,7 +241,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, - rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; - rsp->init_key_dist = 0; - rsp->resp_key_dist = req->resp_key_dist & dist_keys; -- rsp->auth_req = authreq; -+ rsp->auth_req = (authreq & AUTH_REQ_MASK); - } - - static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) -diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c -index bfb57dc..c93d395 100644 ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -822,7 +822,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - if (info->control.vif == &sdata->vif) { - __skb_unlink(skb, &local->pending[i]); -- dev_kfree_skb_irq(skb); -+ ieee80211_free_txskb(&local->hw, skb); - } - } - } -diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c -index f76b833..b71d466 100644 ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -3065,22 +3065,32 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, - ht_cfreq, ht_oper->primary_chan, - cbss->channel->band); - ht_oper = NULL; -+ } else { -+ channel_type = NL80211_CHAN_HT20; - } - } - -- if (ht_oper) { -- channel_type = NL80211_CHAN_HT20; -+ if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { -+ /* -+ * cfg80211 already verified that the channel itself can -+ * be used, but it didn't check that we can do the right -+ * HT type, so do that here as well. If HT40 isn't allowed -+ * on this channel, disable 40 MHz operation. -+ */ - -- if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { -- switch (ht_oper->ht_param & -- IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { -- case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: -+ switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { -+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: -+ if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS) -+ ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; -+ else - channel_type = NL80211_CHAN_HT40PLUS; -- break; -- case IEEE80211_HT_PARAM_CHA_SEC_BELOW: -+ break; -+ case IEEE80211_HT_PARAM_CHA_SEC_BELOW: -+ if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS) -+ ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; -+ else - channel_type = NL80211_CHAN_HT40MINUS; -- break; -- } -+ break; - } - } - -@@ -3457,6 +3467,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, - { - struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; - u8 frame_buf[DEAUTH_DISASSOC_LEN]; -+ bool tx = !req->local_state_change; - - mutex_lock(&ifmgd->mtx); - -@@ -3473,11 +3484,11 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, - if (ifmgd->associated && - ether_addr_equal(ifmgd->associated->bssid, req->bssid)) - ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, -- req->reason_code, true, frame_buf); -+ req->reason_code, tx, frame_buf); - else - ieee80211_send_deauth_disassoc(sdata, req->bssid, - IEEE80211_STYPE_DEAUTH, -- req->reason_code, true, -+ req->reason_code, tx, - frame_buf); - mutex_unlock(&ifmgd->mtx); - -diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c -index 06fa75c..63882b9 100644 ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -585,7 +585,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, - */ - if (!skb) - break; -- dev_kfree_skb(skb); -+ ieee80211_free_txskb(&local->hw, skb); - } - - /* -@@ -614,7 +614,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, - local->total_ps_buffered--; - ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", - sta->sta.addr); -- dev_kfree_skb(skb); -+ ieee80211_free_txskb(&local->hw, skb); - } - - /* -diff --git a/net/mac80211/util.c b/net/mac80211/util.c -index 39b82fe..c9b52f7 100644 ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -400,7 +400,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, - int queue = info->hw_queue; - - if (WARN_ON(!info->control.vif)) { -- kfree_skb(skb); -+ ieee80211_free_txskb(&local->hw, skb); - return; - } - -@@ -425,7 +425,7 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - - if (WARN_ON(!info->control.vif)) { -- kfree_skb(skb); -+ ieee80211_free_txskb(&local->hw, skb); - continue; - } - -diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c -index bdb53ab..e72562a 100644 ---- a/net/mac80211/wpa.c -+++ b/net/mac80211/wpa.c -@@ -106,7 +106,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) - if (status->flag & RX_FLAG_MMIC_ERROR) - goto mic_fail; - -- if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key) -+ if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key && -+ rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP) - goto update_iv; - - return RX_CONTINUE; -diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c -index 97f8918..6a70db4 100644 ---- a/net/sunrpc/xprtsock.c -+++ b/net/sunrpc/xprtsock.c -@@ -254,7 +254,6 @@ struct sock_xprt { - void (*old_data_ready)(struct sock *, int); - void (*old_state_change)(struct sock *); - void (*old_write_space)(struct sock *); -- void (*old_error_report)(struct sock *); - }; - - /* -@@ -737,10 +736,10 @@ static int xs_tcp_send_request(struct rpc_task *task) - dprintk("RPC: sendmsg returned unrecognized error %d\n", - -status); - case -ECONNRESET: -- case -EPIPE: - xs_tcp_shutdown(xprt); - case -ECONNREFUSED: - case -ENOTCONN: -+ case -EPIPE: - clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); - } - -@@ -781,7 +780,6 @@ static void xs_save_old_callbacks(struct sock_xprt *transport, struct sock *sk) - transport->old_data_ready = sk->sk_data_ready; - transport->old_state_change = sk->sk_state_change; - transport->old_write_space = sk->sk_write_space; -- transport->old_error_report = sk->sk_error_report; - } - - static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk) -@@ -789,7 +787,6 @@ static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *s - sk->sk_data_ready = transport->old_data_ready; - sk->sk_state_change = transport->old_state_change; - sk->sk_write_space = transport->old_write_space; -- sk->sk_error_report = transport->old_error_report; - } - - static void xs_reset_transport(struct sock_xprt *transport) -@@ -1462,7 +1459,7 @@ static void xs_tcp_cancel_linger_timeout(struct rpc_xprt *xprt) - xprt_clear_connecting(xprt); - } - --static void xs_sock_mark_closed(struct rpc_xprt *xprt) -+static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt) - { - smp_mb__before_clear_bit(); - clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); -@@ -1470,6 +1467,11 @@ static void xs_sock_mark_closed(struct rpc_xprt *xprt) - clear_bit(XPRT_CLOSE_WAIT, &xprt->state); - clear_bit(XPRT_CLOSING, &xprt->state); - smp_mb__after_clear_bit(); -+} -+ -+static void xs_sock_mark_closed(struct rpc_xprt *xprt) -+{ -+ xs_sock_reset_connection_flags(xprt); - /* Mark transport as closed and wake up all pending tasks */ - xprt_disconnect_done(xprt); - } -@@ -1525,6 +1527,7 @@ static void xs_tcp_state_change(struct sock *sk) - case TCP_CLOSE_WAIT: - /* The server initiated a shutdown of the socket */ - xprt->connect_cookie++; -+ clear_bit(XPRT_CONNECTED, &xprt->state); - xs_tcp_force_close(xprt); - case TCP_CLOSING: - /* -@@ -1549,25 +1552,6 @@ static void xs_tcp_state_change(struct sock *sk) - read_unlock_bh(&sk->sk_callback_lock); - } - --/** -- * xs_error_report - callback mainly for catching socket errors -- * @sk: socket -- */ --static void xs_error_report(struct sock *sk) --{ -- struct rpc_xprt *xprt; -- -- read_lock_bh(&sk->sk_callback_lock); -- if (!(xprt = xprt_from_sock(sk))) -- goto out; -- dprintk("RPC: %s client %p...\n" -- "RPC: error %d\n", -- __func__, xprt, sk->sk_err); -- xprt_wake_pending_tasks(xprt, -EAGAIN); --out: -- read_unlock_bh(&sk->sk_callback_lock); --} -- - static void xs_write_space(struct sock *sk) - { - struct socket *sock; -@@ -1867,7 +1851,6 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt, - sk->sk_user_data = xprt; - sk->sk_data_ready = xs_local_data_ready; - sk->sk_write_space = xs_udp_write_space; -- sk->sk_error_report = xs_error_report; - sk->sk_allocation = GFP_ATOMIC; - - xprt_clear_connected(xprt); -@@ -1995,7 +1978,6 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) - sk->sk_user_data = xprt; - sk->sk_data_ready = xs_udp_data_ready; - sk->sk_write_space = xs_udp_write_space; -- sk->sk_error_report = xs_error_report; - sk->sk_no_check = UDP_CSUM_NORCV; - sk->sk_allocation = GFP_ATOMIC; - -@@ -2065,10 +2047,8 @@ static void xs_abort_connection(struct sock_xprt *transport) - any.sa_family = AF_UNSPEC; - result = kernel_connect(transport->sock, &any, sizeof(any), 0); - if (!result) -- xs_sock_mark_closed(&transport->xprt); -- else -- dprintk("RPC: AF_UNSPEC connect return code %d\n", -- result); -+ xs_sock_reset_connection_flags(&transport->xprt); -+ dprintk("RPC: AF_UNSPEC connect return code %d\n", result); - } - - static void xs_tcp_reuse_connection(struct sock_xprt *transport) -@@ -2113,7 +2093,6 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) - sk->sk_data_ready = xs_tcp_data_ready; - sk->sk_state_change = xs_tcp_state_change; - sk->sk_write_space = xs_tcp_write_space; -- sk->sk_error_report = xs_error_report; - sk->sk_allocation = GFP_ATOMIC; - - /* socket options */ -diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c -index 1cdb1d5..9ea174f 100644 ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -457,20 +457,14 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, - .reason_code = reason, - .ie = ie, - .ie_len = ie_len, -+ .local_state_change = local_state_change, - }; - - ASSERT_WDEV_LOCK(wdev); - -- if (local_state_change) { -- if (wdev->current_bss && -- ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { -- cfg80211_unhold_bss(wdev->current_bss); -- cfg80211_put_bss(&wdev->current_bss->pub); -- wdev->current_bss = NULL; -- } -- -+ if (local_state_change && (!wdev->current_bss || -+ !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) - return 0; -- } - - return rdev->ops->deauth(&rdev->wiphy, dev, &req); - } -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 155cbd2..70ce60f 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -5704,6 +5704,7 @@ static const struct hda_verb alc268_beep_init_verbs[] = { - - enum { - ALC268_FIXUP_INV_DMIC, -+ ALC268_FIXUP_HP_EAPD, - }; - - static const struct alc_fixup alc268_fixups[] = { -@@ -5711,10 +5712,26 @@ static const struct alc_fixup alc268_fixups[] = { - .type = ALC_FIXUP_FUNC, - .v.func = alc_fixup_inv_dmic_0x12, - }, -+ [ALC268_FIXUP_HP_EAPD] = { -+ .type = ALC_FIXUP_VERBS, -+ .v.verbs = (const struct hda_verb[]) { -+ {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, -+ {} -+ } -+ }, - }; - - static const struct alc_model_fixup alc268_fixup_models[] = { - {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, -+ {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, -+ {} -+}; -+ -+static const struct snd_pci_quirk alc268_fixup_tbl[] = { -+ /* below is codec SSID since multiple Toshiba laptops have the -+ * same PCI SSID 1179:ff00 -+ */ -+ SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD), - {} - }; - -@@ -5749,7 +5766,7 @@ static int patch_alc268(struct hda_codec *codec) - - spec = codec->spec; - -- alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups); -+ alc_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); - alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); - - /* automatic parse from the BIOS config */ -@@ -6214,6 +6231,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), - SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), - SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), -+ SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), - SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), - SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), - SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), -diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c -index af0f22f..aca6edc 100644 ---- a/usr/gen_init_cpio.c -+++ b/usr/gen_init_cpio.c -@@ -303,7 +303,7 @@ static int cpio_mkfile(const char *name, const char *location, - int retval; - int rc = -1; - int namesize; -- int i; -+ unsigned int i; - - mode |= S_IFREG; - -@@ -381,25 +381,28 @@ error: - - static char *cpio_replace_env(char *new_location) - { -- char expanded[PATH_MAX + 1]; -- char env_var[PATH_MAX + 1]; -- char *start; -- char *end; -- -- for (start = NULL; (start = strstr(new_location, "${")); ) { -- end = strchr(start, '}'); -- if (start < end) { -- *env_var = *expanded = '\0'; -- strncat(env_var, start + 2, end - start - 2); -- strncat(expanded, new_location, start - new_location); -- strncat(expanded, getenv(env_var), PATH_MAX); -- strncat(expanded, end + 1, PATH_MAX); -- strncpy(new_location, expanded, PATH_MAX); -- } else -- break; -- } -- -- return new_location; -+ char expanded[PATH_MAX + 1]; -+ char env_var[PATH_MAX + 1]; -+ char *start; -+ char *end; -+ -+ for (start = NULL; (start = strstr(new_location, "${")); ) { -+ end = strchr(start, '}'); -+ if (start < end) { -+ *env_var = *expanded = '\0'; -+ strncat(env_var, start + 2, end - start - 2); -+ strncat(expanded, new_location, start - new_location); -+ strncat(expanded, getenv(env_var), -+ PATH_MAX - strlen(expanded)); -+ strncat(expanded, end + 1, -+ PATH_MAX - strlen(expanded)); -+ strncpy(new_location, expanded, PATH_MAX); -+ new_location[PATH_MAX] = 0; -+ } else -+ break; -+ } -+ -+ return new_location; - } - -