commit:     4fe512fa7c50529ee296f5cfb98662ebd146ee7b
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Dec 10 13:49:26 2015 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Dec 10 13:49:26 2015 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=4fe512fa

Linux patch 3.10.94

 0000_README              |   4 +
 1093_linux-3.10.94.patch | 724 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 728 insertions(+)

diff --git a/0000_README b/0000_README
index 5c1813e..a9b48f6 100644
--- a/0000_README
+++ b/0000_README
@@ -414,6 +414,10 @@ Patch:  1092_linux-3.10.93.patch
 From:   http://www.kernel.org
 Desc:   Linux 3.10.93
 
+Patch:  1093_linux-3.10.94.patch
+From:   http://www.kernel.org
+Desc:   Linux 3.10.94
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1093_linux-3.10.94.patch b/1093_linux-3.10.94.patch
new file mode 100644
index 0000000..cd9c4a9
--- /dev/null
+++ b/1093_linux-3.10.94.patch
@@ -0,0 +1,724 @@
+diff --git a/Makefile b/Makefile
+index 6944160a5631..f73ae0748cbc 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 10
+-SUBLEVEL = 93
++SUBLEVEL = 94
+ EXTRAVERSION =
+ NAME = TOSSUG Baby Fish
+ 
+diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
+index 8ca636cf8618..1a00c33a5b7e 100644
+--- a/arch/arm/mm/dma-mapping.c
++++ b/arch/arm/mm/dma-mapping.c
+@@ -1355,12 +1355,19 @@ static int arm_iommu_mmap_attrs(struct device *dev, 
struct vm_area_struct *vma,
+       unsigned long uaddr = vma->vm_start;
+       unsigned long usize = vma->vm_end - vma->vm_start;
+       struct page **pages = __iommu_get_pages(cpu_addr, attrs);
++      unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
++      unsigned long off = vma->vm_pgoff;
+ 
+       vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
+ 
+       if (!pages)
+               return -ENXIO;
+ 
++      if (off >= nr_pages || (usize >> PAGE_SHIFT) > nr_pages - off)
++              return -ENXIO;
++
++      pages += off;
++
+       do {
+               int ret = vm_insert_page(vma, uaddr, *pages++);
+               if (ret) {
+diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
+index c019b7aaf776..553e00a432ec 100644
+--- a/arch/arm/plat-orion/common.c
++++ b/arch/arm/plat-orion/common.c
+@@ -498,7 +498,7 @@ void __init orion_ge00_switch_init(struct 
dsa_platform_data *d, int irq)
+ 
+       d->netdev = &orion_ge00.dev;
+       for (i = 0; i < d->nr_chips; i++)
+-              d->chip[i].mii_bus = &orion_ge00_shared.dev;
++              d->chip[i].mii_bus = &orion_ge_mvmdio.dev;
+       orion_switch_device.dev.platform_data = d;
+ 
+       platform_device_register(&orion_switch_device);
+diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
+index 41a71ee4c3df..7257c364eb99 100644
+--- a/arch/arm64/include/asm/ptrace.h
++++ b/arch/arm64/include/asm/ptrace.h
+@@ -70,14 +70,14 @@
+ #define compat_sp     regs[13]
+ #define compat_lr     regs[14]
+ #define compat_sp_hyp regs[15]
+-#define compat_sp_irq regs[16]
+-#define compat_lr_irq regs[17]
+-#define compat_sp_svc regs[18]
+-#define compat_lr_svc regs[19]
+-#define compat_sp_abt regs[20]
+-#define compat_lr_abt regs[21]
+-#define compat_sp_und regs[22]
+-#define compat_lr_und regs[23]
++#define compat_lr_irq regs[16]
++#define compat_sp_irq regs[17]
++#define compat_lr_svc regs[18]
++#define compat_sp_svc regs[19]
++#define compat_lr_abt regs[20]
++#define compat_sp_abt regs[21]
++#define compat_lr_und regs[22]
++#define compat_sp_und regs[23]
+ #define compat_r8_fiq regs[24]
+ #define compat_r9_fiq regs[25]
+ #define compat_r10_fiq        regs[26]
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 564140155c36..81e0fe48b9b0 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -280,10 +280,9 @@ __setup("nosmap", setup_disable_smap);
+ 
+ static __always_inline void setup_smap(struct cpuinfo_x86 *c)
+ {
+-      unsigned long eflags;
++      unsigned long eflags = native_save_fl();
+ 
+       /* This should have been cleared long ago */
+-      raw_local_save_flags(eflags);
+       BUG_ON(eflags & X86_EFLAGS_AC);
+ 
+       if (cpu_has(c, X86_FEATURE_SMAP)) {
+diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
+index f2a9a2aa98f3..3280489905a8 100644
+--- a/arch/x86/kernel/head_64.S
++++ b/arch/x86/kernel/head_64.S
+@@ -65,6 +65,9 @@ startup_64:
+        * tables and then reload them.
+        */
+ 
++      /* Sanitize CPU configuration */
++      call verify_cpu
++
+       /*
+        * Compute the delta between the address I am compiled to run at and the
+        * address I am actually running at.
+@@ -174,6 +177,9 @@ ENTRY(secondary_startup_64)
+        * after the boot processor executes this code.
+        */
+ 
++      /* Sanitize CPU configuration */
++      call verify_cpu
++
+       movq    $(init_level4_pgt - __START_KERNEL_map), %rax
+ 1:
+ 
+@@ -288,6 +294,8 @@ ENTRY(secondary_startup_64)
+       pushq   %rax            # target address in negative space
+       lretq
+ 
++#include "verify_cpu.S"
++
+ #ifdef CONFIG_HOTPLUG_CPU
+ /*
+  * Boot CPU0 entry point. It's called from play_dead(). Everything has been 
set
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index 91964c663f0d..935aff397fcc 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -1156,6 +1156,14 @@ void __init setup_arch(char **cmdline_p)
+       clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
+                       swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
+                       KERNEL_PGD_PTRS);
++
++      /*
++       * sync back low identity map too.  It is used for example
++       * in the 32-bit EFI stub.
++       */
++      clone_pgd_range(initial_page_table,
++                      swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
++                      min(KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
+ #endif
+ 
+       tboot_probe();
+diff --git a/arch/x86/kernel/verify_cpu.S b/arch/x86/kernel/verify_cpu.S
+index b9242bacbe59..4cf401f581e7 100644
+--- a/arch/x86/kernel/verify_cpu.S
++++ b/arch/x86/kernel/verify_cpu.S
+@@ -34,10 +34,11 @@
+ #include <asm/msr-index.h>
+ 
+ verify_cpu:
+-      pushfl                          # Save caller passed flags
+-      pushl   $0                      # Kill any dangerous flags
+-      popfl
++      pushf                           # Save caller passed flags
++      push    $0                      # Kill any dangerous flags
++      popf
+ 
++#ifndef __x86_64__
+       pushfl                          # standard way to check for cpuid
+       popl    %eax
+       movl    %eax,%ebx
+@@ -48,6 +49,7 @@ verify_cpu:
+       popl    %eax
+       cmpl    %eax,%ebx
+       jz      verify_cpu_no_longmode  # cpu has no cpuid
++#endif
+ 
+       movl    $0x0,%eax               # See if cpuid 1 is implemented
+       cpuid
+@@ -130,10 +132,10 @@ verify_cpu_sse_test:
+       jmp     verify_cpu_sse_test     # try again
+ 
+ verify_cpu_no_longmode:
+-      popfl                           # Restore caller passed flags
++      popf                            # Restore caller passed flags
+       movl $1,%eax
+       ret
+ verify_cpu_sse_ok:
+-      popfl                           # Restore caller passed flags
++      popf                            # Restore caller passed flags
+       xorl %eax, %eax
+       ret
+diff --git a/drivers/net/can/sja1000/sja1000.c 
b/drivers/net/can/sja1000/sja1000.c
+index f17c3018b7c7..c2d0559115d3 100644
+--- a/drivers/net/can/sja1000/sja1000.c
++++ b/drivers/net/can/sja1000/sja1000.c
+@@ -184,6 +184,9 @@ static void sja1000_start(struct net_device *dev)
+       priv->write_reg(priv, SJA1000_RXERR, 0x0);
+       priv->read_reg(priv, SJA1000_ECC);
+ 
++      /* clear interrupt flags */
++      priv->read_reg(priv, SJA1000_IR);
++
+       /* leave reset mode */
+       set_normal_mode(dev);
+ }
+diff --git a/drivers/net/ethernet/marvell/mvneta.c 
b/drivers/net/ethernet/marvell/mvneta.c
+index 8b6c9237eda4..d5643c143bb8 100644
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -910,7 +910,7 @@ static void mvneta_defaults_set(struct mvneta_port *pp)
+       /* Set CPU queue access map - all CPUs have access to all RX
+        * queues and to all TX queues
+        */
+-      for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++)
++      for_each_present_cpu(cpu)
+               mvreg_write(pp, MVNETA_CPU_MAP(cpu),
+                           (MVNETA_CPU_RXQ_ACCESS_ALL_MASK |
+                            MVNETA_CPU_TXQ_ACCESS_ALL_MASK));
+diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c 
b/drivers/net/ethernet/mellanox/mlx4/cmd.c
+index 28d706bd12eb..d64050fcafc3 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
+@@ -1836,7 +1836,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
+                       spin_lock_init(&s_state->lock);
+               }
+ 
+-              memset(&priv->mfunc.master.cmd_eqe, 0, dev->caps.eqe_size);
++              memset(&priv->mfunc.master.cmd_eqe, 0, sizeof(struct mlx4_eqe));
+               priv->mfunc.master.cmd_eqe.type = MLX4_EVENT_TYPE_CMD;
+               INIT_WORK(&priv->mfunc.master.comm_work,
+                         mlx4_master_comm_channel);
+diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c 
b/drivers/net/ethernet/mellanox/mlx4/eq.c
+index 6000342f9725..16a1ccc269f1 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
++++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
+@@ -183,7 +183,7 @@ static void slave_event(struct mlx4_dev *dev, u8 slave, 
struct mlx4_eqe *eqe)
+               return;
+       }
+ 
+-      memcpy(s_eqe, eqe, dev->caps.eqe_size - 1);
++      memcpy(s_eqe, eqe, sizeof(struct mlx4_eqe) - 1);
+       s_eqe->slave_id = slave;
+       /* ensure all information is written before setting the ownersip bit */
+       wmb();
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index c5f9cb85c8ef..ff08be535a4d 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -731,10 +731,13 @@ static int stmmac_get_ts_info(struct net_device *dev,
+ {
+       struct stmmac_priv *priv = netdev_priv(dev);
+ 
+-      if ((priv->hwts_tx_en) && (priv->hwts_rx_en)) {
++      if ((priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) {
+ 
+-              info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
++              info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
++                                      SOF_TIMESTAMPING_TX_HARDWARE |
++                                      SOF_TIMESTAMPING_RX_SOFTWARE |
+                                       SOF_TIMESTAMPING_RX_HARDWARE |
++                                      SOF_TIMESTAMPING_SOFTWARE |
+                                       SOF_TIMESTAMPING_RAW_HARDWARE;
+ 
+               if (priv->ptp_clock)
+diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
+index eda9f3d87746..2840cf608312 100644
+--- a/drivers/net/ppp/pppoe.c
++++ b/drivers/net/ppp/pppoe.c
+@@ -569,7 +569,7 @@ static int pppoe_release(struct socket *sock)
+ 
+       po = pppox_sk(sk);
+ 
+-      if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
++      if (po->pppoe_dev) {
+               dev_put(po->pppoe_dev);
+               po->pppoe_dev = NULL;
+       }
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index 2835bfe151b1..b5d11529a39b 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -1545,9 +1545,9 @@ static int virtnet_probe(struct virtio_device *vdev)
+       /* Do we support "hardware" checksums? */
+       if (virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) {
+               /* This opens up the world of extra features. */
+-              dev->hw_features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
++              dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_SG;
+               if (csum)
+-                      dev->features |= 
NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
++                      dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
+ 
+               if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
+                       dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
+diff --git a/drivers/net/wireless/mwifiex/debugfs.c 
b/drivers/net/wireless/mwifiex/debugfs.c
+index a5f9875cfd6e..f84e5d7e8bbe 100644
+--- a/drivers/net/wireless/mwifiex/debugfs.c
++++ b/drivers/net/wireless/mwifiex/debugfs.c
+@@ -637,7 +637,7 @@ mwifiex_rdeeprom_read(struct file *file, char __user *ubuf,
+               (struct mwifiex_private *) file->private_data;
+       unsigned long addr = get_zeroed_page(GFP_KERNEL);
+       char *buf = (char *) addr;
+-      int pos = 0, ret = 0, i;
++      int pos, ret, i;
+       u8 value[MAX_EEPROM_DATA];
+ 
+       if (!buf)
+@@ -645,7 +645,7 @@ mwifiex_rdeeprom_read(struct file *file, char __user *ubuf,
+ 
+       if (saved_offset == -1) {
+               /* No command has been given */
+-              pos += snprintf(buf, PAGE_SIZE, "0");
++              pos = snprintf(buf, PAGE_SIZE, "0");
+               goto done;
+       }
+ 
+@@ -654,17 +654,17 @@ mwifiex_rdeeprom_read(struct file *file, char __user 
*ubuf,
+                                 (u16) saved_bytes, value);
+       if (ret) {
+               ret = -EINVAL;
+-              goto done;
++              goto out_free;
+       }
+ 
+-      pos += snprintf(buf, PAGE_SIZE, "%d %d ", saved_offset, saved_bytes);
++      pos = snprintf(buf, PAGE_SIZE, "%d %d ", saved_offset, saved_bytes);
+ 
+       for (i = 0; i < saved_bytes; i++)
+-              pos += snprintf(buf + strlen(buf), PAGE_SIZE, "%d ", value[i]);
+-
+-      ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
++              pos += scnprintf(buf + pos, PAGE_SIZE - pos, "%d ", value[i]);
+ 
+ done:
++      ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
++out_free:
+       free_page(addr);
+       return ret;
+ }
+diff --git a/drivers/staging/rtl8712/usb_intf.c 
b/drivers/staging/rtl8712/usb_intf.c
+index e3a005da776b..1d9ab22d9a25 100644
+--- a/drivers/staging/rtl8712/usb_intf.c
++++ b/drivers/staging/rtl8712/usb_intf.c
+@@ -144,6 +144,7 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = {
+       {USB_DEVICE(0x0DF6, 0x0058)},
+       {USB_DEVICE(0x0DF6, 0x0049)},
+       {USB_DEVICE(0x0DF6, 0x004C)},
++      {USB_DEVICE(0x0DF6, 0x006C)},
+       {USB_DEVICE(0x0DF6, 0x0064)},
+       /* Skyworth */
+       {USB_DEVICE(0x14b2, 0x3300)},
+diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
+index d4c47d5d7625..7ac5fac8600b 100644
+--- a/drivers/usb/class/usblp.c
++++ b/drivers/usb/class/usblp.c
+@@ -870,11 +870,11 @@ static int usblp_wwait(struct usblp *usblp, int nonblock)
+ 
+       add_wait_queue(&usblp->wwait, &waita);
+       for (;;) {
+-              set_current_state(TASK_INTERRUPTIBLE);
+               if (mutex_lock_interruptible(&usblp->mut)) {
+                       rc = -EINTR;
+                       break;
+               }
++              set_current_state(TASK_INTERRUPTIBLE);
+               rc = usblp_wtest(usblp, nonblock);
+               mutex_unlock(&usblp->mut);
+               if (rc <= 0)
+diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
+index da0caf3f4b27..462a7d57c095 100644
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -133,7 +133,7 @@ static inline struct musb *dev_to_musb(struct device *dev)
+ /*-------------------------------------------------------------------------*/
+ 
+ #ifndef CONFIG_BLACKFIN
+-static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
++static int musb_ulpi_read(struct usb_phy *phy, u32 reg)
+ {
+       void __iomem *addr = phy->io_priv;
+       int     i = 0;
+@@ -152,7 +152,7 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
+        * ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM.
+        */
+ 
+-      musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
++      musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)reg);
+       musb_writeb(addr, MUSB_ULPI_REG_CONTROL,
+                       MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR);
+ 
+@@ -177,7 +177,7 @@ out:
+       return ret;
+ }
+ 
+-static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
++static int musb_ulpi_write(struct usb_phy *phy, u32 val, u32 reg)
+ {
+       void __iomem *addr = phy->io_priv;
+       int     i = 0;
+@@ -192,8 +192,8 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 
offset, u32 data)
+       power &= ~MUSB_POWER_SUSPENDM;
+       musb_writeb(addr, MUSB_POWER, power);
+ 
+-      musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
+-      musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)data);
++      musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)reg);
++      musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)val);
+       musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ);
+ 
+       while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index c918075e5eae..bdbe642e6569 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -162,6 +162,7 @@ static void option_instat_callback(struct urb *urb);
+ #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED       0x9001
+ #define NOVATELWIRELESS_PRODUCT_E362          0x9010
+ #define NOVATELWIRELESS_PRODUCT_E371          0x9011
++#define NOVATELWIRELESS_PRODUCT_U620L         0x9022
+ #define NOVATELWIRELESS_PRODUCT_G2            0xA010
+ #define NOVATELWIRELESS_PRODUCT_MC551         0xB001
+ 
+@@ -354,6 +355,7 @@ static void option_instat_callback(struct urb *urb);
+ /* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick *
+  * It seems to contain a Qualcomm QSC6240/6290 chipset            */
+ #define FOUR_G_SYSTEMS_PRODUCT_W14            0x9603
++#define FOUR_G_SYSTEMS_PRODUCT_W100           0x9b01
+ 
+ /* iBall 3.5G connect wireless modem */
+ #define IBALL_3_5G_CONNECT                    0x9605
+@@ -527,6 +529,11 @@ static const struct option_blacklist_info 
four_g_w14_blacklist = {
+       .sendsetup = BIT(0) | BIT(1),
+ };
+ 
++static const struct option_blacklist_info four_g_w100_blacklist = {
++      .sendsetup = BIT(1) | BIT(2),
++      .reserved = BIT(3),
++};
++
+ static const struct option_blacklist_info alcatel_x200_blacklist = {
+       .sendsetup = BIT(0) | BIT(1),
+       .reserved = BIT(4),
+@@ -1060,6 +1067,7 @@ static const struct usb_device_id option_ids[] = {
+       { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, 
NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, 
NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, 
NOVATELWIRELESS_PRODUCT_E371, 0xff, 0xff, 0xff) },
++      { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, 
NOVATELWIRELESS_PRODUCT_U620L, 0xff, 0x00, 0x00) },
+ 
+       { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
+       { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
+@@ -1641,6 +1649,9 @@ static const struct usb_device_id option_ids[] = {
+       { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
+         .driver_info = (kernel_ulong_t)&four_g_w14_blacklist
+       },
++      { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W100),
++        .driver_info = (kernel_ulong_t)&four_g_w100_blacklist
++      },
+       { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 
SPEEDUP_PRODUCT_SU9800, 0xff) },
+       { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
+       { USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) },
+diff --git a/include/net/inet_common.h b/include/net/inet_common.h
+index 234008782c8c..102fc42c7fb1 100644
+--- a/include/net/inet_common.h
++++ b/include/net/inet_common.h
+@@ -40,7 +40,8 @@ extern int inet_ctl_sock_create(struct sock **sk, unsigned 
short family,
+ 
+ static inline void inet_ctl_sock_destroy(struct sock *sk)
+ {
+-      sk_release_kernel(sk);
++      if (sk)
++              sk_release_kernel(sk);
+ }
+ 
+ #endif
+diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
+index de030f50f72b..c60563394cd1 100644
+--- a/net/bluetooth/hidp/core.c
++++ b/net/bluetooth/hidp/core.c
+@@ -396,6 +396,20 @@ static void hidp_idle_timeout(unsigned long arg)
+ {
+       struct hidp_session *session = (struct hidp_session *) arg;
+ 
++      /* The HIDP user-space API only contains calls to add and remove
++       * devices. There is no way to forward events of any kind. Therefore,
++       * we have to forcefully disconnect a device on idle-timeouts. This is
++       * unfortunate and weird API design, but it is spec-compliant and
++       * required for backwards-compatibility. Hence, on idle-timeout, we
++       * signal driver-detach events, so poll() will be woken up with an
++       * error-condition on both sockets.
++       */
++
++      session->intr_sock->sk->sk_err = EUNATCH;
++      session->ctrl_sock->sk->sk_err = EUNATCH;
++      wake_up_interruptible(sk_sleep(session->intr_sock->sk));
++      wake_up_interruptible(sk_sleep(session->ctrl_sock->sk));
++
+       hidp_session_terminate(session);
+ }
+ 
+diff --git a/net/core/dst.c b/net/core/dst.c
+index c0e021871df8..01f9980af86e 100644
+--- a/net/core/dst.c
++++ b/net/core/dst.c
+@@ -283,7 +283,7 @@ void dst_release(struct dst_entry *dst)
+ 
+               newrefcnt = atomic_dec_return(&dst->__refcnt);
+               WARN_ON(newrefcnt < 0);
+-              if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt)
++              if (!newrefcnt && unlikely(dst->flags & DST_NOCACHE))
+                       call_rcu(&dst->rcu_head, dst_destroy_rcu);
+       }
+ }
+diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
+index 56d079b63ad3..6f5f943ff395 100644
+--- a/net/ipv4/ipmr.c
++++ b/net/ipv4/ipmr.c
+@@ -1672,8 +1672,8 @@ static inline int ipmr_forward_finish(struct sk_buff 
*skb)
+ {
+       struct ip_options *opt = &(IPCB(skb)->opt);
+ 
+-      IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), 
IPSTATS_MIB_OUTFORWDATAGRAMS);
+-      IP_ADD_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTOCTETS, 
skb->len);
++      IP_INC_STATS(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS);
++      IP_ADD_STATS(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTOCTETS, 
skb->len);
+ 
+       if (unlikely(opt->optlen))
+               ip_forward_options(skb);
+@@ -1735,7 +1735,7 @@ static void ipmr_queue_xmit(struct net *net, struct 
mr_table *mrt,
+                * to blackhole.
+                */
+ 
+-              IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
++              IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
+               ip_rt_put(rt);
+               goto out_free;
+       }
+diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
+index 98ad6ec4bd3c..8ad149478e19 100644
+--- a/net/irda/irlmp.c
++++ b/net/irda/irlmp.c
+@@ -1876,7 +1876,7 @@ static void *irlmp_seq_hb_idx(struct irlmp_iter_state 
*iter, loff_t *off)
+       for (element = hashbin_get_first(iter->hashbin);
+            element != NULL;
+            element = hashbin_get_next(iter->hashbin)) {
+-              if (!off || *off-- == 0) {
++              if (!off || (*off)-- == 0) {
+                       /* NB: hashbin left locked */
+                       return element;
+               }
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index e606e4a113e1..952cb336d704 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -3074,7 +3074,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data 
*sdata,
+ 
+       if (ifmgd->rssi_min_thold != ifmgd->rssi_max_thold &&
+           ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
+-              int sig = ifmgd->ave_beacon_signal;
++              int sig = ifmgd->ave_beacon_signal / 16;
+               int last_sig = ifmgd->last_ave_beacon_signal;
+ 
+               /*
+diff --git a/net/rds/connection.c b/net/rds/connection.c
+index 642ad42c416b..e88bf3976e54 100644
+--- a/net/rds/connection.c
++++ b/net/rds/connection.c
+@@ -177,6 +177,12 @@ static struct rds_connection *__rds_conn_create(__be32 
laddr, __be32 faddr,
+               }
+       }
+ 
++      if (trans == NULL) {
++              kmem_cache_free(rds_conn_slab, conn);
++              conn = ERR_PTR(-ENODEV);
++              goto out;
++      }
++
+       conn->c_trans = trans;
+ 
+       ret = trans->conn_alloc(conn, gfp);
+diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c
+index 4fac4f2bb9dc..8b33d9967b56 100644
+--- a/net/rds/tcp_recv.c
++++ b/net/rds/tcp_recv.c
+@@ -234,8 +234,15 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, 
struct sk_buff *skb,
+                       }
+ 
+                       to_copy = min(tc->t_tinc_data_rem, left);
+-                      pskb_pull(clone, offset);
+-                      pskb_trim(clone, to_copy);
++                      if (!pskb_pull(clone, offset) ||
++                          pskb_trim(clone, to_copy)) {
++                              pr_warn("rds_tcp_data_recv: pull/trim failed "
++                                      "left %zu data_rem %zu skb_len %d\n",
++                                      left, tc->t_tinc_data_rem, skb->len);
++                              kfree_skb(clone);
++                              desc->error = -ENOMEM;
++                              goto out;
++                      }
+                       skb_queue_tail(&tinc->ti_skb_list, clone);
+ 
+                       rdsdebug("skb %p data %p len %d off %u to_copy %zu -> "
+diff --git a/sound/usb/midi.c b/sound/usb/midi.c
+index 93249133aeec..dabbe05d17f5 100644
+--- a/sound/usb/midi.c
++++ b/sound/usb/midi.c
+@@ -174,6 +174,8 @@ struct snd_usb_midi_in_endpoint {
+               u8 running_status_length;
+       } ports[0x10];
+       u8 seen_f5;
++      bool in_sysex;
++      u8 last_cin;
+       u8 error_resubmit;
+       int current_port;
+ };
+@@ -465,6 +467,39 @@ static void 
snd_usbmidi_maudio_broken_running_status_input(
+ }
+ 
+ /*
++ * QinHeng CH345 is buggy: every second packet inside a SysEx has not CIN 4
++ * but the previously seen CIN, but still with three data bytes.
++ */
++static void ch345_broken_sysex_input(struct snd_usb_midi_in_endpoint *ep,
++                                   uint8_t *buffer, int buffer_length)
++{
++      unsigned int i, cin, length;
++
++      for (i = 0; i + 3 < buffer_length; i += 4) {
++              if (buffer[i] == 0 && i > 0)
++                      break;
++              cin = buffer[i] & 0x0f;
++              if (ep->in_sysex &&
++                  cin == ep->last_cin &&
++                  (buffer[i + 1 + (cin == 0x6)] & 0x80) == 0)
++                      cin = 0x4;
++#if 0
++              if (buffer[i + 1] == 0x90) {
++                      /*
++                       * Either a corrupted running status or a real note-on
++                       * message; impossible to detect reliably.
++                       */
++              }
++#endif
++              length = snd_usbmidi_cin_length[cin];
++              snd_usbmidi_input_data(ep, 0, &buffer[i + 1], length);
++              ep->in_sysex = cin == 0x4;
++              if (!ep->in_sysex)
++                      ep->last_cin = cin;
++      }
++}
++
++/*
+  * CME protocol: like the standard protocol, but SysEx commands are sent as a
+  * single USB packet preceded by a 0x0F byte.
+  */
+@@ -650,6 +685,12 @@ static struct usb_protocol_ops snd_usbmidi_cme_ops = {
+       .output_packet = snd_usbmidi_output_standard_packet,
+ };
+ 
++static struct usb_protocol_ops snd_usbmidi_ch345_broken_sysex_ops = {
++      .input = ch345_broken_sysex_input,
++      .output = snd_usbmidi_standard_output,
++      .output_packet = snd_usbmidi_output_standard_packet,
++};
++
+ /*
+  * AKAI MPD16 protocol:
+  *
+@@ -1326,6 +1367,7 @@ static int snd_usbmidi_out_endpoint_create(struct 
snd_usb_midi* umidi,
+                * Various chips declare a packet size larger than 4 bytes, but
+                * do not actually work with larger packets:
+                */
++      case USB_ID(0x0a67, 0x5011): /* Medeli DD305 */
+       case USB_ID(0x0a92, 0x1020): /* ESI M4U */
+       case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
+       case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
+@@ -2216,6 +2258,10 @@ int snd_usbmidi_create(struct snd_card *card,
+ 
+               err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+               break;
++      case QUIRK_MIDI_CH345:
++              umidi->usb_protocol_ops = &snd_usbmidi_ch345_broken_sysex_ops;
++              err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
++              break;
+       default:
+               snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
+               err = -ENXIO;
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index 45d586b6e8b5..9ec5ce4e35fb 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -3041,6 +3041,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
+       .idProduct = 0x1020,
+ },
+ 
++/* QinHeng devices */
++{
++      USB_DEVICE(0x1a86, 0x752d),
++      .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
++              .vendor_name = "QinHeng",
++              .product_name = "CH345",
++              .ifnum = 1,
++              .type = QUIRK_MIDI_CH345
++      }
++},
++
+ /* KeithMcMillen Stringport */
+ {
+       USB_DEVICE(0x1f38, 0x0001),
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 734c6579b194..94cd28c2bd8d 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -313,6 +313,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
+               [QUIRK_MIDI_CME] = create_any_midi_quirk,
+               [QUIRK_MIDI_AKAI] = create_any_midi_quirk,
+               [QUIRK_MIDI_FTDI] = create_any_midi_quirk,
++              [QUIRK_MIDI_CH345] = create_any_midi_quirk,
+               [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
+               [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
+               [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
+diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
+index bc43bcaddf4d..d6f3fefc882f 100644
+--- a/sound/usb/usbaudio.h
++++ b/sound/usb/usbaudio.h
+@@ -83,6 +83,7 @@ enum quirk_type {
+       QUIRK_MIDI_AKAI,
+       QUIRK_MIDI_US122L,
+       QUIRK_MIDI_FTDI,
++      QUIRK_MIDI_CH345,
+       QUIRK_AUDIO_STANDARD_INTERFACE,
+       QUIRK_AUDIO_FIXED_ENDPOINT,
+       QUIRK_AUDIO_EDIROL_UAXX,

Reply via email to