public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Anthony G. Basile" <blueness@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/hardened-patchset:master commit in: 3.6.6/
Date: Wed,  7 Nov 2012 22:45:23 +0000 (UTC)	[thread overview]
Message-ID: <1352328310.33fba0ea3a67831c3efb7e26d24a2389bba7ca89.blueness@gentoo> (raw)

commit:     33fba0ea3a67831c3efb7e26d24a2389bba7ca89
Author:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Wed Nov  7 22:45:10 2012 +0000
Commit:     Anthony G. Basile <blueness <AT> gentoo <DOT> 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,<chip>-pit".
-+- compatible: Should be "atmel,<chip>-tcb".
-   <chip> 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 <plat/fimc-core.h>
- #include <plat/iic-core.h>
- #include <plat/tv-core.h>
-+#include <plat/spi-core.h>
- #include <plat/regs-serial.h>
- 
- #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 <plat/nand-core.h>
- #include <plat/adc-core.h>
- #include <plat/rtc-core.h>
-+#include <plat/spi-core.h>
- 
- 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 <plat/nand-core.h>
- #include <plat/adc-core.h>
- #include <plat/rtc-core.h>
-+#include <plat/spi-core.h>
- 
- 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 <plat/sdhci.h>
- #include <plat/adc-core.h>
- #include <plat/fb-core.h>
-+#include <plat/spi-core.h>
- #include <plat/gpio-cfg.h>
- #include <plat/regs-irqtype.h>
- #include <plat/regs-serial.h>
-@@ -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 <plat/fb-core.h>
- #include <plat/iic-core.h>
- #include <plat/onenand-core.h>
-+#include <plat/spi-core.h>
- #include <plat/regs-serial.h>
- #include <plat/watchdog-reset.h>
- 
-@@ -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 <plat/iic-core.h>
- #include <plat/keypad-core.h>
- #include <plat/tv-core.h>
-+#include <plat/spi-core.h>
- #include <plat/regs-serial.h>
- 
- #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 <heiko@sntech.de>
-+ *
-+ * 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 <ledest@gmail.com> */
-+UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100,
-+		"Casio",
-+		"EX-N1 DigitalCamera",
-+		USB_SC_8070, USB_PR_DEVICE, NULL, 0),
-+
- /* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/
- 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 <linux/mmu_notifier.h>
- #include <linux/migrate.h>
- #include <linux/hugetlb.h>
-+#include <linux/backing-dev.h>
- 
- #include <asm/tlbflush.h>
- 
-@@ -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;
- }
- 
- 


                 reply	other threads:[~2012-11-07 22:45 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1352328310.33fba0ea3a67831c3efb7e26d24a2389bba7ca89.blueness@gentoo \
    --to=blueness@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox