diff -druN linux-libre-3.3.3-gnu/arch/arm/mach-at91/board-sam9261ek.c linux-libre-3.3.4-gnu/arch/arm/mach-at91/board-sam9261ek.c
--- linux-libre-3.3.3-gnu/arch/arm/mach-at91/board-sam9261ek.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/arch/arm/mach-at91/board-sam9261ek.c	2012-04-27 13:17:35.000000000 -0400
@@ -85,8 +85,6 @@
 		.flags	= IORESOURCE_MEM
 	},
 	[2] = {
-		.start	= AT91_PIN_PC11,
-		.end	= AT91_PIN_PC11,
 		.flags	= IORESOURCE_IRQ
 			| IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE,
 	}
@@ -130,6 +128,8 @@
 
 static void __init ek_add_device_dm9000(void)
 {
+	struct resource *r = &dm9000_resource[2];
+
 	/* Configure chip-select 2 (DM9000) */
 	sam9_smc_configure(0, 2, &dm9000_smc_config);
 
@@ -139,6 +139,7 @@
 	/* Configure Interrupt pin as input, no pull-up */
 	at91_set_gpio_input(AT91_PIN_PC11, 0);
 
+	r->start = r->end = gpio_to_irq(AT91_PIN_PC11);
 	platform_device_register(&dm9000_device);
 }
 #else
diff -druN linux-libre-3.3.3-gnu/arch/arm/mach-omap1/timer.c linux-libre-3.3.4-gnu/arch/arm/mach-omap1/timer.c
--- linux-libre-3.3.3-gnu/arch/arm/mach-omap1/timer.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/arch/arm/mach-omap1/timer.c	2012-04-27 13:17:35.000000000 -0400
@@ -47,9 +47,9 @@
 	int n = (pdev->id - 1) << 1;
 	u32 l;
 
-	l = __raw_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
+	l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
 	l |= source << n;
-	__raw_writel(l, MOD_CONF_CTRL_1);
+	omap_writel(l, MOD_CONF_CTRL_1);
 
 	return 0;
 }
diff -druN linux-libre-3.3.3-gnu/arch/arm/mach-omap2/serial.c linux-libre-3.3.4-gnu/arch/arm/mach-omap2/serial.c
--- linux-libre-3.3.3-gnu/arch/arm/mach-omap2/serial.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/arch/arm/mach-omap2/serial.c	2012-04-27 13:17:35.000000000 -0400
@@ -110,8 +110,14 @@
 static void omap_uart_set_smartidle(struct platform_device *pdev)
 {
 	struct omap_device *od = to_omap_device(pdev);
+	u8 idlemode;
 
-	omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART);
+	if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+		idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+	else
+		idlemode = HWMOD_IDLEMODE_SMART;
+
+	omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode);
 }
 
 #else
diff -druN linux-libre-3.3.3-gnu/crypto/sha512_generic.c linux-libre-3.3.4-gnu/crypto/sha512_generic.c
--- linux-libre-3.3.3-gnu/crypto/sha512_generic.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/crypto/sha512_generic.c	2012-04-27 13:17:35.000000000 -0400
@@ -174,7 +174,7 @@
 	index = sctx->count[0] & 0x7f;
 
 	/* Update number of bytes */
-	if (!(sctx->count[0] += len))
+	if ((sctx->count[0] += len) < len)
 		sctx->count[1]++;
 
         part_len = 128 - index;
diff -druN linux-libre-3.3.3-gnu/drivers/bluetooth/ath3k.c linux-libre-3.3.4-gnu/drivers/bluetooth/ath3k.c
--- linux-libre-3.3.3-gnu/drivers/bluetooth/ath3k.c	2012-04-23 12:06:10.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/bluetooth/ath3k.c	2012-04-27 14:43:02.000000000 -0400
@@ -74,6 +74,7 @@
 	{ USB_DEVICE(0x0CF3, 0x3004) },
 	{ USB_DEVICE(0x0CF3, 0x311D) },
 	{ USB_DEVICE(0x13d3, 0x3375) },
+	{ USB_DEVICE(0x04CA, 0x3005) },
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xE02C) },
@@ -92,6 +93,7 @@
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
 
 	{ }	/* Terminating entry */
 };
diff -druN linux-libre-3.3.3-gnu/drivers/bluetooth/btusb.c linux-libre-3.3.4-gnu/drivers/bluetooth/btusb.c
--- linux-libre-3.3.3-gnu/drivers/bluetooth/btusb.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/bluetooth/btusb.c	2012-04-27 13:17:35.000000000 -0400
@@ -130,6 +130,7 @@
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
diff -druN linux-libre-3.3.3-gnu/drivers/md/md.c linux-libre-3.3.4-gnu/drivers/md/md.c
--- linux-libre-3.3.3-gnu/drivers/md/md.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/md/md.c	2012-04-27 13:17:35.000000000 -0400
@@ -7580,14 +7580,14 @@
 		 * any transients in the value of "sync_action".
 		 */
 		set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
-		clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 		/* Clear some bits that don't mean anything, but
 		 * might be left set
 		 */
 		clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
 		clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
 
-		if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
+		if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
+		    test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
 			goto unlock;
 		/* no recovery is running.
 		 * remove any failed drives, then
@@ -8160,7 +8160,8 @@
 
 	for_each_mddev(mddev, tmp) {
 		if (mddev_trylock(mddev)) {
-			__md_stop_writes(mddev);
+			if (mddev->pers)
+				__md_stop_writes(mddev);
 			mddev->safemode = 2;
 			mddev_unlock(mddev);
 		}
diff -druN linux-libre-3.3.3-gnu/drivers/media/dvb/dvb-core/dvb_frontend.c linux-libre-3.3.4-gnu/drivers/media/dvb/dvb-core/dvb_frontend.c
--- linux-libre-3.3.3-gnu/drivers/media/dvb/dvb-core/dvb_frontend.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/media/dvb/dvb-core/dvb_frontend.c	2012-04-27 13:17:35.000000000 -0400
@@ -1446,6 +1446,28 @@
 				__func__);
 			return -EINVAL;
 		}
+		/*
+		 * Get a delivery system that is compatible with DVBv3
+		 * NOTE: in order for this to work with softwares like Kaffeine that
+		 *	uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to
+		 *	DVB-S, drivers that support both should put the SYS_DVBS entry
+		 *	before the SYS_DVBS2, otherwise it won't switch back to DVB-S.
+		 *	The real fix is that userspace applications should not use DVBv3
+		 *	and not trust on calling FE_SET_FRONTEND to switch the delivery
+		 *	system.
+		 */
+		ncaps = 0;
+		while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
+			if (fe->ops.delsys[ncaps] == desired_system) {
+				delsys = desired_system;
+				break;
+			}
+			ncaps++;
+		}
+		if (delsys == SYS_UNDEFINED) {
+			dprintk("%s() Couldn't find a delivery system that matches %d\n",
+				__func__, desired_system);
+		}
 	} else {
 		/*
 		 * This is a DVBv5 call. So, it likely knows the supported
@@ -1494,9 +1516,10 @@
 				__func__);
 			return -EINVAL;
 		}
-		c->delivery_system = delsys;
 	}
 
+	c->delivery_system = delsys;
+
 	/*
 	 * The DVBv3 or DVBv5 call is requesting a different system. So,
 	 * emulation is needed.
diff -druN linux-libre-3.3.3-gnu/drivers/media/dvb/frontends/drxk_hard.c linux-libre-3.3.4-gnu/drivers/media/dvb/frontends/drxk_hard.c
--- linux-libre-3.3.3-gnu/drivers/media/dvb/frontends/drxk_hard.c	2012-04-23 11:42:45.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/media/dvb/frontends/drxk_hard.c	2012-04-27 14:36:17.000000000 -0400
@@ -1525,8 +1525,10 @@
 	dprintk(1, "\n");
 
 	if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
-	    ((resultLen > 0) && (result == NULL)))
-		goto error;
+	    ((resultLen > 0) && (result == NULL))) {
+		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		return status;
+	}
 
 	mutex_lock(&state->mutex);
 
diff -druN linux-libre-3.3.3-gnu/drivers/media/rc/winbond-cir.c linux-libre-3.3.4-gnu/drivers/media/rc/winbond-cir.c
--- linux-libre-3.3.3-gnu/drivers/media/rc/winbond-cir.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/media/rc/winbond-cir.c	2012-04-27 13:17:35.000000000 -0400
@@ -1046,6 +1046,7 @@
 		goto exit_unregister_led;
 	}
 
+	data->dev->driver_type = RC_DRIVER_IR_RAW;
 	data->dev->driver_name = WBCIR_NAME;
 	data->dev->input_name = WBCIR_NAME;
 	data->dev->input_phys = "wbcir/cir0";
diff -druN linux-libre-3.3.3-gnu/drivers/mmc/card/block.c linux-libre-3.3.4-gnu/drivers/mmc/card/block.c
--- linux-libre-3.3.3-gnu/drivers/mmc/card/block.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/mmc/card/block.c	2012-04-27 13:17:35.000000000 -0400
@@ -874,7 +874,7 @@
 {
 	struct mmc_blk_data *md = mq->data;
 	struct mmc_card *card = md->queue.card;
-	unsigned int from, nr, arg;
+	unsigned int from, nr, arg, trim_arg, erase_arg;
 	int err = 0, type = MMC_BLK_SECDISCARD;
 
 	if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) {
@@ -882,20 +882,26 @@
 		goto out;
 	}
 
+	from = blk_rq_pos(req);
+	nr = blk_rq_sectors(req);
+
 	/* The sanitize operation is supported at v4.5 only */
 	if (mmc_can_sanitize(card)) {
-		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-				EXT_CSD_SANITIZE_START, 1, 0);
-		goto out;
+		erase_arg = MMC_ERASE_ARG;
+		trim_arg = MMC_TRIM_ARG;
+	} else {
+		erase_arg = MMC_SECURE_ERASE_ARG;
+		trim_arg = MMC_SECURE_TRIM1_ARG;
 	}
 
-	from = blk_rq_pos(req);
-	nr = blk_rq_sectors(req);
-
-	if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
-		arg = MMC_SECURE_TRIM1_ARG;
-	else
-		arg = MMC_SECURE_ERASE_ARG;
+	if (mmc_erase_group_aligned(card, from, nr))
+		arg = erase_arg;
+	else if (mmc_can_trim(card))
+		arg = trim_arg;
+	else {
+		err = -EINVAL;
+		goto out;
+	}
 retry:
 	if (card->quirks & MMC_QUIRK_INAND_CMD38) {
 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -905,25 +911,41 @@
 				 INAND_CMD38_ARG_SECERASE,
 				 0);
 		if (err)
-			goto out;
+			goto out_retry;
 	}
+
 	err = mmc_erase(card, from, nr, arg);
-	if (!err && arg == MMC_SECURE_TRIM1_ARG) {
+	if (err == -EIO)
+		goto out_retry;
+	if (err)
+		goto out;
+
+	if (arg == MMC_SECURE_TRIM1_ARG) {
 		if (card->quirks & MMC_QUIRK_INAND_CMD38) {
 			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 					 INAND_CMD38_ARG_EXT_CSD,
 					 INAND_CMD38_ARG_SECTRIM2,
 					 0);
 			if (err)
-				goto out;
+				goto out_retry;
 		}
+
 		err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG);
+		if (err == -EIO)
+			goto out_retry;
+		if (err)
+			goto out;
 	}
-out:
-	if (err == -EIO && !mmc_blk_reset(md, card->host, type))
+
+	if (mmc_can_sanitize(card))
+		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+				 EXT_CSD_SANITIZE_START, 1, 0);
+out_retry:
+	if (err && !mmc_blk_reset(md, card->host, type))
 		goto retry;
 	if (!err)
 		mmc_blk_reset_success(md, type);
+out:
 	spin_lock_irq(&md->lock);
 	__blk_end_request(req, err, blk_rq_bytes(req));
 	spin_unlock_irq(&md->lock);
diff -druN linux-libre-3.3.3-gnu/drivers/mmc/card/queue.c linux-libre-3.3.4-gnu/drivers/mmc/card/queue.c
--- linux-libre-3.3.3-gnu/drivers/mmc/card/queue.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/mmc/card/queue.c	2012-04-27 13:17:35.000000000 -0400
@@ -139,7 +139,7 @@
 
 	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
 	q->limits.max_discard_sectors = max_discard;
-	if (card->erased_byte == 0)
+	if (card->erased_byte == 0 && !mmc_can_discard(card))
 		q->limits.discard_zeroes_data = 1;
 	q->limits.discard_granularity = card->pref_erase << 9;
 	/* granularity must not be greater than max. discard */
diff -druN linux-libre-3.3.3-gnu/drivers/mmc/core/core.c linux-libre-3.3.4-gnu/drivers/mmc/core/core.c
--- linux-libre-3.3.3-gnu/drivers/mmc/core/core.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/mmc/core/core.c	2012-04-27 13:17:35.000000000 -0400
@@ -1557,7 +1557,10 @@
 {
 	unsigned int erase_timeout;
 
-	if (card->ext_csd.erase_group_def & 1) {
+	if (arg == MMC_DISCARD_ARG ||
+	    (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) {
+		erase_timeout = card->ext_csd.trim_timeout;
+	} else if (card->ext_csd.erase_group_def & 1) {
 		/* High Capacity Erase Group Size uses HC timeouts */
 		if (arg == MMC_TRIM_ARG)
 			erase_timeout = card->ext_csd.trim_timeout;
@@ -1829,8 +1832,6 @@
 {
 	if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)
 		return 1;
-	if (mmc_can_discard(card))
-		return 1;
 	return 0;
 }
 EXPORT_SYMBOL(mmc_can_trim);
@@ -1849,6 +1850,8 @@
 
 int mmc_can_sanitize(struct mmc_card *card)
 {
+	if (!mmc_can_trim(card) && !mmc_can_erase(card))
+		return 0;
 	if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE)
 		return 1;
 	return 0;
diff -druN linux-libre-3.3.3-gnu/drivers/mmc/host/sdhci.c linux-libre-3.3.4-gnu/drivers/mmc/host/sdhci.c
--- linux-libre-3.3.3-gnu/drivers/mmc/host/sdhci.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/mmc/host/sdhci.c	2012-04-27 13:17:35.000000000 -0400
@@ -147,7 +147,7 @@
 	u32 present, irqs;
 
 	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
-	    !mmc_card_is_removable(host->mmc))
+	    (host->mmc->caps & MMC_CAP_NONREMOVABLE))
 		return;
 
 	present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
diff -druN linux-libre-3.3.3-gnu/drivers/mmc/host/sdhci-esdhc-imx.c linux-libre-3.3.4-gnu/drivers/mmc/host/sdhci-esdhc-imx.c
--- linux-libre-3.3.3-gnu/drivers/mmc/host/sdhci-esdhc-imx.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/mmc/host/sdhci-esdhc-imx.c	2012-04-27 13:17:35.000000000 -0400
@@ -467,8 +467,7 @@
 	clk_enable(clk);
 	pltfm_host->clk = clk;
 
-	if (!is_imx25_esdhc(imx_data))
-		host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+	host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
 	if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
 		/* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
diff -druN linux-libre-3.3.3-gnu/drivers/net/bonding/bond_main.c linux-libre-3.3.4-gnu/drivers/net/bonding/bond_main.c
--- linux-libre-3.3.3-gnu/drivers/net/bonding/bond_main.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/bonding/bond_main.c	2012-04-27 13:17:35.000000000 -0400
@@ -2982,7 +2982,11 @@
 					   trans_start + delta_in_ticks)) ||
 			    bond->curr_active_slave != slave) {
 				slave->link = BOND_LINK_UP;
-				bond->current_arp_slave = NULL;
+				if (bond->current_arp_slave) {
+					bond_set_slave_inactive_flags(
+						bond->current_arp_slave);
+					bond->current_arp_slave = NULL;
+				}
 
 				pr_info("%s: link status definitely up for interface %s.\n",
 					bond->dev->name, slave->dev->name);
diff -druN linux-libre-3.3.3-gnu/drivers/net/dummy.c linux-libre-3.3.4-gnu/drivers/net/dummy.c
--- linux-libre-3.3.3-gnu/drivers/net/dummy.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/dummy.c	2012-04-27 13:17:35.000000000 -0400
@@ -106,14 +106,14 @@
 	return 0;
 }
 
-static void dummy_dev_free(struct net_device *dev)
+static void dummy_dev_uninit(struct net_device *dev)
 {
 	free_percpu(dev->dstats);
-	free_netdev(dev);
 }
 
 static const struct net_device_ops dummy_netdev_ops = {
 	.ndo_init		= dummy_dev_init,
+	.ndo_uninit		= dummy_dev_uninit,
 	.ndo_start_xmit		= dummy_xmit,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_rx_mode	= set_multicast_list,
@@ -127,7 +127,7 @@
 
 	/* Initialize the device structure. */
 	dev->netdev_ops = &dummy_netdev_ops;
-	dev->destructor = dummy_dev_free;
+	dev->destructor = free_netdev;
 
 	/* Fill in device structure with ethernet-generic values. */
 	dev->tx_queue_len = 0;
diff -druN linux-libre-3.3.3-gnu/drivers/net/ethernet/atheros/atlx/atl1.c linux-libre-3.3.4-gnu/drivers/net/ethernet/atheros/atlx/atl1.c
--- linux-libre-3.3.3-gnu/drivers/net/ethernet/atheros/atlx/atl1.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/ethernet/atheros/atlx/atl1.c	2012-04-27 13:17:35.000000000 -0400
@@ -2473,7 +2473,7 @@
 					"pcie phy link down %x\n", status);
 			if (netif_running(adapter->netdev)) {	/* reset MAC */
 				iowrite32(0, adapter->hw.hw_addr + REG_IMR);
-				schedule_work(&adapter->pcie_dma_to_rst_task);
+				schedule_work(&adapter->reset_dev_task);
 				return IRQ_HANDLED;
 			}
 		}
@@ -2485,7 +2485,7 @@
 					"pcie DMA r/w error (status = 0x%x)\n",
 					status);
 			iowrite32(0, adapter->hw.hw_addr + REG_IMR);
-			schedule_work(&adapter->pcie_dma_to_rst_task);
+			schedule_work(&adapter->reset_dev_task);
 			return IRQ_HANDLED;
 		}
 
@@ -2630,10 +2630,10 @@
 	atl1_clean_rx_ring(adapter);
 }
 
-static void atl1_tx_timeout_task(struct work_struct *work)
+static void atl1_reset_dev_task(struct work_struct *work)
 {
 	struct atl1_adapter *adapter =
-		container_of(work, struct atl1_adapter, tx_timeout_task);
+		container_of(work, struct atl1_adapter, reset_dev_task);
 	struct net_device *netdev = adapter->netdev;
 
 	netif_device_detach(netdev);
@@ -3032,12 +3032,10 @@
 		    (unsigned long)adapter);
 	adapter->phy_timer_pending = false;
 
-	INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
+	INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task);
 
 	INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
 
-	INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
-
 	err = register_netdev(netdev);
 	if (err)
 		goto err_common;
diff -druN linux-libre-3.3.3-gnu/drivers/net/ethernet/atheros/atlx/atl1.h linux-libre-3.3.4-gnu/drivers/net/ethernet/atheros/atlx/atl1.h
--- linux-libre-3.3.3-gnu/drivers/net/ethernet/atheros/atlx/atl1.h	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/ethernet/atheros/atlx/atl1.h	2012-04-27 13:17:35.000000000 -0400
@@ -758,9 +758,8 @@
 	u16 link_speed;
 	u16 link_duplex;
 	spinlock_t lock;
-	struct work_struct tx_timeout_task;
+	struct work_struct reset_dev_task;
 	struct work_struct link_chg_task;
-	struct work_struct pcie_dma_to_rst_task;
 
 	struct timer_list phy_config_timer;
 	bool phy_timer_pending;
diff -druN linux-libre-3.3.3-gnu/drivers/net/ethernet/atheros/atlx/atlx.c linux-libre-3.3.4-gnu/drivers/net/ethernet/atheros/atlx/atlx.c
--- linux-libre-3.3.3-gnu/drivers/net/ethernet/atheros/atlx/atlx.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/ethernet/atheros/atlx/atlx.c	2012-04-27 13:17:35.000000000 -0400
@@ -193,7 +193,7 @@
 {
 	struct atlx_adapter *adapter = netdev_priv(netdev);
 	/* Do the reset outside of interrupt context */
-	schedule_work(&adapter->tx_timeout_task);
+	schedule_work(&adapter->reset_dev_task);
 }
 
 /*
diff -druN linux-libre-3.3.3-gnu/drivers/net/ethernet/micrel/ks8851_mll.c linux-libre-3.3.4-gnu/drivers/net/ethernet/micrel/ks8851_mll.c
--- linux-libre-3.3.3-gnu/drivers/net/ethernet/micrel/ks8851_mll.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/ethernet/micrel/ks8851_mll.c	2012-04-27 13:17:35.000000000 -0400
@@ -40,7 +40,7 @@
 #define	DRV_NAME	"ks8851_mll"
 
 static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 };
-#define MAX_RECV_FRAMES			32
+#define MAX_RECV_FRAMES			255
 #define MAX_BUF_SIZE			2048
 #define TX_BUF_SIZE			2000
 #define RX_BUF_SIZE			2000
diff -druN linux-libre-3.3.3-gnu/drivers/net/ethernet/micrel/ksz884x.c linux-libre-3.3.4-gnu/drivers/net/ethernet/micrel/ksz884x.c
--- linux-libre-3.3.3-gnu/drivers/net/ethernet/micrel/ksz884x.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/ethernet/micrel/ksz884x.c	2012-04-27 13:17:35.000000000 -0400
@@ -5675,7 +5675,7 @@
 		memcpy(hw->override_addr, mac->sa_data, ETH_ALEN);
 	}
 
-	memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN);
+	memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN);
 
 	interrupt = hw_block_intr(hw);
 
diff -druN linux-libre-3.3.3-gnu/drivers/net/ethernet/realtek/8139cp.c linux-libre-3.3.4-gnu/drivers/net/ethernet/realtek/8139cp.c
--- linux-libre-3.3.3-gnu/drivers/net/ethernet/realtek/8139cp.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/ethernet/realtek/8139cp.c	2012-04-27 13:17:35.000000000 -0400
@@ -958,6 +958,11 @@
 	cpw8(Cmd, RxOn | TxOn);
 }
 
+static void cp_enable_irq(struct cp_private *cp)
+{
+	cpw16_f(IntrMask, cp_intr_mask);
+}
+
 static void cp_init_hw (struct cp_private *cp)
 {
 	struct net_device *dev = cp->dev;
@@ -997,8 +1002,6 @@
 
 	cpw16(MultiIntr, 0);
 
-	cpw16_f(IntrMask, cp_intr_mask);
-
 	cpw8_f(Cfg9346, Cfg9346_Lock);
 }
 
@@ -1130,6 +1133,8 @@
 	if (rc)
 		goto err_out_hw;
 
+	cp_enable_irq(cp);
+
 	netif_carrier_off(dev);
 	mii_check_media(&cp->mii_if, netif_msg_link(cp), true);
 	netif_start_queue(dev);
@@ -2031,6 +2036,7 @@
 	/* FIXME: sh*t may happen if the Rx ring buffer is depleted */
 	cp_init_rings_index (cp);
 	cp_init_hw (cp);
+	cp_enable_irq(cp);
 	netif_start_queue (dev);
 
 	spin_lock_irqsave (&cp->lock, flags);
diff -druN linux-libre-3.3.3-gnu/drivers/net/ethernet/smsc/smsc911x.c linux-libre-3.3.4-gnu/drivers/net/ethernet/smsc/smsc911x.c
--- linux-libre-3.3.3-gnu/drivers/net/ethernet/smsc/smsc911x.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/ethernet/smsc/smsc911x.c	2012-04-27 13:17:35.000000000 -0400
@@ -1166,10 +1166,8 @@
 
 /* Quickly dumps bad packets */
 static void
-smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes)
+smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktwords)
 {
-	unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2;
-
 	if (likely(pktwords >= 4)) {
 		unsigned int timeout = 500;
 		unsigned int val;
@@ -1233,7 +1231,7 @@
 			continue;
 		}
 
-		skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN);
+		skb = netdev_alloc_skb(dev, pktwords << 2);
 		if (unlikely(!skb)) {
 			SMSC_WARN(pdata, rx_err,
 				  "Unable to allocate skb for rx packet");
@@ -1243,14 +1241,12 @@
 			break;
 		}
 
-		skb->data = skb->head;
-		skb_reset_tail_pointer(skb);
+		pdata->ops->rx_readfifo(pdata,
+				 (unsigned int *)skb->data, pktwords);
 
 		/* Align IP on 16B boundary */
 		skb_reserve(skb, NET_IP_ALIGN);
 		skb_put(skb, pktlength - 4);
-		pdata->ops->rx_readfifo(pdata,
-				 (unsigned int *)skb->head, pktwords);
 		skb->protocol = eth_type_trans(skb, dev);
 		skb_checksum_none_assert(skb);
 		netif_receive_skb(skb);
@@ -1565,7 +1561,7 @@
 	smsc911x_reg_write(pdata, FIFO_INT, temp);
 
 	/* set RX Data offset to 2 bytes for alignment */
-	smsc911x_reg_write(pdata, RX_CFG, (2 << 8));
+	smsc911x_reg_write(pdata, RX_CFG, (NET_IP_ALIGN << 8));
 
 	/* enable NAPI polling before enabling RX interrupts */
 	napi_enable(&pdata->napi);
diff -druN linux-libre-3.3.3-gnu/drivers/net/ethernet/ti/davinci_mdio.c linux-libre-3.3.4-gnu/drivers/net/ethernet/ti/davinci_mdio.c
--- linux-libre-3.3.3-gnu/drivers/net/ethernet/ti/davinci_mdio.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/ethernet/ti/davinci_mdio.c	2012-04-27 13:17:35.000000000 -0400
@@ -181,6 +181,11 @@
 		__davinci_mdio_reset(data);
 		return -EAGAIN;
 	}
+
+	reg = __raw_readl(&regs->user[0].access);
+	if ((reg & USERACCESS_GO) == 0)
+		return 0;
+
 	dev_err(data->dev, "timed out waiting for user access\n");
 	return -ETIMEDOUT;
 }
diff -druN linux-libre-3.3.3-gnu/drivers/net/phy/icplus.c linux-libre-3.3.4-gnu/drivers/net/phy/icplus.c
--- linux-libre-3.3.3-gnu/drivers/net/phy/icplus.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/phy/icplus.c	2012-04-27 13:17:35.000000000 -0400
@@ -162,7 +162,8 @@
 	/* Enable Auto Power Saving mode */
 	c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
 	c |= IP101A_G_APS_ON;
-	return c;
+
+	return phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
 }
 
 static int ip175c_read_status(struct phy_device *phydev)
diff -druN linux-libre-3.3.3-gnu/drivers/net/ppp/ppp_generic.c linux-libre-3.3.4-gnu/drivers/net/ppp/ppp_generic.c
--- linux-libre-3.3.3-gnu/drivers/net/ppp/ppp_generic.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/ppp/ppp_generic.c	2012-04-27 13:17:35.000000000 -0400
@@ -968,7 +968,6 @@
 	proto = npindex_to_proto[npi];
 	put_unaligned_be16(proto, pp);
 
-	netif_stop_queue(dev);
 	skb_queue_tail(&ppp->file.xq, skb);
 	ppp_xmit_process(ppp);
 	return NETDEV_TX_OK;
@@ -1063,6 +1062,8 @@
 		   code that we can accept some more. */
 		if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq))
 			netif_wake_queue(ppp->dev);
+		else
+			netif_stop_queue(ppp->dev);
 	}
 	ppp_xmit_unlock(ppp);
 }
diff -druN linux-libre-3.3.3-gnu/drivers/net/usb/smsc75xx.c linux-libre-3.3.4-gnu/drivers/net/usb/smsc75xx.c
--- linux-libre-3.3.3-gnu/drivers/net/usb/smsc75xx.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/usb/smsc75xx.c	2012-04-27 13:17:35.000000000 -0400
@@ -1051,6 +1051,7 @@
 	dev->net->ethtool_ops = &smsc75xx_ethtool_ops;
 	dev->net->flags |= IFF_MULTICAST;
 	dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD;
+	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
 	return 0;
 }
 
diff -druN linux-libre-3.3.3-gnu/drivers/net/wimax/i2400m/netdev.c linux-libre-3.3.4-gnu/drivers/net/wimax/i2400m/netdev.c
--- linux-libre-3.3.3-gnu/drivers/net/wimax/i2400m/netdev.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/wimax/i2400m/netdev.c	2012-04-27 13:17:35.000000000 -0400
@@ -597,7 +597,8 @@
 	struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
 
 	strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver) - 1);
-	strncpy(info->fw_version, i2400m->fw_name, sizeof(info->fw_version) - 1);
+	strncpy(info->fw_version,
+	        i2400m->fw_name ? : "", sizeof(info->fw_version) - 1);
 	if (net_dev->dev.parent)
 		strncpy(info->bus_info, dev_name(net_dev->dev.parent),
 			sizeof(info->bus_info) - 1);
diff -druN linux-libre-3.3.3-gnu/drivers/net/wireless/brcm80211/brcmsmac/main.c linux-libre-3.3.4-gnu/drivers/net/wireless/brcm80211/brcmsmac/main.c
--- linux-libre-3.3.3-gnu/drivers/net/wireless/brcm80211/brcmsmac/main.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/wireless/brcm80211/brcmsmac/main.c	2012-04-27 13:17:35.000000000 -0400
@@ -7629,6 +7629,7 @@
 {
 	int len_mpdu;
 	struct ieee80211_rx_status rx_status;
+	struct ieee80211_hdr *hdr;
 
 	memset(&rx_status, 0, sizeof(rx_status));
 	prep_mac80211_status(wlc, rxh, p, &rx_status);
@@ -7638,6 +7639,13 @@
 	skb_pull(p, D11_PHY_HDR_LEN);
 	__skb_trim(p, len_mpdu);
 
+	/* unmute transmit */
+	if (wlc->hw->suspended_fifos) {
+		hdr = (struct ieee80211_hdr *)p->data;
+		if (ieee80211_is_beacon(hdr->frame_control))
+			brcms_b_mute(wlc->hw, false);
+	}
+
 	memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
 	ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
 }
diff -druN linux-libre-3.3.3-gnu/drivers/net/wireless/mwifiex/pcie.h linux-libre-3.3.4-gnu/drivers/net/wireless/mwifiex/pcie.h
--- linux-libre-3.3.3-gnu/drivers/net/wireless/mwifiex/pcie.h	2012-04-23 12:01:01.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/net/wireless/mwifiex/pcie.h	2012-04-27 14:41:35.000000000 -0400
@@ -48,15 +48,15 @@
 #define PCIE_HOST_INT_STATUS_MASK			0xC3C
 #define PCIE_SCRATCH_2_REG				0xC40
 #define PCIE_SCRATCH_3_REG				0xC44
-#define PCIE_SCRATCH_4_REG				0xCC0
-#define PCIE_SCRATCH_5_REG				0xCC4
-#define PCIE_SCRATCH_6_REG				0xCC8
-#define PCIE_SCRATCH_7_REG				0xCCC
-#define PCIE_SCRATCH_8_REG				0xCD0
-#define PCIE_SCRATCH_9_REG				0xCD4
-#define PCIE_SCRATCH_10_REG				0xCD8
-#define PCIE_SCRATCH_11_REG				0xCDC
-#define PCIE_SCRATCH_12_REG				0xCE0
+#define PCIE_SCRATCH_4_REG				0xCD0
+#define PCIE_SCRATCH_5_REG				0xCD4
+#define PCIE_SCRATCH_6_REG				0xCD8
+#define PCIE_SCRATCH_7_REG				0xCDC
+#define PCIE_SCRATCH_8_REG				0xCE0
+#define PCIE_SCRATCH_9_REG				0xCE4
+#define PCIE_SCRATCH_10_REG				0xCE8
+#define PCIE_SCRATCH_11_REG				0xCEC
+#define PCIE_SCRATCH_12_REG				0xCF0
 
 #define CPU_INTR_DNLD_RDY				BIT(0)
 #define CPU_INTR_DOOR_BELL				BIT(1)
diff -druN linux-libre-3.3.3-gnu/drivers/pci/quirks.c linux-libre-3.3.4-gnu/drivers/pci/quirks.c
--- linux-libre-3.3.3-gnu/drivers/pci/quirks.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/pci/quirks.c	2012-04-27 13:17:35.000000000 -0400
@@ -2906,6 +2906,40 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata);
 
+/*
+ * Some BIOS implementations leave the Intel GPU interrupts enabled,
+ * even though no one is handling them (f.e. i915 driver is never loaded).
+ * Additionally the interrupt destination is not set up properly
+ * and the interrupt ends up -somewhere-.
+ *
+ * These spurious interrupts are "sticky" and the kernel disables
+ * the (shared) interrupt line after 100.000+ generated interrupts.
+ *
+ * Fix it by disabling the still enabled interrupts.
+ * This resolves crashes often seen on monitor unplug.
+ */
+#define I915_DEIER_REG 0x4400c
+static void __devinit disable_igfx_irq(struct pci_dev *dev)
+{
+	void __iomem *regs = pci_iomap(dev, 0, 0);
+	if (regs == NULL) {
+		dev_warn(&dev->dev, "igfx quirk: Can't iomap PCI device\n");
+		return;
+	}
+
+	/* Check if any interrupt line is still enabled */
+	if (readl(regs + I915_DEIER_REG) != 0) {
+		dev_warn(&dev->dev, "BIOS left Intel GPU interrupts enabled; "
+			"disabling\n");
+
+		writel(0, regs + I915_DEIER_REG);
+	}
+
+	pci_iounmap(dev, regs);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
+
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
 			  struct pci_fixup *end)
 {
diff -druN linux-libre-3.3.3-gnu/drivers/platform/x86/dell-laptop.c linux-libre-3.3.4-gnu/drivers/platform/x86/dell-laptop.c
--- linux-libre-3.3.3-gnu/drivers/platform/x86/dell-laptop.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/platform/x86/dell-laptop.c	2012-04-27 13:17:35.000000000 -0400
@@ -184,6 +184,33 @@
 		},
 		.driver_data = &quirk_dell_vostro_v130,
 	},
+	{
+		.callback = dmi_matched,
+		.ident = "Dell Vostro 3555",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3555"),
+		},
+		.driver_data = &quirk_dell_vostro_v130,
+	},
+	{
+		.callback = dmi_matched,
+		.ident = "Dell Inspiron N311z",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron N311z"),
+		},
+		.driver_data = &quirk_dell_vostro_v130,
+	},
+	{
+		.callback = dmi_matched,
+		.ident = "Dell Inspiron M5110",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron M5110"),
+		},
+		.driver_data = &quirk_dell_vostro_v130,
+	},
 };
 
 static struct calling_interface_buffer *buffer;
@@ -615,6 +642,7 @@
 static struct led_classdev touchpad_led = {
 	.name = "dell-laptop::touchpad",
 	.brightness_set = touchpad_led_set,
+	.flags = LED_CORE_SUSPENDRESUME,
 };
 
 static int __devinit touchpad_led_init(struct device *dev)
diff -druN linux-libre-3.3.3-gnu/drivers/staging/rtl8712/os_intfs.c linux-libre-3.3.4-gnu/drivers/staging/rtl8712/os_intfs.c
--- linux-libre-3.3.3-gnu/drivers/staging/rtl8712/os_intfs.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/staging/rtl8712/os_intfs.c	2012-04-27 13:17:35.000000000 -0400
@@ -476,9 +476,6 @@
 	r8712_free_assoc_resources(padapter);
 	/*s2-4.*/
 	r8712_free_network_queue(padapter);
-	release_firmware(padapter->fw);
-	/* never exit with a firmware callback pending */
-	wait_for_completion(&padapter->rtl8712_fw_ready);
 	return 0;
 }
 
diff -druN linux-libre-3.3.3-gnu/drivers/staging/rtl8712/usb_intf.c linux-libre-3.3.4-gnu/drivers/staging/rtl8712/usb_intf.c
--- linux-libre-3.3.3-gnu/drivers/staging/rtl8712/usb_intf.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/staging/rtl8712/usb_intf.c	2012-04-27 13:17:35.000000000 -0400
@@ -30,6 +30,7 @@
 
 #include <linux/usb.h>
 #include <linux/module.h>
+#include <linux/firmware.h>
 
 #include "osdep_service.h"
 #include "drv_types.h"
@@ -621,6 +622,10 @@
 	struct _adapter *padapter = netdev_priv(pnetdev);
 	struct usb_device *udev = interface_to_usbdev(pusb_intf);
 
+	if (padapter->fw_found)
+		release_firmware(padapter->fw);
+	/* never exit with a firmware callback pending */
+	wait_for_completion(&padapter->rtl8712_fw_ready);
 	usb_set_intfdata(pusb_intf, NULL);
 	if (padapter) {
 		if (drvpriv.drv_registered == true)
diff -druN linux-libre-3.3.3-gnu/drivers/tty/amiserial.c linux-libre-3.3.4-gnu/drivers/tty/amiserial.c
--- linux-libre-3.3.3-gnu/drivers/tty/amiserial.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/tty/amiserial.c	2012-04-27 13:17:35.000000000 -0400
@@ -1113,8 +1113,10 @@
 		    (new_serial.close_delay != state->close_delay) ||
 		    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
 		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
-		     (state->flags & ~ASYNC_USR_MASK)))
+		     (state->flags & ~ASYNC_USR_MASK))) {
+			tty_unlock();
 			return -EPERM;
+		}
 		state->flags = ((state->flags & ~ASYNC_USR_MASK) |
 			       (new_serial.flags & ASYNC_USR_MASK));
 		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
diff -druN linux-libre-3.3.3-gnu/drivers/tty/serial/clps711x.c linux-libre-3.3.4-gnu/drivers/tty/serial/clps711x.c
--- linux-libre-3.3.3-gnu/drivers/tty/serial/clps711x.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/tty/serial/clps711x.c	2012-04-27 13:17:35.000000000 -0400
@@ -154,10 +154,9 @@
 		port->x_char = 0;
 		return IRQ_HANDLED;
 	}
-	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-		clps711xuart_stop_tx(port);
-		return IRQ_HANDLED;
-	}
+
+	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+		goto disable_tx_irq;
 
 	count = port->fifosize >> 1;
 	do {
@@ -171,8 +170,11 @@
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(port);
 
-	if (uart_circ_empty(xmit))
-		clps711xuart_stop_tx(port);
+	if (uart_circ_empty(xmit)) {
+	disable_tx_irq:
+		disable_irq_nosync(TX_IRQ(port));
+		tx_enabled(port) = 0;
+	}
 
 	return IRQ_HANDLED;
 }
diff -druN linux-libre-3.3.3-gnu/drivers/tty/serial/pch_uart.c linux-libre-3.3.4-gnu/drivers/tty/serial/pch_uart.c
--- linux-libre-3.3.3-gnu/drivers/tty/serial/pch_uart.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/tty/serial/pch_uart.c	2012-04-27 13:17:35.000000000 -0400
@@ -1366,9 +1366,11 @@
 			__func__);
 		return -EOPNOTSUPP;
 #endif
-		priv->use_dma = 1;
 		priv->use_dma_flag = 1;
 		dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n");
+		if (!priv->use_dma)
+			pch_request_dma(port);
+		priv->use_dma = 1;
 	}
 
 	return 0;
diff -druN linux-libre-3.3.3-gnu/drivers/usb/core/hub.c linux-libre-3.3.4-gnu/drivers/usb/core/hub.c
--- linux-libre-3.3.3-gnu/drivers/usb/core/hub.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/usb/core/hub.c	2012-04-27 13:17:35.000000000 -0400
@@ -1643,7 +1643,6 @@
 {
 	struct usb_device	*udev = *pdev;
 	int			i;
-	struct usb_hcd		*hcd = bus_to_hcd(udev->bus);
 
 	/* mark the device as inactive, so any further urb submissions for
 	 * this device (and any of its children) will fail immediately.
@@ -1666,9 +1665,7 @@
 	 * so that the hardware is now fully quiesced.
 	 */
 	dev_dbg (&udev->dev, "unregistering device\n");
-	mutex_lock(hcd->bandwidth_mutex);
 	usb_disable_device(udev, 0);
-	mutex_unlock(hcd->bandwidth_mutex);
 	usb_hcd_synchronize_unlinks(udev);
 
 	usb_remove_ep_devs(&udev->ep0);
diff -druN linux-libre-3.3.3-gnu/drivers/usb/core/message.c linux-libre-3.3.4-gnu/drivers/usb/core/message.c
--- linux-libre-3.3.3-gnu/drivers/usb/core/message.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/usb/core/message.c	2012-04-27 13:17:35.000000000 -0400
@@ -1136,8 +1136,6 @@
  * Deallocates hcd/hardware state for the endpoints (nuking all or most
  * pending urbs) and usbcore state for the interfaces, so that usbcore
  * must usb_set_configuration() before any interfaces could be used.
- *
- * Must be called with hcd->bandwidth_mutex held.
  */
 void usb_disable_device(struct usb_device *dev, int skip_ep0)
 {
@@ -1190,7 +1188,9 @@
 			usb_disable_endpoint(dev, i + USB_DIR_IN, false);
 		}
 		/* Remove endpoints from the host controller internal state */
+		mutex_lock(hcd->bandwidth_mutex);
 		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+		mutex_unlock(hcd->bandwidth_mutex);
 		/* Second pass: remove endpoint pointers */
 	}
 	for (i = skip_ep0; i < 16; ++i) {
@@ -1750,7 +1750,6 @@
 	/* if it's already configured, clear out old state first.
 	 * getting rid of old interfaces means unbinding their drivers.
 	 */
-	mutex_lock(hcd->bandwidth_mutex);
 	if (dev->state != USB_STATE_ADDRESS)
 		usb_disable_device(dev, 1);	/* Skip ep0 */
 
@@ -1763,6 +1762,7 @@
 	 * host controller will not allow submissions to dropped endpoints.  If
 	 * this call fails, the device state is unchanged.
 	 */
+	mutex_lock(hcd->bandwidth_mutex);
 	ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
 	if (ret < 0) {
 		mutex_unlock(hcd->bandwidth_mutex);
diff -druN linux-libre-3.3.3-gnu/drivers/usb/dwc3/ep0.c linux-libre-3.3.4-gnu/drivers/usb/dwc3/ep0.c
--- linux-libre-3.3.3-gnu/drivers/usb/dwc3/ep0.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/usb/dwc3/ep0.c	2012-04-27 13:17:35.000000000 -0400
@@ -583,9 +583,10 @@
 		dwc->ep0_bounced = false;
 	} else {
 		transferred = ur->length - trb.length;
-		ur->actual += transferred;
 	}
 
+	ur->actual += transferred;
+
 	if ((epnum & 1) && ur->actual < ur->length) {
 		/* for some reason we did not get everything out */
 
diff -druN linux-libre-3.3.3-gnu/drivers/usb/gadget/f_fs.c linux-libre-3.3.4-gnu/drivers/usb/gadget/f_fs.c
--- linux-libre-3.3.3-gnu/drivers/usb/gadget/f_fs.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/usb/gadget/f_fs.c	2012-04-27 13:17:35.000000000 -0400
@@ -712,7 +712,7 @@
 	if (code == FUNCTIONFS_INTERFACE_REVMAP) {
 		struct ffs_function *func = ffs->func;
 		ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV;
-	} else if (gadget->ops->ioctl) {
+	} else if (gadget && gadget->ops->ioctl) {
 		ret = gadget->ops->ioctl(gadget, code, value);
 	} else {
 		ret = -ENOTTY;
diff -druN linux-libre-3.3.3-gnu/drivers/usb/gadget/udc-core.c linux-libre-3.3.4-gnu/drivers/usb/gadget/udc-core.c
--- linux-libre-3.3.3-gnu/drivers/usb/gadget/udc-core.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/usb/gadget/udc-core.c	2012-04-27 13:17:35.000000000 -0400
@@ -212,8 +212,8 @@
 	if (udc_is_newstyle(udc)) {
 		udc->driver->disconnect(udc->gadget);
 		udc->driver->unbind(udc->gadget);
-		usb_gadget_udc_stop(udc->gadget, udc->driver);
 		usb_gadget_disconnect(udc->gadget);
+		usb_gadget_udc_stop(udc->gadget, udc->driver);
 	} else {
 		usb_gadget_stop(udc->gadget, udc->driver);
 	}
@@ -359,8 +359,12 @@
 	struct usb_udc		*udc = container_of(dev, struct usb_udc, dev);
 
 	if (sysfs_streq(buf, "connect")) {
+		if (udc_is_newstyle(udc))
+			usb_gadget_udc_start(udc->gadget, udc->driver);
 		usb_gadget_connect(udc->gadget);
 	} else if (sysfs_streq(buf, "disconnect")) {
+		if (udc_is_newstyle(udc))
+			usb_gadget_udc_stop(udc->gadget, udc->driver);
 		usb_gadget_disconnect(udc->gadget);
 	} else {
 		dev_err(dev, "unsupported command '%s'\n", buf);
diff -druN linux-libre-3.3.3-gnu/drivers/usb/host/ehci-hcd.c linux-libre-3.3.4-gnu/drivers/usb/host/ehci-hcd.c
--- linux-libre-3.3.3-gnu/drivers/usb/host/ehci-hcd.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/usb/host/ehci-hcd.c	2012-04-27 13:17:35.000000000 -0400
@@ -857,8 +857,13 @@
 		goto dead;
 	}
 
+	/*
+	 * We don't use STS_FLR, but some controllers don't like it to
+	 * remain on, so mask it out along with the other status bits.
+	 */
+	masked_status = status & (INTR_MASK | STS_FLR);
+
 	/* Shared IRQ? */
-	masked_status = status & INTR_MASK;
 	if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
 		spin_unlock(&ehci->lock);
 		return IRQ_NONE;
@@ -909,7 +914,7 @@
 		pcd_status = status;
 
 		/* resume root hub? */
-		if (!(cmd & CMD_RUN))
+		if (ehci->rh_state == EHCI_RH_SUSPENDED)
 			usb_hcd_resume_root_hub(hcd);
 
 		/* get per-port change detect bits */
diff -druN linux-libre-3.3.3-gnu/drivers/usb/misc/yurex.c linux-libre-3.3.4-gnu/drivers/usb/misc/yurex.c
--- linux-libre-3.3.3-gnu/drivers/usb/misc/yurex.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/usb/misc/yurex.c	2012-04-27 13:17:35.000000000 -0400
@@ -99,9 +99,7 @@
 	usb_put_dev(dev->udev);
 	if (dev->cntl_urb) {
 		usb_kill_urb(dev->cntl_urb);
-		if (dev->cntl_req)
-			usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
-				dev->cntl_req, dev->cntl_urb->setup_dma);
+		kfree(dev->cntl_req);
 		if (dev->cntl_buffer)
 			usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
 				dev->cntl_buffer, dev->cntl_urb->transfer_dma);
@@ -234,9 +232,7 @@
 	}
 
 	/* allocate buffer for control req */
-	dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
-					   GFP_KERNEL,
-					   &dev->cntl_urb->setup_dma);
+	dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);
 	if (!dev->cntl_req) {
 		err("Could not allocate cntl_req");
 		goto error;
@@ -286,7 +282,7 @@
 			 usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),
 			 dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,
 			 dev, 1);
-	dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+	dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 	if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
 		retval = -EIO;
 		err("Could not submitting URB");
diff -druN linux-libre-3.3.3-gnu/drivers/usb/musb/omap2430.c linux-libre-3.3.4-gnu/drivers/usb/musb/omap2430.c
--- linux-libre-3.3.3-gnu/drivers/usb/musb/omap2430.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/usb/musb/omap2430.c	2012-04-27 13:17:35.000000000 -0400
@@ -281,7 +281,8 @@
 
 static int omap2430_musb_init(struct musb *musb)
 {
-	u32 l, status = 0;
+	u32 l;
+	int status = 0;
 	struct device *dev = musb->controller;
 	struct musb_hdrc_platform_data *plat = dev->platform_data;
 	struct omap_musb_board_data *data = plat->board_data;
@@ -300,7 +301,7 @@
 
 	status = pm_runtime_get_sync(dev);
 	if (status < 0) {
-		dev_err(dev, "pm_runtime_get_sync FAILED");
+		dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
 		goto err1;
 	}
 
@@ -451,14 +452,14 @@
 		goto err2;
 	}
 
+	pm_runtime_enable(&pdev->dev);
+
 	ret = platform_device_add(musb);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register musb device\n");
 		goto err2;
 	}
 
-	pm_runtime_enable(&pdev->dev);
-
 	return 0;
 
 err2:
diff -druN linux-libre-3.3.3-gnu/drivers/usb/serial/cp210x.c linux-libre-3.3.4-gnu/drivers/usb/serial/cp210x.c
--- linux-libre-3.3.3-gnu/drivers/usb/serial/cp210x.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/usb/serial/cp210x.c	2012-04-27 13:17:35.000000000 -0400
@@ -285,7 +285,8 @@
 	/* Issue the request, attempting to read 'size' bytes */
 	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 				request, REQTYPE_DEVICE_TO_HOST, 0x0000,
-				port_priv->bInterfaceNumber, buf, size, 300);
+				port_priv->bInterfaceNumber, buf, size,
+				USB_CTRL_GET_TIMEOUT);
 
 	/* Convert data into an array of integers */
 	for (i = 0; i < length; i++)
@@ -338,12 +339,14 @@
 		result = usb_control_msg(serial->dev,
 				usb_sndctrlpipe(serial->dev, 0),
 				request, REQTYPE_HOST_TO_DEVICE, 0x0000,
-				port_priv->bInterfaceNumber, buf, size, 300);
+				port_priv->bInterfaceNumber, buf, size,
+				USB_CTRL_SET_TIMEOUT);
 	} else {
 		result = usb_control_msg(serial->dev,
 				usb_sndctrlpipe(serial->dev, 0),
 				request, REQTYPE_HOST_TO_DEVICE, data[0],
-				port_priv->bInterfaceNumber, NULL, 0, 300);
+				port_priv->bInterfaceNumber, NULL, 0,
+				USB_CTRL_SET_TIMEOUT);
 	}
 
 	kfree(buf);
diff -druN linux-libre-3.3.3-gnu/drivers/usb/serial/sierra.c linux-libre-3.3.4-gnu/drivers/usb/serial/sierra.c
--- linux-libre-3.3.3-gnu/drivers/usb/serial/sierra.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/usb/serial/sierra.c	2012-04-27 13:17:35.000000000 -0400
@@ -221,7 +221,7 @@
 };
 
 /* 'blacklist' of interfaces not served by this driver */
-static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 };
+static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };
 static const struct sierra_iface_info direct_ip_interface_blacklist = {
 	.infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
 	.ifaceinfo = direct_ip_non_serial_ifaces,
@@ -289,7 +289,6 @@
 	{ USB_DEVICE(0x1199, 0x6856) },	/* Sierra Wireless AirCard 881 U */
 	{ USB_DEVICE(0x1199, 0x6859) },	/* Sierra Wireless AirCard 885 E */
 	{ USB_DEVICE(0x1199, 0x685A) },	/* Sierra Wireless AirCard 885 E */
-	{ USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */
 	/* Sierra Wireless C885 */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
 	/* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
@@ -299,6 +298,9 @@
 	/* Sierra Wireless HSPA Non-Composite Device */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
 	{ USB_DEVICE(0x1199, 0x6893) },	/* Sierra Wireless Device */
+	{ USB_DEVICE(0x1199, 0x68A2),   /* Sierra Wireless MC77xx in QMI mode */
+	  .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
+	},
 	{ USB_DEVICE(0x1199, 0x68A3), 	/* Sierra Wireless Direct IP modems */
 	  .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
 	},
diff -druN linux-libre-3.3.3-gnu/drivers/uwb/hwa-rc.c linux-libre-3.3.4-gnu/drivers/uwb/hwa-rc.c
--- linux-libre-3.3.3-gnu/drivers/uwb/hwa-rc.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/uwb/hwa-rc.c	2012-04-27 13:17:35.000000000 -0400
@@ -645,7 +645,8 @@
 		dev_err(dev, "NEEP: URB error %d\n", urb->status);
 	}
 	result = usb_submit_urb(urb, GFP_ATOMIC);
-	if (result < 0) {
+	if (result < 0 && result != -ENODEV && result != -EPERM) {
+		/* ignoring unrecoverable errors */
 		dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n",
 			result);
 		goto error;
diff -druN linux-libre-3.3.3-gnu/drivers/uwb/neh.c linux-libre-3.3.4-gnu/drivers/uwb/neh.c
--- linux-libre-3.3.3-gnu/drivers/uwb/neh.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/uwb/neh.c	2012-04-27 13:17:35.000000000 -0400
@@ -107,6 +107,7 @@
 	u8 evt_type;
 	__le16 evt;
 	u8 context;
+	u8 completed;
 	uwb_rc_cmd_cb_f cb;
 	void *arg;
 
@@ -409,6 +410,7 @@
 	struct device *dev = &rc->uwb_dev.dev;
 	struct uwb_rc_neh *neh;
 	struct uwb_rceb *notif;
+	unsigned long flags;
 
 	if (rceb->bEventContext == 0) {
 		notif = kmalloc(size, GFP_ATOMIC);
@@ -422,7 +424,11 @@
 	} else {
 		neh = uwb_rc_neh_lookup(rc, rceb);
 		if (neh) {
-			del_timer_sync(&neh->timer);
+			spin_lock_irqsave(&rc->neh_lock, flags);
+			/* to guard against a timeout */
+			neh->completed = 1;
+			del_timer(&neh->timer);
+			spin_unlock_irqrestore(&rc->neh_lock, flags);
 			uwb_rc_neh_cb(neh, rceb, size);
 		} else
 			dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n",
@@ -568,6 +574,10 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&rc->neh_lock, flags);
+	if (neh->completed) {
+		spin_unlock_irqrestore(&rc->neh_lock, flags);
+		return;
+	}
 	if (neh->context)
 		__uwb_rc_neh_rm(rc, neh);
 	else
diff -druN linux-libre-3.3.3-gnu/drivers/xen/gntdev.c linux-libre-3.3.4-gnu/drivers/xen/gntdev.c
--- linux-libre-3.3.3-gnu/drivers/xen/gntdev.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/xen/gntdev.c	2012-04-27 13:17:35.000000000 -0400
@@ -722,7 +722,7 @@
 	vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;
 
 	if (use_ptemod)
-		vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP;
+		vma->vm_flags |= VM_DONTCOPY;
 
 	vma->vm_private_data = map;
 
diff -druN linux-libre-3.3.3-gnu/drivers/xen/xenbus/xenbus_probe_frontend.c linux-libre-3.3.4-gnu/drivers/xen/xenbus/xenbus_probe_frontend.c
--- linux-libre-3.3.3-gnu/drivers/xen/xenbus/xenbus_probe_frontend.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/drivers/xen/xenbus/xenbus_probe_frontend.c	2012-04-27 13:17:35.000000000 -0400
@@ -129,7 +129,7 @@
 	return xenbus_read_otherend_details(xendev, "backend-id", "backend");
 }
 
-static int is_device_connecting(struct device *dev, void *data)
+static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential)
 {
 	struct xenbus_device *xendev = to_xenbus_device(dev);
 	struct device_driver *drv = data;
@@ -146,16 +146,41 @@
 	if (drv && (dev->driver != drv))
 		return 0;
 
+	if (ignore_nonessential) {
+		/* With older QEMU, for PVonHVM guests the guest config files
+		 * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0']
+		 * which is nonsensical as there is no PV FB (there can be
+		 * a PVKB) running as HVM guest. */
+
+		if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0))
+			return 0;
+
+		if ((strncmp(xendev->nodename, "device/vfb", 10) == 0))
+			return 0;
+	}
 	xendrv = to_xenbus_driver(dev->driver);
 	return (xendev->state < XenbusStateConnected ||
 		(xendev->state == XenbusStateConnected &&
 		 xendrv->is_ready && !xendrv->is_ready(xendev)));
 }
+static int essential_device_connecting(struct device *dev, void *data)
+{
+	return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */);
+}
+static int non_essential_device_connecting(struct device *dev, void *data)
+{
+	return is_device_connecting(dev, data, false);
+}
 
-static int exists_connecting_device(struct device_driver *drv)
+static int exists_essential_connecting_device(struct device_driver *drv)
 {
 	return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
-				is_device_connecting);
+				essential_device_connecting);
+}
+static int exists_non_essential_connecting_device(struct device_driver *drv)
+{
+	return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
+				non_essential_device_connecting);
 }
 
 static int print_device_status(struct device *dev, void *data)
@@ -186,6 +211,23 @@
 /* We only wait for device setup after most initcalls have run. */
 static int ready_to_wait_for_devices;
 
+static bool wait_loop(unsigned long start, unsigned int max_delay,
+		     unsigned int *seconds_waited)
+{
+	if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) {
+		if (!*seconds_waited)
+			printk(KERN_WARNING "XENBUS: Waiting for "
+			       "devices to initialise: ");
+		*seconds_waited += 5;
+		printk("%us...", max_delay - *seconds_waited);
+		if (*seconds_waited == max_delay)
+			return true;
+	}
+
+	schedule_timeout_interruptible(HZ/10);
+
+	return false;
+}
 /*
  * On a 5-minute timeout, wait for all devices currently configured.  We need
  * to do this to guarantee that the filesystems and / or network devices
@@ -209,19 +251,14 @@
 	if (!ready_to_wait_for_devices || !xen_domain())
 		return;
 
-	while (exists_connecting_device(drv)) {
-		if (time_after(jiffies, start + (seconds_waited+5)*HZ)) {
-			if (!seconds_waited)
-				printk(KERN_WARNING "XENBUS: Waiting for "
-				       "devices to initialise: ");
-			seconds_waited += 5;
-			printk("%us...", 300 - seconds_waited);
-			if (seconds_waited == 300)
-				break;
-		}
+	while (exists_non_essential_connecting_device(drv))
+		if (wait_loop(start, 30, &seconds_waited))
+			break;
 
-		schedule_timeout_interruptible(HZ/10);
-	}
+	/* Skips PVKB and PVFB check.*/
+	while (exists_essential_connecting_device(drv))
+		if (wait_loop(start, 270, &seconds_waited))
+			break;
 
 	if (seconds_waited)
 		printk("\n");
diff -druN linux-libre-3.3.3-gnu/fs/btrfs/ctree.h linux-libre-3.3.4-gnu/fs/btrfs/ctree.h
--- linux-libre-3.3.3-gnu/fs/btrfs/ctree.h	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/btrfs/ctree.h	2012-04-27 13:17:35.000000000 -0400
@@ -2115,7 +2115,7 @@
 
 static inline bool btrfs_root_readonly(struct btrfs_root *root)
 {
-	return root->root_item.flags & BTRFS_ROOT_SUBVOL_RDONLY;
+	return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0;
 }
 
 /* struct btrfs_root_backup */
diff -druN linux-libre-3.3.3-gnu/fs/ext4/extents.c linux-libre-3.3.4-gnu/fs/ext4/extents.c
--- linux-libre-3.3.3-gnu/fs/ext4/extents.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/ext4/extents.c	2012-04-27 13:17:35.000000000 -0400
@@ -2811,7 +2811,7 @@
 		if (err)
 			goto fix_extent_len;
 		/* update the extent length and mark as initialized */
-		ex->ee_len = cpu_to_le32(ee_len);
+		ex->ee_len = cpu_to_le16(ee_len);
 		ext4_ext_try_to_merge(inode, path, ex);
 		err = ext4_ext_dirty(handle, inode, path + depth);
 		goto out;
diff -druN linux-libre-3.3.3-gnu/fs/jbd2/commit.c linux-libre-3.3.4-gnu/fs/jbd2/commit.c
--- linux-libre-3.3.3-gnu/fs/jbd2/commit.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/jbd2/commit.c	2012-04-27 13:17:35.000000000 -0400
@@ -689,7 +689,7 @@
 	if (commit_transaction->t_need_data_flush &&
 	    (journal->j_fs_dev != journal->j_dev) &&
 	    (journal->j_flags & JBD2_BARRIER))
-		blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
+		blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL);
 
 	/* Done it all: now write the commit record asynchronously. */
 	if (JBD2_HAS_INCOMPAT_FEATURE(journal,
@@ -825,7 +825,7 @@
 	if (JBD2_HAS_INCOMPAT_FEATURE(journal,
 				      JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) &&
 	    journal->j_flags & JBD2_BARRIER) {
-		blkdev_issue_flush(journal->j_dev, GFP_KERNEL, NULL);
+		blkdev_issue_flush(journal->j_dev, GFP_NOFS, NULL);
 	}
 
 	if (err)
diff -druN linux-libre-3.3.3-gnu/fs/lockd/clnt4xdr.c linux-libre-3.3.4-gnu/fs/lockd/clnt4xdr.c
--- linux-libre-3.3.3-gnu/fs/lockd/clnt4xdr.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/lockd/clnt4xdr.c	2012-04-27 13:17:35.000000000 -0400
@@ -241,7 +241,7 @@
 	p = xdr_inline_decode(xdr, 4);
 	if (unlikely(p == NULL))
 		goto out_overflow;
-	if (unlikely(*p > nlm4_failed))
+	if (unlikely(ntohl(*p) > ntohl(nlm4_failed)))
 		goto out_bad_xdr;
 	*stat = *p;
 	return 0;
diff -druN linux-libre-3.3.3-gnu/fs/lockd/clntxdr.c linux-libre-3.3.4-gnu/fs/lockd/clntxdr.c
--- linux-libre-3.3.3-gnu/fs/lockd/clntxdr.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/lockd/clntxdr.c	2012-04-27 13:17:35.000000000 -0400
@@ -236,7 +236,7 @@
 	p = xdr_inline_decode(xdr, 4);
 	if (unlikely(p == NULL))
 		goto out_overflow;
-	if (unlikely(*p > nlm_lck_denied_grace_period))
+	if (unlikely(ntohl(*p) > ntohl(nlm_lck_denied_grace_period)))
 		goto out_enum;
 	*stat = *p;
 	return 0;
diff -druN linux-libre-3.3.3-gnu/fs/nfsd/nfs3xdr.c linux-libre-3.3.4-gnu/fs/nfsd/nfs3xdr.c
--- linux-libre-3.3.3-gnu/fs/nfsd/nfs3xdr.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/nfsd/nfs3xdr.c	2012-04-27 13:17:35.000000000 -0400
@@ -803,13 +803,13 @@
 	return p;
 }
 
-static int
+static __be32
 compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
 		const char *name, int namlen)
 {
 	struct svc_export	*exp;
 	struct dentry		*dparent, *dchild;
-	int rv = 0;
+	__be32 rv = nfserr_noent;
 
 	dparent = cd->fh.fh_dentry;
 	exp  = cd->fh.fh_export;
@@ -817,26 +817,20 @@
 	if (isdotent(name, namlen)) {
 		if (namlen == 2) {
 			dchild = dget_parent(dparent);
-			if (dchild == dparent) {
-				/* filesystem root - cannot return filehandle for ".." */
-				dput(dchild);
-				return -ENOENT;
-			}
+			/* filesystem root - cannot return filehandle for ".." */
+			if (dchild == dparent)
+				goto out;
 		} else
 			dchild = dget(dparent);
 	} else
 		dchild = lookup_one_len(name, dparent, namlen);
 	if (IS_ERR(dchild))
-		return -ENOENT;
-	rv = -ENOENT;
+		return rv;
 	if (d_mountpoint(dchild))
 		goto out;
-	rv = fh_compose(fhp, exp, dchild, &cd->fh);
-	if (rv)
-		goto out;
 	if (!dchild->d_inode)
 		goto out;
-	rv = 0;
+	rv = fh_compose(fhp, exp, dchild, &cd->fh);
 out:
 	dput(dchild);
 	return rv;
@@ -845,7 +839,7 @@
 static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen)
 {
 	struct svc_fh	fh;
-	int err;
+	__be32 err;
 
 	fh_init(&fh, NFS3_FHSIZE);
 	err = compose_entry_fh(cd, &fh, name, namlen);
diff -druN linux-libre-3.3.3-gnu/fs/nfsd/nfs4proc.c linux-libre-3.3.4-gnu/fs/nfsd/nfs4proc.c
--- linux-libre-3.3.3-gnu/fs/nfsd/nfs4proc.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/nfsd/nfs4proc.c	2012-04-27 13:17:35.000000000 -0400
@@ -826,6 +826,7 @@
 	      struct nfsd4_setattr *setattr)
 {
 	__be32 status = nfs_ok;
+	int err;
 
 	if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
 		nfs4_lock_state();
@@ -837,9 +838,9 @@
 			return status;
 		}
 	}
-	status = fh_want_write(&cstate->current_fh);
-	if (status)
-		return status;
+	err = fh_want_write(&cstate->current_fh);
+	if (err)
+		return nfserrno(err);
 	status = nfs_ok;
 
 	status = check_attr_support(rqstp, cstate, setattr->sa_bmval,
diff -druN linux-libre-3.3.3-gnu/fs/nfsd/nfs4state.c linux-libre-3.3.4-gnu/fs/nfsd/nfs4state.c
--- linux-libre-3.3.3-gnu/fs/nfsd/nfs4state.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/nfsd/nfs4state.c	2012-04-27 13:17:35.000000000 -0400
@@ -4109,16 +4109,14 @@
  * vfs_test_lock.  (Arguably perhaps test_lock should be done with an
  * inode operation.)
  */
-static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
+static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
 {
 	struct file *file;
-	int err;
-
-	err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
-	if (err)
-		return err;
-	err = vfs_test_lock(file, lock);
-	nfsd_close(file);
+	__be32 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
+	if (!err) {
+		err = nfserrno(vfs_test_lock(file, lock));
+		nfsd_close(file);
+	}
 	return err;
 }
 
@@ -4132,7 +4130,6 @@
 	struct inode *inode;
 	struct file_lock file_lock;
 	struct nfs4_lockowner *lo;
-	int error;
 	__be32 status;
 
 	if (locks_in_grace())
@@ -4178,12 +4175,10 @@
 
 	nfs4_transform_lock_offset(&file_lock);
 
-	status = nfs_ok;
-	error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock);
-	if (error) {
-		status = nfserrno(error);
+	status = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock);
+	if (status)
 		goto out;
-	}
+
 	if (file_lock.fl_type != F_UNLCK) {
 		status = nfserr_denied;
 		nfs4_set_lock_denied(&file_lock, &lockt->lt_denied);
diff -druN linux-libre-3.3.3-gnu/fs/nfsd/nfs4xdr.c linux-libre-3.3.4-gnu/fs/nfsd/nfs4xdr.c
--- linux-libre-3.3.3-gnu/fs/nfsd/nfs4xdr.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/nfsd/nfs4xdr.c	2012-04-27 13:17:35.000000000 -0400
@@ -3410,7 +3410,7 @@
 		nfsd4_decode_stateid(argp, &si);
 		valid = nfs4_validate_stateid(cl, &si);
 		RESERVE_SPACE(4);
-		*p++ = htonl(valid);
+		*p++ = valid;
 		resp->p = p;
 	}
 	nfs4_unlock_state();
diff -druN linux-libre-3.3.3-gnu/fs/ocfs2/alloc.c linux-libre-3.3.4-gnu/fs/ocfs2/alloc.c
--- linux-libre-3.3.3-gnu/fs/ocfs2/alloc.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/ocfs2/alloc.c	2012-04-27 13:17:35.000000000 -0400
@@ -1134,7 +1134,7 @@
 	}
 
 	el = path_leaf_el(path);
-	rec = &el->l_recs[le32_to_cpu(el->l_next_free_rec) - 1];
+	rec = &el->l_recs[le16_to_cpu(el->l_next_free_rec) - 1];
 
 	ocfs2_adjust_rightmost_records(handle, et, path, rec);
 
diff -druN linux-libre-3.3.3-gnu/fs/ocfs2/refcounttree.c linux-libre-3.3.4-gnu/fs/ocfs2/refcounttree.c
--- linux-libre-3.3.3-gnu/fs/ocfs2/refcounttree.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/ocfs2/refcounttree.c	2012-04-27 13:17:35.000000000 -0400
@@ -1036,14 +1036,14 @@
 
 	tmp_el = left_path->p_node[subtree_root].el;
 	blkno = left_path->p_node[subtree_root+1].bh->b_blocknr;
-	for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) {
+	for (i = 0; i < le16_to_cpu(tmp_el->l_next_free_rec); i++) {
 		if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) {
 			*cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos);
 			break;
 		}
 	}
 
-	BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec));
+	BUG_ON(i == le16_to_cpu(tmp_el->l_next_free_rec));
 
 out:
 	ocfs2_free_path(left_path);
@@ -1468,7 +1468,7 @@
 
 	trace_ocfs2_divide_leaf_refcount_block(
 		(unsigned long long)ref_leaf_bh->b_blocknr,
-		le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used));
+		le16_to_cpu(rl->rl_count), le16_to_cpu(rl->rl_used));
 
 	/*
 	 * XXX: Improvement later.
@@ -2411,7 +2411,7 @@
 				rb = (struct ocfs2_refcount_block *)
 							prev_bh->b_data;
 
-				if (le64_to_cpu(rb->rf_records.rl_used) +
+				if (le16_to_cpu(rb->rf_records.rl_used) +
 				    recs_add >
 				    le16_to_cpu(rb->rf_records.rl_count))
 					ref_blocks++;
@@ -2476,7 +2476,7 @@
 	if (prev_bh) {
 		rb = (struct ocfs2_refcount_block *)prev_bh->b_data;
 
-		if (le64_to_cpu(rb->rf_records.rl_used) + recs_add >
+		if (le16_to_cpu(rb->rf_records.rl_used) + recs_add >
 		    le16_to_cpu(rb->rf_records.rl_count))
 			ref_blocks++;
 
@@ -3629,7 +3629,7 @@
 			 * one will split a refcount rec, so totally we need
 			 * clusters * 2 new refcount rec.
 			 */
-			if (le64_to_cpu(rb->rf_records.rl_used) + clusters * 2 >
+			if (le16_to_cpu(rb->rf_records.rl_used) + clusters * 2 >
 			    le16_to_cpu(rb->rf_records.rl_count))
 				ref_blocks++;
 
diff -druN linux-libre-3.3.3-gnu/fs/ocfs2/suballoc.c linux-libre-3.3.4-gnu/fs/ocfs2/suballoc.c
--- linux-libre-3.3.3-gnu/fs/ocfs2/suballoc.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/ocfs2/suballoc.c	2012-04-27 13:17:35.000000000 -0400
@@ -600,7 +600,7 @@
 		ret = ocfs2_free_clusters(handle, cluster_ac->ac_inode,
 					  cluster_ac->ac_bh,
 					  le64_to_cpu(rec->e_blkno),
-					  le32_to_cpu(rec->e_leaf_clusters));
+					  le16_to_cpu(rec->e_leaf_clusters));
 		if (ret)
 			mlog_errno(ret);
 		/* Try all the clusters to free */
@@ -1628,7 +1628,7 @@
 {
 	unsigned int bpc = le16_to_cpu(cl->cl_bpc);
 	unsigned int bitoff = le32_to_cpu(rec->e_cpos) * bpc;
-	unsigned int bitcount = le32_to_cpu(rec->e_leaf_clusters) * bpc;
+	unsigned int bitcount = le16_to_cpu(rec->e_leaf_clusters) * bpc;
 
 	if (res->sr_bit_offset < bitoff)
 		return 0;
diff -druN linux-libre-3.3.3-gnu/fs/splice.c linux-libre-3.3.4-gnu/fs/splice.c
--- linux-libre-3.3.3-gnu/fs/splice.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/fs/splice.c	2012-04-27 13:17:35.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/uio.h>
 #include <linux/security.h>
 #include <linux/gfp.h>
+#include <linux/socket.h>
 
 /*
  * Attempt to steal a page from a pipe buffer. This should perhaps go into
@@ -690,7 +691,9 @@
 	if (!likely(file->f_op && file->f_op->sendpage))
 		return -EINVAL;
 
-	more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
+	more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
+	if (sd->len < sd->total_len)
+		more |= MSG_SENDPAGE_NOTLAST;
 	return file->f_op->sendpage(file, buf->page, buf->offset,
 				    sd->len, &pos, more);
 }
diff -druN linux-libre-3.3.3-gnu/include/linux/kvm_host.h linux-libre-3.3.4-gnu/include/linux/kvm_host.h
--- linux-libre-3.3.3-gnu/include/linux/kvm_host.h	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/include/linux/kvm_host.h	2012-04-27 13:17:35.000000000 -0400
@@ -593,6 +593,7 @@
 
 #ifdef CONFIG_IOMMU_API
 int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
+void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
 int kvm_iommu_map_guest(struct kvm *kvm);
 int kvm_iommu_unmap_guest(struct kvm *kvm);
 int kvm_assign_device(struct kvm *kvm,
@@ -606,6 +607,11 @@
 	return 0;
 }
 
+static inline void kvm_iommu_unmap_pages(struct kvm *kvm,
+					 struct kvm_memory_slot *slot)
+{
+}
+
 static inline int kvm_iommu_map_guest(struct kvm *kvm)
 {
 	return -ENODEV;
diff -druN linux-libre-3.3.3-gnu/include/linux/netdevice.h linux-libre-3.3.4-gnu/include/linux/netdevice.h
--- linux-libre-3.3.3-gnu/include/linux/netdevice.h	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/include/linux/netdevice.h	2012-04-27 13:17:35.000000000 -0400
@@ -2582,8 +2582,6 @@
 extern void *dev_seq_start(struct seq_file *seq, loff_t *pos);
 extern void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos);
 extern void dev_seq_stop(struct seq_file *seq, void *v);
-extern int dev_seq_open_ops(struct inode *inode, struct file *file,
-			    const struct seq_operations *ops);
 #endif
 
 extern int netdev_class_create_file(struct class_attribute *class_attr);
diff -druN linux-libre-3.3.3-gnu/include/linux/skbuff.h linux-libre-3.3.4-gnu/include/linux/skbuff.h
--- linux-libre-3.3.3-gnu/include/linux/skbuff.h	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/include/linux/skbuff.h	2012-04-27 13:17:35.000000000 -0400
@@ -468,6 +468,7 @@
 	union {
 		__u32		mark;
 		__u32		dropcount;
+		__u32		avail_size;
 	};
 
 	__u16			vlan_tci;
@@ -1338,6 +1339,18 @@
 }
 
 /**
+ *	skb_availroom - bytes at buffer end
+ *	@skb: buffer to check
+ *
+ *	Return the number of bytes of free space at the tail of an sk_buff
+ *	allocated by sk_stream_alloc()
+ */
+static inline int skb_availroom(const struct sk_buff *skb)
+{
+	return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len;
+}
+
+/**
  *	skb_reserve - adjust headroom
  *	@skb: buffer to alter
  *	@len: bytes to move
diff -druN linux-libre-3.3.3-gnu/include/linux/socket.h linux-libre-3.3.4-gnu/include/linux/socket.h
--- linux-libre-3.3.3-gnu/include/linux/socket.h	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/include/linux/socket.h	2012-04-27 13:17:35.000000000 -0400
@@ -265,7 +265,7 @@
 #define MSG_NOSIGNAL	0x4000	/* Do not generate SIGPIPE */
 #define MSG_MORE	0x8000	/* Sender will send more */
 #define MSG_WAITFORONE	0x10000	/* recvmmsg(): block until 1+ packets avail */
-
+#define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
 #define MSG_EOF         MSG_FIN
 
 #define MSG_CMSG_CLOEXEC 0x40000000	/* Set close_on_exit for file
diff -druN linux-libre-3.3.3-gnu/Makefile linux-libre-3.3.4-gnu/Makefile
--- linux-libre-3.3.3-gnu/Makefile	2012-04-23 11:33:29.000000000 -0400
+++ linux-libre-3.3.4-gnu/Makefile	2012-04-27 14:33:16.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 3
-SUBLEVEL = 3
+SUBLEVEL = 4
 EXTRAVERSION =-gnu
 NAME = Saber-toothed Squirrel
 
diff -druN linux-libre-3.3.3-gnu/mm/memblock.c linux-libre-3.3.4-gnu/mm/memblock.c
--- linux-libre-3.3.3-gnu/mm/memblock.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/mm/memblock.c	2012-04-27 13:17:35.000000000 -0400
@@ -330,6 +330,9 @@
 	phys_addr_t end = base + memblock_cap_size(base, &size);
 	int i, nr_new;
 
+	if (!size)
+		return 0;
+
 	/* special case for empty array */
 	if (type->regions[0].size == 0) {
 		WARN_ON(type->cnt != 1 || type->total_size);
@@ -430,6 +433,9 @@
 
 	*start_rgn = *end_rgn = 0;
 
+	if (!size)
+		return 0;
+
 	/* we'll create at most two more regions */
 	while (type->cnt + 2 > type->max)
 		if (memblock_double_array(type) < 0)
@@ -514,7 +520,6 @@
 		     (unsigned long long)base,
 		     (unsigned long long)base + size,
 		     (void *)_RET_IP_);
-	BUG_ON(0 == size);
 
 	return memblock_add_region(_rgn, base, size, MAX_NUMNODES);
 }
diff -druN linux-libre-3.3.3-gnu/mm/swap_state.c linux-libre-3.3.4-gnu/mm/swap_state.c
--- linux-libre-3.3.3-gnu/mm/swap_state.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/mm/swap_state.c	2012-04-27 13:17:35.000000000 -0400
@@ -26,7 +26,7 @@
  */
 static const struct address_space_operations swap_aops = {
 	.writepage	= swap_writepage,
-	.set_page_dirty	= __set_page_dirty_nobuffers,
+	.set_page_dirty	= __set_page_dirty_no_writeback,
 	.migratepage	= migrate_page,
 };
 
diff -druN linux-libre-3.3.3-gnu/net/ax25/af_ax25.c linux-libre-3.3.4-gnu/net/ax25/af_ax25.c
--- linux-libre-3.3.3-gnu/net/ax25/af_ax25.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/ax25/af_ax25.c	2012-04-27 13:17:35.000000000 -0400
@@ -2012,16 +2012,17 @@
 	proc_net_remove(&init_net, "ax25_route");
 	proc_net_remove(&init_net, "ax25");
 	proc_net_remove(&init_net, "ax25_calls");
-	ax25_rt_free();
-	ax25_uid_free();
-	ax25_dev_free();
 
-	ax25_unregister_sysctl();
 	unregister_netdevice_notifier(&ax25_dev_notifier);
+	ax25_unregister_sysctl();
 
 	dev_remove_pack(&ax25_packet_type);
 
 	sock_unregister(PF_AX25);
 	proto_unregister(&ax25_proto);
+
+	ax25_rt_free();
+	ax25_uid_free();
+	ax25_dev_free();
 }
 module_exit(ax25_exit);
diff -druN linux-libre-3.3.3-gnu/net/bridge/br_multicast.c linux-libre-3.3.4-gnu/net/bridge/br_multicast.c
--- linux-libre-3.3.3-gnu/net/bridge/br_multicast.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/bridge/br_multicast.c	2012-04-27 13:17:35.000000000 -0400
@@ -241,7 +241,6 @@
 	hlist_del_rcu(&mp->hlist[mdb->ver]);
 	mdb->size--;
 
-	del_timer(&mp->query_timer);
 	call_rcu_bh(&mp->rcu, br_multicast_free_group);
 
 out:
@@ -271,7 +270,6 @@
 		rcu_assign_pointer(*pp, p->next);
 		hlist_del_init(&p->mglist);
 		del_timer(&p->timer);
-		del_timer(&p->query_timer);
 		call_rcu_bh(&p->rcu, br_multicast_free_pg);
 
 		if (!mp->ports && !mp->mglist &&
@@ -507,74 +505,6 @@
 	return NULL;
 }
 
-static void br_multicast_send_group_query(struct net_bridge_mdb_entry *mp)
-{
-	struct net_bridge *br = mp->br;
-	struct sk_buff *skb;
-
-	skb = br_multicast_alloc_query(br, &mp->addr);
-	if (!skb)
-		goto timer;
-
-	netif_rx(skb);
-
-timer:
-	if (++mp->queries_sent < br->multicast_last_member_count)
-		mod_timer(&mp->query_timer,
-			  jiffies + br->multicast_last_member_interval);
-}
-
-static void br_multicast_group_query_expired(unsigned long data)
-{
-	struct net_bridge_mdb_entry *mp = (void *)data;
-	struct net_bridge *br = mp->br;
-
-	spin_lock(&br->multicast_lock);
-	if (!netif_running(br->dev) || !mp->mglist ||
-	    mp->queries_sent >= br->multicast_last_member_count)
-		goto out;
-
-	br_multicast_send_group_query(mp);
-
-out:
-	spin_unlock(&br->multicast_lock);
-}
-
-static void br_multicast_send_port_group_query(struct net_bridge_port_group *pg)
-{
-	struct net_bridge_port *port = pg->port;
-	struct net_bridge *br = port->br;
-	struct sk_buff *skb;
-
-	skb = br_multicast_alloc_query(br, &pg->addr);
-	if (!skb)
-		goto timer;
-
-	br_deliver(port, skb);
-
-timer:
-	if (++pg->queries_sent < br->multicast_last_member_count)
-		mod_timer(&pg->query_timer,
-			  jiffies + br->multicast_last_member_interval);
-}
-
-static void br_multicast_port_group_query_expired(unsigned long data)
-{
-	struct net_bridge_port_group *pg = (void *)data;
-	struct net_bridge_port *port = pg->port;
-	struct net_bridge *br = port->br;
-
-	spin_lock(&br->multicast_lock);
-	if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) ||
-	    pg->queries_sent >= br->multicast_last_member_count)
-		goto out;
-
-	br_multicast_send_port_group_query(pg);
-
-out:
-	spin_unlock(&br->multicast_lock);
-}
-
 static struct net_bridge_mdb_entry *br_multicast_get_group(
 	struct net_bridge *br, struct net_bridge_port *port,
 	struct br_ip *group, int hash)
@@ -690,8 +620,6 @@
 	mp->addr = *group;
 	setup_timer(&mp->timer, br_multicast_group_expired,
 		    (unsigned long)mp);
-	setup_timer(&mp->query_timer, br_multicast_group_query_expired,
-		    (unsigned long)mp);
 
 	hlist_add_head_rcu(&mp->hlist[mdb->ver], &mdb->mhash[hash]);
 	mdb->size++;
@@ -746,8 +674,6 @@
 	hlist_add_head(&p->mglist, &port->mglist);
 	setup_timer(&p->timer, br_multicast_port_group_expired,
 		    (unsigned long)p);
-	setup_timer(&p->query_timer, br_multicast_port_group_query_expired,
-		    (unsigned long)p);
 
 	rcu_assign_pointer(*pp, p);
 
@@ -1291,9 +1217,6 @@
 		     time_after(mp->timer.expires, time) :
 		     try_to_del_timer_sync(&mp->timer) >= 0)) {
 			mod_timer(&mp->timer, time);
-
-			mp->queries_sent = 0;
-			mod_timer(&mp->query_timer, now);
 		}
 
 		goto out;
@@ -1310,9 +1233,6 @@
 		     time_after(p->timer.expires, time) :
 		     try_to_del_timer_sync(&p->timer) >= 0)) {
 			mod_timer(&p->timer, time);
-
-			p->queries_sent = 0;
-			mod_timer(&p->query_timer, now);
 		}
 
 		break;
@@ -1681,7 +1601,6 @@
 		hlist_for_each_entry_safe(mp, p, n, &mdb->mhash[i],
 					  hlist[ver]) {
 			del_timer(&mp->timer);
-			del_timer(&mp->query_timer);
 			call_rcu_bh(&mp->rcu, br_multicast_free_group);
 		}
 	}
diff -druN linux-libre-3.3.3-gnu/net/bridge/br_private.h linux-libre-3.3.4-gnu/net/bridge/br_private.h
--- linux-libre-3.3.3-gnu/net/bridge/br_private.h	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/bridge/br_private.h	2012-04-27 13:17:35.000000000 -0400
@@ -82,9 +82,7 @@
 	struct hlist_node		mglist;
 	struct rcu_head			rcu;
 	struct timer_list		timer;
-	struct timer_list		query_timer;
 	struct br_ip			addr;
-	u32				queries_sent;
 };
 
 struct net_bridge_mdb_entry
@@ -94,10 +92,8 @@
 	struct net_bridge_port_group __rcu *ports;
 	struct rcu_head			rcu;
 	struct timer_list		timer;
-	struct timer_list		query_timer;
 	struct br_ip			addr;
 	bool				mglist;
-	u32				queries_sent;
 };
 
 struct net_bridge_mdb_htable
diff -druN linux-libre-3.3.3-gnu/net/core/dev_addr_lists.c linux-libre-3.3.4-gnu/net/core/dev_addr_lists.c
--- linux-libre-3.3.3-gnu/net/core/dev_addr_lists.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/core/dev_addr_lists.c	2012-04-27 13:17:35.000000000 -0400
@@ -696,7 +696,8 @@
 
 static int dev_mc_seq_open(struct inode *inode, struct file *file)
 {
-	return dev_seq_open_ops(inode, file, &dev_mc_seq_ops);
+	return seq_open_net(inode, file, &dev_mc_seq_ops,
+			    sizeof(struct seq_net_private));
 }
 
 static const struct file_operations dev_mc_seq_fops = {
diff -druN linux-libre-3.3.3-gnu/net/core/dev.c linux-libre-3.3.4-gnu/net/core/dev.c
--- linux-libre-3.3.3-gnu/net/core/dev.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/core/dev.c	2012-04-27 13:17:35.000000000 -0400
@@ -4037,54 +4037,41 @@
 
 #ifdef CONFIG_PROC_FS
 
-#define BUCKET_SPACE (32 - NETDEV_HASHBITS)
-
-struct dev_iter_state {
-	struct seq_net_private p;
-	unsigned int pos; /* bucket << BUCKET_SPACE + offset */
-};
+#define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1)
 
 #define get_bucket(x) ((x) >> BUCKET_SPACE)
 #define get_offset(x) ((x) & ((1 << BUCKET_SPACE) - 1))
 #define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
 
-static inline struct net_device *dev_from_same_bucket(struct seq_file *seq)
+static inline struct net_device *dev_from_same_bucket(struct seq_file *seq, loff_t *pos)
 {
-	struct dev_iter_state *state = seq->private;
 	struct net *net = seq_file_net(seq);
 	struct net_device *dev;
 	struct hlist_node *p;
 	struct hlist_head *h;
-	unsigned int count, bucket, offset;
+	unsigned int count = 0, offset = get_offset(*pos);
 
-	bucket = get_bucket(state->pos);
-	offset = get_offset(state->pos);
-	h = &net->dev_name_head[bucket];
-	count = 0;
+	h = &net->dev_name_head[get_bucket(*pos)];
 	hlist_for_each_entry_rcu(dev, p, h, name_hlist) {
-		if (count++ == offset) {
-			state->pos = set_bucket_offset(bucket, count);
+		if (++count == offset)
 			return dev;
-		}
 	}
 
 	return NULL;
 }
 
-static inline struct net_device *dev_from_new_bucket(struct seq_file *seq)
+static inline struct net_device *dev_from_bucket(struct seq_file *seq, loff_t *pos)
 {
-	struct dev_iter_state *state = seq->private;
 	struct net_device *dev;
 	unsigned int bucket;
 
-	bucket = get_bucket(state->pos);
 	do {
-		dev = dev_from_same_bucket(seq);
+		dev = dev_from_same_bucket(seq, pos);
 		if (dev)
 			return dev;
 
-		bucket++;
-		state->pos = set_bucket_offset(bucket, 0);
+		bucket = get_bucket(*pos) + 1;
+		*pos = set_bucket_offset(bucket, 1);
 	} while (bucket < NETDEV_HASHENTRIES);
 
 	return NULL;
@@ -4097,33 +4084,20 @@
 void *dev_seq_start(struct seq_file *seq, loff_t *pos)
 	__acquires(RCU)
 {
-	struct dev_iter_state *state = seq->private;
-
 	rcu_read_lock();
 	if (!*pos)
 		return SEQ_START_TOKEN;
 
-	/* check for end of the hash */
-	if (state->pos == 0 && *pos > 1)
+	if (get_bucket(*pos) >= NETDEV_HASHENTRIES)
 		return NULL;
 
-	return dev_from_new_bucket(seq);
+	return dev_from_bucket(seq, pos);
 }
 
 void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	struct net_device *dev;
-
 	++*pos;
-
-	if (v == SEQ_START_TOKEN)
-		return dev_from_new_bucket(seq);
-
-	dev = dev_from_same_bucket(seq);
-	if (dev)
-		return dev;
-
-	return dev_from_new_bucket(seq);
+	return dev_from_bucket(seq, pos);
 }
 
 void dev_seq_stop(struct seq_file *seq, void *v)
@@ -4222,13 +4196,7 @@
 static int dev_seq_open(struct inode *inode, struct file *file)
 {
 	return seq_open_net(inode, file, &dev_seq_ops,
-			    sizeof(struct dev_iter_state));
-}
-
-int dev_seq_open_ops(struct inode *inode, struct file *file,
-		     const struct seq_operations *ops)
-{
-	return seq_open_net(inode, file, ops, sizeof(struct dev_iter_state));
+			    sizeof(struct seq_net_private));
 }
 
 static const struct file_operations dev_seq_fops = {
diff -druN linux-libre-3.3.3-gnu/net/core/net_namespace.c linux-libre-3.3.4-gnu/net/core/net_namespace.c
--- linux-libre-3.3.3-gnu/net/core/net_namespace.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/core/net_namespace.c	2012-04-27 13:17:35.000000000 -0400
@@ -83,21 +83,29 @@
 
 static int ops_init(const struct pernet_operations *ops, struct net *net)
 {
-	int err;
+	int err = -ENOMEM;
+	void *data = NULL;
+
 	if (ops->id && ops->size) {
-		void *data = kzalloc(ops->size, GFP_KERNEL);
+		data = kzalloc(ops->size, GFP_KERNEL);
 		if (!data)
-			return -ENOMEM;
+			goto out;
 
 		err = net_assign_generic(net, *ops->id, data);
-		if (err) {
-			kfree(data);
-			return err;
-		}
+		if (err)
+			goto cleanup;
 	}
+	err = 0;
 	if (ops->init)
-		return ops->init(net);
-	return 0;
+		err = ops->init(net);
+	if (!err)
+		return 0;
+
+cleanup:
+	kfree(data);
+
+out:
+	return err;
 }
 
 static void ops_free(const struct pernet_operations *ops, struct net *net)
@@ -448,12 +456,7 @@
 static int __register_pernet_operations(struct list_head *list,
 					struct pernet_operations *ops)
 {
-	int err = 0;
-	err = ops_init(ops, &init_net);
-	if (err)
-		ops_free(ops, &init_net);
-	return err;
-	
+	return ops_init(ops, &init_net);
 }
 
 static void __unregister_pernet_operations(struct pernet_operations *ops)
diff -druN linux-libre-3.3.3-gnu/net/core/skbuff.c linux-libre-3.3.4-gnu/net/core/skbuff.c
--- linux-libre-3.3.3-gnu/net/core/skbuff.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/core/skbuff.c	2012-04-27 13:17:35.000000000 -0400
@@ -952,9 +952,11 @@
 		goto adjust_others;
 	}
 
-	data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
+	data = kmalloc(size + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)),
+		       gfp_mask);
 	if (!data)
 		goto nodata;
+	size = SKB_WITH_OVERHEAD(ksize(data));
 
 	/* Copy only real data... and, alas, header. This should be
 	 * optimized for the cases when header is void.
@@ -3160,6 +3162,8 @@
  */
 int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
 {
+	int len = skb->len;
+
 	if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
 	    (unsigned)sk->sk_rcvbuf)
 		return -ENOMEM;
@@ -3174,7 +3178,7 @@
 
 	skb_queue_tail(&sk->sk_error_queue, skb);
 	if (!sock_flag(sk, SOCK_DEAD))
-		sk->sk_data_ready(sk, skb->len);
+		sk->sk_data_ready(sk, len);
 	return 0;
 }
 EXPORT_SYMBOL(sock_queue_err_skb);
diff -druN linux-libre-3.3.3-gnu/net/ipv4/tcp.c linux-libre-3.3.4-gnu/net/ipv4/tcp.c
--- linux-libre-3.3.3-gnu/net/ipv4/tcp.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/ipv4/tcp.c	2012-04-27 13:17:35.000000000 -0400
@@ -699,11 +699,12 @@
 	skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
 	if (skb) {
 		if (sk_wmem_schedule(sk, skb->truesize)) {
+			skb_reserve(skb, sk->sk_prot->max_header);
 			/*
 			 * Make sure that we have exactly size bytes
 			 * available to the caller, no more, no less.
 			 */
-			skb_reserve(skb, skb_tailroom(skb) - size);
+			skb->avail_size = size;
 			return skb;
 		}
 		__kfree_skb(skb);
@@ -858,7 +859,7 @@
 	}
 
 out:
-	if (copied)
+	if (copied && !(flags & MSG_SENDPAGE_NOTLAST))
 		tcp_push(sk, flags, mss_now, tp->nonagle);
 	return copied;
 
@@ -993,10 +994,9 @@
 				copy = seglen;
 
 			/* Where to copy to? */
-			if (skb_tailroom(skb) > 0) {
+			if (skb_availroom(skb) > 0) {
 				/* We have some space in skb head. Superb! */
-				if (copy > skb_tailroom(skb))
-					copy = skb_tailroom(skb);
+				copy = min_t(int, copy, skb_availroom(skb));
 				err = skb_add_data_nocache(sk, skb, from, copy);
 				if (err)
 					goto do_fault;
@@ -3299,8 +3299,7 @@
 
 	tcp_init_mem(&init_net);
 	/* Set per-socket limits to no more than 1/128 the pressure threshold */
-	limit = nr_free_buffer_pages() << (PAGE_SHIFT - 10);
-	limit = max(limit, 128UL);
+	limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7);
 	max_share = min(4UL*1024*1024, limit);
 
 	sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;
diff -druN linux-libre-3.3.3-gnu/net/ipv4/tcp_input.c linux-libre-3.3.4-gnu/net/ipv4/tcp_input.c
--- linux-libre-3.3.3-gnu/net/ipv4/tcp_input.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/ipv4/tcp_input.c	2012-04-27 13:17:35.000000000 -0400
@@ -333,6 +333,7 @@
 			incr = __tcp_grow_window(sk, skb);
 
 		if (incr) {
+			incr = max_t(int, incr, 2 * skb->len);
 			tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr,
 					       tp->window_clamp);
 			inet_csk(sk)->icsk_ack.quick |= 1;
@@ -472,8 +473,11 @@
 		if (!win_dep) {
 			m -= (new_sample >> 3);
 			new_sample += m;
-		} else if (m < new_sample)
-			new_sample = m << 3;
+		} else {
+			m <<= 3;
+			if (m < new_sample)
+				new_sample = m;
+		}
 	} else {
 		/* No previous measure. */
 		new_sample = m << 3;
diff -druN linux-libre-3.3.3-gnu/net/ipv4/tcp_output.c linux-libre-3.3.4-gnu/net/ipv4/tcp_output.c
--- linux-libre-3.3.3-gnu/net/ipv4/tcp_output.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/ipv4/tcp_output.c	2012-04-27 13:17:35.000000000 -0400
@@ -1096,6 +1096,7 @@
 	eat = min_t(int, len, skb_headlen(skb));
 	if (eat) {
 		__skb_pull(skb, eat);
+		skb->avail_size -= eat;
 		len -= eat;
 		if (!len)
 			return;
@@ -2060,7 +2061,7 @@
 		/* Punt if not enough space exists in the first SKB for
 		 * the data in the second
 		 */
-		if (skb->len > skb_tailroom(to))
+		if (skb->len > skb_availroom(to))
 			break;
 
 		if (after(TCP_SKB_CB(skb)->end_seq, tcp_wnd_end(tp)))
diff -druN linux-libre-3.3.3-gnu/net/ipv6/mcast.c linux-libre-3.3.4-gnu/net/ipv6/mcast.c
--- linux-libre-3.3.3-gnu/net/ipv6/mcast.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/ipv6/mcast.c	2012-04-27 13:17:35.000000000 -0400
@@ -2044,7 +2044,7 @@
 		if (!delta)
 			pmc->mca_sfcount[sfmode]--;
 		for (j=0; j<i; j++)
-			(void) ip6_mc_del1_src(pmc, sfmode, &psfsrc[i]);
+			ip6_mc_del1_src(pmc, sfmode, &psfsrc[j]);
 	} else if (isexclude != (pmc->mca_sfcount[MCAST_EXCLUDE] != 0)) {
 		struct ip6_sf_list *psf;
 
diff -druN linux-libre-3.3.3-gnu/net/ipv6/tcp_ipv6.c linux-libre-3.3.4-gnu/net/ipv6/tcp_ipv6.c
--- linux-libre-3.3.3-gnu/net/ipv6/tcp_ipv6.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/ipv6/tcp_ipv6.c	2012-04-27 13:17:35.000000000 -0400
@@ -1493,6 +1493,10 @@
 	tcp_mtup_init(newsk);
 	tcp_sync_mss(newsk, dst_mtu(dst));
 	newtp->advmss = dst_metric_advmss(dst);
+	if (tcp_sk(sk)->rx_opt.user_mss &&
+	    tcp_sk(sk)->rx_opt.user_mss < newtp->advmss)
+		newtp->advmss = tcp_sk(sk)->rx_opt.user_mss;
+
 	tcp_initialize_rcv_mss(newsk);
 	if (tcp_rsk(req)->snt_synack)
 		tcp_valid_rtt_meas(newsk,
diff -druN linux-libre-3.3.3-gnu/net/mac80211/ibss.c linux-libre-3.3.4-gnu/net/mac80211/ibss.c
--- linux-libre-3.3.3-gnu/net/mac80211/ibss.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/mac80211/ibss.c	2012-04-27 13:17:35.000000000 -0400
@@ -435,8 +435,8 @@
 			 * fall back to HT20 if we don't use or use
 			 * the other extension channel
 			 */
-			if ((channel_type == NL80211_CHAN_HT40MINUS ||
-			     channel_type == NL80211_CHAN_HT40PLUS) &&
+			if (!(channel_type == NL80211_CHAN_HT40MINUS ||
+			      channel_type == NL80211_CHAN_HT40PLUS) ||
 			    channel_type != sdata->u.ibss.channel_type)
 				sta_ht_cap_new.cap &=
 					~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
diff -druN linux-libre-3.3.3-gnu/net/netlink/af_netlink.c linux-libre-3.3.4-gnu/net/netlink/af_netlink.c
--- linux-libre-3.3.3-gnu/net/netlink/af_netlink.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/netlink/af_netlink.c	2012-04-27 13:17:35.000000000 -0400
@@ -829,12 +829,19 @@
 	return 0;
 }
 
-int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
+static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
 {
 	int len = skb->len;
 
 	skb_queue_tail(&sk->sk_receive_queue, skb);
 	sk->sk_data_ready(sk, len);
+	return len;
+}
+
+int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
+{
+	int len = __netlink_sendskb(sk, skb);
+
 	sock_put(sk);
 	return len;
 }
@@ -957,8 +964,7 @@
 	if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
 	    !test_bit(0, &nlk->state)) {
 		skb_set_owner_r(skb, sk);
-		skb_queue_tail(&sk->sk_receive_queue, skb);
-		sk->sk_data_ready(sk, skb->len);
+		__netlink_sendskb(sk, skb);
 		return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1);
 	}
 	return -1;
@@ -1680,10 +1686,8 @@
 
 		if (sk_filter(sk, skb))
 			kfree_skb(skb);
-		else {
-			skb_queue_tail(&sk->sk_receive_queue, skb);
-			sk->sk_data_ready(sk, skb->len);
-		}
+		else
+			__netlink_sendskb(sk, skb);
 		return 0;
 	}
 
@@ -1697,10 +1701,8 @@
 
 	if (sk_filter(sk, skb))
 		kfree_skb(skb);
-	else {
-		skb_queue_tail(&sk->sk_receive_queue, skb);
-		sk->sk_data_ready(sk, skb->len);
-	}
+	else
+		__netlink_sendskb(sk, skb);
 
 	if (cb->done)
 		cb->done(cb);
diff -druN linux-libre-3.3.3-gnu/net/phonet/pep.c linux-libre-3.3.4-gnu/net/phonet/pep.c
--- linux-libre-3.3.3-gnu/net/phonet/pep.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/phonet/pep.c	2012-04-27 13:17:35.000000000 -0400
@@ -1130,6 +1130,9 @@
 	int flags = msg->msg_flags;
 	int err, done;
 
+	if (len > USHRT_MAX)
+		return -EMSGSIZE;
+
 	if ((msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|
 				MSG_CMSG_COMPAT)) ||
 			!(msg->msg_flags & MSG_EOR))
diff -druN linux-libre-3.3.3-gnu/net/sched/sch_gred.c linux-libre-3.3.4-gnu/net/sched/sch_gred.c
--- linux-libre-3.3.3-gnu/net/sched/sch_gred.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/sched/sch_gred.c	2012-04-27 13:17:35.000000000 -0400
@@ -565,11 +565,8 @@
 		opt.packets	= q->packetsin;
 		opt.bytesin	= q->bytesin;
 
-		if (gred_wred_mode(table)) {
-			q->vars.qidlestart =
-				table->tab[table->def]->vars.qidlestart;
-			q->vars.qavg = table->tab[table->def]->vars.qavg;
-		}
+		if (gred_wred_mode(table))
+			gred_load_wred_set(table, q);
 
 		opt.qave = red_calc_qavg(&q->parms, &q->vars, q->vars.qavg);
 
diff -druN linux-libre-3.3.3-gnu/net/sctp/socket.c linux-libre-3.3.4-gnu/net/sctp/socket.c
--- linux-libre-3.3.3-gnu/net/sctp/socket.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/sctp/socket.c	2012-04-27 13:17:35.000000000 -0400
@@ -4133,9 +4133,10 @@
 static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval,
 				  int __user *optlen)
 {
-	if (len < sizeof(struct sctp_event_subscribe))
+	if (len <= 0)
 		return -EINVAL;
-	len = sizeof(struct sctp_event_subscribe);
+	if (len > sizeof(struct sctp_event_subscribe))
+		len = sizeof(struct sctp_event_subscribe);
 	if (put_user(len, optlen))
 		return -EFAULT;
 	if (copy_to_user(optval, &sctp_sk(sk)->subscribe, len))
diff -druN linux-libre-3.3.3-gnu/net/socket.c linux-libre-3.3.4-gnu/net/socket.c
--- linux-libre-3.3.3-gnu/net/socket.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/socket.c	2012-04-27 13:17:35.000000000 -0400
@@ -811,9 +811,9 @@
 
 	sock = file->private_data;
 
-	flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
-	if (more)
-		flags |= MSG_MORE;
+	flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
+	/* more is a combination of MSG_MORE and MSG_SENDPAGE_NOTLAST */
+	flags |= more;
 
 	return kernel_sendpage(sock, page, offset, size, flags);
 }
diff -druN linux-libre-3.3.3-gnu/net/wireless/util.c linux-libre-3.3.4-gnu/net/wireless/util.c
--- linux-libre-3.3.3-gnu/net/wireless/util.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/net/wireless/util.c	2012-04-27 13:17:35.000000000 -0400
@@ -988,7 +988,7 @@
 			if (rdev->wiphy.software_iftypes & BIT(iftype))
 				continue;
 			for (j = 0; j < c->n_limits; j++) {
-				if (!(limits[j].types & iftype))
+				if (!(limits[j].types & BIT(iftype)))
 					continue;
 				if (limits[j].max < num[iftype])
 					goto cont;
diff -druN linux-libre-3.3.3-gnu/scripts/mod/file2alias.c linux-libre-3.3.4-gnu/scripts/mod/file2alias.c
--- linux-libre-3.3.3-gnu/scripts/mod/file2alias.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/scripts/mod/file2alias.c	2012-04-27 13:17:35.000000000 -0400
@@ -1075,6 +1075,10 @@
 	if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
 		return;
 
+	/* We're looking for an object */
+	if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
+		return;
+
 	/* All our symbols are of form <prefix>__mod_XXX_device_table. */
 	name = strstr(symname, "__mod_");
 	if (!name)
diff -druN linux-libre-3.3.3-gnu/sound/pci/hda/patch_conexant.c linux-libre-3.3.4-gnu/sound/pci/hda/patch_conexant.c
--- linux-libre-3.3.3-gnu/sound/pci/hda/patch_conexant.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/sound/pci/hda/patch_conexant.c	2012-04-27 13:17:35.000000000 -0400
@@ -3951,9 +3951,14 @@
 	int i;
 
 	mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids);
-	for (i = 0; i < cfg->hp_outs; i++)
+	for (i = 0; i < cfg->hp_outs; i++) {
+		unsigned int val = PIN_OUT;
+		if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) &
+		    AC_PINCAP_HP_DRV)
+			val |= AC_PINCTL_HP_EN;
 		snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
-				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
+				    AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+	}
 	mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
 	mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
 	mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins);
@@ -4362,8 +4367,10 @@
 
 enum {
 	CXT_PINCFG_LENOVO_X200,
+	CXT_PINCFG_LENOVO_TP410,
 };
 
+/* ThinkPad X200 & co with cxt5051 */
 static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
 	{ 0x16, 0x042140ff }, /* HP (seq# overridden) */
 	{ 0x17, 0x21a11000 }, /* dock-mic */
@@ -4371,15 +4378,33 @@
 	{}
 };
 
+/* ThinkPad 410/420/510/520, X201 & co with cxt5066 */
+static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = {
+	{ 0x19, 0x042110ff }, /* HP (seq# overridden) */
+	{ 0x1a, 0x21a190f0 }, /* dock-mic */
+	{ 0x1c, 0x212140ff }, /* dock-HP */
+	{}
+};
+
 static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
 	[CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
+	[CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410,
 };
 
-static const struct snd_pci_quirk cxt_fixups[] = {
+static const struct snd_pci_quirk cxt5051_fixups[] = {
 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
 	{}
 };
 
+static const struct snd_pci_quirk cxt5066_fixups[] = {
+	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
+	SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
+	SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
+	SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
+	SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
+	{}
+};
+
 /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
  * can be created (bko#42825)
  */
@@ -4416,11 +4441,13 @@
 		break;
 	case 0x14f15051:
 		add_cx5051_fake_mutes(codec);
+		apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl);
+		break;
+	default:
+		apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl);
 		break;
 	}
 
-	apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
-
 	err = cx_auto_search_adcs(codec);
 	if (err < 0)
 		return err;
diff -druN linux-libre-3.3.3-gnu/tools/perf/util/hist.c linux-libre-3.3.4-gnu/tools/perf/util/hist.c
--- linux-libre-3.3.3-gnu/tools/perf/util/hist.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/tools/perf/util/hist.c	2012-04-27 13:17:35.000000000 -0400
@@ -237,8 +237,8 @@
 			 * mis-adjust symbol addresses when computing
 			 * the history counter to increment.
 			 */
-			if (he->ms.map != entry->ms.map) {
-				he->ms.map = entry->ms.map;
+			if (he->ms.map != entry.ms.map) {
+				he->ms.map = entry.ms.map;
 				if (he->ms.map)
 					he->ms.map->referenced = true;
 			}
diff -druN linux-libre-3.3.3-gnu/virt/kvm/iommu.c linux-libre-3.3.4-gnu/virt/kvm/iommu.c
--- linux-libre-3.3.3-gnu/virt/kvm/iommu.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/virt/kvm/iommu.c	2012-04-27 13:17:35.000000000 -0400
@@ -310,6 +310,11 @@
 	}
 }
 
+void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
+{
+	kvm_iommu_put_pages(kvm, slot->base_gfn, slot->npages);
+}
+
 static int kvm_iommu_unmap_memslots(struct kvm *kvm)
 {
 	int idx;
@@ -320,7 +325,7 @@
 	slots = kvm_memslots(kvm);
 
 	kvm_for_each_memslot(memslot, slots)
-		kvm_iommu_put_pages(kvm, memslot->base_gfn, memslot->npages);
+		kvm_iommu_unmap_pages(kvm, memslot);
 
 	srcu_read_unlock(&kvm->srcu, idx);
 
diff -druN linux-libre-3.3.3-gnu/virt/kvm/kvm_main.c linux-libre-3.3.4-gnu/virt/kvm/kvm_main.c
--- linux-libre-3.3.3-gnu/virt/kvm/kvm_main.c	2012-04-22 18:39:43.000000000 -0400
+++ linux-libre-3.3.4-gnu/virt/kvm/kvm_main.c	2012-04-27 13:17:35.000000000 -0400
@@ -873,12 +873,13 @@
 	if (r)
 		goto out_free;
 
-	/* map the pages in iommu page table */
+	/* map/unmap the pages in iommu page table */
 	if (npages) {
 		r = kvm_iommu_map_pages(kvm, &new);
 		if (r)
 			goto out_free;
-	}
+	} else
+		kvm_iommu_unmap_pages(kvm, &old);
 
 	r = -ENOMEM;
 	slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots),
