public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] linux-patches r2235 - genpatches-2.6/trunk/3.6
@ 2012-11-26 22:21 Mike Pagano (mpagano)
  0 siblings, 0 replies; only message in thread
From: Mike Pagano (mpagano) @ 2012-11-26 22:21 UTC (permalink / raw
  To: gentoo-commits

Author: mpagano
Date: 2012-11-26 22:20:36 +0000 (Mon, 26 Nov 2012)
New Revision: 2235

Added:
   genpatches-2.6/trunk/3.6/1006_linux-3.6.7.patch
   genpatches-2.6/trunk/3.6/1007_linux-3.6.8.patch
Modified:
   genpatches-2.6/trunk/3.6/0000_README
Log:
Linux patches 3.6.7 and 3.6.8

Modified: genpatches-2.6/trunk/3.6/0000_README
===================================================================
--- genpatches-2.6/trunk/3.6/0000_README	2012-11-06 01:34:32 UTC (rev 2234)
+++ genpatches-2.6/trunk/3.6/0000_README	2012-11-26 22:20:36 UTC (rev 2235)
@@ -63,6 +63,14 @@
 From:   http://www.kernel.org
 Desc:   Linux 3.6.6
 
+Patch:  1006_linux-3.6.7.patch
+From:   http://www.kernel.org
+Desc:   Linux 3.6.7
+
+Patch:  1007_linux-3.6.8.patch
+From:   http://www.kernel.org
+Desc:   Linux 3.6.8
+
 Patch:  2400_kcopy-patch-for-infiniband-driver.patch
 From:   Alexey Shvetsov <alexxy@gentoo.org>
 Desc:   Zero copy for infiniband psm userspace driver

Added: genpatches-2.6/trunk/3.6/1006_linux-3.6.7.patch
===================================================================
--- genpatches-2.6/trunk/3.6/1006_linux-3.6.7.patch	                        (rev 0)
+++ genpatches-2.6/trunk/3.6/1006_linux-3.6.7.patch	2012-11-26 22:20:36 UTC (rev 2235)
@@ -0,0 +1,3082 @@
+diff --git a/Makefile b/Makefile
+index 471b83c..07f2308 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 6
+-SUBLEVEL = 6
++SUBLEVEL = 7
+ EXTRAVERSION =
+ NAME = Terrified Chipmunk
+ 
+diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
+index 5141d80..dde1a3f 100644
+--- a/arch/x86/xen/mmu.c
++++ b/arch/x86/xen/mmu.c
+@@ -1215,6 +1215,25 @@ unsigned long xen_read_cr2_direct(void)
+ 	return this_cpu_read(xen_vcpu_info.arch.cr2);
+ }
+ 
++void xen_flush_tlb_all(void)
++{
++	struct mmuext_op *op;
++	struct multicall_space mcs;
++
++	trace_xen_mmu_flush_tlb_all(0);
++
++	preempt_disable();
++
++	mcs = xen_mc_entry(sizeof(*op));
++
++	op = mcs.args;
++	op->cmd = MMUEXT_TLB_FLUSH_ALL;
++	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
++
++	xen_mc_issue(PARAVIRT_LAZY_MMU);
++
++	preempt_enable();
++}
+ static void xen_flush_tlb(void)
+ {
+ 	struct mmuext_op *op;
+@@ -2366,7 +2385,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
+ 	err = 0;
+ out:
+ 
+-	flush_tlb_all();
++	xen_flush_tlb_all();
+ 
+ 	return err;
+ }
+diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
+index 5062eec..7aff5c7 100644
+--- a/drivers/gpu/drm/drm_fops.c
++++ b/drivers/gpu/drm/drm_fops.c
+@@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct file *filp)
+ 	int minor_id = iminor(inode);
+ 	struct drm_minor *minor;
+ 	int retcode = 0;
++	int need_setup = 0;
++	struct address_space *old_mapping;
+ 
+ 	minor = idr_find(&drm_minors_idr, minor_id);
+ 	if (!minor)
+@@ -132,23 +134,37 @@ int drm_open(struct inode *inode, struct file *filp)
+ 	if (drm_device_is_unplugged(dev))
+ 		return -ENODEV;
+ 
++	if (!dev->open_count++)
++		need_setup = 1;
++	mutex_lock(&dev->struct_mutex);
++	old_mapping = dev->dev_mapping;
++	if (old_mapping == NULL)
++		dev->dev_mapping = &inode->i_data;
++	/* ihold ensures nobody can remove inode with our i_data */
++	ihold(container_of(dev->dev_mapping, struct inode, i_data));
++	inode->i_mapping = dev->dev_mapping;
++	filp->f_mapping = dev->dev_mapping;
++	mutex_unlock(&dev->struct_mutex);
++
+ 	retcode = drm_open_helper(inode, filp, dev);
+-	if (!retcode) {
+-		atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
+-		if (!dev->open_count++)
+-			retcode = drm_setup(dev);
+-	}
+-	if (!retcode) {
+-		mutex_lock(&dev->struct_mutex);
+-		if (dev->dev_mapping == NULL)
+-			dev->dev_mapping = &inode->i_data;
+-		/* ihold ensures nobody can remove inode with our i_data */
+-		ihold(container_of(dev->dev_mapping, struct inode, i_data));
+-		inode->i_mapping = dev->dev_mapping;
+-		filp->f_mapping = dev->dev_mapping;
+-		mutex_unlock(&dev->struct_mutex);
++	if (retcode)
++		goto err_undo;
++	atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
++	if (need_setup) {
++		retcode = drm_setup(dev);
++		if (retcode)
++			goto err_undo;
+ 	}
++	return 0;
+ 
++err_undo:
++	mutex_lock(&dev->struct_mutex);
++	filp->f_mapping = old_mapping;
++	inode->i_mapping = old_mapping;
++	iput(container_of(dev->dev_mapping, struct inode, i_data));
++	dev->dev_mapping = old_mapping;
++	mutex_unlock(&dev->struct_mutex);
++	dev->open_count--;
+ 	return retcode;
+ }
+ EXPORT_SYMBOL(drm_open);
+diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
+index 914c0df..0969a7c 100644
+--- a/drivers/gpu/drm/i915/i915_dma.c
++++ b/drivers/gpu/drm/i915/i915_dma.c
+@@ -1484,7 +1484,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
+ 		goto put_gmch;
+ 	}
+ 
+-	i915_kick_out_firmware_fb(dev_priv);
++	if (drm_core_check_feature(dev, DRIVER_MODESET))
++		i915_kick_out_firmware_fb(dev_priv);
+ 
+ 	pci_set_master(dev->pdev);
+ 
+diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
+index 830d0dd..cf49a57 100644
+--- a/drivers/gpu/drm/i915/intel_overlay.c
++++ b/drivers/gpu/drm/i915/intel_overlay.c
+@@ -431,9 +431,17 @@ static int intel_overlay_off(struct intel_overlay *overlay)
+ 	intel_ring_emit(ring, flip_addr);
+ 	intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
+ 	/* turn overlay off */
+-	intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
+-	intel_ring_emit(ring, flip_addr);
+-	intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
++	if (IS_I830(dev)) {
++		/* Workaround: Don't disable the overlay fully, since otherwise
++		 * it dies on the next OVERLAY_ON cmd. */
++		intel_ring_emit(ring, MI_NOOP);
++		intel_ring_emit(ring, MI_NOOP);
++		intel_ring_emit(ring, MI_NOOP);
++	} else {
++		intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
++		intel_ring_emit(ring, flip_addr);
++		intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
++	}
+ 	intel_ring_advance(ring);
+ 
+ 	return intel_overlay_do_wait_request(overlay, request,
+diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
+index 123afd3..20cb52d 100644
+--- a/drivers/gpu/drm/i915/intel_sdvo.c
++++ b/drivers/gpu/drm/i915/intel_sdvo.c
+@@ -882,6 +882,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
+ }
+ #endif
+ 
++static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo,
++				       unsigned if_index, uint8_t tx_rate,
++				       uint8_t *data, unsigned length)
++{
++	uint8_t set_buf_index[2] = { if_index, 0 };
++	uint8_t hbuf_size, tmp[8];
++	int i;
++
++	if (!intel_sdvo_set_value(intel_sdvo,
++				  SDVO_CMD_SET_HBUF_INDEX,
++				  set_buf_index, 2))
++		return false;
++
++	if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO,
++				  &hbuf_size, 1))
++		return false;
++
++	/* Buffer size is 0 based, hooray! */
++	hbuf_size++;
++
++	DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n",
++		      if_index, length, hbuf_size);
++
++	for (i = 0; i < hbuf_size; i += 8) {
++		memset(tmp, 0, 8);
++		if (i < length)
++			memcpy(tmp, data + i, min_t(unsigned, 8, length - i));
++
++		if (!intel_sdvo_set_value(intel_sdvo,
++					  SDVO_CMD_SET_HBUF_DATA,
++					  tmp, 8))
++			return false;
++	}
++
++	return intel_sdvo_set_value(intel_sdvo,
++				    SDVO_CMD_SET_HBUF_TXRATE,
++				    &tx_rate, 1);
++}
++
+ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
+ {
+ 	struct dip_infoframe avi_if = {
+@@ -889,11 +928,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
+ 		.ver = DIP_VERSION_AVI,
+ 		.len = DIP_LEN_AVI,
+ 	};
+-	uint8_t tx_rate = SDVO_HBUF_TX_VSYNC;
+-	uint8_t set_buf_index[2] = { 1, 0 };
+ 	uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
+-	uint64_t *data = (uint64_t *)sdvo_data;
+-	unsigned i;
+ 
+ 	intel_dip_infoframe_csum(&avi_if);
+ 
+@@ -903,22 +938,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
+ 	sdvo_data[3] = avi_if.checksum;
+ 	memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi));
+ 
+-	if (!intel_sdvo_set_value(intel_sdvo,
+-				  SDVO_CMD_SET_HBUF_INDEX,
+-				  set_buf_index, 2))
+-		return false;
+-
+-	for (i = 0; i < sizeof(sdvo_data); i += 8) {
+-		if (!intel_sdvo_set_value(intel_sdvo,
+-					  SDVO_CMD_SET_HBUF_DATA,
+-					  data, 8))
+-			return false;
+-		data++;
+-	}
+-
+-	return intel_sdvo_set_value(intel_sdvo,
+-				    SDVO_CMD_SET_HBUF_TXRATE,
+-				    &tx_rate, 1);
++	return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF,
++					  SDVO_HBUF_TX_VSYNC,
++					  sdvo_data, sizeof(sdvo_data));
+ }
+ 
+ static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)
+diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h
+index 9d03014..770bdd6 100644
+--- a/drivers/gpu/drm/i915/intel_sdvo_regs.h
++++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h
+@@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg {
+ #define SDVO_CMD_SET_AUDIO_STAT		0x91
+ #define SDVO_CMD_GET_AUDIO_STAT		0x92
+ #define SDVO_CMD_SET_HBUF_INDEX		0x93
++  #define SDVO_HBUF_INDEX_ELD		0
++  #define SDVO_HBUF_INDEX_AVI_IF	1
+ #define SDVO_CMD_GET_HBUF_INDEX		0x94
+ #define SDVO_CMD_GET_HBUF_INFO		0x95
+ #define SDVO_CMD_SET_HBUF_AV_SPLIT	0x96
+diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
+index e932810..4a33cdc 100644
+--- a/drivers/gpu/drm/radeon/evergreen_cs.c
++++ b/drivers/gpu/drm/radeon/evergreen_cs.c
+@@ -2725,6 +2725,9 @@ static bool evergreen_vm_reg_valid(u32 reg)
+ 	/* check config regs */
+ 	switch (reg) {
+ 	case GRBM_GFX_INDEX:
++	case CP_STRMOUT_CNTL:
++	case CP_COHER_CNTL:
++	case CP_COHER_SIZE:
+ 	case VGT_VTX_VECT_EJECT_REG:
+ 	case VGT_CACHE_INVALIDATION:
+ 	case VGT_GS_VERTEX_REUSE:
+diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
+index 7934785..302af4f 100644
+--- a/drivers/gpu/drm/radeon/evergreend.h
++++ b/drivers/gpu/drm/radeon/evergreend.h
+@@ -87,6 +87,10 @@
+ 
+ #define	CONFIG_MEMSIZE					0x5428
+ 
++#define	CP_STRMOUT_CNTL					0x84FC
++
++#define	CP_COHER_CNTL					0x85F0
++#define	CP_COHER_SIZE					0x85F4
+ #define	CP_COHER_BASE					0x85F8
+ #define	CP_STALLED_STAT1			0x8674
+ #define	CP_STALLED_STAT2			0x8678
+diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+index d16f50f..dd402bb 100644
+--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
++++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+@@ -651,6 +651,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
+ 	tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
+ 	WREG32(RADEON_DAC_CNTL, tmp);
+ 
++	tmp = dac_macro_cntl;
+ 	tmp &= ~(RADEON_DAC_PDWN_R |
+ 		 RADEON_DAC_PDWN_G |
+ 		 RADEON_DAC_PDWN_B);
+diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
+index 0139e22..6ab4a90 100644
+--- a/drivers/gpu/drm/radeon/si.c
++++ b/drivers/gpu/drm/radeon/si.c
+@@ -2472,6 +2472,7 @@ static bool si_vm_reg_valid(u32 reg)
+ 	/* check config regs */
+ 	switch (reg) {
+ 	case GRBM_GFX_INDEX:
++	case CP_STRMOUT_CNTL:
+ 	case VGT_VTX_VECT_EJECT_REG:
+ 	case VGT_CACHE_INVALIDATION:
+ 	case VGT_ESGS_RING_SIZE:
+diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
+index ef4815c..6f0083a 100644
+--- a/drivers/gpu/drm/radeon/sid.h
++++ b/drivers/gpu/drm/radeon/sid.h
+@@ -424,6 +424,7 @@
+ #       define RDERR_INT_ENABLE                         (1 << 0)
+ #       define GUI_IDLE_INT_ENABLE                      (1 << 19)
+ 
++#define	CP_STRMOUT_CNTL					0x84FC
+ #define	SCRATCH_REG0					0x8500
+ #define	SCRATCH_REG1					0x8504
+ #define	SCRATCH_REG2					0x8508
+diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
+index fccd361..87aa5f5 100644
+--- a/drivers/gpu/drm/udl/udl_drv.h
++++ b/drivers/gpu/drm/udl/udl_drv.h
+@@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev,
+ 
+ int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
+ 		     const char *front, char **urb_buf_ptr,
+-		     u32 byte_offset, u32 byte_width,
++		     u32 byte_offset, u32 device_byte_offset, u32 byte_width,
+ 		     int *ident_ptr, int *sent_ptr);
+ 
+ int udl_dumb_create(struct drm_file *file_priv,
+diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
+index ce9a611..6f6ca50 100644
+--- a/drivers/gpu/drm/udl/udl_fb.c
++++ b/drivers/gpu/drm/udl/udl_fb.c
+@@ -114,9 +114,10 @@ static void udlfb_dpy_deferred_io(struct fb_info *info,
+ 	list_for_each_entry(cur, &fbdefio->pagelist, lru) {
+ 
+ 		if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8),
+-				  &urb, (char *) info->fix.smem_start,
+-				  &cmd, cur->index << PAGE_SHIFT,
+-				  PAGE_SIZE, &bytes_identical, &bytes_sent))
++				     &urb, (char *) info->fix.smem_start,
++				     &cmd, cur->index << PAGE_SHIFT,
++				     cur->index << PAGE_SHIFT,
++				     PAGE_SIZE, &bytes_identical, &bytes_sent))
+ 			goto error;
+ 		bytes_rendered += PAGE_SIZE;
+ 	}
+@@ -187,10 +188,11 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
+ 	for (i = y; i < y + height ; i++) {
+ 		const int line_offset = fb->base.pitches[0] * i;
+ 		const int byte_offset = line_offset + (x * bpp);
+-
++		const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);
+ 		if (udl_render_hline(dev, bpp, &urb,
+ 				     (char *) fb->obj->vmapping,
+-				     &cmd, byte_offset, width * bpp,
++				     &cmd, byte_offset, dev_byte_offset,
++				     width * bpp,
+ 				     &bytes_identical, &bytes_sent))
+ 			goto error;
+ 	}
+diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c
+index b9320e2..fc11344 100644
+--- a/drivers/gpu/drm/udl/udl_transfer.c
++++ b/drivers/gpu/drm/udl/udl_transfer.c
+@@ -213,11 +213,12 @@ static void udl_compress_hline16(
+  */
+ int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
+ 		     const char *front, char **urb_buf_ptr,
+-		     u32 byte_offset, u32 byte_width,
++		     u32 byte_offset, u32 device_byte_offset,
++		     u32 byte_width,
+ 		     int *ident_ptr, int *sent_ptr)
+ {
+ 	const u8 *line_start, *line_end, *next_pixel;
+-	u32 base16 = 0 + (byte_offset / bpp) * 2;
++	u32 base16 = 0 + (device_byte_offset / bpp) * 2;
+ 	struct urb *urb = *urb_ptr;
+ 	u8 *cmd = *urb_buf_ptr;
+ 	u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
+index 3fa884d..27151f7 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
+@@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin)
+ 
+ 	BUG_ON(!atomic_read(&bo->reserved));
+ 	BUG_ON(old_mem_type != TTM_PL_VRAM &&
+-	       old_mem_type != VMW_PL_FLAG_GMR);
++	       old_mem_type != VMW_PL_GMR);
+ 
+ 	pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED;
+ 	if (pin)
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+index ba2c35d..4a04ae0 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+@@ -1099,6 +1099,11 @@ static void vmw_pm_complete(struct device *kdev)
+ 	struct drm_device *dev = pci_get_drvdata(pdev);
+ 	struct vmw_private *dev_priv = vmw_priv(dev);
+ 
++	mutex_lock(&dev_priv->hw_mutex);
++	vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
++	(void) vmw_read(dev_priv, SVGA_REG_ID);
++	mutex_unlock(&dev_priv->hw_mutex);
++
+ 	/**
+ 	 * Reclaim 3d reference held by fbdev and potentially
+ 	 * start fifo.
+diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
+index 1821b74..de3c7e0 100644
+--- a/drivers/hwmon/w83627ehf.c
++++ b/drivers/hwmon/w83627ehf.c
+@@ -2083,6 +2083,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
+ 	mutex_init(&data->lock);
+ 	mutex_init(&data->update_lock);
+ 	data->name = w83627ehf_device_names[sio_data->kind];
++	data->bank = 0xff;		/* Force initial bank selection */
+ 	platform_set_drvdata(pdev, data);
+ 
+ 	/* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
+diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c
+index 63209aa..eb96f16 100644
+--- a/drivers/input/touchscreen/tsc40.c
++++ b/drivers/input/touchscreen/tsc40.c
+@@ -107,7 +107,6 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv)
+ 	__set_bit(BTN_TOUCH, input_dev->keybit);
+ 	input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0);
+ 	input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0);
+-	input_set_abs_params(ptsc->dev, ABS_PRESSURE, 0, 0, 0, 0);
+ 
+ 	serio_set_drvdata(serio, ptsc);
+ 
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 9a11dc3..b1facf9 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -1307,16 +1307,19 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+ 		 */
+ 		if ((host->flags & SDHCI_NEEDS_RETUNING) &&
+ 		    !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
+-			/* eMMC uses cmd21 while sd and sdio use cmd19 */
+-			tuning_opcode = mmc->card->type == MMC_TYPE_MMC ?
+-				MMC_SEND_TUNING_BLOCK_HS200 :
+-				MMC_SEND_TUNING_BLOCK;
+-			spin_unlock_irqrestore(&host->lock, flags);
+-			sdhci_execute_tuning(mmc, tuning_opcode);
+-			spin_lock_irqsave(&host->lock, flags);
+-
+-			/* Restore original mmc_request structure */
+-			host->mrq = mrq;
++			if (mmc->card) {
++				/* eMMC uses cmd21 but sd and sdio use cmd19 */
++				tuning_opcode =
++					mmc->card->type == MMC_TYPE_MMC ?
++					MMC_SEND_TUNING_BLOCK_HS200 :
++					MMC_SEND_TUNING_BLOCK;
++				spin_unlock_irqrestore(&host->lock, flags);
++				sdhci_execute_tuning(mmc, tuning_opcode);
++				spin_lock_irqsave(&host->lock, flags);
++
++				/* Restore original mmc_request structure */
++				host->mrq = mrq;
++			}
+ 		}
+ 
+ 		if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index ba0e493..9058d21 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -1464,9 +1464,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
+ 
+ 	platform_set_drvdata(pdev, NULL);
+ 
++	clk_disable(host->hclk);
+ 	mmc_free_host(host->mmc);
+ 	pm_runtime_put_sync(&pdev->dev);
+-	clk_disable(host->hclk);
+ 	pm_runtime_disable(&pdev->dev);
+ 
+ 	return 0;
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+index 56b20d1..116f0e9 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+@@ -2673,6 +2673,9 @@ static int ixgbe_get_ts_info(struct net_device *dev,
+ 	case ixgbe_mac_X540:
+ 	case ixgbe_mac_82599EB:
+ 		info->so_timestamping =
++			SOF_TIMESTAMPING_TX_SOFTWARE |
++			SOF_TIMESTAMPING_RX_SOFTWARE |
++			SOF_TIMESTAMPING_SOFTWARE |
+ 			SOF_TIMESTAMPING_TX_HARDWARE |
+ 			SOF_TIMESTAMPING_RX_HARDWARE |
+ 			SOF_TIMESTAMPING_RAW_HARDWARE;
+diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
+index 53743f7..af8b414 100644
+--- a/drivers/net/ethernet/nxp/lpc_eth.c
++++ b/drivers/net/ethernet/nxp/lpc_eth.c
+@@ -1524,6 +1524,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev)
+ 				  pldat->dma_buff_base_p);
+ 	free_irq(ndev->irq, ndev);
+ 	iounmap(pldat->net_base);
++	mdiobus_unregister(pldat->mii_bus);
+ 	mdiobus_free(pldat->mii_bus);
+ 	clk_disable(pldat->clk);
+ 	clk_put(pldat->clk);
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index fc9f578..9c382b5 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -1158,6 +1158,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
+ 		usb_anchor_urb(urb, &dev->deferred);
+ 		/* no use to process more packets */
+ 		netif_stop_queue(net);
++		usb_put_urb(urb);
+ 		spin_unlock_irqrestore(&dev->txq.lock, flags);
+ 		netdev_dbg(dev->net, "Delaying transmission for resumption\n");
+ 		goto deferred;
+@@ -1310,6 +1311,8 @@ void usbnet_disconnect (struct usb_interface *intf)
+ 
+ 	cancel_work_sync(&dev->kevent);
+ 
++	usb_scuttle_anchored_urbs(&dev->deferred);
++
+ 	if (dev->driver_info->unbind)
+ 		dev->driver_info->unbind (dev, intf);
+ 
+diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
+index 423a9f3..88b6acc 100644
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -312,6 +312,7 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
+ 	}
+ 
+ 	bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
++	bf->bf_next = NULL;
+ 	list_del(&bf->list);
+ 
+ 	spin_unlock_bh(&sc->tx.txbuflock);
+@@ -393,7 +394,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
+ 	u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first;
+ 	u32 ba[WME_BA_BMP_SIZE >> 5];
+ 	int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
+-	bool rc_update = true;
++	bool rc_update = true, isba;
+ 	struct ieee80211_tx_rate rates[4];
+ 	struct ath_frame_info *fi;
+ 	int nframes;
+@@ -437,13 +438,17 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
+ 	tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
+ 	tid = ATH_AN_2_TID(an, tidno);
+ 	seq_first = tid->seq_start;
++	isba = ts->ts_flags & ATH9K_TX_BA;
+ 
+ 	/*
+ 	 * The hardware occasionally sends a tx status for the wrong TID.
+ 	 * In this case, the BA status cannot be considered valid and all
+ 	 * subframes need to be retransmitted
++	 *
++	 * Only BlockAcks have a TID and therefore normal Acks cannot be
++	 * checked
+ 	 */
+-	if (tidno != ts->tid)
++	if (isba && tidno != ts->tid)
+ 		txok = false;
+ 
+ 	isaggr = bf_isaggr(bf);
+@@ -1774,6 +1779,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+ 	list_add_tail(&bf->list, &bf_head);
+ 	bf->bf_state.bf_type = 0;
+ 
++	bf->bf_next = NULL;
+ 	bf->bf_lastbf = bf;
+ 	ath_tx_fill_desc(sc, bf, txq, fi->framelen);
+ 	ath_tx_txqaddbuf(sc, txq, &bf_head, false);
+diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
+index b93516d..1345bdd 100644
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -2395,7 +2395,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
+ 	/*
+ 	 * Check if temperature compensation is supported.
+ 	 */
+-	if (tssi_bounds[4] == 0xff)
++	if (tssi_bounds[4] == 0xff || step == 0xff)
+ 		return 0;
+ 
+ 	/*
+diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
+index dd4fce2..6b6f50a 100644
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -3735,7 +3735,9 @@ restart:
+ 		 */
+ 		iscsit_thread_check_cpumask(conn, current, 1);
+ 
+-		schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
++		wait_event_interruptible(conn->queues_wq,
++					 !iscsit_conn_all_queues_empty(conn) ||
++					 ts->status == ISCSI_THREAD_SET_RESET);
+ 
+ 		if ((ts->status == ISCSI_THREAD_SET_RESET) ||
+ 		     signal_pending(current))
+diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h
+index a90294f..1d63d56 100644
+--- a/drivers/target/iscsi/iscsi_target_core.h
++++ b/drivers/target/iscsi/iscsi_target_core.h
+@@ -486,6 +486,7 @@ struct iscsi_tmr_req {
+ };
+ 
+ struct iscsi_conn {
++	wait_queue_head_t	queues_wq;
+ 	/* Authentication Successful for this connection */
+ 	u8			auth_complete;
+ 	/* State connection is currently in */
+diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
+index 6aba439..7b643ab 100644
+--- a/drivers/target/iscsi/iscsi_target_login.c
++++ b/drivers/target/iscsi/iscsi_target_login.c
+@@ -45,6 +45,7 @@ extern spinlock_t sess_idr_lock;
+ 
+ static int iscsi_login_init_conn(struct iscsi_conn *conn)
+ {
++	init_waitqueue_head(&conn->queues_wq);
+ 	INIT_LIST_HEAD(&conn->conn_list);
+ 	INIT_LIST_HEAD(&conn->conn_cmd_list);
+ 	INIT_LIST_HEAD(&conn->immed_queue_list);
+diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
+index b42cdeb..552f45a 100644
+--- a/drivers/target/iscsi/iscsi_target_util.c
++++ b/drivers/target/iscsi/iscsi_target_util.c
+@@ -488,7 +488,7 @@ void iscsit_add_cmd_to_immediate_queue(
+ 	atomic_set(&conn->check_immediate_queue, 1);
+ 	spin_unlock_bh(&conn->immed_queue_lock);
+ 
+-	wake_up_process(conn->thread_set->tx_thread);
++	wake_up(&conn->queues_wq);
+ }
+ 
+ struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn)
+@@ -562,7 +562,7 @@ void iscsit_add_cmd_to_response_queue(
+ 	atomic_inc(&cmd->response_queue_count);
+ 	spin_unlock_bh(&conn->response_queue_lock);
+ 
+-	wake_up_process(conn->thread_set->tx_thread);
++	wake_up(&conn->queues_wq);
+ }
+ 
+ struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn)
+@@ -616,6 +616,24 @@ static void iscsit_remove_cmd_from_response_queue(
+ 	}
+ }
+ 
++bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn)
++{
++	bool empty;
++
++	spin_lock_bh(&conn->immed_queue_lock);
++	empty = list_empty(&conn->immed_queue_list);
++	spin_unlock_bh(&conn->immed_queue_lock);
++
++	if (!empty)
++		return empty;
++
++	spin_lock_bh(&conn->response_queue_lock);
++	empty = list_empty(&conn->response_queue_list);
++	spin_unlock_bh(&conn->response_queue_lock);
++
++	return empty;
++}
++
+ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn)
+ {
+ 	struct iscsi_queue_req *qr, *qr_tmp;
+diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h
+index e1c729b..2ff9bbc 100644
+--- a/drivers/target/iscsi/iscsi_target_util.h
++++ b/drivers/target/iscsi/iscsi_target_util.h
+@@ -25,6 +25,7 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_
+ extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
+ extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *);
+ extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *);
++extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *);
+ extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *);
+ extern void iscsit_release_cmd(struct iscsi_cmd *);
+ extern void iscsit_free_cmd(struct iscsi_cmd *);
+diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
+index 06aca11..ac0b69f 100644
+--- a/drivers/target/target_core_configfs.c
++++ b/drivers/target/target_core_configfs.c
+@@ -3214,7 +3214,8 @@ static int __init target_core_init_configfs(void)
+ 	if (ret < 0)
+ 		goto out;
+ 
+-	if (core_dev_setup_virtual_lun0() < 0)
++	ret = core_dev_setup_virtual_lun0();
++	if (ret < 0)
+ 		goto out;
+ 
+ 	return 0;
+diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
+index 9fc9a60..68d4c10 100644
+--- a/drivers/target/target_core_device.c
++++ b/drivers/target/target_core_device.c
+@@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_device *dev)
+ 
+ static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)
+ {
+-	u32 tmp, aligned_max_sectors;
++	u32 aligned_max_sectors;
++	u32 alignment;
+ 	/*
+ 	 * Limit max_sectors to a PAGE_SIZE aligned value for modern
+ 	 * transport_allocate_data_tasks() operation.
+ 	 */
+-	tmp = rounddown((max_sectors * block_size), PAGE_SIZE);
+-	aligned_max_sectors = (tmp / block_size);
+-	if (max_sectors != aligned_max_sectors) {
+-		printk(KERN_INFO "Rounding down aligned max_sectors from %u"
+-				" to %u\n", max_sectors, aligned_max_sectors);
+-		return aligned_max_sectors;
+-	}
++	alignment = max(1ul, PAGE_SIZE / block_size);
++	aligned_max_sectors = rounddown(max_sectors, alignment);
++
++	if (max_sectors != aligned_max_sectors)
++		pr_info("Rounding down aligned max_sectors from %u to %u\n",
++			max_sectors, aligned_max_sectors);
+ 
+-	return max_sectors;
++	return aligned_max_sectors;
+ }
+ 
+ void se_dev_set_default_attribs(
+diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
+index 9229bd9..6fd434d 100644
+--- a/drivers/target/target_core_spc.c
++++ b/drivers/target/target_core_spc.c
+@@ -605,6 +605,8 @@ static int spc_emulate_inquiry(struct se_cmd *cmd)
+ 	unsigned char buf[SE_INQUIRY_BUF];
+ 	int p, ret;
+ 
++	memset(buf, 0, SE_INQUIRY_BUF);
++
+ 	if (dev == tpg->tpg_virt_lun0.lun_se_dev)
+ 		buf[0] = 0x3f; /* Not connected */
+ 	else
+diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
+index 1c59a3c..be75c43 100644
+--- a/drivers/target/target_core_tmr.c
++++ b/drivers/target/target_core_tmr.c
+@@ -140,15 +140,15 @@ void core_tmr_abort_task(
+ 		printk("ABORT_TASK: Found referenced %s task_tag: %u\n",
+ 			se_cmd->se_tfo->get_fabric_name(), ref_tag);
+ 
+-		spin_lock_irq(&se_cmd->t_state_lock);
++		spin_lock(&se_cmd->t_state_lock);
+ 		if (se_cmd->transport_state & CMD_T_COMPLETE) {
+ 			printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag);
+-			spin_unlock_irq(&se_cmd->t_state_lock);
++			spin_unlock(&se_cmd->t_state_lock);
+ 			spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+ 			goto out;
+ 		}
+ 		se_cmd->transport_state |= CMD_T_ABORTED;
+-		spin_unlock_irq(&se_cmd->t_state_lock);
++		spin_unlock(&se_cmd->t_state_lock);
+ 
+ 		list_del_init(&se_cmd->se_cmd_list);
+ 		kref_get(&se_cmd->cmd_kref);
+diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
+index 7f12416..9a113b7 100644
+--- a/drivers/xen/gntdev.c
++++ b/drivers/xen/gntdev.c
+@@ -105,6 +105,21 @@ static void gntdev_print_maps(struct gntdev_priv *priv,
+ #endif
+ }
+ 
++static void gntdev_free_map(struct grant_map *map)
++{
++	if (map == NULL)
++		return;
++
++	if (map->pages)
++		free_xenballooned_pages(map->count, map->pages);
++	kfree(map->pages);
++	kfree(map->grants);
++	kfree(map->map_ops);
++	kfree(map->unmap_ops);
++	kfree(map->kmap_ops);
++	kfree(map);
++}
++
+ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
+ {
+ 	struct grant_map *add;
+@@ -142,12 +157,7 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
+ 	return add;
+ 
+ err:
+-	kfree(add->pages);
+-	kfree(add->grants);
+-	kfree(add->map_ops);
+-	kfree(add->unmap_ops);
+-	kfree(add->kmap_ops);
+-	kfree(add);
++	gntdev_free_map(add);
+ 	return NULL;
+ }
+ 
+@@ -198,17 +208,9 @@ static void gntdev_put_map(struct grant_map *map)
+ 		evtchn_put(map->notify.event);
+ 	}
+ 
+-	if (map->pages) {
+-		if (!use_ptemod)
+-			unmap_grant_pages(map, 0, map->count);
+-
+-		free_xenballooned_pages(map->count, map->pages);
+-	}
+-	kfree(map->pages);
+-	kfree(map->grants);
+-	kfree(map->map_ops);
+-	kfree(map->unmap_ops);
+-	kfree(map);
++	if (map->pages && !use_ptemod)
++		unmap_grant_pages(map, 0, map->count);
++	gntdev_free_map(map);
+ }
+ 
+ /* ------------------------------------------------------------------ */
+diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
+index 8ff95a2..0967d0c 100644
+--- a/fs/gfs2/lops.c
++++ b/fs/gfs2/lops.c
+@@ -393,12 +393,10 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
+ 	struct gfs2_meta_header *mh;
+ 	struct gfs2_trans *tr;
+ 
+-	lock_buffer(bd->bd_bh);
+-	gfs2_log_lock(sdp);
+ 	tr = current->journal_info;
+ 	tr->tr_touched = 1;
+ 	if (!list_empty(&bd->bd_list))
+-		goto out;
++		return;
+ 	set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
+ 	set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
+ 	mh = (struct gfs2_meta_header *)bd->bd_bh->b_data;
+@@ -414,9 +412,6 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
+ 	sdp->sd_log_num_buf++;
+ 	list_add(&bd->bd_list, &sdp->sd_log_le_buf);
+ 	tr->tr_num_buf_new++;
+-out:
+-	gfs2_log_unlock(sdp);
+-	unlock_buffer(bd->bd_bh);
+ }
+ 
+ static void gfs2_check_magic(struct buffer_head *bh)
+@@ -777,12 +772,10 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
+ 	struct address_space *mapping = bd->bd_bh->b_page->mapping;
+ 	struct gfs2_inode *ip = GFS2_I(mapping->host);
+ 
+-	lock_buffer(bd->bd_bh);
+-	gfs2_log_lock(sdp);
+ 	if (tr)
+ 		tr->tr_touched = 1;
+ 	if (!list_empty(&bd->bd_list))
+-		goto out;
++		return;
+ 	set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
+ 	set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
+ 	if (gfs2_is_jdata(ip)) {
+@@ -793,9 +786,6 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
+ 	} else {
+ 		list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered);
+ 	}
+-out:
+-	gfs2_log_unlock(sdp);
+-	unlock_buffer(bd->bd_bh);
+ }
+ 
+ /**
+diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
+index adbd278..4136270 100644
+--- a/fs/gfs2/trans.c
++++ b/fs/gfs2/trans.c
+@@ -155,14 +155,22 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta)
+ 	struct gfs2_sbd *sdp = gl->gl_sbd;
+ 	struct gfs2_bufdata *bd;
+ 
++	lock_buffer(bh);
++	gfs2_log_lock(sdp);
+ 	bd = bh->b_private;
+ 	if (bd)
+ 		gfs2_assert(sdp, bd->bd_gl == gl);
+ 	else {
++		gfs2_log_unlock(sdp);
++		unlock_buffer(bh);
+ 		gfs2_attach_bufdata(gl, bh, meta);
+ 		bd = bh->b_private;
++		lock_buffer(bh);
++		gfs2_log_lock(sdp);
+ 	}
+ 	lops_add(sdp, bd);
++	gfs2_log_unlock(sdp);
++	unlock_buffer(bh);
+ }
+ 
+ void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
+diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
+index 31c26c4..ca4b11e 100644
+--- a/fs/nfs/dns_resolve.c
++++ b/fs/nfs/dns_resolve.c
+@@ -217,7 +217,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen)
+ {
+ 	char buf1[NFS_DNS_HOSTNAME_MAXLEN+1];
+ 	struct nfs_dns_ent key, *item;
+-	unsigned long ttl;
++	unsigned int ttl;
+ 	ssize_t len;
+ 	int ret = -EINVAL;
+ 
+@@ -240,7 +240,8 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen)
+ 	key.namelen = len;
+ 	memset(&key.h, 0, sizeof(key.h));
+ 
+-	ttl = get_expiry(&buf);
++	if (get_uint(&buf, &ttl) < 0)
++		goto out;
+ 	if (ttl == 0)
+ 		goto out;
+ 	key.h.expiry_time = ttl + seconds_since_boot();
+diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
+index 31fdb03..e794dee 100644
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -353,8 +353,9 @@ extern void nfs_sb_active(struct super_block *sb);
+ extern void nfs_sb_deactive(struct super_block *sb);
+ 
+ /* namespace.c */
++#define NFS_PATH_CANONICAL 1
+ extern char *nfs_path(char **p, struct dentry *dentry,
+-		      char *buffer, ssize_t buflen);
++		      char *buffer, ssize_t buflen, unsigned flags);
+ extern struct vfsmount *nfs_d_automount(struct path *path);
+ struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *,
+ 			      struct nfs_fh *, struct nfs_fattr *);
+@@ -491,7 +492,7 @@ static inline char *nfs_devname(struct dentry *dentry,
+ 				char *buffer, ssize_t buflen)
+ {
+ 	char *dummy;
+-	return nfs_path(&dummy, dentry, buffer, buflen);
++	return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL);
+ }
+ 
+ /*
+diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
+index 8e65c7f..015f71f 100644
+--- a/fs/nfs/mount_clnt.c
++++ b/fs/nfs/mount_clnt.c
+@@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *info)
+ 	else
+ 		msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT];
+ 
+-	status = rpc_call_sync(mnt_clnt, &msg, 0);
++	status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT);
+ 	rpc_shutdown_client(mnt_clnt);
+ 
+ 	if (status < 0)
+diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
+index 6559253..dd057bc 100644
+--- a/fs/nfs/namespace.c
++++ b/fs/nfs/namespace.c
+@@ -33,6 +33,7 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
+  * @dentry - pointer to dentry
+  * @buffer - result buffer
+  * @buflen - length of buffer
++ * @flags - options (see below)
+  *
+  * Helper function for constructing the server pathname
+  * by arbitrary hashed dentry.
+@@ -40,8 +41,14 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
+  * This is mainly for use in figuring out the path on the
+  * server side when automounting on top of an existing partition
+  * and in generating /proc/mounts and friends.
++ *
++ * Supported flags:
++ * NFS_PATH_CANONICAL: ensure there is exactly one slash after
++ *		       the original device (export) name
++ *		       (if unset, the original name is returned verbatim)
+  */
+-char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen)
++char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen,
++	       unsigned flags)
+ {
+ 	char *end;
+ 	int namelen;
+@@ -74,7 +81,7 @@ rename_retry:
+ 		rcu_read_unlock();
+ 		goto rename_retry;
+ 	}
+-	if (*end != '/') {
++	if ((flags & NFS_PATH_CANONICAL) && *end != '/') {
+ 		if (--buflen < 0) {
+ 			spin_unlock(&dentry->d_lock);
+ 			rcu_read_unlock();
+@@ -91,9 +98,11 @@ rename_retry:
+ 		return end;
+ 	}
+ 	namelen = strlen(base);
+-	/* Strip off excess slashes in base string */
+-	while (namelen > 0 && base[namelen - 1] == '/')
+-		namelen--;
++	if (flags & NFS_PATH_CANONICAL) {
++		/* Strip off excess slashes in base string */
++		while (namelen > 0 && base[namelen - 1] == '/')
++			namelen--;
++	}
+ 	buflen -= namelen;
+ 	if (buflen < 0) {
+ 		spin_unlock(&dentry->d_lock);
+diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
+index 017b4b0..c077b25 100644
+--- a/fs/nfs/nfs4namespace.c
++++ b/fs/nfs/nfs4namespace.c
+@@ -81,7 +81,8 @@ static char *nfs_path_component(const char *nfspath, const char *end)
+ static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)
+ {
+ 	char *limit;
+-	char *path = nfs_path(&limit, dentry, buffer, buflen);
++	char *path = nfs_path(&limit, dentry, buffer, buflen,
++			      NFS_PATH_CANONICAL);
+ 	if (!IS_ERR(path)) {
+ 		char *path_component = nfs_path_component(path, limit);
+ 		if (path_component)
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index d5a0cf1..7bff871 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -331,8 +331,7 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
+ 			dprintk("%s ERROR: %d Reset session\n", __func__,
+ 				errorcode);
+ 			nfs4_schedule_session_recovery(clp->cl_session, errorcode);
+-			exception->retry = 1;
+-			break;
++			goto wait_on_recovery;
+ #endif /* defined(CONFIG_NFS_V4_1) */
+ 		case -NFS4ERR_FILE_OPEN:
+ 			if (exception->timeout > HZ) {
+@@ -1499,9 +1498,11 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
+ 	data->timestamp = jiffies;
+ 	if (nfs4_setup_sequence(data->o_arg.server,
+ 				&data->o_arg.seq_args,
+-				&data->o_res.seq_res, task))
+-		return;
+-	rpc_call_start(task);
++				&data->o_res.seq_res,
++				task) != 0)
++		nfs_release_seqid(data->o_arg.seqid);
++	else
++		rpc_call_start(task);
+ 	return;
+ unlock_no_action:
+ 	rcu_read_unlock();
+@@ -2182,9 +2183,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
+ 	if (nfs4_setup_sequence(NFS_SERVER(calldata->inode),
+ 				&calldata->arg.seq_args,
+ 				&calldata->res.seq_res,
+-				task))
+-		goto out;
+-	rpc_call_start(task);
++				task) != 0)
++		nfs_release_seqid(calldata->arg.seqid);
++	else
++		rpc_call_start(task);
+ out:
+ 	dprintk("%s: done!\n", __func__);
+ }
+@@ -4390,6 +4392,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
+ 			if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
+ 				rpc_restart_call_prepare(task);
+ 	}
++	nfs_release_seqid(calldata->arg.seqid);
+ }
+ 
+ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
+@@ -4406,9 +4409,11 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
+ 	calldata->timestamp = jiffies;
+ 	if (nfs4_setup_sequence(calldata->server,
+ 				&calldata->arg.seq_args,
+-				&calldata->res.seq_res, task))
+-		return;
+-	rpc_call_start(task);
++				&calldata->res.seq_res,
++				task) != 0)
++		nfs_release_seqid(calldata->arg.seqid);
++	else
++		rpc_call_start(task);
+ }
+ 
+ static const struct rpc_call_ops nfs4_locku_ops = {
+@@ -4553,7 +4558,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
+ 	/* Do we need to do an open_to_lock_owner? */
+ 	if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) {
+ 		if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0)
+-			return;
++			goto out_release_lock_seqid;
+ 		data->arg.open_stateid = &state->stateid;
+ 		data->arg.new_lock_owner = 1;
+ 		data->res.open_seqid = data->arg.open_seqid;
+@@ -4562,10 +4567,15 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
+ 	data->timestamp = jiffies;
+ 	if (nfs4_setup_sequence(data->server,
+ 				&data->arg.seq_args,
+-				&data->res.seq_res, task))
++				&data->res.seq_res,
++				task) == 0) {
++		rpc_call_start(task);
+ 		return;
+-	rpc_call_start(task);
+-	dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
++	}
++	nfs_release_seqid(data->arg.open_seqid);
++out_release_lock_seqid:
++	nfs_release_seqid(data->arg.lock_seqid);
++	dprintk("%s: done!, ret = %d\n", __func__, task->tk_status);
+ }
+ 
+ static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
+diff --git a/fs/nfs/super.c b/fs/nfs/super.c
+index b8eda70..d8d7396 100644
+--- a/fs/nfs/super.c
++++ b/fs/nfs/super.c
+@@ -765,7 +765,7 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root)
+ 	int err = 0;
+ 	if (!page)
+ 		return -ENOMEM;
+-	devname = nfs_path(&dummy, root, page, PAGE_SIZE);
++	devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0);
+ 	if (IS_ERR(devname))
+ 		err = PTR_ERR(devname);
+ 	else
+diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
+index a8d0ed9..becf4a9 100644
+--- a/fs/xfs/xfs_buf_item.c
++++ b/fs/xfs/xfs_buf_item.c
+@@ -526,7 +526,25 @@ xfs_buf_item_unpin(
+ 		}
+ 		xfs_buf_relse(bp);
+ 	} else if (freed && remove) {
++		/*
++		 * There are currently two references to the buffer - the active
++		 * LRU reference and the buf log item. What we are about to do
++		 * here - simulate a failed IO completion - requires 3
++		 * references.
++		 *
++		 * The LRU reference is removed by the xfs_buf_stale() call. The
++		 * buf item reference is removed by the xfs_buf_iodone()
++		 * callback that is run by xfs_buf_do_callbacks() during ioend
++		 * processing (via the bp->b_iodone callback), and then finally
++		 * the ioend processing will drop the IO reference if the buffer
++		 * is marked XBF_ASYNC.
++		 *
++		 * Hence we need to take an additional reference here so that IO
++		 * completion processing doesn't free the buffer prematurely.
++		 */
+ 		xfs_buf_lock(bp);
++		xfs_buf_hold(bp);
++		bp->b_flags |= XBF_ASYNC;
+ 		xfs_buf_ioerror(bp, EIO);
+ 		XFS_BUF_UNDONE(bp);
+ 		xfs_buf_stale(bp);
+diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
+index 5da3ace..d308749 100644
+--- a/fs/xfs/xfs_log_recover.c
++++ b/fs/xfs/xfs_log_recover.c
+@@ -3541,7 +3541,7 @@ xlog_do_recovery_pass(
+ 				 *   - order is important.
+ 				 */
+ 				error = xlog_bread_offset(log, 0,
+-						bblks - split_bblks, hbp,
++						bblks - split_bblks, dbp,
+ 						offset + BBTOB(split_bblks));
+ 				if (error)
+ 					goto bread_err2;
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index f10553c..fb5204b 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -2633,6 +2633,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);
+ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);
+ 
+ /**
++ * ieee80211_get_mesh_hdrlen - get mesh extension header length
++ * @meshhdr: the mesh extension header, only the flags field
++ *	(first byte) will be accessed
++ * Returns the length of the extension header, which is always at
++ * least 6 bytes and at most 18 if address 5 and 6 are present.
++ */
++unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
++
++/**
+  * DOC: Data path helpers
+  *
+  * In addition to generic utilities, cfg80211 also offers
+diff --git a/include/sound/core.h b/include/sound/core.h
+index bc05668..93896ad 100644
+--- a/include/sound/core.h
++++ b/include/sound/core.h
+@@ -132,6 +132,7 @@ struct snd_card {
+ 	int shutdown;			/* this card is going down */
+ 	int free_on_last_close;		/* free in context of file_release */
+ 	wait_queue_head_t shutdown_sleep;
++	atomic_t refcount;		/* refcount for disconnection */
+ 	struct device *dev;		/* device assigned to this card */
+ 	struct device *card_dev;	/* cardX object for sysfs */
+ 
+@@ -189,6 +190,7 @@ struct snd_minor {
+ 	const struct file_operations *f_ops;	/* file operations */
+ 	void *private_data;		/* private data for f_ops->open */
+ 	struct device *dev;		/* device for sysfs */
++	struct snd_card *card_ptr;	/* assigned card instance */
+ };
+ 
+ /* return a device pointer linked to each sound device as a parent */
+@@ -295,6 +297,7 @@ int snd_card_info_done(void);
+ int snd_component_add(struct snd_card *card, const char *component);
+ int snd_card_file_add(struct snd_card *card, struct file *file);
+ int snd_card_file_remove(struct snd_card *card, struct file *file);
++void snd_card_unref(struct snd_card *card);
+ 
+ #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
+ 
+diff --git a/include/trace/events/xen.h b/include/trace/events/xen.h
+index 15ba03b..d06b6da 100644
+--- a/include/trace/events/xen.h
++++ b/include/trace/events/xen.h
+@@ -377,6 +377,14 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd,
+ DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin);
+ DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin);
+ 
++TRACE_EVENT(xen_mmu_flush_tlb_all,
++	    TP_PROTO(int x),
++	    TP_ARGS(x),
++	    TP_STRUCT__entry(__array(char, x, 0)),
++	    TP_fast_assign((void)x),
++	    TP_printk("%s", "")
++	);
++
+ TRACE_EVENT(xen_mmu_flush_tlb,
+ 	    TP_PROTO(int x),
+ 	    TP_ARGS(x),
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 3717e7b..20ef219 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb,
+ 				struct futex_pi_state **ps,
+ 				struct task_struct *task, int set_waiters)
+ {
+-	int lock_taken, ret, ownerdied = 0;
++	int lock_taken, ret, force_take = 0;
+ 	u32 uval, newval, curval, vpid = task_pid_vnr(task);
+ 
+ retry:
+@@ -755,17 +755,15 @@ retry:
+ 	newval = curval | FUTEX_WAITERS;
+ 
+ 	/*
+-	 * There are two cases, where a futex might have no owner (the
+-	 * owner TID is 0): OWNER_DIED. We take over the futex in this
+-	 * case. We also do an unconditional take over, when the owner
+-	 * of the futex died.
+-	 *
+-	 * This is safe as we are protected by the hash bucket lock !
++	 * Should we force take the futex? See below.
+ 	 */
+-	if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
+-		/* Keep the OWNER_DIED bit */
++	if (unlikely(force_take)) {
++		/*
++		 * Keep the OWNER_DIED and the WAITERS bit and set the
++		 * new TID value.
++		 */
+ 		newval = (curval & ~FUTEX_TID_MASK) | vpid;
+-		ownerdied = 0;
++		force_take = 0;
+ 		lock_taken = 1;
+ 	}
+ 
+@@ -775,7 +773,7 @@ retry:
+ 		goto retry;
+ 
+ 	/*
+-	 * We took the lock due to owner died take over.
++	 * We took the lock due to forced take over.
+ 	 */
+ 	if (unlikely(lock_taken))
+ 		return 1;
+@@ -790,20 +788,25 @@ retry:
+ 		switch (ret) {
+ 		case -ESRCH:
+ 			/*
+-			 * No owner found for this futex. Check if the
+-			 * OWNER_DIED bit is set to figure out whether
+-			 * this is a robust futex or not.
++			 * We failed to find an owner for this
++			 * futex. So we have no pi_state to block
++			 * on. This can happen in two cases:
++			 *
++			 * 1) The owner died
++			 * 2) A stale FUTEX_WAITERS bit
++			 *
++			 * Re-read the futex value.
+ 			 */
+ 			if (get_futex_value_locked(&curval, uaddr))
+ 				return -EFAULT;
+ 
+ 			/*
+-			 * We simply start over in case of a robust
+-			 * futex. The code above will take the futex
+-			 * and return happy.
++			 * If the owner died or we have a stale
++			 * WAITERS bit the owner TID in the user space
++			 * futex is 0.
+ 			 */
+-			if (curval & FUTEX_OWNER_DIED) {
+-				ownerdied = 1;
++			if (!(curval & FUTEX_TID_MASK)) {
++				force_take = 1;
+ 				goto retry;
+ 			}
+ 		default:
+diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
+index 6705d35..e7b5777 100644
+--- a/net/batman-adv/bridge_loop_avoidance.c
++++ b/net/batman-adv/bridge_loop_avoidance.c
+@@ -1205,8 +1205,8 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
+ /**
+  * batadv_bla_check_bcast_duplist
+  * @bat_priv: the bat priv with all the soft interface information
+- * @bcast_packet: originator mac address
+- * @hdr_size: maximum length of the frame
++ * @bcast_packet: encapsulated broadcast frame plus batman header
++ * @bcast_packet_len: length of encapsulated broadcast frame plus batman header
+  *
+  * check if it is on our broadcast list. Another gateway might
+  * have sent the same packet because it is connected to the same backbone,
+@@ -1219,14 +1219,14 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
+  */
+ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
+ 				   struct batadv_bcast_packet *bcast_packet,
+-				   int hdr_size)
++				   int bcast_packet_len)
+ {
+ 	int i, length, curr;
+ 	uint8_t *content;
+ 	uint16_t crc;
+ 	struct batadv_bcast_duplist_entry *entry;
+ 
+-	length = hdr_size - sizeof(*bcast_packet);
++	length = bcast_packet_len - sizeof(*bcast_packet);
+ 	content = (uint8_t *)bcast_packet;
+ 	content += sizeof(*bcast_packet);
+ 
+diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
+index bc2b88b..f861b7c 100644
+--- a/net/batman-adv/routing.c
++++ b/net/batman-adv/routing.c
+@@ -1136,8 +1136,14 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
+ 
+ 	spin_unlock_bh(&orig_node->bcast_seqno_lock);
+ 
++	/* keep skb linear for crc calculation */
++	if (skb_linearize(skb) < 0)
++		goto out;
++
++	bcast_packet = (struct batadv_bcast_packet *)skb->data;
++
+ 	/* check whether this has been sent by another originator before */
+-	if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size))
++	if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len))
+ 		goto out;
+ 
+ 	/* rebroadcast packet */
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 2fb9f59..aed87a4 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -1644,7 +1644,7 @@ static inline int deliver_skb(struct sk_buff *skb,
+ 
+ static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb)
+ {
+-	if (ptype->af_packet_priv == NULL)
++	if (!ptype->af_packet_priv || !skb->sk)
+ 		return false;
+ 
+ 	if (ptype->id_match)
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index ef172af..9708777 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -3384,10 +3384,12 @@ EXPORT_SYMBOL(__skb_warn_lro_forwarding);
+ 
+ void kfree_skb_partial(struct sk_buff *skb, bool head_stolen)
+ {
+-	if (head_stolen)
++	if (head_stolen) {
++		skb_release_head_state(skb);
+ 		kmem_cache_free(skbuff_head_cache, skb);
+-	else
++	} else {
+ 		__kfree_skb(skb);
++	}
+ }
+ EXPORT_SYMBOL(kfree_skb_partial);
+ 
+diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
+index 570e61f..6405a44 100644
+--- a/net/ipv4/inet_diag.c
++++ b/net/ipv4/inet_diag.c
+@@ -883,13 +883,16 @@ static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+ 		struct inet_diag_req_v2 *r, struct nlattr *bc)
+ {
+ 	const struct inet_diag_handler *handler;
++	int err = 0;
+ 
+ 	handler = inet_diag_lock_handler(r->sdiag_protocol);
+ 	if (!IS_ERR(handler))
+ 		handler->dump(skb, cb, r, bc);
++	else
++		err = PTR_ERR(handler);
+ 	inet_diag_unlock_handler(handler);
+ 
+-	return skb->len;
++	return err ? : skb->len;
+ }
+ 
+ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 2a1383c..c017cb1 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1166,8 +1166,12 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
+ 	spin_lock_bh(&fnhe_lock);
+ 
+ 	if (daddr == fnhe->fnhe_daddr) {
+-		struct rtable *orig;
+-
++		struct rtable *orig = rcu_dereference(fnhe->fnhe_rth);
++		if (orig && rt_is_expired(orig)) {
++			fnhe->fnhe_gw = 0;
++			fnhe->fnhe_pmtu = 0;
++			fnhe->fnhe_expires = 0;
++		}
+ 		if (fnhe->fnhe_pmtu) {
+ 			unsigned long expires = fnhe->fnhe_expires;
+ 			unsigned long diff = expires - jiffies;
+@@ -1184,7 +1188,6 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
+ 		} else if (!rt->rt_gateway)
+ 			rt->rt_gateway = daddr;
+ 
+-		orig = rcu_dereference(fnhe->fnhe_rth);
+ 		rcu_assign_pointer(fnhe->fnhe_rth, rt);
+ 		if (orig)
+ 			rt_free(orig);
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 5f64193..49dd993 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -548,14 +548,12 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
+ 			 !tp->urg_data ||
+ 			 before(tp->urg_seq, tp->copied_seq) ||
+ 			 !before(tp->urg_seq, tp->rcv_nxt)) {
+-			struct sk_buff *skb;
+ 
+ 			answ = tp->rcv_nxt - tp->copied_seq;
+ 
+-			/* Subtract 1, if FIN is in queue. */
+-			skb = skb_peek_tail(&sk->sk_receive_queue);
+-			if (answ && skb)
+-				answ -= tcp_hdr(skb)->fin;
++			/* Subtract 1, if FIN was received */
++			if (answ && sock_flag(sk, SOCK_DONE))
++				answ--;
+ 		} else
+ 			answ = tp->urg_seq - tp->copied_seq;
+ 		release_sock(sk);
+diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c
+index 813b43a..834857f 100644
+--- a/net/ipv4/tcp_illinois.c
++++ b/net/ipv4/tcp_illinois.c
+@@ -313,11 +313,13 @@ static void tcp_illinois_info(struct sock *sk, u32 ext,
+ 			.tcpv_rttcnt = ca->cnt_rtt,
+ 			.tcpv_minrtt = ca->base_rtt,
+ 		};
+-		u64 t = ca->sum_rtt;
+ 
+-		do_div(t, ca->cnt_rtt);
+-		info.tcpv_rtt = t;
++		if (info.tcpv_rttcnt > 0) {
++			u64 t = ca->sum_rtt;
+ 
++			do_div(t, info.tcpv_rttcnt);
++			info.tcpv_rtt = t;
++		}
+ 		nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
+ 	}
+ }
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index d377f48..c92c4da 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -4556,6 +4556,9 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
+ 	struct tcphdr *th;
+ 	bool fragstolen;
+ 
++	if (size == 0)
++		return 0;
++
+ 	skb = alloc_skb(size + sizeof(*th), sk->sk_allocation);
+ 	if (!skb)
+ 		goto err;
+diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
+index ff36194..2edce30 100644
+--- a/net/ipv6/ndisc.c
++++ b/net/ipv6/ndisc.c
+@@ -535,7 +535,7 @@ static void ndisc_send_unsol_na(struct net_device *dev)
+ {
+ 	struct inet6_dev *idev;
+ 	struct inet6_ifaddr *ifa;
+-	struct in6_addr mcaddr;
++	struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
+ 
+ 	idev = in6_dev_get(dev);
+ 	if (!idev)
+@@ -543,7 +543,6 @@ static void ndisc_send_unsol_na(struct net_device *dev)
+ 
+ 	read_lock_bh(&idev->lock);
+ 	list_for_each_entry(ifa, &idev->addr_list, if_list) {
+-		addrconf_addr_solict_mult(&ifa->addr, &mcaddr);
+ 		ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr,
+ 			      /*router=*/ !!idev->cnf.forwarding,
+ 			      /*solicited=*/ false, /*override=*/ true,
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 46eff42..070a3ce 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -219,7 +219,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
+ };
+ 
+ static const u32 ip6_template_metrics[RTAX_MAX] = {
+-	[RTAX_HOPLIMIT - 1] = 255,
++	[RTAX_HOPLIMIT - 1] = 0,
+ };
+ 
+ static struct rt6_info ip6_null_entry_template = {
+@@ -1241,7 +1241,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
+ 	rt->rt6i_dst.addr = fl6->daddr;
+ 	rt->rt6i_dst.plen = 128;
+ 	rt->rt6i_idev     = idev;
+-	dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
++	dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 0);
+ 
+ 	spin_lock_bh(&icmp6_dst_lock);
+ 	rt->dst.next = icmp6_dst_gc_list;
+diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
+index 3bfb34a..69bf48d 100644
+--- a/net/l2tp/l2tp_eth.c
++++ b/net/l2tp/l2tp_eth.c
+@@ -290,6 +290,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p
+ 
+ out_del_dev:
+ 	free_netdev(dev);
++	spriv->dev = NULL;
+ out_del_session:
+ 	l2tp_session_delete(session);
+ out:
+diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
+index 5746d62..327aa07 100644
+--- a/net/mac80211/ibss.c
++++ b/net/mac80211/ibss.c
+@@ -1074,7 +1074,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
+ 	sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
+ 	sdata->u.ibss.ibss_join_req = jiffies;
+ 
+-	memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
++	memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
+ 	sdata->u.ibss.ssid_len = params->ssid_len;
+ 
+ 	mutex_unlock(&sdata->u.ibss.mtx);
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 0cb4ede..37fe5ce 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -491,6 +491,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
+ 
+ 		if (ieee80211_is_action(hdr->frame_control)) {
+ 			u8 category;
++
++			/* make sure category field is present */
++			if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
++				return RX_DROP_MONITOR;
++
+ 			mgmt = (struct ieee80211_mgmt *)hdr;
+ 			category = mgmt->u.action.category;
+ 			if (category != WLAN_CATEGORY_MESH_ACTION &&
+@@ -843,14 +848,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
+ 		 */
+ 		if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
+ 		    ieee80211_is_data_present(hdr->frame_control)) {
+-			u16 ethertype;
+-			u8 *payload;
+-
+-			payload = rx->skb->data +
+-				ieee80211_hdrlen(hdr->frame_control);
+-			ethertype = (payload[6] << 8) | payload[7];
+-			if (cpu_to_be16(ethertype) ==
+-			    rx->sdata->control_port_protocol)
++			unsigned int hdrlen;
++			__be16 ethertype;
++
++			hdrlen = ieee80211_hdrlen(hdr->frame_control);
++
++			if (rx->skb->len < hdrlen + 8)
++				return RX_DROP_MONITOR;
++
++			skb_copy_bits(rx->skb, hdrlen + 6, &ethertype, 2);
++			if (ethertype == rx->sdata->control_port_protocol)
+ 				return RX_CONTINUE;
+ 		}
+ 
+@@ -1422,11 +1429,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
+ 
+ 	hdr = (struct ieee80211_hdr *)rx->skb->data;
+ 	fc = hdr->frame_control;
++
++	if (ieee80211_is_ctl(fc))
++		return RX_CONTINUE;
++
+ 	sc = le16_to_cpu(hdr->seq_ctrl);
+ 	frag = sc & IEEE80211_SCTL_FRAG;
+ 
+ 	if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
+-		   (rx->skb)->len < 24 ||
+ 		   is_multicast_ether_addr(hdr->addr1))) {
+ 		/* not fragmented */
+ 		goto out;
+@@ -1849,6 +1859,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
+ 
+ 	hdr = (struct ieee80211_hdr *) skb->data;
+ 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
++
++	/* make sure fixed part of mesh header is there, also checks skb len */
++	if (!pskb_may_pull(rx->skb, hdrlen + 6))
++		return RX_DROP_MONITOR;
++
++	mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
++
++	/* make sure full mesh header is there, also checks skb len */
++	if (!pskb_may_pull(rx->skb,
++			   hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))
++		return RX_DROP_MONITOR;
++
++	/* reload pointers */
++	hdr = (struct ieee80211_hdr *) skb->data;
+ 	mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
+ 
+ 	/* frame is in RMC, don't forward */
+@@ -1857,7 +1881,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
+ 	    mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata))
+ 		return RX_DROP_MONITOR;
+ 
+-	if (!ieee80211_is_data(hdr->frame_control))
++	if (!ieee80211_is_data(hdr->frame_control) ||
++	    !(status->rx_flags & IEEE80211_RX_RA_MATCH))
+ 		return RX_CONTINUE;
+ 
+ 	if (!mesh_hdr->ttl)
+@@ -1871,9 +1896,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
+ 		if (is_multicast_ether_addr(hdr->addr1)) {
+ 			mpp_addr = hdr->addr3;
+ 			proxied_addr = mesh_hdr->eaddr1;
+-		} else {
++		} else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {
++			/* has_a4 already checked in ieee80211_rx_mesh_check */
+ 			mpp_addr = hdr->addr4;
+ 			proxied_addr = mesh_hdr->eaddr2;
++		} else {
++			return RX_DROP_MONITOR;
+ 		}
+ 
+ 		rcu_read_lock();
+@@ -1901,9 +1929,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
+ 	}
+ 	skb_set_queue_mapping(skb, q);
+ 
+-	if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
+-		goto out;
+-
+ 	if (!--mesh_hdr->ttl) {
+ 		IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
+ 		return RX_DROP_MONITOR;
+@@ -2313,6 +2338,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
+ 		}
+ 		break;
+ 	case WLAN_CATEGORY_SELF_PROTECTED:
++		if (len < (IEEE80211_MIN_ACTION_SIZE +
++			   sizeof(mgmt->u.action.u.self_prot.action_code)))
++			break;
++
+ 		switch (mgmt->u.action.u.self_prot.action_code) {
+ 		case WLAN_SP_MESH_PEERING_OPEN:
+ 		case WLAN_SP_MESH_PEERING_CLOSE:
+@@ -2331,6 +2360,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
+ 		}
+ 		break;
+ 	case WLAN_CATEGORY_MESH_ACTION:
++		if (len < (IEEE80211_MIN_ACTION_SIZE +
++			   sizeof(mgmt->u.action.u.mesh_action.action_code)))
++			break;
++
+ 		if (!ieee80211_vif_is_mesh(&sdata->vif))
+ 			break;
+ 		if (mesh_action_is_path_sel(mgmt) &&
+@@ -2865,10 +2898,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
+ 	if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
+ 		local->dot11ReceivedFragmentCount++;
+ 
+-	if (ieee80211_is_mgmt(fc))
+-		err = skb_linearize(skb);
+-	else
++	if (ieee80211_is_mgmt(fc)) {
++		/* drop frame if too short for header */
++		if (skb->len < ieee80211_hdrlen(fc))
++			err = -ENOBUFS;
++		else
++			err = skb_linearize(skb);
++	} else {
+ 		err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
++	}
+ 
+ 	if (err) {
+ 		dev_kfree_skb(skb);
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index c9b52f7..1cfe6d5 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -637,13 +637,41 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
+ 			break;
+ 		}
+ 
+-		if (id != WLAN_EID_VENDOR_SPECIFIC &&
+-		    id != WLAN_EID_QUIET &&
+-		    test_bit(id, seen_elems)) {
+-			elems->parse_error = true;
+-			left -= elen;
+-			pos += elen;
+-			continue;
++		switch (id) {
++		case WLAN_EID_SSID:
++		case WLAN_EID_SUPP_RATES:
++		case WLAN_EID_FH_PARAMS:
++		case WLAN_EID_DS_PARAMS:
++		case WLAN_EID_CF_PARAMS:
++		case WLAN_EID_TIM:
++		case WLAN_EID_IBSS_PARAMS:
++		case WLAN_EID_CHALLENGE:
++		case WLAN_EID_RSN:
++		case WLAN_EID_ERP_INFO:
++		case WLAN_EID_EXT_SUPP_RATES:
++		case WLAN_EID_HT_CAPABILITY:
++		case WLAN_EID_HT_OPERATION:
++		case WLAN_EID_VHT_CAPABILITY:
++		case WLAN_EID_VHT_OPERATION:
++		case WLAN_EID_MESH_ID:
++		case WLAN_EID_MESH_CONFIG:
++		case WLAN_EID_PEER_MGMT:
++		case WLAN_EID_PREQ:
++		case WLAN_EID_PREP:
++		case WLAN_EID_PERR:
++		case WLAN_EID_RANN:
++		case WLAN_EID_CHANNEL_SWITCH:
++		case WLAN_EID_EXT_CHANSWITCH_ANN:
++		case WLAN_EID_COUNTRY:
++		case WLAN_EID_PWR_CONSTRAINT:
++		case WLAN_EID_TIMEOUT_INTERVAL:
++			if (test_bit(id, seen_elems)) {
++				elems->parse_error = true;
++				left -= elen;
++				pos += elen;
++				continue;
++			}
++			break;
+ 		}
+ 
+ 		if (calc_crc && id < 64 && (filter & (1ULL << id)))
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 9172179..0426b67 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -138,6 +138,8 @@ static int netlink_dump(struct sock *sk);
+ static DEFINE_RWLOCK(nl_table_lock);
+ static atomic_t nl_table_users = ATOMIC_INIT(0);
+ 
++#define nl_deref_protected(X) rcu_dereference_protected(X, lockdep_is_held(&nl_table_lock));
++
+ static ATOMIC_NOTIFIER_HEAD(netlink_chain);
+ 
+ static inline u32 netlink_group_mask(u32 group)
+@@ -345,6 +347,11 @@ netlink_update_listeners(struct sock *sk)
+ 	struct hlist_node *node;
+ 	unsigned long mask;
+ 	unsigned int i;
++	struct listeners *listeners;
++
++	listeners = nl_deref_protected(tbl->listeners);
++	if (!listeners)
++		return;
+ 
+ 	for (i = 0; i < NLGRPLONGS(tbl->groups); i++) {
+ 		mask = 0;
+@@ -352,7 +359,7 @@ netlink_update_listeners(struct sock *sk)
+ 			if (i < NLGRPLONGS(nlk_sk(sk)->ngroups))
+ 				mask |= nlk_sk(sk)->groups[i];
+ 		}
+-		tbl->listeners->masks[i] = mask;
++		listeners->masks[i] = mask;
+ 	}
+ 	/* this function is only called with the netlink table "grabbed", which
+ 	 * makes sure updates are visible before bind or setsockopt return. */
+@@ -536,7 +543,11 @@ static int netlink_release(struct socket *sock)
+ 	if (netlink_is_kernel(sk)) {
+ 		BUG_ON(nl_table[sk->sk_protocol].registered == 0);
+ 		if (--nl_table[sk->sk_protocol].registered == 0) {
+-			kfree(nl_table[sk->sk_protocol].listeners);
++			struct listeners *old;
++
++			old = nl_deref_protected(nl_table[sk->sk_protocol].listeners);
++			RCU_INIT_POINTER(nl_table[sk->sk_protocol].listeners, NULL);
++			kfree_rcu(old, rcu);
+ 			nl_table[sk->sk_protocol].module = NULL;
+ 			nl_table[sk->sk_protocol].registered = 0;
+ 		}
+@@ -978,7 +989,7 @@ int netlink_has_listeners(struct sock *sk, unsigned int group)
+ 	rcu_read_lock();
+ 	listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners);
+ 
+-	if (group - 1 < nl_table[sk->sk_protocol].groups)
++	if (listeners && group - 1 < nl_table[sk->sk_protocol].groups)
+ 		res = test_bit(group - 1, listeners->masks);
+ 
+ 	rcu_read_unlock();
+@@ -1620,7 +1631,7 @@ int __netlink_change_ngroups(struct sock *sk, unsigned int groups)
+ 		new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC);
+ 		if (!new)
+ 			return -ENOMEM;
+-		old = rcu_dereference_protected(tbl->listeners, 1);
++		old = nl_deref_protected(tbl->listeners);
+ 		memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups));
+ 		rcu_assign_pointer(tbl->listeners, new);
+ 
+diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
+index fe99628..b1c5be3 100644
+--- a/net/sctp/sm_sideeffect.c
++++ b/net/sctp/sm_sideeffect.c
+@@ -1634,8 +1634,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
+ 					asoc->outqueue.outstanding_bytes;
+ 			sackh.num_gap_ack_blocks = 0;
+ 			sackh.num_dup_tsns = 0;
++			chunk->subh.sack_hdr = &sackh;
+ 			sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK,
+-					SCTP_SACKH(&sackh));
++					SCTP_CHUNK(chunk));
+ 			break;
+ 
+ 		case SCTP_CMD_DISCARD_PACKET:
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index dcd64d5..5797032 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -506,8 +506,7 @@ int wiphy_register(struct wiphy *wiphy)
+ 		for (i = 0; i < sband->n_channels; i++) {
+ 			sband->channels[i].orig_flags =
+ 				sband->channels[i].flags;
+-			sband->channels[i].orig_mag =
+-				sband->channels[i].max_antenna_gain;
++			sband->channels[i].orig_mag = INT_MAX;
+ 			sband->channels[i].orig_mpwr =
+ 				sband->channels[i].max_power;
+ 			sband->channels[i].band = band;
+diff --git a/net/wireless/util.c b/net/wireless/util.c
+index 994e2f0..09afde7 100644
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -309,23 +309,21 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
+ }
+ EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
+ 
+-static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
++unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
+ {
+ 	int ae = meshhdr->flags & MESH_FLAGS_AE;
+-	/* 7.1.3.5a.2 */
++	/* 802.11-2012, 8.2.4.7.3 */
+ 	switch (ae) {
++	default:
+ 	case 0:
+ 		return 6;
+ 	case MESH_FLAGS_AE_A4:
+ 		return 12;
+ 	case MESH_FLAGS_AE_A5_A6:
+ 		return 18;
+-	case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6):
+-		return 24;
+-	default:
+-		return 6;
+ 	}
+ }
++EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
+ 
+ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
+ 			   enum nl80211_iftype iftype)
+@@ -373,6 +371,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
+ 			/* make sure meshdr->flags is on the linear part */
+ 			if (!pskb_may_pull(skb, hdrlen + 1))
+ 				return -1;
++			if (meshdr->flags & MESH_FLAGS_AE_A4)
++				return -1;
+ 			if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
+ 				skb_copy_bits(skb, hdrlen +
+ 					offsetof(struct ieee80211s_hdr, eaddr1),
+@@ -397,6 +397,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
+ 			/* make sure meshdr->flags is on the linear part */
+ 			if (!pskb_may_pull(skb, hdrlen + 1))
+ 				return -1;
++			if (meshdr->flags & MESH_FLAGS_AE_A5_A6)
++				return -1;
+ 			if (meshdr->flags & MESH_FLAGS_AE_A4)
+ 				skb_copy_bits(skb, hdrlen +
+ 					offsetof(struct ieee80211s_hdr, eaddr1),
+diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
+index eb60cb8..d5103f7 100644
+--- a/sound/core/compress_offload.c
++++ b/sound/core/compress_offload.c
+@@ -100,12 +100,15 @@ static int snd_compr_open(struct inode *inode, struct file *f)
+ 
+ 	if (dirn != compr->direction) {
+ 		pr_err("this device doesn't support this direction\n");
++		snd_card_unref(compr->card);
+ 		return -EINVAL;
+ 	}
+ 
+ 	data = kzalloc(sizeof(*data), GFP_KERNEL);
+-	if (!data)
++	if (!data) {
++		snd_card_unref(compr->card);
+ 		return -ENOMEM;
++	}
+ 	data->stream.ops = compr->ops;
+ 	data->stream.direction = dirn;
+ 	data->stream.private_data = compr->private_data;
+@@ -113,6 +116,7 @@ static int snd_compr_open(struct inode *inode, struct file *f)
+ 	runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
+ 	if (!runtime) {
+ 		kfree(data);
++		snd_card_unref(compr->card);
+ 		return -ENOMEM;
+ 	}
+ 	runtime->state = SNDRV_PCM_STATE_OPEN;
+@@ -126,7 +130,8 @@ static int snd_compr_open(struct inode *inode, struct file *f)
+ 		kfree(runtime);
+ 		kfree(data);
+ 	}
+-	return ret;
++	snd_card_unref(compr->card);
++	return 0;
+ }
+ 
+ static int snd_compr_free(struct inode *inode, struct file *f)
+diff --git a/sound/core/control.c b/sound/core/control.c
+index 2487a6b..daa4fc8 100644
+--- a/sound/core/control.c
++++ b/sound/core/control.c
+@@ -86,6 +86,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
+ 	write_lock_irqsave(&card->ctl_files_rwlock, flags);
+ 	list_add_tail(&ctl->list, &card->ctl_files);
+ 	write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
++	snd_card_unref(card);
+ 	return 0;
+ 
+       __error:
+@@ -93,6 +94,8 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
+       __error2:
+ 	snd_card_file_remove(card, file);
+       __error1:
++	if (card)
++		snd_card_unref(card);
+       	return err;
+ }
+ 
+@@ -1433,6 +1436,8 @@ static ssize_t snd_ctl_read(struct file *file, char __user *buffer,
+ 			spin_unlock_irq(&ctl->read_lock);
+ 			schedule();
+ 			remove_wait_queue(&ctl->change_sleep, &wait);
++			if (ctl->card->shutdown)
++				return -ENODEV;
+ 			if (signal_pending(current))
+ 				return -ERESTARTSYS;
+ 			spin_lock_irq(&ctl->read_lock);
+diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
+index 75ea16f..3f7f662 100644
+--- a/sound/core/hwdep.c
++++ b/sound/core/hwdep.c
+@@ -100,8 +100,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
+ 	if (hw == NULL)
+ 		return -ENODEV;
+ 
+-	if (!try_module_get(hw->card->module))
++	if (!try_module_get(hw->card->module)) {
++		snd_card_unref(hw->card);
+ 		return -EFAULT;
++	}
+ 
+ 	init_waitqueue_entry(&wait, current);
+ 	add_wait_queue(&hw->open_wait, &wait);
+@@ -129,6 +131,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
+ 		mutex_unlock(&hw->open_mutex);
+ 		schedule();
+ 		mutex_lock(&hw->open_mutex);
++		if (hw->card->shutdown) {
++			err = -ENODEV;
++			break;
++		}
+ 		if (signal_pending(current)) {
+ 			err = -ERESTARTSYS;
+ 			break;
+@@ -148,6 +154,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
+ 	mutex_unlock(&hw->open_mutex);
+ 	if (err < 0)
+ 		module_put(hw->card->module);
++	snd_card_unref(hw->card);
+ 	return err;
+ }
+ 
+@@ -459,12 +466,15 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device)
+ 		mutex_unlock(&register_mutex);
+ 		return -EINVAL;
+ 	}
++	mutex_lock(&hwdep->open_mutex);
++	wake_up(&hwdep->open_wait);
+ #ifdef CONFIG_SND_OSSEMUL
+ 	if (hwdep->ossreg)
+ 		snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device);
+ #endif
+ 	snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device);
+ 	list_del_init(&hwdep->list);
++	mutex_unlock(&hwdep->open_mutex);
+ 	mutex_unlock(&register_mutex);
+ 	return 0;
+ }
+diff --git a/sound/core/init.c b/sound/core/init.c
+index d8ec849..7b012d1 100644
+--- a/sound/core/init.c
++++ b/sound/core/init.c
+@@ -213,6 +213,7 @@ int snd_card_create(int idx, const char *xid,
+ 	spin_lock_init(&card->files_lock);
+ 	INIT_LIST_HEAD(&card->files_list);
+ 	init_waitqueue_head(&card->shutdown_sleep);
++	atomic_set(&card->refcount, 0);
+ #ifdef CONFIG_PM
+ 	mutex_init(&card->power_lock);
+ 	init_waitqueue_head(&card->power_sleep);
+@@ -446,21 +447,36 @@ static int snd_card_do_free(struct snd_card *card)
+ 	return 0;
+ }
+ 
++/**
++ * snd_card_unref - release the reference counter
++ * @card: the card instance
++ *
++ * Decrements the reference counter.  When it reaches to zero, wake up
++ * the sleeper and call the destructor if needed.
++ */
++void snd_card_unref(struct snd_card *card)
++{
++	if (atomic_dec_and_test(&card->refcount)) {
++		wake_up(&card->shutdown_sleep);
++		if (card->free_on_last_close)
++			snd_card_do_free(card);
++	}
++}
++EXPORT_SYMBOL(snd_card_unref);
++
+ int snd_card_free_when_closed(struct snd_card *card)
+ {
+-	int free_now = 0;
+-	int ret = snd_card_disconnect(card);
+-	if (ret)
+-		return ret;
++	int ret;
+ 
+-	spin_lock(&card->files_lock);
+-	if (list_empty(&card->files_list))
+-		free_now = 1;
+-	else
+-		card->free_on_last_close = 1;
+-	spin_unlock(&card->files_lock);
++	atomic_inc(&card->refcount);
++	ret = snd_card_disconnect(card);
++	if (ret) {
++		atomic_dec(&card->refcount);
++		return ret;
++	}
+ 
+-	if (free_now)
++	card->free_on_last_close = 1;
++	if (atomic_dec_and_test(&card->refcount))
+ 		snd_card_do_free(card);
+ 	return 0;
+ }
+@@ -474,7 +490,7 @@ int snd_card_free(struct snd_card *card)
+ 		return ret;
+ 
+ 	/* wait, until all devices are ready for the free operation */
+-	wait_event(card->shutdown_sleep, list_empty(&card->files_list));
++	wait_event(card->shutdown_sleep, !atomic_read(&card->refcount));
+ 	snd_card_do_free(card);
+ 	return 0;
+ }
+@@ -886,6 +902,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
+ 		return -ENODEV;
+ 	}
+ 	list_add(&mfile->list, &card->files_list);
++	atomic_inc(&card->refcount);
+ 	spin_unlock(&card->files_lock);
+ 	return 0;
+ }
+@@ -908,7 +925,6 @@ EXPORT_SYMBOL(snd_card_file_add);
+ int snd_card_file_remove(struct snd_card *card, struct file *file)
+ {
+ 	struct snd_monitor_file *mfile, *found = NULL;
+-	int last_close = 0;
+ 
+ 	spin_lock(&card->files_lock);
+ 	list_for_each_entry(mfile, &card->files_list, list) {
+@@ -923,19 +939,13 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
+ 			break;
+ 		}
+ 	}
+-	if (list_empty(&card->files_list))
+-		last_close = 1;
+ 	spin_unlock(&card->files_lock);
+-	if (last_close) {
+-		wake_up(&card->shutdown_sleep);
+-		if (card->free_on_last_close)
+-			snd_card_do_free(card);
+-	}
+ 	if (!found) {
+ 		snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
+ 		return -ENOENT;
+ 	}
+ 	kfree(found);
++	snd_card_unref(card);
+ 	return 0;
+ }
+ 
+diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
+index 18297f7..c353768 100644
+--- a/sound/core/oss/mixer_oss.c
++++ b/sound/core/oss/mixer_oss.c
+@@ -52,14 +52,19 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
+ 					 SNDRV_OSS_DEVICE_TYPE_MIXER);
+ 	if (card == NULL)
+ 		return -ENODEV;
+-	if (card->mixer_oss == NULL)
++	if (card->mixer_oss == NULL) {
++		snd_card_unref(card);
+ 		return -ENODEV;
++	}
+ 	err = snd_card_file_add(card, file);
+-	if (err < 0)
++	if (err < 0) {
++		snd_card_unref(card);
+ 		return err;
++	}
+ 	fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL);
+ 	if (fmixer == NULL) {
+ 		snd_card_file_remove(card, file);
++		snd_card_unref(card);
+ 		return -ENOMEM;
+ 	}
+ 	fmixer->card = card;
+@@ -68,8 +73,10 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
+ 	if (!try_module_get(card->module)) {
+ 		kfree(fmixer);
+ 		snd_card_file_remove(card, file);
++		snd_card_unref(card);
+ 		return -EFAULT;
+ 	}
++	snd_card_unref(card);
+ 	return 0;
+ }
+ 
+diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
+index 08fde00..4c1cc51 100644
+--- a/sound/core/oss/pcm_oss.c
++++ b/sound/core/oss/pcm_oss.c
+@@ -2441,6 +2441,10 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
+ 		mutex_unlock(&pcm->open_mutex);
+ 		schedule();
+ 		mutex_lock(&pcm->open_mutex);
++		if (pcm->card->shutdown) {
++			err = -ENODEV;
++			break;
++		}
+ 		if (signal_pending(current)) {
+ 			err = -ERESTARTSYS;
+ 			break;
+@@ -2450,6 +2454,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
+ 	mutex_unlock(&pcm->open_mutex);
+ 	if (err < 0)
+ 		goto __error;
++	snd_card_unref(pcm->card);
+ 	return err;
+ 
+       __error:
+@@ -2457,6 +2462,8 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
+       __error2:
+       	snd_card_file_remove(pcm->card, file);
+       __error1:
++	if (pcm)
++		snd_card_unref(pcm->card);
+ 	return err;
+ }
+ 
+diff --git a/sound/core/pcm.c b/sound/core/pcm.c
+index 1a3070b..e30e1be 100644
+--- a/sound/core/pcm.c
++++ b/sound/core/pcm.c
+@@ -1086,11 +1086,19 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
+ 	if (list_empty(&pcm->list))
+ 		goto unlock;
+ 
++	mutex_lock(&pcm->open_mutex);
++	wake_up(&pcm->open_wait);
+ 	list_del_init(&pcm->list);
+ 	for (cidx = 0; cidx < 2; cidx++)
+-		for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
+-			if (substream->runtime)
++		for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {
++			snd_pcm_stream_lock_irq(substream);
++			if (substream->runtime) {
+ 				substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
++				wake_up(&substream->runtime->sleep);
++				wake_up(&substream->runtime->tsleep);
++			}
++			snd_pcm_stream_unlock_irq(substream);
++		}
+ 	list_for_each_entry(notify, &snd_pcm_notify_list, list) {
+ 		notify->n_disconnect(pcm);
+ 	}
+@@ -1106,6 +1114,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
+ 		}
+ 		snd_unregister_device(devtype, pcm->card, pcm->device);
+ 	}
++	mutex_unlock(&pcm->open_mutex);
+  unlock:
+ 	mutex_unlock(&register_mutex);
+ 	return 0;
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
+index 53b5ada..bf3bf43 100644
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -369,6 +369,14 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime)
+ 	return usecs;
+ }
+ 
++static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state)
++{
++	snd_pcm_stream_lock_irq(substream);
++	if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED)
++		substream->runtime->status->state = state;
++	snd_pcm_stream_unlock_irq(substream);
++}
++
+ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
+ 			     struct snd_pcm_hw_params *params)
+ {
+@@ -452,7 +460,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
+ 		runtime->boundary *= 2;
+ 
+ 	snd_pcm_timer_resolution_change(substream);
+-	runtime->status->state = SNDRV_PCM_STATE_SETUP;
++	snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP);
+ 
+ 	if (pm_qos_request_active(&substream->latency_pm_qos_req))
+ 		pm_qos_remove_request(&substream->latency_pm_qos_req);
+@@ -464,7 +472,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
+ 	/* hardware might be unusable from this time,
+ 	   so we force application to retry to set
+ 	   the correct hardware parameter settings */
+-	runtime->status->state = SNDRV_PCM_STATE_OPEN;
++	snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
+ 	if (substream->ops->hw_free != NULL)
+ 		substream->ops->hw_free(substream);
+ 	return err;
+@@ -512,7 +520,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
+ 		return -EBADFD;
+ 	if (substream->ops->hw_free)
+ 		result = substream->ops->hw_free(substream);
+-	runtime->status->state = SNDRV_PCM_STATE_OPEN;
++	snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
+ 	pm_qos_remove_request(&substream->latency_pm_qos_req);
+ 	return result;
+ }
+@@ -1320,7 +1328,7 @@ static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state)
+ {
+ 	struct snd_pcm_runtime *runtime = substream->runtime;
+ 	runtime->control->appl_ptr = runtime->status->hw_ptr;
+-	runtime->status->state = SNDRV_PCM_STATE_PREPARED;
++	snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED);
+ }
+ 
+ static struct action_ops snd_pcm_action_prepare = {
+@@ -1510,6 +1518,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
+ 		down_read(&snd_pcm_link_rwsem);
+ 		snd_pcm_stream_lock_irq(substream);
+ 		remove_wait_queue(&to_check->sleep, &wait);
++		if (card->shutdown) {
++			result = -ENODEV;
++			break;
++		}
+ 		if (tout == 0) {
+ 			if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
+ 				result = -ESTRPIPE;
+@@ -1633,6 +1645,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
+ 	write_unlock_irq(&snd_pcm_link_rwlock);
+ 	up_write(&snd_pcm_link_rwsem);
+  _nolock:
++	snd_card_unref(substream1->pcm->card);
+ 	fput(file);
+ 	if (res < 0)
+ 		kfree(group);
+@@ -2107,7 +2120,10 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file)
+ 		return err;
+ 	pcm = snd_lookup_minor_data(iminor(inode),
+ 				    SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
+-	return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
++	err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
++	if (pcm)
++		snd_card_unref(pcm->card);
++	return err;
+ }
+ 
+ static int snd_pcm_capture_open(struct inode *inode, struct file *file)
+@@ -2118,7 +2134,10 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file)
+ 		return err;
+ 	pcm = snd_lookup_minor_data(iminor(inode),
+ 				    SNDRV_DEVICE_TYPE_PCM_CAPTURE);
+-	return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
++	err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
++	if (pcm)
++		snd_card_unref(pcm->card);
++	return err;
+ }
+ 
+ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
+@@ -2155,6 +2174,10 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
+ 		mutex_unlock(&pcm->open_mutex);
+ 		schedule();
+ 		mutex_lock(&pcm->open_mutex);
++		if (pcm->card->shutdown) {
++			err = -ENODEV;
++			break;
++		}
+ 		if (signal_pending(current)) {
+ 			err = -ERESTARTSYS;
+ 			break;
+diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
+index ebf6e49..1bb95ae 100644
+--- a/sound/core/rawmidi.c
++++ b/sound/core/rawmidi.c
+@@ -379,8 +379,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
+ 	if (rmidi == NULL)
+ 		return -ENODEV;
+ 
+-	if (!try_module_get(rmidi->card->module))
++	if (!try_module_get(rmidi->card->module)) {
++		snd_card_unref(rmidi->card);
+ 		return -ENXIO;
++	}
+ 
+ 	mutex_lock(&rmidi->open_mutex);
+ 	card = rmidi->card;
+@@ -422,6 +424,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
+ 		mutex_unlock(&rmidi->open_mutex);
+ 		schedule();
+ 		mutex_lock(&rmidi->open_mutex);
++		if (rmidi->card->shutdown) {
++			err = -ENODEV;
++			break;
++		}
+ 		if (signal_pending(current)) {
+ 			err = -ERESTARTSYS;
+ 			break;
+@@ -440,6 +446,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
+ #endif
+ 	file->private_data = rawmidi_file;
+ 	mutex_unlock(&rmidi->open_mutex);
++	snd_card_unref(rmidi->card);
+ 	return 0;
+ 
+  __error:
+@@ -447,6 +454,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
+  __error_card:
+ 	mutex_unlock(&rmidi->open_mutex);
+ 	module_put(rmidi->card->module);
++	snd_card_unref(rmidi->card);
+ 	return err;
+ }
+ 
+@@ -991,6 +999,8 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun
+ 			spin_unlock_irq(&runtime->lock);
+ 			schedule();
+ 			remove_wait_queue(&runtime->sleep, &wait);
++			if (rfile->rmidi->card->shutdown)
++				return -ENODEV;
+ 			if (signal_pending(current))
+ 				return result > 0 ? result : -ERESTARTSYS;
+ 			if (!runtime->avail)
+@@ -1234,6 +1244,8 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
+ 			spin_unlock_irq(&runtime->lock);
+ 			timeout = schedule_timeout(30 * HZ);
+ 			remove_wait_queue(&runtime->sleep, &wait);
++			if (rfile->rmidi->card->shutdown)
++				return -ENODEV;
+ 			if (signal_pending(current))
+ 				return result > 0 ? result : -ERESTARTSYS;
+ 			if (!runtime->avail && !timeout)
+@@ -1609,9 +1621,20 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
+ static int snd_rawmidi_dev_disconnect(struct snd_device *device)
+ {
+ 	struct snd_rawmidi *rmidi = device->device_data;
++	int dir;
+ 
+ 	mutex_lock(&register_mutex);
++	mutex_lock(&rmidi->open_mutex);
++	wake_up(&rmidi->open_wait);
+ 	list_del_init(&rmidi->list);
++	for (dir = 0; dir < 2; dir++) {
++		struct snd_rawmidi_substream *s;
++		list_for_each_entry(s, &rmidi->streams[dir].substreams, list) {
++			if (s->runtime)
++				wake_up(&s->runtime->sleep);
++		}
++	}
++
+ #ifdef CONFIG_SND_OSSEMUL
+ 	if (rmidi->ossreg) {
+ 		if ((int)rmidi->device == midi_map[rmidi->card->number]) {
+@@ -1626,6 +1649,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device)
+ 	}
+ #endif /* CONFIG_SND_OSSEMUL */
+ 	snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
++	mutex_unlock(&rmidi->open_mutex);
+ 	mutex_unlock(&register_mutex);
+ 	return 0;
+ }
+diff --git a/sound/core/sound.c b/sound/core/sound.c
+index 28f3559..3700d96 100644
+--- a/sound/core/sound.c
++++ b/sound/core/sound.c
+@@ -99,6 +99,10 @@ static void snd_request_other(int minor)
+  *
+  * Checks that a minor device with the specified type is registered, and returns
+  * its user data pointer.
++ *
++ * This function increments the reference counter of the card instance
++ * if an associated instance with the given minor number and type is found.
++ * The caller must call snd_card_unref() appropriately later.
+  */
+ void *snd_lookup_minor_data(unsigned int minor, int type)
+ {
+@@ -109,9 +113,11 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
+ 		return NULL;
+ 	mutex_lock(&sound_mutex);
+ 	mreg = snd_minors[minor];
+-	if (mreg && mreg->type == type)
++	if (mreg && mreg->type == type) {
+ 		private_data = mreg->private_data;
+-	else
++		if (private_data && mreg->card_ptr)
++			atomic_inc(&mreg->card_ptr->refcount);
++	} else
+ 		private_data = NULL;
+ 	mutex_unlock(&sound_mutex);
+ 	return private_data;
+@@ -276,6 +282,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
+ 	preg->device = dev;
+ 	preg->f_ops = f_ops;
+ 	preg->private_data = private_data;
++	preg->card_ptr = card;
+ 	mutex_lock(&sound_mutex);
+ #ifdef CONFIG_SND_DYNAMIC_MINORS
+ 	minor = snd_find_free_minor(type);
+diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
+index e952833..726a49a 100644
+--- a/sound/core/sound_oss.c
++++ b/sound/core/sound_oss.c
+@@ -40,6 +40,9 @@
+ static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
+ static DEFINE_MUTEX(sound_oss_mutex);
+ 
++/* NOTE: This function increments the refcount of the associated card like
++ * snd_lookup_minor_data(); the caller must call snd_card_unref() appropriately
++ */
+ void *snd_lookup_oss_minor_data(unsigned int minor, int type)
+ {
+ 	struct snd_minor *mreg;
+@@ -49,9 +52,11 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type)
+ 		return NULL;
+ 	mutex_lock(&sound_oss_mutex);
+ 	mreg = snd_oss_minors[minor];
+-	if (mreg && mreg->type == type)
++	if (mreg && mreg->type == type) {
+ 		private_data = mreg->private_data;
+-	else
++		if (private_data && mreg->card_ptr)
++			atomic_inc(&mreg->card_ptr->refcount);
++	} else
+ 		private_data = NULL;
+ 	mutex_unlock(&sound_oss_mutex);
+ 	return private_data;
+@@ -123,6 +128,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
+ 	preg->device = dev;
+ 	preg->f_ops = f_ops;
+ 	preg->private_data = private_data;
++	preg->card_ptr = card;
+ 	mutex_lock(&sound_oss_mutex);
+ 	snd_oss_minors[minor] = preg;
+ 	minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
+diff --git a/sound/usb/card.c b/sound/usb/card.c
+index 4a469f0..b3f5ad4 100644
+--- a/sound/usb/card.c
++++ b/sound/usb/card.c
+@@ -339,7 +339,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
+ 	}
+ 
+ 	mutex_init(&chip->mutex);
+-	mutex_init(&chip->shutdown_mutex);
++	init_rwsem(&chip->shutdown_rwsem);
+ 	chip->index = idx;
+ 	chip->dev = dev;
+ 	chip->card = card;
+@@ -559,9 +559,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
+ 		return;
+ 
+ 	card = chip->card;
+-	mutex_lock(&register_mutex);
+-	mutex_lock(&chip->shutdown_mutex);
++	down_write(&chip->shutdown_rwsem);
+ 	chip->shutdown = 1;
++	up_write(&chip->shutdown_rwsem);
++
++	mutex_lock(&register_mutex);
+ 	chip->num_interfaces--;
+ 	if (chip->num_interfaces <= 0) {
+ 		snd_card_disconnect(card);
+@@ -582,11 +584,9 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
+ 			snd_usb_mixer_disconnect(p);
+ 		}
+ 		usb_chip[chip->index] = NULL;
+-		mutex_unlock(&chip->shutdown_mutex);
+ 		mutex_unlock(&register_mutex);
+ 		snd_card_free_when_closed(card);
+ 	} else {
+-		mutex_unlock(&chip->shutdown_mutex);
+ 		mutex_unlock(&register_mutex);
+ 	}
+ }
+@@ -618,16 +618,20 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
+ {
+ 	int err = -ENODEV;
+ 
++	down_read(&chip->shutdown_rwsem);
+ 	if (!chip->shutdown && !chip->probing)
+ 		err = usb_autopm_get_interface(chip->pm_intf);
++	up_read(&chip->shutdown_rwsem);
+ 
+ 	return err;
+ }
+ 
+ void snd_usb_autosuspend(struct snd_usb_audio *chip)
+ {
++	down_read(&chip->shutdown_rwsem);
+ 	if (!chip->shutdown && !chip->probing)
+ 		usb_autopm_put_interface(chip->pm_intf);
++	up_read(&chip->shutdown_rwsem);
+ }
+ 
+ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
+diff --git a/sound/usb/card.h b/sound/usb/card.h
+index d9d2b5a..6e262c5 100644
+--- a/sound/usb/card.h
++++ b/sound/usb/card.h
+@@ -125,6 +125,7 @@ struct snd_usb_substream {
+ 	struct snd_usb_endpoint *data_endpoint;
+ 	struct snd_usb_endpoint *sync_endpoint;
+ 	unsigned long flags;
++	unsigned int speed;		/* USB_SPEED_XXX */
+ 
+ 	u64 formats;			/* format bitmasks (all or'ed) */
+ 	unsigned int num_formats;		/* number of supported audio formats (list) */
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
+index fe56c9d..298070e 100644
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -287,25 +287,32 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
+ 	unsigned char buf[2];
+ 	int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
+ 	int timeout = 10;
+-	int err;
++	int idx = 0, err;
+ 
+ 	err = snd_usb_autoresume(cval->mixer->chip);
+ 	if (err < 0)
+ 		return -EIO;
++	down_read(&chip->shutdown_rwsem);
+ 	while (timeout-- > 0) {
++		if (chip->shutdown)
++			break;
++		idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
+ 		if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
+ 				    USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+-				    validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
+-				    buf, val_len) >= val_len) {
++				    validx, idx, buf, val_len) >= val_len) {
+ 			*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
+-			snd_usb_autosuspend(cval->mixer->chip);
+-			return 0;
++			err = 0;
++			goto out;
+ 		}
+ 	}
+-	snd_usb_autosuspend(cval->mixer->chip);
+ 	snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
+-		    request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
+-	return -EINVAL;
++		    request, validx, idx, cval->val_type);
++	err = -EINVAL;
++
++ out:
++	up_read(&chip->shutdown_rwsem);
++	snd_usb_autosuspend(cval->mixer->chip);
++	return err;
+ }
+ 
+ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
+@@ -313,7 +320,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
+ 	struct snd_usb_audio *chip = cval->mixer->chip;
+ 	unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
+ 	unsigned char *val;
+-	int ret, size;
++	int idx = 0, ret, size;
+ 	__u8 bRequest;
+ 
+ 	if (request == UAC_GET_CUR) {
+@@ -330,16 +337,22 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
+ 	if (ret)
+ 		goto error;
+ 
+-	ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
++	down_read(&chip->shutdown_rwsem);
++	if (chip->shutdown)
++		ret = -ENODEV;
++	else {
++		idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
++		ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
+ 			      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+-			      validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
+-			      buf, size);
++			      validx, idx, buf, size);
++	}
++	up_read(&chip->shutdown_rwsem);
+ 	snd_usb_autosuspend(chip);
+ 
+ 	if (ret < 0) {
+ error:
+ 		snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
+-			   request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
++			   request, validx, idx, cval->val_type);
+ 		return ret;
+ 	}
+ 
+@@ -417,7 +430,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
+ {
+ 	struct snd_usb_audio *chip = cval->mixer->chip;
+ 	unsigned char buf[2];
+-	int val_len, err, timeout = 10;
++	int idx = 0, val_len, err, timeout = 10;
+ 
+ 	if (cval->mixer->protocol == UAC_VERSION_1) {
+ 		val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
+@@ -440,19 +453,27 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
+ 	err = snd_usb_autoresume(chip);
+ 	if (err < 0)
+ 		return -EIO;
+-	while (timeout-- > 0)
++	down_read(&chip->shutdown_rwsem);
++	while (timeout-- > 0) {
++		if (chip->shutdown)
++			break;
++		idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
+ 		if (snd_usb_ctl_msg(chip->dev,
+ 				    usb_sndctrlpipe(chip->dev, 0), request,
+ 				    USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
+-				    validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
+-				    buf, val_len) >= 0) {
+-			snd_usb_autosuspend(chip);
+-			return 0;
++				    validx, idx, buf, val_len) >= 0) {
++			err = 0;
++			goto out;
+ 		}
+-	snd_usb_autosuspend(chip);
++	}
+ 	snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
+-		    request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]);
+-	return -EINVAL;
++		    request, validx, idx, cval->val_type, buf[0], buf[1]);
++	err = -EINVAL;
++
++ out:
++	up_read(&chip->shutdown_rwsem);
++	snd_usb_autosuspend(chip);
++	return err;
+ }
+ 
+ static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index 690000d..ae2b714 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -283,6 +283,11 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
+ 	if (value > 1)
+ 		return -EINVAL;
+ 	changed = value != mixer->audigy2nx_leds[index];
++	down_read(&mixer->chip->shutdown_rwsem);
++	if (mixer->chip->shutdown) {
++		err = -ENODEV;
++		goto out;
++	}
+ 	if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
+ 		err = snd_usb_ctl_msg(mixer->chip->dev,
+ 			      usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
+@@ -299,6 +304,8 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
+ 			      usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
+ 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+ 			      value, index + 2, NULL, 0);
++ out:
++	up_read(&mixer->chip->shutdown_rwsem);
+ 	if (err < 0)
+ 		return err;
+ 	mixer->audigy2nx_leds[index] = value;
+@@ -392,11 +399,16 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
+ 
+ 	for (i = 0; jacks[i].name; ++i) {
+ 		snd_iprintf(buffer, "%s: ", jacks[i].name);
+-		err = snd_usb_ctl_msg(mixer->chip->dev,
++		down_read(&mixer->chip->shutdown_rwsem);
++		if (mixer->chip->shutdown)
++			err = 0;
++		else
++			err = snd_usb_ctl_msg(mixer->chip->dev,
+ 				      usb_rcvctrlpipe(mixer->chip->dev, 0),
+ 				      UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
+ 				      USB_RECIP_INTERFACE, 0,
+ 				      jacks[i].unitid << 8, buf, 3);
++		up_read(&mixer->chip->shutdown_rwsem);
+ 		if (err == 3 && (buf[0] == 3 || buf[0] == 6))
+ 			snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
+ 		else
+@@ -426,10 +438,15 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
+ 	else
+ 		new_status = old_status & ~0x02;
+ 	changed = new_status != old_status;
+-	err = snd_usb_ctl_msg(mixer->chip->dev,
++	down_read(&mixer->chip->shutdown_rwsem);
++	if (mixer->chip->shutdown)
++		err = -ENODEV;
++	else
++		err = snd_usb_ctl_msg(mixer->chip->dev,
+ 			      usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
+ 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+ 			      50, 0, &new_status, 1);
++	up_read(&mixer->chip->shutdown_rwsem);
+ 	if (err < 0)
+ 		return err;
+ 	mixer->xonar_u1_status = new_status;
+@@ -468,11 +485,17 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
+ 	u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
+ 	u16 wIndex = kcontrol->private_value & 0xffff;
+ 	u8 tmp;
++	int ret;
+ 
+-	int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
++	down_read(&mixer->chip->shutdown_rwsem);
++	if (mixer->chip->shutdown)
++		ret = -ENODEV;
++	else
++		ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
+ 				  USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+ 				  0, cpu_to_le16(wIndex),
+ 				  &tmp, sizeof(tmp), 1000);
++	up_read(&mixer->chip->shutdown_rwsem);
+ 
+ 	if (ret < 0) {
+ 		snd_printk(KERN_ERR
+@@ -493,11 +516,17 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
+ 	u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
+ 	u16 wIndex = kcontrol->private_value & 0xffff;
+ 	u16 wValue = ucontrol->value.integer.value[0];
++	int ret;
+ 
+-	int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
++	down_read(&mixer->chip->shutdown_rwsem);
++	if (mixer->chip->shutdown)
++		ret = -ENODEV;
++	else
++		ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
+ 				  USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 				  cpu_to_le16(wValue), cpu_to_le16(wIndex),
+ 				  NULL, 0, 1000);
++	up_read(&mixer->chip->shutdown_rwsem);
+ 
+ 	if (ret < 0) {
+ 		snd_printk(KERN_ERR
+@@ -656,11 +685,16 @@ static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl,
+ 		return -EINVAL;
+ 
+ 
+-	err = snd_usb_ctl_msg(chip->dev,
++	down_read(&mixer->chip->shutdown_rwsem);
++	if (mixer->chip->shutdown)
++		err = -ENODEV;
++	else
++		err = snd_usb_ctl_msg(chip->dev,
+ 			usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
+ 			USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+ 			validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
+ 			value, val_len);
++	up_read(&mixer->chip->shutdown_rwsem);
+ 	if (err < 0)
+ 		return err;
+ 
+@@ -703,11 +737,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
+ 
+ 	if (!pval->is_cached) {
+ 		/* Read current value */
+-		err = snd_usb_ctl_msg(chip->dev,
++		down_read(&mixer->chip->shutdown_rwsem);
++		if (mixer->chip->shutdown)
++			err = -ENODEV;
++		else
++			err = snd_usb_ctl_msg(chip->dev,
+ 				usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
+ 				USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+ 				validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
+ 				value, val_len);
++		up_read(&mixer->chip->shutdown_rwsem);
+ 		if (err < 0)
+ 			return err;
+ 
+@@ -719,11 +758,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
+ 	if (cur_val != new_val) {
+ 		value[0] = new_val;
+ 		value[1] = 0;
+-		err = snd_usb_ctl_msg(chip->dev,
++		down_read(&mixer->chip->shutdown_rwsem);
++		if (mixer->chip->shutdown)
++			err = -ENODEV;
++		else
++			err = snd_usb_ctl_msg(chip->dev,
+ 				usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
+ 				USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
+ 				validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
+ 				value, val_len);
++		up_read(&mixer->chip->shutdown_rwsem);
+ 		if (err < 0)
+ 			return err;
+ 
+diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
+index f782ce1..ee3c15c 100644
+--- a/sound/usb/pcm.c
++++ b/sound/usb/pcm.c
+@@ -71,6 +71,8 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream
+ 	unsigned int hwptr_done;
+ 
+ 	subs = (struct snd_usb_substream *)substream->runtime->private_data;
++	if (subs->stream->chip->shutdown)
++		return SNDRV_PCM_POS_XRUN;
+ 	spin_lock(&subs->lock);
+ 	hwptr_done = subs->hwptr_done;
+ 	substream->runtime->delay = snd_usb_pcm_delay(subs,
+@@ -471,8 +473,14 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
+ 	changed = subs->cur_audiofmt != fmt ||
+ 		subs->period_bytes != params_period_bytes(hw_params) ||
+ 		subs->cur_rate != rate;
++
++	down_read(&subs->stream->chip->shutdown_rwsem);
++	if (subs->stream->chip->shutdown) {
++		ret = -ENODEV;
++		goto unlock;
++	}
+ 	if ((ret = set_format(subs, fmt)) < 0)
+-		return ret;
++		goto unlock;
+ 
+ 	if (subs->cur_rate != rate) {
+ 		struct usb_host_interface *alts;
+@@ -481,12 +489,11 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
+ 		alts = &iface->altsetting[fmt->altset_idx];
+ 		ret = snd_usb_init_sample_rate(subs->stream->chip, fmt->iface, alts, fmt, rate);
+ 		if (ret < 0)
+-			return ret;
++			goto unlock;
+ 		subs->cur_rate = rate;
+ 	}
+ 
+ 	if (changed) {
+-		mutex_lock(&subs->stream->chip->shutdown_mutex);
+ 		/* format changed */
+ 		stop_endpoints(subs, 0, 0, 0);
+ 		ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt,
+@@ -497,8 +504,6 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
+ 		if (subs->sync_endpoint)
+ 			ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
+ 							  hw_params, fmt, NULL);
+-unlock:
+-		mutex_unlock(&subs->stream->chip->shutdown_mutex);
+ 	}
+ 
+ 	if (ret == 0) {
+@@ -506,6 +511,8 @@ unlock:
+ 		subs->altset_idx = fmt->altset_idx;
+ 	}
+ 
++unlock:
++	up_read(&subs->stream->chip->shutdown_rwsem);
+ 	return ret;
+ }
+ 
+@@ -521,10 +528,12 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
+ 	subs->cur_audiofmt = NULL;
+ 	subs->cur_rate = 0;
+ 	subs->period_bytes = 0;
+-	mutex_lock(&subs->stream->chip->shutdown_mutex);
+-	stop_endpoints(subs, 0, 1, 1);
+-	deactivate_endpoints(subs);
+-	mutex_unlock(&subs->stream->chip->shutdown_mutex);
++	down_read(&subs->stream->chip->shutdown_rwsem);
++	if (!subs->stream->chip->shutdown) {
++		stop_endpoints(subs, 0, 1, 1);
++		deactivate_endpoints(subs);
++	}
++	up_read(&subs->stream->chip->shutdown_rwsem);
+ 	return snd_pcm_lib_free_vmalloc_buffer(substream);
+ }
+ 
+@@ -537,14 +546,22 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
+ {
+ 	struct snd_pcm_runtime *runtime = substream->runtime;
+ 	struct snd_usb_substream *subs = runtime->private_data;
++	int ret = 0;
+ 
+ 	if (! subs->cur_audiofmt) {
+ 		snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
+ 		return -ENXIO;
+ 	}
+ 
+-	if (snd_BUG_ON(!subs->data_endpoint))
+-		return -EIO;
++	down_read(&subs->stream->chip->shutdown_rwsem);
++	if (subs->stream->chip->shutdown) {
++		ret = -ENODEV;
++		goto unlock;
++	}
++	if (snd_BUG_ON(!subs->data_endpoint)) {
++		ret = -EIO;
++		goto unlock;
++	}
+ 
+ 	/* some unit conversions in runtime */
+ 	subs->data_endpoint->maxframesize =
+@@ -562,9 +579,11 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
+ 	/* for playback, submit the URBs now; otherwise, the first hwptr_done
+ 	 * updates for all URBs would happen at the same time when starting */
+ 	if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
+-		return start_endpoints(subs, 1);
++		ret = start_endpoints(subs, 1);
+ 
+-	return 0;
++ unlock:
++	up_read(&subs->stream->chip->shutdown_rwsem);
++	return ret;
+ }
+ 
+ static struct snd_pcm_hardware snd_usb_hardware =
+@@ -617,7 +636,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs,
+ 		return 0;
+ 	}
+ 	/* check whether the period time is >= the data packet interval */
+-	if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) {
++	if (subs->speed != USB_SPEED_FULL) {
+ 		ptime = 125 * (1 << fp->datainterval);
+ 		if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
+ 			hwc_debug("   > check: ptime %u > max %u\n", ptime, pt->max);
+@@ -895,7 +914,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
+ 		return err;
+ 
+ 	param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
+-	if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
++	if (subs->speed == USB_SPEED_FULL)
+ 		/* full speed devices have fixed data packet interval */
+ 		ptmin = 1000;
+ 	if (ptmin == 1000)
+diff --git a/sound/usb/proc.c b/sound/usb/proc.c
+index ebc1a5b..d218f76 100644
+--- a/sound/usb/proc.c
++++ b/sound/usb/proc.c
+@@ -108,7 +108,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
+ 			}
+ 			snd_iprintf(buffer, "\n");
+ 		}
+-		if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
++		if (subs->speed != USB_SPEED_FULL)
+ 			snd_iprintf(buffer, "    Data packet interval: %d us\n",
+ 				    125 * (1 << fp->datainterval));
+ 		// snd_iprintf(buffer, "    Max Packet Size = %d\n", fp->maxpacksize);
+@@ -124,7 +124,7 @@ static void proc_dump_ep_status(struct snd_usb_substream *subs,
+ 		return;
+ 	snd_iprintf(buffer, "    Packet Size = %d\n", ep->curpacksize);
+ 	snd_iprintf(buffer, "    Momentary freq = %u Hz (%#x.%04x)\n",
+-		    snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
++		    subs->speed == USB_SPEED_FULL
+ 		    ? get_full_speed_hz(ep->freqm)
+ 		    : get_high_speed_hz(ep->freqm),
+ 		    ep->freqm >> 16, ep->freqm & 0xffff);
+diff --git a/sound/usb/stream.c b/sound/usb/stream.c
+index 083ed81..1de0c8c 100644
+--- a/sound/usb/stream.c
++++ b/sound/usb/stream.c
+@@ -90,6 +90,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
+ 	subs->direction = stream;
+ 	subs->dev = as->chip->dev;
+ 	subs->txfr_quirk = as->chip->txfr_quirk;
++	subs->speed = snd_usb_get_speed(subs->dev);
+ 
+ 	snd_usb_set_pcm_ops(as->pcm, stream);
+ 
+diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
+index b8233eb..ef42797 100644
+--- a/sound/usb/usbaudio.h
++++ b/sound/usb/usbaudio.h
+@@ -37,7 +37,7 @@ struct snd_usb_audio {
+ 	struct usb_interface *pm_intf;
+ 	u32 usb_id;
+ 	struct mutex mutex;
+-	struct mutex shutdown_mutex;
++	struct rw_semaphore shutdown_rwsem;
+ 	unsigned int shutdown:1;
+ 	unsigned int probing:1;
+ 	unsigned int autosuspended:1;	

Added: genpatches-2.6/trunk/3.6/1007_linux-3.6.8.patch
===================================================================
--- genpatches-2.6/trunk/3.6/1007_linux-3.6.8.patch	                        (rev 0)
+++ genpatches-2.6/trunk/3.6/1007_linux-3.6.8.patch	2012-11-26 22:20:36 UTC (rev 2235)
@@ -0,0 +1,2823 @@
+diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
+index 4372e6b..97aa4eb 100644
+--- a/Documentation/cgroups/memory.txt
++++ b/Documentation/cgroups/memory.txt
+@@ -466,6 +466,10 @@ Note:
+ 5.3 swappiness
+ 
+ Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
++Please note that unlike the global swappiness, memcg knob set to 0
++really prevents from any swapping even if there is a swap storage
++available. This might lead to memcg OOM killer if there are no file
++pages to reclaim.
+ 
+ Following cgroups' swappiness can't be changed.
+ - root cgroup (uses /proc/sys/vm/swappiness).
+diff --git a/Makefile b/Makefile
+index 07f2308..c5cc2f0 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 6
+-SUBLEVEL = 7
++SUBLEVEL = 8
+ EXTRAVERSION =
+ NAME = Terrified Chipmunk
+ 
+diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
+index 3e4334d..3f96658 100644
+--- a/arch/arm/boot/dts/tegra30.dtsi
++++ b/arch/arm/boot/dts/tegra30.dtsi
+@@ -73,8 +73,8 @@
+ 
+ 	pinmux: pinmux {
+ 		compatible = "nvidia,tegra30-pinmux";
+-		reg = <0x70000868 0xd0    /* Pad control registers */
+-		       0x70003000 0x3e0>; /* Mux registers */
++		reg = <0x70000868 0xd4    /* Pad control registers */
++		       0x70003000 0x3e4>; /* Mux registers */
+ 	};
+ 
+ 	serial@70006000 {
+diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
+index 1b47319..bdbbbbc 100644
+--- a/arch/arm/mach-at91/at91sam9g45_devices.c
++++ b/arch/arm/mach-at91/at91sam9g45_devices.c
+@@ -1847,8 +1847,8 @@ static struct resource sha_resources[] = {
+ 		.flags	= IORESOURCE_MEM,
+ 	},
+ 	[1] = {
+-		.start	= AT91SAM9G45_ID_AESTDESSHA,
+-		.end	= AT91SAM9G45_ID_AESTDESSHA,
++		.start	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
++		.end	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+ 		.flags	= IORESOURCE_IRQ,
+ 	},
+ };
+@@ -1880,8 +1880,8 @@ static struct resource tdes_resources[] = {
+ 		.flags	= IORESOURCE_MEM,
+ 	},
+ 	[1] = {
+-		.start	= AT91SAM9G45_ID_AESTDESSHA,
+-		.end	= AT91SAM9G45_ID_AESTDESSHA,
++		.start	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
++		.end	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+ 		.flags	= IORESOURCE_IRQ,
+ 	},
+ };
+@@ -1916,8 +1916,8 @@ static struct resource aes_resources[] = {
+ 		.flags	= IORESOURCE_MEM,
+ 	},
+ 	[1] = {
+-		.start	= AT91SAM9G45_ID_AESTDESSHA,
+-		.end	= AT91SAM9G45_ID_AESTDESSHA,
++		.start	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
++		.end	= NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+ 		.flags	= IORESOURCE_IRQ,
+ 	},
+ };
+diff --git a/arch/arm/mach-imx/ehci-imx25.c b/arch/arm/mach-imx/ehci-imx25.c
+index 05bb41d..8d5b30a 100644
+--- a/arch/arm/mach-imx/ehci-imx25.c
++++ b/arch/arm/mach-imx/ehci-imx25.c
+@@ -30,7 +30,7 @@
+ #define MX25_H1_SIC_SHIFT	21
+ #define MX25_H1_SIC_MASK	(0x3 << MX25_H1_SIC_SHIFT)
+ #define MX25_H1_PP_BIT		(1 << 18)
+-#define MX25_H1_PM_BIT		(1 << 8)
++#define MX25_H1_PM_BIT		(1 << 16)
+ #define MX25_H1_IPPUE_UP_BIT	(1 << 7)
+ #define MX25_H1_IPPUE_DOWN_BIT	(1 << 6)
+ #define MX25_H1_TLL_BIT		(1 << 5)
+diff --git a/arch/arm/mach-imx/ehci-imx35.c b/arch/arm/mach-imx/ehci-imx35.c
+index 73574c3..746ce5f 100644
+--- a/arch/arm/mach-imx/ehci-imx35.c
++++ b/arch/arm/mach-imx/ehci-imx35.c
+@@ -30,7 +30,7 @@
+ #define MX35_H1_SIC_SHIFT	21
+ #define MX35_H1_SIC_MASK	(0x3 << MX35_H1_SIC_SHIFT)
+ #define MX35_H1_PP_BIT		(1 << 18)
+-#define MX35_H1_PM_BIT		(1 << 8)
++#define MX35_H1_PM_BIT		(1 << 16)
+ #define MX35_H1_IPPUE_UP_BIT	(1 << 7)
+ #define MX35_H1_IPPUE_DOWN_BIT	(1 << 6)
+ #define MX35_H1_TLL_BIT		(1 << 5)
+diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
+index 3a57644..1a52725 100644
+--- a/arch/arm/plat-omap/include/plat/omap-serial.h
++++ b/arch/arm/plat-omap/include/plat/omap-serial.h
+@@ -42,10 +42,10 @@
+ #define OMAP_UART_WER_MOD_WKUP	0X7F
+ 
+ /* Enable XON/XOFF flow control on output */
+-#define OMAP_UART_SW_TX		0x8
++#define OMAP_UART_SW_TX		0x04
+ 
+ /* Enable XON/XOFF flow control on input */
+-#define OMAP_UART_SW_RX		0x2
++#define OMAP_UART_SW_RX		0x04
+ 
+ #define OMAP_UART_SYSC_RESET	0X07
+ #define OMAP_UART_TCR_TRIG	0X0F
+diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h
+index 60e8866..93fe83e 100644
+--- a/arch/m68k/include/asm/signal.h
++++ b/arch/m68k/include/asm/signal.h
+@@ -156,7 +156,7 @@ typedef struct sigaltstack {
+ static inline void sigaddset(sigset_t *set, int _sig)
+ {
+ 	asm ("bfset %0{%1,#1}"
+-		: "+od" (*set)
++		: "+o" (*set)
+ 		: "id" ((_sig - 1) ^ 31)
+ 		: "cc");
+ }
+@@ -164,7 +164,7 @@ static inline void sigaddset(sigset_t *set, int _sig)
+ static inline void sigdelset(sigset_t *set, int _sig)
+ {
+ 	asm ("bfclr %0{%1,#1}"
+-		: "+od" (*set)
++		: "+o" (*set)
+ 		: "id" ((_sig - 1) ^ 31)
+ 		: "cc");
+ }
+@@ -180,7 +180,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig)
+ 	int ret;
+ 	asm ("bfextu %1{%2,#1},%0"
+ 		: "=d" (ret)
+-		: "od" (*set), "id" ((_sig-1) ^ 31)
++		: "o" (*set), "id" ((_sig-1) ^ 31)
+ 		: "cc");
+ 	return ret;
+ }
+diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
+index 234f1d8..2e0a15b 100644
+--- a/arch/s390/include/asm/compat.h
++++ b/arch/s390/include/asm/compat.h
+@@ -20,7 +20,7 @@
+ #define PSW32_MASK_CC		0x00003000UL
+ #define PSW32_MASK_PM		0x00000f00UL
+ 
+-#define PSW32_MASK_USER		0x00003F00UL
++#define PSW32_MASK_USER		0x0000FF00UL
+ 
+ #define PSW32_ADDR_AMODE	0x80000000UL
+ #define PSW32_ADDR_INSN		0x7FFFFFFFUL
+diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
+index d5f08ea..f512565 100644
+--- a/arch/s390/include/asm/ptrace.h
++++ b/arch/s390/include/asm/ptrace.h
+@@ -238,7 +238,7 @@ typedef struct
+ #define PSW_MASK_EA		0x00000000UL
+ #define PSW_MASK_BA		0x00000000UL
+ 
+-#define PSW_MASK_USER		0x00003F00UL
++#define PSW_MASK_USER		0x0000FF00UL
+ 
+ #define PSW_ADDR_AMODE		0x80000000UL
+ #define PSW_ADDR_INSN		0x7FFFFFFFUL
+@@ -267,7 +267,7 @@ typedef struct
+ #define PSW_MASK_EA		0x0000000100000000UL
+ #define PSW_MASK_BA		0x0000000080000000UL
+ 
+-#define PSW_MASK_USER		0x00003F0180000000UL
++#define PSW_MASK_USER		0x0000FF0180000000UL
+ 
+ #define PSW_ADDR_AMODE		0x0000000000000000UL
+ #define PSW_ADDR_INSN		0xFFFFFFFFFFFFFFFFUL
+diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
+index a1e8a86..593fcc9 100644
+--- a/arch/s390/kernel/compat_signal.c
++++ b/arch/s390/kernel/compat_signal.c
+@@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
+ 	regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
+ 		(__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 |
+ 		(__u64)(regs32.psw.addr & PSW32_ADDR_AMODE);
++	/* Check for invalid user address space control. */
++	if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC))
++		regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
++			(regs->psw.mask & ~PSW_MASK_ASC);
+ 	regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
+ 	for (i = 0; i < NUM_GPRS; i++)
+ 		regs->gprs[i] = (__u64) regs32.gprs[i];
+@@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
+ 
+ 	/* Set up registers for signal handler */
+ 	regs->gprs[15] = (__force __u64) frame;
+-	regs->psw.mask |= PSW_MASK_BA;		/* force amode 31 */
++	/* Force 31 bit amode and default user address space control. */
++	regs->psw.mask = PSW_MASK_BA |
++		(psw_user_bits & PSW_MASK_ASC) |
++		(regs->psw.mask & ~PSW_MASK_ASC);
+ 	regs->psw.addr = (__force __u64) ka->sa.sa_handler;
+ 
+ 	regs->gprs[2] = map_signal(sig);
+@@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
+ 
+ 	/* Set up registers for signal handler */
+ 	regs->gprs[15] = (__force __u64) frame;
+-	regs->psw.mask |= PSW_MASK_BA;		/* force amode 31 */
++	/* Force 31 bit amode and default user address space control. */
++	regs->psw.mask = PSW_MASK_BA |
++		(psw_user_bits & PSW_MASK_ASC) |
++		(regs->psw.mask & ~PSW_MASK_ASC);
+ 	regs->psw.addr = (__u64) ka->sa.sa_handler;
+ 
+ 	regs->gprs[2] = map_signal(sig);
+diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
+index c13a2a3..d1259d8 100644
+--- a/arch/s390/kernel/signal.c
++++ b/arch/s390/kernel/signal.c
+@@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
+ 	/* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */
+ 	regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
+ 		(user_sregs.regs.psw.mask & PSW_MASK_USER);
++	/* Check for invalid user address space control. */
++	if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC))
++		regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
++			(regs->psw.mask & ~PSW_MASK_ASC);
+ 	/* Check for invalid amode */
+ 	if (regs->psw.mask & PSW_MASK_EA)
+ 		regs->psw.mask |= PSW_MASK_BA;
+@@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka,
+ 
+ 	/* Set up registers for signal handler */
+ 	regs->gprs[15] = (unsigned long) frame;
+-	regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA;	/* 64 bit amode */
++	/* Force default amode and default user address space control. */
++	regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
++		(psw_user_bits & PSW_MASK_ASC) |
++		(regs->psw.mask & ~PSW_MASK_ASC);
+ 	regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
+ 
+ 	regs->gprs[2] = map_signal(sig);
+@@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+ 
+ 	/* Set up registers for signal handler */
+ 	regs->gprs[15] = (unsigned long) frame;
+-	regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA;	/* 64 bit amode */
++	/* Force default amode and default user address space control. */
++	regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
++		(psw_user_bits & PSW_MASK_ASC) |
++		(regs->psw.mask & ~PSW_MASK_ASC);
+ 	regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
+ 
+ 	regs->gprs[2] = map_signal(sig);
+diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c
+index 65cb06e..4ccf9f5 100644
+--- a/arch/s390/mm/gup.c
++++ b/arch/s390/mm/gup.c
+@@ -183,7 +183,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ 	addr = start;
+ 	len = (unsigned long) nr_pages << PAGE_SHIFT;
+ 	end = start + len;
+-	if (end < start)
++	if ((end < start) || (end > TASK_SIZE))
+ 		goto slow_irqon;
+ 
+ 	/*
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index b1eb202..ff66a3b 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -6584,19 +6584,22 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
+ 		}
+ 	}
+ 
+-	exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
+ 	/* Exposing INVPCID only when PCID is exposed */
+ 	best = kvm_find_cpuid_entry(vcpu, 0x7, 0);
+ 	if (vmx_invpcid_supported() &&
+ 	    best && (best->ebx & bit(X86_FEATURE_INVPCID)) &&
+ 	    guest_cpuid_has_pcid(vcpu)) {
++		exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
+ 		exec_control |= SECONDARY_EXEC_ENABLE_INVPCID;
+ 		vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
+ 			     exec_control);
+ 	} else {
+-		exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
+-		vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
+-			     exec_control);
++		if (cpu_has_secondary_exec_ctrls()) {
++			exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
++			exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
++			vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
++				     exec_control);
++		}
+ 		if (best)
+ 			best->ebx &= ~bit(X86_FEATURE_INVPCID);
+ 	}
+diff --git a/crypto/cryptd.c b/crypto/cryptd.c
+index 671d4d6..7bdd61b 100644
+--- a/crypto/cryptd.c
++++ b/crypto/cryptd.c
+@@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct work_struct *work)
+ 	struct crypto_async_request *req, *backlog;
+ 
+ 	cpu_queue = container_of(work, struct cryptd_cpu_queue, work);
+-	/* Only handle one request at a time to avoid hogging crypto
+-	 * workqueue. preempt_disable/enable is used to prevent
+-	 * being preempted by cryptd_enqueue_request() */
++	/*
++	 * Only handle one request at a time to avoid hogging crypto workqueue.
++	 * preempt_disable/enable is used to prevent being preempted by
++	 * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent
++	 * cryptd_enqueue_request() being accessed from software interrupts.
++	 */
++	local_bh_disable();
+ 	preempt_disable();
+ 	backlog = crypto_get_backlog(&cpu_queue->queue);
+ 	req = crypto_dequeue_request(&cpu_queue->queue);
+ 	preempt_enable();
++	local_bh_enable();
+ 
+ 	if (!req)
+ 		return;
+diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
+index 1e0a9e1..9fe2659 100644
+--- a/drivers/acpi/video.c
++++ b/drivers/acpi/video.c
+@@ -1345,12 +1345,15 @@ static int
+ acpi_video_bus_get_devices(struct acpi_video_bus *video,
+ 			   struct acpi_device *device)
+ {
+-	int status;
++	int status = 0;
+ 	struct acpi_device *dev;
+ 
+-	status = acpi_video_device_enumerate(video);
+-	if (status)
+-		return status;
++	/*
++	 * There are systems where video module known to work fine regardless
++	 * of broken _DOD and ignoring returned value here doesn't cause
++	 * any issues later.
++	 */
++	acpi_video_device_enumerate(video);
+ 
+ 	list_for_each_entry(dev, &device->children, node) {
+ 
+diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
+index fd9ecf7..5b0ba3f 100644
+--- a/drivers/ata/libata-acpi.c
++++ b/drivers/ata/libata-acpi.c
+@@ -1105,10 +1105,15 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev,
+ 	struct acpi_device *acpi_dev;
+ 	struct acpi_device_power_state *states;
+ 
+-	if (ap->flags & ATA_FLAG_ACPI_SATA)
+-		ata_dev = &ap->link.device[sdev->channel];
+-	else
++	if (ap->flags & ATA_FLAG_ACPI_SATA) {
++		if (!sata_pmp_attached(ap))
++			ata_dev = &ap->link.device[sdev->id];
++		else
++			ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id];
++	}
++	else {
+ 		ata_dev = &ap->link.device[sdev->id];
++	}
+ 
+ 	*handle = ata_dev_acpi_handle(ata_dev);
+ 
+diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
+index 20cb52d..d554f64 100644
+--- a/drivers/gpu/drm/i915/intel_sdvo.c
++++ b/drivers/gpu/drm/i915/intel_sdvo.c
+@@ -2287,6 +2287,18 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
+ 	return true;
+ }
+ 
++static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo)
++{
++	struct drm_device *dev = intel_sdvo->base.base.dev;
++	struct drm_connector *connector, *tmp;
++
++	list_for_each_entry_safe(connector, tmp,
++				 &dev->mode_config.connector_list, head) {
++		if (intel_attached_encoder(connector) == &intel_sdvo->base)
++			intel_sdvo_destroy(connector);
++	}
++}
++
+ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
+ 					  struct intel_sdvo_connector *intel_sdvo_connector,
+ 					  int type)
+@@ -2606,7 +2618,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
+ 				    intel_sdvo->caps.output_flags) != true) {
+ 		DRM_DEBUG_KMS("SDVO output failed to setup on %s\n",
+ 			      SDVO_NAME(intel_sdvo));
+-		goto err;
++		/* Output_setup can leave behind connectors! */
++		goto err_output;
+ 	}
+ 
+ 	/* Only enable the hotplug irq if we need it, to work around noisy
+@@ -2619,12 +2632,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
+ 
+ 	/* Set the input timing to the screen. Assume always input 0. */
+ 	if (!intel_sdvo_set_target_input(intel_sdvo))
+-		goto err;
++		goto err_output;
+ 
+ 	if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo,
+ 						    &intel_sdvo->pixel_clock_min,
+ 						    &intel_sdvo->pixel_clock_max))
+-		goto err;
++		goto err_output;
+ 
+ 	DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
+ 			"clock range %dMHz - %dMHz, "
+@@ -2644,6 +2657,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
+ 			(SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
+ 	return true;
+ 
++err_output:
++	intel_sdvo_output_cleanup(intel_sdvo);
++
+ err:
+ 	drm_encoder_cleanup(&intel_encoder->base);
+ 	i2c_del_adapter(&intel_sdvo->ddc);
+diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
+index 6e8803a..2eb418e 100644
+--- a/drivers/gpu/drm/radeon/atombios_encoders.c
++++ b/drivers/gpu/drm/radeon/atombios_encoders.c
+@@ -1421,7 +1421,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
+ 			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
+ 			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+ 			/* some early dce3.2 boards have a bug in their transmitter control table */
+-			if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730))
++			if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730))
+ 				atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+ 		}
+ 		if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
+diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
+index ebc6fac..578207e 100644
+--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
++++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
+@@ -749,7 +749,10 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags,
+ 	/* clear the pages coming from the pool if requested */
+ 	if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) {
+ 		list_for_each_entry(p, &plist, lru) {
+-			clear_page(page_address(p));
++			if (PageHighMem(p))
++				clear_highpage(p);
++			else
++				clear_page(page_address(p));
+ 		}
+ 	}
+ 
+diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
+index 46a6697..c524018 100644
+--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
++++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
+@@ -169,7 +169,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev)
+ 	mux->busses = devm_kzalloc(&pdev->dev,
+ 				   sizeof(mux->busses) * mux->pdata->bus_count,
+ 				   GFP_KERNEL);
+-	if (!mux->states) {
++	if (!mux->busses) {
+ 		dev_err(&pdev->dev, "Cannot allocate busses\n");
+ 		ret = -ENOMEM;
+ 		goto err;
+diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
+index cb9e114..554e6ac 100644
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -4108,7 +4108,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
+ static int intel_iommu_add_device(struct device *dev)
+ {
+ 	struct pci_dev *pdev = to_pci_dev(dev);
+-	struct pci_dev *bridge, *dma_pdev;
++	struct pci_dev *bridge, *dma_pdev = NULL;
+ 	struct iommu_group *group;
+ 	int ret;
+ 
+@@ -4122,7 +4122,7 @@ static int intel_iommu_add_device(struct device *dev)
+ 			dma_pdev = pci_get_domain_bus_and_slot(
+ 						pci_domain_nr(pdev->bus),
+ 						bridge->subordinate->number, 0);
+-		else
++		if (!dma_pdev)
+ 			dma_pdev = pci_dev_get(bridge);
+ 	} else
+ 		dma_pdev = pci_dev_get(pdev);
+diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
+index f15e72e..4bd416b 100644
+--- a/drivers/net/ethernet/broadcom/Kconfig
++++ b/drivers/net/ethernet/broadcom/Kconfig
+@@ -101,6 +101,7 @@ config TIGON3
+ 	tristate "Broadcom Tigon3 support"
+ 	depends on PCI
+ 	select PHYLIB
++	select HWMON
+ 	---help---
+ 	  This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
+ 
+diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
+index bf906c5..711eb14 100644
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -44,10 +44,8 @@
+ #include <linux/prefetch.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/firmware.h>
+-#if IS_ENABLED(CONFIG_HWMON)
+ #include <linux/hwmon.h>
+ #include <linux/hwmon-sysfs.h>
+-#endif
+ 
+ #include <net/checksum.h>
+ #include <net/ip.h>
+@@ -9517,7 +9515,6 @@ static int tg3_init_hw(struct tg3 *tp, int reset_phy)
+ 	return tg3_reset_hw(tp, reset_phy);
+ }
+ 
+-#if IS_ENABLED(CONFIG_HWMON)
+ static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir)
+ {
+ 	int i;
+@@ -9570,22 +9567,17 @@ static const struct attribute_group tg3_group = {
+ 	.attrs = tg3_attributes,
+ };
+ 
+-#endif
+-
+ static void tg3_hwmon_close(struct tg3 *tp)
+ {
+-#if IS_ENABLED(CONFIG_HWMON)
+ 	if (tp->hwmon_dev) {
+ 		hwmon_device_unregister(tp->hwmon_dev);
+ 		tp->hwmon_dev = NULL;
+ 		sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group);
+ 	}
+-#endif
+ }
+ 
+ static void tg3_hwmon_open(struct tg3 *tp)
+ {
+-#if IS_ENABLED(CONFIG_HWMON)
+ 	int i, err;
+ 	u32 size = 0;
+ 	struct pci_dev *pdev = tp->pdev;
+@@ -9617,7 +9609,6 @@ static void tg3_hwmon_open(struct tg3 *tp)
+ 		dev_err(&pdev->dev, "Cannot register hwmon device, aborting\n");
+ 		sysfs_remove_group(&pdev->dev.kobj, &tg3_group);
+ 	}
+-#endif
+ }
+ 
+ 
+diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
+index b47d5b3..df7bbba 100644
+--- a/drivers/net/ethernet/realtek/r8169.c
++++ b/drivers/net/ethernet/realtek/r8169.c
+@@ -77,7 +77,7 @@
+ static const int multicast_filter_limit = 32;
+ 
+ #define MAX_READ_REQUEST_SHIFT	12
+-#define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
++#define TX_DMA_BURST	7	/* Maximum PCI burst, '7' is unlimited */
+ #define SafeMtu		0x1c20	/* ... actually life sucks beyond ~7k */
+ #define InterFrameGap	0x03	/* 3 means InterFrameGap = the shortest one */
+ 
+@@ -3832,6 +3832,8 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
+ 	void __iomem *ioaddr = tp->mmio_addr;
+ 
+ 	switch (tp->mac_version) {
++	case RTL_GIGA_MAC_VER_25:
++	case RTL_GIGA_MAC_VER_26:
+ 	case RTL_GIGA_MAC_VER_29:
+ 	case RTL_GIGA_MAC_VER_30:
+ 	case RTL_GIGA_MAC_VER_32:
+@@ -4524,6 +4526,9 @@ static void rtl_set_rx_mode(struct net_device *dev)
+ 		mc_filter[1] = swab32(data);
+ 	}
+ 
++	if (tp->mac_version == RTL_GIGA_MAC_VER_35)
++		mc_filter[1] = mc_filter[0] = 0xffffffff;
++
+ 	RTL_W32(MAR0 + 4, mc_filter[1]);
+ 	RTL_W32(MAR0 + 0, mc_filter[0]);
+ 
+diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
+index d1a61ba..c3d2751 100644
+--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
++++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
+@@ -314,6 +314,14 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
+ 			dma_map_page(trans->dev, page, 0,
+ 				     PAGE_SIZE << trans_pcie->rx_page_order,
+ 				     DMA_FROM_DEVICE);
++		if (dma_mapping_error(trans->dev, rxb->page_dma)) {
++			rxb->page = NULL;
++			spin_lock_irqsave(&rxq->lock, flags);
++			list_add(&rxb->list, &rxq->rx_used);
++			spin_unlock_irqrestore(&rxq->lock, flags);
++			__free_pages(page, trans_pcie->rx_page_order);
++			return;
++		}
+ 		/* dma address must be no more than 36 bits */
+ 		BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
+ 		/* and also 256 byte aligned! */
+@@ -463,8 +471,19 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
+ 			dma_map_page(trans->dev, rxb->page, 0,
+ 				     PAGE_SIZE << trans_pcie->rx_page_order,
+ 				     DMA_FROM_DEVICE);
+-		list_add_tail(&rxb->list, &rxq->rx_free);
+-		rxq->free_count++;
++		if (dma_mapping_error(trans->dev, rxb->page_dma)) {
++			/*
++			 * free the page(s) as well to not break
++			 * the invariant that the items on the used
++			 * list have no page(s)
++			 */
++			__free_pages(rxb->page, trans_pcie->rx_page_order);
++			rxb->page = NULL;
++			list_add_tail(&rxb->list, &rxq->rx_used);
++		} else {
++			list_add_tail(&rxb->list, &rxq->rx_free);
++			rxq->free_count++;
++		}
+ 	} else
+ 		list_add_tail(&rxb->list, &rxq->rx_used);
+ 	spin_unlock_irqrestore(&rxq->lock, flags);
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+index d6fd6b6..729e038 100644
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -421,6 +421,8 @@ static void pci_device_shutdown(struct device *dev)
+ 	struct pci_dev *pci_dev = to_pci_dev(dev);
+ 	struct pci_driver *drv = pci_dev->driver;
+ 
++	pm_runtime_resume(dev);
++
+ 	if (drv && drv->shutdown)
+ 		drv->shutdown(pci_dev);
+ 	pci_msi_shutdown(pci_dev);
+@@ -431,16 +433,6 @@ static void pci_device_shutdown(struct device *dev)
+ 	 * continue to do DMA
+ 	 */
+ 	pci_disable_device(pci_dev);
+-
+-	/*
+-	 * Devices may be enabled to wake up by runtime PM, but they need not
+-	 * be supposed to wake up the system from its "power off" state (e.g.
+-	 * ACPI S5).  Therefore disable wakeup for all devices that aren't
+-	 * supposed to wake up the system at this point.  The state argument
+-	 * will be ignored by pci_enable_wake().
+-	 */
+-	if (!device_may_wakeup(dev))
+-		pci_enable_wake(pci_dev, PCI_UNKNOWN, false);
+ }
+ 
+ #ifdef CONFIG_PM
+diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
+index 02d107b..f39378d 100644
+--- a/drivers/pci/pci-sysfs.c
++++ b/drivers/pci/pci-sysfs.c
+@@ -458,40 +458,6 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf)
+ }
+ struct device_attribute vga_attr = __ATTR_RO(boot_vga);
+ 
+-static void
+-pci_config_pm_runtime_get(struct pci_dev *pdev)
+-{
+-	struct device *dev = &pdev->dev;
+-	struct device *parent = dev->parent;
+-
+-	if (parent)
+-		pm_runtime_get_sync(parent);
+-	pm_runtime_get_noresume(dev);
+-	/*
+-	 * pdev->current_state is set to PCI_D3cold during suspending,
+-	 * so wait until suspending completes
+-	 */
+-	pm_runtime_barrier(dev);
+-	/*
+-	 * Only need to resume devices in D3cold, because config
+-	 * registers are still accessible for devices suspended but
+-	 * not in D3cold.
+-	 */
+-	if (pdev->current_state == PCI_D3cold)
+-		pm_runtime_resume(dev);
+-}
+-
+-static void
+-pci_config_pm_runtime_put(struct pci_dev *pdev)
+-{
+-	struct device *dev = &pdev->dev;
+-	struct device *parent = dev->parent;
+-
+-	pm_runtime_put(dev);
+-	if (parent)
+-		pm_runtime_put_sync(parent);
+-}
+-
+ static ssize_t
+ pci_read_config(struct file *filp, struct kobject *kobj,
+ 		struct bin_attribute *bin_attr,
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index ab4bf5a..a0f8e8f 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -1910,6 +1910,38 @@ bool pci_dev_run_wake(struct pci_dev *dev)
+ }
+ EXPORT_SYMBOL_GPL(pci_dev_run_wake);
+ 
++void pci_config_pm_runtime_get(struct pci_dev *pdev)
++{
++	struct device *dev = &pdev->dev;
++	struct device *parent = dev->parent;
++
++	if (parent)
++		pm_runtime_get_sync(parent);
++	pm_runtime_get_noresume(dev);
++	/*
++	 * pdev->current_state is set to PCI_D3cold during suspending,
++	 * so wait until suspending completes
++	 */
++	pm_runtime_barrier(dev);
++	/*
++	 * Only need to resume devices in D3cold, because config
++	 * registers are still accessible for devices suspended but
++	 * not in D3cold.
++	 */
++	if (pdev->current_state == PCI_D3cold)
++		pm_runtime_resume(dev);
++}
++
++void pci_config_pm_runtime_put(struct pci_dev *pdev)
++{
++	struct device *dev = &pdev->dev;
++	struct device *parent = dev->parent;
++
++	pm_runtime_put(dev);
++	if (parent)
++		pm_runtime_put_sync(parent);
++}
++
+ /**
+  * pci_pm_init - Initialize PM functions of given PCI device
+  * @dev: PCI device to handle.
+diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
+index bacbcba..fd92aab 100644
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -72,6 +72,8 @@ extern void pci_disable_enabled_device(struct pci_dev *dev);
+ extern int pci_finish_runtime_suspend(struct pci_dev *dev);
+ extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign);
+ extern void pci_wakeup_bus(struct pci_bus *bus);
++extern void pci_config_pm_runtime_get(struct pci_dev *dev);
++extern void pci_config_pm_runtime_put(struct pci_dev *dev);
+ extern void pci_pm_init(struct pci_dev *dev);
+ extern void platform_pci_wakeup_init(struct pci_dev *dev);
+ extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
+diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
+index 27911b5..af028c7 100644
+--- a/drivers/pci/proc.c
++++ b/drivers/pci/proc.c
+@@ -76,6 +76,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
+ 	if (!access_ok(VERIFY_WRITE, buf, cnt))
+ 		return -EINVAL;
+ 
++	pci_config_pm_runtime_get(dev);
++
+ 	if ((pos & 1) && cnt) {
+ 		unsigned char val;
+ 		pci_user_read_config_byte(dev, pos, &val);
+@@ -121,6 +123,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
+ 		cnt--;
+ 	}
+ 
++	pci_config_pm_runtime_put(dev);
++
+ 	*ppos = pos;
+ 	return nbytes;
+ }
+@@ -146,6 +150,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
+ 	if (!access_ok(VERIFY_READ, buf, cnt))
+ 		return -EINVAL;
+ 
++	pci_config_pm_runtime_get(dev);
++
+ 	if ((pos & 1) && cnt) {
+ 		unsigned char val;
+ 		__get_user(val, buf);
+@@ -191,6 +197,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
+ 		cnt--;
+ 	}
+ 
++	pci_config_pm_runtime_put(dev);
++
+ 	*ppos = pos;
+ 	i_size_write(ino, dp->size);
+ 	return nbytes;
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 4838531..e6f2990a 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1942,7 +1942,7 @@ int regulator_is_supported_voltage(struct regulator *regulator,
+ 	if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
+ 		ret = regulator_get_voltage(regulator);
+ 		if (ret >= 0)
+-			return (min_uV >= ret && ret <= max_uV);
++			return (min_uV <= ret && ret <= max_uV);
+ 		else
+ 			return ret;
+ 	}
+diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
+index 45385f5..446fdd8 100644
+--- a/drivers/scsi/isci/host.c
++++ b/drivers/scsi/isci/host.c
+@@ -1079,7 +1079,6 @@ static void sci_controller_completion_handler(struct isci_host *ihost)
+ 
+ void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_task *task)
+ {
+-	task->lldd_task = NULL;
+ 	if (!test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags) &&
+ 	    !(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
+ 		if (test_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags)) {
+@@ -1087,16 +1086,19 @@ void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_ta
+ 			dev_dbg(&ihost->pdev->dev,
+ 				"%s: Normal - ireq/task = %p/%p\n",
+ 				__func__, ireq, task);
+-
++			task->lldd_task = NULL;
+ 			task->task_done(task);
+ 		} else {
+ 			dev_dbg(&ihost->pdev->dev,
+ 				"%s: Error - ireq/task = %p/%p\n",
+ 				__func__, ireq, task);
+-
++			if (sas_protocol_ata(task->task_proto))
++				task->lldd_task = NULL;
+ 			sas_task_abort(task);
+ 		}
+-	}
++	} else
++		task->lldd_task = NULL;
++
+ 	if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags))
+ 		wake_up_all(&ihost->eventq);
+ 
+diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h
+index f2ffd96..d0cafd6 100644
+--- a/drivers/staging/android/android_alarm.h
++++ b/drivers/staging/android/android_alarm.h
+@@ -51,12 +51,10 @@ enum android_alarm_return_flags {
+ #define ANDROID_ALARM_WAIT                  _IO('a', 1)
+ 
+ #define ALARM_IOW(c, type, size)            _IOW('a', (c) | ((type) << 4), size)
+-#define ALARM_IOR(c, type, size)            _IOR('a', (c) | ((type) << 4), size)
+-
+ /* Set alarm */
+ #define ANDROID_ALARM_SET(type)             ALARM_IOW(2, type, struct timespec)
+ #define ANDROID_ALARM_SET_AND_WAIT(type)    ALARM_IOW(3, type, struct timespec)
+-#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOR(4, type, struct timespec)
++#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOW(4, type, struct timespec)
+ #define ANDROID_ALARM_SET_RTC               _IOW('a', 5, struct timespec)
+ #define ANDROID_ALARM_BASE_CMD(cmd)         (cmd & ~(_IOC(0, 0, 0xf0, 0)))
+ #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd)    (_IOC_NR(cmd) >> 4)
+diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
+index 22992cd..d3cda0c 100644
+--- a/drivers/tty/serial/omap-serial.c
++++ b/drivers/tty/serial/omap-serial.c
+@@ -667,19 +667,19 @@ serial_omap_configure_xonxoff
+ 
+ 	/*
+ 	 * IXON Flag:
+-	 * Flow control for OMAP.TX
+-	 * OMAP.RX should listen for XON/XOFF
++	 * Enable XON/XOFF flow control on output.
++	 * Transmit XON1, XOFF1
+ 	 */
+ 	if (termios->c_iflag & IXON)
+-		up->efr |= OMAP_UART_SW_RX;
++		up->efr |= OMAP_UART_SW_TX;
+ 
+ 	/*
+ 	 * IXOFF Flag:
+-	 * Flow control for OMAP.RX
+-	 * OMAP.TX should send XON/XOFF
++	 * Enable XON/XOFF flow control on input.
++	 * Receiver compares XON1, XOFF1.
+ 	 */
+ 	if (termios->c_iflag & IXOFF)
+-		up->efr |= OMAP_UART_SW_TX;
++		up->efr |= OMAP_UART_SW_RX;
+ 
+ 	serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
+ 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
+index f6788d7..059d44b 100644
+--- a/drivers/usb/serial/keyspan.c
++++ b/drivers/usb/serial/keyspan.c
+@@ -2448,7 +2448,7 @@ static void keyspan_release(struct usb_serial *serial)
+ static int keyspan_port_probe(struct usb_serial_port *port)
+ {
+ 	struct usb_serial *serial = port->serial;
+-	struct keyspan_port_private *s_priv;
++	struct keyspan_serial_private *s_priv;
+ 	struct keyspan_port_private *p_priv;
+ 	const struct keyspan_device_details *d_details;
+ 	struct callbacks *cback;
+@@ -2463,7 +2463,6 @@ static int keyspan_port_probe(struct usb_serial_port *port)
+ 	if (!p_priv)
+ 		return -ENOMEM;
+ 
+-	s_priv = usb_get_serial_data(port->serial);
+ 	p_priv->device_details = d_details;
+ 
+ 	/* Setup values for the various callback routines */
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 76a48e4..f852329 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -158,6 +158,7 @@ static void option_instat_callback(struct urb *urb);
+ #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED	0x8001
+ #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED	0x9000
+ #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED	0x9001
++#define NOVATELWIRELESS_PRODUCT_E362		0x9010
+ #define NOVATELWIRELESS_PRODUCT_G1		0xA001
+ #define NOVATELWIRELESS_PRODUCT_G1_M		0xA002
+ #define NOVATELWIRELESS_PRODUCT_G2		0xA010
+@@ -193,6 +194,9 @@ static void option_instat_callback(struct urb *urb);
+ #define DELL_PRODUCT_5730_MINICARD_TELUS	0x8181
+ #define DELL_PRODUCT_5730_MINICARD_VZW		0x8182
+ 
++#define DELL_PRODUCT_5800_MINICARD_VZW		0x8195  /* Novatel E362 */
++#define DELL_PRODUCT_5800_V2_MINICARD_VZW	0x8196  /* Novatel E362 */
++
+ #define KYOCERA_VENDOR_ID			0x0c88
+ #define KYOCERA_PRODUCT_KPC650			0x17da
+ #define KYOCERA_PRODUCT_KPC680			0x180a
+@@ -283,6 +287,7 @@ static void option_instat_callback(struct urb *urb);
+ /* ALCATEL PRODUCTS */
+ #define ALCATEL_VENDOR_ID			0x1bbb
+ #define ALCATEL_PRODUCT_X060S_X200		0x0000
++#define ALCATEL_PRODUCT_X220_X500D		0x0017
+ 
+ #define PIRELLI_VENDOR_ID			0x1266
+ #define PIRELLI_PRODUCT_C100_1			0x1002
+@@ -706,6 +711,7 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) },
+ 	/* Novatel Ovation MC551 a.k.a. Verizon USB551L */
+ 	{ 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(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
+ 	{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
+@@ -728,6 +734,8 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) },	/* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
+ 	{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) },	/* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
+ 	{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, 	/* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
++	{ USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) },
+ 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },	/* ADU-E100, ADU-310 */
+ 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
+ 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
+@@ -1157,6 +1165,7 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
+ 	  .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
+ 	},
++	{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) },
+ 	{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
+ 	{ USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
+ 	{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
+diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
+index 2f2d074..188b5b3 100644
+--- a/drivers/usb/serial/usb_wwan.c
++++ b/drivers/usb/serial/usb_wwan.c
+@@ -455,9 +455,6 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
+ 	struct usb_serial *serial = port->serial;
+ 	struct urb *urb;
+ 
+-	if (endpoint == -1)
+-		return NULL;	/* endpoint not needed */
+-
+ 	urb = usb_alloc_urb(0, GFP_KERNEL);	/* No ISO */
+ 	if (urb == NULL) {
+ 		dbg("%s: alloc for endpoint %d failed.", __func__, endpoint);
+@@ -487,6 +484,9 @@ int usb_wwan_port_probe(struct usb_serial_port *port)
+ 	init_usb_anchor(&portdata->delayed);
+ 
+ 	for (i = 0; i < N_IN_URB; i++) {
++		if (!port->bulk_in_size)
++			break;
++
+ 		buffer = (u8 *)__get_free_page(GFP_KERNEL);
+ 		if (!buffer)
+ 			goto bail_out_error;
+@@ -499,8 +499,8 @@ int usb_wwan_port_probe(struct usb_serial_port *port)
+ 		portdata->in_urbs[i] = urb;
+  	}
+ 	for (i = 0; i < N_OUT_URB; i++) {
+-		if (port->bulk_out_endpointAddress == -1)
+-			continue;
++		if (!port->bulk_out_size)
++			break;
+ 
+ 		buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
+ 		if (!buffer)
+diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
+index c3b3f7f..abd47c7 100644
+--- a/drivers/virtio/virtio.c
++++ b/drivers/virtio/virtio.c
+@@ -225,8 +225,10 @@ EXPORT_SYMBOL_GPL(register_virtio_device);
+ 
+ void unregister_virtio_device(struct virtio_device *dev)
+ {
++	int index = dev->index; /* save for after device release */
++
+ 	device_unregister(&dev->dev);
+-	ida_simple_remove(&virtio_index_ida, dev->index);
++	ida_simple_remove(&virtio_index_ida, index);
+ }
+ EXPORT_SYMBOL_GPL(unregister_virtio_device);
+ 
+diff --git a/drivers/xen/events.c b/drivers/xen/events.c
+index 7595581..99c5345 100644
+--- a/drivers/xen/events.c
++++ b/drivers/xen/events.c
+@@ -1374,8 +1374,8 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
+ {
+ 	struct pt_regs *old_regs = set_irq_regs(regs);
+ 
+-	exit_idle();
+ 	irq_enter();
++	exit_idle();
+ 
+ 	__xen_evtchn_do_upcall();
+ 
+diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
+index 05f4dc2..8d453b7 100644
+--- a/fs/cifs/cifsacl.c
++++ b/fs/cifs/cifsacl.c
+@@ -225,6 +225,13 @@ sid_to_str(struct cifs_sid *sidptr, char *sidstr)
+ }
+ 
+ static void
++cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
++{
++	memcpy(dst, src, sizeof(*dst));
++	dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS);
++}
++
++static void
+ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
+ 		struct cifs_sid_id **psidid, char *typestr)
+ {
+@@ -248,7 +255,7 @@ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
+ 		}
+ 	}
+ 
+-	memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid));
++	cifs_copy_sid(&(*psidid)->sid, sidptr);
+ 	(*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
+ 	(*psidid)->refcount = 0;
+ 
+@@ -354,7 +361,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
+ 	 * any fields of the node after a reference is put .
+ 	 */
+ 	if (test_bit(SID_ID_MAPPED, &psidid->state)) {
+-		memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
++		cifs_copy_sid(ssid, &psidid->sid);
+ 		psidid->time = jiffies; /* update ts for accessing */
+ 		goto id_sid_out;
+ 	}
+@@ -370,14 +377,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
+ 		if (IS_ERR(sidkey)) {
+ 			rc = -EINVAL;
+ 			cFYI(1, "%s: Can't map and id to a SID", __func__);
++		} else if (sidkey->datalen < sizeof(struct cifs_sid)) {
++			rc = -EIO;
++			cFYI(1, "%s: Downcall contained malformed key "
++				"(datalen=%hu)", __func__, sidkey->datalen);
+ 		} else {
+ 			lsid = (struct cifs_sid *)sidkey->payload.data;
+-			memcpy(&psidid->sid, lsid,
+-				sidkey->datalen < sizeof(struct cifs_sid) ?
+-				sidkey->datalen : sizeof(struct cifs_sid));
+-			memcpy(ssid, &psidid->sid,
+-				sidkey->datalen < sizeof(struct cifs_sid) ?
+-				sidkey->datalen : sizeof(struct cifs_sid));
++			cifs_copy_sid(&psidid->sid, lsid);
++			cifs_copy_sid(ssid, &psidid->sid);
+ 			set_bit(SID_ID_MAPPED, &psidid->state);
+ 			key_put(sidkey);
+ 			kfree(psidid->sidstr);
+@@ -396,7 +403,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
+ 			return rc;
+ 		}
+ 		if (test_bit(SID_ID_MAPPED, &psidid->state))
+-			memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
++			cifs_copy_sid(ssid, &psidid->sid);
+ 		else
+ 			rc = -EINVAL;
+ 	}
+@@ -675,8 +682,6 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
+ static void copy_sec_desc(const struct cifs_ntsd *pntsd,
+ 				struct cifs_ntsd *pnntsd, __u32 sidsoffset)
+ {
+-	int i;
+-
+ 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
+ 	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
+ 
+@@ -692,26 +697,14 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd,
+ 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+ 				le32_to_cpu(pntsd->osidoffset));
+ 	nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
+-
+-	nowner_sid_ptr->revision = owner_sid_ptr->revision;
+-	nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
+-	for (i = 0; i < 6; i++)
+-		nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
+-	for (i = 0; i < 5; i++)
+-		nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
++	cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
+ 
+ 	/* copy group sid */
+ 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+ 				le32_to_cpu(pntsd->gsidoffset));
+ 	ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
+ 					sizeof(struct cifs_sid));
+-
+-	ngroup_sid_ptr->revision = group_sid_ptr->revision;
+-	ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
+-	for (i = 0; i < 6; i++)
+-		ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
+-	for (i = 0; i < 5; i++)
+-		ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
++	cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
+ 
+ 	return;
+ }
+@@ -1120,8 +1113,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
+ 				kfree(nowner_sid_ptr);
+ 				return rc;
+ 			}
+-			memcpy(owner_sid_ptr, nowner_sid_ptr,
+-					sizeof(struct cifs_sid));
++			cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
+ 			kfree(nowner_sid_ptr);
+ 			*aclflag = CIFS_ACL_OWNER;
+ 		}
+@@ -1139,8 +1131,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
+ 				kfree(ngroup_sid_ptr);
+ 				return rc;
+ 			}
+-			memcpy(group_sid_ptr, ngroup_sid_ptr,
+-					sizeof(struct cifs_sid));
++			cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
+ 			kfree(ngroup_sid_ptr);
+ 			*aclflag = CIFS_ACL_GROUP;
+ 		}
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
+index 781025b..2b33b2c 100644
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -392,7 +392,16 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
+ 	 * in network traffic in the other paths.
+ 	 */
+ 	if (!(oflags & O_CREAT)) {
+-		struct dentry *res = cifs_lookup(inode, direntry, 0);
++		struct dentry *res;
++
++		/*
++		 * Check for hashed negative dentry. We have already revalidated
++		 * the dentry and it is fine. No need to perform another lookup.
++		 */
++		if (!d_unhashed(direntry))
++			return -ENOENT;
++
++		res = cifs_lookup(inode, direntry, 0);
+ 		if (IS_ERR(res))
+ 			return PTR_ERR(res);
+ 
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 5c69f2b..b686b43 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2046,8 +2046,7 @@ extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count);
+ extern int ext4_calculate_overhead(struct super_block *sb);
+ extern int ext4_superblock_csum_verify(struct super_block *sb,
+ 				       struct ext4_super_block *es);
+-extern void ext4_superblock_csum_set(struct super_block *sb,
+-				     struct ext4_super_block *es);
++extern void ext4_superblock_csum_set(struct super_block *sb);
+ extern void *ext4_kvmalloc(size_t size, gfp_t flags);
+ extern void *ext4_kvzalloc(size_t size, gfp_t flags);
+ extern void ext4_kvfree(void *ptr);
+diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
+index bfa65b4..b4323ba 100644
+--- a/fs/ext4/ext4_jbd2.c
++++ b/fs/ext4/ext4_jbd2.c
+@@ -143,17 +143,13 @@ int __ext4_handle_dirty_super(const char *where, unsigned int line,
+ 	struct buffer_head *bh = EXT4_SB(sb)->s_sbh;
+ 	int err = 0;
+ 
++	ext4_superblock_csum_set(sb);
+ 	if (ext4_handle_valid(handle)) {
+-		ext4_superblock_csum_set(sb,
+-				(struct ext4_super_block *)bh->b_data);
+ 		err = jbd2_journal_dirty_metadata(handle, bh);
+ 		if (err)
+ 			ext4_journal_abort_handle(where, line, __func__,
+ 						  bh, handle, err);
+-	} else {
+-		ext4_superblock_csum_set(sb,
+-				(struct ext4_super_block *)bh->b_data);
++	} else
+ 		mark_buffer_dirty(bh);
+-	}
+ 	return err;
+ }
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 71241bc..101b41c 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -979,7 +979,7 @@ static void update_backups(struct super_block *sb,
+ 		goto exit_err;
+ 	}
+ 
+-	ext4_superblock_csum_set(sb, (struct ext4_super_block *)data);
++	ext4_superblock_csum_set(sb);
+ 
+ 	while ((group = ext4_list_backups(sb, &three, &five, &seven)) < last) {
+ 		struct buffer_head *bh;
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index e44b233..2b5fb60 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -143,9 +143,10 @@ int ext4_superblock_csum_verify(struct super_block *sb,
+ 	return es->s_checksum == ext4_superblock_csum(sb, es);
+ }
+ 
+-void ext4_superblock_csum_set(struct super_block *sb,
+-			      struct ext4_super_block *es)
++void ext4_superblock_csum_set(struct super_block *sb)
+ {
++	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
++
+ 	if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
+ 		EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ 		return;
+@@ -4343,7 +4344,7 @@ static int ext4_commit_super(struct super_block *sb, int sync)
+ 		cpu_to_le32(percpu_counter_sum_positive(
+ 				&EXT4_SB(sb)->s_freeinodes_counter));
+ 	BUFFER_TRACE(sbh, "marking dirty");
+-	ext4_superblock_csum_set(sb, es);
++	ext4_superblock_csum_set(sb);
+ 	mark_buffer_dirty(sbh);
+ 	if (sync) {
+ 		error = sync_dirty_buffer(sbh);
+diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
+index 382000f..07cc71f 100644
+--- a/fs/gfs2/file.c
++++ b/fs/gfs2/file.c
+@@ -515,15 +515,13 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
+ 		struct gfs2_holder i_gh;
+ 		int error;
+ 
+-		gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
+-		error = gfs2_glock_nq(&i_gh);
+-		if (error == 0) {
+-			file_accessed(file);
+-			gfs2_glock_dq(&i_gh);
+-		}
+-		gfs2_holder_uninit(&i_gh);
++		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
++					   &i_gh);
+ 		if (error)
+ 			return error;
++		/* grab lock to update inode */
++		gfs2_glock_dq_uninit(&i_gh);
++		file_accessed(file);
+ 	}
+ 	vma->vm_ops = &gfs2_vm_ops;
+ 	vma->vm_flags |= VM_CAN_NONLINEAR;
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index fc3168f..12ff463 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -810,7 +810,8 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
+ 			return;
+ 		}
+ 		need_unlock = 1;
+-	}
++	} else if (WARN_ON_ONCE(ip->i_gl->gl_state != LM_ST_EXCLUSIVE))
++		return;
+ 
+ 	if (current->journal_info == NULL) {
+ 		ret = gfs2_trans_begin(sdp, RES_DINODE, 0);
+diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
+index f35794b..a506360 100644
+--- a/fs/notify/fanotify/fanotify.c
++++ b/fs/notify/fanotify/fanotify.c
+@@ -21,6 +21,7 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new)
+ 			if ((old->path.mnt == new->path.mnt) &&
+ 			    (old->path.dentry == new->path.dentry))
+ 				return true;
++			break;
+ 		case (FSNOTIFY_EVENT_NONE):
+ 			return true;
+ 		default:
+diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
+index 29996e8..2d1e0f3 100644
+--- a/fs/pstore/platform.c
++++ b/fs/pstore/platform.c
+@@ -161,12 +161,13 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
+ 
+ 	while (s < e) {
+ 		unsigned long flags;
++		u64 id;
+ 
+ 		if (c > psinfo->bufsize)
+ 			c = psinfo->bufsize;
+ 		spin_lock_irqsave(&psinfo->buf_lock, flags);
+ 		memcpy(psinfo->buf, s, c);
+-		psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo);
++		psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo);
+ 		spin_unlock_irqrestore(&psinfo->buf_lock, flags);
+ 		s += c;
+ 		c = e - s;
+diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
+index 63ce6be..567c10c 100644
+--- a/fs/reiserfs/inode.c
++++ b/fs/reiserfs/inode.c
+@@ -1782,8 +1782,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
+ 
+ 	BUG_ON(!th->t_trans_id);
+ 
+-	dquot_initialize(inode);
++	reiserfs_write_unlock(inode->i_sb);
+ 	err = dquot_alloc_inode(inode);
++	reiserfs_write_lock(inode->i_sb);
+ 	if (err)
+ 		goto out_end_trans;
+ 	if (!dir->i_nlink) {
+@@ -1979,8 +1980,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
+ 
+       out_end_trans:
+ 	journal_end(th, th->t_super, th->t_blocks_allocated);
++	reiserfs_write_unlock(inode->i_sb);
+ 	/* Drop can be outside and it needs more credits so it's better to have it outside */
+ 	dquot_drop(inode);
++	reiserfs_write_lock(inode->i_sb);
+ 	inode->i_flags |= S_NOQUOTA;
+ 	make_bad_inode(inode);
+ 
+@@ -3103,10 +3106,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
+ 	/* must be turned off for recursive notify_change calls */
+ 	ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
+ 
+-	depth = reiserfs_write_lock_once(inode->i_sb);
+ 	if (is_quota_modification(inode, attr))
+ 		dquot_initialize(inode);
+-
++	depth = reiserfs_write_lock_once(inode->i_sb);
+ 	if (attr->ia_valid & ATTR_SIZE) {
+ 		/* version 2 items will be caught by the s_maxbytes check
+ 		 ** done for us in vmtruncate
+@@ -3170,7 +3172,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
+ 		error = journal_begin(&th, inode->i_sb, jbegin_count);
+ 		if (error)
+ 			goto out;
++		reiserfs_write_unlock_once(inode->i_sb, depth);
+ 		error = dquot_transfer(inode, attr);
++		depth = reiserfs_write_lock_once(inode->i_sb);
+ 		if (error) {
+ 			journal_end(&th, inode->i_sb, jbegin_count);
+ 			goto out;
+diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
+index f8afa4b..2f40a4c 100644
+--- a/fs/reiserfs/stree.c
++++ b/fs/reiserfs/stree.c
+@@ -1968,7 +1968,9 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree
+ 		       key2type(&(key->on_disk_key)));
+ #endif
+ 
++	reiserfs_write_unlock(inode->i_sb);
+ 	retval = dquot_alloc_space_nodirty(inode, pasted_size);
++	reiserfs_write_lock(inode->i_sb);
+ 	if (retval) {
+ 		pathrelse(search_path);
+ 		return retval;
+@@ -2061,9 +2063,11 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
+ 			       "reiserquota insert_item(): allocating %u id=%u type=%c",
+ 			       quota_bytes, inode->i_uid, head2type(ih));
+ #endif
++		reiserfs_write_unlock(inode->i_sb);
+ 		/* We can't dirty inode here. It would be immediately written but
+ 		 * appropriate stat item isn't inserted yet... */
+ 		retval = dquot_alloc_space_nodirty(inode, quota_bytes);
++		reiserfs_write_lock(inode->i_sb);
+ 		if (retval) {
+ 			pathrelse(path);
+ 			return retval;
+diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
+index 7a37dab..4300030 100644
+--- a/fs/reiserfs/super.c
++++ b/fs/reiserfs/super.c
+@@ -298,7 +298,9 @@ static int finish_unfinished(struct super_block *s)
+ 			retval = remove_save_link_only(s, &save_link_key, 0);
+ 			continue;
+ 		}
++		reiserfs_write_unlock(s);
+ 		dquot_initialize(inode);
++		reiserfs_write_lock(s);
+ 
+ 		if (truncate && S_ISDIR(inode->i_mode)) {
+ 			/* We got a truncate request for a dir which is impossible.
+@@ -1330,7 +1332,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
+ 				kfree(qf_names[i]);
+ #endif
+ 		err = -EINVAL;
+-		goto out_err;
++		goto out_unlock;
+ 	}
+ #ifdef CONFIG_QUOTA
+ 	handle_quota_files(s, qf_names, &qfmt);
+@@ -1374,7 +1376,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
+ 	if (blocks) {
+ 		err = reiserfs_resize(s, blocks);
+ 		if (err != 0)
+-			goto out_err;
++			goto out_unlock;
+ 	}
+ 
+ 	if (*mount_flags & MS_RDONLY) {
+@@ -1384,9 +1386,15 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
+ 			/* it is read-only already */
+ 			goto out_ok;
+ 
++		/*
++		 * Drop write lock. Quota will retake it when needed and lock
++		 * ordering requires calling dquot_suspend() without it.
++		 */
++		reiserfs_write_unlock(s);
+ 		err = dquot_suspend(s, -1);
+ 		if (err < 0)
+ 			goto out_err;
++		reiserfs_write_lock(s);
+ 
+ 		/* try to remount file system with read-only permissions */
+ 		if (sb_umount_state(rs) == REISERFS_VALID_FS
+@@ -1396,7 +1404,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
+ 
+ 		err = journal_begin(&th, s, 10);
+ 		if (err)
+-			goto out_err;
++			goto out_unlock;
+ 
+ 		/* Mounting a rw partition read-only. */
+ 		reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
+@@ -1411,7 +1419,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
+ 
+ 		if (reiserfs_is_journal_aborted(journal)) {
+ 			err = journal->j_errno;
+-			goto out_err;
++			goto out_unlock;
+ 		}
+ 
+ 		handle_data_mode(s, mount_options);
+@@ -1420,7 +1428,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
+ 		s->s_flags &= ~MS_RDONLY;	/* now it is safe to call journal_begin */
+ 		err = journal_begin(&th, s, 10);
+ 		if (err)
+-			goto out_err;
++			goto out_unlock;
+ 
+ 		/* Mount a partition which is read-only, read-write */
+ 		reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
+@@ -1437,10 +1445,16 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
+ 	SB_JOURNAL(s)->j_must_wait = 1;
+ 	err = journal_end(&th, s, 10);
+ 	if (err)
+-		goto out_err;
++		goto out_unlock;
+ 
+ 	if (!(*mount_flags & MS_RDONLY)) {
++		/*
++		 * Drop write lock. Quota will retake it when needed and lock
++		 * ordering requires calling dquot_resume() without it.
++		 */
++		reiserfs_write_unlock(s);
+ 		dquot_resume(s, -1);
++		reiserfs_write_lock(s);
+ 		finish_unfinished(s);
+ 		reiserfs_xattr_init(s, *mount_flags);
+ 	}
+@@ -1450,9 +1464,10 @@ out_ok:
+ 	reiserfs_write_unlock(s);
+ 	return 0;
+ 
++out_unlock:
++	reiserfs_write_unlock(s);
+ out_err:
+ 	kfree(new_opts);
+-	reiserfs_write_unlock(s);
+ 	return err;
+ }
+ 
+@@ -2090,13 +2105,15 @@ static int reiserfs_write_dquot(struct dquot *dquot)
+ 			  REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
+ 	if (ret)
+ 		goto out;
++	reiserfs_write_unlock(dquot->dq_sb);
+ 	ret = dquot_commit(dquot);
++	reiserfs_write_lock(dquot->dq_sb);
+ 	err =
+ 	    journal_end(&th, dquot->dq_sb,
+ 			REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
+ 	if (!ret && err)
+ 		ret = err;
+-      out:
++out:
+ 	reiserfs_write_unlock(dquot->dq_sb);
+ 	return ret;
+ }
+@@ -2112,13 +2129,15 @@ static int reiserfs_acquire_dquot(struct dquot *dquot)
+ 			  REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
+ 	if (ret)
+ 		goto out;
++	reiserfs_write_unlock(dquot->dq_sb);
+ 	ret = dquot_acquire(dquot);
++	reiserfs_write_lock(dquot->dq_sb);
+ 	err =
+ 	    journal_end(&th, dquot->dq_sb,
+ 			REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
+ 	if (!ret && err)
+ 		ret = err;
+-      out:
++out:
+ 	reiserfs_write_unlock(dquot->dq_sb);
+ 	return ret;
+ }
+@@ -2132,19 +2151,21 @@ static int reiserfs_release_dquot(struct dquot *dquot)
+ 	ret =
+ 	    journal_begin(&th, dquot->dq_sb,
+ 			  REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
++	reiserfs_write_unlock(dquot->dq_sb);
+ 	if (ret) {
+ 		/* Release dquot anyway to avoid endless cycle in dqput() */
+ 		dquot_release(dquot);
+ 		goto out;
+ 	}
+ 	ret = dquot_release(dquot);
++	reiserfs_write_lock(dquot->dq_sb);
+ 	err =
+ 	    journal_end(&th, dquot->dq_sb,
+ 			REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
+ 	if (!ret && err)
+ 		ret = err;
+-      out:
+ 	reiserfs_write_unlock(dquot->dq_sb);
++out:
+ 	return ret;
+ }
+ 
+@@ -2169,11 +2190,13 @@ static int reiserfs_write_info(struct super_block *sb, int type)
+ 	ret = journal_begin(&th, sb, 2);
+ 	if (ret)
+ 		goto out;
++	reiserfs_write_unlock(sb);
+ 	ret = dquot_commit_info(sb, type);
++	reiserfs_write_lock(sb);
+ 	err = journal_end(&th, sb, 2);
+ 	if (!ret && err)
+ 		ret = err;
+-      out:
++out:
+ 	reiserfs_write_unlock(sb);
+ 	return ret;
+ }
+@@ -2198,8 +2221,11 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
+ 	struct reiserfs_transaction_handle th;
+ 	int opt = type == USRQUOTA ? REISERFS_USRQUOTA : REISERFS_GRPQUOTA;
+ 
+-	if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt)))
+-		return -EINVAL;
++	reiserfs_write_lock(sb);
++	if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) {
++		err = -EINVAL;
++		goto out;
++	}
+ 
+ 	/* Quotafile not on the same filesystem? */
+ 	if (path->dentry->d_sb != sb) {
+@@ -2241,8 +2267,10 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
+ 		if (err)
+ 			goto out;
+ 	}
+-	err = dquot_quota_on(sb, type, format_id, path);
++	reiserfs_write_unlock(sb);
++	return dquot_quota_on(sb, type, format_id, path);
+ out:
++	reiserfs_write_unlock(sb);
+ 	return err;
+ }
+ 
+@@ -2315,7 +2343,9 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
+ 		tocopy = sb->s_blocksize - offset < towrite ?
+ 		    sb->s_blocksize - offset : towrite;
+ 		tmp_bh.b_state = 0;
++		reiserfs_write_lock(sb);
+ 		err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE);
++		reiserfs_write_unlock(sb);
+ 		if (err)
+ 			goto out;
+ 		if (offset || tocopy != sb->s_blocksize)
+@@ -2331,10 +2361,12 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
+ 		flush_dcache_page(bh->b_page);
+ 		set_buffer_uptodate(bh);
+ 		unlock_buffer(bh);
++		reiserfs_write_lock(sb);
+ 		reiserfs_prepare_for_journal(sb, bh, 1);
+ 		journal_mark_dirty(current->journal_info, sb, bh);
+ 		if (!journal_quota)
+ 			reiserfs_add_ordered_list(inode, bh);
++		reiserfs_write_unlock(sb);
+ 		brelse(bh);
+ 		offset = 0;
+ 		towrite -= tocopy;
+diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c
+index 28ec13a..2dcf3d4 100644
+--- a/fs/ubifs/find.c
++++ b/fs/ubifs/find.c
+@@ -681,8 +681,16 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c)
+ 	if (!lprops) {
+ 		lprops = ubifs_fast_find_freeable(c);
+ 		if (!lprops) {
+-			ubifs_assert(c->freeable_cnt == 0);
+-			if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
++			/*
++			 * The first condition means the following: go scan the
++			 * LPT if there are uncategorized lprops, which means
++			 * there may be freeable LEBs there (UBIFS does not
++			 * store the information about freeable LEBs in the
++			 * master node).
++			 */
++			if (c->in_a_category_cnt != c->main_lebs ||
++			    c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
++				ubifs_assert(c->freeable_cnt == 0);
+ 				lprops = scan_for_leb_for_idx(c);
+ 				if (IS_ERR(lprops)) {
+ 					err = PTR_ERR(lprops);
+diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
+index 86eb8e5..b33ec7a 100644
+--- a/fs/ubifs/lprops.c
++++ b/fs/ubifs/lprops.c
+@@ -300,8 +300,11 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops,
+ 	default:
+ 		ubifs_assert(0);
+ 	}
++
+ 	lprops->flags &= ~LPROPS_CAT_MASK;
+ 	lprops->flags |= cat;
++	c->in_a_category_cnt += 1;
++	ubifs_assert(c->in_a_category_cnt <= c->main_lebs);
+ }
+ 
+ /**
+@@ -334,6 +337,9 @@ static void ubifs_remove_from_cat(struct ubifs_info *c,
+ 	default:
+ 		ubifs_assert(0);
+ 	}
++
++	c->in_a_category_cnt -= 1;
++	ubifs_assert(c->in_a_category_cnt >= 0);
+ }
+ 
+ /**
+diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
+index 1e5a086..51ac3e6 100644
+--- a/fs/ubifs/ubifs.h
++++ b/fs/ubifs/ubifs.h
+@@ -1184,6 +1184,8 @@ struct ubifs_debug_info;
+  * @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size)
+  * @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size)
+  * @freeable_cnt: number of freeable LEBs in @freeable_list
++ * @in_a_category_cnt: count of lprops which are in a certain category, which
++ *                     basically meants that they were loaded from the flash
+  *
+  * @ltab_lnum: LEB number of LPT's own lprops table
+  * @ltab_offs: offset of LPT's own lprops table
+@@ -1413,6 +1415,7 @@ struct ubifs_info {
+ 	struct list_head freeable_list;
+ 	struct list_head frdi_idx_list;
+ 	int freeable_cnt;
++	int in_a_category_cnt;
+ 
+ 	int ltab_lnum;
+ 	int ltab_offs;
+diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
+index 933b793..4b0b8dd 100644
+--- a/fs/xfs/xfs_buf.c
++++ b/fs/xfs/xfs_buf.c
+@@ -1197,9 +1197,14 @@ xfs_buf_bio_end_io(
+ {
+ 	xfs_buf_t		*bp = (xfs_buf_t *)bio->bi_private;
+ 
+-	xfs_buf_ioerror(bp, -error);
++	/*
++	 * don't overwrite existing errors - otherwise we can lose errors on
++	 * buffers that require multiple bios to complete.
++	 */
++	if (!bp->b_error)
++		xfs_buf_ioerror(bp, -error);
+ 
+-	if (!error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ))
++	if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ))
+ 		invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp));
+ 
+ 	_xfs_buf_ioend(bp, 1);
+@@ -1279,6 +1284,11 @@ next_chunk:
+ 		if (size)
+ 			goto next_chunk;
+ 	} else {
++		/*
++		 * This is guaranteed not to be the last io reference count
++		 * because the caller (xfs_buf_iorequest) holds a count itself.
++		 */
++		atomic_dec(&bp->b_io_remaining);
+ 		xfs_buf_ioerror(bp, EIO);
+ 		bio_put(bio);
+ 	}
+diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
+index 2daa54f..a16d929 100644
+--- a/include/linux/mmzone.h
++++ b/include/linux/mmzone.h
+@@ -744,7 +744,7 @@ extern int init_currently_empty_zone(struct zone *zone, unsigned long start_pfn,
+ 				     unsigned long size,
+ 				     enum memmap_context context);
+ 
+-extern void lruvec_init(struct lruvec *lruvec, struct zone *zone);
++extern void lruvec_init(struct lruvec *lruvec);
+ 
+ static inline struct zone *lruvec_zone(struct lruvec *lruvec)
+ {
+diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h
+index 945704c..00b9e61 100644
+--- a/include/linux/ptp_clock_kernel.h
++++ b/include/linux/ptp_clock_kernel.h
+@@ -50,7 +50,8 @@ struct ptp_clock_request {
+  * clock operations
+  *
+  * @adjfreq:  Adjusts the frequency of the hardware clock.
+- *            parameter delta: Desired period change in parts per billion.
++ *            parameter delta: Desired frequency offset from nominal frequency
++ *            in parts per billion
+  *
+  * @adjtime:  Shifts the time of the hardware clock.
+  *            parameter delta: Desired change in nanoseconds.
+diff --git a/kernel/module.c b/kernel/module.c
+index 9ad9ee9..2a15c59 100644
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -2273,12 +2273,17 @@ static void layout_symtab(struct module *mod, struct load_info *info)
+ 	src = (void *)info->hdr + symsect->sh_offset;
+ 	nsrc = symsect->sh_size / sizeof(*src);
+ 
++	/* strtab always starts with a nul, so offset 0 is the empty string. */
++	strtab_size = 1;
++
+ 	/* Compute total space required for the core symbols' strtab. */
+-	for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src)
+-		if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) {
+-			strtab_size += strlen(&info->strtab[src->st_name]) + 1;
++	for (ndst = i = 0; i < nsrc; i++) {
++		if (i == 0 ||
++		    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
++			strtab_size += strlen(&info->strtab[src[i].st_name])+1;
+ 			ndst++;
+ 		}
++	}
+ 
+ 	/* Append room for core symbols at end of core part. */
+ 	info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
+@@ -2312,15 +2317,15 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
+ 	mod->core_symtab = dst = mod->module_core + info->symoffs;
+ 	mod->core_strtab = s = mod->module_core + info->stroffs;
+ 	src = mod->symtab;
+-	*dst = *src;
+ 	*s++ = 0;
+-	for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) {
+-		if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum))
+-			continue;
+-
+-		dst[ndst] = *src;
+-		dst[ndst++].st_name = s - mod->core_strtab;
+-		s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1;
++	for (ndst = i = 0; i < mod->num_symtab; i++) {
++		if (i == 0 ||
++		    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
++			dst[ndst] = src[i];
++			dst[ndst++].st_name = s - mod->core_strtab;
++			s += strlcpy(s, &mod->strtab[src[i].st_name],
++				     KSYM_NAME_LEN) + 1;
++		}
+ 	}
+ 	mod->core_num_syms = ndst;
+ }
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index 795e525..a6e2f81 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -1061,12 +1061,24 @@ struct lruvec *mem_cgroup_zone_lruvec(struct zone *zone,
+ 				      struct mem_cgroup *memcg)
+ {
+ 	struct mem_cgroup_per_zone *mz;
++	struct lruvec *lruvec;
+ 
+-	if (mem_cgroup_disabled())
+-		return &zone->lruvec;
++	if (mem_cgroup_disabled()) {
++		lruvec = &zone->lruvec;
++		goto out;
++	}
+ 
+ 	mz = mem_cgroup_zoneinfo(memcg, zone_to_nid(zone), zone_idx(zone));
+-	return &mz->lruvec;
++	lruvec = &mz->lruvec;
++out:
++	/*
++	 * Since a node can be onlined after the mem_cgroup was created,
++	 * we have to be prepared to initialize lruvec->zone here;
++	 * and if offlined then reonlined, we need to reinitialize it.
++	 */
++	if (unlikely(lruvec->zone != zone))
++		lruvec->zone = zone;
++	return lruvec;
+ }
+ 
+ /*
+@@ -1093,9 +1105,12 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone)
+ 	struct mem_cgroup_per_zone *mz;
+ 	struct mem_cgroup *memcg;
+ 	struct page_cgroup *pc;
++	struct lruvec *lruvec;
+ 
+-	if (mem_cgroup_disabled())
+-		return &zone->lruvec;
++	if (mem_cgroup_disabled()) {
++		lruvec = &zone->lruvec;
++		goto out;
++	}
+ 
+ 	pc = lookup_page_cgroup(page);
+ 	memcg = pc->mem_cgroup;
+@@ -1113,7 +1128,16 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone)
+ 		pc->mem_cgroup = memcg = root_mem_cgroup;
+ 
+ 	mz = page_cgroup_zoneinfo(memcg, page);
+-	return &mz->lruvec;
++	lruvec = &mz->lruvec;
++out:
++	/*
++	 * Since a node can be onlined after the mem_cgroup was created,
++	 * we have to be prepared to initialize lruvec->zone here;
++	 * and if offlined then reonlined, we need to reinitialize it.
++	 */
++	if (unlikely(lruvec->zone != zone))
++		lruvec->zone = zone;
++	return lruvec;
+ }
+ 
+ /**
+@@ -1458,17 +1482,26 @@ static int mem_cgroup_count_children(struct mem_cgroup *memcg)
+ static u64 mem_cgroup_get_limit(struct mem_cgroup *memcg)
+ {
+ 	u64 limit;
+-	u64 memsw;
+ 
+ 	limit = res_counter_read_u64(&memcg->res, RES_LIMIT);
+-	limit += total_swap_pages << PAGE_SHIFT;
+ 
+-	memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT);
+ 	/*
+-	 * If memsw is finite and limits the amount of swap space available
+-	 * to this memcg, return that limit.
++	 * Do not consider swap space if we cannot swap due to swappiness
+ 	 */
+-	return min(limit, memsw);
++	if (mem_cgroup_swappiness(memcg)) {
++		u64 memsw;
++
++		limit += total_swap_pages << PAGE_SHIFT;
++		memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT);
++
++		/*
++		 * If memsw is finite and limits the amount of swap space
++		 * available to this memcg, return that limit.
++		 */
++		limit = min(limit, memsw);
++	}
++
++	return limit;
+ }
+ 
+ void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
+@@ -3694,17 +3727,17 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
+ static bool mem_cgroup_force_empty_list(struct mem_cgroup *memcg,
+ 				int node, int zid, enum lru_list lru)
+ {
+-	struct mem_cgroup_per_zone *mz;
++	struct lruvec *lruvec;
+ 	unsigned long flags, loop;
+ 	struct list_head *list;
+ 	struct page *busy;
+ 	struct zone *zone;
+ 
+ 	zone = &NODE_DATA(node)->node_zones[zid];
+-	mz = mem_cgroup_zoneinfo(memcg, node, zid);
+-	list = &mz->lruvec.lists[lru];
++	lruvec = mem_cgroup_zone_lruvec(zone, memcg);
++	list = &lruvec->lists[lru];
+ 
+-	loop = mz->lru_size[lru];
++	loop = mem_cgroup_get_lru_size(lruvec, lru);
+ 	/* give some margin against EBUSY etc...*/
+ 	loop += 256;
+ 	busy = NULL;
+@@ -4742,7 +4775,7 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
+ 
+ 	for (zone = 0; zone < MAX_NR_ZONES; zone++) {
+ 		mz = &pn->zoneinfo[zone];
+-		lruvec_init(&mz->lruvec, &NODE_DATA(node)->node_zones[zone]);
++		lruvec_init(&mz->lruvec);
+ 		mz->usage_in_excess = 0;
+ 		mz->on_tree = false;
+ 		mz->memcg = memcg;
+diff --git a/mm/mmzone.c b/mm/mmzone.c
+index 3cef80f..4596d81 100644
+--- a/mm/mmzone.c
++++ b/mm/mmzone.c
+@@ -87,7 +87,7 @@ int memmap_valid_within(unsigned long pfn,
+ }
+ #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */
+ 
+-void lruvec_init(struct lruvec *lruvec, struct zone *zone)
++void lruvec_init(struct lruvec *lruvec)
+ {
+ 	enum lru_list lru;
+ 
+@@ -95,8 +95,4 @@ void lruvec_init(struct lruvec *lruvec, struct zone *zone)
+ 
+ 	for_each_lru(lru)
+ 		INIT_LIST_HEAD(&lruvec->lists[lru]);
+-
+-#ifdef CONFIG_MEMCG
+-	lruvec->zone = zone;
+-#endif
+ }
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index c13ea75..d2d8f54 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -4456,7 +4456,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat,
+ 		zone->zone_pgdat = pgdat;
+ 
+ 		zone_pcp_init(zone);
+-		lruvec_init(&zone->lruvec, zone);
++		lruvec_init(&zone->lruvec);
+ 		if (!size)
+ 			continue;
+ 
+diff --git a/mm/shmem.c b/mm/shmem.c
+index d2eeca1..31e1506 100644
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -654,7 +654,7 @@ static void shmem_evict_inode(struct inode *inode)
+ 		kfree(xattr->name);
+ 		kfree(xattr);
+ 	}
+-	BUG_ON(inode->i_blocks);
++	WARN_ON(inode->i_blocks);
+ 	shmem_free_inode(inode->i_sb);
+ 	clear_inode(inode);
+ }
+@@ -1156,8 +1156,20 @@ repeat:
+ 		if (!error) {
+ 			error = shmem_add_to_page_cache(page, mapping, index,
+ 						gfp, swp_to_radix_entry(swap));
+-			/* We already confirmed swap, and make no allocation */
+-			VM_BUG_ON(error);
++			/*
++			 * We already confirmed swap under page lock, and make
++			 * no memory allocation here, so usually no possibility
++			 * of error; but free_swap_and_cache() only trylocks a
++			 * page, so it is just possible that the entry has been
++			 * truncated or holepunched since swap was confirmed.
++			 * shmem_undo_range() will have done some of the
++			 * unaccounting, now delete_from_swap_cache() will do
++			 * the rest (including mem_cgroup_uncharge_swapcache).
++			 * Reset swap.val? No, leave it so "failed" goes back to
++			 * "repeat": reading a hole and writing should succeed.
++			 */
++			if (error)
++				delete_from_swap_cache(page);
+ 		}
+ 		if (error)
+ 			goto failed;
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 99b434b..a018dfc 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -2953,6 +2953,8 @@ static int kswapd(void *p)
+ 						&balanced_classzone_idx);
+ 		}
+ 	}
++
++	current->reclaim_state = NULL;
+ 	return 0;
+ }
+ 
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index eba022d..534250a 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -321,7 +321,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
+ 	struct hci_dev *d;
+ 	size_t rp_len;
+ 	u16 count;
+-	int i, err;
++	int err;
+ 
+ 	BT_DBG("sock %p", sk);
+ 
+@@ -339,17 +339,18 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
+ 		return -ENOMEM;
+ 	}
+ 
+-	rp->num_controllers = cpu_to_le16(count);
+-
+-	i = 0;
++	count = 0;
+ 	list_for_each_entry(d, &hci_dev_list, list) {
+ 		if (test_bit(HCI_SETUP, &d->dev_flags))
+ 			continue;
+ 
+-		rp->index[i++] = cpu_to_le16(d->id);
++		rp->index[count++] = cpu_to_le16(d->id);
+ 		BT_DBG("Added hci%u", d->id);
+ 	}
+ 
++	rp->num_controllers = cpu_to_le16(count);
++	rp_len = sizeof(*rp) + (2 * count);
++
+ 	read_unlock(&hci_dev_list_lock);
+ 
+ 	err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp,
+diff --git a/net/core/dev.c b/net/core/dev.c
+index aed87a4..1dce5b5 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2793,8 +2793,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
+ 		if (unlikely(tcpu != next_cpu) &&
+ 		    (tcpu == RPS_NO_CPU || !cpu_online(tcpu) ||
+ 		     ((int)(per_cpu(softnet_data, tcpu).input_queue_head -
+-		      rflow->last_qtail)) >= 0))
++		      rflow->last_qtail)) >= 0)) {
++			tcpu = next_cpu;
+ 			rflow = set_rps_cpu(dev, skb, rflow, next_cpu);
++		}
+ 
+ 		if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) {
+ 			*rflowp = rflow;
+diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
+index c4cc2bc..716f363 100644
+--- a/net/core/dev_addr_lists.c
++++ b/net/core/dev_addr_lists.c
+@@ -317,7 +317,8 @@ int dev_addr_del(struct net_device *dev, unsigned char *addr,
+ 	 */
+ 	ha = list_first_entry(&dev->dev_addrs.list,
+ 			      struct netdev_hw_addr, list);
+-	if (ha->addr == dev->dev_addr && ha->refcount == 1)
++	if (!memcmp(ha->addr, addr, dev->addr_len) &&
++	    ha->type == addr_type && ha->refcount == 1)
+ 		return -ENOENT;
+ 
+ 	err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len,
+diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
+index 5eea4a8..14bbfcf 100644
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -457,19 +457,28 @@ static int do_ip_setsockopt(struct sock *sk, int level,
+ 	struct inet_sock *inet = inet_sk(sk);
+ 	int val = 0, err;
+ 
+-	if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
+-			     (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
+-			     (1<<IP_RETOPTS) | (1<<IP_TOS) |
+-			     (1<<IP_TTL) | (1<<IP_HDRINCL) |
+-			     (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
+-			     (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
+-			     (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
+-			     (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
+-	    optname == IP_UNICAST_IF ||
+-	    optname == IP_MULTICAST_TTL ||
+-	    optname == IP_MULTICAST_ALL ||
+-	    optname == IP_MULTICAST_LOOP ||
+-	    optname == IP_RECVORIGDSTADDR) {
++	switch (optname) {
++	case IP_PKTINFO:
++	case IP_RECVTTL:
++	case IP_RECVOPTS:
++	case IP_RECVTOS:
++	case IP_RETOPTS:
++	case IP_TOS:
++	case IP_TTL:
++	case IP_HDRINCL:
++	case IP_MTU_DISCOVER:
++	case IP_RECVERR:
++	case IP_ROUTER_ALERT:
++	case IP_FREEBIND:
++	case IP_PASSSEC:
++	case IP_TRANSPARENT:
++	case IP_MINTTL:
++	case IP_NODEFRAG:
++	case IP_UNICAST_IF:
++	case IP_MULTICAST_TTL:
++	case IP_MULTICAST_ALL:
++	case IP_MULTICAST_LOOP:
++	case IP_RECVORIGDSTADDR:
+ 		if (optlen >= sizeof(int)) {
+ 			if (get_user(val, (int __user *) optval))
+ 				return -EFAULT;
+diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
+index 3511ffb..bf89b21 100644
+--- a/net/ipv4/ip_vti.c
++++ b/net/ipv4/ip_vti.c
+@@ -341,12 +341,17 @@ static int vti_rcv(struct sk_buff *skb)
+ 	if (tunnel != NULL) {
+ 		struct pcpu_tstats *tstats;
+ 
++		if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
++			return -1;
++
+ 		tstats = this_cpu_ptr(tunnel->dev->tstats);
+ 		u64_stats_update_begin(&tstats->syncp);
+ 		tstats->rx_packets++;
+ 		tstats->rx_bytes += skb->len;
+ 		u64_stats_update_end(&tstats->syncp);
+ 
++		skb->mark = 0;
++		secpath_reset(skb);
+ 		skb->dev = tunnel->dev;
+ 		rcu_read_unlock();
+ 		return 1;
+diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
+index 3828a42..da4098f 100644
+--- a/net/ipv4/netfilter/nf_nat_standalone.c
++++ b/net/ipv4/netfilter/nf_nat_standalone.c
+@@ -194,7 +194,8 @@ nf_nat_out(unsigned int hooknum,
+ 
+ 		if ((ct->tuplehash[dir].tuple.src.u3.ip !=
+ 		     ct->tuplehash[!dir].tuple.dst.u3.ip) ||
+-		    (ct->tuplehash[dir].tuple.src.u.all !=
++		    (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
++		     ct->tuplehash[dir].tuple.src.u.all !=
+ 		     ct->tuplehash[!dir].tuple.dst.u.all)
+ 		   )
+ 			return ip_xfrm_me_harder(skb) == 0 ? ret : NF_DROP;
+@@ -230,7 +231,8 @@ nf_nat_local_fn(unsigned int hooknum,
+ 				ret = NF_DROP;
+ 		}
+ #ifdef CONFIG_XFRM
+-		else if (ct->tuplehash[dir].tuple.dst.u.all !=
++		else if (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
++			 ct->tuplehash[dir].tuple.dst.u.all !=
+ 			 ct->tuplehash[!dir].tuple.src.u.all)
+ 			if (ip_xfrm_me_harder(skb))
+ 				ret = NF_DROP;
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 49dd993..b0b39f6 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -1236,7 +1236,7 @@ new_segment:
+ wait_for_sndbuf:
+ 			set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+ wait_for_memory:
+-			if (copied && likely(!tp->repair))
++			if (copied)
+ 				tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
+ 
+ 			if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
+@@ -1247,7 +1247,7 @@ wait_for_memory:
+ 	}
+ 
+ out:
+-	if (copied && likely(!tp->repair))
++	if (copied)
+ 		tcp_push(sk, flags, mss_now, tp->nonagle);
+ 	release_sock(sk);
+ 	return copied + copied_syn;
+diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
+index 0abe67b..2efd1a5 100644
+--- a/net/ipv4/tcp_metrics.c
++++ b/net/ipv4/tcp_metrics.c
+@@ -1,13 +1,13 @@
+ #include <linux/rcupdate.h>
+ #include <linux/spinlock.h>
+ #include <linux/jiffies.h>
+-#include <linux/bootmem.h>
+ #include <linux/module.h>
+ #include <linux/cache.h>
+ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/tcp.h>
+ #include <linux/hash.h>
++#include <linux/vmalloc.h>
+ 
+ #include <net/inet_connection_sock.h>
+ #include <net/net_namespace.h>
+@@ -722,7 +722,10 @@ static int __net_init tcp_net_metrics_init(struct net *net)
+ 	net->ipv4.tcp_metrics_hash_log = order_base_2(slots);
+ 	size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log;
+ 
+-	net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL);
++	net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
++	if (!net->ipv4.tcp_metrics_hash)
++		net->ipv4.tcp_metrics_hash = vzalloc(size);
++
+ 	if (!net->ipv4.tcp_metrics_hash)
+ 		return -ENOMEM;
+ 
+@@ -743,7 +746,10 @@ static void __net_exit tcp_net_metrics_exit(struct net *net)
+ 			tm = next;
+ 		}
+ 	}
+-	kfree(net->ipv4.tcp_metrics_hash);
++	if (is_vmalloc_addr(net->ipv4.tcp_metrics_hash))
++		vfree(net->ipv4.tcp_metrics_hash);
++	else
++		kfree(net->ipv4.tcp_metrics_hash);
+ }
+ 
+ static __net_initdata struct pernet_operations tcp_net_metrics_ops = {
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index d046326..6735bea 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1977,6 +1977,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
+ 		tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
+ 		BUG_ON(!tso_segs);
+ 
++		if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE)
++			goto repair; /* Skip network transmission */
++
+ 		cwnd_quota = tcp_cwnd_test(tp, skb);
+ 		if (!cwnd_quota)
+ 			break;
+@@ -2017,6 +2020,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
+ 		if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp)))
+ 			break;
+ 
++repair:
+ 		/* Advance the send_head.  This one is sent out.
+ 		 * This call will increment packets_out.
+ 		 */
+diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
+index ba6d13d..e02faed 100644
+--- a/net/ipv6/ipv6_sockglue.c
++++ b/net/ipv6/ipv6_sockglue.c
+@@ -827,6 +827,7 @@ pref_skip_coa:
+ 		if (val < 0 || val > 255)
+ 			goto e_inval;
+ 		np->min_hopcount = val;
++		retv = 0;
+ 		break;
+ 	case IPV6_DONTFRAG:
+ 		np->dontfrag = valbool;
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index bb61f77..642a2a3 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1304,6 +1304,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
+ 					 struct net_device *dev);
+ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
+ 				       struct net_device *dev);
++void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
++			      struct sk_buff_head *skbs);
+ 
+ /* HT */
+ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index 63882b9..31aa8b8 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -730,8 +730,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
+ 
+ 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+ 		local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
+-		__skb_queue_purge(&sta->ps_tx_buf[ac]);
+-		__skb_queue_purge(&sta->tx_filtered[ac]);
++		ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]);
++		ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]);
+ 	}
+ 
+ #ifdef CONFIG_MAC80211_MESH
+@@ -765,7 +765,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
+ 		tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
+ 		if (!tid_tx)
+ 			continue;
+-		__skb_queue_purge(&tid_tx->pending);
++		ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending);
+ 		kfree(tid_tx);
+ 	}
+ 
+@@ -948,6 +948,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
+ 	struct ieee80211_local *local = sdata->local;
+ 	struct sk_buff_head pending;
+ 	int filtered = 0, buffered = 0, ac;
++	unsigned long flags;
+ 
+ 	clear_sta_flag(sta, WLAN_STA_SP);
+ 
+@@ -963,12 +964,16 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
+ 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+ 		int count = skb_queue_len(&pending), tmp;
+ 
++		spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags);
+ 		skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending);
++		spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags);
+ 		tmp = skb_queue_len(&pending);
+ 		filtered += tmp - count;
+ 		count = tmp;
+ 
++		spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags);
+ 		skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending);
++		spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags);
+ 		tmp = skb_queue_len(&pending);
+ 		buffered += tmp - count;
+ 	}
+diff --git a/net/mac80211/status.c b/net/mac80211/status.c
+index 118329a..14e1b83 100644
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -648,3 +648,12 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb)
+ 	dev_kfree_skb_any(skb);
+ }
+ EXPORT_SYMBOL(ieee80211_free_txskb);
++
++void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
++			      struct sk_buff_head *skbs)
++{
++	struct sk_buff *skb;
++
++	while ((skb = __skb_dequeue(skbs)))
++		ieee80211_free_txskb(hw, skb);
++}
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 362c418..8133fed 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1358,7 +1358,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
+ 		if (tx->skb)
+ 			ieee80211_free_txskb(&tx->local->hw, tx->skb);
+ 		else
+-			__skb_queue_purge(&tx->skbs);
++			ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs);
+ 		return -1;
+ 	} else if (unlikely(res == TX_QUEUED)) {
+ 		I802_DEBUG_INC(tx->local->tx_handlers_queued);
+@@ -2132,10 +2132,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
+  */
+ void ieee80211_clear_tx_pending(struct ieee80211_local *local)
+ {
++	struct sk_buff *skb;
+ 	int i;
+ 
+-	for (i = 0; i < local->hw.queues; i++)
+-		skb_queue_purge(&local->pending[i]);
++	for (i = 0; i < local->hw.queues; i++) {
++		while ((skb = skb_dequeue(&local->pending[i])) != NULL)
++			ieee80211_free_txskb(&local->hw, skb);
++	}
+ }
+ 
+ /*
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index 1cfe6d5..7883449 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -1434,6 +1434,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
+ 		list_for_each_entry(sdata, &local->interfaces, list) {
+ 			if (sdata->vif.type != NL80211_IFTYPE_STATION)
+ 				continue;
++			if (!sdata->u.mgd.associated)
++				continue;
+ 
+ 			ieee80211_send_nullfunc(local, sdata, 0);
+ 		}
+diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
+index 4283b20..02f65bc 100644
+--- a/net/netfilter/nf_conntrack_h323_main.c
++++ b/net/netfilter/nf_conntrack_h323_main.c
+@@ -733,7 +733,8 @@ static int callforward_do_filter(const union nf_inet_addr *src,
+ 				   flowi4_to_flowi(&fl1), false)) {
+ 			if (!afinfo->route(&init_net, (struct dst_entry **)&rt2,
+ 					   flowi4_to_flowi(&fl2), false)) {
+-				if (rt1->rt_gateway == rt2->rt_gateway &&
++				if (rt_nexthop(rt1, fl1.daddr) ==
++				    rt_nexthop(rt2, fl2.daddr) &&
+ 				    rt1->dst.dev  == rt2->dst.dev)
+ 					ret = 1;
+ 				dst_release(&rt2->dst);
+diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
+index ee2e5bc..bd93e51 100644
+--- a/net/netfilter/xt_TEE.c
++++ b/net/netfilter/xt_TEE.c
+@@ -70,6 +70,7 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
+ 	fl4.daddr = info->gw.ip;
+ 	fl4.flowi4_tos = RT_TOS(iph->tos);
+ 	fl4.flowi4_scope = RT_SCOPE_UNIVERSE;
++	fl4.flowi4_flags = FLOWI_FLAG_KNOWN_NH;
+ 	rt = ip_route_output_key(net, &fl4);
+ 	if (IS_ERR(rt))
+ 		return false;
+diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
+index 82f0f75..7dd983a 100644
+--- a/net/nfc/llcp/llcp.c
++++ b/net/nfc/llcp/llcp.c
+@@ -1182,8 +1182,8 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
+ 		goto err_rx_wq;
+ 	}
+ 
+-	local->sockets.lock = __RW_LOCK_UNLOCKED(local->sockets.lock);
+-	local->connecting_sockets.lock = __RW_LOCK_UNLOCKED(local->connecting_sockets.lock);
++	rwlock_init(&local->sockets.lock);
++	rwlock_init(&local->connecting_sockets.lock);
+ 
+ 	nfc_llcp_build_gb(local);
+ 
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index 72d170c..3062b88 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -141,9 +141,8 @@ static const struct ieee80211_regdomain world_regdom = {
+ 	.reg_rules = {
+ 		/* IEEE 802.11b/g, channels 1..11 */
+ 		REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
+-		/* IEEE 802.11b/g, channels 12..13. No HT40
+-		 * channel fits here. */
+-		REG_RULE(2467-10, 2472+10, 20, 6, 20,
++		/* IEEE 802.11b/g, channels 12..13. */
++		REG_RULE(2467-10, 2472+10, 40, 6, 20,
+ 			NL80211_RRF_PASSIVE_SCAN |
+ 			NL80211_RRF_NO_IBSS),
+ 		/* IEEE 802.11 channel 14 - Only JP enables
+diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
+index 28f911c..c5454c0 100644
+--- a/security/selinux/netnode.c
++++ b/security/selinux/netnode.c
+@@ -174,7 +174,8 @@ static void sel_netnode_insert(struct sel_netnode *node)
+ 	if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) {
+ 		struct sel_netnode *tail;
+ 		tail = list_entry(
+-			rcu_dereference(sel_netnode_hash[idx].list.prev),
++			rcu_dereference_protected(sel_netnode_hash[idx].list.prev,
++						  lockdep_is_held(&sel_netnode_lock)),
+ 			struct sel_netnode, list);
+ 		list_del_rcu(&tail->list);
+ 		kfree_rcu(tail, rcu);
+diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
+index 0208fa1..b2cd011 100644
+--- a/sound/pci/hda/patch_analog.c
++++ b/sound/pci/hda/patch_analog.c
+@@ -545,6 +545,7 @@ static int ad198x_build_pcms(struct hda_codec *codec)
+ 	if (spec->multiout.dig_out_nid) {
+ 		info++;
+ 		codec->num_pcms++;
++		codec->spdif_status_reset = 1;
+ 		info->name = "AD198x Digital";
+ 		info->pcm_type = HDA_PCM_TYPE_SPDIF;
+ 		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
+diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
+index cc31346..2bb9bee 100644
+--- a/sound/pci/hda/patch_cirrus.c
++++ b/sound/pci/hda/patch_cirrus.c
+@@ -96,8 +96,8 @@ enum {
+ #define CS420X_VENDOR_NID	0x11
+ #define CS_DIG_OUT1_PIN_NID	0x10
+ #define CS_DIG_OUT2_PIN_NID	0x15
+-#define CS_DMIC1_PIN_NID	0x12
+-#define CS_DMIC2_PIN_NID	0x0e
++#define CS_DMIC1_PIN_NID	0x0e
++#define CS_DMIC2_PIN_NID	0x12
+ 
+ /* coef indices */
+ #define IDX_SPDIF_STAT		0x0000
+@@ -1074,14 +1074,18 @@ static void init_input(struct hda_codec *codec)
+ 			cs_automic(codec);
+ 
+ 		coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
++		cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
++
++		coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG);
+ 		if (is_active_pin(codec, CS_DMIC2_PIN_NID))
+-			coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */
++			coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */
+ 		if (is_active_pin(codec, CS_DMIC1_PIN_NID))
+-			coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off
++			coef |= 1 << 3; /* DMIC1 2 chan on, GPIO0 off
+ 					 * No effect if SPDIF_OUT2 is
+ 					 * selected in IDX_SPDIF_CTL.
+ 					*/
+-		cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
++
++		cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef);
+ 	} else {
+ 		if (spec->mic_detect)
+ 			cs_automic(codec);
+@@ -1102,7 +1106,7 @@ static const struct hda_verb cs_coef_init_verbs[] = {
+ 	  | 0x0400 /* Disable Coefficient Auto increment */
+ 	  )},
+ 	/* Beep */
+-	{0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG},
++	{0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG},
+ 	{0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */
+ 
+ 	{} /* terminator */
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 70ce60f..f6b5995 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5434,6 +5434,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
+ 	SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
+ 	SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
++	SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
+ 	SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
+ 	SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
+ 	SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
+@@ -5867,7 +5868,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
+ 	return alc_parse_auto_config(codec, alc269_ignore, ssids);
+ }
+ 
+-static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
++static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
+ {
+ 	int val = alc_read_coef_idx(codec, 0x04);
+ 	if (power_up)
+@@ -5884,10 +5885,10 @@ static void alc269_shutup(struct hda_codec *codec)
+ 	if (spec->codec_variant != ALC269_TYPE_ALC269VB)
+ 		return;
+ 
+-	if ((alc_get_coef0(codec) & 0x00ff) == 0x017)
+-		alc269_toggle_power_output(codec, 0);
+-	if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
+-		alc269_toggle_power_output(codec, 0);
++	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
++		alc269vb_toggle_power_output(codec, 0);
++	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
++			(alc_get_coef0(codec) & 0x00ff) == 0x018) {
+ 		msleep(150);
+ 	}
+ }
+@@ -5897,24 +5898,22 @@ static int alc269_resume(struct hda_codec *codec)
+ {
+ 	struct alc_spec *spec = codec->spec;
+ 
+-	if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
++	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
++		alc269vb_toggle_power_output(codec, 0);
++	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
+ 			(alc_get_coef0(codec) & 0x00ff) == 0x018) {
+-		alc269_toggle_power_output(codec, 0);
+ 		msleep(150);
+ 	}
+ 
+ 	codec->patch_ops.init(codec);
+ 
+-	if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
++	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
++		alc269vb_toggle_power_output(codec, 1);
++	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
+ 			(alc_get_coef0(codec) & 0x00ff) == 0x017) {
+-		alc269_toggle_power_output(codec, 1);
+ 		msleep(200);
+ 	}
+ 
+-	if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
+-			(alc_get_coef0(codec) & 0x00ff) == 0x018)
+-		alc269_toggle_power_output(codec, 1);
+-
+ 	snd_hda_codec_resume_amp(codec);
+ 	snd_hda_codec_resume_cache(codec);
+ 	hda_call_check_power_status(codec, 0x01);
+@@ -7103,6 +7102,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
+ 	  .patch = patch_alc662 },
+ 	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
+ 	{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
++	{ .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
+ 	{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
+ 	{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
+ 	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
+@@ -7120,6 +7120,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
+ 	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
+ 	{ .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
+ 	{ .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
++	{ .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 },
+ 	{} /* terminator */
+ };
+ 
+diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
+index 4c404a0..66cd4f0 100644
+--- a/sound/pci/hda/patch_via.c
++++ b/sound/pci/hda/patch_via.c
+@@ -1875,11 +1875,11 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec)
+ {
+ 	struct via_spec *spec = codec->spec;
+ 	const struct auto_pin_cfg *cfg = &spec->autocfg;
+-	int i, dac_num;
++	int i;
+ 	hda_nid_t nid;
+ 
++	spec->multiout.num_dacs = 0;
+ 	spec->multiout.dac_nids = spec->private_dac_nids;
+-	dac_num = 0;
+ 	for (i = 0; i < cfg->line_outs; i++) {
+ 		hda_nid_t dac = 0;
+ 		nid = cfg->line_out_pins[i];
+@@ -1890,16 +1890,13 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec)
+ 		if (!i && parse_output_path(codec, nid, dac, 1,
+ 					    &spec->out_mix_path))
+ 			dac = spec->out_mix_path.path[0];
+-		if (dac) {
+-			spec->private_dac_nids[i] = dac;
+-			dac_num++;
+-		}
++		if (dac)
++			spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
+ 	}
+ 	if (!spec->out_path[0].depth && spec->out_mix_path.depth) {
+ 		spec->out_path[0] = spec->out_mix_path;
+ 		spec->out_mix_path.depth = 0;
+ 	}
+-	spec->multiout.num_dacs = dac_num;
+ 	return 0;
+ }
+ 
+@@ -3700,6 +3697,18 @@ static const struct snd_pci_quirk vt2002p_fixups[] = {
+ 	{}
+ };
+ 
++/* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e
++ * Replace this with mixer NID 0x1c
++ */
++static void fix_vt1802_connections(struct hda_codec *codec)
++{
++	static hda_nid_t conn_24[] = { 0x14, 0x1c };
++	static hda_nid_t conn_33[] = { 0x1c };
++
++	snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24);
++	snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33);
++}
++
+ /* patch for vt2002P */
+ static int patch_vt2002P(struct hda_codec *codec)
+ {
+@@ -3714,6 +3723,8 @@ static int patch_vt2002P(struct hda_codec *codec)
+ 	spec->aa_mix_nid = 0x21;
+ 	override_mic_boost(codec, 0x2b, 0, 3, 40);
+ 	override_mic_boost(codec, 0x29, 0, 3, 40);
++	if (spec->codec_type == VT1802)
++		fix_vt1802_connections(codec);
+ 	add_secret_dac_path(codec);
+ 
+ 	snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups);
+diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
+index 628daf6..d8cfcc7 100644
+--- a/sound/soc/codecs/cs42l52.c
++++ b/sound/soc/codecs/cs42l52.c
+@@ -774,7 +774,6 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+ {
+ 	struct snd_soc_codec *codec = codec_dai->codec;
+ 	struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+-	int ret = 0;
+ 	u8 iface = 0;
+ 
+ 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+@@ -823,7 +822,7 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+ 	case SND_SOC_DAIFMT_NB_IF:
+ 		break;
+ 	default:
+-		ret = -EINVAL;
++		return -EINVAL;
+ 	}
+ 	cs42l52->config.format = iface;
+ 	snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format);
+diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
+index a5be3ad..2f46d66 100644
+--- a/sound/soc/codecs/wm8978.c
++++ b/sound/soc/codecs/wm8978.c
+@@ -782,7 +782,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
+ 		wm8978->mclk_idx = -1;
+ 		f_sel = wm8978->f_mclk;
+ 	} else {
+-		if (!wm8978->f_pllout) {
++		if (!wm8978->f_opclk) {
+ 			/* We only enter here, if OPCLK is not used */
+ 			int ret = wm8978_configure_pll(codec);
+ 			if (ret < 0)
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index c501af6..8bf05d7 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -2776,8 +2776,9 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
+ 	val = (ucontrol->value.integer.value[0] + min) & mask;
+ 	val = val << shift;
+ 
+-	if (snd_soc_update_bits_locked(codec, reg, val_mask, val))
+-			return err;
++	err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
++	if (err < 0)
++		return err;
+ 
+ 	if (snd_soc_volsw_is_stereo(mc)) {
+ 		val_mask = mask << rshift;
+diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
+index f90139b..c4a08a2 100644
+--- a/sound/soc/soc-dapm.c
++++ b/sound/soc/soc-dapm.c
+@@ -3710,7 +3710,7 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card)
+ {
+ 	struct snd_soc_codec *codec;
+ 
+-	list_for_each_entry(codec, &card->codec_dev_list, list) {
++	list_for_each_entry(codec, &card->codec_dev_list, card_list) {
+ 		soc_dapm_shutdown_codec(&codec->dapm);
+ 		if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
+ 			snd_soc_dapm_set_bias_level(&codec->dapm,
+diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
+index d9de667..eafc889 100644
+--- a/sound/usb/endpoint.c
++++ b/sound/usb/endpoint.c
+@@ -35,6 +35,7 @@
+ 
+ #define EP_FLAG_ACTIVATED	0
+ #define EP_FLAG_RUNNING		1
++#define EP_FLAG_STOPPING	2
+ 
+ /*
+  * snd_usb_endpoint is a model that abstracts everything related to an
+@@ -502,10 +503,20 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep)
+ 	if (alive)
+ 		snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n",
+ 					alive, ep->ep_num);
++	clear_bit(EP_FLAG_STOPPING, &ep->flags);
+ 
+ 	return 0;
+ }
+ 
++/* sync the pending stop operation;
++ * this function itself doesn't trigger the stop operation
++ */
++void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep)
++{
++	if (ep && test_bit(EP_FLAG_STOPPING, &ep->flags))
++		wait_clear_urbs(ep);
++}
++
+ /*
+  * unlink active urbs.
+  */
+@@ -913,6 +924,8 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
+ 
+ 		if (wait)
+ 			wait_clear_urbs(ep);
++		else
++			set_bit(EP_FLAG_STOPPING, &ep->flags);
+ 	}
+ }
+ 
+diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
+index cbbbdf2..774a0eb 100644
+--- a/sound/usb/endpoint.h
++++ b/sound/usb/endpoint.h
+@@ -16,6 +16,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
+ int  snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep);
+ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
+ 			   int force, int can_sleep, int wait);
++void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep);
+ int  snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
+ int  snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);
+ void snd_usb_endpoint_free(struct list_head *head);
+diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
+index ee3c15c..90731af 100644
+--- a/sound/usb/pcm.c
++++ b/sound/usb/pcm.c
+@@ -563,6 +563,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
+ 		goto unlock;
+ 	}
+ 
++	snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
++	snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
++
+ 	/* some unit conversions in runtime */
+ 	subs->data_endpoint->maxframesize =
+ 		bytes_to_frames(runtime, subs->data_endpoint->maxpacksize);



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2012-11-26 22:21 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-26 22:21 [gentoo-commits] linux-patches r2235 - genpatches-2.6/trunk/3.6 Mike Pagano (mpagano)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox