diff options
author | Jesse Gilles <jgilles@multitech.com> | 2013-04-18 08:47:01 -0500 |
---|---|---|
committer | Jesse Gilles <jgilles@multitech.com> | 2013-04-18 08:47:01 -0500 |
commit | 3dfe52165099ece47657bd595c431c4888bfb60a (patch) | |
tree | 768ffab45c674cb5d1446162b16d9a14c6eb633e | |
parent | f547c4161d0e058326b2341519029fbebc739dce (diff) |
linux: add 2.6.39-at91 recipe using Atmel github branch
21 files changed, 18819 insertions, 0 deletions
diff --git a/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.32.3-at25.patch b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.32.3-at25.patch new file mode 100644 index 0000000..3aa9096 --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.32.3-at25.patch @@ -0,0 +1,37 @@ +diff -uprN -X linux-2.6.32.3/Documentation/dontdiff linux-2.6.32.3-vanilla/drivers/misc/eeprom/at25.c linux-2.6.32.3/drivers/misc/eeprom/at25.c +--- linux-2.6.32.3-vanilla/drivers/misc/eeprom/at25.c 2010-01-06 17:07:45.000000000 -0600 ++++ linux-2.6.32.3/drivers/misc/eeprom/at25.c 2010-10-27 11:05:36.000000000 -0500 +@@ -147,6 +147,7 @@ at25_ee_write(struct at25_data *at25, co + unsigned written = 0; + unsigned buf_size; + u8 *bounce; ++ int a8; + + if (unlikely(off >= at25->bin.size)) + return -EFBIG; +@@ -163,6 +164,11 @@ at25_ee_write(struct at25_data *at25, co + if (!bounce) + return -ENOMEM; + ++ if (!strcmp(at25->chip.name, "at25040b")) ++ a8 = 1; ++ else ++ a8 = 0; ++ + /* For write, rollover is within the page ... so we write at + * most one page, then manually roll over to the next page. + */ +@@ -183,6 +189,13 @@ at25_ee_write(struct at25_data *at25, co + break; + } + ++ if (a8) { ++ if (offset & BIT(8)) ++ bounce[0] |= BIT(3); ++ else ++ bounce[0] &= ~BIT(3); ++ } ++ + /* 8/16/24-bit address is written MSB first */ + switch (at25->addrlen) { + default: /* case 3 */ diff --git a/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.32.3-atmel_spi.patch b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.32.3-atmel_spi.patch new file mode 100644 index 0000000..a7b87b3 --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.32.3-atmel_spi.patch @@ -0,0 +1,12 @@ +diff -uprN -X linux-2.6.32.3/Documentation/dontdiff linux-2.6.32.3-vanilla/drivers/spi/atmel_spi.c linux-2.6.32.3/drivers/spi/atmel_spi.c +--- linux-2.6.32.3-vanilla/drivers/spi/atmel_spi.c 2010-01-06 17:07:45.000000000 -0600 ++++ linux-2.6.32.3/drivers/spi/atmel_spi.c 2010-09-08 13:38:52.000000000 -0500 +@@ -768,7 +768,7 @@ static int __init atmel_spi_probe(struct + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + + master->bus_num = pdev->id; +- master->num_chipselect = 4; ++ master->num_chipselect = 7; + master->setup = atmel_spi_setup; + master->transfer = atmel_spi_transfer; + master->cleanup = atmel_spi_cleanup; diff --git a/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.32.3-option-telit.patch b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.32.3-option-telit.patch new file mode 100644 index 0000000..db0283d --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.32.3-option-telit.patch @@ -0,0 +1,23 @@ +diff linux-2.6.32.3.orig/drivers/usb/serial/option.c linux-2.6.32.3/drivers/usb/serial/option.c +--- linux-2.6.32.3.orig/drivers/usb/serial/option.c ++++ linux-2.6.32.3/drivers/usb/serial/option.c +@@ -293,6 +293,9 @@ static int option_resume(struct usb_serial *serial); + #define TELIT_VENDOR_ID 0x1bc7 + #define TELIT_PRODUCT_UC864E 0x1003 + #define TELIT_PRODUCT_UC864G 0x1004 ++#define TELIT_PRODUCT_CC864_DUAL 0x1005 ++#define TELIT_PRODUCT_CC864_SINGLE 0x1006 ++#define TELIT_PRODUCT_DE910_DUAL 0x1010 + + /* ZTE PRODUCTS */ + #define ZTE_VENDOR_ID 0x19d2 +@@ -523,6 +526,9 @@ static struct usb_device_id option_ids[] = { + { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, diff --git a/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.35.14-at91-gpio-pullup.patch b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.35.14-at91-gpio-pullup.patch new file mode 100644 index 0000000..d967838 --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.35.14-at91-gpio-pullup.patch @@ -0,0 +1,43 @@ +Index: linux-2.6.35/arch/arm/mach-at91/gpio.c +=================================================================== +--- linux-2.6.35.orig/arch/arm/mach-at91/gpio.c 2011-09-27 14:36:06.587267689 -0500 ++++ linux-2.6.35/arch/arm/mach-at91/gpio.c 2011-09-27 14:42:50.997576753 -0500 +@@ -202,6 +202,26 @@ + } + EXPORT_SYMBOL(at91_set_gpio_output); + ++/* ++ * configure pin for output and enable/disable pullup ++ */ ++int __init_or_module at91_set_gpio_output_with_pullup(unsigned pin, int value, int use_pullup) ++{ ++ void __iomem *pio = pin_to_controller(pin); ++ unsigned mask = pin_to_mask(pin); ++ ++ if (!pio) ++ return -EINVAL; ++ ++ __raw_writel(mask, pio + PIO_IDR); ++ __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); ++ __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); ++ __raw_writel(mask, pio + PIO_OER); ++ __raw_writel(mask, pio + PIO_PER); ++ return 0; ++} ++EXPORT_SYMBOL(at91_set_gpio_output_with_pullup); ++ + + /* + * enable/disable the glitch filter; mostly used with IRQ handling. +Index: linux-2.6.35/arch/arm/mach-at91/include/mach/gpio.h +=================================================================== +--- linux-2.6.35.orig/arch/arm/mach-at91/include/mach/gpio.h ++++ linux-2.6.35/arch/arm/mach-at91/include/mach/gpio.h +@@ -194,6 +194,7 @@ extern int __init_or_module at91_set_A_p + extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup); + extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup); + extern int __init_or_module at91_set_gpio_output(unsigned pin, int value); ++extern int __init_or_module at91_set_gpio_output_with_pullup(unsigned pin, int value, int use_pullup); + extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on); + extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on); + diff --git a/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.35.14-option-zte.patch b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.35.14-option-zte.patch new file mode 100644 index 0000000..776c7ee --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.35.14-option-zte.patch @@ -0,0 +1,12 @@ +Index: linux-2.6.35/drivers/usb/serial/option.c +=================================================================== +--- linux-2.6.35.orig/drivers/usb/serial/option.c ++++ linux-2.6.35/drivers/usb/serial/option.c +@@ -889,6 +889,7 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe8, 0xff, 0xff, 0xff) }, // MC2718 + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, diff --git a/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.38-sierra-1.7.40.patch b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.38-sierra-1.7.40.patch new file mode 100644 index 0000000..6e55adf --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.38-sierra-1.7.40.patch @@ -0,0 +1,1556 @@ +Index: linux-2.6.39.4/drivers/net/usb/sierra_net.c +=================================================================== +--- linux-2.6.39.4.orig/drivers/net/usb/sierra_net.c 2012-02-27 15:37:27.810465204 -0600 ++++ linux-2.6.39.4/drivers/net/usb/sierra_net.c 2011-09-22 17:05:46.000000000 -0500 +@@ -1,7 +1,7 @@ + /* + * USB-to-WWAN Driver for Sierra Wireless modems + * +- * Copyright (C) 2008, 2009, 2010 Paxton Smith, Matthew Safar, Rory Filer ++ * Copyright (C) 2008 - 2011 Paxton Smith, Matthew Safar, Rory Filer + * <linux@sierrawireless.com> + * + * Portions of this based on the cdc_ether driver by David Brownell (2003-2005) +@@ -25,13 +25,17 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +-#define DRIVER_VERSION "v.2.0" ++#define DRIVER_VERSION "v.3.2" + #define DRIVER_AUTHOR "Paxton Smith, Matthew Safar, Rory Filer" + #define DRIVER_DESC "USB-to-WWAN Driver for Sierra Wireless modems" + static const char driver_name[] = "sierra_net"; + + /* if defined debug messages enabled */ + /*#define DEBUG*/ ++/* more debug messages */ ++/*#define VERBOSE*/ ++/* Uncomment to force power level set to auto when attaching a device */ ++/*#define POWER_LEVEL_AUTO*/ + + #include <linux/module.h> + #include <linux/etherdevice.h> +@@ -48,6 +52,7 @@ + + #define SWI_USB_REQUEST_GET_FW_ATTR 0x06 + #define SWI_GET_FW_ATTR_MASK 0x08 ++#define SWI_GET_FW_ATTR_APM 0x2 + + /* atomic counter partially included in MAC address to make sure 2 devices + * do not end up with the same MAC - concept breaks in case of > 255 ifaces +@@ -68,6 +73,11 @@ + */ + #define SIERRA_NET_USBCTL_BUF_LEN 1024 + ++/* The SIERRA_NET_RX_URB_SZ defines the receive urb size ++ * for optimal throughput. ++ */ ++#define SIERRA_NET_RX_URB_SZ 1540 ++ + /* list of interface numbers - used for constructing interface lists */ + struct sierra_net_iface_info { + const u32 infolen; /* number of interface numbers on list */ +@@ -139,6 +149,7 @@ + #define SIERRA_NET_SESSION_IDLE 0x00 + /* LSI Link types */ + #define SIERRA_NET_AS_LINK_TYPE_IPv4 0x00 ++#define SIERRA_NET_AS_LINK_TYPE_IPv6 0x02 + + struct lsi_umts { + u8 protocol; +@@ -200,10 +211,11 @@ + dev->data[0] = (unsigned long)priv; + } + +-/* is packet IPv4 */ ++/* is packet IP */ + static inline int is_ip(struct sk_buff *skb) + { +- return skb->protocol == cpu_to_be16(ETH_P_IP); ++ return ((skb->protocol == cpu_to_be16(ETH_P_IP)) || ++ (skb->protocol == cpu_to_be16(ETH_P_IPV6))); + } + + /* +@@ -312,6 +324,24 @@ + /*----------------------------------------------------------------------------* + * END HIP * + *----------------------------------------------------------------------------*/ ++/* This should come out before going to kernel.org */ ++static void sierra_net_printk_buf(u8 *buf, u16 len) ++{ ++#ifdef VERBOSE ++ u16 i; ++ u16 k; ++ ++ for (i = k = 0; i < len / 4; i++, k += 4) { ++ printk(KERN_DEBUG "%02x%02x%02x%02x ", ++ buf[k+0], buf[k+1], buf[k+2], buf[k+3]); ++ } ++ ++ for (; k < len; k++) ++ printk(KERN_DEBUG "%02x", buf[k]); ++ ++ printk("\n"); ++#endif ++} + + static int sierra_net_send_cmd(struct usbnet *dev, + u8 *cmd, int cmdlen, const char * cmd_name) +@@ -319,10 +349,12 @@ + struct sierra_net_data *priv = sierra_net_get_private(dev); + int status; + ++ usb_autopm_get_interface(dev->intf); + status = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), + USB_CDC_SEND_ENCAPSULATED_COMMAND, + USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE, 0, + priv->ifnum, cmd, cmdlen, USB_CTRL_SET_TIMEOUT); ++ usb_autopm_put_interface(dev->intf); + + if (status != cmdlen && status != -ENODEV) + netdev_err(dev->net, "Submit %s failed %d\n", cmd_name, status); +@@ -339,8 +371,17 @@ + + status = sierra_net_send_cmd(dev, priv->sync_msg, + sizeof(priv->sync_msg), "SYNC"); ++ return status; ++} + +- return status; ++static void sierra_net_send_shutdown(struct usbnet *dev) ++{ ++ struct sierra_net_data *priv = sierra_net_get_private(dev); ++ ++ dev_dbg(&dev->udev->dev, "%s", __func__); ++ ++ sierra_net_send_cmd(dev, priv->shdwn_msg, ++ sizeof(priv->shdwn_msg), "Shutdown"); + } + + static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix) +@@ -354,7 +395,7 @@ + + static inline int sierra_net_is_valid_addrlen(u8 len) + { +- return len == sizeof(struct in_addr); ++ return (len == sizeof(struct in_addr)); + } + + static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen) +@@ -383,10 +424,11 @@ + } + + /* Validate the link type */ +- if (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) { +- netdev_err(dev->net, "Link type unsupported: 0x%02x\n", ++ if ((lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) && ++ (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv6)) { ++ netdev_err(dev->net, "Link unavailable: 0x%02x", + lsi->link_type); +- return -1; ++ return 0; + } + + /* Validate the coverage */ +@@ -474,13 +516,15 @@ + return; + } + ifnum = priv->ifnum; ++ usb_autopm_get_interface(dev->intf); + len = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), + USB_CDC_GET_ENCAPSULATED_RESPONSE, + USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE, + 0, ifnum, buf, SIERRA_NET_USBCTL_BUF_LEN, + USB_CTRL_SET_TIMEOUT); ++ usb_autopm_put_interface(dev->intf); + +- if (len < 0) { ++ if (unlikely(len < 0)) { + netdev_err(dev->net, + "usb_control_msg failed, status %d\n", len); + } else { +@@ -488,6 +532,7 @@ + + dev_dbg(&dev->udev->dev, "%s: Received status message," + " %04x bytes", __func__, len); ++ sierra_net_printk_buf(buf, len); + + err = parse_hip(buf, len, &hh); + if (err) { +@@ -534,7 +579,10 @@ + "extmsgid 0x%04x\n", hh.extmsgid.word); + break; + case SIERRA_NET_HIP_RCGI: +- /* Ignored */ ++ /* Ignored. It is a firmware ++ * workaround to solve a Windows driver bug and ++ * may be removed in the future. ++ */ + break; + default: + netdev_err(dev->net, "Unrecognized HIP msg, " +@@ -561,7 +609,10 @@ + struct sierra_net_data *priv = sierra_net_get_private(dev); + + set_bit(work, &priv->kevent_flags); +- schedule_work(&priv->sierra_net_kevent); ++ if (!schedule_work(&priv->sierra_net_kevent)) ++ dev_dbg(&dev->udev->dev, "sierra_net_kevent %d may have been dropped", work); ++ else ++ dev_dbg(&dev->udev->dev, "sierra_net_kevent %d scheduled", work); + } + + /* +@@ -581,6 +632,7 @@ + struct usb_cdc_notification *event; + + dev_dbg(&dev->udev->dev, "%s", __func__); ++ sierra_net_printk_buf(urb->transfer_buffer, urb->actual_length); + + if (urb->actual_length < sizeof *event) + return; +@@ -661,6 +713,7 @@ + if (!attrdata) + return -ENOMEM; + ++ usb_autopm_get_interface(dev->intf); + result = usb_control_msg( + dev->udev, + usb_rcvctrlpipe(dev->udev, 0), +@@ -672,6 +725,7 @@ + attrdata, /* char *data */ + sizeof(*attrdata), /* __u16 size */ + USB_CTRL_SET_TIMEOUT); /* int timeout */ ++ usb_autopm_put_interface(dev->intf); + + if (result < 0) { + kfree(attrdata); +@@ -684,6 +738,12 @@ + return result; + } + ++static int sierra_net_manage_power(struct usbnet *dev, int on) ++{ ++ dev->intf->needs_remote_wakeup = on; ++ return 0; ++} ++ + /* + * collects the bulk endpoints, the status endpoint. + */ +@@ -735,6 +795,10 @@ + + priv->usbnet = dev; + priv->ifnum = ifacenum; ++ /* override change_mtu with our own routine - need to bound check */ ++ /* replace structure to our own structure where we have our own ++ * routine - need to bound check ++ */ + dev->net->netdev_ops = &sierra_net_device_ops; + + /* change MAC addr to include, ifacenum, and to be unique */ +@@ -761,6 +825,7 @@ + + /* Set up the netdev */ + dev->net->flags |= IFF_NOARP; ++ dev->net->flags |= IFF_MULTICAST; + dev->net->ethtool_ops = &sierra_net_ethtool_ops; + netif_carrier_off(dev->net); + +@@ -773,11 +838,23 @@ + + /* Only need to do this once */ + init_timer(&priv->sync_timer); +- + /* verify fw attributes */ + status = sierra_net_get_fw_attr(dev, &fwattr); +- dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr); +- ++ dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr); ++ if (status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_APM)) { ++/******************************************************************************* ++ * If you want the default /sys/bus/usb/devices/.../.../power/level to be forced ++ * to auto, the following needs to be compiled in. ++ */ ++#ifdef POWER_LEVEL_AUTO ++ /* make power level default be 'auto' */ ++ dev_dbg(&dev->udev->dev, "Enabling APM"); ++ usb_enable_autosuspend(dev->udev); ++#endif ++ } else { ++ dev_info(&intf->dev, "Disabling APM - not supported"); ++ usb_disable_autosuspend(dev->udev); ++ } + /* test whether firmware supports DHCP */ + if (!(status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_MASK))) { + /* found incompatible firmware version */ +@@ -789,33 +866,45 @@ + /* prepare sync message from template */ + memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg)); + ++ return 0; ++} ++ ++static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ struct sierra_net_data *priv = sierra_net_get_private(dev); ++ ++ dev_dbg(&dev->udev->dev, "%s", __func__); ++ ++ sierra_net_set_private(dev, NULL); ++ ++ kfree(priv); ++} ++ ++static int sierra_net_open(struct usbnet *dev) ++{ ++ dev_dbg(&dev->udev->dev, "%s", __func__); ++ + /* initiate the sync sequence */ + sierra_net_dosync(dev); + + return 0; + } + +-static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf) ++static int sierra_net_stop(struct usbnet *dev) + { +- int status; + struct sierra_net_data *priv = sierra_net_get_private(dev); + + dev_dbg(&dev->udev->dev, "%s", __func__); + +- /* kill the timer and work */ ++ /* Kill the timer then flush the work queue */ + del_timer_sync(&priv->sync_timer); ++ + cancel_work_sync(&priv->sierra_net_kevent); + + /* tell modem we are going away */ +- status = sierra_net_send_cmd(dev, priv->shdwn_msg, +- sizeof(priv->shdwn_msg), "Shutdown"); +- if (status < 0) +- netdev_err(dev->net, +- "usb_control_msg failed, status %d\n", status); +- +- sierra_net_set_private(dev, NULL); ++ sierra_net_send_shutdown(dev); + +- kfree(priv); ++ return 0; + } + + static struct sk_buff *sierra_net_skb_clone(struct usbnet *dev, +@@ -847,9 +936,13 @@ + int err; + struct hip_hdr hh; + struct sk_buff *new_skb; ++ struct ethhdr *eth; ++ struct iphdr *ip; + + dev_dbg(&dev->udev->dev, "%s", __func__); + ++ sierra_net_printk_buf(skb->data, skb->len); ++ + /* could contain multiple packets */ + while (likely(skb->len)) { + err = parse_hip(skb->data, skb->len, &hh); +@@ -879,6 +972,12 @@ + memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl, + ETH_HLEN); + ++ ip = (struct iphdr *)((char *)skb->data + ETH_HLEN); ++ if(ip->version == 6) { ++ eth = (struct ethhdr *)skb->data; ++ eth->h_proto = cpu_to_be16(ETH_P_IPV6); ++ } ++ + /* Last packet in batch handled by usbnet */ + if (hh.payload_len.word == skb->len) + return 1; +@@ -923,6 +1022,8 @@ + } + } + build_hip(skb->data, len, priv); ++ ++ sierra_net_printk_buf(skb->data, skb->len); + return skb; + } else { + /* +@@ -942,16 +1043,24 @@ + return NULL; + } + ++static int sierra_net_reset_resume(struct usb_interface *intf) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ netdev_err(dev->net, "%s\n", __func__); ++ return usbnet_resume(intf); ++} ++ + static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 }; +-static const struct sierra_net_info_data sierra_net_info_data_68A3 = { +- .rx_urb_size = 8 * 1024, ++static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { ++ /* .rx_urb_size = 8 * 1024, */ ++ .rx_urb_size = SIERRA_NET_RX_URB_SZ, + .whitelist = { + .infolen = ARRAY_SIZE(sierra_net_ifnum_list), + .ifaceinfo = sierra_net_ifnum_list + } + }; + +-static const struct driver_info sierra_net_info_68A3 = { ++static const struct driver_info sierra_net_info_direct_ip = { + .description = "Sierra Wireless USB-to-WWAN Modem", + .flags = FLAG_WWAN | FLAG_SEND_ZLP, + .bind = sierra_net_bind, +@@ -959,12 +1068,21 @@ + .status = sierra_net_status, + .rx_fixup = sierra_net_rx_fixup, + .tx_fixup = sierra_net_tx_fixup, +- .data = (unsigned long)&sierra_net_info_data_68A3, ++ .manage_power = sierra_net_manage_power, ++ .stop = sierra_net_stop, ++ .check_connect = sierra_net_open, ++ .data = (unsigned long)&sierra_net_info_data_direct_ip, + }; + + static const struct usb_device_id products[] = { +- {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ +- .driver_info = (unsigned long) &sierra_net_info_68A3}, ++ {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modem */ ++ .driver_info = (unsigned long) &sierra_net_info_direct_ip}, ++ {USB_DEVICE(0xF3D, 0x68A3), /* AT&T Direct IP modem */ ++ .driver_info = (unsigned long) &sierra_net_info_direct_ip}, ++ {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ ++ .driver_info = (unsigned long) &sierra_net_info_direct_ip}, ++ {USB_DEVICE(0xF3D, 0x68AA), /* AT&T Direct IP LTE modem */ ++ .driver_info = (unsigned long) &sierra_net_info_direct_ip}, + + {}, /* last item */ + }; +@@ -978,7 +1096,9 @@ + .disconnect = usbnet_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, ++ .reset_resume = sierra_net_reset_resume, + .no_dynamic_id = 1, ++ .supports_autosuspend = 1, + }; + + static int __init sierra_net_init(void) +Index: linux-2.6.39.4/drivers/usb/serial/sierra.c +=================================================================== +--- linux-2.6.39.4.orig/drivers/usb/serial/sierra.c 2012-02-27 15:38:01.519215085 -0600 ++++ linux-2.6.39.4/drivers/usb/serial/sierra.c 2011-09-22 17:05:46.000000000 -0500 +@@ -3,7 +3,7 @@ + + Copyright (C) 2006, 2007, 2008 Kevin Lloyd <klloyd@sierrawireless.com>, + +- Copyright (C) 2008, 2009 Elina Pasheva, Matthew Safar, Rory Filer ++ Copyright (C) 2008 - 2011 Elina Pasheva, Matthew Safar, Rory Filer + <linux@sierrawireless.com> + + IMPORTANT DISCLAIMER: This driver is not commercially supported by +@@ -17,8 +17,12 @@ + Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> + */ + /* Uncomment to log function calls */ +-/* #define DEBUG */ +-#define DRIVER_VERSION "v.1.7.16" ++/*#define DEBUG*/ ++/* Uncomment to force power level set to auto when attaching a device */ ++/*#define POWER_LEVEL_AUTO*/ ++ ++/* Sierra driver - kernel 2.6.38 */ ++#define DRIVER_VERSION "v.1.7.40" + #define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" + #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" + +@@ -31,9 +35,13 @@ + #include <linux/module.h> + #include <linux/usb.h> + #include <linux/usb/serial.h> ++#include <asm/unaligned.h> + + #define SWIMS_USB_REQUEST_SetPower 0x00 ++#define SWIMS_USB_REQUEST_GetFwAttr 0x06 + #define SWIMS_USB_REQUEST_SetNmea 0x07 ++#define USB_REQUEST_TYPE_CLASS 0xA1 ++#define USB_REQUEST_IFACE 0x20 + + #define N_IN_URB_HM 8 + #define N_OUT_URB_HM 64 +@@ -46,19 +54,47 @@ + allocations > PAGE_SIZE and the number of packets in a page + is an integer 512 is the largest possible packet on EHCI */ + ++#define SWI_FW_ATTR_PM_MASK 0x02 ++/* PORTION_LEN defines the length of device attribute buffer */ ++#define PORTION_LEN 4096 ++ + static int debug; + static int nmea; + ++/* sysfs attributes */ ++static int sierra_create_sysfs_attrs(struct usb_serial_port *port); ++static int sierra_remove_sysfs_attrs(struct usb_serial_port *port); ++ + /* Used in interface blacklisting */ + struct sierra_iface_info { + const u32 infolen; /* number of interface numbers on blacklist */ + const u8 *ifaceinfo; /* pointer to the array holding the numbers */ + }; + ++/* per interface statistics */ ++struct sierra_intf_stats { ++ atomic_t rx_bytes; /* received bytes */ ++ atomic_t indat_cb_cnt; /* indat callback count */ ++ atomic_t indat_cb_fail; /* indat cb with error */ ++ ++ atomic_t tx_bytes; /* transmitted bytes */ ++ atomic_t write_cnt; /* no. of writes */ ++ atomic_t write_err; /* no. of failed writes */ ++ ++ atomic_t delayed_writes; /* no. of delayed writes */ ++ atomic_t delayed_write_err; /* no. of delayed write errs */ ++ ++ atomic_t outdat_cb_cnt; /* outdat callback count */ ++ atomic_t outdat_cb_fail; /* outdat cb with error */ ++ ++}; ++ + struct sierra_intf_private { + spinlock_t susp_lock; + unsigned int suspended:1; + int in_flight; ++ ++ struct sierra_intf_stats stats; + }; + + static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) +@@ -91,6 +127,38 @@ + return result; + } + ++static int sierra_get_fw_attr(struct usb_device *udev, u16 *data) ++{ ++ int result; ++ u16 *attrdata; ++ ++ dev_dbg(&udev->dev, "%s\n", __func__); ++ ++ attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL); ++ if (!attrdata) ++ return -ENOMEM; ++ ++ result = usb_control_msg(udev, ++ usb_rcvctrlpipe(udev, 0), ++ SWIMS_USB_REQUEST_GetFwAttr, /* __u8 request*/ ++ USB_TYPE_VENDOR | USB_DIR_IN, /* request type*/ ++ 0x0000, /* __u16 value */ ++ 0x0000, /* __u16 index */ ++ attrdata, /* void *data */ ++ sizeof(*attrdata), /* _u16 size */ ++ USB_CTRL_SET_TIMEOUT); /* in timeout */ ++ ++ if (result < 0) { ++ kfree(attrdata); ++ return -EIO; ++ } ++ ++ *data = *attrdata; ++ ++ kfree(attrdata); ++ return result; ++} ++ + static int sierra_calc_num_ports(struct usb_serial *serial) + { + int num_ports = 0; +@@ -150,7 +218,6 @@ + int interface; + struct usb_interface *p_interface; + struct usb_host_interface *p_host_interface; +- dev_dbg(&serial->dev->dev, "%s\n", __func__); + + /* Get the interface structure pointer from the serial struct */ + p_interface = serial->interface; +@@ -159,8 +226,7 @@ + p_host_interface = p_interface->cur_altsetting; + + /* read the interface descriptor for this active altsetting +- * to find out the interface number we are on +- */ ++ * to find out the interface number we are on */ + interface = p_host_interface->desc.bInterfaceNumber; + + return interface; +@@ -171,7 +237,7 @@ + { + int result = 0; + struct usb_device *udev; +- struct sierra_intf_private *data; ++ struct sierra_intf_private *intfdata; + u8 ifnum; + + udev = serial->dev; +@@ -185,7 +251,9 @@ + if (serial->interface->num_altsetting == 2) { + dev_dbg(&udev->dev, "Selecting alt setting for interface %d\n", + ifnum); +- /* We know the alternate setting is 1 for the MC8785 */ ++ /* We know the alternate setting is for composite USB interface ++ * modems ++ */ + usb_set_interface(udev, ifnum, 1); + } + +@@ -199,10 +267,11 @@ + return -ENODEV; + } + +- data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL); +- if (!data) ++ intfdata = serial->private = kzalloc(sizeof(struct sierra_intf_private), ++ GFP_KERNEL); ++ if (!intfdata) + return -ENOMEM; +- spin_lock_init(&data->susp_lock); ++ spin_lock_init(&intfdata->susp_lock); + + return result; + } +@@ -223,15 +292,15 @@ + /* 'blacklist' of interfaces not served by this driver */ + static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; + static const struct sierra_iface_info direct_ip_interface_blacklist = { +- .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), ++ .infolen = ARRAY_SIZE( direct_ip_non_serial_ifaces ), + .ifaceinfo = direct_ip_non_serial_ifaces, + }; + +-static const struct usb_device_id id_table[] = { ++static const struct usb_device_id id_table [] = { + { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ + { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */ +- { USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */ + { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */ ++ { USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */ + + { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ + { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ +@@ -245,7 +314,10 @@ + { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ + { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ + { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ +- { USB_DEVICE(0x1199, 0x0301) }, /* Sierra Wireless USB Dongle 250U */ ++ { USB_DEVICE(0x1199, 0x0301) }, /* Sierra Wireless USB Dongle 250U/3G */ ++ /* Sierra Wireless MC5728 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0400, 0xFF, 0xFF, 0xFF) }, ++ + /* Sierra Wireless C597 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, + /* Sierra Wireless T598 */ +@@ -253,7 +325,7 @@ + { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */ + { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */ + { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */ +- { USB_DEVICE(0x1199, 0x0029) }, /* Sierra Wireless Device */ ++ { USB_DEVICE(0x114F, 0x6000) }, /* Sierra Wireless Q26 Elite */ + + { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ + { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ +@@ -277,7 +349,7 @@ + { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ + { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ + /* Sierra Wireless MC8790, MC8791, MC8792 Composite */ +- { USB_DEVICE(0x1199, 0x683C) }, ++ { USB_DEVICE(0x1199, 0x683C) }, + { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8791 Composite */ + /* Sierra Wireless MC8790, MC8791, MC8792 */ + { USB_DEVICE(0x1199, 0x683E) }, +@@ -298,22 +370,34 @@ + /* 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, 0x68A3), /* Sierra Wireless Direct IP modems */ +- .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist ++ /* Sierra Wireless Direct IP modems */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68A3, 0xFF, 0xFF, 0xFF), ++ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist + }, +- { USB_DEVICE(0x0f3d, 0x68A3), /* Airprime/Sierra Wireless Direct IP modems */ +- .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist ++ /* AT&T Direct IP modems */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68A3, 0xFF, 0xFF, 0xFF), ++ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist + }, +- { USB_DEVICE(0x413C, 0x08133) }, /* Dell Computer Corp. Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */ ++ /* Sierra Wireless Direct IP LTE modems */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68AA, 0xFF, 0xFF, 0xFF), ++ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist ++ }, ++ /* AT&T Direct IP LTE modems */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), ++ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist ++ }, ++ /* Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */ ++ { USB_DEVICE(0x413C, 0x8133) }, + + { } + }; + MODULE_DEVICE_TABLE(usb, id_table); + +- ++/* per port private data */ + struct sierra_port_private { + spinlock_t lock; /* lock the structure */ + int outstanding_urbs; /* number of out urbs in flight */ ++ + struct usb_anchor active; + struct usb_anchor delayed; + +@@ -335,7 +419,7 @@ + static int sierra_send_setup(struct usb_serial_port *port) + { + struct usb_serial *serial = port->serial; +- struct sierra_port_private *portdata; ++ struct sierra_port_private *portdata = usb_get_serial_port_data(port); + __u16 interface = 0; + int val = 0; + int do_send = 0; +@@ -343,8 +427,6 @@ + + dev_dbg(&port->dev, "%s\n", __func__); + +- portdata = usb_get_serial_port_data(port); +- + if (portdata->dtr_state) + val |= 0x01; + if (portdata->rts_state) +@@ -376,10 +458,7 @@ + if (!do_send) + return 0; + +- retval = usb_autopm_get_interface(serial->interface); +- if (retval < 0) +- return retval; +- ++ usb_autopm_get_interface(serial->interface); + retval = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), + 0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT); + usb_autopm_put_interface(serial->interface); +@@ -395,7 +474,7 @@ + sierra_send_setup(port); + } + +-static int sierra_tiocmget(struct tty_struct *tty) ++static int sierra_tiocmget(struct tty_struct *tty, struct file *file) + { + struct usb_serial_port *port = tty->driver_data; + unsigned int value; +@@ -414,7 +493,7 @@ + return value; + } + +-static int sierra_tiocmset(struct tty_struct *tty, ++static int sierra_tiocmset(struct tty_struct *tty, struct file *file, + unsigned int set, unsigned int clear) + { + struct usb_serial_port *port = tty->driver_data; +@@ -440,11 +519,77 @@ + if (urb) { + port = urb->context; + dev_dbg(&port->dev, "%s: %p\n", __func__, urb); +- kfree(urb->transfer_buffer); + usb_free_urb(urb); + } + } + ++/* Sysfs Attributes */ ++ ++static ssize_t show_suspend_status(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct usb_serial_port *port; ++ struct sierra_port_private *portdata; ++ struct sierra_intf_private *intfdata; ++ unsigned long flags; ++ unsigned int flag_suspended = 0; ++ ++ port = to_usb_serial_port(dev); ++ portdata = usb_get_serial_port_data(port); ++ intfdata = port->serial->private; ++ ++ spin_lock_irqsave(&intfdata->susp_lock, flags); ++ flag_suspended = intfdata->suspended; ++ spin_unlock_irqrestore(&intfdata->susp_lock, flags); ++ ++ return snprintf(buf, PORTION_LEN, "%i\n", flag_suspended); ++} ++ ++static ssize_t show_stats(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct usb_serial_port *port; ++ struct sierra_intf_private *intfdata; ++ ++ port = to_usb_serial_port(dev); ++ intfdata = port->serial->private; ++ ++ return snprintf(buf, PORTION_LEN, ++ "rx: %i B\tindat: %i\tindat err: %i\n" ++ "tx: %i B\toutdat: %i\toutdat err: %i\n" ++ "writes: %i\t\twrite err: %i\n" ++ "delayed writes: %i\tdelayed write err: %i\n", ++ atomic_read(&intfdata->stats.rx_bytes), atomic_read(&intfdata->stats.indat_cb_cnt), atomic_read(&intfdata->stats.indat_cb_fail), ++ atomic_read(&intfdata->stats.tx_bytes), atomic_read(&intfdata->stats.outdat_cb_cnt), atomic_read(&intfdata->stats.outdat_cb_fail), ++ atomic_read(&intfdata->stats.write_cnt), atomic_read(&intfdata->stats.write_err), ++ atomic_read(&intfdata->stats.delayed_writes), atomic_read(&intfdata->stats.delayed_write_err) ++ ); ++} ++ ++/* Read only suspend status */ ++static DEVICE_ATTR(suspend_status, S_IWUSR | S_IRUGO, show_suspend_status, ++ NULL); ++ ++/* Read only statistics */ ++static DEVICE_ATTR(stats, S_IWUSR | S_IRUGO, show_stats, NULL); ++ ++static int sierra_create_sysfs_attrs(struct usb_serial_port *port) ++{ ++ int result = 0; ++ ++ result = device_create_file(&port->dev, &dev_attr_stats); ++ if (unlikely (result < 0)) ++ return result; ++ return device_create_file(&port->dev, &dev_attr_suspend_status); ++} ++ ++static int sierra_remove_sysfs_attrs(struct usb_serial_port *port) ++{ ++ device_remove_file(&port->dev, &dev_attr_stats); ++ device_remove_file(&port->dev, &dev_attr_suspend_status); ++ return 0; ++} ++ + static void sierra_outdat_callback(struct urb *urb) + { + struct usb_serial_port *port = urb->context; +@@ -455,16 +600,20 @@ + dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); + intfdata = port->serial->private; + +- /* free up the transfer buffer, as usb_free_urb() does not do this */ +- kfree(urb->transfer_buffer); + usb_autopm_put_interface_async(port->serial->interface); +- if (status) ++ ++ atomic_inc(&intfdata->stats.outdat_cb_cnt); ++ ++ if (status) { + dev_dbg(&port->dev, "%s - nonzero write bulk status " + "received: %d\n", __func__, status); ++ atomic_inc(&intfdata->stats.outdat_cb_fail); ++ } + + spin_lock(&portdata->lock); + --portdata->outstanding_urbs; + spin_unlock(&portdata->lock); ++ + spin_lock(&intfdata->susp_lock); + --intfdata->in_flight; + spin_unlock(&intfdata->susp_lock); +@@ -473,10 +622,11 @@ + } + + /* Write */ +-static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, +- const unsigned char *buf, int count) ++static int sierra_write(struct tty_struct *tty, ++ struct usb_serial_port *port, ++ const unsigned char *buf, int count) + { +- struct sierra_port_private *portdata; ++ struct sierra_port_private *portdata = usb_get_serial_port_data(port); + struct sierra_intf_private *intfdata; + struct usb_serial *serial = port->serial; + unsigned long flags; +@@ -489,46 +639,49 @@ + if (count == 0) + return 0; + +- portdata = usb_get_serial_port_data(port); ++ dev_dbg(&port->dev, "%s: write (%zu bytes)\n", __func__, writesize); ++ + intfdata = serial->private; + +- dev_dbg(&port->dev, "%s: write (%zd bytes)\n", __func__, writesize); + spin_lock_irqsave(&portdata->lock, flags); +- dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__, +- portdata->outstanding_urbs); + if (portdata->outstanding_urbs > portdata->num_out_urbs) { + spin_unlock_irqrestore(&portdata->lock, flags); + dev_dbg(&port->dev, "%s - write limit hit\n", __func__); + return 0; + } + portdata->outstanding_urbs++; +- dev_dbg(&port->dev, "%s - 1, outstanding_urbs: %d\n", __func__, +- portdata->outstanding_urbs); + spin_unlock_irqrestore(&portdata->lock, flags); + + retval = usb_autopm_get_interface_async(serial->interface); +- if (retval < 0) { ++ if (unlikely(retval < 0)) { + spin_lock_irqsave(&portdata->lock, flags); + portdata->outstanding_urbs--; + spin_unlock_irqrestore(&portdata->lock, flags); +- goto error_simple; ++ return retval; + } + + buffer = kmalloc(writesize, GFP_ATOMIC); + if (!buffer) { + dev_err(&port->dev, "out of memory\n"); +- retval = -ENOMEM; +- goto error_no_buffer; ++ spin_lock_irqsave(&portdata->lock, flags); ++ --portdata->outstanding_urbs; ++ spin_unlock_irqrestore(&portdata->lock, flags); ++ usb_autopm_put_interface_async(serial->interface); ++ return -ENOMEM; + } + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + dev_err(&port->dev, "no more free urbs\n"); +- retval = -ENOMEM; +- goto error_no_urb; ++ kfree(buffer); ++ spin_lock_irqsave(&portdata->lock, flags); ++ --portdata->outstanding_urbs; ++ spin_unlock_irqrestore(&portdata->lock, flags); ++ usb_autopm_put_interface_async(serial->interface); ++ return -ENOMEM; + } + +- memcpy(buffer, buf, writesize); ++ memcpy(buffer, buf, writesize); + + usb_serial_debug_data(debug, &port->dev, __func__, writesize, buffer); + +@@ -537,69 +690,73 @@ + port->bulk_out_endpointAddress), + buffer, writesize, sierra_outdat_callback, port); + +- /* Handle the need to send a zero length packet */ +- urb->transfer_flags |= URB_ZERO_PACKET; ++ /* Handle the need to send a zero length packet and release the ++ * transfer buffer ++ */ ++ urb->transfer_flags |= (URB_ZERO_PACKET | URB_FREE_BUFFER); + + spin_lock_irqsave(&intfdata->susp_lock, flags); + + if (intfdata->suspended) { + usb_anchor_urb(urb, &portdata->delayed); + spin_unlock_irqrestore(&intfdata->susp_lock, flags); +- goto skip_power; +- } else { +- usb_anchor_urb(urb, &portdata->active); ++ /* release our reference to this urb, the USB core will ++ * eventually free it entirely */ ++ usb_free_urb(urb); ++ return writesize; + } ++ usb_anchor_urb(urb, &portdata->active); ++ + /* send it down the pipe */ + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) { + usb_unanchor_urb(urb); + spin_unlock_irqrestore(&intfdata->susp_lock, flags); ++ + dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " + "with status = %d\n", __func__, retval); +- goto error; ++ usb_free_urb(urb); ++ spin_lock_irqsave(&portdata->lock, flags); ++ --portdata->outstanding_urbs; ++ spin_unlock_irqrestore(&portdata->lock, flags); ++ usb_autopm_put_interface_async(serial->interface); ++ atomic_inc(&intfdata->stats.write_err); ++ return retval; + } else { + intfdata->in_flight++; + spin_unlock_irqrestore(&intfdata->susp_lock, flags); ++ atomic_inc(&intfdata->stats.write_cnt); ++ atomic_add(writesize, &intfdata->stats.tx_bytes); + } +- +-skip_power: +- /* we are done with this urb, so let the host driver +- * really free it when it is finished with it */ +- usb_free_urb(urb); ++ /* release our reference to this urb, the USB core will eventually ++ * free it entirely */ ++ usb_free_urb(urb); + + return writesize; +-error: +- usb_free_urb(urb); +-error_no_urb: +- kfree(buffer); +-error_no_buffer: +- spin_lock_irqsave(&portdata->lock, flags); +- --portdata->outstanding_urbs; +- dev_dbg(&port->dev, "%s - 2. outstanding_urbs: %d\n", __func__, +- portdata->outstanding_urbs); +- spin_unlock_irqrestore(&portdata->lock, flags); +- usb_autopm_put_interface_async(serial->interface); +-error_simple: +- return retval; + } + + static void sierra_indat_callback(struct urb *urb) + { + int err; + int endpoint; +- struct usb_serial_port *port; ++ struct usb_serial_port *port = urb->context; + struct tty_struct *tty; ++ struct sierra_intf_private *intfdata; + unsigned char *data = urb->transfer_buffer; + int status = urb->status; + + endpoint = usb_pipeendpoint(urb->pipe); +- port = urb->context; + + dev_dbg(&port->dev, "%s: %p\n", __func__, urb); + ++ intfdata = port->serial->private; ++ ++ atomic_inc(&intfdata->stats.indat_cb_cnt); /* indat calls */ ++ + if (status) { + dev_dbg(&port->dev, "%s: nonzero status: %d on" + " endpoint %02x\n", __func__, status, endpoint); ++ atomic_inc(&intfdata->stats.indat_cb_fail); /* indat fails */ + } else { + if (urb->actual_length) { + tty = tty_port_tty_get(&port->port); +@@ -609,6 +766,10 @@ + tty_flip_buffer_push(tty); + + tty_kref_put(tty); ++ /* tty invalid after this point */ ++ /* rx'd bytes */ ++ atomic_add(urb->actual_length, ++ &intfdata->stats.rx_bytes); + usb_serial_debug_data(debug, &port->dev, + __func__, urb->actual_length, data); + } +@@ -619,13 +780,15 @@ + } + + /* Resubmit urb so we continue receiving */ +- if (status != -ESHUTDOWN && status != -EPERM) { ++ if (status != -ESHUTDOWN && status != -ENOENT && status != -ENODEV) { + usb_mark_last_busy(port->serial->dev); + err = usb_submit_urb(urb, GFP_ATOMIC); +- if (err && err != -EPERM) ++ if (err && err != -ENODEV) + dev_err(&port->dev, "resubmit read urb failed." + "(%d)\n", err); + } ++ ++ return; + } + + static void sierra_instat_callback(struct urb *urb) +@@ -636,31 +799,29 @@ + struct sierra_port_private *portdata = usb_get_serial_port_data(port); + struct usb_serial *serial = port->serial; + +- dev_dbg(&port->dev, "%s: urb %p port %p has data %p\n", __func__, +- urb, port, portdata); ++ dev_dbg(&port->dev, "%s: %p\n", __func__, urb); + + if (status == 0) { + struct usb_ctrlrequest *req_pkt = + (struct usb_ctrlrequest *)urb->transfer_buffer; + +- if (!req_pkt) { +- dev_dbg(&port->dev, "%s: NULL req_pkt\n", +- __func__); +- return; +- } +- if ((req_pkt->bRequestType == 0xA1) && +- (req_pkt->bRequest == 0x20)) { ++ const u16 *sigp = (u16 *)(req_pkt + 1); ++ /* usb_ctrlrequest we parsed is followed by two bytes of data ++ * make sure we received that many bytes ++ */ ++ if (urb->actual_length >= sizeof(*req_pkt) + sizeof(*sigp) && ++ req_pkt->bRequestType == USB_REQUEST_TYPE_CLASS && ++ req_pkt->bRequest == USB_REQUEST_IFACE) { + int old_dcd_state; +- unsigned char signals = *((unsigned char *) +- urb->transfer_buffer + +- sizeof(struct usb_ctrlrequest)); ++ const u16 signals = get_unaligned_le16(sigp); + struct tty_struct *tty; + +- dev_dbg(&port->dev, "%s: signal x%x\n", __func__, ++ dev_dbg(&port->dev, "%s: signal 0x%x\n", __func__, + signals); + + old_dcd_state = portdata->dcd_state; +- portdata->cts_state = 1; ++ /* Note: CTS from modem is in reverse logic! */ ++ portdata->cts_state = ((signals & 0x100) ? 0 : 1); + portdata->dcd_state = ((signals & 0x01) ? 1 : 0); + portdata->dsr_state = ((signals & 0x02) ? 1 : 0); + portdata->ri_state = ((signals & 0x08) ? 1 : 0); +@@ -671,19 +832,19 @@ + tty_hangup(tty); + tty_kref_put(tty); + } else { +- dev_dbg(&port->dev, "%s: type %x req %x\n", +- __func__, req_pkt->bRequestType, +- req_pkt->bRequest); ++ /* dump the data we don't understand to log */ ++ usb_serial_debug_data(1, &port->dev, __func__, ++ urb->actual_length, urb->transfer_buffer); + } + } else + dev_dbg(&port->dev, "%s: error %d\n", __func__, status); + + /* Resubmit urb so we continue receiving IRQ data */ +- if (status != -ESHUTDOWN && status != -ENOENT) { ++ if (status != -ESHUTDOWN && status != -ENOENT && status != -ENODEV) { + usb_mark_last_busy(serial->dev); + urb->dev = serial->dev; + err = usb_submit_urb(urb, GFP_ATOMIC); +- if (err && err != -EPERM) ++ if (err && err != -ENODEV) + dev_err(&port->dev, "%s: resubmit intr urb " + "failed. (%d)\n", __func__, err); + } +@@ -694,20 +855,21 @@ + struct usb_serial_port *port = tty->driver_data; + struct sierra_port_private *portdata = usb_get_serial_port_data(port); + unsigned long flags; ++ int retval; + + dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); + + /* try to give a good number back based on if we have any free urbs at + * this point in time */ ++ retval = MAX_TRANSFER; ++ + spin_lock_irqsave(&portdata->lock, flags); +- if (portdata->outstanding_urbs > (portdata->num_out_urbs * 2) / 3) { +- spin_unlock_irqrestore(&portdata->lock, flags); +- dev_dbg(&port->dev, "%s - write limit hit\n", __func__); +- return 0; ++ if (portdata->outstanding_urbs >= portdata->num_out_urbs) { ++ retval = 0; + } + spin_unlock_irqrestore(&portdata->lock, flags); + +- return 2048; ++ return retval; + } + + static void sierra_stop_rx_urbs(struct usb_serial_port *port) +@@ -734,6 +896,7 @@ + urb = portdata->in_urbs[i]; + if (!urb) + continue; ++ urb->transfer_flags |= URB_FREE_BUFFER; + err = usb_submit_urb(urb, mem_flags); + if (err) { + dev_err(&port->dev, "%s: submit urb failed: %d\n", +@@ -795,38 +958,31 @@ + + return urb; + } +- + static void sierra_close(struct usb_serial_port *port) + { + int i; ++ struct urb *urb; + struct usb_serial *serial = port->serial; + struct sierra_port_private *portdata; + struct sierra_intf_private *intfdata = port->serial->private; + +- + dev_dbg(&port->dev, "%s\n", __func__); + portdata = usb_get_serial_port_data(port); + + portdata->rts_state = 0; + portdata->dtr_state = 0; + ++ usb_autopm_get_interface(serial->interface); ++ + if (serial->dev) { + mutex_lock(&serial->disc_mutex); +- if (!serial->disconnected) { +- serial->interface->needs_remote_wakeup = 0; +- /* odd error handling due to pm counters */ +- if (!usb_autopm_get_interface(serial->interface)) +- sierra_send_setup(port); +- else +- usb_autopm_get_interface_no_resume(serial->interface); +- +- } ++ if (!serial->disconnected) ++ sierra_send_setup(port); + mutex_unlock(&serial->disc_mutex); + spin_lock_irq(&intfdata->susp_lock); + portdata->opened = 0; + spin_unlock_irq(&intfdata->susp_lock); + +- + /* Stop reading urbs */ + sierra_stop_rx_urbs(port); + /* .. and release them */ +@@ -834,6 +990,14 @@ + sierra_release_urb(portdata->in_urbs[i]); + portdata->in_urbs[i] = NULL; + } ++ while((urb = usb_get_from_anchor(&portdata->delayed))) { ++ sierra_release_urb(urb); ++ usb_autopm_put_interface(serial->interface); ++ } ++ /* wait for active to finish */ ++ usb_wait_anchor_empty_timeout(&portdata->active, 500); ++ usb_kill_anchored_urbs(&portdata->active); ++ + } + } + +@@ -867,18 +1031,41 @@ + usb_clear_halt(serial->dev, + usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN); + ++ /* reset outstanding out urbs counter */ ++ spin_lock_irq(&portdata->lock); ++ portdata->outstanding_urbs = 0; ++ spin_unlock_irq(&portdata->lock); ++ + err = sierra_submit_rx_urbs(port, GFP_KERNEL); + if (err) { +- /* get rid of everything as in close */ +- sierra_close(port); +- /* restore balance for autopm */ +- if (!serial->disconnected) ++ /* do everything as in close() but do not call close() because ++ * usbserial calls sierra_open() with mutex taken; ++ * then if we call sierra_close() inside sierra_open() we ++ * violate 'no nested mutexes' kernel condition ++ */ ++ portdata->rts_state = 0; ++ portdata->dtr_state = 0; ++ usb_autopm_get_interface(serial->interface); ++ /* Stop reading urbs */ ++ sierra_stop_rx_urbs(port); ++ /* .. and release them */ ++ for (i = 0; i < portdata->num_in_urbs; i++) { ++ sierra_release_urb(portdata->in_urbs[i]); ++ portdata->in_urbs[i] = NULL; ++ } ++ while((urb = usb_get_from_anchor(&portdata->delayed))) { ++ sierra_release_urb(urb); + usb_autopm_put_interface(serial->interface); ++ } ++ /* wait for active to finish */ ++ usb_wait_anchor_empty_timeout(&portdata->active, 500); ++ usb_kill_anchored_urbs(&portdata->active); ++ /* restore balance for autopm */ ++ usb_autopm_put_interface(serial->interface); + return err; + } + sierra_send_setup(port); + +- serial->interface->needs_remote_wakeup = 1; + spin_lock_irq(&intfdata->susp_lock); + portdata->opened = 1; + spin_unlock_irq(&intfdata->susp_lock); +@@ -887,7 +1074,6 @@ + return 0; + } + +- + static void sierra_dtr_rts(struct usb_serial_port *port, int on) + { + struct usb_serial *serial = port->serial; +@@ -907,11 +1093,13 @@ + + static int sierra_startup(struct usb_serial *serial) + { +- struct usb_serial_port *port; +- struct sierra_port_private *portdata; ++ struct usb_serial_port *port = NULL; ++ struct sierra_port_private *portdata = NULL; + struct sierra_iface_info *himemoryp = NULL; + int i; + u8 ifnum; ++ u16 fw_attr; ++ int result; + + dev_dbg(&serial->dev->dev, "%s\n", __func__); + +@@ -922,19 +1110,30 @@ + if (nmea) + sierra_vsc_set_nmea(serial->dev, 1); + +- /* Now setup per port private data */ +- for (i = 0; i < serial->num_ports; i++) { +- port = serial->port[i]; +- portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); ++ if (serial->num_ports) { ++ /* Note: One big piece of memory is allocated for all ports ++ * private data in one shot. This memory is split into equal ++ * pieces for each port. ++ */ ++ portdata = (struct sierra_port_private *)kzalloc ++ (sizeof(*portdata) * serial->num_ports, GFP_KERNEL); + if (!portdata) { +- dev_dbg(&port->dev, "%s: kmalloc for " +- "sierra_port_private (%d) failed!\n", +- __func__, i); ++ dev_dbg(&serial->dev->dev, "%s: No memory!\n", __func__); + return -ENOMEM; + } ++ } ++ ++ /* Now setup per port private data */ ++ for (i = 0; i < serial->num_ports; i++, portdata++) { ++ port = serial->port[i]; ++ /* Initialize selected members of private data because these ++ * may be referred to right away */ + spin_lock_init(&portdata->lock); + init_usb_anchor(&portdata->active); + init_usb_anchor(&portdata->delayed); ++ ++ portdata->cts_state = 1; ++ + ifnum = i; + /* Assume low memory requirements */ + portdata->num_out_urbs = N_OUT_URB; +@@ -959,12 +1158,29 @@ + portdata->num_in_urbs = N_IN_URB_HM; + } + } +- dev_dbg(&serial->dev->dev, ++ dev_dbg(&serial->dev->dev, + "Memory usage (urbs) interface #%d, in=%d, out=%d\n", + ifnum,portdata->num_in_urbs, portdata->num_out_urbs ); + /* Set the port private data pointer */ + usb_set_serial_port_data(port, portdata); + } ++ serial->interface->needs_remote_wakeup = 1; ++ ++ result = sierra_get_fw_attr(serial->dev, &fw_attr); ++ if (result == sizeof(fw_attr) && (fw_attr & SWI_FW_ATTR_PM_MASK) ) { ++ dev_info(&serial->dev->dev, ++ "APM supported, enabling autosuspend.\n"); ++/******************************************************************************* ++ * If you want the default /sys/bus/usb/devices/.../.../power/level to be forced ++ * to auto, the following needs to be compiled in. ++ */ ++#ifdef POWER_LEVEL_AUTO ++ /* make power level default be 'auto' */ ++ usb_enable_autosuspend(serial->dev); ++#endif ++ } else { ++ usb_disable_autosuspend(serial->dev); ++ } + + return 0; + } +@@ -973,19 +1189,29 @@ + { + int i; + struct usb_serial_port *port; +- struct sierra_port_private *portdata; ++ struct sierra_intf_private *intfdata = serial->private; + + dev_dbg(&serial->dev->dev, "%s\n", __func__); + ++ if (serial->num_ports > 0) { ++ port = serial->port[0]; ++ if (port) ++ /* Note: The entire piece of memory that was allocated ++ * in the startup routine can be released by passing ++ * a pointer to the beginning of the piece. ++ * This address corresponds to the address of the chunk ++ * that was given to port 0. ++ */ ++ kfree(usb_get_serial_port_data(port)); ++ } ++ + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + if (!port) + continue; +- portdata = usb_get_serial_port_data(port); +- if (!portdata) +- continue; +- kfree(portdata); ++ usb_set_serial_port_data(port, NULL); + } ++ kfree(intfdata); + } + + #ifdef CONFIG_PM +@@ -1007,21 +1233,21 @@ + static int sierra_suspend(struct usb_serial *serial, pm_message_t message) + { + struct sierra_intf_private *intfdata; +- int b; + +- if (message.event & PM_EVENT_AUTO) { +- intfdata = serial->private; +- spin_lock_irq(&intfdata->susp_lock); +- b = intfdata->in_flight; ++ dev_dbg(&serial->dev->dev, "%s\n", __func__); ++ ++ intfdata = serial->private; ++ spin_lock_irq(&intfdata->susp_lock); + +- if (b) { ++ if (message.event & PM_EVENT_AUTO) { ++ if (intfdata->in_flight) { + spin_unlock_irq(&intfdata->susp_lock); + return -EBUSY; +- } else { +- intfdata->suspended = 1; +- spin_unlock_irq(&intfdata->susp_lock); + } + } ++ intfdata->suspended = 1; ++ spin_unlock_irq(&intfdata->susp_lock); ++ + stop_read_write_urbs(serial); + + return 0; +@@ -1035,22 +1261,35 @@ + struct urb *urb; + int ec = 0; + int i, err; ++ int len; ++ int failed_submits; + ++ dev_dbg(&serial->dev->dev, "%s\n", __func__); ++ + spin_lock_irq(&intfdata->susp_lock); + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + portdata = usb_get_serial_port_data(port); +- ++ failed_submits = 0; + while ((urb = usb_get_from_anchor(&portdata->delayed))) { + usb_anchor_urb(urb, &portdata->active); + intfdata->in_flight++; ++ len = urb->transfer_buffer_length; + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err < 0) { + intfdata->in_flight--; + usb_unanchor_urb(urb); +- usb_scuttle_anchored_urbs(&portdata->delayed); +- break; ++ failed_submits++; ++ atomic_inc(&intfdata->stats.delayed_write_err); ++ /* fix pm_usage_cnt */ ++ usb_autopm_put_interface_async( ++ port->serial->interface); ++ } else { ++ atomic_inc(&intfdata->stats.delayed_writes); ++ atomic_add(len, &intfdata->stats.tx_bytes); + } ++ /* release urb - usb_get_from_anchor increased kref */ ++ usb_free_urb(urb); + } + + if (portdata->opened) { +@@ -1058,12 +1297,24 @@ + if (err) + ec++; + } ++ if (failed_submits) { ++ /* fix outstanding_urbs counter */ ++ spin_lock(&portdata->lock); /* assuming irq disabled */ ++ portdata->outstanding_urbs -= failed_submits; ++ spin_unlock(&portdata->lock); ++ /* unblock a writer */ ++ usb_serial_port_softint(port); ++ } + } + intfdata->suspended = 0; + spin_unlock_irq(&intfdata->susp_lock); + + return ec ? -EIO : 0; + } ++#else ++#define sierra_suspend NULL ++#define sierra_resume NULL ++#endif + + static int sierra_reset_resume(struct usb_interface *intf) + { +@@ -1071,11 +1322,6 @@ + dev_err(&serial->dev->dev, "%s\n", __func__); + return usb_serial_resume(intf); + } +-#else +-#define sierra_suspend NULL +-#define sierra_resume NULL +-#define sierra_reset_resume NULL +-#endif + + static struct usb_driver sierra_driver = { + .name = "sierra", +@@ -1085,10 +1331,12 @@ + .resume = usb_serial_resume, + .reset_resume = sierra_reset_resume, + .id_table = id_table, +- .no_dynamic_id = 1, +- .supports_autosuspend = 1, ++ ++ .no_dynamic_id = 1, ++ .supports_autosuspend = 1, + }; + ++ + static struct usb_serial_driver sierra_device = { + .driver = { + .owner = THIS_MODULE, +@@ -1109,9 +1357,12 @@ + .tiocmset = sierra_tiocmset, + .attach = sierra_startup, + .release = sierra_release, +- .suspend = sierra_suspend, +- .resume = sierra_resume, ++ .port_probe = sierra_create_sysfs_attrs, ++ .port_remove = sierra_remove_sysfs_attrs, ++ .suspend = sierra_suspend, ++ .resume = sierra_resume, + .read_int_callback = sierra_instat_callback, ++ + }; + + /* Functions used by new usb-serial code. */ +@@ -1122,7 +1373,6 @@ + if (retval) + goto failed_device_register; + +- + retval = usb_register(&sierra_driver); + if (retval) + goto failed_driver_register; diff --git a/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-at91.patch b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-at91.patch new file mode 100644 index 0000000..579ddfa --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-at91.patch @@ -0,0 +1,13539 @@ +diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt +index a167ab8..7cc6bf2 100644 +--- a/Documentation/filesystems/caching/netfs-api.txt ++++ b/Documentation/filesystems/caching/netfs-api.txt +@@ -673,6 +673,22 @@ storage request to complete, or it may attempt to cancel the storage request - + in which case the page will not be stored in the cache this time. + + ++BULK INODE PAGE UNCACHE ++----------------------- ++ ++A convenience routine is provided to perform an uncache on all the pages ++attached to an inode. This assumes that the pages on the inode correspond on a ++1:1 basis with the pages in the cache. ++ ++ void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, ++ struct inode *inode); ++ ++This takes the netfs cookie that the pages were cached with and the inode that ++the pages are attached to. This function will wait for pages to finish being ++written to the cache and for the cache to finish with the page generally. No ++error is returned. ++ ++ + ========================== + INDEX AND DATA FILE UPDATE + ========================== +diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients +index 5ebf5af..5aa5337 100644 +--- a/Documentation/i2c/writing-clients ++++ b/Documentation/i2c/writing-clients +@@ -38,7 +38,7 @@ static struct i2c_driver foo_driver = { + .name = "foo", + }, + +- .id_table = foo_ids, ++ .id_table = foo_idtable, + .probe = foo_probe, + .remove = foo_remove, + /* if device autodetection is needed: */ +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index cc85a92..066b642 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -2590,6 +2590,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + unlock ejectable media); + m = MAX_SECTORS_64 (don't transfer more + than 64 sectors = 32 KB at a time); ++ n = INITIAL_READ10 (force a retry of the ++ initial READ(10) command); + o = CAPACITY_OK (accept the capacity + reported by the device); + r = IGNORE_RESIDUE (the device reports +diff --git a/Documentation/usb/linux-cdc-acm.inf b/Documentation/usb/linux-cdc-acm.inf +index 612e722..37a02ce 100644 +--- a/Documentation/usb/linux-cdc-acm.inf ++++ b/Documentation/usb/linux-cdc-acm.inf +@@ -90,10 +90,10 @@ ServiceBinary=%12%\USBSER.sys + [SourceDisksFiles] + [SourceDisksNames] + [DeviceList] +-%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_0525&PID_A4AB&MI_02 ++%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02 + + [DeviceList.NTamd64] +-%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_0525&PID_A4AB&MI_02 ++%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02 + + + ;------------------------------------------------------------------------------ +diff --git a/Documentation/usb/linux.inf b/Documentation/usb/linux.inf +index 4dee958..4ffa715b0 100644 +--- a/Documentation/usb/linux.inf ++++ b/Documentation/usb/linux.inf +@@ -18,15 +18,15 @@ DriverVer = 06/21/2006,6.0.6000.16384 + + ; Decoration for x86 architecture + [LinuxDevices.NTx86] +-%LinuxDevice% = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_0525&PID_a4ab&MI_00 ++%LinuxDevice% = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_1d6b&PID_0104&MI_00 + + ; Decoration for x64 architecture + [LinuxDevices.NTamd64] +-%LinuxDevice% = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_0525&PID_a4ab&MI_00 ++%LinuxDevice% = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_1d6b&PID_0104&MI_00 + + ; Decoration for ia64 architecture + [LinuxDevices.NTia64] +-%LinuxDevice% = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_0525&PID_a4ab&MI_00 ++%LinuxDevice% = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_1d6b&PID_0104&MI_00 + + ;@@@ This is the common setting for setup + [ControlFlags] +diff --git a/Makefile b/Makefile +index 123d858..1b2a736 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + VERSION = 2 + PATCHLEVEL = 6 + SUBLEVEL = 39 +-EXTRAVERSION = ++EXTRAVERSION = .4 + NAME = Flesh-Eating Bats with Fangs + + # *DOCUMENTATION* +@@ -1374,7 +1374,7 @@ endif # KBUILD_EXTMOD + clean: $(clean-dirs) + $(call cmd,rmdirs) + $(call cmd,rmfiles) +- @find $(or $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ ++ @find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ + \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ + -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ + -o -name '*.symtypes' -o -name 'modules.order' \ +diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c +index 376f221..326f0a2 100644 +--- a/arch/alpha/kernel/osf_sys.c ++++ b/arch/alpha/kernel/osf_sys.c +@@ -409,7 +409,7 @@ SYSCALL_DEFINE2(osf_getdomainname, char __user *, name, int, namelen) + return -EFAULT; + + len = namelen; +- if (namelen > 32) ++ if (len > 32) + len = 32; + + down_read(&uts_sem); +@@ -594,7 +594,7 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count) + down_read(&uts_sem); + res = sysinfo_table[offset]; + len = strlen(res)+1; +- if (len > count) ++ if ((unsigned long)len > (unsigned long)count) + len = count; + if (copy_to_user(buf, res, len)) + err = -EFAULT; +@@ -649,7 +649,7 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer, + return 1; + + case GSI_GET_HWRPB: +- if (nbytes < sizeof(*hwrpb)) ++ if (nbytes > sizeof(*hwrpb)) + return -EINVAL; + if (copy_to_user(buffer, hwrpb, nbytes) != 0) + return -EFAULT; +@@ -1008,6 +1008,7 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options, + { + struct rusage r; + long ret, err; ++ unsigned int status = 0; + mm_segment_t old_fs; + + if (!ur) +@@ -1016,13 +1017,15 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options, + old_fs = get_fs(); + + set_fs (KERNEL_DS); +- ret = sys_wait4(pid, ustatus, options, (struct rusage __user *) &r); ++ ret = sys_wait4(pid, (unsigned int __user *) &status, options, ++ (struct rusage __user *) &r); + set_fs (old_fs); + + if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur))) + return -EFAULT; + + err = 0; ++ err |= put_user(status, ustatus); + err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec); + err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec); + err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec); +diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c +index 139e3c8..d284a30 100644 +--- a/arch/arm/kernel/perf_event.c ++++ b/arch/arm/kernel/perf_event.c +@@ -588,7 +588,7 @@ static int armpmu_event_init(struct perf_event *event) + static void armpmu_enable(struct pmu *pmu) + { + /* Enable all of the perf events on hardware. */ +- int idx; ++ int idx, enabled = 0; + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + + if (!armpmu) +@@ -601,9 +601,11 @@ static void armpmu_enable(struct pmu *pmu) + continue; + + armpmu->enable(&event->hw, idx); ++ enabled = 1; + } + +- armpmu->start(); ++ if (enabled) ++ armpmu->start(); + } + + static void armpmu_disable(struct pmu *pmu) +diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c +index c67f684..09a87e6 100644 +--- a/arch/arm/mach-davinci/board-dm365-evm.c ++++ b/arch/arm/mach-davinci/board-dm365-evm.c +@@ -520,7 +520,7 @@ fail: + */ + if (have_imager()) { + label = "HD imager"; +- mux |= 1; ++ mux |= 2; + + /* externally mux MMC1/ENET/AIC33 to imager */ + mux |= BIT(6) | BIT(5) | BIT(3); +@@ -540,7 +540,7 @@ fail: + resets &= ~BIT(1); + + if (have_tvp7002()) { +- mux |= 2; ++ mux |= 1; + resets &= ~BIT(2); + label = "tvp7002 HD"; + } else { +diff --git a/arch/arm/mach-exynos4/init.c b/arch/arm/mach-exynos4/init.c +index cf91f50..a8a83e3 100644 +--- a/arch/arm/mach-exynos4/init.c ++++ b/arch/arm/mach-exynos4/init.c +@@ -35,6 +35,7 @@ void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) + tcfg->clocks = exynos4_serial_clocks; + tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks); + } ++ tcfg->flags |= NO_NEED_CHECK_CLKSRC; + } + + s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); +diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c +index 72b4e76..ab9f999 100644 +--- a/arch/arm/mach-mmp/pxa168.c ++++ b/arch/arm/mach-mmp/pxa168.c +@@ -79,7 +79,7 @@ static APBC_CLK(ssp4, PXA168_SSP4, 4, 0); + static APBC_CLK(ssp5, PXA168_SSP5, 4, 0); + static APBC_CLK(keypad, PXA168_KPC, 0, 32000); + +-static APMU_CLK(nand, NAND, 0x01db, 208000000); ++static APMU_CLK(nand, NAND, 0x19b, 156000000); + static APMU_CLK(lcd, LCD, 0x7f, 312000000); + + /* device and clock bindings */ +diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c +index 8f92ccd..1464607 100644 +--- a/arch/arm/mach-mmp/pxa910.c ++++ b/arch/arm/mach-mmp/pxa910.c +@@ -110,7 +110,7 @@ static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000); + static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000); + static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000); + +-static APMU_CLK(nand, NAND, 0x01db, 208000000); ++static APMU_CLK(nand, NAND, 0x19b, 156000000); + static APMU_CLK(u2o, USB, 0x1b, 480000000); + + /* device and clock bindings */ +diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c +index 1d1419b..dfff1de 100644 +--- a/arch/arm/mach-pxa/mfp-pxa2xx.c ++++ b/arch/arm/mach-pxa/mfp-pxa2xx.c +@@ -347,9 +347,9 @@ static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state) + if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && + (GPDR(i) & GPIO_bit(i))) { + if (GPLR(i) & GPIO_bit(i)) +- PGSR(i) |= GPIO_bit(i); ++ PGSR(gpio_to_bank(i)) |= GPIO_bit(i); + else +- PGSR(i) &= ~GPIO_bit(i); ++ PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i); + } + } + +diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S +index c96fa1b..73b4a8b 100644 +--- a/arch/arm/mm/cache-v6.S ++++ b/arch/arm/mm/cache-v6.S +@@ -176,6 +176,7 @@ ENDPROC(v6_coherent_kern_range) + */ + ENTRY(v6_flush_kern_dcache_area) + add r1, r0, r1 ++ bic r0, r0, #D_CACHE_LINE_SIZE - 1 + 1: + #ifdef HARVARD_CACHE + mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line +diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S +index dc18d81..d32f02b 100644 +--- a/arch/arm/mm/cache-v7.S ++++ b/arch/arm/mm/cache-v7.S +@@ -221,6 +221,8 @@ ENDPROC(v7_coherent_user_range) + ENTRY(v7_flush_kern_dcache_area) + dcache_line_size r2, r3 + add r1, r0, r1 ++ sub r3, r2, #1 ++ bic r0, r0, r3 + 1: + mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line + add r0, r0, r2 +diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h +index 788837e9..d2ef07f 100644 +--- a/arch/arm/plat-samsung/include/plat/regs-serial.h ++++ b/arch/arm/plat-samsung/include/plat/regs-serial.h +@@ -224,6 +224,8 @@ + #define S5PV210_UFSTAT_RXMASK (255<<0) + #define S5PV210_UFSTAT_RXSHIFT (0) + ++#define NO_NEED_CHECK_CLKSRC 1 ++ + #ifndef __ASSEMBLY__ + + /* struct s3c24xx_uart_clksrc +diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S +index 9b8393d..c54cca87 100644 +--- a/arch/m68k/kernel/syscalltable.S ++++ b/arch/m68k/kernel/syscalltable.S +@@ -319,8 +319,8 @@ ENTRY(sys_call_table) + .long sys_readlinkat + .long sys_fchmodat + .long sys_faccessat /* 300 */ +- .long sys_ni_syscall /* Reserved for pselect6 */ +- .long sys_ni_syscall /* Reserved for ppoll */ ++ .long sys_pselect6 ++ .long sys_ppoll + .long sys_unshare + .long sys_set_robust_list + .long sys_get_robust_list /* 305 */ +diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h +index 3eb82c2a..9cbc2c3 100644 +--- a/arch/parisc/include/asm/unistd.h ++++ b/arch/parisc/include/asm/unistd.h +@@ -814,8 +814,14 @@ + #define __NR_recvmmsg (__NR_Linux + 319) + #define __NR_accept4 (__NR_Linux + 320) + #define __NR_prlimit64 (__NR_Linux + 321) +- +-#define __NR_Linux_syscalls (__NR_prlimit64 + 1) ++#define __NR_fanotify_init (__NR_Linux + 322) ++#define __NR_fanotify_mark (__NR_Linux + 323) ++#define __NR_clock_adjtime (__NR_Linux + 324) ++#define __NR_name_to_handle_at (__NR_Linux + 325) ++#define __NR_open_by_handle_at (__NR_Linux + 326) ++#define __NR_syncfs (__NR_Linux + 327) ++ ++#define __NR_Linux_syscalls (__NR_syncfs + 1) + + + #define __IGNORE_select /* newselect */ +diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c +index 88a0ad1..dc9a624 100644 +--- a/arch/parisc/kernel/sys_parisc32.c ++++ b/arch/parisc/kernel/sys_parisc32.c +@@ -228,3 +228,11 @@ asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, + return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, + ((loff_t)lenhi << 32) | lenlo); + } ++ ++asmlinkage long compat_sys_fanotify_mark(int fan_fd, int flags, u32 mask_hi, ++ u32 mask_lo, int fd, ++ const char __user *pathname) ++{ ++ return sys_fanotify_mark(fan_fd, flags, ((u64)mask_hi << 32) | mask_lo, ++ fd, pathname); ++} +diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S +index 4be85ee..a5b02ce 100644 +--- a/arch/parisc/kernel/syscall_table.S ++++ b/arch/parisc/kernel/syscall_table.S +@@ -420,6 +420,12 @@ + ENTRY_COMP(recvmmsg) + ENTRY_SAME(accept4) /* 320 */ + ENTRY_SAME(prlimit64) ++ ENTRY_SAME(fanotify_init) ++ ENTRY_COMP(fanotify_mark) ++ ENTRY_COMP(clock_adjtime) ++ ENTRY_SAME(name_to_handle_at) /* 325 */ ++ ENTRY_COMP(open_by_handle_at) ++ ENTRY_SAME(syncfs) + + /* Nothing yet */ + +diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c +index 5b5e1f0..c37ff6b 100644 +--- a/arch/powerpc/kernel/crash.c ++++ b/arch/powerpc/kernel/crash.c +@@ -170,7 +170,7 @@ static void crash_kexec_wait_realmode(int cpu) + int i; + + msecs = 10000; +- for (i=0; i < NR_CPUS && msecs > 0; i++) { ++ for (i=0; i < nr_cpu_ids && msecs > 0; i++) { + if (i == cpu) + continue; + +diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S +index c5c24be..727f40a 100644 +--- a/arch/powerpc/kernel/head_32.S ++++ b/arch/powerpc/kernel/head_32.S +@@ -896,7 +896,7 @@ _GLOBAL(start_secondary_resume) + rlwinm r1,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ + addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD + li r3,0 +- std r3,0(r1) /* Zero the stack frame pointer */ ++ stw r3,0(r1) /* Zero the stack frame pointer */ + bl start_secondary + b . + #endif /* CONFIG_SMP */ +diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S +index 206a321..e89df59 100644 +--- a/arch/powerpc/kernel/misc_64.S ++++ b/arch/powerpc/kernel/misc_64.S +@@ -462,7 +462,8 @@ _GLOBAL(disable_kernel_fp) + * wait for the flag to change, indicating this kernel is going away but + * the slave code for the next one is at addresses 0 to 100. + * +- * This is used by all slaves. ++ * This is used by all slaves, even those that did not find a matching ++ * paca in the secondary startup code. + * + * Physical (hardware) cpu id should be in r3. + */ +@@ -471,10 +472,6 @@ _GLOBAL(kexec_wait) + 1: mflr r5 + addi r5,r5,kexec_flag-1b + +- li r4,KEXEC_STATE_REAL_MODE +- stb r4,PACAKEXECSTATE(r13) +- SYNC +- + 99: HMT_LOW + #ifdef CONFIG_KEXEC /* use no memory without kexec */ + lwz r4,0(r5) +@@ -499,11 +496,17 @@ kexec_flag: + * + * get phys id from paca + * switch to real mode ++ * mark the paca as no longer used + * join other cpus in kexec_wait(phys_id) + */ + _GLOBAL(kexec_smp_wait) + lhz r3,PACAHWCPUID(r13) + bl real_mode ++ ++ li r4,KEXEC_STATE_REAL_MODE ++ stb r4,PACAKEXECSTATE(r13) ++ SYNC ++ + b .kexec_wait + + /* +diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c +index cbdbb14..f2dcab7 100644 +--- a/arch/powerpc/kernel/smp.c ++++ b/arch/powerpc/kernel/smp.c +@@ -410,8 +410,6 @@ int __cpuinit __cpu_up(unsigned int cpu) + { + int rc, c; + +- secondary_ti = current_set[cpu]; +- + if (smp_ops == NULL || + (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))) + return -EINVAL; +@@ -421,6 +419,8 @@ int __cpuinit __cpu_up(unsigned int cpu) + if (rc) + return rc; + ++ secondary_ti = current_set[cpu]; ++ + /* Make sure callin-map entry is 0 (can be leftover a CPU + * hotplug + */ +diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c +index 8ee51a2..e6bec74 100644 +--- a/arch/powerpc/oprofile/op_model_power4.c ++++ b/arch/powerpc/oprofile/op_model_power4.c +@@ -261,6 +261,28 @@ static int get_kernel(unsigned long pc, unsigned long mmcra) + return is_kernel; + } + ++static bool pmc_overflow(unsigned long val) ++{ ++ if ((int)val < 0) ++ return true; ++ ++ /* ++ * Events on POWER7 can roll back if a speculative event doesn't ++ * eventually complete. Unfortunately in some rare cases they will ++ * raise a performance monitor exception. We need to catch this to ++ * ensure we reset the PMC. In all cases the PMC will be 256 or less ++ * cycles from overflow. ++ * ++ * We only do this if the first pass fails to find any overflowing ++ * PMCs because a user might set a period of less than 256 and we ++ * don't want to mistakenly reset them. ++ */ ++ if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256)) ++ return true; ++ ++ return false; ++} ++ + static void power4_handle_interrupt(struct pt_regs *regs, + struct op_counter_config *ctr) + { +@@ -281,7 +303,7 @@ static void power4_handle_interrupt(struct pt_regs *regs, + + for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) { + val = classic_ctr_read(i); +- if (val < 0) { ++ if (pmc_overflow(val)) { + if (oprofile_running && ctr[i].enabled) { + oprofile_add_ext_sample(pc, regs, i, is_kernel); + classic_ctr_write(i, reset_value[i]); +diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile +index d49c213..ae95935 100644 +--- a/arch/sh/kernel/cpu/Makefile ++++ b/arch/sh/kernel/cpu/Makefile +@@ -17,7 +17,5 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/ + + obj-$(CONFIG_SH_ADC) += adc.o + obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o +-obj-$(CONFIG_SH_FPU) += fpu.o +-obj-$(CONFIG_SH_FPU_EMU) += fpu.o + +-obj-y += irq/ init.o clock.o hwblk.o proc.o ++obj-y += irq/ init.o clock.o fpu.o hwblk.o proc.o +diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c +index ea38f0c..1073269 100644 +--- a/arch/tile/kernel/pci.c ++++ b/arch/tile/kernel/pci.c +@@ -179,12 +179,6 @@ int __init tile_pci_init(void) + + controller = &controllers[num_controllers]; + +- if (tile_init_irqs(i, controller)) { +- pr_err("PCI: Could not initialize " +- "IRQs, aborting.\n"); +- goto err_cont; +- } +- + controller->index = num_controllers; + controller->hv_cfg_fd[0] = hv_cfg_fd0; + controller->hv_cfg_fd[1] = hv_cfg_fd1; +@@ -300,6 +294,11 @@ static int __init pcibios_init(void) + struct pci_controller *controller = &controllers[i]; + struct pci_bus *bus; + ++ if (tile_init_irqs(i, controller)) { ++ pr_err("PCI: Could not initialize IRQS\n"); ++ continue; ++ } ++ + pr_info("PCI: initializing controller #%d\n", i); + + /* +diff --git a/arch/um/Kconfig.x86 b/arch/um/Kconfig.x86 +index a9da516..795ea8e 100644 +--- a/arch/um/Kconfig.x86 ++++ b/arch/um/Kconfig.x86 +@@ -29,10 +29,10 @@ config X86_64 + def_bool 64BIT + + config RWSEM_XCHGADD_ALGORITHM +- def_bool X86_XADD ++ def_bool X86_XADD && 64BIT + + config RWSEM_GENERIC_SPINLOCK +- def_bool !X86_XADD ++ def_bool !RWSEM_XCHGADD_ALGORITHM + + config 3_LEVEL_PGTABLES + bool "Three-level pagetables (EXPERIMENTAL)" if !64BIT +diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h +index 91f3e087..cc5b052 100644 +--- a/arch/x86/include/asm/cpufeature.h ++++ b/arch/x86/include/asm/cpufeature.h +@@ -125,7 +125,7 @@ + #define X86_FEATURE_OSXSAVE (4*32+27) /* "" XSAVE enabled in the OS */ + #define X86_FEATURE_AVX (4*32+28) /* Advanced Vector Extensions */ + #define X86_FEATURE_F16C (4*32+29) /* 16-bit fp conversions */ +-#define X86_FEATURE_RDRND (4*32+30) /* The RDRAND instruction */ ++#define X86_FEATURE_RDRAND (4*32+30) /* The RDRAND instruction */ + #define X86_FEATURE_HYPERVISOR (4*32+31) /* Running on a hypervisor */ + + /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ +diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h +index 31d84ac..a518c0a 100644 +--- a/arch/x86/include/asm/pvclock.h ++++ b/arch/x86/include/asm/pvclock.h +@@ -22,6 +22,8 @@ static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift) + u64 product; + #ifdef __i386__ + u32 tmp1, tmp2; ++#else ++ ulong tmp; + #endif + + if (shift < 0) +@@ -42,8 +44,11 @@ static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift) + : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); + #elif defined(__x86_64__) + __asm__ ( +- "mul %%rdx ; shrd $32,%%rdx,%%rax" +- : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) ); ++ "mul %[mul_frac] ; shrd $32, %[hi], %[lo]" ++ : [lo]"=a"(product), ++ [hi]"=d"(tmp) ++ : "0"(delta), ++ [mul_frac]"rm"((u64)mul_frac)); + #else + #error implement me! + #endif +diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h +index abd3e0e..99f0ad7 100644 +--- a/arch/x86/include/asm/uaccess.h ++++ b/arch/x86/include/asm/uaccess.h +@@ -42,7 +42,7 @@ + * Returns 0 if the range is valid, nonzero otherwise. + * + * This is equivalent to the following test: +- * (u33)addr + (u33)size >= (u33)current->addr_limit.seg (u65 for x86_64) ++ * (u33)addr + (u33)size > (u33)current->addr_limit.seg (u65 for x86_64) + * + * This needs 33-bit (65-bit for x86_64) arithmetic. We have a carry... + */ +diff --git a/arch/x86/kernel/acpi/realmode/wakeup.S b/arch/x86/kernel/acpi/realmode/wakeup.S +index ead21b6..b4fd836 100644 +--- a/arch/x86/kernel/acpi/realmode/wakeup.S ++++ b/arch/x86/kernel/acpi/realmode/wakeup.S +@@ -28,6 +28,8 @@ pmode_cr3: .long 0 /* Saved %cr3 */ + pmode_cr4: .long 0 /* Saved %cr4 */ + pmode_efer: .quad 0 /* Saved EFER */ + pmode_gdt: .quad 0 ++pmode_misc_en: .quad 0 /* Saved MISC_ENABLE MSR */ ++pmode_behavior: .long 0 /* Wakeup behavior flags */ + realmode_flags: .long 0 + real_magic: .long 0 + trampoline_segment: .word 0 +@@ -91,6 +93,18 @@ wakeup_code: + /* Call the C code */ + calll main + ++ /* Restore MISC_ENABLE before entering protected mode, in case ++ BIOS decided to clear XD_DISABLE during S3. */ ++ movl pmode_behavior, %eax ++ btl $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %eax ++ jnc 1f ++ ++ movl pmode_misc_en, %eax ++ movl pmode_misc_en + 4, %edx ++ movl $MSR_IA32_MISC_ENABLE, %ecx ++ wrmsr ++1: ++ + /* Do any other stuff... */ + + #ifndef CONFIG_64BIT +diff --git a/arch/x86/kernel/acpi/realmode/wakeup.h b/arch/x86/kernel/acpi/realmode/wakeup.h +index e1828c0..97a29e1 100644 +--- a/arch/x86/kernel/acpi/realmode/wakeup.h ++++ b/arch/x86/kernel/acpi/realmode/wakeup.h +@@ -21,6 +21,9 @@ struct wakeup_header { + u32 pmode_efer_low; /* Protected mode EFER */ + u32 pmode_efer_high; + u64 pmode_gdt; ++ u32 pmode_misc_en_low; /* Protected mode MISC_ENABLE */ ++ u32 pmode_misc_en_high; ++ u32 pmode_behavior; /* Wakeup routine behavior flags */ + u32 realmode_flags; + u32 real_magic; + u16 trampoline_segment; /* segment with trampoline code, 64-bit only */ +@@ -39,4 +42,7 @@ extern struct wakeup_header wakeup_header; + #define WAKEUP_HEADER_SIGNATURE 0x51ee1111 + #define WAKEUP_END_SIGNATURE 0x65a22c82 + ++/* Wakeup behavior bits */ ++#define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0 ++ + #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ +diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c +index ff93bc1..cdddffc 100644 +--- a/arch/x86/kernel/acpi/sleep.c ++++ b/arch/x86/kernel/acpi/sleep.c +@@ -77,6 +77,12 @@ int acpi_suspend_lowlevel(void) + + header->pmode_cr0 = read_cr0(); + header->pmode_cr4 = read_cr4_safe(); ++ header->pmode_behavior = 0; ++ if (!rdmsr_safe(MSR_IA32_MISC_ENABLE, ++ &header->pmode_misc_en_low, ++ &header->pmode_misc_en_high)) ++ header->pmode_behavior |= ++ (1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE); + header->realmode_flags = acpi_realmode_flags; + header->real_magic = 0x12345678; + +diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c +index 57ca777..e7115c8 100644 +--- a/arch/x86/kernel/amd_iommu.c ++++ b/arch/x86/kernel/amd_iommu.c +@@ -28,6 +28,7 @@ + #include <asm/proto.h> + #include <asm/iommu.h> + #include <asm/gart.h> ++#include <asm/dma.h> + #include <asm/amd_iommu_proto.h> + #include <asm/amd_iommu_types.h> + #include <asm/amd_iommu.h> +@@ -153,6 +154,10 @@ static int iommu_init_device(struct device *dev) + pdev = pci_get_bus_and_slot(PCI_BUS(alias), alias & 0xff); + if (pdev) + dev_data->alias = &pdev->dev; ++ else { ++ kfree(dev_data); ++ return -ENOTSUPP; ++ } + + atomic_set(&dev_data->bind, 0); + +@@ -162,6 +167,20 @@ static int iommu_init_device(struct device *dev) + return 0; + } + ++static void iommu_ignore_device(struct device *dev) ++{ ++ u16 devid, alias; ++ ++ devid = get_device_id(dev); ++ alias = amd_iommu_alias_table[devid]; ++ ++ memset(&amd_iommu_dev_table[devid], 0, sizeof(struct dev_table_entry)); ++ memset(&amd_iommu_dev_table[alias], 0, sizeof(struct dev_table_entry)); ++ ++ amd_iommu_rlookup_table[devid] = NULL; ++ amd_iommu_rlookup_table[alias] = NULL; ++} ++ + static void iommu_uninit_device(struct device *dev) + { + kfree(dev->archdata.iommu); +@@ -191,7 +210,9 @@ int __init amd_iommu_init_devices(void) + continue; + + ret = iommu_init_device(&pdev->dev); +- if (ret) ++ if (ret == -ENOTSUPP) ++ iommu_ignore_device(&pdev->dev); ++ else if (ret) + goto out_free; + } + +@@ -2296,6 +2317,23 @@ static struct dma_map_ops amd_iommu_dma_ops = { + .dma_supported = amd_iommu_dma_supported, + }; + ++static unsigned device_dma_ops_init(void) ++{ ++ struct pci_dev *pdev = NULL; ++ unsigned unhandled = 0; ++ ++ for_each_pci_dev(pdev) { ++ if (!check_device(&pdev->dev)) { ++ unhandled += 1; ++ continue; ++ } ++ ++ pdev->dev.archdata.dma_ops = &amd_iommu_dma_ops; ++ } ++ ++ return unhandled; ++} ++ + /* + * The function which clues the AMD IOMMU driver into dma_ops. + */ +@@ -2308,7 +2346,7 @@ void __init amd_iommu_init_api(void) + int __init amd_iommu_init_dma_ops(void) + { + struct amd_iommu *iommu; +- int ret; ++ int ret, unhandled; + + /* + * first allocate a default protection domain for every IOMMU we +@@ -2334,7 +2372,11 @@ int __init amd_iommu_init_dma_ops(void) + swiotlb = 0; + + /* Make the driver finally visible to the drivers */ +- dma_ops = &amd_iommu_dma_ops; ++ unhandled = device_dma_ops_init(); ++ if (unhandled && max_pfn > MAX_DMA32_PFN) { ++ /* There are unhandled devices - initialize swiotlb for them */ ++ swiotlb = 1; ++ } + + amd_iommu_stats_init(); + +diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c +index 246d727..b9e207e 100644 +--- a/arch/x86/kernel/amd_iommu_init.c ++++ b/arch/x86/kernel/amd_iommu_init.c +@@ -701,8 +701,8 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu, + { + u8 *p = (u8 *)h; + u8 *end = p, flags = 0; +- u16 dev_i, devid = 0, devid_start = 0, devid_to = 0; +- u32 ext_flags = 0; ++ u16 devid = 0, devid_start = 0, devid_to = 0; ++ u32 dev_i, ext_flags = 0; + bool alias = false; + struct ivhd_entry *e; + +@@ -857,7 +857,7 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu, + /* Initializes the device->iommu mapping for the driver */ + static int __init init_iommu_devices(struct amd_iommu *iommu) + { +- u16 i; ++ u32 i; + + for (i = iommu->first_device; i <= iommu->last_device; ++i) + set_iommu_for_device(iommu, i); +@@ -1146,7 +1146,7 @@ static int __init init_memory_definitions(struct acpi_table_header *table) + */ + static void init_device_table(void) + { +- u16 devid; ++ u32 devid; + + for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) { + set_dev_entry_bit(devid, DEV_ENTRY_VALID); +diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c +index 45fd33d..df63620 100644 +--- a/arch/x86/kernel/apic/io_apic.c ++++ b/arch/x86/kernel/apic/io_apic.c +@@ -621,14 +621,14 @@ struct IO_APIC_route_entry **alloc_ioapic_entries(void) + struct IO_APIC_route_entry **ioapic_entries; + + ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics, +- GFP_KERNEL); ++ GFP_ATOMIC); + if (!ioapic_entries) + return 0; + + for (apic = 0; apic < nr_ioapics; apic++) { + ioapic_entries[apic] = + kzalloc(sizeof(struct IO_APIC_route_entry) * +- nr_ioapic_registers[apic], GFP_KERNEL); ++ nr_ioapic_registers[apic], GFP_ATOMIC); + if (!ioapic_entries[apic]) + goto nomem; + } +diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c +index 6f9d1f6..b13ed39 100644 +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -612,8 +612,11 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) + } + #endif + +- /* As a rule processors have APIC timer running in deep C states */ +- if (c->x86 > 0xf && !cpu_has_amd_erratum(amd_erratum_400)) ++ /* ++ * Family 0x12 and above processors have APIC timer ++ * running in deep C states. ++ */ ++ if (c->x86 > 0x11) + set_cpu_cap(c, X86_FEATURE_ARAT); + + /* +@@ -629,10 +632,13 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) + * Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=33012 + */ + u64 mask; ++ int err; + +- rdmsrl(MSR_AMD64_MCx_MASK(4), mask); +- mask |= (1 << 10); +- wrmsrl(MSR_AMD64_MCx_MASK(4), mask); ++ err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask); ++ if (err == 0) { ++ mask |= (1 << 10); ++ checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask); ++ } + } + } + +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index e2ced00..173f3a3 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -565,8 +565,7 @@ void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) + + cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx); + +- if (eax > 0) +- c->x86_capability[9] = ebx; ++ c->x86_capability[9] = ebx; + } + + /* AMD-defined flags: level 0x80000001 */ +diff --git a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c +index 755a31e..907c8e6 100644 +--- a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c ++++ b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c +@@ -39,7 +39,7 @@ + + #include <acpi/processor.h> + +-#define PCC_VERSION "1.00.00" ++#define PCC_VERSION "1.10.00" + #define POLL_LOOPS 300 + + #define CMD_COMPLETE 0x1 +@@ -102,7 +102,7 @@ static struct acpi_generic_address doorbell; + static u64 doorbell_preserve; + static u64 doorbell_write; + +-static u8 OSC_UUID[16] = {0x63, 0x9B, 0x2C, 0x9F, 0x70, 0x91, 0x49, 0x1f, ++static u8 OSC_UUID[16] = {0x9F, 0x2C, 0x9B, 0x63, 0x91, 0x70, 0x1f, 0x49, + 0xBB, 0x4F, 0xA5, 0x98, 0x2F, 0xA1, 0xB5, 0x46}; + + struct pcc_cpu { +diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c +index e90f084..bea9c03 100644 +--- a/arch/x86/kernel/devicetree.c ++++ b/arch/x86/kernel/devicetree.c +@@ -13,6 +13,7 @@ + #include <linux/slab.h> + #include <linux/pci.h> + #include <linux/of_pci.h> ++#include <linux/initrd.h> + + #include <asm/hpet.h> + #include <asm/irq_controller.h> +@@ -98,6 +99,16 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) + return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); + } + ++#ifdef CONFIG_BLK_DEV_INITRD ++void __init early_init_dt_setup_initrd_arch(unsigned long start, ++ unsigned long end) ++{ ++ initrd_start = (unsigned long)__va(start); ++ initrd_end = (unsigned long)__va(end); ++ initrd_below_start_ok = 1; ++} ++#endif ++ + void __init add_dtb(u64 data) + { + initial_dtb = data + offsetof(struct setup_data, data); +diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c +index 8d12878..a3d0dc5 100644 +--- a/arch/x86/kernel/process_32.c ++++ b/arch/x86/kernel/process_32.c +@@ -245,7 +245,6 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) + { + set_user_gs(regs, 0); + regs->fs = 0; +- set_fs(USER_DS); + regs->ds = __USER_DS; + regs->es = __USER_DS; + regs->ss = __USER_DS; +diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c +index 6c9dd92..ca6f7ab 100644 +--- a/arch/x86/kernel/process_64.c ++++ b/arch/x86/kernel/process_64.c +@@ -338,7 +338,6 @@ start_thread_common(struct pt_regs *regs, unsigned long new_ip, + regs->cs = _cs; + regs->ss = _ss; + regs->flags = X86_EFLAGS_IF; +- set_fs(USER_DS); + /* + * Free the old FP and other extended state + */ +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index 08c44b0..1def278 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -411,6 +411,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"), + }, + }, ++ { /* Handle problems with rebooting on the Latitude E5420. */ ++ .callback = set_pci_reboot, ++ .ident = "Dell Latitude E5420", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5420"), ++ }, ++ }, + { } + }; + +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index c2871d3..c58d144 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -285,6 +285,19 @@ notrace static void __cpuinit start_secondary(void *unused) + per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; + x86_platform.nmi_init(); + ++ /* ++ * Wait until the cpu which brought this one up marked it ++ * online before enabling interrupts. If we don't do that then ++ * we can end up waking up the softirq thread before this cpu ++ * reached the active state, which makes the scheduler unhappy ++ * and schedule the softirq thread on the wrong cpu. This is ++ * only observable with forced threaded interrupts, but in ++ * theory it could also happen w/o them. It's just way harder ++ * to achieve. ++ */ ++ while (!cpumask_test_cpu(smp_processor_id(), cpu_active_mask)) ++ cpu_relax(); ++ + /* enable local interrupts */ + local_irq_enable(); + +diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c +index 1cd6089..493ea1f 100644 +--- a/arch/x86/lguest/boot.c ++++ b/arch/x86/lguest/boot.c +@@ -995,6 +995,7 @@ static void lguest_time_irq(unsigned int irq, struct irq_desc *desc) + static void lguest_time_init(void) + { + /* Set up the timer interrupt (0) to go to our simple timer routine */ ++ lguest_setup_irq(0); + irq_set_handler(0, lguest_time_irq); + + clocksource_register(&lguest_clock); +diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S +index 99e4826..a73397f 100644 +--- a/arch/x86/lib/copy_user_64.S ++++ b/arch/x86/lib/copy_user_64.S +@@ -72,7 +72,7 @@ ENTRY(_copy_to_user) + addq %rdx,%rcx + jc bad_to_user + cmpq TI_addr_limit(%rax),%rcx +- jae bad_to_user ++ ja bad_to_user + ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string + CFI_ENDPROC + ENDPROC(_copy_to_user) +@@ -85,7 +85,7 @@ ENTRY(_copy_from_user) + addq %rdx,%rcx + jc bad_from_user + cmpq TI_addr_limit(%rax),%rcx +- jae bad_from_user ++ ja bad_from_user + ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string + CFI_ENDPROC + ENDPROC(_copy_from_user) +diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c +index cf97500..68894fd 100644 +--- a/arch/x86/oprofile/nmi_int.c ++++ b/arch/x86/oprofile/nmi_int.c +@@ -112,8 +112,10 @@ static void nmi_cpu_start(void *dummy) + static int nmi_start(void) + { + get_online_cpus(); +- on_each_cpu(nmi_cpu_start, NULL, 1); + ctr_running = 1; ++ /* make ctr_running visible to the nmi handler: */ ++ smp_mb(); ++ on_each_cpu(nmi_cpu_start, NULL, 1); + put_online_cpus(); + return 0; + } +@@ -504,15 +506,18 @@ static int nmi_setup(void) + + nmi_enabled = 0; + ctr_running = 0; +- barrier(); ++ /* make variables visible to the nmi handler: */ ++ smp_mb(); + err = register_die_notifier(&profile_exceptions_nb); + if (err) + goto fail; + + get_online_cpus(); + register_cpu_notifier(&oprofile_cpu_nb); +- on_each_cpu(nmi_cpu_setup, NULL, 1); + nmi_enabled = 1; ++ /* make nmi_enabled visible to the nmi handler: */ ++ smp_mb(); ++ on_each_cpu(nmi_cpu_setup, NULL, 1); + put_online_cpus(); + + return 0; +@@ -531,7 +536,8 @@ static void nmi_shutdown(void) + nmi_enabled = 0; + ctr_running = 0; + put_online_cpus(); +- barrier(); ++ /* make variables visible to the nmi handler: */ ++ smp_mb(); + unregister_die_notifier(&profile_exceptions_nb); + msrs = &get_cpu_var(cpu_msrs); + model->shutdown(msrs); +diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c +index c3b8e24..9fd8a56 100644 +--- a/arch/x86/oprofile/op_model_amd.c ++++ b/arch/x86/oprofile/op_model_amd.c +@@ -316,16 +316,23 @@ static void op_amd_stop_ibs(void) + wrmsrl(MSR_AMD64_IBSOPCTL, 0); + } + +-static inline int eilvt_is_available(int offset) ++static inline int get_eilvt(int offset) + { +- /* check if we may assign a vector */ + return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1); + } + ++static inline int put_eilvt(int offset) ++{ ++ return !setup_APIC_eilvt(offset, 0, 0, 1); ++} ++ + static inline int ibs_eilvt_valid(void) + { + int offset; + u64 val; ++ int valid = 0; ++ ++ preempt_disable(); + + rdmsrl(MSR_AMD64_IBSCTL, val); + offset = val & IBSCTL_LVT_OFFSET_MASK; +@@ -333,16 +340,20 @@ static inline int ibs_eilvt_valid(void) + if (!(val & IBSCTL_LVT_OFFSET_VALID)) { + pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n", + smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); +- return 0; ++ goto out; + } + +- if (!eilvt_is_available(offset)) { ++ if (!get_eilvt(offset)) { + pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n", + smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); +- return 0; ++ goto out; + } + +- return 1; ++ valid = 1; ++out: ++ preempt_enable(); ++ ++ return valid; + } + + static inline int get_ibs_offset(void) +@@ -600,67 +611,69 @@ static int setup_ibs_ctl(int ibs_eilvt_off) + + static int force_ibs_eilvt_setup(void) + { +- int i; ++ int offset; + int ret; + +- /* find the next free available EILVT entry */ +- for (i = 1; i < 4; i++) { +- if (!eilvt_is_available(i)) +- continue; +- ret = setup_ibs_ctl(i); +- if (ret) +- return ret; +- pr_err(FW_BUG "using offset %d for IBS interrupts\n", i); +- return 0; ++ /* ++ * find the next free available EILVT entry, skip offset 0, ++ * pin search to this cpu ++ */ ++ preempt_disable(); ++ for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) { ++ if (get_eilvt(offset)) ++ break; + } ++ preempt_enable(); + +- printk(KERN_DEBUG "No EILVT entry available\n"); +- +- return -EBUSY; +-} +- +-static int __init_ibs_nmi(void) +-{ +- int ret; +- +- if (ibs_eilvt_valid()) +- return 0; ++ if (offset == APIC_EILVT_NR_MAX) { ++ printk(KERN_DEBUG "No EILVT entry available\n"); ++ return -EBUSY; ++ } + +- ret = force_ibs_eilvt_setup(); ++ ret = setup_ibs_ctl(offset); + if (ret) +- return ret; ++ goto out; + +- if (!ibs_eilvt_valid()) +- return -EFAULT; ++ if (!ibs_eilvt_valid()) { ++ ret = -EFAULT; ++ goto out; ++ } + ++ pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset); + pr_err(FW_BUG "workaround enabled for IBS LVT offset\n"); + + return 0; ++out: ++ preempt_disable(); ++ put_eilvt(offset); ++ preempt_enable(); ++ return ret; + } + + /* + * check and reserve APIC extended interrupt LVT offset for IBS if + * available +- * +- * init_ibs() preforms implicitly cpu-local operations, so pin this +- * thread to its current CPU + */ + + static void init_ibs(void) + { +- preempt_disable(); +- + ibs_caps = get_ibs_caps(); ++ + if (!ibs_caps) ++ return; ++ ++ if (ibs_eilvt_valid()) + goto out; + +- if (__init_ibs_nmi() < 0) +- ibs_caps = 0; +- else +- printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); ++ if (!force_ibs_eilvt_setup()) ++ goto out; ++ ++ /* Failed to setup ibs */ ++ ibs_caps = 0; ++ return; + + out: +- preempt_enable(); ++ printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); + } + + static int (*create_arch_files)(struct super_block *sb, struct dentry *root); +diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c +index e37b407..632ba33 100644 +--- a/arch/x86/pci/xen.c ++++ b/arch/x86/pci/xen.c +@@ -316,7 +316,7 @@ int __init pci_xen_hvm_init(void) + } + + #ifdef CONFIG_XEN_DOM0 +-static int xen_register_pirq(u32 gsi, int triggering) ++static int xen_register_pirq(u32 gsi, int gsi_override, int triggering) + { + int rc, pirq, irq = -1; + struct physdev_map_pirq map_irq; +@@ -333,16 +333,18 @@ static int xen_register_pirq(u32 gsi, int triggering) + shareable = 1; + name = "ioapic-level"; + } +- + pirq = xen_allocate_pirq_gsi(gsi); + if (pirq < 0) + goto out; + +- irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); ++ if (gsi_override >= 0) ++ irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name); ++ else ++ irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); + if (irq < 0) + goto out; + +- printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d\n", pirq, irq); ++ printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi); + + map_irq.domid = DOMID_SELF; + map_irq.type = MAP_PIRQ_TYPE_GSI; +@@ -359,7 +361,7 @@ out: + return irq; + } + +-static int xen_register_gsi(u32 gsi, int triggering, int polarity) ++static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity) + { + int rc, irq; + struct physdev_setup_gsi setup_gsi; +@@ -370,7 +372,7 @@ static int xen_register_gsi(u32 gsi, int triggering, int polarity) + printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", + gsi, triggering, polarity); + +- irq = xen_register_pirq(gsi, triggering); ++ irq = xen_register_pirq(gsi, gsi_override, triggering); + + setup_gsi.gsi = gsi; + setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); +@@ -392,6 +394,8 @@ static __init void xen_setup_acpi_sci(void) + int rc; + int trigger, polarity; + int gsi = acpi_sci_override_gsi; ++ int irq = -1; ++ int gsi_override = -1; + + if (!gsi) + return; +@@ -408,7 +412,25 @@ static __init void xen_setup_acpi_sci(void) + printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " + "polarity=%d\n", gsi, trigger, polarity); + +- gsi = xen_register_gsi(gsi, trigger, polarity); ++ /* Before we bind the GSI to a Linux IRQ, check whether ++ * we need to override it with bus_irq (IRQ) value. Usually for ++ * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: ++ * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) ++ * but there are oddballs where the IRQ != GSI: ++ * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) ++ * which ends up being: gsi_to_irq[9] == 20 ++ * (which is what acpi_gsi_to_irq ends up calling when starting the ++ * the ACPI interpreter and keels over since IRQ 9 has not been ++ * setup as we had setup IRQ 20 for it). ++ */ ++ /* Check whether the GSI != IRQ */ ++ if (acpi_gsi_to_irq(gsi, &irq) == 0) { ++ if (irq >= 0 && irq != gsi) ++ /* Bugger, we MUST have that IRQ. */ ++ gsi_override = irq; ++ } ++ ++ gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity); + printk(KERN_INFO "xen: acpi sci %d\n", gsi); + + return; +@@ -417,7 +439,7 @@ static __init void xen_setup_acpi_sci(void) + static int acpi_register_gsi_xen(struct device *dev, u32 gsi, + int trigger, int polarity) + { +- return xen_register_gsi(gsi, trigger, polarity); ++ return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity); + } + + static int __init pci_xen_initial_domain(void) +@@ -456,7 +478,7 @@ void __init xen_setup_pirqs(void) + if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) + continue; + +- xen_register_pirq(irq, ++ xen_register_pirq(irq, -1 /* no GSI override */, + trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); + } + } +diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c +index 0684f3c..0d668d1 100644 +--- a/arch/x86/xen/mmu.c ++++ b/arch/x86/xen/mmu.c +@@ -59,6 +59,7 @@ + #include <asm/page.h> + #include <asm/init.h> + #include <asm/pat.h> ++#include <asm/smp.h> + + #include <asm/xen/hypercall.h> + #include <asm/xen/hypervisor.h> +@@ -1187,7 +1188,7 @@ static void drop_other_mm_ref(void *info) + + active_mm = percpu_read(cpu_tlbstate.active_mm); + +- if (active_mm == mm) ++ if (active_mm == mm && percpu_read(cpu_tlbstate.state) != TLBSTATE_OK) + leave_mm(smp_processor_id()); + + /* If this cpu still has a stale cr3 reference, then make sure +@@ -1353,7 +1354,11 @@ static void xen_flush_tlb_others(const struct cpumask *cpus, + { + struct { + struct mmuext_op op; ++#ifdef CONFIG_SMP ++ DECLARE_BITMAP(mask, num_processors); ++#else + DECLARE_BITMAP(mask, NR_CPUS); ++#endif + } *args; + struct multicall_space mcs; + +@@ -1721,6 +1726,11 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) + for (pteidx = 0; pteidx < PTRS_PER_PTE; pteidx++, pfn++) { + pte_t pte; + ++#ifdef CONFIG_X86_32 ++ if (pfn > max_pfn_mapped) ++ max_pfn_mapped = pfn; ++#endif ++ + if (!pte_none(pte_page[pteidx])) + continue; + +@@ -1888,7 +1898,9 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, + initial_kernel_pmd = + extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE); + +- max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->mfn_list)); ++ max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) + ++ xen_start_info->nr_pt_frames * PAGE_SIZE + ++ 512*1024); + + kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd); + memcpy(initial_kernel_pmd, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD); +diff --git a/arch/x86/xen/multicalls.c b/arch/x86/xen/multicalls.c +index 8bff7e7..1b2b73f 100644 +--- a/arch/x86/xen/multicalls.c ++++ b/arch/x86/xen/multicalls.c +@@ -189,10 +189,10 @@ struct multicall_space __xen_mc_entry(size_t args) + unsigned argidx = roundup(b->argidx, sizeof(u64)); + + BUG_ON(preemptible()); +- BUG_ON(b->argidx > MC_ARGS); ++ BUG_ON(b->argidx >= MC_ARGS); + + if (b->mcidx == MC_BATCH || +- (argidx + args) > MC_ARGS) { ++ (argidx + args) >= MC_ARGS) { + mc_stats_flush(b->mcidx == MC_BATCH ? FL_SLOTS : FL_ARGS); + xen_mc_flush(); + argidx = roundup(b->argidx, sizeof(u64)); +@@ -206,7 +206,7 @@ struct multicall_space __xen_mc_entry(size_t args) + ret.args = &b->args[argidx]; + b->argidx = argidx + args; + +- BUG_ON(b->argidx > MC_ARGS); ++ BUG_ON(b->argidx >= MC_ARGS); + return ret; + } + +@@ -216,7 +216,7 @@ struct multicall_space xen_mc_extend_args(unsigned long op, size_t size) + struct multicall_space ret = { NULL, NULL }; + + BUG_ON(preemptible()); +- BUG_ON(b->argidx > MC_ARGS); ++ BUG_ON(b->argidx >= MC_ARGS); + + if (b->mcidx == 0) + return ret; +@@ -224,14 +224,14 @@ struct multicall_space xen_mc_extend_args(unsigned long op, size_t size) + if (b->entries[b->mcidx - 1].op != op) + return ret; + +- if ((b->argidx + size) > MC_ARGS) ++ if ((b->argidx + size) >= MC_ARGS) + return ret; + + ret.mc = &b->entries[b->mcidx - 1]; + ret.args = &b->args[b->argidx]; + b->argidx += size; + +- BUG_ON(b->argidx > MC_ARGS); ++ BUG_ON(b->argidx >= MC_ARGS); + return ret; + } + +diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c +index 141eb0d..c881ae4 100644 +--- a/arch/x86/xen/p2m.c ++++ b/arch/x86/xen/p2m.c +@@ -522,11 +522,20 @@ static bool __init __early_alloc_p2m(unsigned long pfn) + /* Boundary cross-over for the edges: */ + if (idx) { + unsigned long *p2m = extend_brk(PAGE_SIZE, PAGE_SIZE); ++ unsigned long *mid_mfn_p; + + p2m_init(p2m); + + p2m_top[topidx][mididx] = p2m; + ++ /* For save/restore we need to MFN of the P2M saved */ ++ ++ mid_mfn_p = p2m_top_mfn_p[topidx]; ++ WARN(mid_mfn_p[mididx] != virt_to_mfn(p2m_missing), ++ "P2M_TOP_P[%d][%d] != MFN of p2m_missing!\n", ++ topidx, mididx); ++ mid_mfn_p[mididx] = virt_to_mfn(p2m); ++ + } + return idx != 0; + } +@@ -549,12 +558,29 @@ unsigned long __init set_phys_range_identity(unsigned long pfn_s, + pfn += P2M_MID_PER_PAGE * P2M_PER_PAGE) + { + unsigned topidx = p2m_top_index(pfn); +- if (p2m_top[topidx] == p2m_mid_missing) { +- unsigned long **mid = extend_brk(PAGE_SIZE, PAGE_SIZE); ++ unsigned long *mid_mfn_p; ++ unsigned long **mid; ++ ++ mid = p2m_top[topidx]; ++ mid_mfn_p = p2m_top_mfn_p[topidx]; ++ if (mid == p2m_mid_missing) { ++ mid = extend_brk(PAGE_SIZE, PAGE_SIZE); + + p2m_mid_init(mid); + + p2m_top[topidx] = mid; ++ ++ BUG_ON(mid_mfn_p != p2m_mid_missing_mfn); ++ } ++ /* And the save/restore P2M tables.. */ ++ if (mid_mfn_p == p2m_mid_missing_mfn) { ++ mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE); ++ p2m_mid_mfn_init(mid_mfn_p); ++ ++ p2m_top_mfn_p[topidx] = mid_mfn_p; ++ p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p); ++ /* Note: we don't set mid_mfn_p[midix] here, ++ * look in __early_alloc_p2m */ + } + } + +diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c +index 90bac0a..ca6297b 100644 +--- a/arch/x86/xen/setup.c ++++ b/arch/x86/xen/setup.c +@@ -166,7 +166,7 @@ static unsigned long __init xen_set_identity(const struct e820entry *list, + if (last > end) + continue; + +- if (entry->type == E820_RAM) { ++ if ((entry->type == E820_RAM) || (entry->type == E820_UNUSABLE)) { + if (start > start_pci) + identity += set_phys_range_identity( + PFN_UP(start_pci), PFN_DOWN(start)); +@@ -227,7 +227,11 @@ char * __init xen_memory_setup(void) + + memcpy(map_raw, map, sizeof(map)); + e820.nr_map = 0; ++#ifdef CONFIG_X86_32 ++ xen_extra_mem_start = mem_end; ++#else + xen_extra_mem_start = max((1ULL << 32), mem_end); ++#endif + for (i = 0; i < memmap.nr_entries; i++) { + unsigned long long end; + +diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c +index 3061244..ae49046 100644 +--- a/arch/x86/xen/smp.c ++++ b/arch/x86/xen/smp.c +@@ -206,11 +206,18 @@ static void __init xen_smp_prepare_boot_cpu(void) + static void __init xen_smp_prepare_cpus(unsigned int max_cpus) + { + unsigned cpu; ++ unsigned int i; + + xen_init_lock_cpu(0); + + smp_store_cpu_info(0); + cpu_data(0).x86_max_cores = 1; ++ ++ for_each_possible_cpu(i) { ++ zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL); ++ zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL); ++ zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL); ++ } + set_cpu_sibling_map(0); + + if (xen_smp_intr_init(0)) +diff --git a/block/blk-core.c b/block/blk-core.c +index 3fe00a1..5323076 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -345,6 +345,7 @@ void blk_put_queue(struct request_queue *q) + { + kobject_put(&q->kobj); + } ++EXPORT_SYMBOL(blk_put_queue); + + /* + * Note: If a driver supplied the queue lock, it should not zap that lock +@@ -566,6 +567,7 @@ int blk_get_queue(struct request_queue *q) + + return 1; + } ++EXPORT_SYMBOL(blk_get_queue); + + static inline void blk_free_request(struct request_queue *q, struct request *rq) + { +diff --git a/block/blk-flush.c b/block/blk-flush.c +index 6c9b5e1..bb21e4c 100644 +--- a/block/blk-flush.c ++++ b/block/blk-flush.c +@@ -212,13 +212,19 @@ static void flush_end_io(struct request *flush_rq, int error) + } + + /* +- * Moving a request silently to empty queue_head may stall the +- * queue. Kick the queue in those cases. This function is called +- * from request completion path and calling directly into +- * request_fn may confuse the driver. Always use kblockd. ++ * Kick the queue to avoid stall for two cases: ++ * 1. Moving a request silently to empty queue_head may stall the ++ * queue. ++ * 2. When flush request is running in non-queueable queue, the ++ * queue is hold. Restart the queue after flush request is finished ++ * to avoid stall. ++ * This function is called from request completion path and calling ++ * directly into request_fn may confuse the driver. Always use ++ * kblockd. + */ +- if (queued) ++ if (queued || q->flush_queue_delayed) + blk_run_queue_async(q); ++ q->flush_queue_delayed = 0; + } + + /** +diff --git a/block/blk-settings.c b/block/blk-settings.c +index 1fa7692..fa1eb04 100644 +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -120,7 +120,7 @@ void blk_set_default_limits(struct queue_limits *lim) + lim->discard_granularity = 0; + lim->discard_alignment = 0; + lim->discard_misaligned = 0; +- lim->discard_zeroes_data = -1; ++ lim->discard_zeroes_data = 1; + lim->logical_block_size = lim->physical_block_size = lim->io_min = 512; + lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT); + lim->alignment_offset = 0; +@@ -166,6 +166,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) + + blk_set_default_limits(&q->limits); + blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS); ++ q->limits.discard_zeroes_data = 0; + + /* + * by default assume old behaviour and bounce for any highmem page +@@ -790,6 +791,12 @@ void blk_queue_flush(struct request_queue *q, unsigned int flush) + } + EXPORT_SYMBOL_GPL(blk_queue_flush); + ++void blk_queue_flush_queueable(struct request_queue *q, bool queueable) ++{ ++ q->flush_not_queueable = !queueable; ++} ++EXPORT_SYMBOL_GPL(blk_queue_flush_queueable); ++ + static int __init blk_settings_init(void) + { + blk_max_low_pfn = max_low_pfn - 1; +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index bd23631..d935bd8 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -152,7 +152,8 @@ static ssize_t queue_discard_granularity_show(struct request_queue *q, char *pag + + static ssize_t queue_discard_max_show(struct request_queue *q, char *page) + { +- return queue_var_show(q->limits.max_discard_sectors << 9, page); ++ return sprintf(page, "%llu\n", ++ (unsigned long long)q->limits.max_discard_sectors << 9); + } + + static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page) +diff --git a/block/blk.h b/block/blk.h +index 6126346..1566e8d 100644 +--- a/block/blk.h ++++ b/block/blk.h +@@ -61,8 +61,28 @@ static inline struct request *__elv_next_request(struct request_queue *q) + rq = list_entry_rq(q->queue_head.next); + return rq; + } +- +- if (!q->elevator->ops->elevator_dispatch_fn(q, 0)) ++ /* ++ * Flush request is running and flush request isn't queueable ++ * in the drive, we can hold the queue till flush request is ++ * finished. Even we don't do this, driver can't dispatch next ++ * requests and will requeue them. And this can improve ++ * throughput too. For example, we have request flush1, write1, ++ * flush 2. flush1 is dispatched, then queue is hold, write1 ++ * isn't inserted to queue. After flush1 is finished, flush2 ++ * will be dispatched. Since disk cache is already clean, ++ * flush2 will be finished very soon, so looks like flush2 is ++ * folded to flush1. ++ * Since the queue is hold, a flag is set to indicate the queue ++ * should be restarted later. Please see flush_end_io() for ++ * details. ++ */ ++ if (q->flush_pending_idx != q->flush_running_idx && ++ !queue_flush_queueable(q)) { ++ q->flush_queue_delayed = 1; ++ return NULL; ++ } ++ if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags) || ++ !q->elevator->ops->elevator_dispatch_fn(q, 0)) + return NULL; + } + } +diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c +index ab7a9e6..bd2fa5f 100644 +--- a/block/cfq-iosched.c ++++ b/block/cfq-iosched.c +@@ -2704,8 +2704,14 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd, + smp_wmb(); + cic->key = cfqd_dead_key(cfqd); + +- if (ioc->ioc_data == cic) ++ rcu_read_lock(); ++ if (rcu_dereference(ioc->ioc_data) == cic) { ++ rcu_read_unlock(); ++ spin_lock(&ioc->lock); + rcu_assign_pointer(ioc->ioc_data, NULL); ++ spin_unlock(&ioc->lock); ++ } else ++ rcu_read_unlock(); + + if (cic->cfqq[BLK_RW_ASYNC]) { + cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_ASYNC]); +@@ -3012,7 +3018,8 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc, + + spin_lock_irqsave(&ioc->lock, flags); + +- BUG_ON(ioc->ioc_data == cic); ++ BUG_ON(rcu_dereference_check(ioc->ioc_data, ++ lockdep_is_held(&ioc->lock)) == cic); + + radix_tree_delete(&ioc->radix_root, cfqd->cic_index); + hlist_del_rcu(&cic->cic_list); +diff --git a/block/genhd.c b/block/genhd.c +index 2dd9887..95822ae 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -1728,7 +1728,7 @@ static void disk_add_events(struct gendisk *disk) + { + struct disk_events *ev; + +- if (!disk->fops->check_events || !(disk->events | disk->async_events)) ++ if (!disk->fops->check_events) + return; + + ev = kzalloc(sizeof(*ev), GFP_KERNEL); +diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c +index dad9fd6..17b74f4 100644 +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -2802,10 +2802,11 @@ int ata_eh_reset(struct ata_link *link, int classify, + } + + /* +- * Some controllers can't be frozen very well and may set +- * spuruious error conditions during reset. Clear accumulated +- * error information. As reset is the final recovery action, +- * nothing is lost by doing this. ++ * Some controllers can't be frozen very well and may set spurious ++ * error conditions during reset. Clear accumulated error ++ * information and re-thaw the port if frozen. As reset is the ++ * final recovery action and we cross check link onlineness against ++ * device classification later, no hotplug event is lost by this. + */ + spin_lock_irqsave(link->ap->lock, flags); + memset(&link->eh_info, 0, sizeof(link->eh_info)); +@@ -2814,6 +2815,9 @@ int ata_eh_reset(struct ata_link *link, int classify, + ap->pflags &= ~ATA_PFLAG_EH_PENDING; + spin_unlock_irqrestore(link->ap->lock, flags); + ++ if (ap->pflags & ATA_PFLAG_FROZEN) ++ ata_eh_thaw_port(ap); ++ + /* + * Make sure onlineness and classification result correspond. + * Hotplug could have happened during reset and some +diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c +index e2f57e9e..d51f979 100644 +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -1089,21 +1089,21 @@ static int atapi_drain_needed(struct request *rq) + static int ata_scsi_dev_config(struct scsi_device *sdev, + struct ata_device *dev) + { ++ struct request_queue *q = sdev->request_queue; ++ + if (!ata_id_has_unload(dev->id)) + dev->flags |= ATA_DFLAG_NO_UNLOAD; + + /* configure max sectors */ +- blk_queue_max_hw_sectors(sdev->request_queue, dev->max_sectors); ++ blk_queue_max_hw_sectors(q, dev->max_sectors); + + if (dev->class == ATA_DEV_ATAPI) { +- struct request_queue *q = sdev->request_queue; + void *buf; + + sdev->sector_size = ATA_SECT_SIZE; + + /* set DMA padding */ +- blk_queue_update_dma_pad(sdev->request_queue, +- ATA_DMA_PAD_SZ - 1); ++ blk_queue_update_dma_pad(q, ATA_DMA_PAD_SZ - 1); + + /* configure draining */ + buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL); +@@ -1131,8 +1131,7 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, + "sector_size=%u > PAGE_SIZE, PIO may malfunction\n", + sdev->sector_size); + +- blk_queue_update_dma_alignment(sdev->request_queue, +- sdev->sector_size - 1); ++ blk_queue_update_dma_alignment(q, sdev->sector_size - 1); + + if (dev->flags & ATA_DFLAG_AN) + set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events); +@@ -1145,6 +1144,8 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, + scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth); + } + ++ blk_queue_flush_queueable(q, false); ++ + dev->sdev = sdev; + return 0; + } +@@ -2138,7 +2139,7 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf) + * with the unmap bit set. + */ + if (ata_id_has_trim(args->id)) { +- put_unaligned_be32(65535 * 512 / 8, &rbuf[20]); ++ put_unaligned_be64(65535 * 512 / 8, &rbuf[36]); + put_unaligned_be32(1, &rbuf[28]); + } + +diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c +index 905ff76..635a759 100644 +--- a/drivers/ata/pata_cmd64x.c ++++ b/drivers/ata/pata_cmd64x.c +@@ -41,6 +41,9 @@ + enum { + CFR = 0x50, + CFR_INTR_CH0 = 0x04, ++ CNTRL = 0x51, ++ CNTRL_CH0 = 0x04, ++ CNTRL_CH1 = 0x08, + CMDTIM = 0x52, + ARTTIM0 = 0x53, + DRWTIM0 = 0x54, +@@ -328,9 +331,19 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) + .port_ops = &cmd648_port_ops + } + }; +- const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL }; +- u8 mrdmode; ++ const struct ata_port_info *ppi[] = { ++ &cmd_info[id->driver_data], ++ &cmd_info[id->driver_data], ++ NULL ++ }; ++ u8 mrdmode, reg; + int rc; ++ struct pci_dev *bridge = pdev->bus->self; ++ /* mobility split bridges don't report enabled ports correctly */ ++ int port_ok = !(bridge && bridge->vendor == ++ PCI_VENDOR_ID_MOBILITY_ELECTRONICS); ++ /* all (with exceptions below) apart from 643 have CNTRL_CH0 bit */ ++ int cntrl_ch0_ok = (id->driver_data != 0); + + rc = pcim_enable_device(pdev); + if (rc) +@@ -341,11 +354,18 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) + + if (pdev->device == PCI_DEVICE_ID_CMD_646) { + /* Does UDMA work ? */ +- if (pdev->revision > 4) ++ if (pdev->revision > 4) { + ppi[0] = &cmd_info[2]; ++ ppi[1] = &cmd_info[2]; ++ } + /* Early rev with other problems ? */ +- else if (pdev->revision == 1) ++ else if (pdev->revision == 1) { + ppi[0] = &cmd_info[3]; ++ ppi[1] = &cmd_info[3]; ++ } ++ /* revs 1,2 have no CNTRL_CH0 */ ++ if (pdev->revision < 3) ++ cntrl_ch0_ok = 0; + } + + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); +@@ -354,6 +374,20 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) + mrdmode |= 0x02; /* Memory read line enable */ + pci_write_config_byte(pdev, MRDMODE, mrdmode); + ++ /* check for enabled ports */ ++ pci_read_config_byte(pdev, CNTRL, ®); ++ if (!port_ok) ++ dev_printk(KERN_NOTICE, &pdev->dev, "Mobility Bridge detected, ignoring CNTRL port enable/disable\n"); ++ if (port_ok && cntrl_ch0_ok && !(reg & CNTRL_CH0)) { ++ dev_printk(KERN_NOTICE, &pdev->dev, "Primary port is disabled\n"); ++ ppi[0] = &ata_dummy_port_info; ++ ++ } ++ if (port_ok && !(reg & CNTRL_CH1)) { ++ dev_printk(KERN_NOTICE, &pdev->dev, "Secondary port is disabled\n"); ++ ppi[1] = &ata_dummy_port_info; ++ } ++ + /* Force PIO 0 here.. */ + + /* PPC specific fixup copied from old driver */ +diff --git a/drivers/base/platform.c b/drivers/base/platform.c +index 9e0e4fc..5d5bd1a 100644 +--- a/drivers/base/platform.c ++++ b/drivers/base/platform.c +@@ -367,7 +367,7 @@ EXPORT_SYMBOL_GPL(platform_device_unregister); + * + * Returns &struct platform_device pointer on success, or ERR_PTR() on error. + */ +-struct platform_device *__init_or_module platform_device_register_resndata( ++struct platform_device *platform_device_register_resndata( + struct device *parent, + const char *name, int id, + const struct resource *res, unsigned int num, +diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c +index abe3ab7..631b5d3 100644 +--- a/drivers/base/power/main.c ++++ b/drivers/base/power/main.c +@@ -57,7 +57,8 @@ static int async_error; + */ + void device_pm_init(struct device *dev) + { +- dev->power.in_suspend = false; ++ dev->power.is_prepared = false; ++ dev->power.is_suspended = false; + init_completion(&dev->power.completion); + complete_all(&dev->power.completion); + dev->power.wakeup = NULL; +@@ -91,7 +92,7 @@ void device_pm_add(struct device *dev) + pr_debug("PM: Adding info for %s:%s\n", + dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); + mutex_lock(&dpm_list_mtx); +- if (dev->parent && dev->parent->power.in_suspend) ++ if (dev->parent && dev->parent->power.is_prepared) + dev_warn(dev, "parent %s should not be sleeping\n", + dev_name(dev->parent)); + list_add_tail(&dev->power.entry, &dpm_list); +@@ -513,7 +514,14 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) + dpm_wait(dev->parent, async); + device_lock(dev); + +- dev->power.in_suspend = false; ++ /* ++ * This is a fib. But we'll allow new children to be added below ++ * a resumed device, even if the device hasn't been completed yet. ++ */ ++ dev->power.is_prepared = false; ++ ++ if (!dev->power.is_suspended) ++ goto Unlock; + + if (dev->pwr_domain) { + pm_dev_dbg(dev, state, "power domain "); +@@ -549,6 +557,9 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) + } + + End: ++ dev->power.is_suspended = false; ++ ++ Unlock: + device_unlock(dev); + complete_all(&dev->power.completion); + +@@ -668,7 +679,7 @@ static void dpm_complete(pm_message_t state) + struct device *dev = to_device(dpm_prepared_list.prev); + + get_device(dev); +- dev->power.in_suspend = false; ++ dev->power.is_prepared = false; + list_move(&dev->power.entry, &list); + mutex_unlock(&dpm_list_mtx); + +@@ -834,11 +845,11 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) + device_lock(dev); + + if (async_error) +- goto End; ++ goto Unlock; + + if (pm_wakeup_pending()) { + async_error = -EBUSY; +- goto End; ++ goto Unlock; + } + + if (dev->type && dev->type->pm) { +@@ -876,6 +887,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) + } + + End: ++ dev->power.is_suspended = !error; ++ ++ Unlock: + device_unlock(dev); + complete_all(&dev->power.completion); + +@@ -1037,7 +1051,7 @@ static int dpm_prepare(pm_message_t state) + put_device(dev); + break; + } +- dev->power.in_suspend = true; ++ dev->power.is_prepared = true; + if (!list_empty(&dev->power.entry)) + list_move_tail(&dev->power.entry, &dpm_prepared_list); + put_device(dev); +diff --git a/drivers/block/brd.c b/drivers/block/brd.c +index b7f51e4..c94bc48 100644 +--- a/drivers/block/brd.c ++++ b/drivers/block/brd.c +@@ -552,7 +552,7 @@ static struct kobject *brd_probe(dev_t dev, int *part, void *data) + struct kobject *kobj; + + mutex_lock(&brd_devices_mutex); +- brd = brd_init_one(dev & MINORMASK); ++ brd = brd_init_one(MINOR(dev) >> part_shift); + kobj = brd ? get_disk(brd->brd_disk) : ERR_PTR(-ENOMEM); + mutex_unlock(&brd_devices_mutex); + +@@ -585,15 +585,18 @@ static int __init brd_init(void) + if (max_part > 0) + part_shift = fls(max_part); + ++ if ((1UL << part_shift) > DISK_MAX_PARTS) ++ return -EINVAL; ++ + if (rd_nr > 1UL << (MINORBITS - part_shift)) + return -EINVAL; + + if (rd_nr) { + nr = rd_nr; +- range = rd_nr; ++ range = rd_nr << part_shift; + } else { + nr = CONFIG_BLK_DEV_RAM_COUNT; +- range = 1UL << (MINORBITS - part_shift); ++ range = 1UL << MINORBITS; + } + + if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) +@@ -632,7 +635,7 @@ static void __exit brd_exit(void) + unsigned long range; + struct brd_device *brd, *next; + +- range = rd_nr ? rd_nr : 1UL << (MINORBITS - part_shift); ++ range = rd_nr ? rd_nr << part_shift : 1UL << MINORBITS; + + list_for_each_entry_safe(brd, next, &brd_devices, brd_list) + brd_del_one(brd); +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index a076a14..c59a672 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -1658,7 +1658,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data) + struct kobject *kobj; + + mutex_lock(&loop_devices_mutex); +- lo = loop_init_one(dev & MINORMASK); ++ lo = loop_init_one(MINOR(dev) >> part_shift); + kobj = lo ? get_disk(lo->lo_disk) : ERR_PTR(-ENOMEM); + mutex_unlock(&loop_devices_mutex); + +@@ -1691,15 +1691,18 @@ static int __init loop_init(void) + if (max_part > 0) + part_shift = fls(max_part); + ++ if ((1UL << part_shift) > DISK_MAX_PARTS) ++ return -EINVAL; ++ + if (max_loop > 1UL << (MINORBITS - part_shift)) + return -EINVAL; + + if (max_loop) { + nr = max_loop; +- range = max_loop; ++ range = max_loop << part_shift; + } else { + nr = 8; +- range = 1UL << (MINORBITS - part_shift); ++ range = 1UL << MINORBITS; + } + + if (register_blkdev(LOOP_MAJOR, "loop")) +@@ -1738,7 +1741,7 @@ static void __exit loop_exit(void) + unsigned long range; + struct loop_device *lo, *next; + +- range = max_loop ? max_loop : 1UL << (MINORBITS - part_shift); ++ range = max_loop ? max_loop << part_shift : 1UL << MINORBITS; + + list_for_each_entry_safe(lo, next, &loop_devices, lo_list) + loop_del_one(lo); +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index e6fc716..a576406 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -756,6 +756,12 @@ static int __init nbd_init(void) + if (max_part > 0) + part_shift = fls(max_part); + ++ if ((1UL << part_shift) > DISK_MAX_PARTS) ++ return -EINVAL; ++ ++ if (nbds_max > 1UL << (MINORBITS - part_shift)) ++ return -EINVAL; ++ + for (i = 0; i < nbds_max; i++) { + struct gendisk *disk = alloc_disk(1 << part_shift); + if (!disk) +diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c +index 8690e31..46b8136 100644 +--- a/drivers/block/paride/pcd.c ++++ b/drivers/block/paride/pcd.c +@@ -320,6 +320,7 @@ static void pcd_init_units(void) + disk->first_minor = unit; + strcpy(disk->disk_name, cd->name); /* umm... */ + disk->fops = &pcd_bdops; ++ disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; + } + } + +diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c +index e427fbe..7878da8 100644 +--- a/drivers/cdrom/viocd.c ++++ b/drivers/cdrom/viocd.c +@@ -625,7 +625,8 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) + blk_queue_max_hw_sectors(q, 4096 / 512); + gendisk->queue = q; + gendisk->fops = &viocd_fops; +- gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE; ++ gendisk->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE | ++ GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; + set_capacity(gendisk, 0); + gendisk->private_data = d; + d->viocd_disk = gendisk; +diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c +index d72433f..ee01716 100644 +--- a/drivers/char/i8k.c ++++ b/drivers/char/i8k.c +@@ -139,8 +139,8 @@ static int i8k_smm(struct smm_regs *regs) + "movl %%edi,20(%%rax)\n\t" + "popq %%rdx\n\t" + "movl %%edx,0(%%rax)\n\t" +- "lahf\n\t" +- "shrl $8,%%eax\n\t" ++ "pushfq\n\t" ++ "popq %%rax\n\t" + "andl $1,%%eax\n" + :"=a"(rc) + : "a"(regs) +diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c +index 219d88a..dde6a0f 100644 +--- a/drivers/connector/connector.c ++++ b/drivers/connector/connector.c +@@ -139,6 +139,7 @@ static int cn_call_callback(struct sk_buff *skb) + spin_unlock_bh(&dev->cbdev->queue_lock); + + if (cbq != NULL) { ++ err = 0; + cbq->callback(msg, nsp); + kfree_skb(skb); + cn_queue_release_callback(cbq); +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index 2dafc5c..7c10f96 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -1208,12 +1208,28 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) + cpufreq_driver->exit(data); + unlock_policy_rwsem_write(cpu); + ++ cpufreq_debug_enable_ratelimit(); ++ ++#ifdef CONFIG_HOTPLUG_CPU ++ /* when the CPU which is the parent of the kobj is hotplugged ++ * offline, check for siblings, and create cpufreq sysfs interface ++ * and symlinks ++ */ ++ if (unlikely(cpumask_weight(data->cpus) > 1)) { ++ /* first sibling now owns the new sysfs dir */ ++ cpumask_clear_cpu(cpu, data->cpus); ++ cpufreq_add_dev(get_cpu_sysdev(cpumask_first(data->cpus))); ++ ++ /* finally remove our own symlink */ ++ lock_policy_rwsem_write(cpu); ++ __cpufreq_remove_dev(sys_dev); ++ } ++#endif ++ + free_cpumask_var(data->related_cpus); + free_cpumask_var(data->cpus); + kfree(data); +- per_cpu(cpufreq_cpu_data, cpu) = NULL; + +- cpufreq_debug_enable_ratelimit(); + return 0; + } + +diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c +index 00d73fc..7c7a1e4 100644 +--- a/drivers/cpufreq/cpufreq_stats.c ++++ b/drivers/cpufreq/cpufreq_stats.c +@@ -165,17 +165,27 @@ static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq) + return -1; + } + ++/* should be called late in the CPU removal sequence so that the stats ++ * memory is still available in case someone tries to use it. ++ */ + static void cpufreq_stats_free_table(unsigned int cpu) + { + struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, cpu); +- struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); +- if (policy && policy->cpu == cpu) +- sysfs_remove_group(&policy->kobj, &stats_attr_group); + if (stat) { + kfree(stat->time_in_state); + kfree(stat); + } + per_cpu(cpufreq_stats_table, cpu) = NULL; ++} ++ ++/* must be called early in the CPU removal sequence (before ++ * cpufreq_remove_dev) so that policy is still valid. ++ */ ++static void cpufreq_stats_free_sysfs(unsigned int cpu) ++{ ++ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); ++ if (policy && policy->cpu == cpu) ++ sysfs_remove_group(&policy->kobj, &stats_attr_group); + if (policy) + cpufreq_cpu_put(policy); + } +@@ -316,6 +326,9 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, + case CPU_ONLINE_FROZEN: + cpufreq_update_policy(cpu); + break; ++ case CPU_DOWN_PREPARE: ++ cpufreq_stats_free_sysfs(cpu); ++ break; + case CPU_DEAD: + case CPU_DEAD_FROZEN: + cpufreq_stats_free_table(cpu); +@@ -324,9 +337,11 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, + return NOTIFY_OK; + } + ++/* priority=1 so this will get called before cpufreq_remove_dev */ + static struct notifier_block cpufreq_stat_cpu_notifier __refdata = + { + .notifier_call = cpufreq_stat_cpu_callback, ++ .priority = 1, + }; + + static struct notifier_block notifier_policy_block = { +@@ -373,6 +388,7 @@ static void __exit cpufreq_stats_exit(void) + unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); + for_each_online_cpu(cpu) { + cpufreq_stats_free_table(cpu); ++ cpufreq_stats_free_sysfs(cpu); + } + } + +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index f508690..c47f3d0 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -237,6 +237,7 @@ static int menu_select(struct cpuidle_device *dev) + unsigned int power_usage = -1; + int i; + int multiplier; ++ struct timespec t; + + if (data->needs_update) { + menu_update(dev); +@@ -251,8 +252,9 @@ static int menu_select(struct cpuidle_device *dev) + return 0; + + /* determine the expected residency time, round up */ ++ t = ktime_to_timespec(tick_nohz_get_sleep_length()); + data->expected_us = +- DIV_ROUND_UP((u32)ktime_to_ns(tick_nohz_get_sleep_length()), 1000); ++ t.tv_sec * USEC_PER_SEC + t.tv_nsec / NSEC_PER_USEC; + + + data->bucket = which_bucket(data->expected_us); +diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c +index 23d1468..578d139 100644 +--- a/drivers/firewire/ohci.c ++++ b/drivers/firewire/ohci.c +@@ -264,6 +264,7 @@ static char ohci_driver_name[] = KBUILD_MODNAME; + #define PCI_DEVICE_ID_AGERE_FW643 0x5901 + #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 + #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 ++#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd + + #define QUIRK_CYCLE_TIMER 1 + #define QUIRK_RESET_PACKET 2 +@@ -3170,6 +3171,11 @@ static int __devinit pci_probe(struct pci_dev *dev, + int i, err; + size_t size; + ++ if (dev->vendor == PCI_VENDOR_ID_PINNACLE_SYSTEMS) { ++ dev_err(&dev->dev, "Pinnacle MovieBoard is not yet supported\n"); ++ return -ENOSYS; ++ } ++ + ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); + if (ohci == NULL) { + err = -ENOMEM; +diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c +index e1aee4f..b6a19cb 100644 +--- a/drivers/gpu/drm/drm_pci.c ++++ b/drivers/gpu/drm/drm_pci.c +@@ -251,7 +251,7 @@ err: + } + + +-int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p) ++static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p) + { + if ((p->busnum >> 8) != drm_get_pci_domain(dev) || + (p->busnum & 0xff) != dev->pdev->bus->number || +@@ -292,6 +292,7 @@ static struct drm_bus drm_pci_bus = { + .get_name = drm_pci_get_name, + .set_busid = drm_pci_set_busid, + .set_unique = drm_pci_set_unique, ++ .irq_by_busid = drm_pci_irq_by_busid, + .agp_init = drm_pci_agp_init, + }; + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 188b497..58c7f27 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1567,6 +1567,17 @@ static void ironlake_irq_preinstall(struct drm_device *dev) + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + + I915_WRITE(HWSTAM, 0xeffe); ++ if (IS_GEN6(dev)) { ++ /* Workaround stalls observed on Sandy Bridge GPUs by ++ * making the blitter command streamer generate a ++ * write to the Hardware Status Page for ++ * MI_USER_INTERRUPT. This appears to serialize the ++ * previous seqno write out before the interrupt ++ * happens. ++ */ ++ I915_WRITE(GEN6_BLITTER_HWSTAM, ~GEN6_BLITTER_USER_INTERRUPT); ++ I915_WRITE(GEN6_BSD_HWSTAM, ~GEN6_BSD_USER_INTERRUPT); ++ } + + /* XXX hotplug from PCH */ + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index f39ac3a..5a96fd1 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -528,6 +528,7 @@ + #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE 0 + #define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3) + ++#define GEN6_BSD_HWSTAM 0x12098 + #define GEN6_BSD_IMR 0x120a8 + #define GEN6_BSD_USER_INTERRUPT (1 << 12) + +diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c +index d3b903b..d98cee6 100644 +--- a/drivers/gpu/drm/i915/intel_i2c.c ++++ b/drivers/gpu/drm/i915/intel_i2c.c +@@ -401,8 +401,7 @@ int intel_setup_gmbus(struct drm_device *dev) + bus->reg0 = i | GMBUS_RATE_100KHZ; + + /* XXX force bit banging until GMBUS is fully debugged */ +- if (IS_GEN2(dev)) +- bus->force_bit = intel_gpio_create(dev_priv, i); ++ bus->force_bit = intel_gpio_create(dev_priv, i); + } + + intel_i2c_reset(dev_priv->dev); +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 67cb076..b28f7bd 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -727,6 +727,14 @@ static const struct dmi_system_id intel_no_lvds[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "U800"), + }, + }, ++ { ++ .callback = intel_no_lvds_dmi_callback, ++ .ident = "Asus EeeBox PC EB1007", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"), ++ }, ++ }, + + { } /* terminating entry */ + }; +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index e9e6f71..c4504a2 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -666,12 +666,37 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) + static bool + bsd_ring_get_irq(struct intel_ring_buffer *ring) + { +- return ring_get_irq(ring, GT_BSD_USER_INTERRUPT); ++ struct drm_device *dev = ring->dev; ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ ++ if (!dev->irq_enabled) ++ return false; ++ ++ spin_lock(&ring->irq_lock); ++ if (ring->irq_refcount++ == 0) { ++ if (IS_G4X(dev)) ++ i915_enable_irq(dev_priv, I915_BSD_USER_INTERRUPT); ++ else ++ ironlake_enable_irq(dev_priv, GT_BSD_USER_INTERRUPT); ++ } ++ spin_unlock(&ring->irq_lock); ++ ++ return true; + } + static void + bsd_ring_put_irq(struct intel_ring_buffer *ring) + { +- ring_put_irq(ring, GT_BSD_USER_INTERRUPT); ++ struct drm_device *dev = ring->dev; ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ ++ spin_lock(&ring->irq_lock); ++ if (--ring->irq_refcount == 0) { ++ if (IS_G4X(dev)) ++ i915_disable_irq(dev_priv, I915_BSD_USER_INTERRUPT); ++ else ++ ironlake_disable_irq(dev_priv, GT_BSD_USER_INTERRUPT); ++ } ++ spin_unlock(&ring->irq_lock); + } + + static int +diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c +index 529a3a7..02705c7 100644 +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -1011,7 +1011,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, + uint64_t fb_location; + uint32_t fb_format, fb_pitch_pixels, tiling_flags; + u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); +- u32 tmp; ++ u32 tmp, viewport_w, viewport_h; + int r; + + /* no fb bound */ +@@ -1137,8 +1137,10 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, + y &= ~1; + WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, + (x << 16) | y); ++ viewport_w = crtc->mode.hdisplay; ++ viewport_h = (crtc->mode.vdisplay + 1) & ~1; + WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, +- (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); ++ (viewport_w << 16) | viewport_h); + + /* pageflip setup */ + /* make sure flip is at vb rather than hb */ +@@ -1179,7 +1181,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, + uint64_t fb_location; + uint32_t fb_format, fb_pitch_pixels, tiling_flags; + u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; +- u32 tmp; ++ u32 tmp, viewport_w, viewport_h; + int r; + + /* no fb bound */ +@@ -1304,8 +1306,10 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, + y &= ~1; + WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, + (x << 16) | y); ++ viewport_w = crtc->mode.hdisplay; ++ viewport_h = (crtc->mode.vdisplay + 1) & ~1; + WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, +- (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); ++ (viewport_w << 16) | viewport_h); + + /* pageflip setup */ + /* make sure flip is at vb rather than hb */ +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index 9073e3b..10e4e34 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -960,17 +960,19 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav + { + save->vga_control[0] = RREG32(D1VGA_CONTROL); + save->vga_control[1] = RREG32(D2VGA_CONTROL); +- save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); +- save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); +- save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); +- save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); + save->vga_render_control = RREG32(VGA_RENDER_CONTROL); + save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); + save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); + save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); +- if (!(rdev->flags & RADEON_IS_IGP)) { ++ if (rdev->num_crtc >= 4) { ++ save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); ++ save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); + save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); + save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); ++ } ++ if (rdev->num_crtc >= 6) { ++ save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); ++ save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); + save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); + save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); + } +@@ -979,35 +981,45 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav + WREG32(VGA_RENDER_CONTROL, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); +- if (!(rdev->flags & RADEON_IS_IGP)) { ++ if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); ++ } ++ if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); + } + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); +- if (!(rdev->flags & RADEON_IS_IGP)) { ++ if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); ++ } ++ if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); +- if (!(rdev->flags & RADEON_IS_IGP)) { ++ if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); ++ } ++ if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } + + WREG32(D1VGA_CONTROL, 0); + WREG32(D2VGA_CONTROL, 0); +- WREG32(EVERGREEN_D3VGA_CONTROL, 0); +- WREG32(EVERGREEN_D4VGA_CONTROL, 0); +- WREG32(EVERGREEN_D5VGA_CONTROL, 0); +- WREG32(EVERGREEN_D6VGA_CONTROL, 0); ++ if (rdev->num_crtc >= 4) { ++ WREG32(EVERGREEN_D3VGA_CONTROL, 0); ++ WREG32(EVERGREEN_D4VGA_CONTROL, 0); ++ } ++ if (rdev->num_crtc >= 6) { ++ WREG32(EVERGREEN_D5VGA_CONTROL, 0); ++ WREG32(EVERGREEN_D6VGA_CONTROL, 0); ++ } + } + + void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) +@@ -1030,7 +1042,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + +- if (!(rdev->flags & RADEON_IS_IGP)) { ++ if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, +@@ -1048,7 +1060,8 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s + (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); +- ++ } ++ if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, +@@ -1076,31 +1089,41 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s + /* Restore video state */ + WREG32(D1VGA_CONTROL, save->vga_control[0]); + WREG32(D2VGA_CONTROL, save->vga_control[1]); +- WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); +- WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); +- WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); +- WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); ++ if (rdev->num_crtc >= 4) { ++ WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); ++ WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); ++ } ++ if (rdev->num_crtc >= 6) { ++ WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); ++ WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); ++ } + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); +- if (!(rdev->flags & RADEON_IS_IGP)) { ++ if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); ++ } ++ if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); + } + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); +- if (!(rdev->flags & RADEON_IS_IGP)) { ++ if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); ++ } ++ if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); + } + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); +- if (!(rdev->flags & RADEON_IS_IGP)) { ++ if (rdev->num_crtc >= 4) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); ++ } ++ if (rdev->num_crtc >= 6) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } +@@ -1578,7 +1601,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) + u32 sq_stack_resource_mgmt_2; + u32 sq_stack_resource_mgmt_3; + u32 vgt_cache_invalidation; +- u32 hdp_host_path_cntl; ++ u32 hdp_host_path_cntl, tmp; + int i, j, num_shader_engines, ps_thread_count; + + switch (rdev->family) { +@@ -1900,7 +1923,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) + gb_backend_map = 0x66442200; + break; + case CHIP_JUNIPER: +- gb_backend_map = 0x00006420; ++ gb_backend_map = 0x00002200; + break; + default: + gb_backend_map = +@@ -2141,6 +2164,10 @@ static void evergreen_gpu_init(struct radeon_device *rdev) + for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4) + WREG32(i, 0); + ++ tmp = RREG32(HDP_MISC_CNTL); ++ tmp |= HDP_FLUSH_INVALIDATE_CACHE; ++ WREG32(HDP_MISC_CNTL, tmp); ++ + hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); + WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); + +@@ -2323,18 +2350,22 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) + WREG32(GRBM_INT_CNTL, 0); + WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); +- if (!(rdev->flags & RADEON_IS_IGP)) { ++ if (rdev->num_crtc >= 4) { + WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); ++ } ++ if (rdev->num_crtc >= 6) { + WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } + + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); +- if (!(rdev->flags & RADEON_IS_IGP)) { ++ if (rdev->num_crtc >= 4) { + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); ++ } ++ if (rdev->num_crtc >= 6) { + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } +@@ -2453,19 +2484,25 @@ int evergreen_irq_set(struct radeon_device *rdev) + + WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); + WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); +- if (!(rdev->flags & RADEON_IS_IGP)) { ++ if (rdev->num_crtc >= 4) { + WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); + WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); ++ } ++ if (rdev->num_crtc >= 6) { + WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); + WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); + } + + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); +- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); +- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); +- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); +- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); ++ if (rdev->num_crtc >= 4) { ++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); ++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); ++ } ++ if (rdev->num_crtc >= 6) { ++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); ++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); ++ } + + WREG32(DC_HPD1_INT_CONTROL, hpd1); + WREG32(DC_HPD2_INT_CONTROL, hpd2); +@@ -2489,53 +2526,57 @@ static inline void evergreen_irq_ack(struct radeon_device *rdev) + rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); + rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); + rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); +- rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); +- rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); +- rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); +- rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); ++ if (rdev->num_crtc >= 4) { ++ rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); ++ rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); ++ } ++ if (rdev->num_crtc >= 6) { ++ rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); ++ rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); ++ } + + if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) + WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); + if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED) + WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); +- if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED) +- WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); +- if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED) +- WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); +- if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED) +- WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); +- if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED) +- WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); +- + if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) + WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); + if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) + WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); +- + if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) + WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); + if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) + WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); + +- if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) +- WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); +- if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) +- WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); +- +- if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) +- WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); +- if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) +- WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); +- +- if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) +- WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); +- if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) +- WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); +- +- if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) +- WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); +- if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) +- WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); ++ if (rdev->num_crtc >= 4) { ++ if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED) ++ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); ++ if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED) ++ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); ++ if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) ++ WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); ++ if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) ++ WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); ++ if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) ++ WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); ++ if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) ++ WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); ++ } ++ ++ if (rdev->num_crtc >= 6) { ++ if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED) ++ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); ++ if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED) ++ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); ++ if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) ++ WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); ++ if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) ++ WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); ++ if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) ++ WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); ++ if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) ++ WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); ++ } + + if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { + tmp = RREG32(DC_HPD1_INT_CONTROL); +@@ -3146,6 +3187,7 @@ void evergreen_fini(struct radeon_device *rdev) + r700_cp_fini(rdev); + r600_irq_fini(rdev); + radeon_wb_fini(rdev); ++ radeon_ib_pool_fini(rdev); + radeon_irq_kms_fini(rdev); + evergreen_pcie_gart_fini(rdev); + radeon_gem_fini(rdev); +diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h +index fc40e0c..273e7e9 100644 +--- a/drivers/gpu/drm/radeon/evergreend.h ++++ b/drivers/gpu/drm/radeon/evergreend.h +@@ -64,6 +64,8 @@ + #define GB_BACKEND_MAP 0x98FC + #define DMIF_ADDR_CONFIG 0xBD4 + #define HDP_ADDR_CONFIG 0x2F48 ++#define HDP_MISC_CNTL 0x2F4C ++#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0) + + #define CC_SYS_RB_BACKEND_DISABLE 0x3F88 + #define GC_USER_RB_BACKEND_DISABLE 0x9B7C +@@ -458,7 +460,7 @@ + #define IH_RB_WPTR_ADDR_LO 0x3e14 + #define IH_CNTL 0x3e18 + # define ENABLE_INTR (1 << 0) +-# define IH_MC_SWAP(x) ((x) << 2) ++# define IH_MC_SWAP(x) ((x) << 1) + # define IH_MC_SWAP_NONE 0 + # define IH_MC_SWAP_16BIT 1 + # define IH_MC_SWAP_32BIT 2 +@@ -539,7 +541,7 @@ + # define LB_D5_VBLANK_INTERRUPT (1 << 3) + # define DC_HPD5_INTERRUPT (1 << 17) + # define DC_HPD5_RX_INTERRUPT (1 << 18) +-#define DISP_INTERRUPT_STATUS_CONTINUE5 0x6050 ++#define DISP_INTERRUPT_STATUS_CONTINUE5 0x6150 + # define LB_D6_VLINE_INTERRUPT (1 << 2) + # define LB_D6_VBLANK_INTERRUPT (1 << 3) + # define DC_HPD6_INTERRUPT (1 << 17) +diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c +index 3d8a763..58f5070 100644 +--- a/drivers/gpu/drm/radeon/ni.c ++++ b/drivers/gpu/drm/radeon/ni.c +@@ -417,7 +417,7 @@ static u32 cayman_get_tile_pipe_to_backend_map(struct radeon_device *rdev, + num_shader_engines = 1; + if (num_shader_engines > rdev->config.cayman.max_shader_engines) + num_shader_engines = rdev->config.cayman.max_shader_engines; +- if (num_backends_per_asic > num_shader_engines) ++ if (num_backends_per_asic < num_shader_engines) + num_backends_per_asic = num_shader_engines; + if (num_backends_per_asic > (rdev->config.cayman.max_backends_per_se * num_shader_engines)) + num_backends_per_asic = rdev->config.cayman.max_backends_per_se * num_shader_engines; +@@ -829,7 +829,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) + rdev->config.cayman.tile_config |= + ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; + rdev->config.cayman.tile_config |= +- (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT; ++ ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; + rdev->config.cayman.tile_config |= + ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; + +@@ -931,6 +931,10 @@ static void cayman_gpu_init(struct radeon_device *rdev) + WREG32(CB_PERF_CTR3_SEL_0, 0); + WREG32(CB_PERF_CTR3_SEL_1, 0); + ++ tmp = RREG32(HDP_MISC_CNTL); ++ tmp |= HDP_FLUSH_INVALIDATE_CACHE; ++ WREG32(HDP_MISC_CNTL, tmp); ++ + hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); + WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); + +@@ -1580,6 +1584,7 @@ void cayman_fini(struct radeon_device *rdev) + cayman_cp_fini(rdev); + r600_irq_fini(rdev); + radeon_wb_fini(rdev); ++ radeon_ib_pool_fini(rdev); + radeon_irq_kms_fini(rdev); + cayman_pcie_gart_fini(rdev); + radeon_gem_fini(rdev); +diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h +index 0f9a08b..b2088c1 100644 +--- a/drivers/gpu/drm/radeon/nid.h ++++ b/drivers/gpu/drm/radeon/nid.h +@@ -136,6 +136,8 @@ + #define HDP_NONSURFACE_INFO 0x2C08 + #define HDP_NONSURFACE_SIZE 0x2C0C + #define HDP_ADDR_CONFIG 0x2F48 ++#define HDP_MISC_CNTL 0x2F4C ++#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0) + + #define CC_SYS_RB_BACKEND_DISABLE 0x3F88 + #define GC_USER_SYS_RB_BACKEND_DISABLE 0x3F8C +diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h +index 2fef9de..686f9dc 100644 +--- a/drivers/gpu/drm/radeon/r100_track.h ++++ b/drivers/gpu/drm/radeon/r100_track.h +@@ -63,7 +63,7 @@ struct r100_cs_track { + unsigned num_arrays; + unsigned max_indx; + unsigned color_channel_mask; +- struct r100_cs_track_array arrays[11]; ++ struct r100_cs_track_array arrays[16]; + struct r100_cs_track_cb cb[R300_MAX_CB]; + struct r100_cs_track_cb zb; + struct r100_cs_track_cb aa; +@@ -146,6 +146,12 @@ static inline int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, + ib = p->ib->ptr; + track = (struct r100_cs_track *)p->track; + c = radeon_get_ib_value(p, idx++) & 0x1F; ++ if (c > 16) { ++ DRM_ERROR("Only 16 vertex buffers are allowed %d\n", ++ pkt->opcode); ++ r100_cs_dump_packet(p, pkt); ++ return -EINVAL; ++ } + track->num_arrays = c; + for (i = 0; i < (c - 1); i+=2, idx+=3) { + r = r100_cs_packet_next_reloc(p, &reloc); +diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c +index 6f27593..068cc85 100644 +--- a/drivers/gpu/drm/radeon/r600.c ++++ b/drivers/gpu/drm/radeon/r600.c +@@ -2613,6 +2613,7 @@ void r600_fini(struct radeon_device *rdev) + r600_cp_fini(rdev); + r600_irq_fini(rdev); + radeon_wb_fini(rdev); ++ radeon_ib_pool_fini(rdev); + radeon_irq_kms_fini(rdev); + r600_pcie_gart_fini(rdev); + radeon_agp_fini(rdev); +diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h +index b2b944bc..e5eaef9 100644 +--- a/drivers/gpu/drm/radeon/r600d.h ++++ b/drivers/gpu/drm/radeon/r600d.h +@@ -536,7 +536,7 @@ + #define IH_RB_WPTR_ADDR_LO 0x3e14 + #define IH_CNTL 0x3e18 + # define ENABLE_INTR (1 << 0) +-# define IH_MC_SWAP(x) ((x) << 2) ++# define IH_MC_SWAP(x) ((x) << 1) + # define IH_MC_SWAP_NONE 0 + # define IH_MC_SWAP_16BIT 1 + # define IH_MC_SWAP_32BIT 2 +diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c +index ca57619..d948265 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.c ++++ b/drivers/gpu/drm/radeon/radeon_asic.c +@@ -782,6 +782,7 @@ static struct radeon_asic evergreen_asic = { + .hpd_fini = &evergreen_hpd_fini, + .hpd_sense = &evergreen_hpd_sense, + .hpd_set_polarity = &evergreen_hpd_set_polarity, ++ .ioctl_wait_idle = r600_ioctl_wait_idle, + .gui_idle = &r600_gui_idle, + .pm_misc = &evergreen_pm_misc, + .pm_prepare = &evergreen_pm_prepare, +@@ -828,6 +829,7 @@ static struct radeon_asic sumo_asic = { + .hpd_fini = &evergreen_hpd_fini, + .hpd_sense = &evergreen_hpd_sense, + .hpd_set_polarity = &evergreen_hpd_set_polarity, ++ .ioctl_wait_idle = r600_ioctl_wait_idle, + .gui_idle = &r600_gui_idle, + .pm_misc = &evergreen_pm_misc, + .pm_prepare = &evergreen_pm_prepare, +@@ -874,6 +876,7 @@ static struct radeon_asic btc_asic = { + .hpd_fini = &evergreen_hpd_fini, + .hpd_sense = &evergreen_hpd_sense, + .hpd_set_polarity = &evergreen_hpd_set_polarity, ++ .ioctl_wait_idle = r600_ioctl_wait_idle, + .gui_idle = &r600_gui_idle, + .pm_misc = &evergreen_pm_misc, + .pm_prepare = &evergreen_pm_prepare, +@@ -920,6 +923,7 @@ static struct radeon_asic cayman_asic = { + .hpd_fini = &evergreen_hpd_fini, + .hpd_sense = &evergreen_hpd_sense, + .hpd_set_polarity = &evergreen_hpd_set_polarity, ++ .ioctl_wait_idle = r600_ioctl_wait_idle, + .gui_idle = &r600_gui_idle, + .pm_misc = &evergreen_pm_misc, + .pm_prepare = &evergreen_pm_prepare, +diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c +index 890217e..5d6ccc3 100644 +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -752,6 +752,7 @@ int radeon_device_init(struct radeon_device *rdev, + dma_bits = rdev->need_dma32 ? 32 : 40; + r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits)); + if (r) { ++ rdev->need_dma32 = true; + printk(KERN_WARNING "radeon: No suitable DMA available.\n"); + } + +diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c +index bdbab5c..2802c56 100644 +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -264,6 +264,8 @@ static void radeon_unpin_work_func(struct work_struct *__work) + radeon_bo_unreserve(work->old_rbo); + } else + DRM_ERROR("failed to reserve buffer after flip\n"); ++ ++ drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); + kfree(work); + } + +@@ -371,6 +373,8 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, + new_radeon_fb = to_radeon_framebuffer(fb); + /* schedule unpin of the old buffer */ + obj = old_radeon_fb->obj; ++ /* take a reference to the old object */ ++ drm_gem_object_reference(obj); + rbo = gem_to_radeon_bo(obj); + work->old_rbo = rbo; + INIT_WORK(&work->work, radeon_unpin_work_func); +@@ -378,12 +382,9 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, + /* We borrow the event spin lock for protecting unpin_work */ + spin_lock_irqsave(&dev->event_lock, flags); + if (radeon_crtc->unpin_work) { +- spin_unlock_irqrestore(&dev->event_lock, flags); +- kfree(work); +- radeon_fence_unref(&fence); +- + DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); +- return -EBUSY; ++ r = -EBUSY; ++ goto unlock_free; + } + radeon_crtc->unpin_work = work; + radeon_crtc->deferred_flip_completion = 0; +@@ -497,6 +498,8 @@ pflip_cleanup1: + pflip_cleanup: + spin_lock_irqsave(&dev->event_lock, flags); + radeon_crtc->unpin_work = NULL; ++unlock_free: ++ drm_gem_object_unreference_unlocked(old_radeon_fb->obj); + spin_unlock_irqrestore(&dev->event_lock, flags); + radeon_fence_unref(&fence); + kfree(work); +diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c +index b427488..9423fba 100644 +--- a/drivers/gpu/drm/radeon/radeon_encoders.c ++++ b/drivers/gpu/drm/radeon/radeon_encoders.c +@@ -1294,7 +1294,11 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) + if (is_dig) { + switch (mode) { + case DRM_MODE_DPMS_ON: +- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); ++ /* some early dce3.2 boards have a bug in their transmitter control table */ ++ if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); ++ else ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); + if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + +diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c +index ef8a5ba..33b856b 100644 +--- a/drivers/gpu/drm/radeon/rv770.c ++++ b/drivers/gpu/drm/radeon/rv770.c +@@ -572,6 +572,12 @@ static void rv770_program_channel_remap(struct radeon_device *rdev) + else + tcp_chan_steer = 0x00fac688; + ++ /* RV770 CE has special chremap setup */ ++ if (rdev->pdev->device == 0x944e) { ++ tcp_chan_steer = 0x00b08b08; ++ mc_shared_chremap = 0x00b08b08; ++ } ++ + WREG32(TCP_CHAN_STEER, tcp_chan_steer); + WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); + } +@@ -1359,6 +1365,7 @@ void rv770_fini(struct radeon_device *rdev) + r700_cp_fini(rdev); + r600_irq_fini(rdev); + radeon_wb_fini(rdev); ++ radeon_ib_pool_fini(rdev); + radeon_irq_kms_fini(rdev); + rv770_pcie_gart_fini(rdev); + rv770_vram_scratch_fini(rdev); +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 0ec91c1..a5eda4c 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -501,9 +501,17 @@ static int magicmouse_probe(struct hid_device *hdev, + } + report->size = 6; + ++ /* ++ * The device reponds with 'invalid report id' when feature ++ * report switching it into multitouch mode is sent to it. ++ * ++ * This results in -EIO from the _raw low-level transport callback, ++ * but there seems to be no other way of switching the mode. ++ * Thus the super-ugly hacky success check below. ++ */ + ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), + HID_FEATURE_REPORT); +- if (ret != sizeof(feature)) { ++ if (ret != -EIO) { + hid_err(hdev, "unable to request touch data (%d)\n", ret); + goto err_stop_hw; + } +diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c +index b5e8920..3462242 100644 +--- a/drivers/hwmon/asus_atk0110.c ++++ b/drivers/hwmon/asus_atk0110.c +@@ -673,6 +673,7 @@ static int atk_debugfs_gitm_get(void *p, u64 *val) + else + err = -EIO; + ++ ACPI_FREE(ret); + return err; + } + +diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c +index 194ca0a..08cea44 100644 +--- a/drivers/hwmon/coretemp.c ++++ b/drivers/hwmon/coretemp.c +@@ -263,7 +263,7 @@ static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, + * If the TjMax is not plausible, an assumption + * will be used + */ +- if ((val > 80) && (val < 120)) { ++ if (val >= 70 && val <= 125) { + dev_info(dev, "TjMax is %d C.\n", val); + return val * 1000; + } +@@ -271,24 +271,9 @@ static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, + + /* + * An assumption is made for early CPUs and unreadable MSR. +- * NOTE: the given value may not be correct. ++ * NOTE: the calculated value may not be correct. + */ +- +- switch (c->x86_model) { +- case 0xe: +- case 0xf: +- case 0x16: +- case 0x1a: +- dev_warn(dev, "TjMax is assumed as 100 C!\n"); +- return 100000; +- case 0x17: +- case 0x1c: /* Atom CPUs */ +- return adjust_tjmax(c, id, dev); +- default: +- dev_warn(dev, "CPU (model=0x%x) is not supported yet," +- " using default TjMax of 100C.\n", c->x86_model); +- return 100000; +- } ++ return adjust_tjmax(c, id, dev); + } + + static void __devinit get_ucode_rev_on_cpu(void *edx) +diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c +index bc6e2ab..affc17e 100644 +--- a/drivers/hwmon/ibmaem.c ++++ b/drivers/hwmon/ibmaem.c +@@ -947,6 +947,7 @@ static int aem_register_sensors(struct aem_data *data, + + /* Set up read-only sensors */ + while (ro->label) { ++ sysfs_attr_init(&sensors->dev_attr.attr); + sensors->dev_attr.attr.name = ro->label; + sensors->dev_attr.attr.mode = S_IRUGO; + sensors->dev_attr.show = ro->show; +@@ -963,6 +964,7 @@ static int aem_register_sensors(struct aem_data *data, + + /* Set up read-write sensors */ + while (rw->label) { ++ sysfs_attr_init(&sensors->dev_attr.attr); + sensors->dev_attr.attr.name = rw->label; + sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR; + sensors->dev_attr.show = rw->show; +diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c +index 06d4eaf..41dbf81 100644 +--- a/drivers/hwmon/ibmpex.c ++++ b/drivers/hwmon/ibmpex.c +@@ -358,6 +358,7 @@ static int create_sensor(struct ibmpex_bmc_data *data, int type, + else if (type == POWER_SENSOR) + sprintf(n, power_sensor_name_templates[func], "power", counter); + ++ sysfs_attr_init(&data->sensors[sensor].attr[func].dev_attr.attr); + data->sensors[sensor].attr[func].dev_attr.attr.name = n; + data->sensors[sensor].attr[func].dev_attr.attr.mode = S_IRUGO; + data->sensors[sensor].attr[func].dev_attr.show = ibmpex_show_sensor; +diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c +index 316b648..a8d2359 100644 +--- a/drivers/hwmon/it87.c ++++ b/drivers/hwmon/it87.c +@@ -1535,7 +1535,7 @@ static struct attribute *it87_attributes_label[] = { + }; + + static const struct attribute_group it87_group_label = { +- .attrs = it87_attributes_vid, ++ .attrs = it87_attributes_label, + }; + + /* SuperIO detection - will change isa_address if a chip is found */ +diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c +index 1a6dfb6..d3b464b 100644 +--- a/drivers/hwmon/lm95241.c ++++ b/drivers/hwmon/lm95241.c +@@ -98,11 +98,16 @@ struct lm95241_data { + }; + + /* Conversions */ +-static int TempFromReg(u8 val_h, u8 val_l) ++static int temp_from_reg_signed(u8 val_h, u8 val_l) + { +- if (val_h & 0x80) +- return val_h - 0x100; +- return val_h * 1000 + val_l * 1000 / 256; ++ s16 val_hl = (val_h << 8) | val_l; ++ return val_hl * 1000 / 256; ++} ++ ++static int temp_from_reg_unsigned(u8 val_h, u8 val_l) ++{ ++ u16 val_hl = (val_h << 8) | val_l; ++ return val_hl * 1000 / 256; + } + + static struct lm95241_data *lm95241_update_device(struct device *dev) +@@ -135,10 +140,13 @@ static ssize_t show_input(struct device *dev, struct device_attribute *attr, + char *buf) + { + struct lm95241_data *data = lm95241_update_device(dev); ++ int index = to_sensor_dev_attr(attr)->index; + + return snprintf(buf, PAGE_SIZE - 1, "%d\n", +- TempFromReg(data->temp[to_sensor_dev_attr(attr)->index], +- data->temp[to_sensor_dev_attr(attr)->index + 1])); ++ index == 0 || (data->config & (1 << (index / 2))) ? ++ temp_from_reg_signed(data->temp[index], data->temp[index + 1]) : ++ temp_from_reg_unsigned(data->temp[index], ++ data->temp[index + 1])); + } + + static ssize_t show_type(struct device *dev, struct device_attribute *attr, +@@ -339,7 +347,7 @@ static int lm95241_detect(struct i2c_client *new_client, + if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID) + == MANUFACTURER_ID) + && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) +- >= DEFAULT_REVISION)) { ++ == DEFAULT_REVISION)) { + name = DEVNAME; + } else { + dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n", +diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c +index 12a54aa..14335bb 100644 +--- a/drivers/hwmon/max1111.c ++++ b/drivers/hwmon/max1111.c +@@ -40,6 +40,8 @@ struct max1111_data { + struct spi_transfer xfer[2]; + uint8_t *tx_buf; + uint8_t *rx_buf; ++ struct mutex drvdata_lock; ++ /* protect msg, xfer and buffers from multiple access */ + }; + + static int max1111_read(struct device *dev, int channel) +@@ -48,6 +50,9 @@ static int max1111_read(struct device *dev, int channel) + uint8_t v1, v2; + int err; + ++ /* writing to drvdata struct is not thread safe, wait on mutex */ ++ mutex_lock(&data->drvdata_lock); ++ + data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) | + MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 | + MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR; +@@ -55,12 +60,15 @@ static int max1111_read(struct device *dev, int channel) + err = spi_sync(data->spi, &data->msg); + if (err < 0) { + dev_err(dev, "spi_sync failed with %d\n", err); ++ mutex_unlock(&data->drvdata_lock); + return err; + } + + v1 = data->rx_buf[0]; + v2 = data->rx_buf[1]; + ++ mutex_unlock(&data->drvdata_lock); ++ + if ((v1 & 0xc0) || (v2 & 0x3f)) + return -EINVAL; + +@@ -176,6 +184,8 @@ static int __devinit max1111_probe(struct spi_device *spi) + if (err) + goto err_free_data; + ++ mutex_init(&data->drvdata_lock); ++ + data->spi = spi; + spi_set_drvdata(spi, data); + +@@ -213,6 +223,7 @@ static int __devexit max1111_remove(struct spi_device *spi) + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); ++ mutex_destroy(&data->drvdata_lock); + kfree(data->rx_buf); + kfree(data->tx_buf); + kfree(data); +diff --git a/drivers/hwmon/pmbus.c b/drivers/hwmon/pmbus.c +index 98e2e28..9b1f0c3 100644 +--- a/drivers/hwmon/pmbus.c ++++ b/drivers/hwmon/pmbus.c +@@ -47,22 +47,29 @@ static void pmbus_find_sensor_groups(struct i2c_client *client, + if (info->func[0] + && pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT)) + info->func[0] |= PMBUS_HAVE_STATUS_INPUT; +- if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) { ++ if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) && ++ pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) { + info->func[0] |= PMBUS_HAVE_FAN12; + if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN12; + } +- if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) { ++ if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) && ++ pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) { + info->func[0] |= PMBUS_HAVE_FAN34; + if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34)) + info->func[0] |= PMBUS_HAVE_STATUS_FAN34; + } +- if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) { ++ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) + info->func[0] |= PMBUS_HAVE_TEMP; +- if (pmbus_check_byte_register(client, 0, +- PMBUS_STATUS_TEMPERATURE)) ++ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2)) ++ info->func[0] |= PMBUS_HAVE_TEMP2; ++ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3)) ++ info->func[0] |= PMBUS_HAVE_TEMP3; ++ if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 ++ | PMBUS_HAVE_TEMP3) ++ && pmbus_check_byte_register(client, 0, ++ PMBUS_STATUS_TEMPERATURE)) + info->func[0] |= PMBUS_HAVE_STATUS_TEMP; +- } + + /* Sensors detected on all pages */ + for (page = 0; page < info->pages; page++) { +diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c +index 196ffaf..8217d19 100644 +--- a/drivers/hwmon/pmbus_core.c ++++ b/drivers/hwmon/pmbus_core.c +@@ -355,8 +355,8 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) + * Convert linear sensor values to milli- or micro-units + * depending on sensor type. + */ +-static int pmbus_reg2data_linear(struct pmbus_data *data, +- struct pmbus_sensor *sensor) ++static long pmbus_reg2data_linear(struct pmbus_data *data, ++ struct pmbus_sensor *sensor) + { + s16 exponent; + s32 mantissa; +@@ -390,15 +390,15 @@ static int pmbus_reg2data_linear(struct pmbus_data *data, + else + val >>= -exponent; + +- return (int)val; ++ return val; + } + + /* + * Convert direct sensor values to milli- or micro-units + * depending on sensor type. + */ +-static int pmbus_reg2data_direct(struct pmbus_data *data, +- struct pmbus_sensor *sensor) ++static long pmbus_reg2data_direct(struct pmbus_data *data, ++ struct pmbus_sensor *sensor) + { + long val = (s16) sensor->data; + long m, b, R; +@@ -433,12 +433,12 @@ static int pmbus_reg2data_direct(struct pmbus_data *data, + R++; + } + +- return (int)((val - b) / m); ++ return (val - b) / m; + } + +-static int pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) ++static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) + { +- int val; ++ long val; + + if (data->info->direct[sensor->class]) + val = pmbus_reg2data_direct(data, sensor); +@@ -612,7 +612,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) + if (!s1 && !s2) + *val = !!regval; + else { +- int v1, v2; ++ long v1, v2; + struct pmbus_sensor *sensor1, *sensor2; + + sensor1 = &data->sensors[s1]; +@@ -654,7 +654,7 @@ static ssize_t pmbus_show_sensor(struct device *dev, + if (sensor->data < 0) + return sensor->data; + +- return snprintf(buf, PAGE_SIZE, "%d\n", pmbus_reg2data(data, sensor)); ++ return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor)); + } + + static ssize_t pmbus_set_sensor(struct device *dev, +@@ -700,6 +700,7 @@ do { \ + struct sensor_device_attribute *a \ + = &data->_type##s[data->num_##_type##s].attribute; \ + BUG_ON(data->num_attributes >= data->max_attributes); \ ++ sysfs_attr_init(&a->dev_attr.attr); \ + a->dev_attr.attr.name = _name; \ + a->dev_attr.attr.mode = _mode; \ + a->dev_attr.show = _show; \ +@@ -1517,14 +1518,9 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + +- /* +- * Bail out if status register or PMBus revision register +- * does not exist. +- */ +- if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0 +- || i2c_smbus_read_byte_data(client, PMBUS_REVISION) < 0) { +- dev_err(&client->dev, +- "Status or revision register not found\n"); ++ /* Bail out if PMBus status register does not exist. */ ++ if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) { ++ dev_err(&client->dev, "PMBus status register not found\n"); + ret = -ENODEV; + goto out_data; + } +diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c +index 92b42db..b39f52e 100644 +--- a/drivers/hwmon/s3c-hwmon.c ++++ b/drivers/hwmon/s3c-hwmon.c +@@ -232,6 +232,7 @@ static int s3c_hwmon_create_attr(struct device *dev, + + attr = &attrs->in; + attr->index = channel; ++ sysfs_attr_init(&attr->dev_attr.attr); + attr->dev_attr.attr.name = attrs->in_name; + attr->dev_attr.attr.mode = S_IRUGO; + attr->dev_attr.show = s3c_hwmon_ch_show; +@@ -249,6 +250,7 @@ static int s3c_hwmon_create_attr(struct device *dev, + + attr = &attrs->label; + attr->index = channel; ++ sysfs_attr_init(&attr->dev_attr.attr); + attr->dev_attr.attr.name = attrs->label_name; + attr->dev_attr.attr.mode = S_IRUGO; + attr->dev_attr.show = s3c_hwmon_label_show; +diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c +index dd39c1e..26c352a 100644 +--- a/drivers/i2c/busses/i2c-taos-evm.c ++++ b/drivers/i2c/busses/i2c-taos-evm.c +@@ -234,7 +234,7 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv) + + if (taos->state != TAOS_STATE_IDLE) { + err = -ENODEV; +- dev_dbg(&serio->dev, "TAOS EVM reset failed (state=%d, " ++ dev_err(&serio->dev, "TAOS EVM reset failed (state=%d, " + "pos=%d)\n", taos->state, taos->pos); + goto exit_close; + } +@@ -255,7 +255,7 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv) + msecs_to_jiffies(250)); + if (taos->state != TAOS_STATE_IDLE) { + err = -ENODEV; +- dev_err(&adapter->dev, "Echo off failed " ++ dev_err(&serio->dev, "TAOS EVM echo off failed " + "(state=%d)\n", taos->state); + goto exit_close; + } +@@ -263,7 +263,7 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv) + err = i2c_add_adapter(adapter); + if (err) + goto exit_close; +- dev_dbg(&serio->dev, "Connected to TAOS EVM\n"); ++ dev_info(&serio->dev, "Connected to TAOS EVM\n"); + + taos->client = taos_instantiate_device(adapter); + return 0; +@@ -288,7 +288,7 @@ static void taos_disconnect(struct serio *serio) + serio_set_drvdata(serio, NULL); + kfree(taos); + +- dev_dbg(&serio->dev, "Disconnected from TAOS EVM\n"); ++ dev_info(&serio->dev, "Disconnected from TAOS EVM\n"); + } + + static struct serio_device_id taos_serio_ids[] = { +diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c +index b4ab39b..5f1b92c 100644 +--- a/drivers/i2c/busses/i2c-tegra.c ++++ b/drivers/i2c/busses/i2c-tegra.c +@@ -330,6 +330,11 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) + i2c_writel(i2c_dev, 0, I2C_INT_MASK); + clk_set_rate(i2c_dev->clk, i2c_dev->bus_clk_rate * 8); + ++ if (!i2c_dev->is_dvc) { ++ u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG); ++ i2c_writel(i2c_dev, sl_cfg | I2C_SL_CNFG_NEWSL, I2C_SL_CNFG); ++ } ++ + val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT | + 0 << I2C_FIFO_CONTROL_RX_TRIG_SHIFT; + i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL); +diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c +index 54e1ce7..6f89536 100644 +--- a/drivers/i2c/muxes/pca954x.c ++++ b/drivers/i2c/muxes/pca954x.c +@@ -201,10 +201,11 @@ static int pca954x_probe(struct i2c_client *client, + + i2c_set_clientdata(client, data); + +- /* Read the mux register at addr to verify +- * that the mux is in fact present. ++ /* Write the mux register at addr to verify ++ * that the mux is in fact present. This also ++ * initializes the mux to disconnected state. + */ +- if (i2c_smbus_read_byte(client) < 0) { ++ if (i2c_smbus_write_byte(client, 0) < 0) { + dev_warn(&client->dev, "probe failed\n"); + goto exit_free; + } +diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c +index a5ec5a7..9560822 100644 +--- a/drivers/ide/ide-cd.c ++++ b/drivers/ide/ide-cd.c +@@ -1773,7 +1773,8 @@ static int ide_cd_probe(ide_drive_t *drive) + + g->minors = 1; + g->driverfs_dev = &drive->gendev; +- g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; ++ g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE | ++ GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; + if (ide_cdrom_setup(drive)) { + put_device(&info->dev); + goto failed; +diff --git a/drivers/input/input.c b/drivers/input/input.c +index ebbceed..e3c88fc 100644 +--- a/drivers/input/input.c ++++ b/drivers/input/input.c +@@ -1757,7 +1757,7 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) + } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { + mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - + dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, +- clamp(mt_slots, 2, 32); ++ mt_slots = clamp(mt_slots, 2, 32); + } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { + mt_slots = 2; + } else { +diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c +index 7630273..f8ba7c9 100644 +--- a/drivers/input/mousedev.c ++++ b/drivers/input/mousedev.c +@@ -187,7 +187,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, + if (size == 0) + size = xres ? : 1; + +- clamp(value, min, max); ++ value = clamp(value, min, max); + + mousedev->packet.x = ((value - min) * xres) / size; + mousedev->packet.abs_event = 1; +@@ -201,7 +201,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, + if (size == 0) + size = yres ? : 1; + +- clamp(value, min, max); ++ value = clamp(value, min, max); + + mousedev->packet.y = yres - ((value - min) * yres) / size; + mousedev->packet.abs_event = 1; +diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c +index 5c93627..70bd738 100644 +--- a/drivers/md/bitmap.c ++++ b/drivers/md/bitmap.c +@@ -493,11 +493,11 @@ void bitmap_update_sb(struct bitmap *bitmap) + spin_unlock_irqrestore(&bitmap->lock, flags); + sb = kmap_atomic(bitmap->sb_page, KM_USER0); + sb->events = cpu_to_le64(bitmap->mddev->events); +- if (bitmap->mddev->events < bitmap->events_cleared) { ++ if (bitmap->mddev->events < bitmap->events_cleared) + /* rocking back to read-only */ + bitmap->events_cleared = bitmap->mddev->events; +- sb->events_cleared = cpu_to_le64(bitmap->events_cleared); +- } ++ sb->events_cleared = cpu_to_le64(bitmap->events_cleared); ++ sb->state = cpu_to_le32(bitmap->flags); + /* Just in case these have been changed via sysfs: */ + sb->daemon_sleep = cpu_to_le32(bitmap->mddev->bitmap_info.daemon_sleep/HZ); + sb->write_behind = cpu_to_le32(bitmap->mddev->bitmap_info.max_write_behind); +@@ -618,7 +618,7 @@ success: + if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN) + bitmap->flags |= BITMAP_HOSTENDIAN; + bitmap->events_cleared = le64_to_cpu(sb->events_cleared); +- if (sb->state & cpu_to_le32(BITMAP_STALE)) ++ if (bitmap->flags & BITMAP_STALE) + bitmap->events_cleared = bitmap->mddev->events; + err = 0; + out: +@@ -652,9 +652,11 @@ static int bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits, + switch (op) { + case MASK_SET: + sb->state |= cpu_to_le32(bits); ++ bitmap->flags |= bits; + break; + case MASK_UNSET: + sb->state &= cpu_to_le32(~bits); ++ bitmap->flags &= ~bits; + break; + default: + BUG(); +diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c +index a550a05..aa4e570 100644 +--- a/drivers/md/dm-mpath.c ++++ b/drivers/md/dm-mpath.c +@@ -1290,7 +1290,7 @@ static int do_end_io(struct multipath *m, struct request *clone, + if (!error && !clone->errors) + return 0; /* I/O complete */ + +- if (error == -EOPNOTSUPP || error == -EREMOTEIO) ++ if (error == -EOPNOTSUPP || error == -EREMOTEIO || error == -EILSEQ) + return error; + + if (mpio->pgpath) +diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c +index cb8380c..53e603b 100644 +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -362,6 +362,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) + static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) + { ++ struct request_queue *q; + struct queue_limits *limits = data; + struct block_device *bdev = dev->bdev; + sector_t dev_size = +@@ -370,6 +371,22 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, + limits->logical_block_size >> SECTOR_SHIFT; + char b[BDEVNAME_SIZE]; + ++ /* ++ * Some devices exist without request functions, ++ * such as loop devices not yet bound to backing files. ++ * Forbid the use of such devices. ++ */ ++ q = bdev_get_queue(bdev); ++ if (!q || !q->make_request_fn) { ++ DMWARN("%s: %s is not yet initialised: " ++ "start=%llu, len=%llu, dev_size=%llu", ++ dm_device_name(ti->table->md), bdevname(bdev, b), ++ (unsigned long long)start, ++ (unsigned long long)len, ++ (unsigned long long)dev_size); ++ return 1; ++ } ++ + if (!dev_size) + return 0; + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 7d6f7f1..a7ed02c 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -2462,7 +2462,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) + if (rdev->raid_disk == -1) + return -EEXIST; + /* personality does all needed checks */ +- if (rdev->mddev->pers->hot_add_disk == NULL) ++ if (rdev->mddev->pers->hot_remove_disk == NULL) + return -EINVAL; + err = rdev->mddev->pers-> + hot_remove_disk(rdev->mddev, rdev->raid_disk); +@@ -4347,13 +4347,19 @@ static int md_alloc(dev_t dev, char *name) + disk->fops = &md_fops; + disk->private_data = mddev; + disk->queue = mddev->queue; ++ blk_queue_flush(mddev->queue, REQ_FLUSH | REQ_FUA); + /* Allow extended partitions. This makes the + * 'mdp' device redundant, but we can't really + * remove it now. + */ + disk->flags |= GENHD_FL_EXT_DEVT; +- add_disk(disk); + mddev->gendisk = disk; ++ /* As soon as we call add_disk(), another thread could get ++ * through to md_open, so make sure it doesn't get too far ++ */ ++ mutex_lock(&mddev->open_mutex); ++ add_disk(disk); ++ + error = kobject_init_and_add(&mddev->kobj, &md_ktype, + &disk_to_dev(disk)->kobj, "%s", "md"); + if (error) { +@@ -4367,8 +4373,7 @@ static int md_alloc(dev_t dev, char *name) + if (mddev->kobj.sd && + sysfs_create_group(&mddev->kobj, &md_bitmap_group)) + printk(KERN_DEBUG "pointless warning\n"); +- +- blk_queue_flush(mddev->queue, REQ_FLUSH | REQ_FUA); ++ mutex_unlock(&mddev->open_mutex); + abort: + mutex_unlock(&disks_mutex); + if (!error && mddev->kobj.sd) { +@@ -7057,6 +7062,7 @@ static int remove_and_add_spares(mddev_t *mddev) + list_for_each_entry(rdev, &mddev->disks, same_set) { + if (rdev->raid_disk >= 0 && + !test_bit(In_sync, &rdev->flags) && ++ !test_bit(Faulty, &rdev->flags) && + !test_bit(Blocked, &rdev->flags)) + spares++; + if (rdev->raid_disk < 0 +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 49bf5f8..3d13d11 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -129,7 +129,7 @@ static inline int raid5_dec_bi_hw_segments(struct bio *bio) + + static inline void raid5_set_bi_hw_segments(struct bio *bio, unsigned int cnt) + { +- bio->bi_phys_segments = raid5_bi_phys_segments(bio) || (cnt << 16); ++ bio->bi_phys_segments = raid5_bi_phys_segments(bio) | (cnt << 16); + } + + /* Find first data disk in a raid6 stripe */ +@@ -514,7 +514,7 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) + bi = &sh->dev[i].req; + + bi->bi_rw = rw; +- if (rw == WRITE) ++ if (rw & WRITE) + bi->bi_end_io = raid5_end_write_request; + else + bi->bi_end_io = raid5_end_read_request; +@@ -548,13 +548,13 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) + bi->bi_io_vec[0].bv_offset = 0; + bi->bi_size = STRIPE_SIZE; + bi->bi_next = NULL; +- if (rw == WRITE && ++ if ((rw & WRITE) && + test_bit(R5_ReWrite, &sh->dev[i].flags)) + atomic_add(STRIPE_SECTORS, + &rdev->corrected_errors); + generic_make_request(bi); + } else { +- if (rw == WRITE) ++ if (rw & WRITE) + set_bit(STRIPE_DEGRADED, &sh->state); + pr_debug("skip op %ld on disc %d for sector %llu\n", + bi->bi_rw, i, (unsigned long long)sh->sector); +diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c +index af5263c..7b42ace 100644 +--- a/drivers/media/media-devnode.c ++++ b/drivers/media/media-devnode.c +@@ -213,14 +213,14 @@ int __must_check media_devnode_register(struct media_devnode *mdev) + + /* Part 1: Find a free minor number */ + mutex_lock(&media_devnode_lock); +- minor = find_next_zero_bit(media_devnode_nums, 0, MEDIA_NUM_DEVICES); ++ minor = find_next_zero_bit(media_devnode_nums, MEDIA_NUM_DEVICES, 0); + if (minor == MEDIA_NUM_DEVICES) { + mutex_unlock(&media_devnode_lock); + printk(KERN_ERR "could not get a free minor\n"); + return -ENFILE; + } + +- set_bit(mdev->minor, media_devnode_nums); ++ set_bit(minor, media_devnode_nums); + mutex_unlock(&media_devnode_lock); + + mdev->minor = minor; +diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c +index deca2e0..c9f4a8e 100644 +--- a/drivers/media/radio/si4713-i2c.c ++++ b/drivers/media/radio/si4713-i2c.c +@@ -1033,7 +1033,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev, + char ps_name[MAX_RDS_PS_NAME + 1]; + + len = control->size - 1; +- if (len > MAX_RDS_PS_NAME) { ++ if (len < 0 || len > MAX_RDS_PS_NAME) { + rval = -ERANGE; + goto exit; + } +@@ -1057,7 +1057,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev, + char radio_text[MAX_RDS_RADIO_TEXT + 1]; + + len = control->size - 1; +- if (len > MAX_RDS_RADIO_TEXT) { ++ if (len < 0 || len > MAX_RDS_RADIO_TEXT) { + rval = -ERANGE; + goto exit; + } +diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c +index 11c19d8..423ed45 100644 +--- a/drivers/media/rc/ir-raw.c ++++ b/drivers/media/rc/ir-raw.c +@@ -114,18 +114,20 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) + s64 delta; /* ns */ + DEFINE_IR_RAW_EVENT(ev); + int rc = 0; ++ int delay; + + if (!dev->raw) + return -EINVAL; + + now = ktime_get(); + delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); ++ delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]); + + /* Check for a long duration since last event or if we're + * being called for the first time, note that delta can't + * possibly be negative. + */ +- if (delta > IR_MAX_DURATION || !dev->raw->last_type) ++ if (delta > delay || !dev->raw->last_type) + type |= IR_START_EVENT; + else + ev.duration = delta; +diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c +index 43908a7..c1717bf 100644 +--- a/drivers/media/rc/ite-cir.c ++++ b/drivers/media/rc/ite-cir.c +@@ -1357,6 +1357,7 @@ static const struct ite_dev_params ite_dev_descs[] = { + { /* 0: ITE8704 */ + .model = "ITE8704 CIR transceiver", + .io_region_size = IT87_IOREG_LENGTH, ++ .io_rsrc_no = 0, + .hw_tx_capable = true, + .sample_period = (u32) (1000000000ULL / 115200), + .tx_carrier_freq = 38000, +@@ -1381,6 +1382,7 @@ static const struct ite_dev_params ite_dev_descs[] = { + { /* 1: ITE8713 */ + .model = "ITE8713 CIR transceiver", + .io_region_size = IT87_IOREG_LENGTH, ++ .io_rsrc_no = 0, + .hw_tx_capable = true, + .sample_period = (u32) (1000000000ULL / 115200), + .tx_carrier_freq = 38000, +@@ -1405,6 +1407,7 @@ static const struct ite_dev_params ite_dev_descs[] = { + { /* 2: ITE8708 */ + .model = "ITE8708 CIR transceiver", + .io_region_size = IT8708_IOREG_LENGTH, ++ .io_rsrc_no = 0, + .hw_tx_capable = true, + .sample_period = (u32) (1000000000ULL / 115200), + .tx_carrier_freq = 38000, +@@ -1430,6 +1433,7 @@ static const struct ite_dev_params ite_dev_descs[] = { + { /* 3: ITE8709 */ + .model = "ITE8709 CIR transceiver", + .io_region_size = IT8709_IOREG_LENGTH, ++ .io_rsrc_no = 2, + .hw_tx_capable = true, + .sample_period = (u32) (1000000000ULL / 115200), + .tx_carrier_freq = 38000, +@@ -1471,6 +1475,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id + struct rc_dev *rdev = NULL; + int ret = -ENOMEM; + int model_no; ++ int io_rsrc_no; + + ite_dbg("%s called", __func__); + +@@ -1500,10 +1505,11 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id + + /* get the description for the device */ + dev_desc = &ite_dev_descs[model_no]; ++ io_rsrc_no = dev_desc->io_rsrc_no; + + /* validate pnp resources */ +- if (!pnp_port_valid(pdev, 0) || +- pnp_port_len(pdev, 0) != dev_desc->io_region_size) { ++ if (!pnp_port_valid(pdev, io_rsrc_no) || ++ pnp_port_len(pdev, io_rsrc_no) != dev_desc->io_region_size) { + dev_err(&pdev->dev, "IR PNP Port not valid!\n"); + goto failure; + } +@@ -1514,7 +1520,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id + } + + /* store resource values */ +- itdev->cir_addr = pnp_port_start(pdev, 0); ++ itdev->cir_addr = pnp_port_start(pdev, io_rsrc_no); + itdev->cir_irq = pnp_irq(pdev, 0); + + /* initialize spinlocks */ +diff --git a/drivers/media/rc/ite-cir.h b/drivers/media/rc/ite-cir.h +index 16a19f5..aa899a0 100644 +--- a/drivers/media/rc/ite-cir.h ++++ b/drivers/media/rc/ite-cir.h +@@ -57,6 +57,9 @@ struct ite_dev_params { + /* size of the I/O region */ + int io_region_size; + ++ /* IR pnp I/O resource number */ ++ int io_rsrc_no; ++ + /* true if the hardware supports transmission */ + bool hw_tx_capable; + +diff --git a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c +index bb10ffe..8d558ae 100644 +--- a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c ++++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c +@@ -15,43 +15,39 @@ + /* Pinnacle PCTV HD 800i mini remote */ + + static struct rc_map_table pinnacle_pctv_hd[] = { +- +- { 0x0f, KEY_1 }, +- { 0x15, KEY_2 }, +- { 0x10, KEY_3 }, +- { 0x18, KEY_4 }, +- { 0x1b, KEY_5 }, +- { 0x1e, KEY_6 }, +- { 0x11, KEY_7 }, +- { 0x21, KEY_8 }, +- { 0x12, KEY_9 }, +- { 0x27, KEY_0 }, +- +- { 0x24, KEY_ZOOM }, +- { 0x2a, KEY_SUBTITLE }, +- +- { 0x00, KEY_MUTE }, +- { 0x01, KEY_ENTER }, /* Pinnacle Logo */ +- { 0x39, KEY_POWER }, +- +- { 0x03, KEY_VOLUMEUP }, +- { 0x09, KEY_VOLUMEDOWN }, +- { 0x06, KEY_CHANNELUP }, +- { 0x0c, KEY_CHANNELDOWN }, +- +- { 0x2d, KEY_REWIND }, +- { 0x30, KEY_PLAYPAUSE }, +- { 0x33, KEY_FASTFORWARD }, +- { 0x3c, KEY_STOP }, +- { 0x36, KEY_RECORD }, +- { 0x3f, KEY_EPG }, /* Labeled "?" */ ++ /* Key codes for the tiny Pinnacle remote*/ ++ { 0x0700, KEY_MUTE }, ++ { 0x0701, KEY_MENU }, /* Pinnacle logo */ ++ { 0x0739, KEY_POWER }, ++ { 0x0703, KEY_VOLUMEUP }, ++ { 0x0709, KEY_VOLUMEDOWN }, ++ { 0x0706, KEY_CHANNELUP }, ++ { 0x070c, KEY_CHANNELDOWN }, ++ { 0x070f, KEY_1 }, ++ { 0x0715, KEY_2 }, ++ { 0x0710, KEY_3 }, ++ { 0x0718, KEY_4 }, ++ { 0x071b, KEY_5 }, ++ { 0x071e, KEY_6 }, ++ { 0x0711, KEY_7 }, ++ { 0x0721, KEY_8 }, ++ { 0x0712, KEY_9 }, ++ { 0x0727, KEY_0 }, ++ { 0x0724, KEY_ZOOM }, /* 'Square' key */ ++ { 0x072a, KEY_SUBTITLE }, /* 'T' key */ ++ { 0x072d, KEY_REWIND }, ++ { 0x0730, KEY_PLAYPAUSE }, ++ { 0x0733, KEY_FASTFORWARD }, ++ { 0x0736, KEY_RECORD }, ++ { 0x073c, KEY_STOP }, ++ { 0x073f, KEY_HELP }, /* '?' key */ + }; + + static struct rc_map_list pinnacle_pctv_hd_map = { + .map = { + .scan = pinnacle_pctv_hd, + .size = ARRAY_SIZE(pinnacle_pctv_hd), +- .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ ++ .rc_type = RC_TYPE_RC5, + .name = RC_MAP_PINNACLE_PCTV_HD, + } + }; +diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c +index 91399c9..3ea1a5d 100644 +--- a/drivers/media/video/bt8xx/bttv-driver.c ++++ b/drivers/media/video/bt8xx/bttv-driver.c +@@ -3474,7 +3474,7 @@ static int radio_s_tuner(struct file *file, void *priv, + if (0 != t->index) + return -EINVAL; + +- bttv_call_all(btv, tuner, g_tuner, t); ++ bttv_call_all(btv, tuner, s_tuner, t); + return 0; + } + +diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c +index 9933810..2a3fab1 100644 +--- a/drivers/media/video/cx23885/cx23885-core.c ++++ b/drivers/media/video/cx23885/cx23885-core.c +@@ -2060,12 +2060,8 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev, + goto fail_irq; + } + +- if (!pci_enable_msi(pci_dev)) +- err = request_irq(pci_dev->irq, cx23885_irq, +- IRQF_DISABLED, dev->name, dev); +- else +- err = request_irq(pci_dev->irq, cx23885_irq, +- IRQF_SHARED | IRQF_DISABLED, dev->name, dev); ++ err = request_irq(pci_dev->irq, cx23885_irq, ++ IRQF_SHARED | IRQF_DISABLED, dev->name, dev); + if (err < 0) { + printk(KERN_ERR "%s: can't get IRQ %d\n", + dev->name, pci_dev->irq); +@@ -2114,7 +2110,6 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev) + + /* unregister stuff */ + free_irq(pci_dev->irq, dev); +- pci_disable_msi(pci_dev); + + cx23885_dev_unregister(dev); + v4l2_device_unregister(v4l2_dev); +diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c +index bca307e..f637d34 100644 +--- a/drivers/media/video/cx88/cx88-blackbird.c ++++ b/drivers/media/video/cx88/cx88-blackbird.c +@@ -1122,7 +1122,6 @@ static int mpeg_release(struct file *file) + mutex_lock(&dev->core->lock); + file->private_data = NULL; + kfree(fh); +- mutex_unlock(&dev->core->lock); + + /* Make sure we release the hardware */ + drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); +@@ -1131,6 +1130,8 @@ static int mpeg_release(struct file *file) + + atomic_dec(&dev->core->mpeg_users); + ++ mutex_unlock(&dev->core->lock); ++ + return 0; + } + +@@ -1334,11 +1335,9 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) + blackbird_register_video(dev); + + /* initial device configuration: needed ? */ +- mutex_lock(&dev->core->lock); + // init_controls(core); + cx88_set_tvnorm(core,core->tvnorm); + cx88_video_mux(core,0); +- mutex_unlock(&dev->core->lock); + + return 0; + +diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c +index 7b8c9d3..c69df7e 100644 +--- a/drivers/media/video/cx88/cx88-dvb.c ++++ b/drivers/media/video/cx88/cx88-dvb.c +@@ -133,6 +133,7 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) + return -EINVAL; + } + ++ mutex_lock(&dev->core->lock); + drv = cx8802_get_driver(dev, CX88_MPEG_DVB); + if (drv) { + if (acquire){ +@@ -143,6 +144,7 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) + dev->frontends.active_fe_id = 0; + } + } ++ mutex_unlock(&dev->core->lock); + + return ret; + } +diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c +index addf954..497f26f 100644 +--- a/drivers/media/video/cx88/cx88-mpeg.c ++++ b/drivers/media/video/cx88/cx88-mpeg.c +@@ -624,13 +624,11 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) + + if (drv->advise_acquire) + { +- mutex_lock(&drv->core->lock); + core->active_ref++; + if (core->active_type_id == CX88_BOARD_NONE) { + core->active_type_id = drv->type_id; + drv->advise_acquire(drv); + } +- mutex_unlock(&drv->core->lock); + + mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); + } +@@ -643,14 +641,12 @@ static int cx8802_request_release(struct cx8802_driver *drv) + { + struct cx88_core *core = drv->core; + +- mutex_lock(&drv->core->lock); + if (drv->advise_release && --core->active_ref == 0) + { + drv->advise_release(drv); + core->active_type_id = CX88_BOARD_NONE; + mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); + } +- mutex_unlock(&drv->core->lock); + + return 0; + } +@@ -713,18 +709,17 @@ int cx8802_register_driver(struct cx8802_driver *drv) + drv->request_release = cx8802_request_release; + memcpy(driver, drv, sizeof(*driver)); + ++ mutex_lock(&drv->core->lock); + err = drv->probe(driver); + if (err == 0) { + i++; +- mutex_lock(&drv->core->lock); + list_add_tail(&driver->drvlist, &dev->drvlist); +- mutex_unlock(&drv->core->lock); + } else { + printk(KERN_ERR + "%s/2: cx8802 probe failed, err = %d\n", + dev->core->name, err); + } +- ++ mutex_unlock(&drv->core->lock); + } + + return i ? 0 : -ENODEV; +@@ -748,6 +743,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) + dev->pci->subsystem_device, dev->core->board.name, + dev->core->boardnr); + ++ mutex_lock(&dev->core->lock); ++ + list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) { + /* only unregister the correct driver type */ + if (d->type_id != drv->type_id) +@@ -755,15 +752,14 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) + + err = d->remove(d); + if (err == 0) { +- mutex_lock(&drv->core->lock); + list_del(&d->drvlist); +- mutex_unlock(&drv->core->lock); + kfree(d); + } else + printk(KERN_ERR "%s/2: cx8802 driver remove " + "failed (%d)\n", dev->core->name, err); + } + ++ mutex_unlock(&dev->core->lock); + } + + return err; +@@ -827,6 +823,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev) + + flush_request_modules(dev); + ++ mutex_lock(&dev->core->lock); ++ + if (!list_empty(&dev->drvlist)) { + struct cx8802_driver *drv, *tmp; + int err; +@@ -838,9 +836,7 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev) + list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) { + err = drv->remove(drv); + if (err == 0) { +- mutex_lock(&drv->core->lock); + list_del(&drv->drvlist); +- mutex_unlock(&drv->core->lock); + } else + printk(KERN_ERR "%s/2: cx8802 driver remove " + "failed (%d)\n", dev->core->name, err); +@@ -848,6 +844,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev) + } + } + ++ mutex_unlock(&dev->core->lock); ++ + /* Destroy any 8802 reference. */ + dev->core->dvbdev = NULL; + +diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h +index 9b3742a..3d32f4a 100644 +--- a/drivers/media/video/cx88/cx88.h ++++ b/drivers/media/video/cx88/cx88.h +@@ -505,6 +505,8 @@ struct cx8802_driver { + int (*suspend)(struct pci_dev *pci_dev, pm_message_t state); + int (*resume)(struct pci_dev *pci_dev); + ++ /* Callers to the following functions must hold core->lock */ ++ + /* MPEG 8802 -> mini driver - Driver probe and configuration */ + int (*probe)(struct cx8802_driver *drv); + int (*remove)(struct cx8802_driver *drv); +@@ -561,8 +563,9 @@ struct cx8802_dev { + /* for switching modulation types */ + unsigned char ts_gen_cntrl; + +- /* List of attached drivers */ ++ /* List of attached drivers; must hold core->lock to access */ + struct list_head drvlist; ++ + struct work_struct request_module_wk; + }; + +@@ -685,6 +688,8 @@ int cx88_audio_thread(void *data); + + int cx8802_register_driver(struct cx8802_driver *drv); + int cx8802_unregister_driver(struct cx8802_driver *drv); ++ ++/* Caller must hold core->lock */ + struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); + + /* ----------------------------------------------------------- */ +diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c +index 9d0dd08..e98d382 100644 +--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c ++++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c +@@ -3046,6 +3046,8 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) + if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) { + struct v4l2_tuner vt; + memset(&vt, 0, sizeof(vt)); ++ vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? ++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + vt.audmode = hdw->audiomode_val; + v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt); + } +@@ -5171,6 +5173,8 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw) + { + struct v4l2_tuner *vtp = &hdw->tuner_signal_info; + memset(vtp, 0, sizeof(*vtp)); ++ vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? ++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + hdw->tuner_signal_stale = 0; + /* Note: There apparently is no replacement for VIDIOC_CROPCAP + using v4l2-subdev - therefore we can't support that AT ALL right +diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c +index 9363ed9..1843fc2 100644 +--- a/drivers/media/video/tuner-core.c ++++ b/drivers/media/video/tuner-core.c +@@ -724,19 +724,15 @@ static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode) + } + + /** +- * set_mode_freq - Switch tuner to other mode. +- * @client: struct i2c_client pointer ++ * set_mode - Switch tuner to other mode. + * @t: a pointer to the module's internal struct_tuner + * @mode: enum v4l2_type (radio or TV) +- * @freq: frequency to set (0 means to use the previous one) + * + * If tuner doesn't support the needed mode (radio or TV), prints a + * debug message and returns -EINVAL, changing its state to standby. +- * Otherwise, changes the state and sets frequency to the last value, if +- * the tuner can sleep or if it supports both Radio and TV. ++ * Otherwise, changes the mode and returns 0. + */ +-static int set_mode_freq(struct i2c_client *client, struct tuner *t, +- enum v4l2_tuner_type mode, unsigned int freq) ++static int set_mode(struct tuner *t, enum v4l2_tuner_type mode) + { + struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; + +@@ -752,17 +748,27 @@ static int set_mode_freq(struct i2c_client *client, struct tuner *t, + t->mode = mode; + tuner_dbg("Changing to mode %d\n", mode); + } ++ return 0; ++} ++ ++/** ++ * set_freq - Set the tuner to the desired frequency. ++ * @t: a pointer to the module's internal struct_tuner ++ * @freq: frequency to set (0 means to use the current frequency) ++ */ ++static void set_freq(struct tuner *t, unsigned int freq) ++{ ++ struct i2c_client *client = v4l2_get_subdevdata(&t->sd); ++ + if (t->mode == V4L2_TUNER_RADIO) { +- if (freq) +- t->radio_freq = freq; +- set_radio_freq(client, t->radio_freq); ++ if (!freq) ++ freq = t->radio_freq; ++ set_radio_freq(client, freq); + } else { +- if (freq) +- t->tv_freq = freq; +- set_tv_freq(client, t->tv_freq); ++ if (!freq) ++ freq = t->tv_freq; ++ set_tv_freq(client, freq); + } +- +- return 0; + } + + /* +@@ -1058,10 +1064,9 @@ static void tuner_status(struct dvb_frontend *fe) + static int tuner_s_radio(struct v4l2_subdev *sd) + { + struct tuner *t = to_tuner(sd); +- struct i2c_client *client = v4l2_get_subdevdata(sd); + +- if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL) +- return 0; ++ if (set_mode(t, V4L2_TUNER_RADIO) == 0) ++ set_freq(t, 0); + return 0; + } + +@@ -1093,25 +1098,22 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on) + static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std) + { + struct tuner *t = to_tuner(sd); +- struct i2c_client *client = v4l2_get_subdevdata(sd); + +- if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL) ++ if (set_mode(t, V4L2_TUNER_ANALOG_TV)) + return 0; + + t->std = std; + tuner_fixup_std(t); +- ++ set_freq(t, 0); + return 0; + } + + static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) + { + struct tuner *t = to_tuner(sd); +- struct i2c_client *client = v4l2_get_subdevdata(sd); +- +- if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL) +- return 0; + ++ if (set_mode(t, f->type) == 0) ++ set_freq(t, f->frequency); + return 0; + } + +@@ -1180,13 +1182,13 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) + static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) + { + struct tuner *t = to_tuner(sd); +- struct i2c_client *client = v4l2_get_subdevdata(sd); + +- if (set_mode_freq(client, t, vt->type, 0) == -EINVAL) ++ if (set_mode(t, vt->type)) + return 0; + + if (t->mode == V4L2_TUNER_RADIO) + t->audmode = vt->audmode; ++ set_freq(t, 0); + + return 0; + } +@@ -1221,7 +1223,8 @@ static int tuner_resume(struct i2c_client *c) + tuner_dbg("resume\n"); + + if (!t->standby) +- set_mode_freq(c, t, t->type, 0); ++ if (set_mode(t, t->mode) == 0) ++ set_freq(t, 0); + + return 0; + } +diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c +index f14581b..48c5c57 100644 +--- a/drivers/media/video/uvc/uvc_queue.c ++++ b/drivers/media/video/uvc/uvc_queue.c +@@ -104,6 +104,8 @@ static int __uvc_free_buffers(struct uvc_video_queue *queue) + } + + if (queue->count) { ++ uvc_queue_cancel(queue, 0); ++ INIT_LIST_HEAD(&queue->mainqueue); + vfree(queue->mem); + queue->count = 0; + } +diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c +index 506edcc..a2e442a 100644 +--- a/drivers/media/video/v4l2-ioctl.c ++++ b/drivers/media/video/v4l2-ioctl.c +@@ -1822,6 +1822,8 @@ static long __video_do_ioctl(struct file *file, + if (!ops->vidioc_g_tuner) + break; + ++ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? ++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + ret = ops->vidioc_g_tuner(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, type=%d, " +@@ -1840,6 +1842,8 @@ static long __video_do_ioctl(struct file *file, + + if (!ops->vidioc_s_tuner) + break; ++ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? ++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "capability=0x%x, rangelow=%d, " + "rangehigh=%d, signal=%d, afc=%d, " +@@ -1858,6 +1862,8 @@ static long __video_do_ioctl(struct file *file, + if (!ops->vidioc_g_frequency) + break; + ++ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? ++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + ret = ops->vidioc_g_frequency(file, fh, p); + if (!ret) + dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", +diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c +index 3ab9ffa..55c5d47 100644 +--- a/drivers/mfd/omap-usb-host.c ++++ b/drivers/mfd/omap-usb-host.c +@@ -994,22 +994,33 @@ static void usbhs_disable(struct device *dev) + dev_dbg(dev, "operation timed out\n"); + } + +- if (pdata->ehci_data->phy_reset) { +- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) +- gpio_free(pdata->ehci_data->reset_gpio_port[0]); +- +- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) +- gpio_free(pdata->ehci_data->reset_gpio_port[1]); ++ if (is_omap_usbhs_rev2(omap)) { ++ if (is_ehci_tll_mode(pdata->port_mode[0])) ++ clk_enable(omap->usbtll_p1_fck); ++ if (is_ehci_tll_mode(pdata->port_mode[1])) ++ clk_enable(omap->usbtll_p2_fck); ++ clk_disable(omap->utmi_p2_fck); ++ clk_disable(omap->utmi_p1_fck); + } + +- clk_disable(omap->utmi_p2_fck); +- clk_disable(omap->utmi_p1_fck); + clk_disable(omap->usbtll_ick); + clk_disable(omap->usbtll_fck); + clk_disable(omap->usbhost_fs_fck); + clk_disable(omap->usbhost_hs_fck); + clk_disable(omap->usbhost_ick); + ++ /* The gpio_free migh sleep; so unlock the spinlock */ ++ spin_unlock_irqrestore(&omap->lock, flags); ++ ++ if (pdata->ehci_data->phy_reset) { ++ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) ++ gpio_free(pdata->ehci_data->reset_gpio_port[0]); ++ ++ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) ++ gpio_free(pdata->ehci_data->reset_gpio_port[1]); ++ } ++ return; ++ + end_disble: + spin_unlock_irqrestore(&omap->lock, flags); + } +diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c +index 81d7fa4..150cd70 100644 +--- a/drivers/misc/lkdtm.c ++++ b/drivers/misc/lkdtm.c +@@ -120,6 +120,7 @@ static int recur_count = REC_NUM_DEFAULT; + static enum cname cpoint = CN_INVALID; + static enum ctype cptype = CT_NONE; + static int count = DEFAULT_COUNT; ++static DEFINE_SPINLOCK(count_lock); + + module_param(recur_count, int, 0644); + MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ +@@ -230,11 +231,14 @@ static const char *cp_name_to_str(enum cname name) + static int lkdtm_parse_commandline(void) + { + int i; ++ unsigned long flags; + + if (cpoint_count < 1 || recur_count < 1) + return -EINVAL; + ++ spin_lock_irqsave(&count_lock, flags); + count = cpoint_count; ++ spin_unlock_irqrestore(&count_lock, flags); + + /* No special parameters */ + if (!cpoint_type && !cpoint_name) +@@ -349,6 +353,9 @@ static void lkdtm_do_action(enum ctype which) + + static void lkdtm_handler(void) + { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&count_lock, flags); + count--; + printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n", + cp_name_to_str(cpoint), cp_type_to_str(cptype), count); +@@ -357,6 +364,7 @@ static void lkdtm_handler(void) + lkdtm_do_action(cptype); + count = cpoint_count; + } ++ spin_unlock_irqrestore(&count_lock, flags); + } + + static int lkdtm_register_cpoint(enum cname which) +diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c +index a19967d..ba31abe 100644 +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -74,7 +74,7 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg) + if (boarddata && gpio_is_valid(boarddata->cd_gpio) + && gpio_get_value(boarddata->cd_gpio)) + /* no card, if a valid gpio says so... */ +- val &= SDHCI_CARD_PRESENT; ++ val &= ~SDHCI_CARD_PRESENT; + else + /* ... in all other cases assume card is present */ + val |= SDHCI_CARD_PRESENT; +diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c +index 710339a..b98196c 100644 +--- a/drivers/mmc/host/tmio_mmc_pio.c ++++ b/drivers/mmc/host/tmio_mmc_pio.c +@@ -760,8 +760,8 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc) + struct tmio_mmc_host *host = mmc_priv(mmc); + struct tmio_mmc_data *pdata = host->pdata; + +- return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) || +- !(sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)); ++ return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) || ++ (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)); + } + + static int tmio_mmc_get_cd(struct mmc_host *mmc) +diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c +index 5060e60..e601672 100644 +--- a/drivers/mtd/mtdconcat.c ++++ b/drivers/mtd/mtdconcat.c +@@ -319,7 +319,7 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + +- ops->retlen = 0; ++ ops->retlen = ops->oobretlen = 0; + + for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; +@@ -334,7 +334,7 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) + devops.len = subdev->size - to; + + err = subdev->write_oob(subdev, to, &devops); +- ops->retlen += devops.retlen; ++ ops->retlen += devops.oobretlen; + if (err) + return err; + +diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c +index c54a4cb..d1345fc 100644 +--- a/drivers/mtd/nand/nand_base.c ++++ b/drivers/mtd/nand/nand_base.c +@@ -3112,6 +3112,8 @@ ident_done: + chip->chip_shift += 32 - 1; + } + ++ chip->badblockbits = 8; ++ + /* Set the bad block position */ + if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16)) + chip->badblockpos = NAND_LARGE_BADBLOCK_POS; +diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c +index da9a351..2c8040f 100644 +--- a/drivers/mtd/nand/omap2.c ++++ b/drivers/mtd/nand/omap2.c +@@ -263,11 +263,10 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) + if (ret) { + /* PFPW engine is busy, use cpu copy method */ + if (info->nand.options & NAND_BUSWIDTH_16) +- omap_read_buf16(mtd, buf, len); ++ omap_read_buf16(mtd, (u_char *)p, len); + else +- omap_read_buf8(mtd, buf, len); ++ omap_read_buf8(mtd, (u_char *)p, len); + } else { +- p = (u32 *) buf; + do { + r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); + r_count = r_count >> 2; +@@ -293,7 +292,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd, + struct omap_nand_info, mtd); + uint32_t w_count = 0; + int i = 0, ret = 0; +- u16 *p; ++ u16 *p = (u16 *)buf; + unsigned long tim, limit; + + /* take care of subpage writes */ +@@ -309,11 +308,10 @@ static void omap_write_buf_pref(struct mtd_info *mtd, + if (ret) { + /* PFPW engine is busy, use cpu copy method */ + if (info->nand.options & NAND_BUSWIDTH_16) +- omap_write_buf16(mtd, buf, len); ++ omap_write_buf16(mtd, (u_char *)p, len); + else +- omap_write_buf8(mtd, buf, len); ++ omap_write_buf8(mtd, (u_char *)p, len); + } else { +- p = (u16 *) buf; + while (len) { + w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); + w_count = w_count >> 1; +diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c +index ba71582..a20bfef 100644 +--- a/drivers/net/bonding/bond_alb.c ++++ b/drivers/net/bonding/bond_alb.c +@@ -163,8 +163,6 @@ static int tlb_initialize(struct bonding *bond) + struct tlb_client_info *new_hashtbl; + int i; + +- spin_lock_init(&(bond_info->tx_hashtbl_lock)); +- + new_hashtbl = kzalloc(size, GFP_KERNEL); + if (!new_hashtbl) { + pr_err("%s: Error: Failed to allocate TLB hash table\n", +@@ -764,8 +762,6 @@ static int rlb_initialize(struct bonding *bond) + int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info); + int i; + +- spin_lock_init(&(bond_info->rx_hashtbl_lock)); +- + new_hashtbl = kmalloc(size, GFP_KERNEL); + if (!new_hashtbl) { + pr_err("%s: Error: Failed to allocate RLB hash table\n", +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 16d6fe9..ffb0fde 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1535,12 +1535,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) + bond_dev->name, slave_dev->name); + } + +- /* bond must be initialized by bond_open() before enslaving */ +- if (!(bond_dev->flags & IFF_UP)) { +- pr_warning("%s: master_dev is not up in bond_enslave\n", +- bond_dev->name); +- } +- + /* already enslaved */ + if (slave_dev->flags & IFF_SLAVE) { + pr_debug("Error, Device was already enslaved\n"); +@@ -4975,9 +4969,19 @@ static int bond_init(struct net_device *bond_dev) + { + struct bonding *bond = netdev_priv(bond_dev); + struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id); ++ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); + + pr_debug("Begin bond_init for %s\n", bond_dev->name); + ++ /* ++ * Initialize locks that may be required during ++ * en/deslave operations. All of the bond_open work ++ * (of which this is part) should really be moved to ++ * a phase prior to dev_open ++ */ ++ spin_lock_init(&(bond_info->tx_hashtbl_lock)); ++ spin_lock_init(&(bond_info->rx_hashtbl_lock)); ++ + bond->wq = create_singlethread_workqueue(bond_dev->name); + if (!bond->wq) + return -ENOMEM; +diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c +index de87aea..8a2717e 100644 +--- a/drivers/net/bonding/bond_sysfs.c ++++ b/drivers/net/bonding/bond_sysfs.c +@@ -227,12 +227,6 @@ static ssize_t bonding_store_slaves(struct device *d, + struct net_device *dev; + struct bonding *bond = to_bond(d); + +- /* Quick sanity check -- is the bond interface up? */ +- if (!(bond->dev->flags & IFF_UP)) { +- pr_warning("%s: doing slave updates when interface is down.\n", +- bond->dev->name); +- } +- + if (!rtnl_trylock()) + return restart_syscall(); + +diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c +index 3e5d0b6..0d28378 100644 +--- a/drivers/net/hamradio/6pack.c ++++ b/drivers/net/hamradio/6pack.c +@@ -692,10 +692,10 @@ static void sixpack_close(struct tty_struct *tty) + { + struct sixpack *sp; + +- write_lock(&disc_data_lock); ++ write_lock_bh(&disc_data_lock); + sp = tty->disc_data; + tty->disc_data = NULL; +- write_unlock(&disc_data_lock); ++ write_unlock_bh(&disc_data_lock); + if (!sp) + return; + +diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c +index 4c62839..bc02968 100644 +--- a/drivers/net/hamradio/mkiss.c ++++ b/drivers/net/hamradio/mkiss.c +@@ -813,10 +813,10 @@ static void mkiss_close(struct tty_struct *tty) + { + struct mkiss *ax; + +- write_lock(&disc_data_lock); ++ write_lock_bh(&disc_data_lock); + ax = tty->disc_data; + tty->disc_data = NULL; +- write_unlock(&disc_data_lock); ++ write_unlock_bh(&disc_data_lock); + + if (!ax) + return; +diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c +index 0dfd1b9..0e3fccb 100644 +--- a/drivers/net/igb/igb_main.c ++++ b/drivers/net/igb/igb_main.c +@@ -2372,6 +2372,9 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) + } + #endif /* CONFIG_PCI_IOV */ + adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus()); ++ /* i350 cannot do RSS and SR-IOV at the same time */ ++ if (hw->mac.type == e1000_i350 && adapter->vfs_allocated_count) ++ adapter->rss_queues = 1; + + /* + * if rss_queues > 4 or vfs are going to be allocated with rss_queues +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index 78e34e9..6d357d6 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -598,8 +598,8 @@ static int macvlan_port_create(struct net_device *dev) + err = netdev_rx_handler_register(dev, macvlan_handle_frame, port); + if (err) + kfree(port); +- +- dev->priv_flags |= IFF_MACVLAN_PORT; ++ else ++ dev->priv_flags |= IFF_MACVLAN_PORT; + return err; + } + +diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c +index 89f7540..5f597ca 100644 +--- a/drivers/net/pxa168_eth.c ++++ b/drivers/net/pxa168_eth.c +@@ -1273,7 +1273,7 @@ static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) + wmb(); + wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD); + +- stats->tx_bytes += skb->len; ++ stats->tx_bytes += length; + stats->tx_packets++; + dev->trans_start = jiffies; + if (pep->tx_ring_size - pep->tx_desc_count <= 1) { +diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c +index 1033ef6..f2b974d 100644 +--- a/drivers/net/usb/cdc_ncm.c ++++ b/drivers/net/usb/cdc_ncm.c +@@ -1254,6 +1254,7 @@ static struct usb_driver cdc_ncm_driver = { + .disconnect = cdc_ncm_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, ++ .reset_resume = usbnet_resume, + .supports_autosuspend = 1, + }; + +diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c +index 349a596..76d5089 100644 +--- a/drivers/net/wireless/ath/ath5k/base.c ++++ b/drivers/net/wireless/ath/ath5k/base.c +@@ -72,6 +72,11 @@ static int modparam_all_channels; + module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); + MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); + ++static int modparam_fastchanswitch; ++module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO); ++MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); ++ ++ + /* Module info */ + MODULE_AUTHOR("Jiri Slaby"); + MODULE_AUTHOR("Nick Kossifidis"); +@@ -2644,6 +2649,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, + struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); + int ret, ani_mode; ++ bool fast; + + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); + +@@ -2663,7 +2669,10 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, + ath5k_drain_tx_buffs(sc); + if (chan) + sc->curchan = chan; +- ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL, ++ ++ fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0; ++ ++ ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast, + skip_pcu); + if (ret) { + ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); +diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c +index efb672c..a33ae01 100644 +--- a/drivers/net/wireless/ath/ath5k/eeprom.c ++++ b/drivers/net/wireless/ath/ath5k/eeprom.c +@@ -1565,14 +1565,12 @@ ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) + if (!chinfo[pier].pd_curves) + continue; + +- for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { ++ for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) { + struct ath5k_pdgain_info *pd = + &chinfo[pier].pd_curves[pdg]; + +- if (pd != NULL) { +- kfree(pd->pd_step); +- kfree(pd->pd_pwr); +- } ++ kfree(pd->pd_step); ++ kfree(pd->pd_pwr); + } + + kfree(chinfo[pier].pd_curves); +diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c +index 3c44689..2e251f6 100644 +--- a/drivers/net/wireless/ath/ath5k/pci.c ++++ b/drivers/net/wireless/ath/ath5k/pci.c +@@ -265,7 +265,9 @@ ath5k_pci_remove(struct pci_dev *pdev) + #ifdef CONFIG_PM_SLEEP + static int ath5k_pci_suspend(struct device *dev) + { +- struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); ++ struct pci_dev *pdev = to_pci_dev(dev); ++ struct ieee80211_hw *hw = pci_get_drvdata(pdev); ++ struct ath5k_softc *sc = hw->priv; + + ath5k_led_off(sc); + return 0; +@@ -274,7 +276,8 @@ static int ath5k_pci_suspend(struct device *dev) + static int ath5k_pci_resume(struct device *dev) + { + struct pci_dev *pdev = to_pci_dev(dev); +- struct ath5k_softc *sc = pci_get_drvdata(pdev); ++ struct ieee80211_hw *hw = pci_get_drvdata(pdev); ++ struct ath5k_softc *sc = hw->priv; + + /* + * Suspend/Resume resets the PCI configuration space, so we have to +diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c +index 8420689..6f53d2b 100644 +--- a/drivers/net/wireless/ath/ath5k/reset.c ++++ b/drivers/net/wireless/ath/ath5k/reset.c +@@ -1119,8 +1119,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, + /* Non fatal, can happen eg. + * on mode change */ + ret = 0; +- } else ++ } else { ++ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET, ++ "fast chan change successful\n"); + return 0; ++ } + } + + /* +diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c +index 929c68c..a073cdc 100644 +--- a/drivers/net/wireless/ath/ath5k/sysfs.c ++++ b/drivers/net/wireless/ath/ath5k/sysfs.c +@@ -10,7 +10,8 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ + { \ +- struct ath5k_softc *sc = dev_get_drvdata(dev); \ ++ struct ieee80211_hw *hw = dev_get_drvdata(dev); \ ++ struct ath5k_softc *sc = hw->priv; \ + return snprintf(buf, PAGE_SIZE, "%d\n", get); \ + } \ + \ +@@ -18,7 +19,8 @@ static ssize_t ath5k_attr_store_##name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ + { \ +- struct ath5k_softc *sc = dev_get_drvdata(dev); \ ++ struct ieee80211_hw *hw = dev_get_drvdata(dev); \ ++ struct ath5k_softc *sc = hw->priv; \ + int val; \ + \ + val = (int)simple_strtoul(buf, NULL, 10); \ +@@ -33,7 +35,8 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ + { \ +- struct ath5k_softc *sc = dev_get_drvdata(dev); \ ++ struct ieee80211_hw *hw = dev_get_drvdata(dev); \ ++ struct ath5k_softc *sc = hw->priv; \ + return snprintf(buf, PAGE_SIZE, "%d\n", get); \ + } \ + static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL) +diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +index 6eadf97..db4416c 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +@@ -652,7 +652,7 @@ static const struct ar9300_eeprom ar9300_x113 = { + .regDmn = { LE16(0), LE16(0x1f) }, + .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ + .opCapFlags = { +- .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, ++ .opFlags = AR5416_OPFLAGS_11A, + .eepMisc = 0, + }, + .rfSilent = 0, +@@ -922,7 +922,7 @@ static const struct ar9300_eeprom ar9300_x113 = { + .db_stage2 = {3, 3, 3}, /* 3 chain */ + .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ + .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ +- .xpaBiasLvl = 0, ++ .xpaBiasLvl = 0xf, + .txFrameToDataStart = 0x0e, + .txFrameToPaOn = 0x0e, + .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ +@@ -3994,6 +3994,16 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) + POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0) + ); + ++ /* Write the power for duplicated frames - HT40 */ ++ ++ /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */ ++ REG_WRITE(ah, 0xa3e0, ++ POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) | ++ POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) | ++ POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) | ++ POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0) ++ ); ++ + /* Write the HT20 power per rate set */ + + /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */ +@@ -4588,10 +4598,16 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, + case 1: + break; + case 2: +- scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; ++ if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) ++ scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; ++ else ++ scaledPower = 0; + break; + case 3: +- scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; ++ if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) ++ scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; ++ else ++ scaledPower = 0; + break; + } + +diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c +index 8649581..fe3c10e 100644 +--- a/drivers/net/wireless/ath/ath9k/calib.c ++++ b/drivers/net/wireless/ath/ath9k/calib.c +@@ -69,15 +69,21 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, + int16_t *nfarray) + { + struct ath_common *common = ath9k_hw_common(ah); ++ struct ieee80211_conf *conf = &common->hw->conf; + struct ath_nf_limits *limit; + struct ath9k_nfcal_hist *h; + bool high_nf_mid = false; ++ u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; + int i; + + h = cal->nfCalHist; + limit = ath9k_hw_get_nf_limits(ah, ah->curchan); + + for (i = 0; i < NUM_NF_READINGS; i++) { ++ if (!(chainmask & (1 << i)) || ++ ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))) ++ continue; ++ + h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; + + if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX) +@@ -225,6 +231,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) + int32_t val; + u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; + struct ath_common *common = ath9k_hw_common(ah); ++ struct ieee80211_conf *conf = &common->hw->conf; + s16 default_nf = ath9k_hw_get_default_nf(ah, chan); + + if (ah->caldata) +@@ -234,6 +241,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) + if (chainmask & (1 << i)) { + s16 nfval; + ++ if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)) ++ continue; ++ + if (h) + nfval = h[i].privNF; + else +@@ -293,6 +303,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) + ENABLE_REGWRITE_BUFFER(ah); + for (i = 0; i < NUM_NF_READINGS; i++) { + if (chainmask & (1 << i)) { ++ if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)) ++ continue; ++ + val = REG_READ(ah, ah->nf_regs[i]); + val &= 0xFFFFFE00; + val |= (((u32) (-50) << 1) & 0x1ff); +diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c +index 8cd8333..945e448 100644 +--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c ++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c +@@ -522,10 +522,16 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah, + case 1: + break; + case 2: +- scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; ++ if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) ++ scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; ++ else ++ scaledPower = 0; + break; + case 3: +- scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; ++ if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) ++ scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; ++ else ++ scaledPower = 0; + break; + } + scaledPower = max((u16)0, scaledPower); +diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c +index 1482fa6..846bb4f 100644 +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -633,7 +633,8 @@ void ath9k_tasklet(unsigned long data) + u32 status = sc->intrstatus; + u32 rxmask; + +- if (status & ATH9K_INT_FATAL) { ++ if ((status & ATH9K_INT_FATAL) || ++ (status & ATH9K_INT_BB_WATCHDOG)) { + ath_reset(sc, true); + return; + } +@@ -699,6 +700,7 @@ irqreturn_t ath_isr(int irq, void *dev) + { + #define SCHED_INTR ( \ + ATH9K_INT_FATAL | \ ++ ATH9K_INT_BB_WATCHDOG | \ + ATH9K_INT_RXORN | \ + ATH9K_INT_RXEOL | \ + ATH9K_INT_RX | \ +diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c +index 9c65459..e137212 100644 +--- a/drivers/net/wireless/ath/ath9k/pci.c ++++ b/drivers/net/wireless/ath/ath9k/pci.c +@@ -278,6 +278,12 @@ static int ath_pci_suspend(struct device *device) + + ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); + ++ /* The device has to be moved to FULLSLEEP forcibly. ++ * Otherwise the chip never moved to full sleep, ++ * when no interface is up. ++ */ ++ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); ++ + return 0; + } + +diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c +index 4c0d36a..a39dfc4 100644 +--- a/drivers/net/wireless/ath/ath9k/rc.c ++++ b/drivers/net/wireless/ath/ath9k/rc.c +@@ -689,7 +689,8 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table, + + if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) { + rate->flags |= IEEE80211_TX_RC_MCS; +- if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) ++ if (WLAN_RC_PHY_40(rate_table->info[rix].phy) && ++ conf_is_ht40(&txrc->hw->conf)) + rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy)) + rate->flags |= IEEE80211_TX_RC_SHORT_GI; +diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c +index 88fa7fd..4f2c8df 100644 +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -662,7 +662,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, + * TODO - this could be improved to be dependent on the rate. + * The hardware can keep up at lower rates, but not higher rates + */ +- if (fi->keyix != ATH9K_TXKEYIX_INVALID) ++ if ((fi->keyix != ATH9K_TXKEYIX_INVALID) && ++ !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) + ndelim += ATH_AGGR_ENCRYPTDELIM; + + /* +diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c +index 2fb53d0..333b69e 100644 +--- a/drivers/net/wireless/ath/carl9170/usb.c ++++ b/drivers/net/wireless/ath/carl9170/usb.c +@@ -112,6 +112,8 @@ static struct usb_device_id carl9170_usb_ids[] = { + { USB_DEVICE(0x04bb, 0x093f) }, + /* NEC WL300NU-G */ + { USB_DEVICE(0x0409, 0x0249) }, ++ /* NEC WL300NU-AG */ ++ { USB_DEVICE(0x0409, 0x02b4) }, + /* AVM FRITZ!WLAN USB Stick N */ + { USB_DEVICE(0x057c, 0x8401) }, + /* AVM FRITZ!WLAN USB Stick N 2.4 */ +diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c +index 5a8a3cc..455f1f7 100644 +--- a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c ++++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c +@@ -628,11 +628,11 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, + + /* rx_status carries information about the packet to mac80211 */ + rx_status.mactime = le64_to_cpu(phy_res->timestamp); ++ rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? ++ IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + rx_status.freq = + ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), + rx_status.band); +- rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? +- IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + rx_status.rate_idx = + iwl4965_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); + rx_status.flag = 0; +diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c +index f5433c7..facc94e 100644 +--- a/drivers/net/wireless/iwlegacy/iwl-4965.c ++++ b/drivers/net/wireless/iwlegacy/iwl-4965.c +@@ -1218,10 +1218,10 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c + * receive commit_rxon request + * abort any previous channel switch if still in process + */ +- if (priv->switch_rxon.switch_in_progress && +- (priv->switch_rxon.channel != ctx->staging.channel)) { ++ if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) && ++ (priv->switch_channel != ctx->staging.channel)) { + IWL_DEBUG_11H(priv, "abort channel switch on %d\n", +- le16_to_cpu(priv->switch_rxon.channel)); ++ le16_to_cpu(priv->switch_channel)); + iwl_legacy_chswitch_done(priv, false); + } + +@@ -1237,7 +1237,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c + + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + iwl_legacy_print_rx_config_cmd(priv, ctx); +- return 0; ++ goto set_tx_power; + } + + /* If we are currently associated and the new config requires +@@ -1317,6 +1317,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c + + iwl4965_init_sensitivity(priv); + ++set_tx_power: + /* If we issue a new RXON command which required a tune then we must + * send a new TXPOWER command or we won't be able to Tx any frames */ + ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); +@@ -1403,9 +1404,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, + return rc; + } + +- priv->switch_rxon.channel = cmd.channel; +- priv->switch_rxon.switch_in_progress = true; +- + return iwl_legacy_send_cmd_pdu(priv, + REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); + } +@@ -1543,7 +1541,7 @@ static void iwl4965_temperature_calib(struct iwl_priv *priv) + s32 temp; + + temp = iwl4965_hw_get_temperature(priv); +- if (temp < 0) ++ if (IWL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(temp)) + return; + + if (priv->temperature != temp) { +diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c +index 42db0fc..8ad7922 100644 +--- a/drivers/net/wireless/iwlegacy/iwl-core.c ++++ b/drivers/net/wireless/iwlegacy/iwl-core.c +@@ -862,12 +862,8 @@ void iwl_legacy_chswitch_done(struct iwl_priv *priv, bool is_success) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + +- if (priv->switch_rxon.switch_in_progress) { ++ if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) + ieee80211_chswitch_done(ctx->vif, is_success); +- mutex_lock(&priv->mutex); +- priv->switch_rxon.switch_in_progress = false; +- mutex_unlock(&priv->mutex); +- } + } + EXPORT_SYMBOL(iwl_legacy_chswitch_done); + +@@ -879,19 +875,19 @@ void iwl_legacy_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct iwl_legacy_rxon_cmd *rxon = (void *)&ctx->active; + +- if (priv->switch_rxon.switch_in_progress) { +- if (!le32_to_cpu(csa->status) && +- (csa->channel == priv->switch_rxon.channel)) { +- rxon->channel = csa->channel; +- ctx->staging.channel = csa->channel; +- IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", +- le16_to_cpu(csa->channel)); +- iwl_legacy_chswitch_done(priv, true); +- } else { +- IWL_ERR(priv, "CSA notif (fail) : channel %d\n", ++ if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) ++ return; ++ ++ if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { ++ rxon->channel = csa->channel; ++ ctx->staging.channel = csa->channel; ++ IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", + le16_to_cpu(csa->channel)); +- iwl_legacy_chswitch_done(priv, false); +- } ++ iwl_legacy_chswitch_done(priv, true); ++ } else { ++ IWL_ERR(priv, "CSA notif (fail) : channel %d\n", ++ le16_to_cpu(csa->channel)); ++ iwl_legacy_chswitch_done(priv, false); + } + } + EXPORT_SYMBOL(iwl_legacy_rx_csa); +diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h +index f03b463..e49176a 100644 +--- a/drivers/net/wireless/iwlegacy/iwl-core.h ++++ b/drivers/net/wireless/iwlegacy/iwl-core.h +@@ -561,7 +561,7 @@ void iwl_legacy_free_geos(struct iwl_priv *priv); + #define STATUS_SCAN_HW 15 + #define STATUS_POWER_PMI 16 + #define STATUS_FW_ERROR 17 +- ++#define STATUS_CHANNEL_SWITCH_PENDING 18 + + static inline int iwl_legacy_is_ready(struct iwl_priv *priv) + { +diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h +index f43ac1e..54f89b4 100644 +--- a/drivers/net/wireless/iwlegacy/iwl-dev.h ++++ b/drivers/net/wireless/iwlegacy/iwl-dev.h +@@ -854,17 +854,6 @@ struct traffic_stats { + }; + + /* +- * iwl_switch_rxon: "channel switch" structure +- * +- * @ switch_in_progress: channel switch in progress +- * @ channel: new channel +- */ +-struct iwl_switch_rxon { +- bool switch_in_progress; +- __le16 channel; +-}; +- +-/* + * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds + * to perform continuous uCode event logging operation if enabled + */ +@@ -1115,7 +1104,7 @@ struct iwl_priv { + + struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; + +- struct iwl_switch_rxon switch_rxon; ++ __le16 switch_channel; + + /* 1st responses from initialize and runtime uCode images. + * _4965's initialize alive response contains some calibration data. */ +diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c +index a62fe24..d654876 100644 +--- a/drivers/net/wireless/iwlegacy/iwl4965-base.c ++++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c +@@ -2851,16 +2851,13 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, + goto out_exit; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || +- test_bit(STATUS_SCANNING, &priv->status)) ++ test_bit(STATUS_SCANNING, &priv->status) || ++ test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) + goto out_exit; + + if (!iwl_legacy_is_associated_ctx(ctx)) + goto out_exit; + +- /* channel switch in progress */ +- if (priv->switch_rxon.switch_in_progress == true) +- goto out_exit; +- + mutex_lock(&priv->mutex); + if (priv->cfg->ops->lib->set_channel_switch) { + +@@ -2910,16 +2907,20 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, + * at this point, staging_rxon has the + * configuration for channel switch + */ ++ set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); ++ priv->switch_channel = cpu_to_le16(ch); + if (priv->cfg->ops->lib->set_channel_switch(priv, +- ch_switch)) +- priv->switch_rxon.switch_in_progress = false; ++ ch_switch)) { ++ clear_bit(STATUS_CHANNEL_SWITCH_PENDING, ++ &priv->status); ++ priv->switch_channel = 0; ++ ieee80211_chswitch_done(ctx->vif, false); ++ } + } + } + out: + mutex_unlock(&priv->mutex); + out_exit: +- if (!priv->switch_rxon.switch_in_progress) +- ieee80211_chswitch_done(ctx->vif, false); + IWL_DEBUG_MAC80211(priv, "leave\n"); + } + +diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c +index d7b6126..d474cf3 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-2000.c ++++ b/drivers/net/wireless/iwlwifi/iwl-2000.c +@@ -181,79 +181,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) + return 0; + } + +-static int iwl2030_hw_channel_switch(struct iwl_priv *priv, +- struct ieee80211_channel_switch *ch_switch) +-{ +- /* +- * MULTI-FIXME +- * See iwl_mac_channel_switch. +- */ +- struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; +- struct iwl6000_channel_switch_cmd cmd; +- const struct iwl_channel_info *ch_info; +- u32 switch_time_in_usec, ucode_switch_time; +- u16 ch; +- u32 tsf_low; +- u8 switch_count; +- u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); +- struct ieee80211_vif *vif = ctx->vif; +- struct iwl_host_cmd hcmd = { +- .id = REPLY_CHANNEL_SWITCH, +- .len = sizeof(cmd), +- .flags = CMD_SYNC, +- .data = &cmd, +- }; +- +- cmd.band = priv->band == IEEE80211_BAND_2GHZ; +- ch = ch_switch->channel->hw_value; +- IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", +- ctx->active.channel, ch); +- cmd.channel = cpu_to_le16(ch); +- cmd.rxon_flags = ctx->staging.flags; +- cmd.rxon_filter_flags = ctx->staging.filter_flags; +- switch_count = ch_switch->count; +- tsf_low = ch_switch->timestamp & 0x0ffffffff; +- /* +- * calculate the ucode channel switch time +- * adding TSF as one of the factor for when to switch +- */ +- if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { +- if (switch_count > ((priv->ucode_beacon_time - tsf_low) / +- beacon_interval)) { +- switch_count -= (priv->ucode_beacon_time - +- tsf_low) / beacon_interval; +- } else +- switch_count = 0; +- } +- if (switch_count <= 1) +- cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); +- else { +- switch_time_in_usec = +- vif->bss_conf.beacon_int * switch_count * TIME_UNIT; +- ucode_switch_time = iwl_usecs_to_beacons(priv, +- switch_time_in_usec, +- beacon_interval); +- cmd.switch_time = iwl_add_beacon_time(priv, +- priv->ucode_beacon_time, +- ucode_switch_time, +- beacon_interval); +- } +- IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", +- cmd.switch_time); +- ch_info = iwl_get_channel_info(priv, priv->band, ch); +- if (ch_info) +- cmd.expect_beacon = is_channel_radar(ch_info); +- else { +- IWL_ERR(priv, "invalid channel switch from %u to %u\n", +- ctx->active.channel, ch); +- return -EFAULT; +- } +- priv->switch_rxon.channel = cmd.channel; +- priv->switch_rxon.switch_in_progress = true; +- +- return iwl_send_cmd_sync(priv, &hcmd); +-} +- + static struct iwl_lib_ops iwl2000_lib = { + .set_hw_params = iwl2000_hw_set_hw_params, + .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, +@@ -277,7 +204,6 @@ static struct iwl_lib_ops iwl2000_lib = { + .alive_notify = iwlagn_alive_notify, + .send_tx_power = iwlagn_send_tx_power, + .update_chain_flags = iwl_update_chain_flags, +- .set_channel_switch = iwl2030_hw_channel_switch, + .apm_ops = { + .init = iwl_apm_init, + .config = iwl2000_nic_config, +diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c +index 22e045b..dcf40e8 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-5000.c ++++ b/drivers/net/wireless/iwlwifi/iwl-5000.c +@@ -337,8 +337,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, + ctx->active.channel, ch); + return -EFAULT; + } +- priv->switch_rxon.channel = cmd.channel; +- priv->switch_rxon.switch_in_progress = true; + + return iwl_send_cmd_sync(priv, &hcmd); + } +@@ -513,7 +511,6 @@ static struct iwl_base_params iwl5000_base_params = { + }; + static struct iwl_ht_params iwl5000_ht_params = { + .ht_greenfield_support = true, +- .use_rts_for_aggregation = true, /* use rts/cts protection */ + }; + + #define IWL_DEVICE_5000 \ +diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c +index a745b01..9035255 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-6000.c ++++ b/drivers/net/wireless/iwlwifi/iwl-6000.c +@@ -277,8 +277,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, + ctx->active.channel, ch); + return -EFAULT; + } +- priv->switch_rxon.channel = cmd.channel; +- priv->switch_rxon.switch_in_progress = true; + + return iwl_send_cmd_sync(priv, &hcmd); + } +diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +index 41543ad..129a551 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c ++++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +@@ -217,17 +217,9 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv, + __le16 fc, __le32 *tx_flags) + { + if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS || +- info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { ++ info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT || ++ info->flags & IEEE80211_TX_CTL_AMPDU) + *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; +- return; +- } +- +- if (priv->cfg->ht_params && +- priv->cfg->ht_params->use_rts_for_aggregation && +- info->flags & IEEE80211_TX_CTL_AMPDU) { +- *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; +- return; +- } + } + + /* Calc max signal level (dBm) among 3 possible receivers */ +diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +index fbbde07..7c0f80c 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c ++++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +@@ -173,6 +173,14 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) + return 0; + } + ++ /* ++ * force CTS-to-self frames protection if RTS-CTS is not preferred ++ * one aggregation protection method ++ */ ++ if (!(priv->cfg->ht_params && ++ priv->cfg->ht_params->use_rts_for_aggregation)) ++ ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; ++ + if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || + !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; +@@ -189,10 +197,10 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) + * receive commit_rxon request + * abort any previous channel switch if still in process + */ +- if (priv->switch_rxon.switch_in_progress && +- (priv->switch_rxon.channel != ctx->staging.channel)) { ++ if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) && ++ (priv->switch_channel != ctx->staging.channel)) { + IWL_DEBUG_11H(priv, "abort channel switch on %d\n", +- le16_to_cpu(priv->switch_rxon.channel)); ++ le16_to_cpu(priv->switch_channel)); + iwl_chswitch_done(priv, false); + } + +@@ -210,6 +218,11 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) + + memcpy(active, &ctx->staging, sizeof(*active)); + iwl_print_rx_config_cmd(priv, ctx); ++ /* ++ * We do not commit tx power settings while channel changing, ++ * do it now if after settings changed. ++ */ ++ iwl_set_tx_power(priv, priv->tx_power_next, false); + return 0; + } + +diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c +index 321b18b..5941e61 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-agn.c ++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c +@@ -3461,16 +3461,13 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, + goto out_exit; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || +- test_bit(STATUS_SCANNING, &priv->status)) ++ test_bit(STATUS_SCANNING, &priv->status) || ++ test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) + goto out_exit; + + if (!iwl_is_associated_ctx(ctx)) + goto out_exit; + +- /* channel switch in progress */ +- if (priv->switch_rxon.switch_in_progress == true) +- goto out_exit; +- + mutex_lock(&priv->mutex); + if (priv->cfg->ops->lib->set_channel_switch) { + +@@ -3520,16 +3517,20 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, + * at this point, staging_rxon has the + * configuration for channel switch + */ ++ set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); ++ priv->switch_channel = cpu_to_le16(ch); + if (priv->cfg->ops->lib->set_channel_switch(priv, +- ch_switch)) +- priv->switch_rxon.switch_in_progress = false; ++ ch_switch)) { ++ clear_bit(STATUS_CHANNEL_SWITCH_PENDING, ++ &priv->status); ++ priv->switch_channel = 0; ++ ieee80211_chswitch_done(ctx->vif, false); ++ } + } + } + out: + mutex_unlock(&priv->mutex); + out_exit: +- if (!priv->switch_rxon.switch_in_progress) +- ieee80211_chswitch_done(ctx->vif, false); + IWL_DEBUG_MAC80211(priv, "leave\n"); + } + +diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c +index bafbe57..7fd7fe6 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-core.c ++++ b/drivers/net/wireless/iwlwifi/iwl-core.c +@@ -861,12 +861,8 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + +- if (priv->switch_rxon.switch_in_progress) { ++ if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) + ieee80211_chswitch_done(ctx->vif, is_success); +- mutex_lock(&priv->mutex); +- priv->switch_rxon.switch_in_progress = false; +- mutex_unlock(&priv->mutex); +- } + } + + #ifdef CONFIG_IWLWIFI_DEBUG +@@ -1776,6 +1772,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + struct iwl_rxon_context *tmp; ++ enum nl80211_iftype newviftype = newtype; + u32 interface_modes; + int err; + +@@ -1783,6 +1780,15 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + + mutex_lock(&priv->mutex); + ++ if (!ctx->vif || !iwl_is_ready_rf(priv)) { ++ /* ++ * Huh? But wait ... this can maybe happen when ++ * we're in the middle of a firmware restart! ++ */ ++ err = -EBUSY; ++ goto out; ++ } ++ + interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; + + if (!(interface_modes & BIT(newtype))) { +@@ -1809,7 +1815,8 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + + /* success */ + iwl_teardown_interface(priv, vif, true); +- vif->type = newtype; ++ vif->type = newviftype; ++ vif->p2p = newp2p; + err = iwl_setup_interface(priv, ctx); + WARN_ON(err); + /* +diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h +index b316d83..92f65b6 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-core.h ++++ b/drivers/net/wireless/iwlwifi/iwl-core.h +@@ -662,7 +662,7 @@ void iwlcore_free_geos(struct iwl_priv *priv); + #define STATUS_SCAN_HW 15 + #define STATUS_POWER_PMI 16 + #define STATUS_FW_ERROR 17 +- ++#define STATUS_CHANNEL_SWITCH_PENDING 19 + + static inline int iwl_is_ready(struct iwl_priv *priv) + { +diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h +index 68b953f..65a16ae 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-dev.h ++++ b/drivers/net/wireless/iwlwifi/iwl-dev.h +@@ -1037,17 +1037,6 @@ struct traffic_stats { + }; + + /* +- * iwl_switch_rxon: "channel switch" structure +- * +- * @ switch_in_progress: channel switch in progress +- * @ channel: new channel +- */ +-struct iwl_switch_rxon { +- bool switch_in_progress; +- __le16 channel; +-}; +- +-/* + * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds + * to perform continuous uCode event logging operation if enabled + */ +@@ -1344,7 +1333,7 @@ struct iwl_priv { + + struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; + +- struct iwl_switch_rxon switch_rxon; ++ __le16 switch_channel; + + /* 1st responses from initialize and runtime uCode images. + * _agn's initialize alive response contains some calibration data. */ +@@ -1658,21 +1647,24 @@ iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) + ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \ + if (priv->valid_contexts & BIT(ctx->ctxid)) + +-static inline int iwl_is_associated(struct iwl_priv *priv, +- enum iwl_rxon_context_id ctxid) ++static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx) + { +- return (priv->contexts[ctxid].active.filter_flags & +- RXON_FILTER_ASSOC_MSK) ? 1 : 0; ++ return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; + } + +-static inline int iwl_is_any_associated(struct iwl_priv *priv) ++static inline int iwl_is_associated(struct iwl_priv *priv, ++ enum iwl_rxon_context_id ctxid) + { +- return iwl_is_associated(priv, IWL_RXON_CTX_BSS); ++ return iwl_is_associated_ctx(&priv->contexts[ctxid]); + } + +-static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx) ++static inline int iwl_is_any_associated(struct iwl_priv *priv) + { +- return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; ++ struct iwl_rxon_context *ctx; ++ for_each_context(priv, ctx) ++ if (iwl_is_associated_ctx(ctx)) ++ return true; ++ return false; + } + + static inline int is_channel_valid(const struct iwl_channel_info *ch_info) +diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c +index 6f9a2fa..8055910 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-rx.c ++++ b/drivers/net/wireless/iwlwifi/iwl-rx.c +@@ -299,19 +299,19 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct iwl_rxon_cmd *rxon = (void *)&ctx->active; + +- if (priv->switch_rxon.switch_in_progress) { +- if (!le32_to_cpu(csa->status) && +- (csa->channel == priv->switch_rxon.channel)) { +- rxon->channel = csa->channel; +- ctx->staging.channel = csa->channel; +- IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", +- le16_to_cpu(csa->channel)); +- iwl_chswitch_done(priv, true); +- } else { +- IWL_ERR(priv, "CSA notif (fail) : channel %d\n", ++ if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) ++ return; ++ ++ if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { ++ rxon->channel = csa->channel; ++ ctx->staging.channel = csa->channel; ++ IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", + le16_to_cpu(csa->channel)); +- iwl_chswitch_done(priv, false); +- } ++ iwl_chswitch_done(priv, true); ++ } else { ++ IWL_ERR(priv, "CSA notif (fail) : channel %d\n", ++ le16_to_cpu(csa->channel)); ++ iwl_chswitch_done(priv, false); + } + } + +diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c +index e183587..a8f3bc7 100644 +--- a/drivers/net/wireless/p54/p54usb.c ++++ b/drivers/net/wireless/p54/p54usb.c +@@ -82,6 +82,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { + {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ + {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ + {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ ++ {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */ + {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ + {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ + {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */ +diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +index 71244a3..91bf182 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +@@ -278,6 +278,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { + {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ + {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ + {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ ++ {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ + {RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ + {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ + /* HP - Lite-On ,8188CUS Slim Combo */ +diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c +index ab607bb..13c0c77 100644 +--- a/drivers/net/wireless/zd1211rw/zd_usb.c ++++ b/drivers/net/wireless/zd1211rw/zd_usb.c +@@ -1533,6 +1533,31 @@ static void __exit usb_exit(void) + module_init(usb_init); + module_exit(usb_exit); + ++static int zd_ep_regs_out_msg(struct usb_device *udev, void *data, int len, ++ int *actual_length, int timeout) ++{ ++ /* In USB 2.0 mode EP_REGS_OUT endpoint is interrupt type. However in ++ * USB 1.1 mode endpoint is bulk. Select correct type URB by endpoint ++ * descriptor. ++ */ ++ struct usb_host_endpoint *ep; ++ unsigned int pipe; ++ ++ pipe = usb_sndintpipe(udev, EP_REGS_OUT); ++ ep = usb_pipe_endpoint(udev, pipe); ++ if (!ep) ++ return -EINVAL; ++ ++ if (usb_endpoint_xfer_int(&ep->desc)) { ++ return usb_interrupt_msg(udev, pipe, data, len, ++ actual_length, timeout); ++ } else { ++ pipe = usb_sndbulkpipe(udev, EP_REGS_OUT); ++ return usb_bulk_msg(udev, pipe, data, len, actual_length, ++ timeout); ++ } ++} ++ + static int usb_int_regs_length(unsigned int count) + { + return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data); +@@ -1648,15 +1673,14 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, + + udev = zd_usb_to_usbdev(usb); + prepare_read_regs_int(usb); +- r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), +- req, req_len, &actual_req_len, 50 /* ms */); ++ r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/); + if (r) { + dev_dbg_f(zd_usb_dev(usb), +- "error in usb_interrupt_msg(). Error number %d\n", r); ++ "error in zd_ep_regs_out_msg(). Error number %d\n", r); + goto error; + } + if (req_len != actual_req_len) { +- dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n" ++ dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()\n" + " req_len %d != actual_req_len %d\n", + req_len, actual_req_len); + r = -EIO; +@@ -1818,9 +1842,17 @@ int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, + rw->value = cpu_to_le16(ioreqs[i].value); + } + +- usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT), +- req, req_len, iowrite16v_urb_complete, usb, +- ep->desc.bInterval); ++ /* In USB 2.0 mode endpoint is interrupt type. However in USB 1.1 mode ++ * endpoint is bulk. Select correct type URB by endpoint descriptor. ++ */ ++ if (usb_endpoint_xfer_int(&ep->desc)) ++ usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT), ++ req, req_len, iowrite16v_urb_complete, usb, ++ ep->desc.bInterval); ++ else ++ usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_REGS_OUT), ++ req, req_len, iowrite16v_urb_complete, usb); ++ + urb->transfer_flags |= URB_FREE_BUFFER; + + /* Submit previous URB */ +@@ -1924,15 +1956,14 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) + } + + udev = zd_usb_to_usbdev(usb); +- r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), +- req, req_len, &actual_req_len, 50 /* ms */); ++ r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/); + if (r) { + dev_dbg_f(zd_usb_dev(usb), +- "error in usb_interrupt_msg(). Error number %d\n", r); ++ "error in zd_ep_regs_out_msg(). Error number %d\n", r); + goto out; + } + if (req_len != actual_req_len) { +- dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()" ++ dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()" + " req_len %d != actual_req_len %d\n", + req_len, actual_req_len); + r = -EIO; +diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c +index a3984f4..f34b5b2 100644 +--- a/drivers/oprofile/buffer_sync.c ++++ b/drivers/oprofile/buffer_sync.c +@@ -141,6 +141,13 @@ static struct notifier_block module_load_nb = { + .notifier_call = module_load_notify, + }; + ++static void free_all_tasks(void) ++{ ++ /* make sure we don't leak task structs */ ++ process_task_mortuary(); ++ process_task_mortuary(); ++} ++ + int sync_start(void) + { + int err; +@@ -148,8 +155,6 @@ int sync_start(void) + if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL)) + return -ENOMEM; + +- mutex_lock(&buffer_mutex); +- + err = task_handoff_register(&task_free_nb); + if (err) + goto out1; +@@ -166,7 +171,6 @@ int sync_start(void) + start_cpu_work(); + + out: +- mutex_unlock(&buffer_mutex); + return err; + out4: + profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); +@@ -174,6 +178,7 @@ out3: + profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); + out2: + task_handoff_unregister(&task_free_nb); ++ free_all_tasks(); + out1: + free_cpumask_var(marked_cpus); + goto out; +@@ -182,20 +187,16 @@ out1: + + void sync_stop(void) + { +- /* flush buffers */ +- mutex_lock(&buffer_mutex); + end_cpu_work(); + unregister_module_notifier(&module_load_nb); + profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); + profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); + task_handoff_unregister(&task_free_nb); +- mutex_unlock(&buffer_mutex); +- flush_cpu_work(); ++ barrier(); /* do all of the above first */ + +- /* make sure we don't leak task structs */ +- process_task_mortuary(); +- process_task_mortuary(); ++ flush_cpu_work(); + ++ free_all_tasks(); + free_cpumask_var(marked_cpus); + } + +diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c +index 80b461c..749fdf0 100644 +--- a/drivers/pci/hotplug/pcihp_slot.c ++++ b/drivers/pci/hotplug/pcihp_slot.c +@@ -158,6 +158,47 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) + */ + } + ++/* Program PCIE MaxPayload setting on device: ensure parent maxpayload <= device */ ++static int pci_set_payload(struct pci_dev *dev) ++{ ++ int pos, ppos; ++ u16 pctl, psz; ++ u16 dctl, dsz, dcap, dmax; ++ struct pci_dev *parent; ++ ++ parent = dev->bus->self; ++ pos = pci_find_capability(dev, PCI_CAP_ID_EXP); ++ if (!pos) ++ return 0; ++ ++ /* Read Device MaxPayload capability and setting */ ++ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &dctl); ++ pci_read_config_word(dev, pos + PCI_EXP_DEVCAP, &dcap); ++ dsz = (dctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5; ++ dmax = (dcap & PCI_EXP_DEVCAP_PAYLOAD); ++ ++ /* Read Parent MaxPayload setting */ ++ ppos = pci_find_capability(parent, PCI_CAP_ID_EXP); ++ if (!ppos) ++ return 0; ++ pci_read_config_word(parent, ppos + PCI_EXP_DEVCTL, &pctl); ++ psz = (pctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5; ++ ++ /* If parent payload > device max payload -> error ++ * If parent payload > device payload -> set speed ++ * If parent payload <= device payload -> do nothing ++ */ ++ if (psz > dmax) ++ return -1; ++ else if (psz > dsz) { ++ dev_info(&dev->dev, "Setting MaxPayload to %d\n", 128 << psz); ++ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, ++ (dctl & ~PCI_EXP_DEVCTL_PAYLOAD) + ++ (psz << 5)); ++ } ++ return 0; ++} ++ + void pci_configure_slot(struct pci_dev *dev) + { + struct pci_dev *cdev; +@@ -169,6 +210,10 @@ void pci_configure_slot(struct pci_dev *dev) + (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) + return; + ++ ret = pci_set_payload(dev); ++ if (ret) ++ dev_warn(&dev->dev, "could not set device max payload\n"); ++ + memset(&hpp, 0, sizeof(hpp)); + ret = pci_get_hp_params(dev, &hpp); + if (ret) +diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c +index d552d2c..5db70c7 100644 +--- a/drivers/pci/intel-iommu.c ++++ b/drivers/pci/intel-iommu.c +@@ -46,6 +46,8 @@ + #define ROOT_SIZE VTD_PAGE_SIZE + #define CONTEXT_SIZE VTD_PAGE_SIZE + ++#define IS_BRIDGE_HOST_DEVICE(pdev) \ ++ ((pdev->class >> 8) == PCI_CLASS_BRIDGE_HOST) + #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) + #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) + #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) +@@ -1416,6 +1418,10 @@ static void domain_exit(struct dmar_domain *domain) + if (!domain) + return; + ++ /* Flush any lazy unmaps that may reference this domain */ ++ if (!intel_iommu_strict) ++ flush_unmaps_timeout(0); ++ + domain_remove_dev_info(domain); + /* destroy iovas */ + put_iova_domain(&domain->iovad); +@@ -2105,10 +2111,10 @@ static int identity_mapping(struct pci_dev *pdev) + if (likely(!iommu_identity_mapping)) + return 0; + ++ info = pdev->dev.archdata.iommu; ++ if (info && info != DUMMY_DEVICE_DOMAIN_INFO) ++ return (info->domain == si_domain); + +- list_for_each_entry(info, &si_domain->devices, link) +- if (info->dev == pdev) +- return 1; + return 0; + } + +@@ -2186,8 +2192,19 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup) + * Assume that they will -- if they turn out not to be, then we can + * take them out of the 1:1 domain later. + */ +- if (!startup) +- return pdev->dma_mask > DMA_BIT_MASK(32); ++ if (!startup) { ++ /* ++ * If the device's dma_mask is less than the system's memory ++ * size then this is not a candidate for identity mapping. ++ */ ++ u64 dma_mask = pdev->dma_mask; ++ ++ if (pdev->dev.coherent_dma_mask && ++ pdev->dev.coherent_dma_mask < dma_mask) ++ dma_mask = pdev->dev.coherent_dma_mask; ++ ++ return dma_mask >= dma_get_required_mask(&pdev->dev); ++ } + + return 1; + } +@@ -2202,6 +2219,9 @@ static int __init iommu_prepare_static_identity_mapping(int hw) + return -EFAULT; + + for_each_pci_dev(pdev) { ++ /* Skip Host/PCI Bridge devices */ ++ if (IS_BRIDGE_HOST_DEVICE(pdev)) ++ continue; + if (iommu_should_identity_map(pdev, 1)) { + printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n", + hw ? "hardware" : "software", pci_name(pdev)); +@@ -2591,8 +2611,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, + iommu = domain_get_iommu(domain); + size = aligned_nrpages(paddr, size); + +- iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), +- pdev->dma_mask); ++ iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), dma_mask); + if (!iova) + goto error; + +@@ -3379,8 +3398,8 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, + spin_lock_irqsave(&device_domain_lock, flags); + list_for_each_safe(entry, tmp, &domain->devices) { + info = list_entry(entry, struct device_domain_info, link); +- /* No need to compare PCI domain; it has to be the same */ +- if (info->bus == pdev->bus->number && ++ if (info->segment == pci_domain_nr(pdev->bus) && ++ info->bus == pdev->bus->number && + info->devfn == pdev->devfn) { + list_del(&info->link); + list_del(&info->global); +@@ -3418,10 +3437,13 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, + domain_update_iommu_cap(domain); + spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); + +- spin_lock_irqsave(&iommu->lock, tmp_flags); +- clear_bit(domain->id, iommu->domain_ids); +- iommu->domains[domain->id] = NULL; +- spin_unlock_irqrestore(&iommu->lock, tmp_flags); ++ if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && ++ !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)) { ++ spin_lock_irqsave(&iommu->lock, tmp_flags); ++ clear_bit(domain->id, iommu->domain_ids); ++ iommu->domains[domain->id] = NULL; ++ spin_unlock_irqrestore(&iommu->lock, tmp_flags); ++ } + } + + spin_unlock_irqrestore(&device_domain_lock, flags); +diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c +index 9606e59..c5c274a 100644 +--- a/drivers/pci/iova.c ++++ b/drivers/pci/iova.c +@@ -63,8 +63,16 @@ __cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free) + curr = iovad->cached32_node; + cached_iova = container_of(curr, struct iova, node); + +- if (free->pfn_lo >= cached_iova->pfn_lo) +- iovad->cached32_node = rb_next(&free->node); ++ if (free->pfn_lo >= cached_iova->pfn_lo) { ++ struct rb_node *node = rb_next(&free->node); ++ struct iova *iova = container_of(node, struct iova, node); ++ ++ /* only cache if it's below 32bit pfn */ ++ if (node && iova->pfn_lo < iovad->dma_32bit_pfn) ++ iovad->cached32_node = node; ++ else ++ iovad->cached32_node = NULL; ++ } + } + + /* Computes the padding size required, to make the +diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c +index 135df16..46767c5 100644 +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -624,7 +624,7 @@ static int pci_pm_prepare(struct device *dev) + * system from the sleep state, we'll have to prevent it from signaling + * wake-up. + */ +- pm_runtime_resume(dev); ++ pm_runtime_get_sync(dev); + + if (drv && drv->pm && drv->pm->prepare) + error = drv->pm->prepare(dev); +@@ -638,6 +638,8 @@ static void pci_pm_complete(struct device *dev) + + if (drv && drv->pm && drv->pm->complete) + drv->pm->complete(dev); ++ ++ pm_runtime_put_sync(dev); + } + + #else /* !CONFIG_PM_SLEEP */ +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 5129ed6..362e3b3 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -2755,9 +2755,34 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) + + dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n"); + dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n"); ++ ++ /* ++ * RICOH 0xe823 SD/MMC card reader fails to recognize ++ * certain types of SD/MMC cards. Lowering the SD base ++ * clock frequency from 200Mhz to 50Mhz fixes this issue. ++ * ++ * 0x150 - SD2.0 mode enable for changing base clock ++ * frequency to 50Mhz ++ * 0xe1 - Base clock frequency ++ * 0x32 - 50Mhz new clock frequency ++ * 0xf9 - Key register for 0x150 ++ * 0xfc - key register for 0xe1 ++ */ ++ if (dev->device == PCI_DEVICE_ID_RICOH_R5CE823) { ++ pci_write_config_byte(dev, 0xf9, 0xfc); ++ pci_write_config_byte(dev, 0x150, 0x10); ++ pci_write_config_byte(dev, 0xf9, 0x00); ++ pci_write_config_byte(dev, 0xfc, 0x01); ++ pci_write_config_byte(dev, 0xe1, 0x32); ++ pci_write_config_byte(dev, 0xfc, 0x00); ++ ++ dev_notice(&dev->dev, "MMC controller base frequency changed to 50Mhz.\n"); ++ } + } + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); + DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); ++DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); + #endif /*CONFIG_MMC_RICOH_MMC*/ + + #if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP) +@@ -2784,6 +2809,16 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors); + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors); + #endif + ++static void __devinit fixup_ti816x_class(struct pci_dev* dev) ++{ ++ /* TI 816x devices do not have class code set when in PCIe boot mode */ ++ if (dev->class == PCI_CLASS_NOT_DEFINED) { ++ dev_info(&dev->dev, "Setting PCI class for 816x PCIe device\n"); ++ dev->class = PCI_CLASS_MULTIMEDIA_VIDEO; ++ } ++} ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_TI, 0xb800, fixup_ti816x_class); ++ + static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, + struct pci_fixup *end) + { +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 832a3fd7..c8c9842 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -1223,7 +1223,7 @@ static int asus_wmi_sysfs_init(struct platform_device *device) + /* + * Platform device + */ +-static int __init asus_wmi_platform_init(struct asus_wmi *asus) ++static int asus_wmi_platform_init(struct asus_wmi *asus) + { + int rv; + +diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c +index de301aa8..fdfb9e7 100644 +--- a/drivers/platform/x86/dell-laptop.c ++++ b/drivers/platform/x86/dell-laptop.c +@@ -290,12 +290,9 @@ static int dell_rfkill_set(void *data, bool blocked) + dell_send_request(buffer, 17, 11); + + /* If the hardware switch controls this radio, and the hardware +- switch is disabled, don't allow changing the software state. +- If the hardware switch is reported as not supported, always +- fire the SMI to toggle the killswitch. */ ++ switch is disabled, don't allow changing the software state */ + if ((hwswitch_state & BIT(hwswitch_bit)) && +- !(buffer->output[1] & BIT(16)) && +- (buffer->output[1] & BIT(0))) { ++ !(buffer->output[1] & BIT(16))) { + ret = -EINVAL; + goto out; + } +@@ -401,23 +398,6 @@ static const struct file_operations dell_debugfs_fops = { + + static void dell_update_rfkill(struct work_struct *ignored) + { +- int status; +- +- get_buffer(); +- dell_send_request(buffer, 17, 11); +- status = buffer->output[1]; +- release_buffer(); +- +- /* if hardware rfkill is not supported, set it explicitly */ +- if (!(status & BIT(0))) { +- if (wifi_rfkill) +- dell_rfkill_set((void *)1, !((status & BIT(17)) >> 17)); +- if (bluetooth_rfkill) +- dell_rfkill_set((void *)2, !((status & BIT(18)) >> 18)); +- if (wwan_rfkill) +- dell_rfkill_set((void *)3, !((status & BIT(19)) >> 19)); +- } +- + if (wifi_rfkill) + dell_rfkill_query(wifi_rfkill, (void *)1); + if (bluetooth_rfkill) +diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c +index f0b8951..a8a2b6b 100644 +--- a/drivers/scsi/bnx2i/bnx2i_hwi.c ++++ b/drivers/scsi/bnx2i/bnx2i_hwi.c +@@ -1274,6 +1274,7 @@ int bnx2i_send_fw_iscsi_init_msg(struct bnx2i_hba *hba) + iscsi_init.dummy_buffer_addr_hi = + (u32) ((u64) hba->dummy_buf_dma >> 32); + ++ hba->num_ccell = hba->max_sqes >> 1; + hba->ctx_ccell_tasks = + ((hba->num_ccell & 0xFFFF) | (hba->max_sqes << 16)); + iscsi_init.num_ccells_per_conn = hba->num_ccell; +diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c +index 1d24a28..6adbdc3 100644 +--- a/drivers/scsi/bnx2i/bnx2i_init.c ++++ b/drivers/scsi/bnx2i/bnx2i_init.c +@@ -244,7 +244,7 @@ void bnx2i_stop(void *handle) + wait_event_interruptible_timeout(hba->eh_wait, + (list_empty(&hba->ep_ofld_list) && + list_empty(&hba->ep_destroy_list)), +- 10 * HZ); ++ 2 * HZ); + /* Wait for all endpoints to be torn down, Chip will be reset once + * control returns to network driver. So it is required to cleanup and + * release all connection resources before returning from this routine. +diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c +index 1809f9c..51a970f 100644 +--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c ++++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c +@@ -858,7 +858,7 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) + mutex_init(&hba->net_dev_lock); + init_waitqueue_head(&hba->eh_wait); + if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { +- hba->hba_shutdown_tmo = 20 * HZ; ++ hba->hba_shutdown_tmo = 30 * HZ; + hba->conn_teardown_tmo = 20 * HZ; + hba->conn_ctx_destroy_tmo = 6 * HZ; + } else { /* 5706/5708/5709 */ +@@ -1208,6 +1208,9 @@ static int bnx2i_task_xmit(struct iscsi_task *task) + struct bnx2i_cmd *cmd = task->dd_data; + struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr; + ++ if (bnx2i_conn->ep->num_active_cmds + 1 > hba->max_sqes) ++ return -ENOMEM; ++ + /* + * If there is no scsi_cmnd this must be a mgmt task + */ +diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c +index d2064a0..9aab26a 100644 +--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c ++++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c +@@ -113,6 +113,7 @@ struct sense_info { + }; + + ++#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC) + #define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF) + + /** +@@ -121,6 +122,7 @@ struct sense_info { + * @work: work object (ioc->fault_reset_work_q) + * @cancel_pending_work: flag set during reset handling + * @ioc: per adapter object ++ * @device_handle: device handle + * @VF_ID: virtual function id + * @VP_ID: virtual port id + * @ignore: flag meaning this event has been marked to ignore +@@ -134,6 +136,7 @@ struct fw_event_work { + u8 cancel_pending_work; + struct delayed_work delayed_work; + struct MPT2SAS_ADAPTER *ioc; ++ u16 device_handle; + u8 VF_ID; + u8 VP_ID; + u8 ignore; +@@ -3708,17 +3711,75 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, + #endif + + /** +- * _scsih_smart_predicted_fault - illuminate Fault LED ++ * _scsih_turn_on_fault_led - illuminate Fault LED + * @ioc: per adapter object + * @handle: device handle ++ * Context: process + * + * Return nothing. + */ + static void +-_scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) ++_scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) + { + Mpi2SepReply_t mpi_reply; + Mpi2SepRequest_t mpi_request; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; ++ mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; ++ mpi_request.SlotStatus = ++ cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); ++ mpi_request.DevHandle = cpu_to_le16(handle); ++ mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS; ++ if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, ++ &mpi_request)) != 0) { ++ printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { ++ dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "enclosure_processor: " ++ "ioc_status (0x%04x), loginfo(0x%08x)\n", ioc->name, ++ le16_to_cpu(mpi_reply.IOCStatus), ++ le32_to_cpu(mpi_reply.IOCLogInfo))); ++ return; ++ } ++} ++ ++/** ++ * _scsih_send_event_to_turn_on_fault_led - fire delayed event ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: interrupt. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_send_event_to_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct fw_event_work *fw_event; ++ ++ fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); ++ if (!fw_event) ++ return; ++ fw_event->event = MPT2SAS_TURN_ON_FAULT_LED; ++ fw_event->device_handle = handle; ++ fw_event->ioc = ioc; ++ _scsih_fw_event_add(ioc, fw_event); ++} ++ ++/** ++ * _scsih_smart_predicted_fault - process smart errors ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: interrupt. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) ++{ + struct scsi_target *starget; + struct MPT2SAS_TARGET *sas_target_priv_data; + Mpi2EventNotificationReply_t *event_reply; +@@ -3745,30 +3806,8 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) + starget_printk(KERN_WARNING, starget, "predicted fault\n"); + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + +- if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) { +- memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); +- mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; +- mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; +- mpi_request.SlotStatus = +- cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); +- mpi_request.DevHandle = cpu_to_le16(handle); +- mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS; +- if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, +- &mpi_request)) != 0) { +- printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", +- ioc->name, __FILE__, __LINE__, __func__); +- return; +- } +- +- if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { +- dewtprintk(ioc, printk(MPT2SAS_INFO_FMT +- "enclosure_processor: ioc_status (0x%04x), " +- "loginfo(0x%08x)\n", ioc->name, +- le16_to_cpu(mpi_reply.IOCStatus), +- le32_to_cpu(mpi_reply.IOCLogInfo))); +- return; +- } +- } ++ if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) ++ _scsih_send_event_to_turn_on_fault_led(ioc, handle); + + /* insert into event log */ + sz = offsetof(Mpi2EventNotificationReply_t, EventData) + +@@ -6330,6 +6369,9 @@ _firmware_event_work(struct work_struct *work) + } + + switch (fw_event->event) { ++ case MPT2SAS_TURN_ON_FAULT_LED: ++ _scsih_turn_on_fault_led(ioc, fw_event->device_handle); ++ break; + case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: + _scsih_sas_topology_change_event(ioc, fw_event); + break; +diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c +index d3e58d7..c52a0a2 100644 +--- a/drivers/scsi/qla2xxx/qla_attr.c ++++ b/drivers/scsi/qla2xxx/qla_attr.c +@@ -1877,14 +1877,15 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) + + scsi_remove_host(vha->host); + ++ /* Allow timer to run to drain queued items, when removing vp */ ++ qla24xx_deallocate_vp_id(vha); ++ + if (vha->timer_active) { + qla2x00_vp_stop_timer(vha); + DEBUG15(printk(KERN_INFO "scsi(%ld): timer for the vport[%d]" + " = %p has stopped\n", vha->host_no, vha->vp_idx, vha)); + } + +- qla24xx_deallocate_vp_id(vha); +- + /* No pending activities shall be there on the vha now */ + DEBUG(msleep(random32()%10)); /* Just to see if something falls on + * the net we have placed below */ +diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h +index f5ba09c..5223c1d 100644 +--- a/drivers/scsi/qla2xxx/qla_fw.h ++++ b/drivers/scsi/qla2xxx/qla_fw.h +@@ -416,8 +416,7 @@ struct cmd_type_6 { + uint8_t vp_index; + + uint32_t fcp_data_dseg_address[2]; /* Data segment address. */ +- uint16_t fcp_data_dseg_len; /* Data segment length. */ +- uint16_t reserved_1; /* MUST be set to 0. */ ++ uint32_t fcp_data_dseg_len; /* Data segment length. */ + }; + + #define COMMAND_TYPE_7 0x18 /* Command Type 7 entry */ +diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c +index 455fe13..eb31213 100644 +--- a/drivers/scsi/qla2xxx/qla_nx.c ++++ b/drivers/scsi/qla2xxx/qla_nx.c +@@ -2548,11 +2548,11 @@ qla2xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, + dsd_seg = (uint32_t *)&cmd_pkt->fcp_data_dseg_address; + *dsd_seg++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); + *dsd_seg++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); +- cmd_pkt->fcp_data_dseg_len = dsd_list_len; ++ *dsd_seg++ = cpu_to_le32(dsd_list_len); + } else { + *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); + *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); +- *cur_dsd++ = dsd_list_len; ++ *cur_dsd++ = cpu_to_le32(dsd_list_len); + } + cur_dsd = (uint32_t *)next_dsd; + while (avail_dsds) { +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index aa77475..4c3f5e8 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -2360,21 +2360,26 @@ qla2x00_remove_one(struct pci_dev *pdev) + base_vha = pci_get_drvdata(pdev); + ha = base_vha->hw; + +- spin_lock_irqsave(&ha->vport_slock, flags); +- list_for_each_entry(vha, &ha->vp_list, list) { +- atomic_inc(&vha->vref_count); ++ mutex_lock(&ha->vport_lock); ++ while (ha->cur_vport_count) { ++ struct Scsi_Host *scsi_host; + +- if (vha->fc_vport) { +- spin_unlock_irqrestore(&ha->vport_slock, flags); ++ spin_lock_irqsave(&ha->vport_slock, flags); + +- fc_vport_terminate(vha->fc_vport); ++ BUG_ON(base_vha->list.next == &ha->vp_list); ++ /* This assumes first entry in ha->vp_list is always base vha */ ++ vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list); ++ scsi_host = scsi_host_get(vha->host); + +- spin_lock_irqsave(&ha->vport_slock, flags); +- } ++ spin_unlock_irqrestore(&ha->vport_slock, flags); ++ mutex_unlock(&ha->vport_lock); ++ ++ fc_vport_terminate(vha->fc_vport); ++ scsi_host_put(vha->host); + +- atomic_dec(&vha->vref_count); ++ mutex_lock(&ha->vport_lock); + } +- spin_unlock_irqrestore(&ha->vport_slock, flags); ++ mutex_unlock(&ha->vport_lock); + + set_bit(UNLOADING, &base_vha->dpc_flags); + +@@ -3604,7 +3609,8 @@ qla2x00_timer(scsi_qla_host_t *vha) + if (!pci_channel_offline(ha->pdev)) + pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); + +- if (IS_QLA82XX(ha)) { ++ /* Make sure qla82xx_watchdog is run only for physical port */ ++ if (!vha->vp_idx && IS_QLA82XX(ha)) { + if (test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) + start_dpc++; + qla82xx_watchdog(vha); +@@ -3675,8 +3681,8 @@ qla2x00_timer(scsi_qla_host_t *vha) + atomic_read(&vha->loop_down_timer))); + } + +- /* Check if beacon LED needs to be blinked */ +- if (ha->beacon_blink_led == 1) { ++ /* Check if beacon LED needs to be blinked for physical host only */ ++ if (!vha->vp_idx && (ha->beacon_blink_led == 1)) { + set_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags); + start_dpc++; + } +diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c +index 58584dc..44e8ca3 100644 +--- a/drivers/scsi/scsi_scan.c ++++ b/drivers/scsi/scsi_scan.c +@@ -297,7 +297,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, + kfree(sdev); + goto out; + } +- ++ blk_get_queue(sdev->request_queue); + sdev->request_queue->queuedata = sdev; + scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); + +diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c +index e639125..e0bd3f7 100644 +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -322,6 +322,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) + kfree(evt); + } + ++ blk_put_queue(sdev->request_queue); + /* NULL queue means the device can't be used */ + sdev->request_queue = NULL; + +diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c +index 95019c7..4778e27 100644 +--- a/drivers/scsi/sr.c ++++ b/drivers/scsi/sr.c +@@ -636,7 +636,7 @@ static int sr_probe(struct device *dev) + disk->first_minor = minor; + sprintf(disk->disk_name, "sr%d", minor); + disk->fops = &sr_bdops; +- disk->flags = GENHD_FL_CD; ++ disk->flags = GENHD_FL_CD | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; + disk->events = DISK_EVENT_MEDIA_CHANGE | DISK_EVENT_EJECT_REQUEST; + + blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT); +diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c +index 9f4b58b..7e22b73 100644 +--- a/drivers/scsi/ultrastor.c ++++ b/drivers/scsi/ultrastor.c +@@ -307,7 +307,7 @@ static inline int find_and_clear_bit_16(unsigned long *field) + "0: bsfw %1,%w0\n\t" + "btr %0,%1\n\t" + "jnc 0b" +- : "=&r" (rv), "=m" (*field) :); ++ : "=&r" (rv), "+m" (*field) :); + + return rv; + } +diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c +index 6172335..82dd6fb 100644 +--- a/drivers/sh/clk/cpg.c ++++ b/drivers/sh/clk/cpg.c +@@ -105,7 +105,7 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) + + /* Rebuild the frequency table */ + clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, +- table, &clk->arch_flags); ++ table, NULL); + + return 0; + } +diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +index f008659..f7bff4e 100644 +--- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c ++++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +@@ -1123,21 +1123,12 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, + ini->txretry[index] = 0; + + /* ampdu_ack_len: number of acked aggregated frames */ +- /* ampdu_ack_map: block ack bit map for the aggregation */ + /* ampdu_len: number of aggregated frames */ + rate_status(wlc, tx_info, txs, mcs); + tx_info->flags |= IEEE80211_TX_STAT_ACK; + tx_info->flags |= IEEE80211_TX_STAT_AMPDU; +- +- /* XXX TODO: Make these accurate. */ + tx_info->status.ampdu_ack_len = +- (txs-> +- status & TX_STATUS_FRM_RTX_MASK) >> +- TX_STATUS_FRM_RTX_SHIFT; +- tx_info->status.ampdu_len = +- (txs-> +- status & TX_STATUS_FRM_RTX_MASK) >> +- TX_STATUS_FRM_RTX_SHIFT; ++ tx_info->status.ampdu_len = 1; + + skb_pull(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_TXH_LEN); +@@ -1163,6 +1154,8 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, + /* Retry timeout */ + ini->tx_in_transit--; + ieee80211_tx_info_clear_status(tx_info); ++ tx_info->status.ampdu_ack_len = 0; ++ tx_info->status.ampdu_len = 1; + tx_info->flags |= + IEEE80211_TX_STAT_AMPDU_NO_BACK; + skb_pull(p, D11_PHY_HDR_LEN); +diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c +index f67f53b..1b96199 100644 +--- a/drivers/staging/gma500/psb_fb.c ++++ b/drivers/staging/gma500/psb_fb.c +@@ -489,6 +489,16 @@ static int psbfb_create(struct psb_fbdev *fbdev, + info->screen_size = size; + memset(info->screen_base, 0, size); + ++ if (dev_priv->pg->stolen_size) { ++ info->apertures = alloc_apertures(1); ++ if (!info->apertures) { ++ ret = -ENOMEM; ++ goto out_err0; ++ } ++ info->apertures->ranges[0].base = dev->mode_config.fb_base; ++ info->apertures->ranges[0].size = dev_priv->pg->stolen_size; ++ } ++ + drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); + drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper, + sizes->fb_width, sizes->fb_height); +diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c +index dd6a57c..4e051f6 100644 +--- a/drivers/staging/lirc/lirc_zilog.c ++++ b/drivers/staging/lirc/lirc_zilog.c +@@ -475,14 +475,14 @@ static int lirc_thread(void *arg) + dprintk("poll thread started\n"); + + while (!kthread_should_stop()) { ++ set_current_state(TASK_INTERRUPTIBLE); ++ + /* if device not opened, we can sleep half a second */ + if (atomic_read(&ir->open_count) == 0) { + schedule_timeout(HZ/2); + continue; + } + +- set_current_state(TASK_INTERRUPTIBLE); +- + /* + * This is ~113*2 + 24 + jitter (2*repeat gap + code length). + * We use this interval as the chip resets every time you poll +diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c +index 8b1451d..8486eb1 100644 +--- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c ++++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c +@@ -68,7 +68,10 @@ static u8 do_join(struct _adapter *padapter) + pmlmepriv->fw_state |= _FW_UNDER_LINKING; + pmlmepriv->pscanned = plist; + pmlmepriv->to_join = true; +- if (_queue_empty(queue) == true) { ++ ++ /* adhoc mode will start with an empty queue, but skip checking */ ++ if (!check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) && ++ _queue_empty(queue)) { + if (pmlmepriv->fw_state & _FW_UNDER_LINKING) + pmlmepriv->fw_state ^= _FW_UNDER_LINKING; + /* when set_ssid/set_bssid for do_join(), but scanning queue +diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c +index 7b1fe45..37b650b 100644 +--- a/drivers/staging/usbip/usbip_common.c ++++ b/drivers/staging/usbip/usbip_common.c +@@ -604,7 +604,7 @@ static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu, + be32_to_cpus(&pdu->status); + be32_to_cpus(&pdu->actual_length); + be32_to_cpus(&pdu->start_frame); +- cpu_to_be32s(&pdu->number_of_packets); ++ be32_to_cpus(&pdu->number_of_packets); + be32_to_cpus(&pdu->error_count); + } + } +diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c +index d25e208..fc10ed4 100644 +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -150,13 +150,13 @@ out: + + { + struct se_device *dev = se_lun->lun_se_dev; +- spin_lock(&dev->stats_lock); ++ spin_lock_irq(&dev->stats_lock); + dev->num_cmds++; + if (se_cmd->data_direction == DMA_TO_DEVICE) + dev->write_bytes += se_cmd->data_length; + else if (se_cmd->data_direction == DMA_FROM_DEVICE) + dev->read_bytes += se_cmd->data_length; +- spin_unlock(&dev->stats_lock); ++ spin_unlock_irq(&dev->stats_lock); + } + + /* +diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c +index 4a10983..59b8b9c 100644 +--- a/drivers/target/target_core_tmr.c ++++ b/drivers/target/target_core_tmr.c +@@ -55,7 +55,8 @@ struct se_tmr_req *core_tmr_alloc_req( + { + struct se_tmr_req *tmr; + +- tmr = kmem_cache_zalloc(se_tmr_req_cache, GFP_KERNEL); ++ tmr = kmem_cache_zalloc(se_tmr_req_cache, (in_interrupt()) ? ++ GFP_ATOMIC : GFP_KERNEL); + if (!(tmr)) { + printk(KERN_ERR "Unable to allocate struct se_tmr_req\n"); + return ERR_PTR(-ENOMEM); +@@ -398,9 +399,9 @@ int core_tmr_lun_reset( + printk(KERN_INFO "LUN_RESET: SCSI-2 Released reservation\n"); + } + +- spin_lock(&dev->stats_lock); ++ spin_lock_irq(&dev->stats_lock); + dev->num_resets++; +- spin_unlock(&dev->stats_lock); ++ spin_unlock_irq(&dev->stats_lock); + + DEBUG_LR("LUN_RESET: %s for [%s] Complete\n", + (preempt_and_abort_list) ? "Preempt" : "TMR", +diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c +index 9583b23..beaf8fa 100644 +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -762,7 +762,6 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd) + transport_all_task_dev_remove_state(cmd); + spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags); + +- transport_free_dev_tasks(cmd); + + check_lun: + spin_lock_irqsave(&lun->lun_cmd_lock, flags); +@@ -1195,6 +1194,7 @@ transport_get_task_from_execute_queue(struct se_device *dev) + break; + + list_del(&task->t_execute_list); ++ atomic_set(&task->task_execute_queue, 0); + atomic_dec(&dev->execute_tasks); + + return task; +@@ -1210,8 +1210,14 @@ void transport_remove_task_from_execute_queue( + { + unsigned long flags; + ++ if (atomic_read(&task->task_execute_queue) == 0) { ++ dump_stack(); ++ return; ++ } ++ + spin_lock_irqsave(&dev->execute_task_lock, flags); + list_del(&task->t_execute_list); ++ atomic_set(&task->task_execute_queue, 0); + atomic_dec(&dev->execute_tasks); + spin_unlock_irqrestore(&dev->execute_task_lock, flags); + } +@@ -2058,6 +2064,13 @@ int transport_generic_handle_tmr( + } + EXPORT_SYMBOL(transport_generic_handle_tmr); + ++void transport_generic_free_cmd_intr( ++ struct se_cmd *cmd) ++{ ++ transport_add_cmd_to_queue(cmd, TRANSPORT_FREE_CMD_INTR); ++} ++EXPORT_SYMBOL(transport_generic_free_cmd_intr); ++ + static int transport_stop_tasks_for_cmd(struct se_cmd *cmd) + { + struct se_task *task, *task_tmp; +@@ -4776,18 +4789,20 @@ void transport_do_task_sg_chain(struct se_cmd *cmd) + sg_end_cur->page_link &= ~0x02; + + sg_chain(sg_head, task_sg_num, sg_head_cur); +- sg_count += (task->task_sg_num + 1); +- } else + sg_count += task->task_sg_num; ++ task_sg_num = (task->task_sg_num + 1); ++ } else { ++ sg_chain(sg_head, task_sg_num, sg_head_cur); ++ sg_count += task->task_sg_num; ++ task_sg_num = task->task_sg_num; ++ } + + sg_head = sg_head_cur; + sg_link = sg_link_cur; +- task_sg_num = task->task_sg_num; + continue; + } + sg_head = sg_first = &task->task_sg[0]; + sg_link = &task->task_sg[task->task_sg_num]; +- task_sg_num = task->task_sg_num; + /* + * Check for single task.. + */ +@@ -4798,9 +4813,12 @@ void transport_do_task_sg_chain(struct se_cmd *cmd) + */ + sg_end = &task->task_sg[task->task_sg_num - 1]; + sg_end->page_link &= ~0x02; +- sg_count += (task->task_sg_num + 1); +- } else + sg_count += task->task_sg_num; ++ task_sg_num = (task->task_sg_num + 1); ++ } else { ++ sg_count += task->task_sg_num; ++ task_sg_num = task->task_sg_num; ++ } + } + /* + * Setup the starting pointer and total t_tasks_sg_linked_no including +@@ -4809,21 +4827,20 @@ void transport_do_task_sg_chain(struct se_cmd *cmd) + T_TASK(cmd)->t_tasks_sg_chained = sg_first; + T_TASK(cmd)->t_tasks_sg_chained_no = sg_count; + +- DEBUG_CMD_M("Setup T_TASK(cmd)->t_tasks_sg_chained: %p and" +- " t_tasks_sg_chained_no: %u\n", T_TASK(cmd)->t_tasks_sg_chained, ++ DEBUG_CMD_M("Setup cmd: %p T_TASK(cmd)->t_tasks_sg_chained: %p and" ++ " t_tasks_sg_chained_no: %u\n", cmd, T_TASK(cmd)->t_tasks_sg_chained, + T_TASK(cmd)->t_tasks_sg_chained_no); + + for_each_sg(T_TASK(cmd)->t_tasks_sg_chained, sg, + T_TASK(cmd)->t_tasks_sg_chained_no, i) { + +- DEBUG_CMD_M("SG: %p page: %p length: %d offset: %d\n", +- sg, sg_page(sg), sg->length, sg->offset); ++ DEBUG_CMD_M("SG[%d]: %p page: %p length: %d offset: %d, magic: 0x%08x\n", ++ i, sg, sg_page(sg), sg->length, sg->offset, sg->sg_magic); + if (sg_is_chain(sg)) + DEBUG_CMD_M("SG: %p sg_is_chain=1\n", sg); + if (sg_is_last(sg)) + DEBUG_CMD_M("SG: %p sg_is_last=1\n", sg); + } +- + } + EXPORT_SYMBOL(transport_do_task_sg_chain); + +@@ -5297,6 +5314,8 @@ void transport_generic_free_cmd( + if (wait_for_tasks && cmd->transport_wait_for_tasks) + cmd->transport_wait_for_tasks(cmd, 0, 0); + ++ transport_free_dev_tasks(cmd); ++ + transport_generic_remove(cmd, release_to_pool, + session_reinstatement); + } +@@ -6132,6 +6151,9 @@ get_cmd: + case TRANSPORT_REMOVE: + transport_generic_remove(cmd, 1, 0); + break; ++ case TRANSPORT_FREE_CMD_INTR: ++ transport_generic_free_cmd(cmd, 0, 1, 0); ++ break; + case TRANSPORT_PROCESS_TMR: + transport_generic_do_tmr(cmd); + break; +diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c +index 26403b8..da9270e 100644 +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -1392,6 +1392,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, + int fifosize, base_baud; + int port_type; + struct pch_uart_driver_data *board; ++ const char *board_name; + + board = &drv_dat[id->driver_data]; + port_type = board->port_type; +@@ -1407,7 +1408,8 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, + base_baud = 1843200; /* 1.8432MHz */ + + /* quirk for CM-iTC board */ +- if (strstr(dmi_get_system_info(DMI_BOARD_NAME), "CM-iTC")) ++ board_name = dmi_get_system_info(DMI_BOARD_NAME); ++ if (board_name && strstr(board_name, "CM-iTC")) + base_baud = 192000000; /* 192.0MHz */ + + switch (port_type) { +diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c +index 6ebccd7..453e5b7 100644 +--- a/drivers/tty/serial/s5pv210.c ++++ b/drivers/tty/serial/s5pv210.c +@@ -31,7 +31,7 @@ static int s5pv210_serial_setsource(struct uart_port *port, + struct s3c2410_uartcfg *cfg = port->dev->platform_data; + unsigned long ucon = rd_regl(port, S3C2410_UCON); + +- if ((cfg->clocks_size) == 1) ++ if (cfg->flags & NO_NEED_CHECK_CLKSRC) + return 0; + + if (strcmp(clk->name, "pclk") == 0) +@@ -56,7 +56,7 @@ static int s5pv210_serial_getsource(struct uart_port *port, + + clk->divisor = 1; + +- if ((cfg->clocks_size) == 1) ++ if (cfg->flags & NO_NEED_CHECK_CLKSRC) + return 0; + + switch (ucon & S5PV210_UCON_CLKMASK) { +diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c +index 733fe8e..d4bee1b 100644 +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -172,12 +172,16 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in + + retval = uport->ops->startup(uport); + if (retval == 0) { +- if (init_hw) { +- /* +- * Initialise the hardware port settings. +- */ +- uart_change_speed(tty, state, NULL); ++ if (uart_console(uport) && uport->cons->cflag) { ++ tty->termios->c_cflag = uport->cons->cflag; ++ uport->cons->cflag = 0; ++ } ++ /* ++ * Initialise the hardware port settings. ++ */ ++ uart_change_speed(tty, state, NULL); + ++ if (init_hw) { + /* + * Setup the RTS and DTR signals once the + * port is open and ready to respond. +@@ -1466,45 +1470,6 @@ static void uart_hangup(struct tty_struct *tty) + mutex_unlock(&port->mutex); + } + +-/** +- * uart_update_termios - update the terminal hw settings +- * @tty: tty associated with UART +- * @state: UART to update +- * +- * Copy across the serial console cflag setting into the termios settings +- * for the initial open of the port. This allows continuity between the +- * kernel settings, and the settings init adopts when it opens the port +- * for the first time. +- */ +-static void uart_update_termios(struct tty_struct *tty, +- struct uart_state *state) +-{ +- struct uart_port *port = state->uart_port; +- +- if (uart_console(port) && port->cons->cflag) { +- tty->termios->c_cflag = port->cons->cflag; +- port->cons->cflag = 0; +- } +- +- /* +- * If the device failed to grab its irq resources, +- * or some other error occurred, don't try to talk +- * to the port hardware. +- */ +- if (!(tty->flags & (1 << TTY_IO_ERROR))) { +- /* +- * Make termios settings take effect. +- */ +- uart_change_speed(tty, state, NULL); +- +- /* +- * And finally enable the RTS and DTR signals. +- */ +- if (tty->termios->c_cflag & CBAUD) +- uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS); +- } +-} +- + static int uart_carrier_raised(struct tty_port *port) + { + struct uart_state *state = container_of(port, struct uart_state, port); +@@ -1524,16 +1489,8 @@ static void uart_dtr_rts(struct tty_port *port, int onoff) + struct uart_state *state = container_of(port, struct uart_state, port); + struct uart_port *uport = state->uart_port; + +- if (onoff) { ++ if (onoff) + uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); +- +- /* +- * If this is the first open to succeed, +- * adjust things to suit. +- */ +- if (!test_and_set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags)) +- uart_update_termios(port->tty, state); +- } + else + uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); + } +diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c +index e19e136..1104c9d 100644 +--- a/drivers/tty/tty_ldisc.c ++++ b/drivers/tty/tty_ldisc.c +@@ -555,7 +555,7 @@ static void tty_ldisc_flush_works(struct tty_struct *tty) + static int tty_ldisc_wait_idle(struct tty_struct *tty) + { + int ret; +- ret = wait_event_interruptible_timeout(tty_ldisc_idle, ++ ret = wait_event_timeout(tty_ldisc_idle, + atomic_read(&tty->ldisc->users) == 1, 5 * HZ); + if (ret < 0) + return ret; +@@ -763,6 +763,8 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) + if (IS_ERR(ld)) + return -1; + ++ WARN_ON_ONCE(tty_ldisc_wait_idle(tty)); ++ + tty_ldisc_close(tty, tty->ldisc); + tty_ldisc_put(tty->ldisc); + tty->ldisc = NULL; +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index e057e53..d0b84ff 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -946,7 +946,7 @@ static int acm_probe(struct usb_interface *intf, + u8 ac_management_function = 0; + u8 call_management_function = 0; + int call_interface_num = -1; +- int data_interface_num; ++ int data_interface_num = -1; + unsigned long quirks; + int num_rx_buf; + int i; +@@ -1030,7 +1030,11 @@ next_desc: + if (!union_header) { + if (call_interface_num > 0) { + dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n"); +- data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); ++ /* quirks for Droids MuIn LCD */ ++ if (quirks & NO_DATA_INTERFACE) ++ data_interface = usb_ifnum_to_if(usb_dev, 0); ++ else ++ data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); + control_interface = intf; + } else { + if (intf->cur_altsetting->desc.bNumEndpoints != 3) { +@@ -1613,6 +1617,8 @@ static const struct usb_device_id acm_ids[] = { + { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */ + { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */ + { NOKIA_PCSUITE_ACM_INFO(0x0302), }, /* Nokia N8 */ ++ { NOKIA_PCSUITE_ACM_INFO(0x0335), }, /* Nokia E7 */ ++ { NOKIA_PCSUITE_ACM_INFO(0x03cd), }, /* Nokia C7 */ + { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ + + /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ +@@ -1622,6 +1628,11 @@ static const struct usb_device_id acm_ids[] = { + .driver_info = NOT_A_MODEM, + }, + ++ /* Support for Droids MuIn LCD */ ++ { USB_DEVICE(0x04d8, 0x000b), ++ .driver_info = NO_DATA_INTERFACE, ++ }, ++ + /* control interfaces without any protocol set */ + { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, + USB_CDC_PROTO_NONE) }, +diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h +index b4ea54d..683104a 100644 +--- a/drivers/usb/class/cdc-acm.h ++++ b/drivers/usb/class/cdc-acm.h +@@ -137,3 +137,4 @@ struct acm { + #define SINGLE_RX_URB 2 + #define NO_CAP_LINE 4 + #define NOT_A_MODEM 8 ++#define NO_DATA_INTERFACE 16 +diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c +index e35a176..34e3da5 100644 +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -375,7 +375,7 @@ static int usb_unbind_interface(struct device *dev) + * Just re-enable it without affecting the endpoint toggles. + */ + usb_enable_interface(udev, intf, false); +- } else if (!error && !intf->dev.power.in_suspend) { ++ } else if (!error && !intf->dev.power.is_prepared) { + r = usb_set_interface(udev, intf->altsetting[0]. + desc.bInterfaceNumber, 0); + if (r < 0) +@@ -960,7 +960,7 @@ void usb_rebind_intf(struct usb_interface *intf) + } + + /* Try to rebind the interface */ +- if (!intf->dev.power.in_suspend) { ++ if (!intf->dev.power.is_prepared) { + intf->needs_binding = 0; + rc = device_attach(&intf->dev); + if (rc < 0) +@@ -1107,7 +1107,7 @@ static int usb_resume_interface(struct usb_device *udev, + if (intf->condition == USB_INTERFACE_UNBOUND) { + + /* Carry out a deferred switch to altsetting 0 */ +- if (intf->needs_altsetting0 && !intf->dev.power.in_suspend) { ++ if (intf->needs_altsetting0 && !intf->dev.power.is_prepared) { + usb_set_interface(udev, intf->altsetting[0]. + desc.bInterfaceNumber, 0); + intf->needs_altsetting0 = 0; +@@ -1187,13 +1187,22 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) + for (i = n - 1; i >= 0; --i) { + intf = udev->actconfig->interface[i]; + status = usb_suspend_interface(udev, intf, msg); ++ ++ /* Ignore errors during system sleep transitions */ ++ if (!(msg.event & PM_EVENT_AUTO)) ++ status = 0; + if (status != 0) + break; + } + } +- if (status == 0) ++ if (status == 0) { + status = usb_suspend_device(udev, msg); + ++ /* Again, ignore errors during system sleep transitions */ ++ if (!(msg.event & PM_EVENT_AUTO)) ++ status = 0; ++ } ++ + /* If the suspend failed, resume interfaces that did get suspended */ + if (status != 0) { + msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME); +diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c +index 77a7fae..cddc533 100644 +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -986,7 +986,7 @@ static int register_root_hub(struct usb_hcd *hcd) + spin_unlock_irq (&hcd_root_hub_lock); + + /* Did the HC die before the root hub was registered? */ +- if (HCD_DEAD(hcd) || hcd->state == HC_STATE_HALT) ++ if (HCD_DEAD(hcd)) + usb_hc_died (hcd); /* This time clean up */ + } + +@@ -2128,9 +2128,6 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) + set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); + if (hcd->shared_hcd) + set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); +- +- if (unlikely(hcd->state == HC_STATE_HALT)) +- usb_hc_died(hcd); + rc = IRQ_HANDLED; + } + +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 93720bd..64edb30 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -339,7 +339,8 @@ static int get_hub_status(struct usb_device *hdev, + { + int i, status = -ETIMEDOUT; + +- for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) { ++ for (i = 0; i < USB_STS_RETRIES && ++ (status == -ETIMEDOUT || status == -EPIPE); i++) { + status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0), + USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0, + data, sizeof(*data), USB_STS_TIMEOUT); +@@ -355,7 +356,8 @@ static int get_port_status(struct usb_device *hdev, int port1, + { + int i, status = -ETIMEDOUT; + +- for (i = 0; i < USB_STS_RETRIES && status == -ETIMEDOUT; i++) { ++ for (i = 0; i < USB_STS_RETRIES && ++ (status == -ETIMEDOUT || status == -EPIPE); i++) { + status = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0), + USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port1, + data, sizeof(*data), USB_STS_TIMEOUT); +@@ -1641,6 +1643,7 @@ void usb_disconnect(struct usb_device **pdev) + { + struct usb_device *udev = *pdev; + int i; ++ struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + if (!udev) { + pr_debug ("%s nodev\n", __func__); +@@ -1668,7 +1671,9 @@ void usb_disconnect(struct usb_device **pdev) + * 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); +@@ -2306,6 +2311,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) + USB_DEVICE_REMOTE_WAKEUP, 0, + NULL, 0, + USB_CTRL_SET_TIMEOUT); ++ ++ /* System sleep transitions should never fail */ ++ if (!(msg.event & PM_EVENT_AUTO)) ++ status = 0; + } else { + /* device has up to 10 msec to fully suspend */ + dev_dbg(&udev->dev, "usb %ssuspend\n", +@@ -2544,16 +2553,15 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) + struct usb_device *hdev = hub->hdev; + unsigned port1; + +- /* fail if children aren't already suspended */ ++ /* Warn if children aren't already suspended */ + for (port1 = 1; port1 <= hdev->maxchild; port1++) { + struct usb_device *udev; + + udev = hdev->children [port1-1]; + if (udev && udev->can_submit) { +- if (!(msg.event & PM_EVENT_AUTO)) +- dev_dbg(&intf->dev, "port %d nyet suspended\n", +- port1); +- return -EBUSY; ++ dev_warn(&intf->dev, "port %d nyet suspended\n", port1); ++ if (msg.event & PM_EVENT_AUTO) ++ return -EBUSY; + } + } + +diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c +index 5701e85..0b5ec23 100644 +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -1135,15 +1135,26 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, + * 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) + { + int i; ++ struct usb_hcd *hcd = bus_to_hcd(dev->bus); + + /* getting rid of interfaces will disconnect + * any drivers bound to them (a key side effect) + */ + if (dev->actconfig) { ++ /* ++ * FIXME: In order to avoid self-deadlock involving the ++ * bandwidth_mutex, we have to mark all the interfaces ++ * before unregistering any of them. ++ */ ++ for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) ++ dev->actconfig->interface[i]->unregistering = 1; ++ + for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { + struct usb_interface *interface; + +@@ -1153,7 +1164,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) + continue; + dev_dbg(&dev->dev, "unregistering interface %s\n", + dev_name(&interface->dev)); +- interface->unregistering = 1; + remove_intf_ep_devs(interface); + device_del(&interface->dev); + } +@@ -1172,6 +1182,16 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) + + dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, + skip_ep0 ? "non-ep0" : "all"); ++ if (hcd->driver->check_bandwidth) { ++ /* First pass: Cancel URBs, leave endpoint pointers intact. */ ++ for (i = skip_ep0; i < 16; ++i) { ++ usb_disable_endpoint(dev, i, false); ++ usb_disable_endpoint(dev, i + USB_DIR_IN, false); ++ } ++ /* Remove endpoints from the host controller internal state */ ++ usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); ++ /* Second pass: remove endpoint pointers */ ++ } + for (i = skip_ep0; i < 16; ++i) { + usb_disable_endpoint(dev, i, true); + usb_disable_endpoint(dev, i + USB_DIR_IN, true); +@@ -1273,6 +1293,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) + interface); + return -EINVAL; + } ++ if (iface->unregistering) ++ return -ENODEV; + + alt = usb_altnum_to_altsetting(iface, alternate); + if (!alt) { +@@ -1727,6 +1749,7 @@ free_interfaces: + /* 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 */ + +@@ -1739,7 +1762,6 @@ free_interfaces: + * 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 --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c +index 882484a..fa12ec8 100644 +--- a/drivers/usb/gadget/f_rndis.c ++++ b/drivers/usb/gadget/f_rndis.c +@@ -420,8 +420,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) + */ + case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) + | USB_CDC_SEND_ENCAPSULATED_COMMAND: +- if (w_length > req->length || w_value +- || w_index != rndis->ctrl_id) ++ if (w_value || w_index != rndis->ctrl_id) + goto invalid; + /* read the request; process it later */ + value = w_length; +diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c +index 78561d1..c606b02 100644 +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -777,8 +777,9 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) + goto dead; + } + ++ /* Shared IRQ? */ + masked_status = status & INTR_MASK; +- if (!masked_status) { /* irq sharing? */ ++ if (!masked_status || unlikely(hcd->state == HC_STATE_HALT)) { + spin_unlock(&ehci->lock); + return IRQ_NONE; + } +@@ -873,6 +874,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) + dead: + ehci_reset(ehci); + ehci_writel(ehci, 0, &ehci->regs->configured_flag); ++ usb_hc_died(hcd); + /* generic layer kills/unlinks all urbs, then + * uses ehci_stop to clean up the rest + */ +diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c +index 1543c83..d12426f 100644 +--- a/drivers/usb/host/ehci-sched.c ++++ b/drivers/usb/host/ehci-sched.c +@@ -471,8 +471,10 @@ static int enable_periodic (struct ehci_hcd *ehci) + */ + status = handshake_on_error_set_halt(ehci, &ehci->regs->status, + STS_PSS, 0, 9 * 125); +- if (status) ++ if (status) { ++ usb_hc_died(ehci_to_hcd(ehci)); + return status; ++ } + + cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; + ehci_writel(ehci, cmd, &ehci->regs->command); +@@ -510,8 +512,10 @@ static int disable_periodic (struct ehci_hcd *ehci) + */ + status = handshake_on_error_set_halt(ehci, &ehci->regs->status, + STS_PSS, STS_PSS, 9 * 125); +- if (status) ++ if (status) { ++ usb_hc_died(ehci_to_hcd(ehci)); + return status; ++ } + + cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE; + ehci_writel(ehci, cmd, &ehci->regs->command); +diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c +index c0e22f2..baae4cc 100644 +--- a/drivers/usb/host/isp116x-hcd.c ++++ b/drivers/usb/host/isp116x-hcd.c +@@ -612,6 +612,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd) + /* IRQ's are off, we do no DMA, + perfectly ready to die ... */ + hcd->state = HC_STATE_HALT; ++ usb_hc_died(hcd); + ret = IRQ_HANDLED; + goto done; + } +diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c +index d557235..c001fff 100644 +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -764,6 +764,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) + if (ints == ~(u32)0) { + disable (ohci); + ohci_dbg (ohci, "device removed!\n"); ++ usb_hc_died(hcd); + return IRQ_HANDLED; + } + +@@ -771,7 +772,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) + ints &= ohci_readl(ohci, ®s->intrenable); + + /* interrupt for some other device? */ +- if (ints == 0) ++ if (ints == 0 || unlikely(hcd->state == HC_STATE_HALT)) + return IRQ_NOTMINE; + + if (ints & OHCI_INTR_UE) { +@@ -788,6 +789,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) + } else { + disable (ohci); + ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n"); ++ usb_hc_died(hcd); + } + + ohci_dump (ohci, 1); +diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c +index d84d6f0..ad8166c 100644 +--- a/drivers/usb/host/ohci-pci.c ++++ b/drivers/usb/host/ohci-pci.c +@@ -181,10 +181,18 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) + */ + static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd) + { ++ struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + +- ohci->flags |= OHCI_QUIRK_SHUTDOWN; +- ohci_dbg(ohci, "enabled nVidia shutdown quirk\n"); ++ /* Evidently nVidia fixed their later hardware; this is a guess at ++ * the changeover point. ++ */ ++#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB 0x026d ++ ++ if (pdev->device < PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB) { ++ ohci->flags |= OHCI_QUIRK_SHUTDOWN; ++ ohci_dbg(ohci, "enabled nVidia shutdown quirk\n"); ++ } + + return 0; + } +diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c +index 4a771f6..5fbe997 100644 +--- a/drivers/usb/host/oxu210hp-hcd.c ++++ b/drivers/usb/host/oxu210hp-hcd.c +@@ -1884,6 +1884,7 @@ static int enable_periodic(struct oxu_hcd *oxu) + status = handshake(oxu, &oxu->regs->status, STS_PSS, 0, 9 * 125); + if (status != 0) { + oxu_to_hcd(oxu)->state = HC_STATE_HALT; ++ usb_hc_died(oxu_to_hcd(oxu)); + return status; + } + +@@ -1909,6 +1910,7 @@ static int disable_periodic(struct oxu_hcd *oxu) + status = handshake(oxu, &oxu->regs->status, STS_PSS, STS_PSS, 9 * 125); + if (status != 0) { + oxu_to_hcd(oxu)->state = HC_STATE_HALT; ++ usb_hc_died(oxu_to_hcd(oxu)); + return status; + } + +@@ -2449,8 +2451,9 @@ static irqreturn_t oxu210_hcd_irq(struct usb_hcd *hcd) + goto dead; + } + ++ /* Shared IRQ? */ + status &= INTR_MASK; +- if (!status) { /* irq sharing? */ ++ if (!status || unlikely(hcd->state == HC_STATE_HALT)) { + spin_unlock(&oxu->lock); + return IRQ_NONE; + } +@@ -2516,6 +2519,7 @@ static irqreturn_t oxu210_hcd_irq(struct usb_hcd *hcd) + dead: + ehci_reset(oxu); + writel(0, &oxu->regs->configured_flag); ++ usb_hc_died(hcd); + /* generic layer kills/unlinks all urbs, then + * uses oxu_stop to clean up the rest + */ +diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c +index 0231814..ff00bd8 100644 +--- a/drivers/usb/host/xhci-dbg.c ++++ b/drivers/usb/host/xhci-dbg.c +@@ -437,13 +437,13 @@ char *xhci_get_slot_state(struct xhci_hcd *xhci, + struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx); + + switch (GET_SLOT_STATE(slot_ctx->dev_state)) { +- case 0: ++ case SLOT_STATE_ENABLED: + return "enabled/disabled"; +- case 1: ++ case SLOT_STATE_DEFAULT: + return "default"; +- case 2: ++ case SLOT_STATE_ADDRESSED: + return "addressed"; +- case 3: ++ case SLOT_STATE_CONFIGURED: + return "configured"; + default: + return "reserved"; +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index 627f343..976422a 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -207,14 +207,13 @@ void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci, + + rings_cached = virt_dev->num_rings_cached; + if (rings_cached < XHCI_MAX_RINGS_CACHED) { +- virt_dev->num_rings_cached++; +- rings_cached = virt_dev->num_rings_cached; + virt_dev->ring_cache[rings_cached] = + virt_dev->eps[ep_index].ring; ++ virt_dev->num_rings_cached++; + xhci_dbg(xhci, "Cached old ring, " + "%d ring%s cached\n", +- rings_cached, +- (rings_cached > 1) ? "s" : ""); ++ virt_dev->num_rings_cached, ++ (virt_dev->num_rings_cached > 1) ? "s" : ""); + } else { + xhci_ring_free(xhci, virt_dev->eps[ep_index].ring); + xhci_dbg(xhci, "Ring cache full (%d rings), " +@@ -987,9 +986,19 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev, + interval = clamp_val(ep->desc.bInterval, 1, 16) - 1; + if (interval != ep->desc.bInterval - 1) + dev_warn(&udev->dev, +- "ep %#x - rounding interval to %d microframes\n", ++ "ep %#x - rounding interval to %d %sframes\n", + ep->desc.bEndpointAddress, +- 1 << interval); ++ 1 << interval, ++ udev->speed == USB_SPEED_FULL ? "" : "micro"); ++ ++ if (udev->speed == USB_SPEED_FULL) { ++ /* ++ * Full speed isoc endpoints specify interval in frames, ++ * not microframes. We are using microframes everywhere, ++ * so adjust accordingly. ++ */ ++ interval += 3; /* 1 frame = 2^3 uframes */ ++ } + + return interval; + } +@@ -1046,12 +1055,12 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev, + break; + + case USB_SPEED_FULL: +- if (usb_endpoint_xfer_int(&ep->desc)) { ++ if (usb_endpoint_xfer_isoc(&ep->desc)) { + interval = xhci_parse_exponent_interval(udev, ep); + break; + } + /* +- * Fall through for isochronous endpoint interval decoding ++ * Fall through for interrupt endpoint interval decoding + * since it uses the same rules as low speed interrupt + * endpoints. + */ +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index a10494c..6fce318 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -28,6 +28,9 @@ + #define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 + #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000 + ++#define PCI_VENDOR_ID_ETRON 0x1b6f ++#define PCI_DEVICE_ID_ASROCK_P67 0x7023 ++ + static const char hcd_name[] = "xhci_hcd"; + + /* called after powerup, by probe or system-pm "wakeup" */ +@@ -105,12 +108,27 @@ static int xhci_pci_setup(struct usb_hcd *hcd) + + /* Look for vendor-specific quirks */ + if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && +- pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK && +- pdev->revision == 0x0) { ++ pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) { ++ if (pdev->revision == 0x0) { + xhci->quirks |= XHCI_RESET_EP_QUIRK; + xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" + " endpoint cmd after reset endpoint\n"); ++ } ++ /* Fresco Logic confirms: all revisions of this chip do not ++ * support MSI, even though some of them claim to in their PCI ++ * capabilities. ++ */ ++ xhci->quirks |= XHCI_BROKEN_MSI; ++ xhci_dbg(xhci, "QUIRK: Fresco Logic revision %u " ++ "has broken MSI implementation\n", ++ pdev->revision); + } ++ if (pdev->vendor == PCI_VENDOR_ID_ETRON && ++ pdev->device == PCI_DEVICE_ID_ASROCK_P67) { ++ xhci->quirks |= XHCI_RESET_ON_RESUME; ++ xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); ++ } ++ + if (pdev->vendor == PCI_VENDOR_ID_NEC) + xhci->quirks |= XHCI_NEC_HOST; + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 7437386..a5e96cb 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1632,6 +1632,9 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, + else + *status = 0; + break; ++ case COMP_STOP_INVAL: ++ case COMP_STOP: ++ return finish_td(xhci, td, event_trb, event, ep, status, false); + default: + if (!xhci_requires_manual_halt_cleanup(xhci, + ep_ctx, trb_comp_code)) +@@ -1676,15 +1679,12 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, + } + } else { + /* Maybe the event was for the data stage? */ +- if (trb_comp_code != COMP_STOP_INVAL) { +- /* We didn't stop on a link TRB in the middle */ +- td->urb->actual_length = +- td->urb->transfer_buffer_length - +- TRB_LEN(event->transfer_len); +- xhci_dbg(xhci, "Waiting for status " +- "stage event\n"); +- return 0; +- } ++ td->urb->actual_length = ++ td->urb->transfer_buffer_length - ++ TRB_LEN(le32_to_cpu(event->transfer_len)); ++ xhci_dbg(xhci, "Waiting for status " ++ "stage event\n"); ++ return 0; + } + } + +@@ -1768,9 +1768,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, + } + } + +- if ((idx == urb_priv->length - 1) && *status == -EINPROGRESS) +- *status = 0; +- + return finish_td(xhci, td, event_trb, event, ep, status, false); + } + +@@ -1788,8 +1785,7 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, + idx = urb_priv->td_cnt; + frame = &td->urb->iso_frame_desc[idx]; + +- /* The transfer is partly done */ +- *status = -EXDEV; ++ /* The transfer is partly done. */ + frame->status = -EXDEV; + + /* calc actual length */ +@@ -2139,6 +2135,11 @@ cleanup: + "status = %d\n", + urb, urb->actual_length, status); + spin_unlock(&xhci->lock); ++ /* EHCI, UHCI, and OHCI always unconditionally set the ++ * urb->status of an isochronous endpoint to 0. ++ */ ++ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) ++ status = 0; + usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status); + spin_lock(&xhci->lock); + } +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 81b976e..4209b02 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -430,12 +430,19 @@ int xhci_run(struct usb_hcd *hcd) + free_irq(hcd->irq, hcd); + hcd->irq = -1; + ++ /* Some Fresco Logic host controllers advertise MSI, but fail to ++ * generate interrupts. Don't even try to enable MSI. ++ */ ++ if (xhci->quirks & XHCI_BROKEN_MSI) ++ goto legacy_irq; ++ + ret = xhci_setup_msix(xhci); + if (ret) + /* fall back to msi*/ + ret = xhci_setup_msi(xhci); + + if (ret) { ++legacy_irq: + /* fall back to legacy interrupt*/ + ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, + hcd->irq_descr, hcd); +@@ -752,6 +759,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + msleep(100); + + spin_lock_irq(&xhci->lock); ++ if (xhci->quirks & XHCI_RESET_ON_RESUME) ++ hibernated = true; + + if (!hibernated) { + /* step 1: restore register */ +@@ -1389,6 +1398,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, + u32 added_ctxs; + unsigned int last_ctx; + u32 new_add_flags, new_drop_flags, new_slot_info; ++ struct xhci_virt_device *virt_dev; + int ret = 0; + + ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); +@@ -1411,11 +1421,25 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, + return 0; + } + +- in_ctx = xhci->devs[udev->slot_id]->in_ctx; +- out_ctx = xhci->devs[udev->slot_id]->out_ctx; ++ virt_dev = xhci->devs[udev->slot_id]; ++ in_ctx = virt_dev->in_ctx; ++ out_ctx = virt_dev->out_ctx; + ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ep_index = xhci_get_endpoint_index(&ep->desc); + ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); ++ ++ /* If this endpoint is already in use, and the upper layers are trying ++ * to add it again without dropping it, reject the addition. ++ */ ++ if (virt_dev->eps[ep_index].ring && ++ !(le32_to_cpu(ctrl_ctx->drop_flags) & ++ xhci_get_endpoint_flag(&ep->desc))) { ++ xhci_warn(xhci, "Trying to add endpoint 0x%x " ++ "without dropping it.\n", ++ (unsigned int) ep->desc.bEndpointAddress); ++ return -EINVAL; ++ } ++ + /* If the HCD has already noted the endpoint is enabled, + * ignore this request. + */ +@@ -1430,8 +1454,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, + * process context, not interrupt context (or so documenation + * for usb_set_interface() and usb_set_configuration() claim). + */ +- if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], +- udev, ep, GFP_NOIO) < 0) { ++ if (xhci_endpoint_init(xhci, virt_dev, udev, ep, GFP_NOIO) < 0) { + dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", + __func__, ep->desc.bEndpointAddress); + return -ENOMEM; +@@ -1692,8 +1715,17 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) + xhci_dbg_ctx(xhci, virt_dev->out_ctx, + LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); + ++ /* Free any rings that were dropped, but not changed. */ ++ for (i = 1; i < 31; ++i) { ++ if ((ctrl_ctx->drop_flags & (1 << (i + 1))) && ++ !(ctrl_ctx->add_flags & (1 << (i + 1)))) ++ xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); ++ } + xhci_zero_in_ctx(xhci, virt_dev); +- /* Install new rings and free or cache any old rings */ ++ /* ++ * Install any rings for completely new endpoints or changed endpoints, ++ * and free or cache any old rings from changed endpoints. ++ */ + for (i = 1; i < 31; ++i) { + if (!virt_dev->eps[i].new_ring) + continue; +@@ -2275,6 +2307,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) + struct xhci_command *reset_device_cmd; + int timeleft; + int last_freed_endpoint; ++ struct xhci_slot_ctx *slot_ctx; + + ret = xhci_check_args(hcd, udev, NULL, 0, false, __func__); + if (ret <= 0) +@@ -2307,6 +2340,12 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) + return -EINVAL; + } + ++ /* If device is not setup, there is no point in resetting it */ ++ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); ++ if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == ++ SLOT_STATE_DISABLED) ++ return 0; ++ + xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); + /* Allocate the command structure that holds the struct completion. + * Assume we're in process context, since the normal device reset +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index ba1be6b..1e52d5e 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -560,6 +560,11 @@ struct xhci_slot_ctx { + #define SLOT_STATE (0x1f << 27) + #define GET_SLOT_STATE(p) (((p) & (0x1f << 27)) >> 27) + ++#define SLOT_STATE_DISABLED 0 ++#define SLOT_STATE_ENABLED SLOT_STATE_DISABLED ++#define SLOT_STATE_DEFAULT 1 ++#define SLOT_STATE_ADDRESSED 2 ++#define SLOT_STATE_CONFIGURED 3 + + /** + * struct xhci_ep_ctx +@@ -1281,6 +1286,8 @@ struct xhci_hcd { + #define XHCI_RESET_EP_QUIRK (1 << 1) + #define XHCI_NEC_HOST (1 << 2) + #define XHCI_AMD_PLL_FIX (1 << 3) ++#define XHCI_BROKEN_MSI (1 << 6) ++#define XHCI_RESET_ON_RESUME (1 << 7) + /* There are two roothubs to keep track of bus suspend info for */ + struct xhci_bus_state bus_state[2]; + /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index 0f11afd..ebeccb7 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -112,6 +112,10 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */ + { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ + { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ ++ { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */ ++ { USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */ ++ { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ ++ { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ + { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */ +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 4de6ef0..2e06b90 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -179,6 +179,7 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_232H_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, +@@ -566,6 +567,7 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, FTDI_IBS_APP70_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_TAVIR_STK500_PID) }, + /* + * ELV devices: + */ +@@ -646,6 +648,7 @@ static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) }, + { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_3_PID) }, + { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) }, + { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_1_PID) }, + { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_2_PID) }, +@@ -846,7 +849,8 @@ static const char *ftdi_chip_name[] = { + [FT2232C] = "FT2232C", + [FT232RL] = "FT232RL", + [FT2232H] = "FT2232H", +- [FT4232H] = "FT4232H" ++ [FT4232H] = "FT4232H", ++ [FT232H] = "FT232H" + }; + + +@@ -1166,6 +1170,7 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, + break; + case FT2232H: /* FT2232H chip */ + case FT4232H: /* FT4232H chip */ ++ case FT232H: /* FT232H chip */ + if ((baud <= 12000000) & (baud >= 1200)) { + div_value = ftdi_2232h_baud_to_divisor(baud); + } else if (baud < 1200) { +@@ -1427,9 +1432,12 @@ static void ftdi_determine_type(struct usb_serial_port *port) + } else if (version < 0x600) { + /* Assume it's an FT232BM (or FT245BM) */ + priv->chip_type = FT232BM; +- } else { +- /* Assume it's an FT232R */ ++ } else if (version < 0x900) { ++ /* Assume it's an FT232RL */ + priv->chip_type = FT232RL; ++ } else { ++ /* Assume it's an FT232H */ ++ priv->chip_type = FT232H; + } + dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); + } +@@ -1557,7 +1565,8 @@ static int create_sysfs_attrs(struct usb_serial_port *port) + priv->chip_type == FT2232C || + priv->chip_type == FT232RL || + priv->chip_type == FT2232H || +- priv->chip_type == FT4232H)) { ++ priv->chip_type == FT4232H || ++ priv->chip_type == FT232H)) { + retval = device_create_file(&port->dev, + &dev_attr_latency_timer); + } +@@ -1578,7 +1587,8 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) + priv->chip_type == FT2232C || + priv->chip_type == FT232RL || + priv->chip_type == FT2232H || +- priv->chip_type == FT4232H) { ++ priv->chip_type == FT4232H || ++ priv->chip_type == FT232H) { + device_remove_file(&port->dev, &dev_attr_latency_timer); + } + } +@@ -2210,6 +2220,7 @@ static int ftdi_tiocmget(struct tty_struct *tty) + case FT232RL: + case FT2232H: + case FT4232H: ++ case FT232H: + len = 2; + break; + default: +diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h +index 213fe3d..19584fa 100644 +--- a/drivers/usb/serial/ftdi_sio.h ++++ b/drivers/usb/serial/ftdi_sio.h +@@ -156,7 +156,8 @@ enum ftdi_chip_type { + FT2232C = 4, + FT232RL = 5, + FT2232H = 6, +- FT4232H = 7 ++ FT4232H = 7, ++ FT232H = 8 + }; + + enum ftdi_sio_baudrate { +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index efffc23..19156d1 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -22,6 +22,7 @@ + #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ + #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ + #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ ++#define FTDI_232H_PID 0x6014 /* Single channel hi-speed device */ + #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ + #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ + +@@ -351,6 +352,7 @@ + */ + #define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 + #define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 ++#define FTDI_4N_GALAXY_DE_3_PID 0xF3C2 + + /* + * Linx Technologies product ids +@@ -491,6 +493,11 @@ + /* www.canusb.com Lawicel CANUSB device (FTDI_VID) */ + #define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ + ++/* ++ * TavIR AVR product ids (FTDI_VID) ++ */ ++#define FTDI_TAVIR_STK500_PID 0xFA33 /* STK500 AVR programmer */ ++ + + + /********************************/ +diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c +index 26710b1..456447e033 100644 +--- a/drivers/usb/serial/garmin_gps.c ++++ b/drivers/usb/serial/garmin_gps.c +@@ -1,7 +1,7 @@ + /* + * Garmin GPS driver + * +- * Copyright (C) 2006-2009 Hermann Kneissel herkne@users.sourceforge.net ++ * Copyright (C) 2006-2011 Hermann Kneissel herkne@gmx.de + * + * The latest version of the driver can be found at + * http://sourceforge.net/projects/garmin-gps/ +@@ -51,7 +51,7 @@ static int debug; + */ + + #define VERSION_MAJOR 0 +-#define VERSION_MINOR 33 ++#define VERSION_MINOR 36 + + #define _STR(s) #s + #define _DRIVER_VERSION(a, b) "v" _STR(a) "." _STR(b) +@@ -410,6 +410,7 @@ static int gsp_send_ack(struct garmin_data *garmin_data_p, __u8 pkt_id) + */ + static int gsp_rec_packet(struct garmin_data *garmin_data_p, int count) + { ++ unsigned long flags; + const __u8 *recpkt = garmin_data_p->inbuffer+GSP_INITIAL_OFFSET; + __le32 *usbdata = (__le32 *) garmin_data_p->inbuffer; + +@@ -458,7 +459,9 @@ static int gsp_rec_packet(struct garmin_data *garmin_data_p, int count) + /* if this was an abort-transfer command, flush all + queued data. */ + if (isAbortTrfCmnd(garmin_data_p->inbuffer)) { ++ spin_lock_irqsave(&garmin_data_p->lock, flags); + garmin_data_p->flags |= FLAGS_DROP_DATA; ++ spin_unlock_irqrestore(&garmin_data_p->lock, flags); + pkt_clear(garmin_data_p); + } + +@@ -943,7 +946,7 @@ static int garmin_open(struct tty_struct *tty, struct usb_serial_port *port) + spin_lock_irqsave(&garmin_data_p->lock, flags); + garmin_data_p->mode = initial_mode; + garmin_data_p->count = 0; +- garmin_data_p->flags = 0; ++ garmin_data_p->flags &= FLAGS_SESSION_REPLY1_SEEN; + spin_unlock_irqrestore(&garmin_data_p->lock, flags); + + /* shutdown any bulk reads that might be going on */ +@@ -1178,7 +1181,8 @@ static int garmin_write_room(struct tty_struct *tty) + + + static void garmin_read_process(struct garmin_data *garmin_data_p, +- unsigned char *data, unsigned data_length) ++ unsigned char *data, unsigned data_length, ++ int bulk_data) + { + unsigned long flags; + +@@ -1193,7 +1197,8 @@ static void garmin_read_process(struct garmin_data *garmin_data_p, + send it directly to the tty port */ + if (garmin_data_p->flags & FLAGS_QUEUING) { + pkt_add(garmin_data_p, data, data_length); +- } else if (getLayerId(data) == GARMIN_LAYERID_APPL) { ++ } else if (bulk_data || ++ getLayerId(data) == GARMIN_LAYERID_APPL) { + + spin_lock_irqsave(&garmin_data_p->lock, flags); + garmin_data_p->flags |= APP_RESP_SEEN; +@@ -1237,7 +1242,7 @@ static void garmin_read_bulk_callback(struct urb *urb) + usb_serial_debug_data(debug, &port->dev, + __func__, urb->actual_length, data); + +- garmin_read_process(garmin_data_p, data, urb->actual_length); ++ garmin_read_process(garmin_data_p, data, urb->actual_length, 1); + + if (urb->actual_length == 0 && + 0 != (garmin_data_p->flags & FLAGS_BULK_IN_RESTART)) { +@@ -1346,7 +1351,7 @@ static void garmin_read_int_callback(struct urb *urb) + __func__, garmin_data_p->serial_num); + } + +- garmin_read_process(garmin_data_p, data, urb->actual_length); ++ garmin_read_process(garmin_data_p, data, urb->actual_length, 0); + + port->interrupt_in_urb->dev = port->serial->dev; + retval = usb_submit_urb(urb, GFP_ATOMIC); +@@ -1461,6 +1466,7 @@ static int garmin_attach(struct usb_serial *serial) + garmin_data_p->timer.function = timeout_handler; + garmin_data_p->port = port; + garmin_data_p->state = 0; ++ garmin_data_p->flags = 0; + garmin_data_p->count = 0; + usb_set_serial_port_data(port, garmin_data_p); + +diff --git a/drivers/usb/serial/moto_modem.c b/drivers/usb/serial/moto_modem.c +index 653465f..e2bfecc 100644 +--- a/drivers/usb/serial/moto_modem.c ++++ b/drivers/usb/serial/moto_modem.c +@@ -25,6 +25,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ + { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */ + { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */ ++ { USB_DEVICE(0x22b8, 0x2c84) }, /* Motorola VE240 phone */ + { USB_DEVICE(0x22b8, 0x2c64) }, /* Motorola V950 phone */ + { }, + }; +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index d77ff04..60b25d8 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -149,6 +149,7 @@ static void option_instat_callback(struct urb *urb); + #define HUAWEI_PRODUCT_K3765 0x1465 + #define HUAWEI_PRODUCT_E14AC 0x14AC + #define HUAWEI_PRODUCT_ETS1220 0x1803 ++#define HUAWEI_PRODUCT_E353 0x1506 + + #define QUANTA_VENDOR_ID 0x0408 + #define QUANTA_PRODUCT_Q101 0xEA02 +@@ -310,10 +311,6 @@ static void option_instat_callback(struct urb *urb); + #define ZTE_PRODUCT_AC2726 0xfff5 + #define ZTE_PRODUCT_AC8710T 0xffff + +-/* ZTE PRODUCTS -- alternate vendor ID */ +-#define ZTE_VENDOR_ID2 0x1d6b +-#define ZTE_PRODUCT_MF_330 0x0002 +- + #define BENQ_VENDOR_ID 0x04a5 + #define BENQ_PRODUCT_H10 0x4068 + +@@ -339,11 +336,12 @@ static void option_instat_callback(struct urb *urb); + #define TOSHIBA_PRODUCT_G450 0x0d45 + + #define ALINK_VENDOR_ID 0x1e0e ++#define ALINK_PRODUCT_PH300 0x9100 + #define ALINK_PRODUCT_3GU 0x9200 + + /* ALCATEL PRODUCTS */ + #define ALCATEL_VENDOR_ID 0x1bbb +-#define ALCATEL_PRODUCT_X060S 0x0000 ++#define ALCATEL_PRODUCT_X060S_X200 0x0000 + + #define PIRELLI_VENDOR_ID 0x1266 + #define PIRELLI_PRODUCT_C100_1 0x1002 +@@ -378,6 +376,9 @@ static void option_instat_callback(struct urb *urb); + * It seems to contain a Qualcomm QSC6240/6290 chipset */ + #define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603 + ++/* Zoom */ ++#define ZOOM_PRODUCT_4597 0x9607 ++ + /* Haier products */ + #define HAIER_VENDOR_ID 0x201e + #define HAIER_PRODUCT_CE100 0x2009 +@@ -431,6 +432,20 @@ static const struct option_blacklist_info four_g_w14_blacklist = { + .reason = OPTION_BLACKLIST_SENDSETUP + }; + ++static const u8 alcatel_x200_no_sendsetup[] = { 0, 1 }; ++static const struct option_blacklist_info alcatel_x200_blacklist = { ++ .infolen = ARRAY_SIZE(alcatel_x200_no_sendsetup), ++ .ifaceinfo = alcatel_x200_no_sendsetup, ++ .reason = OPTION_BLACKLIST_SENDSETUP ++}; ++ ++static const u8 zte_k3765_z_no_sendsetup[] = { 0, 1, 2 }; ++static const struct option_blacklist_info zte_k3765_z_blacklist = { ++ .infolen = ARRAY_SIZE(zte_k3765_z_no_sendsetup), ++ .ifaceinfo = zte_k3765_z_no_sendsetup, ++ .reason = OPTION_BLACKLIST_SENDSETUP ++}; ++ + static const struct usb_device_id option_ids[] = { + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, +@@ -532,6 +547,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, +@@ -914,13 +930,13 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, ++ 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, +- { USB_DEVICE(ZTE_VENDOR_ID2, ZTE_PRODUCT_MF_330) }, + { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, + { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, + { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ +@@ -933,13 +949,17 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, + { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ + { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, ++ { USB_DEVICE(ALINK_VENDOR_ID, ALINK_PRODUCT_PH300) }, + { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, +- { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, ++ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), ++ .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist ++ }, + { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, + { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), + .driver_info = (kernel_ulong_t)&four_g_w14_blacklist + }, ++ { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) }, + { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, + /* Pirelli */ + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)}, +@@ -972,7 +992,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, + { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ + { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ +- { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730/GT-B3710 LTE USB modem.*/ ++ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +@@ -1109,6 +1129,12 @@ static int option_probe(struct usb_serial *serial, + serial->interface->cur_altsetting->desc.bInterfaceNumber == 1) + return -ENODEV; + ++ /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */ ++ if (serial->dev->descriptor.idVendor == SAMSUNG_VENDOR_ID && ++ serial->dev->descriptor.idProduct == SAMSUNG_PRODUCT_GT_B3730 && ++ serial->interface->cur_altsetting->desc.bInterfaceClass != USB_CLASS_CDC_DATA) ++ return -ENODEV; ++ + data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); + + if (!data) +diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c +index 30461fc..0c20831 100644 +--- a/drivers/usb/serial/pl2303.c ++++ b/drivers/usb/serial/pl2303.c +@@ -91,6 +91,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, + { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, + { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, ++ { USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) }, + { } /* Terminating entry */ + }; + +diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h +index 1b025f7..ca0d237 100644 +--- a/drivers/usb/serial/pl2303.h ++++ b/drivers/usb/serial/pl2303.h +@@ -144,3 +144,7 @@ + /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ + #define ADLINK_VENDOR_ID 0x0b63 + #define ADLINK_ND6530_PRODUCT_ID 0x6530 ++ ++/* WinChipHead USB->RS 232 adapter */ ++#define WINCHIPHEAD_VENDOR_ID 0x4348 ++#define WINCHIPHEAD_USBSER_PRODUCT_ID 0x5523 +diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c +index 0041899..e8ae21b 100644 +--- a/drivers/usb/storage/transport.c ++++ b/drivers/usb/storage/transport.c +@@ -819,6 +819,35 @@ Retry_Sense: + } + } + ++ /* ++ * Some devices don't work or return incorrect data the first ++ * time they get a READ(10) command, or for the first READ(10) ++ * after a media change. If the INITIAL_READ10 flag is set, ++ * keep track of whether READ(10) commands succeed. If the ++ * previous one succeeded and this one failed, set the REDO_READ10 ++ * flag to force a retry. ++ */ ++ if (unlikely((us->fflags & US_FL_INITIAL_READ10) && ++ srb->cmnd[0] == READ_10)) { ++ if (srb->result == SAM_STAT_GOOD) { ++ set_bit(US_FLIDX_READ10_WORKED, &us->dflags); ++ } else if (test_bit(US_FLIDX_READ10_WORKED, &us->dflags)) { ++ clear_bit(US_FLIDX_READ10_WORKED, &us->dflags); ++ set_bit(US_FLIDX_REDO_READ10, &us->dflags); ++ } ++ ++ /* ++ * Next, if the REDO_READ10 flag is set, return a result ++ * code that will cause the SCSI core to retry the READ(10) ++ * command immediately. ++ */ ++ if (test_bit(US_FLIDX_REDO_READ10, &us->dflags)) { ++ clear_bit(US_FLIDX_REDO_READ10, &us->dflags); ++ srb->result = DID_IMM_RETRY << 16; ++ srb->sense_buffer[0] = 0; ++ } ++ } ++ + /* Did we transfer less than the minimum amount required? */ + if ((srb->result == SAM_STAT_GOOD || srb->sense_buffer[2] == 0) && + scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow) +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index c1602b8..ccff348 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -1114,6 +1114,16 @@ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + ++/* Reported by Paul Hartman <paul.hartman+linux@gmail.com> ++ * This card reader returns "Illegal Request, Logical Block Address ++ * Out of Range" for the first READ(10) after a new card is inserted. ++ */ ++UNUSUAL_DEV( 0x090c, 0x6000, 0x0100, 0x0100, ++ "Feiya", ++ "SD/SDHC Card Reader", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_INITIAL_READ10 ), ++ + /* This Pentax still camera is not conformant + * to the USB storage specification: - + * - It does not like the INQUIRY command. So we must handle this command +@@ -1888,6 +1898,15 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_READ_DISC_INFO ), + ++/* Reported by Sven Geggus <sven-usbst@geggus.net> ++ * This encrypted pen drive returns bogus data for the initial READ(10). ++ */ ++UNUSUAL_DEV( 0x1b1c, 0x1ab5, 0x0200, 0x0200, ++ "Corsair", ++ "Padlock v2", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_INITIAL_READ10 ), ++ + /* Patch by Richard Schütz <r.schtz@t-online.de> + * This external hard drive enclosure uses a JMicron chip which + * needs the US_FL_IGNORE_RESIDUE flag to work properly. */ +diff --git a/drivers/usb/storage/unusual_realtek.h b/drivers/usb/storage/unusual_realtek.h +index 3236e03..e41f50c 100644 +--- a/drivers/usb/storage/unusual_realtek.h ++++ b/drivers/usb/storage/unusual_realtek.h +@@ -23,19 +23,19 @@ + #if defined(CONFIG_USB_STORAGE_REALTEK) || \ + defined(CONFIG_USB_STORAGE_REALTEK_MODULE) + +-UNUSUAL_DEV(0x0bda, 0x0159, 0x0000, 0x9999, ++UNUSUAL_DEV(0x0bda, 0x0138, 0x0000, 0x9999, + "Realtek", + "USB Card Reader", +- USB_SC_SCSI, USB_PR_BULK, init_realtek_cr, 0), ++ USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0), + + UNUSUAL_DEV(0x0bda, 0x0158, 0x0000, 0x9999, + "Realtek", + "USB Card Reader", +- USB_SC_SCSI, USB_PR_BULK, init_realtek_cr, 0), ++ USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0), + +-UNUSUAL_DEV(0x0bda, 0x0138, 0x0000, 0x9999, ++UNUSUAL_DEV(0x0bda, 0x0159, 0x0000, 0x9999, + "Realtek", + "USB Card Reader", +- USB_SC_SCSI, USB_PR_BULK, init_realtek_cr, 0), ++ USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0), + + #endif /* defined(CONFIG_USB_STORAGE_REALTEK) || ... */ +diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c +index 4219c19..07d6d73 100644 +--- a/drivers/usb/storage/usb.c ++++ b/drivers/usb/storage/usb.c +@@ -439,7 +439,8 @@ static void adjust_quirks(struct us_data *us) + US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE | + US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 | + US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE | +- US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT); ++ US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT | ++ US_FL_INITIAL_READ10); + + p = quirks; + while (*p) { +@@ -483,6 +484,9 @@ static void adjust_quirks(struct us_data *us) + case 'm': + f |= US_FL_MAX_SECTORS_64; + break; ++ case 'n': ++ f |= US_FL_INITIAL_READ10; ++ break; + case 'o': + f |= US_FL_CAPACITY_OK; + break; +@@ -946,6 +950,13 @@ int usb_stor_probe2(struct us_data *us) + if (result) + goto BadDevice; + ++ /* ++ * If the device returns invalid data for the first READ(10) ++ * command, indicate the command should be retried. ++ */ ++ if (us->fflags & US_FL_INITIAL_READ10) ++ set_bit(US_FLIDX_REDO_READ10, &us->dflags); ++ + /* Acquire all the other resources and add the host */ + result = usb_stor_acquire_resources(us); + if (result) +diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h +index 89d3bff..7b0f211 100644 +--- a/drivers/usb/storage/usb.h ++++ b/drivers/usb/storage/usb.h +@@ -73,6 +73,8 @@ struct us_unusual_dev { + #define US_FLIDX_RESETTING 4 /* device reset in progress */ + #define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ + #define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */ ++#define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */ ++#define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */ + + #define USB_STOR_STRING_LEN 32 + +diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c +index 53b2c5a..305c975 100644 +--- a/drivers/video/vga16fb.c ++++ b/drivers/video/vga16fb.c +@@ -1265,9 +1265,11 @@ static void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image + + static void vga16fb_destroy(struct fb_info *info) + { ++ struct platform_device *dev = container_of(info->device, struct platform_device, dev); + iounmap(info->screen_base); + fb_dealloc_cmap(&info->cmap); + /* XXX unshare VGA regions */ ++ platform_set_drvdata(dev, NULL); + framebuffer_release(info); + } + +diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c +index 5ec5ac1..befbe80 100644 +--- a/drivers/watchdog/mtx-1_wdt.c ++++ b/drivers/watchdog/mtx-1_wdt.c +@@ -211,6 +211,12 @@ static int __devinit mtx1_wdt_probe(struct platform_device *pdev) + int ret; + + mtx1_wdt_device.gpio = pdev->resource[0].start; ++ ret = gpio_request_one(mtx1_wdt_device.gpio, ++ GPIOF_OUT_INIT_HIGH, "mtx1-wdt"); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "failed to request gpio"); ++ return ret; ++ } + + spin_lock_init(&mtx1_wdt_device.lock); + init_completion(&mtx1_wdt_device.stop); +@@ -236,6 +242,8 @@ static int __devexit mtx1_wdt_remove(struct platform_device *pdev) + mtx1_wdt_device.queue = 0; + wait_for_completion(&mtx1_wdt_device.stop); + } ++ ++ gpio_free(mtx1_wdt_device.gpio); + misc_deregister(&mtx1_wdt_misc); + return 0; + } +diff --git a/fs/block_dev.c b/fs/block_dev.c +index 257b00e..610e8e0 100644 +--- a/fs/block_dev.c ++++ b/fs/block_dev.c +@@ -762,7 +762,19 @@ static struct block_device *bd_start_claiming(struct block_device *bdev, + if (!disk) + return ERR_PTR(-ENXIO); + +- whole = bdget_disk(disk, 0); ++ /* ++ * Normally, @bdev should equal what's returned from bdget_disk() ++ * if partno is 0; however, some drivers (floppy) use multiple ++ * bdev's for the same physical device and @bdev may be one of the ++ * aliases. Keep @bdev if partno is 0. This means claimer ++ * tracking is broken for those devices but it has always been that ++ * way. ++ */ ++ if (partno) ++ whole = bdget_disk(disk, 0); ++ else ++ whole = bdgrab(bdev); ++ + module_put(disk->fops->owner); + put_disk(disk); + if (!whole) +@@ -1120,6 +1132,15 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) + goto restart; + } + } ++ ++ if (!ret && !bdev->bd_openers) { ++ bd_set_size(bdev,(loff_t)get_capacity(disk)<<9); ++ bdi = blk_get_backing_dev_info(bdev); ++ if (bdi == NULL) ++ bdi = &default_backing_dev_info; ++ bdev_inode_switch_bdi(bdev->bd_inode, bdi); ++ } ++ + /* + * If the device is invalidated, rescan partition + * if open succeeded or failed with -ENOMEDIUM. +@@ -1130,14 +1151,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) + rescan_partitions(disk, bdev); + if (ret) + goto out_clear; +- +- if (!bdev->bd_openers) { +- bd_set_size(bdev,(loff_t)get_capacity(disk)<<9); +- bdi = blk_get_backing_dev_info(bdev); +- if (bdi == NULL) +- bdi = &default_backing_dev_info; +- bdev_inode_switch_bdi(bdev->bd_inode, bdi); +- } + } else { + struct block_device *whole; + whole = bdget_disk(disk, 0); +@@ -1237,6 +1250,8 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) + res = __blkdev_get(bdev, mode, 0); + + if (whole) { ++ struct gendisk *disk = whole->bd_disk; ++ + /* finish claiming */ + mutex_lock(&bdev->bd_mutex); + spin_lock(&bdev_lock); +@@ -1263,15 +1278,16 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) + spin_unlock(&bdev_lock); + + /* +- * Block event polling for write claims. Any write +- * holder makes the write_holder state stick until all +- * are released. This is good enough and tracking +- * individual writeable reference is too fragile given +- * the way @mode is used in blkdev_get/put(). ++ * Block event polling for write claims if requested. Any ++ * write holder makes the write_holder state stick until ++ * all are released. This is good enough and tracking ++ * individual writeable reference is too fragile given the ++ * way @mode is used in blkdev_get/put(). + */ +- if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) { ++ if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder && ++ (disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE)) { + bdev->bd_write_holder = true; +- disk_block_events(bdev->bd_disk); ++ disk_block_events(disk); + } + + mutex_unlock(&bdev->bd_mutex); +diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c +index d1a016b..ba3d95b 100644 +--- a/fs/cifs/cifsencrypt.c ++++ b/fs/cifs/cifsencrypt.c +@@ -184,7 +184,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, + if (cifs_pdu == NULL || server == NULL) + return -EINVAL; + +- if (cifs_pdu->Command == SMB_COM_NEGOTIATE) ++ if (!server->session_estab) + return 0; + + if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) { +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 277262a..01db14c 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -199,7 +199,7 @@ cifs_reconnect(struct TCP_Server_Info *server) + } + spin_unlock(&GlobalMid_Lock); + +- while (server->tcpStatus == CifsNeedReconnect) { ++ do { + try_to_freeze(); + + /* we should try only the port we connected to before */ +@@ -214,7 +214,7 @@ cifs_reconnect(struct TCP_Server_Info *server) + server->tcpStatus = CifsNeedNegotiate; + spin_unlock(&GlobalMid_Lock); + } +- } ++ } while (server->tcpStatus == CifsNeedReconnect); + + return rc; + } +@@ -2447,7 +2447,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, + + if (!CIFSSMBQFSUnixInfo(xid, tcon)) { + __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); +- ++ cFYI(1, "unix caps which server supports %lld", cap); + /* check for reconnect case in which we do not + want to change the mount behavior if we can avoid it */ + if (vol_info == NULL) { +@@ -2465,6 +2465,9 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, + } + } + ++ if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP) ++ cERROR(1, "per-share encryption not supported yet"); ++ + cap &= CIFS_UNIX_CAP_MASK; + if (vol_info && vol_info->no_psx_acl) + cap &= ~CIFS_UNIX_POSIX_ACL_CAP; +@@ -2513,6 +2516,10 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, + cFYI(1, "very large read cap"); + if (cap & CIFS_UNIX_LARGE_WRITE_CAP) + cFYI(1, "very large write cap"); ++ if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP) ++ cFYI(1, "transport encryption cap"); ++ if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP) ++ cFYI(1, "mandatory transport encryption cap"); + #endif /* CIFS_DEBUG2 */ + if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { + if (vol_info == NULL) { +@@ -2564,23 +2571,6 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, + else /* default */ + cifs_sb->rsize = CIFSMaxBufSize; + +- if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { +- cERROR(1, "wsize %d too large, using 4096 instead", +- pvolume_info->wsize); +- cifs_sb->wsize = 4096; +- } else if (pvolume_info->wsize) +- cifs_sb->wsize = pvolume_info->wsize; +- else +- cifs_sb->wsize = min_t(const int, +- PAGEVEC_SIZE * PAGE_CACHE_SIZE, +- 127*1024); +- /* old default of CIFSMaxBufSize was too small now +- that SMB Write2 can send multiple pages in kvec. +- RFC1001 does not describe what happens when frame +- bigger than 128K is sent so use that as max in +- conjunction with 52K kvec constraint on arch with 4K +- page size */ +- + if (cifs_sb->rsize < 2048) { + cifs_sb->rsize = 2048; + /* Windows ME may prefer this */ +@@ -2658,6 +2648,48 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, + "mount option supported"); + } + ++/* Prior to 3.0, cifs couldn't handle writes larger than this */ ++#define CIFS_MAX_WSIZE (PAGEVEC_SIZE * PAGE_CACHE_SIZE) ++ ++/* ++ * When the server doesn't allow large posix writes, only allow a wsize of ++ * 128k minus the size of the WRITE_AND_X header. That allows for a write up ++ * to the maximum size described by RFC1002. ++ */ ++#define CIFS_MAX_RFC1002_WSIZE (128 * 1024 - sizeof(WRITE_REQ) + 4) ++ ++/* Make the default the same as the max */ ++#define CIFS_DEFAULT_WSIZE CIFS_MAX_WSIZE ++ ++static unsigned int ++cifs_negotiate_wsize(struct cifsTconInfo *tcon, struct smb_vol *pvolume_info) ++{ ++ __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); ++ struct TCP_Server_Info *server = tcon->ses->server; ++ unsigned int wsize = pvolume_info->wsize ? pvolume_info->wsize : ++ CIFS_DEFAULT_WSIZE; ++ ++ /* can server support 24-bit write sizes? (via UNIX extensions) */ ++ if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) ++ wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1002_WSIZE); ++ ++ /* ++ * no CAP_LARGE_WRITE_X or is signing enabled without CAP_UNIX set? ++ * Limit it to max buffer offered by the server, minus the size of the ++ * WRITEX header, not including the 4 byte RFC1001 length. ++ */ ++ if (!(server->capabilities & CAP_LARGE_WRITE_X) || ++ (!(server->capabilities & CAP_UNIX) && ++ (server->secMode & (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)))) ++ wsize = min_t(unsigned int, wsize, ++ server->maxBuf - sizeof(WRITE_REQ) + 4); ++ ++ /* hard limit of CIFS_MAX_WSIZE */ ++ wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); ++ ++ return wsize; ++} ++ + static int + is_path_accessible(int xid, struct cifsTconInfo *tcon, + struct cifs_sb_info *cifs_sb, const char *full_path) +@@ -2831,20 +2863,26 @@ try_mount_again: + goto remote_path_check; + } + +- /* do not care if following two calls succeed - informational */ +- if (!tcon->ipc) { +- CIFSSMBQFSDeviceInfo(xid, tcon); +- CIFSSMBQFSAttributeInfo(xid, tcon); +- } +- + /* tell server which Unix caps we support */ +- if (tcon->ses->capabilities & CAP_UNIX) ++ if (tcon->ses->capabilities & CAP_UNIX) { + /* reset of caps checks mount to see if unix extensions + disabled for just this mount */ + reset_cifs_unix_caps(xid, tcon, sb, volume_info); +- else ++ if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && ++ (le64_to_cpu(tcon->fsUnixInfo.Capability) & ++ CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) { ++ rc = -EACCES; ++ goto mount_fail_check; ++ } ++ } else + tcon->unix_ext = 0; /* server does not support them */ + ++ /* do not care if following two calls succeed - informational */ ++ if (!tcon->ipc) { ++ CIFSSMBQFSDeviceInfo(xid, tcon); ++ CIFSSMBQFSAttributeInfo(xid, tcon); ++ } ++ + /* convert forward to back slashes in prepath here if needed */ + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) + convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb)); +@@ -2853,13 +2891,12 @@ try_mount_again: + cifs_sb->rsize = 1024 * 127; + cFYI(DBG2, "no very large read support, rsize now 127K"); + } +- if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) +- cifs_sb->wsize = min(cifs_sb->wsize, +- (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); + if (!(tcon->ses->capabilities & CAP_LARGE_READ_X)) + cifs_sb->rsize = min(cifs_sb->rsize, + (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); + ++ cifs_sb->wsize = cifs_negotiate_wsize(tcon, volume_info); ++ + remote_path_check: + /* check if a whole path (including prepath) is not remote */ + if (!rc && tcon) { +@@ -3195,7 +3232,7 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses) + } + if (rc == 0) { + spin_lock(&GlobalMid_Lock); +- if (server->tcpStatus != CifsExiting) ++ if (server->tcpStatus == CifsNeedNegotiate) + server->tcpStatus = CifsGood; + else + rc = -EHOSTDOWN; +diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c +index 297a43d..05268cf 100644 +--- a/fs/cifs/fscache.c ++++ b/fs/cifs/fscache.c +@@ -94,6 +94,7 @@ static void cifs_fscache_disable_inode_cookie(struct inode *inode) + if (cifsi->fscache) { + cFYI(1, "CIFS disabling inode cookie (0x%p)", + cifsi->fscache); ++ fscache_uncache_all_inode_pages(cifsi->fscache, inode); + fscache_relinquish_cookie(cifsi->fscache, 1); + cifsi->fscache = NULL; + } +diff --git a/fs/dcookies.c b/fs/dcookies.c +index a21cabd..dda0dc7 100644 +--- a/fs/dcookies.c ++++ b/fs/dcookies.c +@@ -178,6 +178,8 @@ SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len) + /* FIXME: (deleted) ? */ + path = d_path(&dcs->path, kbuf, PAGE_SIZE); + ++ mutex_unlock(&dcookie_mutex); ++ + if (IS_ERR(path)) { + err = PTR_ERR(path); + goto out_free; +@@ -194,6 +196,7 @@ SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len) + + out_free: + kfree(kbuf); ++ return err; + out: + mutex_unlock(&dcookie_mutex); + return err; +diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c +index 4d4cc6a..94ab3c0 100644 +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -527,6 +527,8 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) + dget(lower_dentry); + rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); + dput(lower_dentry); ++ if (!rc && dentry->d_inode) ++ clear_nlink(dentry->d_inode); + fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); + dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; + unlock_dir(lower_dir_dentry); +diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c +index 03e609c..27a7fef 100644 +--- a/fs/ecryptfs/keystore.c ++++ b/fs/ecryptfs/keystore.c +@@ -599,8 +599,8 @@ struct ecryptfs_write_tag_70_packet_silly_stack { + struct mutex *tfm_mutex; + char *block_aligned_filename; + struct ecryptfs_auth_tok *auth_tok; +- struct scatterlist src_sg; +- struct scatterlist dst_sg; ++ struct scatterlist src_sg[2]; ++ struct scatterlist dst_sg[2]; + struct blkcipher_desc desc; + char iv[ECRYPTFS_MAX_IV_BYTES]; + char hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; +@@ -816,23 +816,21 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, + memcpy(&s->block_aligned_filename[s->num_rand_bytes], filename, + filename_size); + rc = virt_to_scatterlist(s->block_aligned_filename, +- s->block_aligned_filename_size, &s->src_sg, 1); +- if (rc != 1) { ++ s->block_aligned_filename_size, s->src_sg, 2); ++ if (rc < 1) { + printk(KERN_ERR "%s: Internal error whilst attempting to " +- "convert filename memory to scatterlist; " +- "expected rc = 1; got rc = [%d]. " ++ "convert filename memory to scatterlist; rc = [%d]. " + "block_aligned_filename_size = [%zd]\n", __func__, rc, + s->block_aligned_filename_size); + goto out_release_free_unlock; + } + rc = virt_to_scatterlist(&dest[s->i], s->block_aligned_filename_size, +- &s->dst_sg, 1); +- if (rc != 1) { ++ s->dst_sg, 2); ++ if (rc < 1) { + printk(KERN_ERR "%s: Internal error whilst attempting to " + "convert encrypted filename memory to scatterlist; " +- "expected rc = 1; got rc = [%d]. " +- "block_aligned_filename_size = [%zd]\n", __func__, rc, +- s->block_aligned_filename_size); ++ "rc = [%d]. block_aligned_filename_size = [%zd]\n", ++ __func__, rc, s->block_aligned_filename_size); + goto out_release_free_unlock; + } + /* The characters in the first block effectively do the job +@@ -855,7 +853,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, + mount_crypt_stat->global_default_fn_cipher_key_bytes); + goto out_release_free_unlock; + } +- rc = crypto_blkcipher_encrypt_iv(&s->desc, &s->dst_sg, &s->src_sg, ++ rc = crypto_blkcipher_encrypt_iv(&s->desc, s->dst_sg, s->src_sg, + s->block_aligned_filename_size); + if (rc) { + printk(KERN_ERR "%s: Error attempting to encrypt filename; " +@@ -891,8 +889,8 @@ struct ecryptfs_parse_tag_70_packet_silly_stack { + struct mutex *tfm_mutex; + char *decrypted_filename; + struct ecryptfs_auth_tok *auth_tok; +- struct scatterlist src_sg; +- struct scatterlist dst_sg; ++ struct scatterlist src_sg[2]; ++ struct scatterlist dst_sg[2]; + struct blkcipher_desc desc; + char fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1]; + char iv[ECRYPTFS_MAX_IV_BYTES]; +@@ -1008,13 +1006,12 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, + } + mutex_lock(s->tfm_mutex); + rc = virt_to_scatterlist(&data[(*packet_size)], +- s->block_aligned_filename_size, &s->src_sg, 1); +- if (rc != 1) { ++ s->block_aligned_filename_size, s->src_sg, 2); ++ if (rc < 1) { + printk(KERN_ERR "%s: Internal error whilst attempting to " + "convert encrypted filename memory to scatterlist; " +- "expected rc = 1; got rc = [%d]. " +- "block_aligned_filename_size = [%zd]\n", __func__, rc, +- s->block_aligned_filename_size); ++ "rc = [%d]. block_aligned_filename_size = [%zd]\n", ++ __func__, rc, s->block_aligned_filename_size); + goto out_unlock; + } + (*packet_size) += s->block_aligned_filename_size; +@@ -1028,13 +1025,12 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, + goto out_unlock; + } + rc = virt_to_scatterlist(s->decrypted_filename, +- s->block_aligned_filename_size, &s->dst_sg, 1); +- if (rc != 1) { ++ s->block_aligned_filename_size, s->dst_sg, 2); ++ if (rc < 1) { + printk(KERN_ERR "%s: Internal error whilst attempting to " + "convert decrypted filename memory to scatterlist; " +- "expected rc = 1; got rc = [%d]. " +- "block_aligned_filename_size = [%zd]\n", __func__, rc, +- s->block_aligned_filename_size); ++ "rc = [%d]. block_aligned_filename_size = [%zd]\n", ++ __func__, rc, s->block_aligned_filename_size); + goto out_free_unlock; + } + /* The characters in the first block effectively do the job of +@@ -1065,7 +1061,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, + mount_crypt_stat->global_default_fn_cipher_key_bytes); + goto out_free_unlock; + } +- rc = crypto_blkcipher_decrypt_iv(&s->desc, &s->dst_sg, &s->src_sg, ++ rc = crypto_blkcipher_decrypt_iv(&s->desc, s->dst_sg, s->src_sg, + s->block_aligned_filename_size); + if (rc) { + printk(KERN_ERR "%s: Error attempting to decrypt filename; " +diff --git a/fs/exec.c b/fs/exec.c +index 5e62d26..0c3682d 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1046,6 +1046,7 @@ int flush_old_exec(struct linux_binprm * bprm) + + bprm->mm = NULL; /* We're using it now */ + ++ set_fs(USER_DS); + current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD); + flush_thread(); + current->personality &= ~bprm->per_clear; +@@ -1310,10 +1311,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) + if (retval) + return retval; + +- /* kernel module loader fixup */ +- /* so we don't try to load run modprobe in kernel space. */ +- set_fs(USER_DS); +- + retval = audit_bprm(bprm); + if (retval) + return retval; +diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c +index 32f3b86..93f9fd0 100644 +--- a/fs/ext3/namei.c ++++ b/fs/ext3/namei.c +@@ -1416,10 +1416,19 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, + frame->at = entries; + frame->bh = bh; + bh = bh2; ++ /* ++ * Mark buffers dirty here so that if do_split() fails we write a ++ * consistent set of buffers to disk. ++ */ ++ ext3_journal_dirty_metadata(handle, frame->bh); ++ ext3_journal_dirty_metadata(handle, bh); + de = do_split(handle,dir, &bh, frame, &hinfo, &retval); +- dx_release (frames); +- if (!(de)) ++ if (!de) { ++ ext3_mark_inode_dirty(handle, dir); ++ dx_release(frames); + return retval; ++ } ++ dx_release(frames); + + return add_dirent_to_buf(handle, dentry, inode, de, bh); + } +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index 4daaf2b..1e37c09 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1590,12 +1590,8 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr, + */ + struct ext4_lazy_init { + unsigned long li_state; +- +- wait_queue_head_t li_wait_daemon; + wait_queue_head_t li_wait_task; +- struct timer_list li_timer; + struct task_struct *li_task; +- + struct list_head li_request_list; + struct mutex li_list_mtx; + }; +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index d8a16ee..15bfa44 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -1273,6 +1273,8 @@ repeat_load_buddy: + return 0; + + err: ++ if (page) ++ page_cache_release(page); + if (e4b->bd_bitmap_page) + page_cache_release(e4b->bd_bitmap_page); + if (e4b->bd_buddy_page) +diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c +index b6dbd05..7bb8f76 100644 +--- a/fs/ext4/page-io.c ++++ b/fs/ext4/page-io.c +@@ -203,46 +203,29 @@ static void ext4_end_bio(struct bio *bio, int error) + for (i = 0; i < io_end->num_io_pages; i++) { + struct page *page = io_end->pages[i]->p_page; + struct buffer_head *bh, *head; +- int partial_write = 0; ++ loff_t offset; ++ loff_t io_end_offset; + +- head = page_buffers(page); +- if (error) ++ if (error) { + SetPageError(page); +- BUG_ON(!head); +- if (head->b_size != PAGE_CACHE_SIZE) { +- loff_t offset; +- loff_t io_end_offset = io_end->offset + io_end->size; ++ set_bit(AS_EIO, &page->mapping->flags); ++ head = page_buffers(page); ++ BUG_ON(!head); ++ ++ io_end_offset = io_end->offset + io_end->size; + + offset = (sector_t) page->index << PAGE_CACHE_SHIFT; + bh = head; + do { + if ((offset >= io_end->offset) && +- (offset+bh->b_size <= io_end_offset)) { +- if (error) +- buffer_io_error(bh); +- +- } +- if (buffer_delay(bh)) +- partial_write = 1; +- else if (!buffer_mapped(bh)) +- clear_buffer_dirty(bh); +- else if (buffer_dirty(bh)) +- partial_write = 1; ++ (offset+bh->b_size <= io_end_offset)) ++ buffer_io_error(bh); ++ + offset += bh->b_size; + bh = bh->b_this_page; + } while (bh != head); + } + +- /* +- * If this is a partial write which happened to make +- * all buffers uptodate then we can optimize away a +- * bogus readpage() for the next read(). Here we +- * 'discover' whether the page went uptodate as a +- * result of this (potentially partial) write. +- */ +- if (!partial_write) +- SetPageUptodate(page); +- + put_io_page(io_end->pages[i]); + } + io_end->num_io_pages = 0; +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 8553dfb..e6ea384 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2659,12 +2659,6 @@ static void print_daily_error_info(unsigned long arg) + mod_timer(&sbi->s_err_report, jiffies + 24*60*60*HZ); /* Once a day */ + } + +-static void ext4_lazyinode_timeout(unsigned long data) +-{ +- struct task_struct *p = (struct task_struct *)data; +- wake_up_process(p); +-} +- + /* Find next suitable group and run ext4_init_inode_table */ + static int ext4_run_li_request(struct ext4_li_request *elr) + { +@@ -2712,7 +2706,7 @@ static int ext4_run_li_request(struct ext4_li_request *elr) + + /* + * Remove lr_request from the list_request and free the +- * request tructure. Should be called with li_list_mtx held ++ * request structure. Should be called with li_list_mtx held + */ + static void ext4_remove_li_request(struct ext4_li_request *elr) + { +@@ -2730,14 +2724,16 @@ static void ext4_remove_li_request(struct ext4_li_request *elr) + + static void ext4_unregister_li_request(struct super_block *sb) + { +- struct ext4_li_request *elr = EXT4_SB(sb)->s_li_request; +- +- if (!ext4_li_info) ++ mutex_lock(&ext4_li_mtx); ++ if (!ext4_li_info) { ++ mutex_unlock(&ext4_li_mtx); + return; ++ } + + mutex_lock(&ext4_li_info->li_list_mtx); +- ext4_remove_li_request(elr); ++ ext4_remove_li_request(EXT4_SB(sb)->s_li_request); + mutex_unlock(&ext4_li_info->li_list_mtx); ++ mutex_unlock(&ext4_li_mtx); + } + + static struct task_struct *ext4_lazyinit_task; +@@ -2756,14 +2752,10 @@ static int ext4_lazyinit_thread(void *arg) + struct ext4_lazy_init *eli = (struct ext4_lazy_init *)arg; + struct list_head *pos, *n; + struct ext4_li_request *elr; +- unsigned long next_wakeup; +- DEFINE_WAIT(wait); ++ unsigned long next_wakeup, cur; + + BUG_ON(NULL == eli); + +- eli->li_timer.data = (unsigned long)current; +- eli->li_timer.function = ext4_lazyinode_timeout; +- + eli->li_task = current; + wake_up(&eli->li_wait_task); + +@@ -2797,19 +2789,15 @@ cont_thread: + if (freezing(current)) + refrigerator(); + +- if ((time_after_eq(jiffies, next_wakeup)) || ++ cur = jiffies; ++ if ((time_after_eq(cur, next_wakeup)) || + (MAX_JIFFY_OFFSET == next_wakeup)) { + cond_resched(); + continue; + } + +- eli->li_timer.expires = next_wakeup; +- add_timer(&eli->li_timer); +- prepare_to_wait(&eli->li_wait_daemon, &wait, +- TASK_INTERRUPTIBLE); +- if (time_before(jiffies, next_wakeup)) +- schedule(); +- finish_wait(&eli->li_wait_daemon, &wait); ++ schedule_timeout_interruptible(next_wakeup - cur); ++ + if (kthread_should_stop()) { + ext4_clear_request_list(); + goto exit_thread; +@@ -2833,12 +2821,10 @@ exit_thread: + goto cont_thread; + } + mutex_unlock(&eli->li_list_mtx); +- del_timer_sync(&ext4_li_info->li_timer); + eli->li_task = NULL; + wake_up(&eli->li_wait_task); + + kfree(ext4_li_info); +- ext4_lazyinit_task = NULL; + ext4_li_info = NULL; + mutex_unlock(&ext4_li_mtx); + +@@ -2866,7 +2852,6 @@ static int ext4_run_lazyinit_thread(void) + if (IS_ERR(ext4_lazyinit_task)) { + int err = PTR_ERR(ext4_lazyinit_task); + ext4_clear_request_list(); +- del_timer_sync(&ext4_li_info->li_timer); + kfree(ext4_li_info); + ext4_li_info = NULL; + printk(KERN_CRIT "EXT4: error %d creating inode table " +@@ -2915,9 +2900,7 @@ static int ext4_li_info_new(void) + INIT_LIST_HEAD(&eli->li_request_list); + mutex_init(&eli->li_list_mtx); + +- init_waitqueue_head(&eli->li_wait_daemon); + init_waitqueue_head(&eli->li_wait_task); +- init_timer(&eli->li_timer); + eli->li_state |= EXT4_LAZYINIT_QUIT; + + ext4_li_info = eli; +@@ -4652,6 +4635,9 @@ static int ext4_quota_off(struct super_block *sb, int type) + if (test_opt(sb, DELALLOC)) + sync_filesystem(sb); + ++ if (!inode) ++ goto out; ++ + /* Update modification times of quota files when userspace can + * start looking at them */ + handle = ext4_journal_start(inode, 1); +diff --git a/fs/fat/file.c b/fs/fat/file.c +index 7257752..7018e1d 100644 +--- a/fs/fat/file.c ++++ b/fs/fat/file.c +@@ -102,7 +102,7 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) + if (attr & ATTR_SYS) + inode->i_flags |= S_IMMUTABLE; + else +- inode->i_flags &= S_IMMUTABLE; ++ inode->i_flags &= ~S_IMMUTABLE; + } + + fat_save_attrs(inode, attr); +diff --git a/fs/fscache/page.c b/fs/fscache/page.c +index 41c441c..fd03b0e 100644 +--- a/fs/fscache/page.c ++++ b/fs/fscache/page.c +@@ -967,3 +967,43 @@ void fscache_mark_pages_cached(struct fscache_retrieval *op, + pagevec_reinit(pagevec); + } + EXPORT_SYMBOL(fscache_mark_pages_cached); ++ ++/* ++ * Uncache all the pages in an inode that are marked PG_fscache, assuming them ++ * to be associated with the given cookie. ++ */ ++void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, ++ struct inode *inode) ++{ ++ struct address_space *mapping = inode->i_mapping; ++ struct pagevec pvec; ++ pgoff_t next; ++ int i; ++ ++ _enter("%p,%p", cookie, inode); ++ ++ if (!mapping || mapping->nrpages == 0) { ++ _leave(" [no pages]"); ++ return; ++ } ++ ++ pagevec_init(&pvec, 0); ++ next = 0; ++ do { ++ if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) ++ break; ++ for (i = 0; i < pagevec_count(&pvec); i++) { ++ struct page *page = pvec.pages[i]; ++ next = page->index; ++ if (PageFsCache(page)) { ++ __fscache_wait_on_page_write(cookie, page); ++ __fscache_uncache_page(cookie, page); ++ } ++ } ++ pagevec_release(&pvec); ++ cond_resched(); ++ } while (++next); ++ ++ _leave(""); ++} ++EXPORT_SYMBOL(__fscache_uncache_all_inode_pages); +diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c +index e483108..418728f 100644 +--- a/fs/gfs2/file.c ++++ b/fs/gfs2/file.c +@@ -826,6 +826,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, + loff_t bytes, max_bytes; + struct gfs2_alloc *al; + int error; ++ loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1); + loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift; + next = (next + 1) << sdp->sd_sb.sb_bsize_shift; + +@@ -833,13 +834,15 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, + if (mode & ~FALLOC_FL_KEEP_SIZE) + return -EOPNOTSUPP; + +- offset = (offset >> sdp->sd_sb.sb_bsize_shift) << +- sdp->sd_sb.sb_bsize_shift; ++ offset &= bsize_mask; + + len = next - offset; + bytes = sdp->sd_max_rg_data * sdp->sd_sb.sb_bsize / 2; + if (!bytes) + bytes = UINT_MAX; ++ bytes &= bsize_mask; ++ if (bytes == 0) ++ bytes = sdp->sd_sb.sb_bsize; + + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); + error = gfs2_glock_nq(&ip->i_gh); +@@ -870,6 +873,9 @@ retry: + if (error) { + if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) { + bytes >>= 1; ++ bytes &= bsize_mask; ++ if (bytes == 0) ++ bytes = sdp->sd_sb.sb_bsize; + goto retry; + } + goto out_qunlock; +diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c +index 3031d81..4ac88ff 100644 +--- a/fs/hfsplus/wrapper.c ++++ b/fs/hfsplus/wrapper.c +@@ -36,6 +36,7 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector, + { + DECLARE_COMPLETION_ONSTACK(wait); + struct bio *bio; ++ int ret = 0; + + bio = bio_alloc(GFP_NOIO, 1); + bio->bi_sector = sector; +@@ -54,8 +55,10 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector, + wait_for_completion(&wait); + + if (!bio_flagged(bio, BIO_UPTODATE)) +- return -EIO; +- return 0; ++ ret = -EIO; ++ ++ bio_put(bio); ++ return ret; + } + + static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd) +diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c +index 69b1804..f486ff6 100644 +--- a/fs/jbd/commit.c ++++ b/fs/jbd/commit.c +@@ -722,8 +722,13 @@ wait_for_iobuf: + required. */ + JBUFFER_TRACE(jh, "file as BJ_Forget"); + journal_file_buffer(jh, commit_transaction, BJ_Forget); +- /* Wake up any transactions which were waiting for this +- IO to complete */ ++ /* ++ * Wake up any transactions which were waiting for this ++ * IO to complete. The barrier must be here so that changes ++ * by journal_file_buffer() take effect before wake_up_bit() ++ * does the waitqueue check. ++ */ ++ smp_mb(); + wake_up_bit(&bh->b_state, BH_Unshadow); + JBUFFER_TRACE(jh, "brelse shadowed buffer"); + __brelse(bh); +diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c +index b3713af..e2d4285 100644 +--- a/fs/jbd/journal.c ++++ b/fs/jbd/journal.c +@@ -437,9 +437,12 @@ int __log_space_left(journal_t *journal) + int __log_start_commit(journal_t *journal, tid_t target) + { + /* +- * Are we already doing a recent enough commit? ++ * The only transaction we can possibly wait upon is the ++ * currently running transaction (if it exists). Otherwise, ++ * the target tid must be an old one. + */ +- if (!tid_geq(journal->j_commit_request, target)) { ++ if (journal->j_running_transaction && ++ journal->j_running_transaction->t_tid == target) { + /* + * We want a new commit: OK, mark the request and wakeup the + * commit thread. We do _not_ do the commit ourselves. +@@ -451,7 +454,14 @@ int __log_start_commit(journal_t *journal, tid_t target) + journal->j_commit_sequence); + wake_up(&journal->j_wait_commit); + return 1; +- } ++ } else if (!tid_geq(journal->j_commit_request, target)) ++ /* This should never happen, but if it does, preserve ++ the evidence before kjournald goes into a loop and ++ increments j_commit_sequence beyond all recognition. */ ++ WARN_ONCE(1, "jbd: bad log_start_commit: %u %u %u %u\n", ++ journal->j_commit_request, journal->j_commit_sequence, ++ target, journal->j_running_transaction ? ++ journal->j_running_transaction->t_tid : 0); + return 0; + } + +diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c +index adb45ec..e374050 100644 +--- a/fs/lockd/clntproc.c ++++ b/fs/lockd/clntproc.c +@@ -708,7 +708,13 @@ static void nlmclnt_unlock_callback(struct rpc_task *task, void *data) + + if (task->tk_status < 0) { + dprintk("lockd: unlock failed (err = %d)\n", -task->tk_status); +- goto retry_rebind; ++ switch (task->tk_status) { ++ case -EACCES: ++ case -EIO: ++ goto die; ++ default: ++ goto retry_rebind; ++ } + } + if (status == NLM_LCK_DENIED_GRACE_PERIOD) { + rpc_delay(task, NLMCLNT_GRACE_WAIT); +diff --git a/fs/locks.c b/fs/locks.c +index 0a4f50d..b286539 100644 +--- a/fs/locks.c ++++ b/fs/locks.c +@@ -160,10 +160,28 @@ EXPORT_SYMBOL_GPL(unlock_flocks); + + static struct kmem_cache *filelock_cache __read_mostly; + ++static void locks_init_lock_always(struct file_lock *fl) ++{ ++ fl->fl_next = NULL; ++ fl->fl_fasync = NULL; ++ fl->fl_owner = NULL; ++ fl->fl_pid = 0; ++ fl->fl_nspid = NULL; ++ fl->fl_file = NULL; ++ fl->fl_flags = 0; ++ fl->fl_type = 0; ++ fl->fl_start = fl->fl_end = 0; ++} ++ + /* Allocate an empty lock structure. */ + struct file_lock *locks_alloc_lock(void) + { +- return kmem_cache_alloc(filelock_cache, GFP_KERNEL); ++ struct file_lock *fl = kmem_cache_alloc(filelock_cache, GFP_KERNEL); ++ ++ if (fl) ++ locks_init_lock_always(fl); ++ ++ return fl; + } + EXPORT_SYMBOL_GPL(locks_alloc_lock); + +@@ -200,17 +218,9 @@ void locks_init_lock(struct file_lock *fl) + INIT_LIST_HEAD(&fl->fl_link); + INIT_LIST_HEAD(&fl->fl_block); + init_waitqueue_head(&fl->fl_wait); +- fl->fl_next = NULL; +- fl->fl_fasync = NULL; +- fl->fl_owner = NULL; +- fl->fl_pid = 0; +- fl->fl_nspid = NULL; +- fl->fl_file = NULL; +- fl->fl_flags = 0; +- fl->fl_type = 0; +- fl->fl_start = fl->fl_end = 0; + fl->fl_ops = NULL; + fl->fl_lmops = NULL; ++ locks_init_lock_always(fl); + } + + EXPORT_SYMBOL(locks_init_lock); +diff --git a/fs/namei.c b/fs/namei.c +index e3c4f11..732a754 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -1013,7 +1013,6 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, + * Don't forget we might have a non-mountpoint managed dentry + * that wants to block transit. + */ +- *inode = path->dentry->d_inode; + if (!reverse_transit && + unlikely(managed_dentry_might_block(path->dentry))) + return false; +@@ -1027,6 +1026,12 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, + path->mnt = mounted; + path->dentry = mounted->mnt_root; + nd->seq = read_seqcount_begin(&path->dentry->d_seq); ++ /* ++ * Update the inode too. We don't need to re-check the ++ * dentry sequence number here after this d_inode read, ++ * because a mount-point is always pinned. ++ */ ++ *inode = path->dentry->d_inode; + } + + if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT)) +@@ -1378,12 +1383,12 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd) + { + int res; + +- BUG_ON(nd->depth >= MAX_NESTED_LINKS); + if (unlikely(current->link_count >= MAX_NESTED_LINKS)) { + path_put_conditional(path, nd); + path_put(&nd->path); + return -ELOOP; + } ++ BUG_ON(nd->depth >= MAX_NESTED_LINKS); + + nd->depth++; + current->link_count++; +diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c +index ce153a6..419119c 100644 +--- a/fs/nfs/fscache.c ++++ b/fs/nfs/fscache.c +@@ -259,12 +259,10 @@ static void nfs_fscache_disable_inode_cookie(struct inode *inode) + dfprintk(FSCACHE, + "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode)); + +- /* Need to invalidate any mapped pages that were read in before +- * turning off the cache. ++ /* Need to uncache any pages attached to this inode that ++ * fscache knows about before turning off the cache. + */ +- if (inode->i_mapping && inode->i_mapping->nrpages) +- invalidate_inode_pages2(inode->i_mapping); +- ++ fscache_uncache_all_inode_pages(NFS_I(inode)->fscache, inode); + nfs_fscache_zap_inode_cookie(inode); + } + } +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 57bb31a..19877db 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -256,7 +256,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) + + nfs_attr_check_mountpoint(sb, fattr); + +- if ((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0 && (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) ++ if (((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0) && ++ !nfs_attr_use_mounted_on_fileid(fattr)) + goto out_no_inode; + if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0) + goto out_no_inode; +@@ -1294,7 +1295,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) + if (new_isize != cur_isize) { + /* Do we perhaps have any outstanding writes, or has + * the file grown beyond our last write? */ +- if (nfsi->npages == 0 || new_isize > cur_isize) { ++ if ((nfsi->npages == 0 && !test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) || ++ new_isize > cur_isize) { + i_size_write(inode, new_isize); + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; + } +diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h +index ce118ce..d10eb7e 100644 +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -45,6 +45,17 @@ static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct + fattr->valid |= NFS_ATTR_FATTR_MOUNTPOINT; + } + ++static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr) ++{ ++ if (((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) == 0) || ++ (((fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) && ++ ((fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) == 0))) ++ return 0; ++ ++ fattr->fileid = fattr->mounted_on_fileid; ++ return 1; ++} ++ + struct nfs_clone_mount { + const struct super_block *sb; + const struct dentry *dentry; +diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c +index be79dc9..590c09c 100644 +--- a/fs/nfs/nfs4filelayout.c ++++ b/fs/nfs/nfs4filelayout.c +@@ -554,13 +554,18 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, + __func__, nfl_util, fl->num_fh, fl->first_stripe_index, + fl->pattern_offset); + +- if (!fl->num_fh) ++ /* Note that a zero value for num_fh is legal for STRIPE_SPARSE. ++ * Futher checking is done in filelayout_check_layout */ ++ if (fl->num_fh < 0 || fl->num_fh > ++ max(NFS4_PNFS_MAX_STRIPE_CNT, NFS4_PNFS_MAX_MULTI_CNT)) + goto out_err; + +- fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), +- gfp_flags); +- if (!fl->fh_array) +- goto out_err; ++ if (fl->num_fh > 0) { ++ fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), ++ gfp_flags); ++ if (!fl->fh_array) ++ goto out_err; ++ } + + for (i = 0; i < fl->num_fh; i++) { + /* Do we want to use a mempool here? */ +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index cf1b339..d348326 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -267,9 +267,11 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc + break; + nfs4_schedule_stateid_recovery(server, state); + goto wait_on_recovery; ++ case -NFS4ERR_EXPIRED: ++ if (state != NULL) ++ nfs4_schedule_stateid_recovery(server, state); + case -NFS4ERR_STALE_STATEID: + case -NFS4ERR_STALE_CLIENTID: +- case -NFS4ERR_EXPIRED: + nfs4_schedule_lease_recovery(clp); + goto wait_on_recovery; + #if defined(CONFIG_NFS_V4_1) +@@ -2263,12 +2265,14 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, + return nfs4_map_errors(status); + } + ++static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); + /* + * Get locations and (maybe) other attributes of a referral. + * Note that we'll actually follow the referral later when + * we detect fsid mismatch in inode revalidation + */ +-static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct nfs_fattr *fattr, struct nfs_fh *fhandle) ++static int nfs4_get_referral(struct inode *dir, const struct qstr *name, ++ struct nfs_fattr *fattr, struct nfs_fh *fhandle) + { + int status = -ENOMEM; + struct page *page = NULL; +@@ -2286,15 +2290,16 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name, struct + goto out; + /* Make sure server returned a different fsid for the referral */ + if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) { +- dprintk("%s: server did not return a different fsid for a referral at %s\n", __func__, name->name); ++ dprintk("%s: server did not return a different fsid for" ++ " a referral at %s\n", __func__, name->name); + status = -EIO; + goto out; + } ++ /* Fixup attributes for the nfs_lookup() call to nfs_fhget() */ ++ nfs_fixup_referral_attributes(&locations->fattr); + ++ /* replace the lookup nfs_fattr with the locations nfs_fattr */ + memcpy(fattr, &locations->fattr, sizeof(struct nfs_fattr)); +- fattr->valid |= NFS_ATTR_FATTR_V4_REFERRAL; +- if (!fattr->mode) +- fattr->mode = S_IFDIR; + memset(fhandle, 0, sizeof(struct nfs_fh)); + out: + if (page) +@@ -3670,9 +3675,11 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, + break; + nfs4_schedule_stateid_recovery(server, state); + goto wait_on_recovery; ++ case -NFS4ERR_EXPIRED: ++ if (state != NULL) ++ nfs4_schedule_stateid_recovery(server, state); + case -NFS4ERR_STALE_STATEID: + case -NFS4ERR_STALE_CLIENTID: +- case -NFS4ERR_EXPIRED: + nfs4_schedule_lease_recovery(clp); + goto wait_on_recovery; + #if defined(CONFIG_NFS_V4_1) +@@ -4543,6 +4550,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) + case -ESTALE: + goto out; + case -NFS4ERR_EXPIRED: ++ nfs4_schedule_stateid_recovery(server, state); + case -NFS4ERR_STALE_CLIENTID: + case -NFS4ERR_STALE_STATEID: + nfs4_schedule_lease_recovery(server->nfs_client); +@@ -4652,11 +4660,15 @@ static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list, + return len; + } + ++/* ++ * nfs_fhget will use either the mounted_on_fileid or the fileid ++ */ + static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr) + { +- if (!((fattr->valid & NFS_ATTR_FATTR_FILEID) && +- (fattr->valid & NFS_ATTR_FATTR_FSID) && +- (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL))) ++ if (!(((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) || ++ (fattr->valid & NFS_ATTR_FATTR_FILEID)) && ++ (fattr->valid & NFS_ATTR_FATTR_FSID) && ++ (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL))) + return; + + fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE | +@@ -4671,7 +4683,6 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, + struct nfs_server *server = NFS_SERVER(dir); + u32 bitmask[2] = { + [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, +- [1] = FATTR4_WORD1_MOUNTED_ON_FILEID, + }; + struct nfs4_fs_locations_arg args = { + .dir_fh = NFS_FH(dir), +@@ -4690,11 +4701,18 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, + int status; + + dprintk("%s: start\n", __func__); ++ ++ /* Ask for the fileid of the absent filesystem if mounted_on_fileid ++ * is not supported */ ++ if (NFS_SERVER(dir)->attr_bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) ++ bitmask[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID; ++ else ++ bitmask[0] |= FATTR4_WORD0_FILEID; ++ + nfs_fattr_init(&fs_locations->fattr); + fs_locations->server = server; + fs_locations->nlocations = 0; + status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); +- nfs_fixup_referral_attributes(&fs_locations->fattr); + dprintk("%s: returned status = %d\n", __func__, status); + return status; + } +diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c +index 036f5ad..e97dd21 100644 +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -1466,7 +1466,10 @@ static int nfs4_reclaim_lease(struct nfs_client *clp) + #ifdef CONFIG_NFS_V4_1 + void nfs4_schedule_session_recovery(struct nfs4_session *session) + { +- nfs4_schedule_lease_recovery(session->clp); ++ struct nfs_client *clp = session->clp; ++ ++ set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); ++ nfs4_schedule_lease_recovery(clp); + } + EXPORT_SYMBOL_GPL(nfs4_schedule_session_recovery); + +@@ -1549,6 +1552,7 @@ static int nfs4_reset_session(struct nfs_client *clp) + status = nfs4_recovery_handle_error(clp, status); + goto out; + } ++ clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); + /* create_session negotiated new slot table */ + clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); + +diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c +index c3ccd2c..a58bd56 100644 +--- a/fs/nfs/nfs4xdr.c ++++ b/fs/nfs/nfs4xdr.c +@@ -91,7 +91,7 @@ static int nfs4_stat_to_errno(int); + #define encode_getfh_maxsz (op_encode_hdr_maxsz) + #define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \ + ((3+NFS4_FHSIZE) >> 2)) +-#define nfs4_fattr_bitmap_maxsz 3 ++#define nfs4_fattr_bitmap_maxsz 4 + #define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz) + #define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2)) + #define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) +@@ -3030,7 +3030,7 @@ out_overflow: + return -EIO; + } + +-static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap) ++static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res) + { + __be32 *p; + +@@ -3041,7 +3041,7 @@ static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap) + if (unlikely(!p)) + goto out_overflow; + bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR; +- return -be32_to_cpup(p); ++ *res = -be32_to_cpup(p); + } + return 0; + out_overflow: +@@ -4002,6 +4002,7 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, + int status; + umode_t fmode = 0; + uint32_t type; ++ int32_t err; + + status = decode_attr_type(xdr, bitmap, &type); + if (status < 0) +@@ -4027,13 +4028,12 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, + goto xdr_error; + fattr->valid |= status; + +- status = decode_attr_error(xdr, bitmap); +- if (status == -NFS4ERR_WRONGSEC) { +- nfs_fixup_secinfo_attributes(fattr, fh); +- status = 0; +- } ++ err = 0; ++ status = decode_attr_error(xdr, bitmap, &err); + if (status < 0) + goto xdr_error; ++ if (err == -NFS4ERR_WRONGSEC) ++ nfs_fixup_secinfo_attributes(fattr, fh); + + status = decode_attr_filehandle(xdr, bitmap, fh); + if (status < 0) +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index f57f528..101c85a 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -1009,7 +1009,7 @@ void + pnfs_set_layoutcommit(struct nfs_write_data *wdata) + { + struct nfs_inode *nfsi = NFS_I(wdata->inode); +- loff_t end_pos = wdata->args.offset + wdata->res.count; ++ loff_t end_pos = wdata->mds_offset + wdata->res.count; + bool mark_as_dirty = false; + + spin_lock(&nfsi->vfs_inode.i_lock); +diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig +index 18b3e89..fbb2a5e 100644 +--- a/fs/nfsd/Kconfig ++++ b/fs/nfsd/Kconfig +@@ -82,6 +82,7 @@ config NFSD_V4 + select NFSD_V3 + select FS_POSIX_ACL + select SUNRPC_GSS ++ select CRYPTO + help + This option enables support in your system's NFS server for + version 4 of the NFS protocol (RFC 3530). +diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c +index 1f5eae4..2b1449d 100644 +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -13,6 +13,7 @@ + #include <linux/lockd/lockd.h> + #include <linux/sunrpc/clnt.h> + #include <linux/sunrpc/gss_api.h> ++#include <linux/sunrpc/gss_krb5_enctypes.h> + + #include "idmap.h" + #include "nfsd.h" +@@ -189,18 +190,10 @@ static struct file_operations export_features_operations = { + .release = single_release, + }; + +-#ifdef CONFIG_SUNRPC_GSS ++#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE) + static int supported_enctypes_show(struct seq_file *m, void *v) + { +- struct gss_api_mech *k5mech; +- +- k5mech = gss_mech_get_by_name("krb5"); +- if (k5mech == NULL) +- goto out; +- if (k5mech->gm_upcall_enctypes != NULL) +- seq_printf(m, k5mech->gm_upcall_enctypes); +- gss_mech_put(k5mech); +-out: ++ seq_printf(m, KRB5_SUPPORTED_ENCTYPES); + return 0; + } + +@@ -215,7 +208,7 @@ static struct file_operations supported_enctypes_ops = { + .llseek = seq_lseek, + .release = single_release, + }; +-#endif /* CONFIG_SUNRPC_GSS */ ++#endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */ + + extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); + extern int nfsd_pool_stats_release(struct inode *inode, struct file *file); +@@ -1427,9 +1420,9 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) + [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, + [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, + [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, +-#ifdef CONFIG_SUNRPC_GSS ++#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE) + [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO}, +-#endif /* CONFIG_SUNRPC_GSS */ ++#endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */ + #ifdef CONFIG_NFSD_V4 + [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, + [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR}, +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index 129f3c9..d80b2d8 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -699,7 +699,15 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor + } + #endif /* CONFIG_NFSD_V3 */ + ++static int nfsd_open_break_lease(struct inode *inode, int access) ++{ ++ unsigned int mode; + ++ if (access & NFSD_MAY_NOT_BREAK_LEASE) ++ return 0; ++ mode = (access & NFSD_MAY_WRITE) ? O_WRONLY : O_RDONLY; ++ return break_lease(inode, mode | O_NONBLOCK); ++} + + /* + * Open an existing file or directory. +@@ -747,12 +755,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, + if (!inode->i_fop) + goto out; + +- /* +- * Check to see if there are any leases on this file. +- * This may block while leases are broken. +- */ +- if (!(access & NFSD_MAY_NOT_BREAK_LEASE)) +- host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0)); ++ host_err = nfsd_open_break_lease(inode, access); + if (host_err) /* NOMEM or WOULDBLOCK */ + goto out_nfserr; + +@@ -1653,8 +1656,10 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, + if (!dold->d_inode) + goto out_drop_write; + host_err = nfsd_break_lease(dold->d_inode); +- if (host_err) ++ if (host_err) { ++ err = nfserrno(host_err); + goto out_drop_write; ++ } + host_err = vfs_link(dold, dirp, dnew); + if (!host_err) { + err = nfserrno(commit_metadata(ffhp)); +diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c +index 19d6750..6296b40 100644 +--- a/fs/partitions/efi.c ++++ b/fs/partitions/efi.c +@@ -310,6 +310,15 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba, + goto fail; + } + ++ /* Check the GUID Partition Table header size */ ++ if (le32_to_cpu((*gpt)->header_size) > ++ bdev_logical_block_size(state->bdev)) { ++ pr_debug("GUID Partition Table Header size is wrong: %u > %u\n", ++ le32_to_cpu((*gpt)->header_size), ++ bdev_logical_block_size(state->bdev)); ++ goto fail; ++ } ++ + /* Check the GUID Partition Table CRC */ + origcrc = le32_to_cpu((*gpt)->header_crc32); + (*gpt)->header_crc32 = 0; +diff --git a/fs/partitions/ldm.c b/fs/partitions/ldm.c +index ce4f624..a29d5cc 100644 +--- a/fs/partitions/ldm.c ++++ b/fs/partitions/ldm.c +@@ -1335,6 +1335,11 @@ static bool ldm_frag_add (const u8 *data, int size, struct list_head *frags) + + list_add_tail (&f->list, frags); + found: ++ if (rec >= f->num) { ++ ldm_error("REC value (%d) exceeds NUM value (%d)", rec, f->num); ++ return false; ++ } ++ + if (f->map & (1 << rec)) { + ldm_error ("Duplicate VBLK, part %d.", rec); + f->map &= 0x7F; /* Mark the group as broken */ +diff --git a/fs/proc/base.c b/fs/proc/base.c +index dfa5327..0352336 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -2762,6 +2762,9 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) + struct task_io_accounting acct = task->ioac; + unsigned long flags; + ++ if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ return -EACCES; ++ + if (whole && lock_task_sighand(task, &flags)) { + struct task_struct *t = task; + +@@ -2892,7 +2895,7 @@ static const struct pid_entry tgid_base_stuff[] = { + REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations), + #endif + #ifdef CONFIG_TASK_IO_ACCOUNTING +- INF("io", S_IRUGO, proc_tgid_io_accounting), ++ INF("io", S_IRUSR, proc_tgid_io_accounting), + #endif + }; + +@@ -3230,7 +3233,7 @@ static const struct pid_entry tid_base_stuff[] = { + REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations), + #endif + #ifdef CONFIG_TASK_IO_ACCOUNTING +- INF("io", S_IRUGO, proc_tid_io_accounting), ++ INF("io", S_IRUSR, proc_tid_io_accounting), + #endif + }; + +diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c +index aed25e8..e5cb2ce 100644 +--- a/fs/ubifs/journal.c ++++ b/fs/ubifs/journal.c +@@ -666,6 +666,7 @@ out_free: + + out_release: + release_head(c, BASEHD); ++ kfree(dent); + out_ro: + ubifs_ro_mode(c, err); + if (last_reference) +diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c +index bf31b47..cad60b5 100644 +--- a/fs/ubifs/sb.c ++++ b/fs/ubifs/sb.c +@@ -475,7 +475,8 @@ failed: + * @c: UBIFS file-system description object + * + * This function returns a pointer to the superblock node or a negative error +- * code. ++ * code. Note, the user of this function is responsible of kfree()'ing the ++ * returned superblock buffer. + */ + struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c) + { +diff --git a/fs/ubifs/shrinker.c b/fs/ubifs/shrinker.c +index 46961c0..d8f5d0f 100644 +--- a/fs/ubifs/shrinker.c ++++ b/fs/ubifs/shrinker.c +@@ -283,7 +283,11 @@ int ubifs_shrinker(struct shrinker *shrink, int nr, gfp_t gfp_mask) + long clean_zn_cnt = atomic_long_read(&ubifs_clean_zn_cnt); + + if (nr == 0) +- return clean_zn_cnt; ++ /* ++ * Due to the way UBIFS updates the clean znode counter it may ++ * temporarily be negative. ++ */ ++ return clean_zn_cnt >= 0 ? clean_zn_cnt : 1; + + if (!clean_zn_cnt) { + /* +diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c +index 04ad07f..328e6fc 100644 +--- a/fs/ubifs/super.c ++++ b/fs/ubifs/super.c +@@ -1584,6 +1584,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) + } + sup->leb_cnt = cpu_to_le32(c->leb_cnt); + err = ubifs_write_sb_node(c, sup); ++ kfree(sup); + if (err) + goto out; + } +diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c +index 27d64d7..a892ed9 100644 +--- a/fs/xfs/xfs_alloc.c ++++ b/fs/xfs/xfs_alloc.c +@@ -2610,6 +2610,12 @@ restart: + new->bno + new->length) - + min(busyp->bno, new->bno); + new->bno = min(busyp->bno, new->bno); ++ /* ++ * Start the search over from the tree root, because ++ * erasing the node can rearrange the tree topology. ++ */ ++ spin_unlock(&pag->pagb_lock); ++ goto restart; + } else + busyp = NULL; + +diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h +index e5a3f58..dfb0ec6 100644 +--- a/include/asm-generic/bug.h ++++ b/include/asm-generic/bug.h +@@ -162,9 +162,6 @@ extern void warn_slowpath_null(const char *file, const int line); + unlikely(__ret_warn_once); \ + }) + +-#define WARN_ON_RATELIMIT(condition, state) \ +- WARN_ON((condition) && __ratelimit(state)) +- + /* + * WARN_ON_SMP() is for cases that the warning is either + * meaningless for !SMP or may even cause failures. +diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h +index f04b2a3..06cd510 100644 +--- a/include/drm/drm_pciids.h ++++ b/include/drm/drm_pciids.h +@@ -182,6 +182,7 @@ + {0x1002, 0x6750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6758, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6759, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x675F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6761, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ +@@ -192,6 +193,7 @@ + {0x1002, 0x6767, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6768, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x6778, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ +diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h +index be50d9e..acdb143 100644 +--- a/include/linux/blk_types.h ++++ b/include/linux/blk_types.h +@@ -168,7 +168,7 @@ enum rq_flag_bits { + (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) + #define REQ_COMMON_MASK \ + (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_DISCARD | \ +- REQ_NOIDLE | REQ_FLUSH | REQ_FUA) ++ REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE) + #define REQ_CLONE_MASK REQ_COMMON_MASK + + #define REQ_RAHEAD (1 << __REQ_RAHEAD) +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 2ad95fa..ae9091a 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -257,7 +257,7 @@ struct queue_limits { + unsigned char misaligned; + unsigned char discard_misaligned; + unsigned char cluster; +- signed char discard_zeroes_data; ++ unsigned char discard_zeroes_data; + }; + + struct request_queue +@@ -364,6 +364,8 @@ struct request_queue + * for flush operations + */ + unsigned int flush_flags; ++ unsigned int flush_not_queueable:1; ++ unsigned int flush_queue_delayed:1; + unsigned int flush_pending_idx:1; + unsigned int flush_running_idx:1; + unsigned long flush_pending_since; +@@ -843,6 +845,7 @@ extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); + extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *); + extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); + extern void blk_queue_flush(struct request_queue *q, unsigned int flush); ++extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable); + extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); + + extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); +@@ -1066,13 +1069,16 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector + { + unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1); + ++ if (!lim->max_discard_sectors) ++ return 0; ++ + return (lim->discard_granularity + lim->discard_alignment - alignment) + & (lim->discard_granularity - 1); + } + + static inline unsigned int queue_discard_zeroes_data(struct request_queue *q) + { +- if (q->limits.discard_zeroes_data == 1) ++ if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1) + return 1; + + return 0; +@@ -1111,6 +1117,11 @@ static inline unsigned int block_size(struct block_device *bdev) + return bdev->bd_block_size; + } + ++static inline bool queue_flush_queueable(struct request_queue *q) ++{ ++ return !q->flush_not_queueable; ++} ++ + typedef struct {struct page *v;} Sector; + + unsigned char *read_dev_sector(struct block_device *, sector_t, Sector *); +diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h +index c37b21a..24e2932 100644 +--- a/include/linux/clocksource.h ++++ b/include/linux/clocksource.h +@@ -192,6 +192,7 @@ struct clocksource { + #ifdef CONFIG_CLOCKSOURCE_WATCHDOG + /* Watchdog related data, used by the framework */ + struct list_head wd_list; ++ cycle_t cs_last; + cycle_t wd_last; + #endif + }; +diff --git a/include/linux/connector.h b/include/linux/connector.h +index 7c60d09..f696bcc 100644 +--- a/include/linux/connector.h ++++ b/include/linux/connector.h +@@ -44,7 +44,7 @@ + #define CN_VAL_DRBD 0x1 + #define CN_KVP_IDX 0x9 /* HyperV KVP */ + +-#define CN_NETLINK_USERS 9 ++#define CN_NETLINK_USERS 10 /* Highest index + 1 */ + + /* + * Maximum connector's message size. +diff --git a/include/linux/device.h b/include/linux/device.h +index d08399d..779e860 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -506,13 +506,13 @@ static inline int device_is_registered(struct device *dev) + + static inline void device_enable_async_suspend(struct device *dev) + { +- if (!dev->power.in_suspend) ++ if (!dev->power.is_prepared) + dev->power.async_suspend = true; + } + + static inline void device_disable_async_suspend(struct device *dev) + { +- if (!dev->power.in_suspend) ++ if (!dev->power.is_prepared) + dev->power.async_suspend = false; + } + +diff --git a/include/linux/fscache.h b/include/linux/fscache.h +index 7c4d72f..9ec20de 100644 +--- a/include/linux/fscache.h ++++ b/include/linux/fscache.h +@@ -204,6 +204,8 @@ extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *); + extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *); + extern bool __fscache_maybe_release_page(struct fscache_cookie *, struct page *, + gfp_t); ++extern void __fscache_uncache_all_inode_pages(struct fscache_cookie *, ++ struct inode *); + + /** + * fscache_register_netfs - Register a filesystem as desiring caching services +@@ -643,4 +645,23 @@ bool fscache_maybe_release_page(struct fscache_cookie *cookie, + return false; + } + ++/** ++ * fscache_uncache_all_inode_pages - Uncache all an inode's pages ++ * @cookie: The cookie representing the inode's cache object. ++ * @inode: The inode to uncache pages from. ++ * ++ * Uncache all the pages in an inode that are marked PG_fscache, assuming them ++ * to be associated with the given cookie. ++ * ++ * This function may sleep. It will wait for pages that are being written out ++ * and will wait whilst the PG_fscache mark is removed by the cache. ++ */ ++static inline ++void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, ++ struct inode *inode) ++{ ++ if (fscache_cookie_valid(cookie)) ++ __fscache_uncache_all_inode_pages(cookie, inode); ++} ++ + #endif /* _LINUX_FSCACHE_H */ +diff --git a/include/linux/genhd.h b/include/linux/genhd.h +index d764a42..300d758 100644 +--- a/include/linux/genhd.h ++++ b/include/linux/genhd.h +@@ -127,6 +127,7 @@ struct hd_struct { + #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 + #define GENHD_FL_EXT_DEVT 64 /* allow extended devt */ + #define GENHD_FL_NATIVE_CAPACITY 128 ++#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256 + + enum { + DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */ +diff --git a/include/linux/if_packet.h b/include/linux/if_packet.h +index 72bfa5a..8e37fba 100644 +--- a/include/linux/if_packet.h ++++ b/include/linux/if_packet.h +@@ -62,6 +62,7 @@ struct tpacket_auxdata { + __u16 tp_mac; + __u16 tp_net; + __u16 tp_vlan_tci; ++ __u16 tp_padding; + }; + + /* Rx ring - header status */ +@@ -100,6 +101,7 @@ struct tpacket2_hdr { + __u32 tp_sec; + __u32 tp_nsec; + __u16 tp_vlan_tci; ++ __u16 tp_padding; + }; + + #define TPACKET2_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + sizeof(struct sockaddr_ll)) +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 0249fe7..66b22bf 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1680,9 +1680,12 @@ static inline int skb_gro_header_hard(struct sk_buff *skb, unsigned int hlen) + static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen, + unsigned int offset) + { ++ if (!pskb_may_pull(skb, hlen)) ++ return NULL; ++ + NAPI_GRO_CB(skb)->frag0 = NULL; + NAPI_GRO_CB(skb)->frag0_len = 0; +- return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; ++ return skb->data + offset; + } + + static inline void *skb_gro_mac_header(struct sk_buff *skb) +diff --git a/include/linux/netfilter/ipset/ip_set_ahash.h b/include/linux/netfilter/ipset/ip_set_ahash.h +index a0196ac..ac3c822 100644 +--- a/include/linux/netfilter/ipset/ip_set_ahash.h ++++ b/include/linux/netfilter/ipset/ip_set_ahash.h +@@ -839,7 +839,7 @@ type_pf_tdel(struct ip_set *set, void *value, u32 timeout) + struct htable *t = h->table; + const struct type_pf_elem *d = value; + struct hbucket *n; +- int i, ret = 0; ++ int i; + struct type_pf_elem *data; + u32 key; + +@@ -850,7 +850,7 @@ type_pf_tdel(struct ip_set *set, void *value, u32 timeout) + if (!type_pf_data_equal(data, d)) + continue; + if (type_pf_data_expired(data)) +- ret = -IPSET_ERR_EXIST; ++ return -IPSET_ERR_EXIST; + if (i != n->pos - 1) + /* Not last one */ + type_pf_data_copy(data, ahash_tdata(n, n->pos - 1)); +diff --git a/include/linux/netfilter/ipset/ip_set_timeout.h b/include/linux/netfilter/ipset/ip_set_timeout.h +index 9f30c5f..bb773c1 100644 +--- a/include/linux/netfilter/ipset/ip_set_timeout.h ++++ b/include/linux/netfilter/ipset/ip_set_timeout.h +@@ -45,7 +45,7 @@ ip_set_timeout_test(unsigned long timeout) + { + return timeout != IPSET_ELEM_UNSET && + (timeout == IPSET_ELEM_PERMANENT || +- time_after(timeout, jiffies)); ++ time_is_after_jiffies(timeout)); + } + + static inline bool +@@ -53,7 +53,7 @@ ip_set_timeout_expired(unsigned long timeout) + { + return timeout != IPSET_ELEM_UNSET && + timeout != IPSET_ELEM_PERMANENT && +- time_before(timeout, jiffies); ++ time_is_before_jiffies(timeout); + } + + static inline unsigned long +@@ -64,7 +64,7 @@ ip_set_timeout_set(u32 timeout) + if (!timeout) + return IPSET_ELEM_PERMANENT; + +- t = timeout * HZ + jiffies; ++ t = msecs_to_jiffies(timeout * 1000) + jiffies; + if (t == IPSET_ELEM_UNSET || t == IPSET_ELEM_PERMANENT) + /* Bingo! */ + t++; +@@ -75,7 +75,8 @@ ip_set_timeout_set(u32 timeout) + static inline u32 + ip_set_timeout_get(unsigned long timeout) + { +- return timeout == IPSET_ELEM_PERMANENT ? 0 : (timeout - jiffies)/HZ; ++ return timeout == IPSET_ELEM_PERMANENT ? 0 : ++ jiffies_to_msecs(timeout - jiffies)/1000; + } + + #else +@@ -89,14 +90,14 @@ static inline bool + ip_set_timeout_test(unsigned long timeout) + { + return timeout == IPSET_ELEM_PERMANENT || +- time_after(timeout, jiffies); ++ time_is_after_jiffies(timeout); + } + + static inline bool + ip_set_timeout_expired(unsigned long timeout) + { + return timeout != IPSET_ELEM_PERMANENT && +- time_before(timeout, jiffies); ++ time_is_before_jiffies(timeout); + } + + static inline unsigned long +@@ -107,7 +108,7 @@ ip_set_timeout_set(u32 timeout) + if (!timeout) + return IPSET_ELEM_PERMANENT; + +- t = timeout * HZ + jiffies; ++ t = msecs_to_jiffies(timeout * 1000) + jiffies; + if (t == IPSET_ELEM_PERMANENT) + /* Bingo! :-) */ + t++; +@@ -118,7 +119,8 @@ ip_set_timeout_set(u32 timeout) + static inline u32 + ip_set_timeout_get(unsigned long timeout) + { +- return timeout == IPSET_ELEM_PERMANENT ? 0 : (timeout - jiffies)/HZ; ++ return timeout == IPSET_ELEM_PERMANENT ? 0 : ++ jiffies_to_msecs(timeout - jiffies)/1000; + } + #endif /* ! IP_SET_BITMAP_TIMEOUT */ + +diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h +index 8abe8d7..d041a4a 100644 +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -608,6 +608,8 @@ + #define PCI_DEVICE_ID_MATROX_G550 0x2527 + #define PCI_DEVICE_ID_MATROX_VIA 0x4536 + ++#define PCI_VENDOR_ID_MOBILITY_ELECTRONICS 0x14f2 ++ + #define PCI_VENDOR_ID_CT 0x102c + #define PCI_DEVICE_ID_CT_69000 0x00c0 + #define PCI_DEVICE_ID_CT_65545 0x00d8 +@@ -1535,6 +1537,7 @@ + #define PCI_DEVICE_ID_RICOH_RL5C476 0x0476 + #define PCI_DEVICE_ID_RICOH_RL5C478 0x0478 + #define PCI_DEVICE_ID_RICOH_R5C822 0x0822 ++#define PCI_DEVICE_ID_RICOH_R5CE823 0xe823 + #define PCI_DEVICE_ID_RICOH_R5C832 0x0832 + #define PCI_DEVICE_ID_RICOH_R5C843 0x0843 + +diff --git a/include/linux/pm.h b/include/linux/pm.h +index 512e091..fffb12f 100644 +--- a/include/linux/pm.h ++++ b/include/linux/pm.h +@@ -425,7 +425,8 @@ struct dev_pm_info { + pm_message_t power_state; + unsigned int can_wakeup:1; + unsigned int async_suspend:1; +- unsigned int in_suspend:1; /* Owned by the PM core */ ++ bool is_prepared:1; /* Owned by the PM core */ ++ bool is_suspended:1; /* Ditto */ + spinlock_t lock; + #ifdef CONFIG_PM_SLEEP + struct list_head entry; +diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h +index 77cbddb..a7d87f9 100644 +--- a/include/linux/pm_qos_params.h ++++ b/include/linux/pm_qos_params.h +@@ -16,6 +16,10 @@ + #define PM_QOS_NUM_CLASSES 4 + #define PM_QOS_DEFAULT_VALUE -1 + ++#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) ++#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) ++#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 ++ + struct pm_qos_request_list { + struct plist_node list; + int pm_qos_class; +diff --git a/include/linux/ratelimit.h b/include/linux/ratelimit.h +index 03ff67b..2f00715 100644 +--- a/include/linux/ratelimit.h ++++ b/include/linux/ratelimit.h +@@ -41,4 +41,44 @@ extern struct ratelimit_state printk_ratelimit_state; + extern int ___ratelimit(struct ratelimit_state *rs, const char *func); + #define __ratelimit(state) ___ratelimit(state, __func__) + ++#ifdef CONFIG_PRINTK ++ ++#define WARN_ON_RATELIMIT(condition, state) \ ++ WARN_ON((condition) && __ratelimit(state)) ++ ++#define __WARN_RATELIMIT(condition, state, format...) \ ++({ \ ++ int rtn = 0; \ ++ if (unlikely(__ratelimit(state))) \ ++ rtn = WARN(condition, format); \ ++ rtn; \ ++}) ++ ++#define WARN_RATELIMIT(condition, format...) \ ++({ \ ++ static DEFINE_RATELIMIT_STATE(_rs, \ ++ DEFAULT_RATELIMIT_INTERVAL, \ ++ DEFAULT_RATELIMIT_BURST); \ ++ __WARN_RATELIMIT(condition, &_rs, format); \ ++}) ++ ++#else ++ ++#define WARN_ON_RATELIMIT(condition, state) \ ++ WARN_ON(condition) ++ ++#define __WARN_RATELIMIT(condition, state, format...) \ ++({ \ ++ int rtn = WARN(condition, format); \ ++ rtn; \ ++}) ++ ++#define WARN_RATELIMIT(condition, format...) \ ++({ \ ++ int rtn = WARN(condition, format); \ ++ rtn; \ ++}) ++ ++#endif ++ + #endif /* _LINUX_RATELIMIT_H */ +diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h +index e98cd2e..06d6964 100644 +--- a/include/linux/seqlock.h ++++ b/include/linux/seqlock.h +@@ -88,12 +88,12 @@ static __always_inline unsigned read_seqbegin(const seqlock_t *sl) + unsigned ret; + + repeat: +- ret = sl->sequence; +- smp_rmb(); ++ ret = ACCESS_ONCE(sl->sequence); + if (unlikely(ret & 1)) { + cpu_relax(); + goto repeat; + } ++ smp_rmb(); + + return ret; + } +diff --git a/include/linux/sunrpc/gss_krb5_enctypes.h b/include/linux/sunrpc/gss_krb5_enctypes.h +new file mode 100644 +index 0000000..ec6234e +--- /dev/null ++++ b/include/linux/sunrpc/gss_krb5_enctypes.h +@@ -0,0 +1,4 @@ ++/* ++ * Dumb way to share this static piece of information with nfsd ++ */ ++#define KRB5_SUPPORTED_ENCTYPES "18,17,16,23,3,1,2" +diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h +index f73c482..fe2d8e6 100644 +--- a/include/linux/sunrpc/sched.h ++++ b/include/linux/sunrpc/sched.h +@@ -84,7 +84,8 @@ struct rpc_task { + #endif + unsigned char tk_priority : 2,/* Task priority */ + tk_garb_retry : 2, +- tk_cred_retry : 2; ++ tk_cred_retry : 2, ++ tk_rebind_retry : 2; + }; + #define tk_xprt tk_client->cl_xprt + +diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h +index 71693d4..17df360 100644 +--- a/include/linux/usb_usual.h ++++ b/include/linux/usb_usual.h +@@ -62,7 +62,9 @@ + US_FLAG(NO_READ_DISC_INFO, 0x00040000) \ + /* cannot handle READ_DISC_INFO */ \ + US_FLAG(NO_READ_CAPACITY_16, 0x00080000) \ +- /* cannot handle READ_CAPACITY_16 */ ++ /* cannot handle READ_CAPACITY_16 */ \ ++ US_FLAG(INITIAL_READ10, 0x00100000) \ ++ /* Initial READ(10) (and others) must be retried */ + + #define US_FLAG(name, value) US_FL_##name = value , + enum { US_DO_ALL_FLAGS }; +diff --git a/include/net/dst.h b/include/net/dst.h +index 75b95df..b3ad020 100644 +--- a/include/net/dst.h ++++ b/include/net/dst.h +@@ -120,6 +120,8 @@ static inline u32 *dst_metrics_write_ptr(struct dst_entry *dst) + { + unsigned long p = dst->_metrics; + ++ BUG_ON(!p); ++ + if (p & DST_METRICS_READ_ONLY) + return dst->ops->cow_metrics(dst, p); + return __DST_METRICS_PTR(p); +diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h +index 86aefed..e5bf4c8 100644 +--- a/include/net/ip_vs.h ++++ b/include/net/ip_vs.h +@@ -802,7 +802,8 @@ struct netns_ipvs { + struct list_head rs_table[IP_VS_RTAB_SIZE]; + /* ip_vs_app */ + struct list_head app_list; +- ++ /* ip_vs_ftp */ ++ struct ip_vs_app *ftp_app; + /* ip_vs_proto */ + #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */ + struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE]; +diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h +index 1d3b5b2..561ac99 100644 +--- a/include/target/target_core_base.h ++++ b/include/target/target_core_base.h +@@ -98,6 +98,7 @@ enum transport_state_table { + TRANSPORT_REMOVE = 14, + TRANSPORT_FREE = 15, + TRANSPORT_NEW_CMD_MAP = 16, ++ TRANSPORT_FREE_CMD_INTR = 17, + }; + + /* Used for struct se_cmd->se_cmd_flags */ +diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h +index 59aa464..24a1c6c 100644 +--- a/include/target/target_core_transport.h ++++ b/include/target/target_core_transport.h +@@ -172,6 +172,7 @@ extern int transport_generic_handle_cdb_map(struct se_cmd *); + extern int transport_generic_handle_data(struct se_cmd *); + extern void transport_new_cmd_failure(struct se_cmd *); + extern int transport_generic_handle_tmr(struct se_cmd *); ++extern void transport_generic_free_cmd_intr(struct se_cmd *); + extern void __transport_stop_task_timer(struct se_task *, unsigned long *); + extern unsigned char transport_asciihex_to_binaryhex(unsigned char val[2]); + extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32, +diff --git a/init/calibrate.c b/init/calibrate.c +index 76ac919..30a44cd 100644 +--- a/init/calibrate.c ++++ b/init/calibrate.c +@@ -185,30 +185,32 @@ recalibrate: + + void __cpuinit calibrate_delay(void) + { ++ unsigned long lpj; + static bool printed; + + if (preset_lpj) { +- loops_per_jiffy = preset_lpj; ++ lpj = preset_lpj; + if (!printed) + pr_info("Calibrating delay loop (skipped) " + "preset value.. "); + } else if ((!printed) && lpj_fine) { +- loops_per_jiffy = lpj_fine; ++ lpj = lpj_fine; + pr_info("Calibrating delay loop (skipped), " + "value calculated using timer frequency.. "); +- } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) { ++ } else if ((lpj = calibrate_delay_direct()) != 0) { + if (!printed) + pr_info("Calibrating delay using timer " + "specific routine.. "); + } else { + if (!printed) + pr_info("Calibrating delay loop... "); +- loops_per_jiffy = calibrate_delay_converge(); ++ lpj = calibrate_delay_converge(); + } + if (!printed) + pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n", +- loops_per_jiffy/(500000/HZ), +- (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy); ++ lpj/(500000/HZ), ++ (lpj/(5000/HZ)) % 100, lpj); + ++ loops_per_jiffy = lpj; + printed = true; + } +diff --git a/init/main.c b/init/main.c +index 4a9479e..48df882 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -580,8 +580,8 @@ asmlinkage void __init start_kernel(void) + #endif + page_cgroup_init(); + enable_debug_pagealloc(); +- kmemleak_init(); + debug_objects_mem_init(); ++ kmemleak_init(); + setup_per_cpu_pageset(); + numa_policy_init(); + if (late_time_init) +diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c +index 2c039c9..51e4944 100644 +--- a/kernel/irq/irqdesc.c ++++ b/kernel/irq/irqdesc.c +@@ -257,13 +257,11 @@ int __init early_irq_init(void) + count = ARRAY_SIZE(irq_desc); + + for (i = 0; i < count; i++) { +- desc[i].irq_data.irq = i; +- desc[i].irq_data.chip = &no_irq_chip; + desc[i].kstat_irqs = alloc_percpu(unsigned int); +- irq_settings_clr_and_set(desc, ~0, _IRQ_DEFAULT_INIT_FLAGS); +- alloc_masks(desc + i, GFP_KERNEL, node); +- desc_smp_init(desc + i, node); ++ alloc_masks(&desc[i], GFP_KERNEL, node); ++ raw_spin_lock_init(&desc[i].lock); + lockdep_set_class(&desc[i].lock, &irq_desc_lock_class); ++ desc_set_defaults(i, &desc[i], node); + } + return arch_early_irq_init(); + } +diff --git a/kernel/lockdep.c b/kernel/lockdep.c +index 53a6895..49452a7 100644 +--- a/kernel/lockdep.c ++++ b/kernel/lockdep.c +@@ -3242,7 +3242,7 @@ int lock_is_held(struct lockdep_map *lock) + int ret = 0; + + if (unlikely(current->lockdep_recursion)) +- return ret; ++ return 1; /* avoid false negative lockdep_assert_held() */ + + raw_local_irq_save(flags); + check_flags(flags); +diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c +index 0da058b..a9582ef 100644 +--- a/kernel/pm_qos_params.c ++++ b/kernel/pm_qos_params.c +@@ -53,11 +53,17 @@ enum pm_qos_type { + PM_QOS_MIN /* return the smallest value */ + }; + ++/* ++ * Note: The lockless read path depends on the CPU accessing ++ * target_value atomically. Atomic access is only guaranteed on all CPU ++ * types linux supports for 32 bit quantites ++ */ + struct pm_qos_object { + struct plist_head requests; + struct blocking_notifier_head *notifiers; + struct miscdevice pm_qos_power_miscdev; + char *name; ++ s32 target_value; /* Do not change to 64 bit */ + s32 default_value; + enum pm_qos_type type; + }; +@@ -70,7 +76,8 @@ static struct pm_qos_object cpu_dma_pm_qos = { + .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock), + .notifiers = &cpu_dma_lat_notifier, + .name = "cpu_dma_latency", +- .default_value = 2000 * USEC_PER_SEC, ++ .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, ++ .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, + .type = PM_QOS_MIN, + }; + +@@ -79,7 +86,8 @@ static struct pm_qos_object network_lat_pm_qos = { + .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock), + .notifiers = &network_lat_notifier, + .name = "network_latency", +- .default_value = 2000 * USEC_PER_SEC, ++ .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, ++ .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, + .type = PM_QOS_MIN + }; + +@@ -89,7 +97,8 @@ static struct pm_qos_object network_throughput_pm_qos = { + .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock), + .notifiers = &network_throughput_notifier, + .name = "network_throughput", +- .default_value = 0, ++ .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, ++ .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, + .type = PM_QOS_MAX, + }; + +@@ -135,6 +144,16 @@ static inline int pm_qos_get_value(struct pm_qos_object *o) + } + } + ++static inline s32 pm_qos_read_value(struct pm_qos_object *o) ++{ ++ return o->target_value; ++} ++ ++static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value) ++{ ++ o->target_value = value; ++} ++ + static void update_target(struct pm_qos_object *o, struct plist_node *node, + int del, int value) + { +@@ -159,6 +178,7 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node, + plist_add(node, &o->requests); + } + curr_value = pm_qos_get_value(o); ++ pm_qos_set_value(o, curr_value); + spin_unlock_irqrestore(&pm_qos_lock, flags); + + if (prev_value != curr_value) +@@ -193,18 +213,11 @@ static int find_pm_qos_object_by_minor(int minor) + * pm_qos_request - returns current system wide qos expectation + * @pm_qos_class: identification of which qos value is requested + * +- * This function returns the current target value in an atomic manner. ++ * This function returns the current target value. + */ + int pm_qos_request(int pm_qos_class) + { +- unsigned long flags; +- int value; +- +- spin_lock_irqsave(&pm_qos_lock, flags); +- value = pm_qos_get_value(pm_qos_array[pm_qos_class]); +- spin_unlock_irqrestore(&pm_qos_lock, flags); +- +- return value; ++ return pm_qos_read_value(pm_qos_array[pm_qos_class]); + } + EXPORT_SYMBOL_GPL(pm_qos_request); + +diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c +index ca0aacc..1a78c1a 100644 +--- a/kernel/power/snapshot.c ++++ b/kernel/power/snapshot.c +@@ -1199,7 +1199,11 @@ static void free_unnecessary_pages(void) + to_free_highmem = alloc_highmem - save; + } else { + to_free_highmem = 0; +- to_free_normal -= save - alloc_highmem; ++ save -= alloc_highmem; ++ if (to_free_normal > save) ++ to_free_normal -= save; ++ else ++ to_free_normal = 0; + } + + memory_bm_position_reset(©_bm); +diff --git a/kernel/power/user.c b/kernel/power/user.c +index 7d02d33..42ddbc6 100644 +--- a/kernel/power/user.c ++++ b/kernel/power/user.c +@@ -113,8 +113,10 @@ static int snapshot_open(struct inode *inode, struct file *filp) + if (error) + pm_notifier_call_chain(PM_POST_RESTORE); + } +- if (error) ++ if (error) { ++ free_basic_memory_bitmaps(); + atomic_inc(&snapshot_device_available); ++ } + data->frozen = 0; + data->ready = 0; + data->platform_support = 0; +diff --git a/kernel/taskstats.c b/kernel/taskstats.c +index 9ffea36..fc0f220 100644 +--- a/kernel/taskstats.c ++++ b/kernel/taskstats.c +@@ -285,16 +285,18 @@ ret: + static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) + { + struct listener_list *listeners; +- struct listener *s, *tmp; ++ struct listener *s, *tmp, *s2; + unsigned int cpu; + + if (!cpumask_subset(mask, cpu_possible_mask)) + return -EINVAL; + ++ s = NULL; + if (isadd == REGISTER) { + for_each_cpu(cpu, mask) { +- s = kmalloc_node(sizeof(struct listener), GFP_KERNEL, +- cpu_to_node(cpu)); ++ if (!s) ++ s = kmalloc_node(sizeof(struct listener), ++ GFP_KERNEL, cpu_to_node(cpu)); + if (!s) + goto cleanup; + s->pid = pid; +@@ -303,9 +305,16 @@ static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) + + listeners = &per_cpu(listener_array, cpu); + down_write(&listeners->sem); ++ list_for_each_entry_safe(s2, tmp, &listeners->list, list) { ++ if (s2->pid == pid) ++ goto next_cpu; ++ } + list_add(&s->list, &listeners->list); ++ s = NULL; ++next_cpu: + up_write(&listeners->sem); + } ++ kfree(s); + return 0; + } + +diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c +index 0e17c10..727da92 100644 +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -185,7 +185,6 @@ static struct clocksource *watchdog; + static struct timer_list watchdog_timer; + static DECLARE_WORK(watchdog_work, clocksource_watchdog_work); + static DEFINE_SPINLOCK(watchdog_lock); +-static cycle_t watchdog_last; + static int watchdog_running; + + static int clocksource_watchdog_kthread(void *data); +@@ -254,11 +253,6 @@ static void clocksource_watchdog(unsigned long data) + if (!watchdog_running) + goto out; + +- wdnow = watchdog->read(watchdog); +- wd_nsec = clocksource_cyc2ns((wdnow - watchdog_last) & watchdog->mask, +- watchdog->mult, watchdog->shift); +- watchdog_last = wdnow; +- + list_for_each_entry(cs, &watchdog_list, wd_list) { + + /* Clocksource already marked unstable? */ +@@ -268,19 +262,28 @@ static void clocksource_watchdog(unsigned long data) + continue; + } + ++ local_irq_disable(); + csnow = cs->read(cs); ++ wdnow = watchdog->read(watchdog); ++ local_irq_enable(); + + /* Clocksource initialized ? */ + if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) { + cs->flags |= CLOCK_SOURCE_WATCHDOG; +- cs->wd_last = csnow; ++ cs->wd_last = wdnow; ++ cs->cs_last = csnow; + continue; + } + +- /* Check the deviation from the watchdog clocksource. */ +- cs_nsec = clocksource_cyc2ns((csnow - cs->wd_last) & ++ wd_nsec = clocksource_cyc2ns((wdnow - cs->wd_last) & watchdog->mask, ++ watchdog->mult, watchdog->shift); ++ ++ cs_nsec = clocksource_cyc2ns((csnow - cs->cs_last) & + cs->mask, cs->mult, cs->shift); +- cs->wd_last = csnow; ++ cs->cs_last = csnow; ++ cs->wd_last = wdnow; ++ ++ /* Check the deviation from the watchdog clocksource. */ + if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) { + clocksource_unstable(cs, cs_nsec - wd_nsec); + continue; +@@ -318,7 +321,6 @@ static inline void clocksource_start_watchdog(void) + return; + init_timer(&watchdog_timer); + watchdog_timer.function = clocksource_watchdog; +- watchdog_last = watchdog->read(watchdog); + watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL; + add_timer_on(&watchdog_timer, cpumask_first(cpu_online_mask)); + watchdog_running = 1; +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index ee24fa1..666880d 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -2413,14 +2413,16 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable) + ftrace_match_records(parser->buffer, parser->idx, enable); + } + +- mutex_lock(&ftrace_lock); +- if (ftrace_start_up && ftrace_enabled) +- ftrace_run_update_code(FTRACE_ENABLE_CALLS); +- mutex_unlock(&ftrace_lock); +- + trace_parser_put(parser); + kfree(iter); + ++ if (file->f_mode & FMODE_WRITE) { ++ mutex_lock(&ftrace_lock); ++ if (ftrace_start_up && ftrace_enabled) ++ ftrace_run_update_code(FTRACE_ENABLE_CALLS); ++ mutex_unlock(&ftrace_lock); ++ } ++ + mutex_unlock(&ftrace_regex_lock); + return 0; + } +diff --git a/lib/debugobjects.c b/lib/debugobjects.c +index 9d86e45..a78b7c6 100644 +--- a/lib/debugobjects.c ++++ b/lib/debugobjects.c +@@ -198,7 +198,7 @@ static void free_object(struct debug_obj *obj) + * initialized: + */ + if (obj_pool_free > ODEBUG_POOL_SIZE && obj_cache) +- sched = !work_pending(&debug_obj_work); ++ sched = keventd_up() && !work_pending(&debug_obj_work); + hlist_add_head(&obj->node, &obj_pool); + obj_pool_free++; + obj_pool_used--; +diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c +index 619313e..507a22f 100644 +--- a/lib/locking-selftest.c ++++ b/lib/locking-selftest.c +@@ -144,7 +144,7 @@ static void init_shared_classes(void) + + #define HARDIRQ_ENTER() \ + local_irq_disable(); \ +- irq_enter(); \ ++ __irq_enter(); \ + WARN_ON(!in_irq()); + + #define HARDIRQ_EXIT() \ +diff --git a/mm/compaction.c b/mm/compaction.c +index 021a296..e4e0166 100644 +--- a/mm/compaction.c ++++ b/mm/compaction.c +@@ -144,9 +144,20 @@ static void isolate_freepages(struct zone *zone, + int nr_freepages = cc->nr_freepages; + struct list_head *freelist = &cc->freepages; + ++ /* ++ * Initialise the free scanner. The starting point is where we last ++ * scanned from (or the end of the zone if starting). The low point ++ * is the end of the pageblock the migration scanner is using. ++ */ + pfn = cc->free_pfn; + low_pfn = cc->migrate_pfn + pageblock_nr_pages; +- high_pfn = low_pfn; ++ ++ /* ++ * Take care that if the migration scanner is at the end of the zone ++ * that the free scanner does not accidentally move to the next zone ++ * in the next isolation cycle. ++ */ ++ high_pfn = min(low_pfn, pfn); + + /* + * Isolate free pages until enough are available to migrate the +@@ -240,11 +251,18 @@ static bool too_many_isolated(struct zone *zone) + return isolated > (inactive + active) / 2; + } + ++/* possible outcome of isolate_migratepages */ ++typedef enum { ++ ISOLATE_ABORT, /* Abort compaction now */ ++ ISOLATE_NONE, /* No pages isolated, continue scanning */ ++ ISOLATE_SUCCESS, /* Pages isolated, migrate */ ++} isolate_migrate_t; ++ + /* + * Isolate all pages that can be migrated from the block pointed to by + * the migrate scanner within compact_control. + */ +-static unsigned long isolate_migratepages(struct zone *zone, ++static isolate_migrate_t isolate_migratepages(struct zone *zone, + struct compact_control *cc) + { + unsigned long low_pfn, end_pfn; +@@ -261,7 +279,7 @@ static unsigned long isolate_migratepages(struct zone *zone, + /* Do not cross the free scanner or scan within a memory hole */ + if (end_pfn > cc->free_pfn || !pfn_valid(low_pfn)) { + cc->migrate_pfn = end_pfn; +- return 0; ++ return ISOLATE_NONE; + } + + /* +@@ -270,10 +288,14 @@ static unsigned long isolate_migratepages(struct zone *zone, + * delay for some time until fewer pages are isolated + */ + while (unlikely(too_many_isolated(zone))) { ++ /* async migration should just abort */ ++ if (!cc->sync) ++ return ISOLATE_ABORT; ++ + congestion_wait(BLK_RW_ASYNC, HZ/10); + + if (fatal_signal_pending(current)) +- return 0; ++ return ISOLATE_ABORT; + } + + /* Time to isolate some pages for migration */ +@@ -358,7 +380,7 @@ static unsigned long isolate_migratepages(struct zone *zone, + + trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated); + +- return cc->nr_migratepages; ++ return ISOLATE_SUCCESS; + } + + /* +@@ -522,8 +544,15 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) + unsigned long nr_migrate, nr_remaining; + int err; + +- if (!isolate_migratepages(zone, cc)) ++ switch (isolate_migratepages(zone, cc)) { ++ case ISOLATE_ABORT: ++ ret = COMPACT_PARTIAL; ++ goto out; ++ case ISOLATE_NONE: + continue; ++ case ISOLATE_SUCCESS: ++ ; ++ } + + nr_migrate = cc->nr_migratepages; + err = migrate_pages(&cc->migratepages, compaction_alloc, +@@ -547,6 +576,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) + + } + ++out: + /* Release free pages and check accounting */ + cc->nr_freepages -= release_freepages(&cc->freepages); + VM_BUG_ON(cc->nr_freepages != 0); +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 8ee3bd8..f7c32fb 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -1033,10 +1033,10 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma, + */ + chg = vma_needs_reservation(h, vma, addr); + if (chg < 0) +- return ERR_PTR(chg); ++ return ERR_PTR(-VM_FAULT_OOM); + if (chg) + if (hugetlb_get_quota(inode->i_mapping, chg)) +- return ERR_PTR(-ENOSPC); ++ return ERR_PTR(-VM_FAULT_SIGBUS); + + spin_lock(&hugetlb_lock); + page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve); +@@ -1111,6 +1111,14 @@ static void __init gather_bootmem_prealloc(void) + WARN_ON(page_count(page) != 1); + prep_compound_huge_page(page, h->order); + prep_new_huge_page(h, page, page_to_nid(page)); ++ /* ++ * If we had gigantic hugepages allocated at boot time, we need ++ * to restore the 'stolen' pages to totalram_pages in order to ++ * fix confusing memory reports from free(1) and another ++ * side-effects, like CommitLimit going negative. ++ */ ++ if (h->order > (MAX_ORDER - 1)) ++ totalram_pages += 1 << h->order; + } + } + +diff --git a/mm/kmemleak.c b/mm/kmemleak.c +index c1d5867..aacee45 100644 +--- a/mm/kmemleak.c ++++ b/mm/kmemleak.c +@@ -1414,9 +1414,12 @@ static void *kmemleak_seq_next(struct seq_file *seq, void *v, loff_t *pos) + ++(*pos); + + list_for_each_continue_rcu(n, &object_list) { +- next_obj = list_entry(n, struct kmemleak_object, object_list); +- if (get_object(next_obj)) ++ struct kmemleak_object *obj = ++ list_entry(n, struct kmemleak_object, object_list); ++ if (get_object(obj)) { ++ next_obj = obj; + break; ++ } + } + + put_object(prev_obj); +diff --git a/mm/ksm.c b/mm/ksm.c +index 942dfc7..e48c86e 100644 +--- a/mm/ksm.c ++++ b/mm/ksm.c +@@ -1301,6 +1301,12 @@ static struct rmap_item *scan_get_next_rmap_item(struct page **page) + slot = list_entry(slot->mm_list.next, struct mm_slot, mm_list); + ksm_scan.mm_slot = slot; + spin_unlock(&ksm_mmlist_lock); ++ /* ++ * Although we tested list_empty() above, a racing __ksm_exit ++ * of the last mm on the list may have removed it since then. ++ */ ++ if (slot == &ksm_mm_head) ++ return NULL; + next_mm: + ksm_scan.address = 0; + ksm_scan.rmap_list = &slot->rmap_list; +diff --git a/mm/memory-failure.c b/mm/memory-failure.c +index 2b9a5ee..9568e0b 100644 +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -52,6 +52,7 @@ + #include <linux/swapops.h> + #include <linux/hugetlb.h> + #include <linux/memory_hotplug.h> ++#include <linux/mm_inline.h> + #include "internal.h" + + int sysctl_memory_failure_early_kill __read_mostly = 0; +@@ -1463,7 +1464,8 @@ int soft_offline_page(struct page *page, int flags) + ret = isolate_lru_page(page); + if (!ret) { + LIST_HEAD(pagelist); +- ++ inc_zone_page_state(page, NR_ISOLATED_ANON + ++ page_is_file_cache(page)); + list_add(&page->lru, &pagelist); + ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, + 0, true); +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index 9ca1d60..fc5e0ba 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -518,7 +518,7 @@ int mem_online_node(int nid) + + lock_memory_hotplug(); + pgdat = hotadd_new_pgdat(nid, 0); +- if (pgdat) { ++ if (!pgdat) { + ret = -ENOMEM; + goto out; + } +diff --git a/mm/migrate.c b/mm/migrate.c +index 34132f8..3179891 100644 +--- a/mm/migrate.c ++++ b/mm/migrate.c +@@ -288,7 +288,7 @@ static int migrate_page_move_mapping(struct address_space *mapping, + */ + __dec_zone_page_state(page, NR_FILE_PAGES); + __inc_zone_page_state(newpage, NR_FILE_PAGES); +- if (PageSwapBacked(page)) { ++ if (!PageSwapCache(page) && PageSwapBacked(page)) { + __dec_zone_page_state(page, NR_SHMEM); + __inc_zone_page_state(newpage, NR_SHMEM); + } +diff --git a/mm/nommu.c b/mm/nommu.c +index c4c542c..0376a4c 100644 +--- a/mm/nommu.c ++++ b/mm/nommu.c +@@ -1819,10 +1819,13 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, + return NULL; + } + +-int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, +- unsigned long to, unsigned long size, pgprot_t prot) ++int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, ++ unsigned long pfn, unsigned long size, pgprot_t prot) + { +- vma->vm_start = vma->vm_pgoff << PAGE_SHIFT; ++ if (addr != (pfn << PAGE_SHIFT)) ++ return -EINVAL; ++ ++ vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; + return 0; + } + EXPORT_SYMBOL(remap_pfn_range); +diff --git a/mm/oom_kill.c b/mm/oom_kill.c +index f52e85c..5299cb8 100644 +--- a/mm/oom_kill.c ++++ b/mm/oom_kill.c +@@ -285,7 +285,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints, + do_each_thread(g, p) { + unsigned int points; + +- if (!p->mm) ++ if (p->exit_state) + continue; + if (oom_unkillable_task(p, mem, nodemask)) + continue; +@@ -301,6 +301,8 @@ static struct task_struct *select_bad_process(unsigned int *ppoints, + */ + if (test_tsk_thread_flag(p, TIF_MEMDIE)) + return ERR_PTR(-1UL); ++ if (!p->mm) ++ continue; + + if (p->flags & PF_EXITING) { + /* +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 3f8bce2..e78b324 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -2064,6 +2064,7 @@ restart: + first_zones_zonelist(zonelist, high_zoneidx, NULL, + &preferred_zone); + ++rebalance: + /* This is the last chance, in general, before the goto nopage. */ + page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist, + high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS, +@@ -2071,7 +2072,6 @@ restart: + if (page) + goto got_pg; + +-rebalance: + /* Allocate without watermarks if the context allows */ + if (alloc_flags & ALLOC_NO_WATERMARKS) { + page = __alloc_pages_high_priority(gfp_mask, order, +diff --git a/mm/shmem.c b/mm/shmem.c +index dfc7069..ba12be4 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -916,11 +916,12 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, s + if (size > ENTRIES_PER_PAGE) + size = ENTRIES_PER_PAGE; + offset = shmem_find_swp(entry, ptr, ptr+size); ++ shmem_swp_unmap(ptr); + if (offset >= 0) { + shmem_dir_unmap(dir); ++ ptr = shmem_swp_map(subdir); + goto found; + } +- shmem_swp_unmap(ptr); + } + } + lost1: +@@ -1100,8 +1101,8 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc) + delete_from_page_cache(page); + shmem_swp_set(info, entry, swap.val); + shmem_swp_unmap(entry); +- spin_unlock(&info->lock); + swap_shmem_alloc(swap); ++ spin_unlock(&info->lock); + BUG_ON(page_mapped(page)); + swap_writepage(page, wbc); + return 0; +diff --git a/mm/slub.c b/mm/slub.c +index 9d2e5e4..f6cb6cd 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -261,6 +261,18 @@ static inline void *get_freepointer(struct kmem_cache *s, void *object) + return *(void **)(object + s->offset); + } + ++static inline void *get_freepointer_safe(struct kmem_cache *s, void *object) ++{ ++ void *p; ++ ++#ifdef CONFIG_DEBUG_PAGEALLOC ++ probe_kernel_read(&p, (void **)(object + s->offset), sizeof(p)); ++#else ++ p = get_freepointer(s, object); ++#endif ++ return p; ++} ++ + static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) + { + *(void **)(object + s->offset) = fp; +@@ -1943,7 +1955,7 @@ redo: + if (unlikely(!irqsafe_cpu_cmpxchg_double( + s->cpu_slab->freelist, s->cpu_slab->tid, + object, tid, +- get_freepointer(s, object), next_tid(tid)))) { ++ get_freepointer_safe(s, object), next_tid(tid)))) { + + note_cmpxchg_failure("slab_alloc", s, tid); + goto redo; +diff --git a/mm/vmscan.c b/mm/vmscan.c +index 8bfd450..7f3270f 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -230,8 +230,11 @@ unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, + if (scanned == 0) + scanned = SWAP_CLUSTER_MAX; + +- if (!down_read_trylock(&shrinker_rwsem)) +- return 1; /* Assume we'll be able to shrink next time */ ++ if (!down_read_trylock(&shrinker_rwsem)) { ++ /* Assume we'll be able to shrink next time */ ++ ret = 1; ++ goto out; ++ } + + list_for_each_entry(shrinker, &shrinker_list, list) { + unsigned long long delta; +@@ -282,6 +285,8 @@ unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, + shrinker->nr += total_scan; + } + up_read(&shrinker_rwsem); ++out: ++ cond_resched(); + return ret; + } + +@@ -1109,8 +1114,20 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan, + nr_lumpy_dirty++; + scan++; + } else { +- /* the page is freed already. */ +- if (!page_count(cursor_page)) ++ /* ++ * Check if the page is freed already. ++ * ++ * We can't use page_count() as that ++ * requires compound_head and we don't ++ * have a pin on the page here. If a ++ * page is tail, we may or may not ++ * have isolated the head, so assume ++ * it's not free, it'd be tricky to ++ * track the head status without a ++ * page pin. ++ */ ++ if (!PageTail(cursor_page) && ++ !atomic_read(&cursor_page->_count)) + continue; + break; + } +@@ -2240,7 +2257,8 @@ static bool pgdat_balanced(pg_data_t *pgdat, unsigned long balanced_pages, + for (i = 0; i <= classzone_idx; i++) + present_pages += pgdat->node_zones[i].present_pages; + +- return balanced_pages > (present_pages >> 2); ++ /* A special case here: if zone has no page, we think it's balanced */ ++ return balanced_pages >= (present_pages >> 2); + } + + /* is kswapd sleeping prematurely? */ +@@ -2256,7 +2274,7 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining, + return true; + + /* Check the watermark levels */ +- for (i = 0; i < pgdat->nr_zones; i++) { ++ for (i = 0; i <= classzone_idx; i++) { + struct zone *zone = pgdat->node_zones + i; + + if (!populated_zone(zone)) +@@ -2274,7 +2292,7 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining, + } + + if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone), +- classzone_idx, 0)) ++ i, 0)) + all_zones_ok = false; + else + balanced += zone->present_pages; +@@ -2286,7 +2304,7 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining, + * must be balanced + */ + if (order) +- return pgdat_balanced(pgdat, balanced, classzone_idx); ++ return !pgdat_balanced(pgdat, balanced, classzone_idx); + else + return !all_zones_ok; + } +@@ -2376,7 +2394,6 @@ loop_again: + if (!zone_watermark_ok_safe(zone, order, + high_wmark_pages(zone), 0, 0)) { + end_zone = i; +- *classzone_idx = i; + break; + } + } +@@ -2431,19 +2448,19 @@ loop_again: + KSWAPD_ZONE_BALANCE_GAP_RATIO); + if (!zone_watermark_ok_safe(zone, order, + high_wmark_pages(zone) + balance_gap, +- end_zone, 0)) ++ end_zone, 0)) { + shrink_zone(priority, zone, &sc); +- reclaim_state->reclaimed_slab = 0; +- nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, +- lru_pages); +- sc.nr_reclaimed += reclaim_state->reclaimed_slab; +- total_scanned += sc.nr_scanned; + +- if (zone->all_unreclaimable) +- continue; +- if (nr_slab == 0 && +- !zone_reclaimable(zone)) +- zone->all_unreclaimable = 1; ++ reclaim_state->reclaimed_slab = 0; ++ nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, ++ lru_pages); ++ sc.nr_reclaimed += reclaim_state->reclaimed_slab; ++ total_scanned += sc.nr_scanned; ++ ++ if (nr_slab == 0 && !zone_reclaimable(zone)) ++ zone->all_unreclaimable = 1; ++ } ++ + /* + * If we've done a decent amount of scanning and + * the reclaim ratio is low, start doing writepage +@@ -2453,6 +2470,12 @@ loop_again: + total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2) + sc.may_writepage = 1; + ++ if (zone->all_unreclaimable) { ++ if (end_zone && end_zone == i) ++ end_zone--; ++ continue; ++ } ++ + if (!zone_watermark_ok_safe(zone, order, + high_wmark_pages(zone), end_zone, 0)) { + all_zones_ok = 0; +@@ -2631,8 +2654,8 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx) + */ + static int kswapd(void *p) + { +- unsigned long order; +- int classzone_idx; ++ unsigned long order, new_order; ++ int classzone_idx, new_classzone_idx; + pg_data_t *pgdat = (pg_data_t*)p; + struct task_struct *tsk = current; + +@@ -2662,17 +2685,23 @@ static int kswapd(void *p) + tsk->flags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD; + set_freezable(); + +- order = 0; +- classzone_idx = MAX_NR_ZONES - 1; ++ order = new_order = 0; ++ classzone_idx = new_classzone_idx = pgdat->nr_zones - 1; + for ( ; ; ) { +- unsigned long new_order; +- int new_classzone_idx; + int ret; + +- new_order = pgdat->kswapd_max_order; +- new_classzone_idx = pgdat->classzone_idx; +- pgdat->kswapd_max_order = 0; +- pgdat->classzone_idx = MAX_NR_ZONES - 1; ++ /* ++ * If the last balance_pgdat was unsuccessful it's unlikely a ++ * new request of a similar or harder type will succeed soon ++ * so consider going to sleep on the basis we reclaimed at ++ */ ++ if (classzone_idx >= new_classzone_idx && order == new_order) { ++ new_order = pgdat->kswapd_max_order; ++ new_classzone_idx = pgdat->classzone_idx; ++ pgdat->kswapd_max_order = 0; ++ pgdat->classzone_idx = pgdat->nr_zones - 1; ++ } ++ + if (order < new_order || classzone_idx > new_classzone_idx) { + /* + * Don't sleep if someone wants a larger 'order' +@@ -2685,7 +2714,7 @@ static int kswapd(void *p) + order = pgdat->kswapd_max_order; + classzone_idx = pgdat->classzone_idx; + pgdat->kswapd_max_order = 0; +- pgdat->classzone_idx = MAX_NR_ZONES - 1; ++ pgdat->classzone_idx = pgdat->nr_zones - 1; + } + + ret = try_to_freeze(); +diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c +index b2ff6c8..f11e61e 100644 +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -338,7 +338,7 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, + u64_stats_update_begin(&stats->syncp); + stats->tx_packets++; + stats->tx_bytes += len; +- u64_stats_update_begin(&stats->syncp); ++ u64_stats_update_end(&stats->syncp); + } else { + this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped); + } +diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c +index f7fa67c..f49da58 100644 +--- a/net/atm/atm_sysfs.c ++++ b/net/atm/atm_sysfs.c +@@ -59,6 +59,14 @@ static ssize_t show_atmaddress(struct device *cdev, + return pos - buf; + } + ++static ssize_t show_atmindex(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct atm_dev *adev = to_atm_dev(cdev); ++ ++ return sprintf(buf, "%d\n", adev->number); ++} ++ + static ssize_t show_carrier(struct device *cdev, + struct device_attribute *attr, char *buf) + { +@@ -99,6 +107,7 @@ static ssize_t show_link_rate(struct device *cdev, + + static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); + static DEVICE_ATTR(atmaddress, S_IRUGO, show_atmaddress, NULL); ++static DEVICE_ATTR(atmindex, S_IRUGO, show_atmindex, NULL); + static DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL); + static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); + static DEVICE_ATTR(link_rate, S_IRUGO, show_link_rate, NULL); +@@ -106,6 +115,7 @@ static DEVICE_ATTR(link_rate, S_IRUGO, show_link_rate, NULL); + static struct device_attribute *atm_attrs[] = { + &dev_attr_atmaddress, + &dev_attr_address, ++ &dev_attr_atmindex, + &dev_attr_carrier, + &dev_attr_type, + &dev_attr_link_rate, +diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c +index 74ef4d4..ecaaa00 100644 +--- a/net/bridge/br_netfilter.c ++++ b/net/bridge/br_netfilter.c +@@ -104,10 +104,16 @@ static void fake_update_pmtu(struct dst_entry *dst, u32 mtu) + { + } + ++static u32 *fake_cow_metrics(struct dst_entry *dst, unsigned long old) ++{ ++ return NULL; ++} ++ + static struct dst_ops fake_dst_ops = { + .family = AF_INET, + .protocol = cpu_to_be16(ETH_P_IP), + .update_pmtu = fake_update_pmtu, ++ .cow_metrics = fake_cow_metrics, + }; + + /* +@@ -117,6 +123,10 @@ static struct dst_ops fake_dst_ops = { + * ipt_REJECT needs it. Future netfilter modules might + * require us to fill additional fields. + */ ++static const u32 br_dst_default_metrics[RTAX_MAX] = { ++ [RTAX_MTU - 1] = 1500, ++}; ++ + void br_netfilter_rtable_init(struct net_bridge *br) + { + struct rtable *rt = &br->fake_rtable; +@@ -124,7 +134,7 @@ void br_netfilter_rtable_init(struct net_bridge *br) + atomic_set(&rt->dst.__refcnt, 1); + rt->dst.dev = br->dev; + rt->dst.path = &rt->dst; +- dst_metric_set(&rt->dst, RTAX_MTU, 1500); ++ dst_init_metrics(&rt->dst, br_dst_default_metrics, true); + rt->dst.flags = DST_NOXFRM; + rt->dst.ops = &fake_dst_ops; + } +diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h +index 387013d..5e9ae57 100644 +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -123,6 +123,7 @@ struct net_bridge_port + bridge_id designated_bridge; + u32 path_cost; + u32 designated_cost; ++ unsigned long designated_age; + + struct timer_list forward_delay_timer; + struct timer_list hold_timer; +diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c +index 7370d14..c24ae0d 100644 +--- a/net/bridge/br_stp.c ++++ b/net/bridge/br_stp.c +@@ -164,8 +164,7 @@ void br_transmit_config(struct net_bridge_port *p) + else { + struct net_bridge_port *root + = br_get_port(br, br->root_port); +- bpdu.message_age = br->max_age +- - (root->message_age_timer.expires - jiffies) ++ bpdu.message_age = (jiffies - root->designated_age) + + MESSAGE_AGE_INCR; + } + bpdu.max_age = br->max_age; +@@ -189,6 +188,7 @@ static inline void br_record_config_information(struct net_bridge_port *p, + p->designated_cost = bpdu->root_path_cost; + p->designated_bridge = bpdu->bridge_id; + p->designated_port = bpdu->port_id; ++ p->designated_age = jiffies + bpdu->message_age; + + mod_timer(&p->message_age_timer, jiffies + + (p->br->max_age - bpdu->message_age)); +diff --git a/net/core/dev.c b/net/core/dev.c +index b624fe4..acd7423 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1007,7 +1007,7 @@ rollback: + } + + write_lock_bh(&dev_base_lock); +- hlist_del(&dev->name_hlist); ++ hlist_del_rcu(&dev->name_hlist); + write_unlock_bh(&dev_base_lock); + + synchronize_rcu(); +@@ -5258,7 +5258,7 @@ void netdev_update_features(struct net_device *dev) + if (dev->features == features) + return; + +- netdev_info(dev, "Features changed: 0x%08x -> 0x%08x\n", ++ netdev_dbg(dev, "Features changed: 0x%08x -> 0x%08x\n", + dev->features, features); + + if (dev->netdev_ops->ndo_set_features) +diff --git a/net/core/dst.c b/net/core/dst.c +index 91104d3..b71b7a3 100644 +--- a/net/core/dst.c ++++ b/net/core/dst.c +@@ -314,7 +314,7 @@ void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old) + { + unsigned long prev, new; + +- new = (unsigned long) dst_default_metrics; ++ new = ((unsigned long) dst_default_metrics) | DST_METRICS_READ_ONLY; + prev = cmpxchg(&dst->_metrics, old, new); + if (prev == old) + kfree(__DST_METRICS_PTR(old)); +diff --git a/net/core/ethtool.c b/net/core/ethtool.c +index 74ead9e..76ed645 100644 +--- a/net/core/ethtool.c ++++ b/net/core/ethtool.c +@@ -231,6 +231,29 @@ static int ethtool_set_feature_compat(struct net_device *dev, + return 1; + } + ++static int ethtool_set_flags_compat(struct net_device *dev, ++ int (*legacy_set)(struct net_device *, u32), ++ struct ethtool_set_features_block *features, u32 mask) ++{ ++ u32 value; ++ ++ if (!legacy_set) ++ return 0; ++ ++ if (!(features[0].valid & mask)) ++ return 0; ++ ++ value = dev->features & ~features[0].valid; ++ value |= features[0].requested; ++ ++ features[0].valid &= ~mask; ++ ++ if (legacy_set(dev, value & mask) < 0) ++ netdev_info(dev, "Legacy flags change failed\n"); ++ ++ return 1; ++} ++ + static int ethtool_set_features_compat(struct net_device *dev, + struct ethtool_set_features_block *features) + { +@@ -247,7 +270,7 @@ static int ethtool_set_features_compat(struct net_device *dev, + features, NETIF_F_ALL_TSO); + compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_rx_csum, + features, NETIF_F_RXCSUM); +- compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_flags, ++ compat |= ethtool_set_flags_compat(dev, dev->ethtool_ops->set_flags, + features, flags_dup_features); + + return compat; +@@ -330,7 +353,7 @@ static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GS + /* NETIF_F_IP_CSUM */ "tx-checksum-ipv4", + /* NETIF_F_NO_CSUM */ "tx-checksum-unneeded", + /* NETIF_F_HW_CSUM */ "tx-checksum-ip-generic", +- /* NETIF_F_IPV6_CSUM */ "tx_checksum-ipv6", ++ /* NETIF_F_IPV6_CSUM */ "tx-checksum-ipv6", + /* NETIF_F_HIGHDMA */ "highdma", + /* NETIF_F_FRAGLIST */ "tx-scatter-gather-fraglist", + /* NETIF_F_HW_VLAN_TX */ "tx-vlan-hw-insert", +diff --git a/net/core/filter.c b/net/core/filter.c +index afb8afb..1238cbd 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -38,6 +38,7 @@ + #include <asm/unaligned.h> + #include <linux/filter.h> + #include <linux/reciprocal_div.h> ++#include <linux/ratelimit.h> + + enum { + BPF_S_RET_K = 1, +@@ -409,7 +410,9 @@ load_b: + continue; + } + default: +- WARN_ON(1); ++ WARN_RATELIMIT(1, "Unknown code:%u jt:%u tf:%u k:%u\n", ++ fentry->code, fentry->jt, ++ fentry->jf, fentry->k); + return 0; + } + } +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 7ebeed0..3e934fe 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -2993,6 +2993,9 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) + skb->destructor = sock_rmem_free; + atomic_add(skb->truesize, &sk->sk_rmem_alloc); + ++ /* before exiting rcu section, make sure dst is refcounted */ ++ skb_dst_force(skb); ++ + skb_queue_tail(&sk->sk_error_queue, skb); + if (!sock_flag(sk, SOCK_DEAD)) + sk->sk_data_ready(sk, skb->len); +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index 807d83c..6bab50e 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -464,6 +464,9 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + if (addr_len < sizeof(struct sockaddr_in)) + goto out; + ++ if (addr->sin_family != AF_INET) ++ goto out; ++ + chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); + + /* Not specified by any standard per-se, however it breaks too +diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c +index 1fd3d9c..57ca93a 100644 +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -1169,20 +1169,18 @@ static void igmp_group_dropped(struct ip_mc_list *im) + + if (!in_dev->dead) { + if (IGMP_V1_SEEN(in_dev)) +- goto done; ++ return; + if (IGMP_V2_SEEN(in_dev)) { + if (reporter) + igmp_send_report(in_dev, im, IGMP_HOST_LEAVE_MESSAGE); +- goto done; ++ return; + } + /* IGMPv3 */ + igmpv3_add_delrec(in_dev, im); + + igmp_ifc_event(in_dev); + } +-done: + #endif +- ip_mc_clear_src(im); + } + + static void igmp_group_added(struct ip_mc_list *im) +@@ -1319,6 +1317,7 @@ void ip_mc_dec_group(struct in_device *in_dev, __be32 addr) + *ip = i->next_rcu; + in_dev->mc_count--; + igmp_group_dropped(i); ++ ip_mc_clear_src(i); + + if (!in_dev->dead) + ip_rt_multicast_event(in_dev); +@@ -1428,7 +1427,8 @@ void ip_mc_destroy_dev(struct in_device *in_dev) + in_dev->mc_list = i->next_rcu; + in_dev->mc_count--; + +- igmp_group_dropped(i); ++ /* We've dropped the groups in ip_mc_down already */ ++ ip_mc_clear_src(i); + ip_ma_put(i); + } + } +diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c +index 2ada171..65c23d9 100644 +--- a/net/ipv4/inet_diag.c ++++ b/net/ipv4/inet_diag.c +@@ -437,7 +437,7 @@ static int valid_cc(const void *bc, int len, int cc) + return 0; + if (cc == len) + return 1; +- if (op->yes < 4) ++ if (op->yes < 4 || op->yes & 3) + return 0; + len -= op->yes; + bc += op->yes; +@@ -447,11 +447,11 @@ static int valid_cc(const void *bc, int len, int cc) + + static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) + { +- const unsigned char *bc = bytecode; ++ const void *bc = bytecode; + int len = bytecode_len; + + while (len > 0) { +- struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)bc; ++ const struct inet_diag_bc_op *op = bc; + + //printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); + switch (op->code) { +@@ -462,22 +462,20 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) + case INET_DIAG_BC_S_LE: + case INET_DIAG_BC_D_GE: + case INET_DIAG_BC_D_LE: +- if (op->yes < 4 || op->yes > len + 4) +- return -EINVAL; + case INET_DIAG_BC_JMP: +- if (op->no < 4 || op->no > len + 4) ++ if (op->no < 4 || op->no > len + 4 || op->no & 3) + return -EINVAL; + if (op->no < len && + !valid_cc(bytecode, bytecode_len, len - op->no)) + return -EINVAL; + break; + case INET_DIAG_BC_NOP: +- if (op->yes < 4 || op->yes > len + 4) +- return -EINVAL; + break; + default: + return -EINVAL; + } ++ if (op->yes < 4 || op->yes > len + 4 || op->yes & 3) ++ return -EINVAL; + bc += op->yes; + len -= op->yes; + } +diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c +index 9df4e63..ce616d9 100644 +--- a/net/ipv4/inetpeer.c ++++ b/net/ipv4/inetpeer.c +@@ -154,11 +154,9 @@ void __init inet_initpeers(void) + /* Called with or without local BH being disabled. */ + static void unlink_from_unused(struct inet_peer *p) + { +- if (!list_empty(&p->unused)) { +- spin_lock_bh(&unused_peers.lock); +- list_del_init(&p->unused); +- spin_unlock_bh(&unused_peers.lock); +- } ++ spin_lock_bh(&unused_peers.lock); ++ list_del_init(&p->unused); ++ spin_unlock_bh(&unused_peers.lock); + } + + static int addr_compare(const struct inetpeer_addr *a, +@@ -205,6 +203,20 @@ static int addr_compare(const struct inetpeer_addr *a, + u; \ + }) + ++static bool atomic_add_unless_return(atomic_t *ptr, int a, int u, int *newv) ++{ ++ int cur, old = atomic_read(ptr); ++ ++ while (old != u) { ++ *newv = old + a; ++ cur = atomic_cmpxchg(ptr, old, *newv); ++ if (cur == old) ++ return true; ++ old = cur; ++ } ++ return false; ++} ++ + /* + * Called with rcu_read_lock() + * Because we hold no lock against a writer, its quite possible we fall +@@ -213,7 +225,8 @@ static int addr_compare(const struct inetpeer_addr *a, + * We exit from this function if number of links exceeds PEER_MAXDEPTH + */ + static struct inet_peer *lookup_rcu(const struct inetpeer_addr *daddr, +- struct inet_peer_base *base) ++ struct inet_peer_base *base, ++ int *newrefcnt) + { + struct inet_peer *u = rcu_dereference(base->root); + int count = 0; +@@ -226,7 +239,7 @@ static struct inet_peer *lookup_rcu(const struct inetpeer_addr *daddr, + * distinction between an unused entry (refcnt=0) and + * a freed one. + */ +- if (unlikely(!atomic_add_unless(&u->refcnt, 1, -1))) ++ if (!atomic_add_unless_return(&u->refcnt, 1, -1, newrefcnt)) + u = NULL; + return u; + } +@@ -465,22 +478,23 @@ struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) + struct inet_peer_base *base = family_to_base(daddr->family); + struct inet_peer *p; + unsigned int sequence; +- int invalidated; ++ int invalidated, newrefcnt = 0; + + /* Look up for the address quickly, lockless. + * Because of a concurrent writer, we might not find an existing entry. + */ + rcu_read_lock(); + sequence = read_seqbegin(&base->lock); +- p = lookup_rcu(daddr, base); ++ p = lookup_rcu(daddr, base, &newrefcnt); + invalidated = read_seqretry(&base->lock, sequence); + rcu_read_unlock(); + + if (p) { +- /* The existing node has been found. ++found: /* The existing node has been found. + * Remove the entry from unused list if it was there. + */ +- unlink_from_unused(p); ++ if (newrefcnt == 1) ++ unlink_from_unused(p); + return p; + } + +@@ -494,11 +508,9 @@ struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) + write_seqlock_bh(&base->lock); + p = lookup(daddr, stack, base); + if (p != peer_avl_empty) { +- atomic_inc(&p->refcnt); ++ newrefcnt = atomic_inc_return(&p->refcnt); + write_sequnlock_bh(&base->lock); +- /* Remove the entry from unused list if it was there. */ +- unlink_from_unused(p); +- return p; ++ goto found; + } + p = create ? kmem_cache_alloc(peer_cachep, GFP_ATOMIC) : NULL; + if (p) { +diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c +index 4614bab..2e97e3e 100644 +--- a/net/ipv4/netfilter.c ++++ b/net/ipv4/netfilter.c +@@ -17,51 +17,35 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) + const struct iphdr *iph = ip_hdr(skb); + struct rtable *rt; + struct flowi4 fl4 = {}; +- unsigned long orefdst; ++ __be32 saddr = iph->saddr; ++ __u8 flags = 0; + unsigned int hh_len; +- unsigned int type; + +- type = inet_addr_type(net, iph->saddr); +- if (skb->sk && inet_sk(skb->sk)->transparent) +- type = RTN_LOCAL; +- if (addr_type == RTN_UNSPEC) +- addr_type = type; ++ if (!skb->sk && addr_type != RTN_LOCAL) { ++ if (addr_type == RTN_UNSPEC) ++ addr_type = inet_addr_type(net, saddr); ++ if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) ++ flags |= FLOWI_FLAG_ANYSRC; ++ else ++ saddr = 0; ++ } + + /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause + * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. + */ +- if (addr_type == RTN_LOCAL) { +- fl4.daddr = iph->daddr; +- if (type == RTN_LOCAL) +- fl4.saddr = iph->saddr; +- fl4.flowi4_tos = RT_TOS(iph->tos); +- fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; +- fl4.flowi4_mark = skb->mark; +- fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; +- rt = ip_route_output_key(net, &fl4); +- if (IS_ERR(rt)) +- return -1; +- +- /* Drop old route. */ +- skb_dst_drop(skb); +- skb_dst_set(skb, &rt->dst); +- } else { +- /* non-local src, find valid iif to satisfy +- * rp-filter when calling ip_route_input. */ +- fl4.daddr = iph->saddr; +- rt = ip_route_output_key(net, &fl4); +- if (IS_ERR(rt)) +- return -1; ++ fl4.daddr = iph->daddr; ++ fl4.saddr = saddr; ++ fl4.flowi4_tos = RT_TOS(iph->tos); ++ fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; ++ fl4.flowi4_mark = skb->mark; ++ fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags; ++ rt = ip_route_output_key(net, &fl4); ++ if (IS_ERR(rt)) ++ return -1; + +- orefdst = skb->_skb_refdst; +- if (ip_route_input(skb, iph->daddr, iph->saddr, +- RT_TOS(iph->tos), rt->dst.dev) != 0) { +- dst_release(&rt->dst); +- return -1; +- } +- dst_release(&rt->dst); +- refdst_drop(orefdst); +- } ++ /* Drop old route. */ ++ skb_dst_drop(skb); ++ skb_dst_set(skb, &rt->dst); + + if (skb_dst(skb)->error) + return -1; +diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c +index 1ff79e5..51f13f8 100644 +--- a/net/ipv4/netfilter/ipt_REJECT.c ++++ b/net/ipv4/netfilter/ipt_REJECT.c +@@ -40,7 +40,6 @@ static void send_reset(struct sk_buff *oldskb, int hook) + struct iphdr *niph; + const struct tcphdr *oth; + struct tcphdr _otcph, *tcph; +- unsigned int addr_type; + + /* IP header checks: fragment. */ + if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET)) +@@ -55,6 +54,9 @@ static void send_reset(struct sk_buff *oldskb, int hook) + if (oth->rst) + return; + ++ if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) ++ return; ++ + /* Check checksum */ + if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP)) + return; +@@ -101,19 +103,11 @@ static void send_reset(struct sk_buff *oldskb, int hook) + nskb->csum_start = (unsigned char *)tcph - nskb->head; + nskb->csum_offset = offsetof(struct tcphdr, check); + +- addr_type = RTN_UNSPEC; +- if (hook != NF_INET_FORWARD +-#ifdef CONFIG_BRIDGE_NETFILTER +- || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED) +-#endif +- ) +- addr_type = RTN_LOCAL; +- + /* ip_route_me_harder expects skb->dst to be set */ + skb_dst_set_noref(nskb, skb_dst(oldskb)); + + nskb->protocol = htons(ETH_P_IP); +- if (ip_route_me_harder(nskb, addr_type)) ++ if (ip_route_me_harder(nskb, RTN_UNSPEC)) + goto free_nskb; + + niph->ttl = ip4_dst_hoplimit(skb_dst(nskb)); +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 99e6e4b..b8b5c3f 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1914,9 +1914,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, + + hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); + rth = rt_intern_hash(hash, rth, skb, dev->ifindex); +- err = 0; +- if (IS_ERR(rth)) +- err = PTR_ERR(rth); ++ return IS_ERR(rth) ? PTR_ERR(rth) : 0; + + e_nobufs: + return -ENOBUFS; +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index f87a8eb..0e33e34 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1241,6 +1241,9 @@ csum_copy_err: + + if (noblock) + return -EAGAIN; ++ ++ /* starting over for a new packet */ ++ msg->msg_flags &= ~MSG_TRUNC; + goto try_again; + } + +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 9e305d74..b31a2f3 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -453,8 +453,11 @@ csum_copy_err: + } + unlock_sock_fast(sk, slow); + +- if (flags & MSG_DONTWAIT) ++ if (noblock) + return -EAGAIN; ++ ++ /* starting over for a new packet */ ++ msg->msg_flags &= ~MSG_TRUNC; + goto try_again; + } + +diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c +index 4404973..3740403 100644 +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -228,11 +228,11 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, + goto out; + + if (pairwise) +- key = sta->ptk; ++ key = rcu_dereference(sta->ptk); + else if (key_idx < NUM_DEFAULT_KEYS) +- key = sta->gtk[key_idx]; ++ key = rcu_dereference(sta->gtk[key_idx]); + } else +- key = sdata->keys[key_idx]; ++ key = rcu_dereference(sdata->keys[key_idx]); + + if (!key) + goto out; +@@ -921,8 +921,10 @@ static int ieee80211_change_mpath(struct wiphy *wiphy, + static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, + struct mpath_info *pinfo) + { +- if (mpath->next_hop) +- memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN); ++ struct sta_info *next_hop_sta = rcu_dereference(mpath->next_hop); ++ ++ if (next_hop_sta) ++ memcpy(next_hop, next_hop_sta->sta.addr, ETH_ALEN); + else + memset(next_hop, 0, ETH_ALEN); + +diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c +index 3e81af1..821590d 100644 +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -967,6 +967,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) + + mutex_lock(&sdata->u.ibss.mtx); + ++ sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; ++ memset(sdata->u.ibss.bssid, 0, ETH_ALEN); ++ sdata->u.ibss.ssid_len = 0; ++ + active_ibss = ieee80211_sta_active_ibss(sdata); + + if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { +@@ -1000,8 +1004,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) + kfree_skb(skb); + + skb_queue_purge(&sdata->skb_queue); +- memset(sdata->u.ibss.bssid, 0, ETH_ALEN); +- sdata->u.ibss.ssid_len = 0; + + del_timer_sync(&sdata->u.ibss.timer); + +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index 64d92d5..7ffcb55 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -789,7 +789,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); + } + +- netif_tx_start_all_queues(sdata->dev); ++ netif_tx_wake_all_queues(sdata->dev); + } + + void ieee80211_dynamic_ps_timer(unsigned long data) +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index f1765de..3814b81 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -86,6 +86,11 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) + struct sk_buff *skb = rx->skb; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ int queue = rx->queue; ++ ++ /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */ ++ if (rx->queue == NUM_RX_DATA_QUEUES - 1) ++ queue = 0; + + /* No way to verify the MIC if the hardware stripped it */ + if (status->flag & RX_FLAG_MMIC_STRIPPED) +@@ -119,8 +124,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) + skb_trim(skb, skb->len - MICHAEL_MIC_LEN); + + /* update IV in key information to be able to detect replays */ +- rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; +- rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; ++ rx->key->u.tkip.rx[queue].iv32 = rx->tkip_iv32; ++ rx->key->u.tkip.rx[queue].iv16 = rx->tkip_iv16; + + return RX_CONTINUE; + } +@@ -201,6 +206,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) + struct ieee80211_key *key = rx->key; + struct sk_buff *skb = rx->skb; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); ++ int queue = rx->queue; ++ ++ /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */ ++ if (rx->queue == NUM_RX_DATA_QUEUES - 1) ++ queue = 0; + + hdrlen = ieee80211_hdrlen(hdr->frame_control); + +@@ -221,7 +231,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) + res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, + key, skb->data + hdrlen, + skb->len - hdrlen, rx->sta->sta.addr, +- hdr->addr1, hwaccel, rx->queue, ++ hdr->addr1, hwaccel, queue, + &rx->tkip_iv32, + &rx->tkip_iv16); + if (res != TKIP_DECRYPT_OK) +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index 72d1ac6..8041bef 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -815,7 +815,7 @@ ip_set_flush(struct sock *ctnl, struct sk_buff *skb, + ip_set_id_t i; + + if (unlikely(protocol_failed(attr))) +- return -EPROTO; ++ return -IPSET_ERR_PROTOCOL; + + if (!attr[IPSET_ATTR_SETNAME]) { + for (i = 0; i < ip_set_max; i++) +diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c +index bf28ac2..782db27 100644 +--- a/net/netfilter/ipvs/ip_vs_conn.c ++++ b/net/netfilter/ipvs/ip_vs_conn.c +@@ -776,8 +776,16 @@ static void ip_vs_conn_expire(unsigned long data) + if (cp->control) + ip_vs_control_del(cp); + +- if (cp->flags & IP_VS_CONN_F_NFCT) ++ if (cp->flags & IP_VS_CONN_F_NFCT) { + ip_vs_conn_drop_conntrack(cp); ++ /* Do not access conntracks during subsys cleanup ++ * because nf_conntrack_find_get can not be used after ++ * conntrack cleanup for the net. ++ */ ++ smp_rmb(); ++ if (ipvs->enable) ++ ip_vs_conn_drop_conntrack(cp); ++ } + + ip_vs_pe_put(cp->pe); + kfree(cp->pe_data); +diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c +index a74dae6..7729eae 100644 +--- a/net/netfilter/ipvs/ip_vs_core.c ++++ b/net/netfilter/ipvs/ip_vs_core.c +@@ -1965,6 +1965,7 @@ static void __net_exit __ip_vs_dev_cleanup(struct net *net) + { + EnterFunction(2); + net_ipvs(net)->enable = 0; /* Disable packet reception */ ++ smp_wmb(); + __ip_vs_sync_cleanup(net); + LeaveFunction(2); + } +diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c +index 6b5dd6d..af63553 100644 +--- a/net/netfilter/ipvs/ip_vs_ftp.c ++++ b/net/netfilter/ipvs/ip_vs_ftp.c +@@ -411,25 +411,35 @@ static struct ip_vs_app ip_vs_ftp = { + static int __net_init __ip_vs_ftp_init(struct net *net) + { + int i, ret; +- struct ip_vs_app *app = &ip_vs_ftp; ++ struct ip_vs_app *app; ++ struct netns_ipvs *ipvs = net_ipvs(net); ++ ++ app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL); ++ if (!app) ++ return -ENOMEM; ++ INIT_LIST_HEAD(&app->a_list); ++ INIT_LIST_HEAD(&app->incs_list); ++ ipvs->ftp_app = app; + + ret = register_ip_vs_app(net, app); + if (ret) +- return ret; ++ goto err_exit; + + for (i=0; i<IP_VS_APP_MAX_PORTS; i++) { + if (!ports[i]) + continue; + ret = register_ip_vs_app_inc(net, app, app->protocol, ports[i]); + if (ret) +- break; ++ goto err_unreg; + pr_info("%s: loaded support on port[%d] = %d\n", + app->name, i, ports[i]); + } ++ return 0; + +- if (ret) +- unregister_ip_vs_app(net, app); +- ++err_unreg: ++ unregister_ip_vs_app(net, app); ++err_exit: ++ kfree(ipvs->ftp_app); + return ret; + } + /* +@@ -437,9 +447,10 @@ static int __net_init __ip_vs_ftp_init(struct net *net) + */ + static void __ip_vs_ftp_exit(struct net *net) + { +- struct ip_vs_app *app = &ip_vs_ftp; ++ struct netns_ipvs *ipvs = net_ipvs(net); + +- unregister_ip_vs_app(net, app); ++ unregister_ip_vs_app(net, ipvs->ftp_app); ++ kfree(ipvs->ftp_app); + } + + static struct pernet_operations ip_vs_ftp_ops = { +diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c +index 237cc19..cb5a285 100644 +--- a/net/netfilter/nf_conntrack_sip.c ++++ b/net/netfilter/nf_conntrack_sip.c +@@ -1419,6 +1419,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, + const char *dptr, *end; + s16 diff, tdiff = 0; + int ret = NF_ACCEPT; ++ bool term; + typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust; + + if (ctinfo != IP_CT_ESTABLISHED && +@@ -1453,14 +1454,21 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, + if (dptr + matchoff == end) + break; + +- if (end + strlen("\r\n\r\n") > dptr + datalen) +- break; +- if (end[0] != '\r' || end[1] != '\n' || +- end[2] != '\r' || end[3] != '\n') ++ term = false; ++ for (; end + strlen("\r\n\r\n") <= dptr + datalen; end++) { ++ if (end[0] == '\r' && end[1] == '\n' && ++ end[2] == '\r' && end[3] == '\n') { ++ term = true; ++ break; ++ } ++ } ++ if (!term) + break; + end += strlen("\r\n\r\n") + clen; + + msglen = origlen = end - dptr; ++ if (msglen > datalen) ++ return NF_DROP; + + ret = process_sip_msg(skb, ct, dataoff, &dptr, &msglen); + if (ret != NF_ACCEPT) +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index b5362e9..04098c2 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -799,6 +799,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, + h.h2->tp_sec = ts.tv_sec; + h.h2->tp_nsec = ts.tv_nsec; + h.h2->tp_vlan_tci = vlan_tx_tag_get(skb); ++ h.h2->tp_padding = 0; + hdrlen = sizeof(*h.h2); + break; + default: +@@ -1727,6 +1728,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, + aux.tp_net = skb_network_offset(skb); + aux.tp_vlan_tci = vlan_tx_tag_get(skb); + ++ aux.tp_padding = 0; + put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); + } + +diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c +index c2e628d..6d96275 100644 +--- a/net/sched/sch_sfq.c ++++ b/net/sched/sch_sfq.c +@@ -361,7 +361,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) + { + struct sfq_sched_data *q = qdisc_priv(sch); + unsigned int hash; +- sfq_index x; ++ sfq_index x, qlen; + struct sfq_slot *slot; + int uninitialized_var(ret); + +@@ -405,20 +405,12 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) + if (++sch->q.qlen <= q->limit) + return NET_XMIT_SUCCESS; + ++ qlen = slot->qlen; + sfq_drop(sch); +- return NET_XMIT_CN; +-} +- +-static struct sk_buff * +-sfq_peek(struct Qdisc *sch) +-{ +- struct sfq_sched_data *q = qdisc_priv(sch); +- +- /* No active slots */ +- if (q->tail == NULL) +- return NULL; +- +- return q->slots[q->tail->next].skblist_next; ++ /* Return Congestion Notification only if we dropped a packet ++ * from this flow. ++ */ ++ return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS; + } + + static struct sk_buff * +@@ -702,7 +694,7 @@ static struct Qdisc_ops sfq_qdisc_ops __read_mostly = { + .priv_size = sizeof(struct sfq_sched_data), + .enqueue = sfq_enqueue, + .dequeue = sfq_dequeue, +- .peek = sfq_peek, ++ .peek = qdisc_peek_dequeued, + .drop = sfq_drop, + .init = sfq_init, + .reset = sfq_reset, +diff --git a/net/sctp/associola.c b/net/sctp/associola.c +index 1a21c57..525f97c 100644 +--- a/net/sctp/associola.c ++++ b/net/sctp/associola.c +@@ -64,6 +64,7 @@ + /* Forward declarations for internal functions. */ + static void sctp_assoc_bh_rcv(struct work_struct *work); + static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc); ++static void sctp_assoc_free_asconf_queue(struct sctp_association *asoc); + + /* Keep track of the new idr low so that we don't re-use association id + * numbers too fast. It is protected by they idr spin lock is in the +@@ -446,6 +447,9 @@ void sctp_association_free(struct sctp_association *asoc) + /* Free any cached ASCONF_ACK chunk. */ + sctp_assoc_free_asconf_acks(asoc); + ++ /* Free the ASCONF queue. */ ++ sctp_assoc_free_asconf_queue(asoc); ++ + /* Free any cached ASCONF chunk. */ + if (asoc->addip_last_asconf) + sctp_chunk_free(asoc->addip_last_asconf); +@@ -1578,6 +1582,18 @@ retry: + return error; + } + ++/* Free the ASCONF queue */ ++static void sctp_assoc_free_asconf_queue(struct sctp_association *asoc) ++{ ++ struct sctp_chunk *asconf; ++ struct sctp_chunk *tmp; ++ ++ list_for_each_entry_safe(asconf, tmp, &asoc->addip_chunk_list, list) { ++ list_del_init(&asconf->list); ++ sctp_chunk_free(asconf); ++ } ++} ++ + /* Free asconf_ack cache */ + static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc) + { +diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c +index faf71d1..6150ac5 100644 +--- a/net/sctp/bind_addr.c ++++ b/net/sctp/bind_addr.c +@@ -140,14 +140,12 @@ void sctp_bind_addr_init(struct sctp_bind_addr *bp, __u16 port) + /* Dispose of the address list. */ + static void sctp_bind_addr_clean(struct sctp_bind_addr *bp) + { +- struct sctp_sockaddr_entry *addr; +- struct list_head *pos, *temp; ++ struct sctp_sockaddr_entry *addr, *temp; + + /* Empty the bind address list. */ +- list_for_each_safe(pos, temp, &bp->address_list) { +- addr = list_entry(pos, struct sctp_sockaddr_entry, list); +- list_del(pos); +- kfree(addr); ++ list_for_each_entry_safe(addr, temp, &bp->address_list, list) { ++ list_del_rcu(&addr->list); ++ call_rcu(&addr->rcu, sctp_local_addr_free); + SCTP_DBG_OBJCNT_DEC(addr); + } + } +diff --git a/net/socket.c b/net/socket.c +index 310d16b..65b2310 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -2122,14 +2122,16 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, + */ + if (MSG_CMSG_COMPAT & flags) { + err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry, +- &msg_sys, flags, datagrams); ++ &msg_sys, flags & ~MSG_WAITFORONE, ++ datagrams); + if (err < 0) + break; + err = __put_user(err, &compat_entry->msg_len); + ++compat_entry; + } else { + err = __sys_recvmsg(sock, (struct msghdr __user *)entry, +- &msg_sys, flags, datagrams); ++ &msg_sys, flags & ~MSG_WAITFORONE, ++ datagrams); + if (err < 0) + break; + err = put_user(err, &entry->msg_len); +diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c +index 339ba64..5daf6cc 100644 +--- a/net/sunrpc/auth_gss/auth_gss.c ++++ b/net/sunrpc/auth_gss/auth_gss.c +@@ -577,13 +577,13 @@ retry: + } + inode = &gss_msg->inode->vfs_inode; + for (;;) { +- prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE); ++ prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE); + spin_lock(&inode->i_lock); + if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { + break; + } + spin_unlock(&inode->i_lock); +- if (signalled()) { ++ if (fatal_signal_pending(current)) { + err = -ERESTARTSYS; + goto out_intr; + } +diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c +index 0a9a2ec..c3b7533 100644 +--- a/net/sunrpc/auth_gss/gss_krb5_mech.c ++++ b/net/sunrpc/auth_gss/gss_krb5_mech.c +@@ -43,6 +43,7 @@ + #include <linux/sunrpc/gss_krb5.h> + #include <linux/sunrpc/xdr.h> + #include <linux/crypto.h> ++#include <linux/sunrpc/gss_krb5_enctypes.h> + + #ifdef RPC_DEBUG + # define RPCDBG_FACILITY RPCDBG_AUTH +@@ -750,7 +751,7 @@ static struct gss_api_mech gss_kerberos_mech = { + .gm_ops = &gss_kerberos_ops, + .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs), + .gm_pfs = gss_kerberos_pfs, +- .gm_upcall_enctypes = "18,17,16,23,3,1,2", ++ .gm_upcall_enctypes = KRB5_SUPPORTED_ENCTYPES, + }; + + static int __init init_kerberos_module(void) +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index 8d83f9d..00df09b 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -1058,7 +1058,7 @@ call_allocate(struct rpc_task *task) + + dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid); + +- if (RPC_IS_ASYNC(task) || !signalled()) { ++ if (RPC_IS_ASYNC(task) || !fatal_signal_pending(current)) { + task->tk_action = call_allocate; + rpc_delay(task, HZ>>4); + return; +@@ -1172,6 +1172,9 @@ call_bind_status(struct rpc_task *task) + status = -EOPNOTSUPP; + break; + } ++ if (task->tk_rebind_retry == 0) ++ break; ++ task->tk_rebind_retry--; + rpc_delay(task, 3*HZ); + goto retry_timeout; + case -ETIMEDOUT: +diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c +index c652e4c..9574bc4 100644 +--- a/net/sunrpc/rpcb_clnt.c ++++ b/net/sunrpc/rpcb_clnt.c +@@ -528,7 +528,7 @@ void rpcb_getport_async(struct rpc_task *task) + u32 bind_version; + struct rpc_xprt *xprt; + struct rpc_clnt *rpcb_clnt; +- static struct rpcbind_args *map; ++ struct rpcbind_args *map; + struct rpc_task *child; + struct sockaddr_storage addr; + struct sockaddr *sap = (struct sockaddr *)&addr; +diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c +index 6b43ee7..4814e24 100644 +--- a/net/sunrpc/sched.c ++++ b/net/sunrpc/sched.c +@@ -616,30 +616,25 @@ static void __rpc_execute(struct rpc_task *task) + BUG_ON(RPC_IS_QUEUED(task)); + + for (;;) { ++ void (*do_action)(struct rpc_task *); + + /* +- * Execute any pending callback. ++ * Execute any pending callback first. + */ +- if (task->tk_callback) { +- void (*save_callback)(struct rpc_task *); +- +- /* +- * We set tk_callback to NULL before calling it, +- * in case it sets the tk_callback field itself: +- */ +- save_callback = task->tk_callback; +- task->tk_callback = NULL; +- save_callback(task); +- } else { ++ do_action = task->tk_callback; ++ task->tk_callback = NULL; ++ if (do_action == NULL) { + /* + * Perform the next FSM step. +- * tk_action may be NULL when the task has been killed +- * by someone else. ++ * tk_action may be NULL if the task has been killed. ++ * In particular, note that rpc_killall_tasks may ++ * do this at any time, so beware when dereferencing. + */ +- if (task->tk_action == NULL) ++ do_action = task->tk_action; ++ if (do_action == NULL) + break; +- task->tk_action(task); + } ++ do_action(task); + + /* + * Lockless check for whether task is sleeping or not. +@@ -792,6 +787,7 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta + /* Initialize retry counters */ + task->tk_garb_retry = 2; + task->tk_cred_retry = 2; ++ task->tk_rebind_retry = 2; + + task->tk_priority = task_setup_data->priority - RPC_PRIORITY_LOW; + task->tk_owner = current->tgid; +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index bf005d3..f34f5ab 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -1344,7 +1344,6 @@ static void xs_tcp_state_change(struct sock *sk) + case TCP_CLOSE_WAIT: + /* The server initiated a shutdown of the socket */ + xprt_force_disconnect(xprt); +- case TCP_SYN_SENT: + xprt->connect_cookie++; + case TCP_CLOSING: + /* +@@ -1758,6 +1757,7 @@ static void xs_tcp_reuse_connection(struct sock_xprt *transport) + static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) + { + struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); ++ int ret = -ENOTCONN; + + if (!transport->inet) { + struct sock *sk = sock->sk; +@@ -1789,12 +1789,22 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) + } + + if (!xprt_bound(xprt)) +- return -ENOTCONN; ++ goto out; + + /* Tell the socket layer to start connecting... */ + xprt->stat.connect_count++; + xprt->stat.connect_start = jiffies; +- return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); ++ ret = kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); ++ switch (ret) { ++ case 0: ++ case -EINPROGRESS: ++ /* SYN_SENT! */ ++ xprt->connect_cookie++; ++ if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) ++ xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; ++ } ++out: ++ return ret; + } + + /** +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 4ebce42..29a1ce1 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -1679,14 +1679,6 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) + if (err) + goto out; + +- if (!(rdev->wiphy.flags & +- WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) { +- if (!key.def_uni || !key.def_multi) { +- err = -EOPNOTSUPP; +- goto out; +- } +- } +- + err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx, + key.def_uni, key.def_multi); + +@@ -3247,12 +3239,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) + i = 0; + if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { + nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { ++ request->ssids[i].ssid_len = nla_len(attr); + if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) { + err = -EINVAL; + goto out_free; + } + memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr)); +- request->ssids[i].ssid_len = nla_len(attr); + i++; + } + } +diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c +index 47f1b86..b11ea69 100644 +--- a/net/xfrm/xfrm_replay.c ++++ b/net/xfrm/xfrm_replay.c +@@ -265,7 +265,7 @@ static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq) + bitnr = bitnr & 0x1F; + replay_esn->bmp[nr] |= (1U << bitnr); + } else { +- nr = replay_esn->replay_window >> 5; ++ nr = (replay_esn->replay_window - 1) >> 5; + for (i = 0; i <= nr; i++) + replay_esn->bmp[i] = 0; + +@@ -471,7 +471,7 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq) + bitnr = bitnr & 0x1F; + replay_esn->bmp[nr] |= (1U << bitnr); + } else { +- nr = replay_esn->replay_window >> 5; ++ nr = (replay_esn->replay_window - 1) >> 5; + for (i = 0; i <= nr; i++) + replay_esn->bmp[i] = 0; + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index ae3a698..3d2fd14 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -593,7 +593,8 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, + sa.aad.op = OP_SETPROCATTR; + sa.aad.info = name; + sa.aad.error = -EINVAL; +- return aa_audit(AUDIT_APPARMOR_DENIED, NULL, GFP_KERNEL, ++ return aa_audit(AUDIT_APPARMOR_DENIED, ++ __aa_current_profile(), GFP_KERNEL, + &sa, NULL); + } + } else if (strcmp(name, "exec") == 0) { +@@ -611,7 +612,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, + static int apparmor_task_setrlimit(struct task_struct *task, + unsigned int resource, struct rlimit *new_rlim) + { +- struct aa_profile *profile = aa_current_profile(); ++ struct aa_profile *profile = __aa_current_profile(); + int error = 0; + + if (!unconfined(profile)) +diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c +index 930634e..7a0c586 100644 +--- a/security/keys/process_keys.c ++++ b/security/keys/process_keys.c +@@ -845,6 +845,7 @@ void key_replace_session_keyring(void) + new-> sgid = old-> sgid; + new->fsgid = old->fsgid; + new->user = get_uid(old->user); ++ new->user_ns = new->user->user_ns; + new->group_info = get_group_info(old->group_info); + + new->securebits = old->securebits; +diff --git a/security/keys/request_key.c b/security/keys/request_key.c +index df3c041..6197a26 100644 +--- a/security/keys/request_key.c ++++ b/security/keys/request_key.c +@@ -470,7 +470,7 @@ static struct key *construct_key_and_link(struct key_type *type, + } else if (ret == -EINPROGRESS) { + ret = 0; + } else { +- key = ERR_PTR(ret); ++ goto couldnt_alloc_key; + } + + key_put(dest_keyring); +@@ -480,6 +480,7 @@ static struct key *construct_key_and_link(struct key_type *type, + construction_failed: + key_negate_and_link(key, key_negative_timeout, NULL, NULL); + key_put(key); ++couldnt_alloc_key: + key_put(dest_keyring); + kleave(" = %d", ret); + return ERR_PTR(ret); +diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c +index 82bf8c2..afa07cf 100644 +--- a/security/tomoyo/mount.c ++++ b/security/tomoyo/mount.c +@@ -138,7 +138,7 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name, + } + if (need_dev) { + /* Get mount point or device file. */ +- if (kern_path(dev_name, LOOKUP_FOLLOW, &path)) { ++ if (!dev_name || kern_path(dev_name, LOOKUP_FOLLOW, &path)) { + error = -ENOENT; + goto out; + } +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index 70a9d32..f5cad7c 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2349,9 +2349,16 @@ static int __devinit check_position_fix(struct azx *chip, int fix) + /* Check VIA/ATI HD Audio Controller exist */ + switch (chip->driver_type) { + case AZX_DRIVER_VIA: +- case AZX_DRIVER_ATI: + /* Use link position directly, avoid any transfer problem. */ + return POS_FIX_VIACOMBO; ++ case AZX_DRIVER_ATI: ++ /* ATI chipsets don't work well with position-buffer */ ++ return POS_FIX_LPIB; ++ case AZX_DRIVER_GENERIC: ++ /* AMD chipsets also don't work with position-buffer */ ++ if (chip->pci->vendor == PCI_VENDOR_ID_AMD) ++ return POS_FIX_LPIB; ++ break; + } + + return POS_FIX_AUTO; +diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c +index 2942d2a..9f886bf 100644 +--- a/sound/pci/hda/patch_analog.c ++++ b/sound/pci/hda/patch_analog.c +@@ -3070,6 +3070,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec) + + for (i = 0; i < cfg->num_inputs; i++) { + hda_nid_t nid = cfg->inputs[i].pin; ++ int type = cfg->inputs[i].type; + switch (nid) { + case 0x15: /* port-C */ + snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0); +@@ -3079,7 +3080,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec) + break; + } + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, +- i == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN); ++ type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN); + if (nid != AD1988_PIN_CD_NID) + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_MUTE); +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index ad97d93..e47f22c 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -3036,6 +3036,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), + SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), + SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), ++ SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), + SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), + SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ + {} +@@ -3845,6 +3846,8 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = { + .patch = patch_cxt5066 }, + { .id = 0x14f15069, .name = "CX20585", + .patch = patch_cxt5066 }, ++ { .id = 0x14f1506c, .name = "CX20588", ++ .patch = patch_cxt5066 }, + { .id = 0x14f1506e, .name = "CX20590", + .patch = patch_cxt5066 }, + { .id = 0x14f15097, .name = "CX20631", +@@ -3873,6 +3876,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15066"); + MODULE_ALIAS("snd-hda-codec-id:14f15067"); + MODULE_ALIAS("snd-hda-codec-id:14f15068"); + MODULE_ALIAS("snd-hda-codec-id:14f15069"); ++MODULE_ALIAS("snd-hda-codec-id:14f1506c"); + MODULE_ALIAS("snd-hda-codec-id:14f1506e"); + MODULE_ALIAS("snd-hda-codec-id:14f15097"); + MODULE_ALIAS("snd-hda-codec-id:14f15098"); +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index c82979a..4145c3c 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -4607,7 +4607,6 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { + SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), + SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), + SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), +- SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), + SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), + SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), + SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), +@@ -13804,6 +13803,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", + ALC268_ACER_ASPIRE_ONE), + SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), ++ SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO), + SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, + "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), + /* almost compatible with toshiba but with optional digital outs; +diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c +index 94d19c0..1e32235 100644 +--- a/sound/pci/hda/patch_sigmatel.c ++++ b/sound/pci/hda/patch_sigmatel.c +@@ -1600,7 +1600,7 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe, + "Dell Studio XPS 1645", STAC_DELL_M6_BOTH), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, +- "Dell Studio 1558", STAC_DELL_M6_BOTH), ++ "Dell Studio 1558", STAC_DELL_M6_DMIC), + {} /* terminator */ + }; + +diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c +index 890a0dc..bd11e33 100644 +--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c ++++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c +@@ -138,11 +138,20 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream) + pr_debug("%s enter\n", __func__); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + diff = sport_curr_offset_tx(sport); +- frames = bytes_to_frames(substream->runtime, diff); + } else { + diff = sport_curr_offset_rx(sport); +- frames = bytes_to_frames(substream->runtime, diff); + } ++ ++ /* ++ * TX at least can report one frame beyond the end of the ++ * buffer if we hit the wraparound case - clamp to within the ++ * buffer as the ALSA APIs require. ++ */ ++ if (diff == snd_pcm_lib_buffer_bytes(substream)) ++ diff = 0; ++ ++ frames = bytes_to_frames(substream->runtime, diff); ++ + return frames; + } + +diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c +index ab63d52..754c496 100644 +--- a/sound/soc/codecs/ad1836.c ++++ b/sound/soc/codecs/ad1836.c +@@ -145,22 +145,22 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream, + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: +- word_len = 3; ++ word_len = AD1836_WORD_LEN_16; + break; + case SNDRV_PCM_FORMAT_S20_3LE: +- word_len = 1; ++ word_len = AD1836_WORD_LEN_20; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S32_LE: +- word_len = 0; ++ word_len = AD1836_WORD_LEN_24; + break; + } + +- snd_soc_update_bits(codec, AD1836_DAC_CTRL1, +- AD1836_DAC_WORD_LEN_MASK, word_len); ++ snd_soc_update_bits(codec, AD1836_DAC_CTRL1, AD1836_DAC_WORD_LEN_MASK, ++ word_len << AD1836_DAC_WORD_LEN_OFFSET); + +- snd_soc_update_bits(codec, AD1836_ADC_CTRL2, +- AD1836_ADC_WORD_LEN_MASK, word_len); ++ snd_soc_update_bits(codec, AD1836_ADC_CTRL2, AD1836_ADC_WORD_LEN_MASK, ++ word_len << AD1836_ADC_WORD_OFFSET); + + return 0; + } +diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h +index 8455967..9d6a3f8 100644 +--- a/sound/soc/codecs/ad1836.h ++++ b/sound/soc/codecs/ad1836.h +@@ -25,6 +25,7 @@ + #define AD1836_DAC_SERFMT_PCK256 (0x4 << 5) + #define AD1836_DAC_SERFMT_PCK128 (0x5 << 5) + #define AD1836_DAC_WORD_LEN_MASK 0x18 ++#define AD1836_DAC_WORD_LEN_OFFSET 3 + + #define AD1836_DAC_CTRL2 1 + #define AD1836_DACL1_MUTE 0 +@@ -51,6 +52,7 @@ + #define AD1836_ADCL2_MUTE 2 + #define AD1836_ADCR2_MUTE 3 + #define AD1836_ADC_WORD_LEN_MASK 0x30 ++#define AD1836_ADC_WORD_OFFSET 5 + #define AD1836_ADC_SERFMT_MASK (7 << 6) + #define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) + #define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) +@@ -60,4 +62,8 @@ + + #define AD1836_NUM_REGS 16 + ++#define AD1836_WORD_LEN_24 0x0 ++#define AD1836_WORD_LEN_20 0x1 ++#define AD1836_WORD_LEN_16 0x2 ++ + #endif +diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c +index 4be0570..65f4604 100644 +--- a/sound/soc/codecs/ak4642.c ++++ b/sound/soc/codecs/ak4642.c +@@ -357,7 +357,7 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) + default: + return -EINVAL; + } +- snd_soc_update_bits(codec, PW_MGMT2, MS, data); ++ snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data); + snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko); + + /* format type */ +diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c +index 6785688..9a5e67c 100644 +--- a/sound/soc/codecs/wm8804.c ++++ b/sound/soc/codecs/wm8804.c +@@ -680,20 +680,25 @@ static struct snd_soc_dai_ops wm8804_dai_ops = { + #define WM8804_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + ++#define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ ++ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ ++ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \ ++ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000) ++ + static struct snd_soc_dai_driver wm8804_dai = { + .name = "wm8804-spdif", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, +- .rates = SNDRV_PCM_RATE_8000_192000, ++ .rates = WM8804_RATES, + .formats = WM8804_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 2, +- .rates = SNDRV_PCM_RATE_8000_192000, ++ .rates = WM8804_RATES, + .formats = WM8804_FORMATS, + }, + .ops = &wm8804_dai_ops, +diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c +index 500011e..c22659e 100644 +--- a/sound/soc/codecs/wm8962.c ++++ b/sound/soc/codecs/wm8962.c +@@ -1998,12 +1998,12 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, + return 0; + + /* If the left PGA is enabled hit that VU bit... */ +- if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_HPOUTL_PGA_ENA) ++ if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTL_PGA_ENA) + return snd_soc_write(codec, WM8962_HPOUTL_VOLUME, + reg_cache[WM8962_HPOUTL_VOLUME]); + + /* ...otherwise the right. The VU is stereo. */ +- if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_HPOUTR_PGA_ENA) ++ if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTR_PGA_ENA) + return snd_soc_write(codec, WM8962_HPOUTR_VOLUME, + reg_cache[WM8962_HPOUTR_VOLUME]); + +diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c +index 84e1bd1..89acb0f 100644 +--- a/sound/soc/codecs/wm8994.c ++++ b/sound/soc/codecs/wm8994.c +@@ -1446,7 +1446,6 @@ SND_SOC_DAPM_INPUT("DMIC1DAT"), + SND_SOC_DAPM_INPUT("DMIC2DAT"), + SND_SOC_DAPM_INPUT("Clock"), + +-SND_SOC_DAPM_MICBIAS("MICBIAS", WM8994_MICBIAS, 2, 0), + SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev, + SND_SOC_DAPM_PRE_PMU), + +@@ -1765,8 +1764,10 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = { + { "AIF2DACDAT", NULL, "AIF1DACDAT" }, + { "AIF1ADCDAT", NULL, "AIF2ADCDAT" }, + { "AIF2ADCDAT", NULL, "AIF1ADCDAT" }, +- { "MICBIAS", NULL, "CLK_SYS" }, +- { "MICBIAS", NULL, "MICBIAS Supply" }, ++ { "MICBIAS1", NULL, "CLK_SYS" }, ++ { "MICBIAS1", NULL, "MICBIAS Supply" }, ++ { "MICBIAS2", NULL, "CLK_SYS" }, ++ { "MICBIAS2", NULL, "MICBIAS Supply" }, + }; + + static const struct snd_soc_dapm_route wm8994_intercon[] = { +@@ -1969,6 +1970,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, + snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, + WM8994_FLL1_ENA | WM8994_FLL1_FRAC, + reg); ++ ++ msleep(5); + } + + wm8994->fll[id].in = freq_in; +@@ -3018,7 +3021,7 @@ static void wm8958_default_micdet(u16 status, void *data) + report = SND_JACK_MICROPHONE; + + /* Everything else is buttons; just assign slots */ +- if (status & 0x1c0) ++ if (status & 0x1c) + report |= SND_JACK_BTN_0; + + done: +diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c +index 4005e9a..e55b298 100644 +--- a/sound/soc/codecs/wm_hubs.c ++++ b/sound/soc/codecs/wm_hubs.c +@@ -787,17 +787,17 @@ static const struct snd_soc_dapm_route analogue_routes[] = { + static const struct snd_soc_dapm_route lineout1_diff_routes[] = { + { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" }, + { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" }, +- { "LINEOUT1 Mixer", "Output Switch", "Left Output Mixer" }, ++ { "LINEOUT1 Mixer", "Output Switch", "Left Output PGA" }, + + { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" }, + { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" }, + }; + + static const struct snd_soc_dapm_route lineout1_se_routes[] = { +- { "LINEOUT1N Mixer", "Left Output Switch", "Left Output Mixer" }, +- { "LINEOUT1N Mixer", "Right Output Switch", "Left Output Mixer" }, ++ { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" }, ++ { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" }, + +- { "LINEOUT1P Mixer", "Left Output Switch", "Left Output Mixer" }, ++ { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" }, + + { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, + { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" }, +@@ -806,17 +806,17 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = { + static const struct snd_soc_dapm_route lineout2_diff_routes[] = { + { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, + { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, +- { "LINEOUT2 Mixer", "Output Switch", "Right Output Mixer" }, ++ { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" }, + + { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, + { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" }, + }; + + static const struct snd_soc_dapm_route lineout2_se_routes[] = { +- { "LINEOUT2N Mixer", "Left Output Switch", "Left Output Mixer" }, +- { "LINEOUT2N Mixer", "Right Output Switch", "Left Output Mixer" }, ++ { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" }, ++ { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" }, + +- { "LINEOUT2P Mixer", "Right Output Switch", "Right Output Mixer" }, ++ { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" }, + + { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, + { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" }, +@@ -836,17 +836,21 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec) + snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, + WM8993_IN2_VU, WM8993_IN2_VU); + ++ snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_LEFT, ++ WM8993_SPKOUT_VU, WM8993_SPKOUT_VU); + snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT, + WM8993_SPKOUT_VU, WM8993_SPKOUT_VU); + + snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME, +- WM8993_HPOUT1L_ZC, WM8993_HPOUT1L_ZC); ++ WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC, ++ WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC); + snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME, + WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC, + WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC); + + snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME, +- WM8993_MIXOUTL_ZC, WM8993_MIXOUTL_ZC); ++ WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU, ++ WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU); + snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME, + WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, + WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); +diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c +index 2ce0b2d..fab20a5 100644 +--- a/sound/soc/pxa/pxa2xx-pcm.c ++++ b/sound/soc/pxa/pxa2xx-pcm.c +@@ -95,14 +95,14 @@ static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + +- if (dai->driver->playback.channels_min) { ++ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { + ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_PLAYBACK); + if (ret) + goto out; + } + +- if (dai->driver->capture.channels_min) { ++ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { + ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_CAPTURE); + if (ret) +diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c +index 2afabaf..1a591f1 100644 +--- a/sound/soc/pxa/raumfeld.c ++++ b/sound/soc/pxa/raumfeld.c +@@ -151,13 +151,13 @@ static struct snd_soc_ops raumfeld_cs4270_ops = { + .hw_params = raumfeld_cs4270_hw_params, + }; + +-static int raumfeld_line_suspend(struct snd_soc_card *card) ++static int raumfeld_analog_suspend(struct snd_soc_card *card) + { + raumfeld_enable_audio(false); + return 0; + } + +-static int raumfeld_line_resume(struct snd_soc_card *card) ++static int raumfeld_analog_resume(struct snd_soc_card *card) + { + raumfeld_enable_audio(true); + return 0; +@@ -225,32 +225,53 @@ static struct snd_soc_ops raumfeld_ak4104_ops = { + .hw_params = raumfeld_ak4104_hw_params, + }; + +-static struct snd_soc_dai_link raumfeld_dai[] = { ++#define DAI_LINK_CS4270 \ ++{ \ ++ .name = "CS4270", \ ++ .stream_name = "CS4270", \ ++ .cpu_dai_name = "pxa-ssp-dai.0", \ ++ .platform_name = "pxa-pcm-audio", \ ++ .codec_dai_name = "cs4270-hifi", \ ++ .codec_name = "cs4270-codec.0-0048", \ ++ .ops = &raumfeld_cs4270_ops, \ ++} ++ ++#define DAI_LINK_AK4104 \ ++{ \ ++ .name = "ak4104", \ ++ .stream_name = "Playback", \ ++ .cpu_dai_name = "pxa-ssp-dai.1", \ ++ .codec_dai_name = "ak4104-hifi", \ ++ .platform_name = "pxa-pcm-audio", \ ++ .ops = &raumfeld_ak4104_ops, \ ++ .codec_name = "spi0.0", \ ++} ++ ++static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] = + { +- .name = "ak4104", +- .stream_name = "Playback", +- .cpu_dai_name = "pxa-ssp-dai.1", +- .codec_dai_name = "ak4104-hifi", +- .platform_name = "pxa-pcm-audio", +- .ops = &raumfeld_ak4104_ops, +- .codec_name = "ak4104-codec.0", +-}, ++ DAI_LINK_CS4270, ++ DAI_LINK_AK4104, ++}; ++ ++static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] = + { +- .name = "CS4270", +- .stream_name = "CS4270", +- .cpu_dai_name = "pxa-ssp-dai.0", +- .platform_name = "pxa-pcm-audio", +- .codec_dai_name = "cs4270-hifi", +- .codec_name = "cs4270-codec.0-0048", +- .ops = &raumfeld_cs4270_ops, +-},}; +- +-static struct snd_soc_card snd_soc_raumfeld = { +- .name = "Raumfeld", +- .dai_link = raumfeld_dai, +- .suspend_post = raumfeld_line_suspend, +- .resume_pre = raumfeld_line_resume, +- .num_links = ARRAY_SIZE(raumfeld_dai), ++ DAI_LINK_CS4270, ++}; ++ ++static struct snd_soc_card snd_soc_raumfeld_connector = { ++ .name = "Raumfeld Connector", ++ .dai_link = snd_soc_raumfeld_connector_dai, ++ .num_links = ARRAY_SIZE(snd_soc_raumfeld_connector_dai), ++ .suspend_post = raumfeld_analog_suspend, ++ .resume_pre = raumfeld_analog_resume, ++}; ++ ++static struct snd_soc_card snd_soc_raumfeld_speaker = { ++ .name = "Raumfeld Speaker", ++ .dai_link = snd_soc_raumfeld_speaker_dai, ++ .num_links = ARRAY_SIZE(snd_soc_raumfeld_speaker_dai), ++ .suspend_post = raumfeld_analog_suspend, ++ .resume_pre = raumfeld_analog_resume, + }; + + static struct platform_device *raumfeld_audio_device; +@@ -271,22 +292,25 @@ static int __init raumfeld_audio_init(void) + + set_max9485_clk(MAX9485_MCLK_FREQ_122880); + +- /* Register LINE and SPDIF */ ++ /* Register analog device */ + raumfeld_audio_device = platform_device_alloc("soc-audio", 0); + if (!raumfeld_audio_device) + return -ENOMEM; + +- platform_set_drvdata(raumfeld_audio_device, +- &snd_soc_raumfeld); +- ret = platform_device_add(raumfeld_audio_device); +- +- /* no S/PDIF on Speakers */ + if (machine_is_raumfeld_speaker()) ++ platform_set_drvdata(raumfeld_audio_device, ++ &snd_soc_raumfeld_speaker); ++ ++ if (machine_is_raumfeld_connector()) ++ platform_set_drvdata(raumfeld_audio_device, ++ &snd_soc_raumfeld_connector); ++ ++ ret = platform_device_add(raumfeld_audio_device); ++ if (ret < 0) + return ret; + + raumfeld_enable_audio(true); +- +- return ret; ++ return 0; + } + + static void __exit raumfeld_audio_exit(void) +diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c +index ffa09b3..992a732 100644 +--- a/sound/soc/samsung/i2s.c ++++ b/sound/soc/samsung/i2s.c +@@ -191,7 +191,7 @@ static inline bool tx_active(struct i2s_dai *i2s) + if (!i2s) + return false; + +- active = readl(i2s->addr + I2SMOD); ++ active = readl(i2s->addr + I2SCON); + + if (is_secondary(i2s)) + active &= CON_TXSDMA_ACTIVE; +@@ -223,7 +223,7 @@ static inline bool rx_active(struct i2s_dai *i2s) + if (!i2s) + return false; + +- active = readl(i2s->addr + I2SMOD) & CON_RXDMA_ACTIVE; ++ active = readl(i2s->addr + I2SCON) & CON_RXDMA_ACTIVE; + + return active ? true : false; + } +diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c +index 81c4052..586d10b 100644 +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -362,9 +362,9 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) + } + + /* create new dapm mixer control */ +-static int dapm_new_mixer(struct snd_soc_dapm_context *dapm, +- struct snd_soc_dapm_widget *w) ++static int dapm_new_mixer(struct snd_soc_dapm_widget *w) + { ++ struct snd_soc_dapm_context *dapm = w->dapm; + int i, ret = 0; + size_t name_len, prefix_len; + struct snd_soc_dapm_path *path; +@@ -443,9 +443,9 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm, + } + + /* create new dapm mux control */ +-static int dapm_new_mux(struct snd_soc_dapm_context *dapm, +- struct snd_soc_dapm_widget *w) ++static int dapm_new_mux(struct snd_soc_dapm_widget *w) + { ++ struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_dapm_path *path = NULL; + struct snd_kcontrol *kcontrol; + struct snd_card *card = dapm->card->snd_card; +@@ -490,8 +490,7 @@ err: + } + + /* create new dapm volume control */ +-static int dapm_new_pga(struct snd_soc_dapm_context *dapm, +- struct snd_soc_dapm_widget *w) ++static int dapm_new_pga(struct snd_soc_dapm_widget *w) + { + if (w->num_kcontrols) + dev_err(w->dapm->dev, +@@ -1735,13 +1734,13 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) + case snd_soc_dapm_mixer: + case snd_soc_dapm_mixer_named_ctl: + w->power_check = dapm_generic_check_power; +- dapm_new_mixer(dapm, w); ++ dapm_new_mixer(w); + break; + case snd_soc_dapm_mux: + case snd_soc_dapm_virt_mux: + case snd_soc_dapm_value_mux: + w->power_check = dapm_generic_check_power; +- dapm_new_mux(dapm, w); ++ dapm_new_mux(w); + break; + case snd_soc_dapm_adc: + case snd_soc_dapm_aif_out: +@@ -1754,7 +1753,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) + case snd_soc_dapm_pga: + case snd_soc_dapm_out_drv: + w->power_check = dapm_generic_check_power; +- dapm_new_pga(dapm, w); ++ dapm_new_pga(w); + break; + case snd_soc_dapm_input: + case snd_soc_dapm_output: +diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c +index ae72ae60..e3f1235 100644 +--- a/virt/kvm/assigned-dev.c ++++ b/virt/kvm/assigned-dev.c +@@ -197,8 +197,7 @@ static void kvm_free_assigned_device(struct kvm *kvm, + { + kvm_free_assigned_irq(kvm, assigned_dev); + +- __pci_reset_function(assigned_dev->dev); +- pci_restore_state(assigned_dev->dev); ++ pci_reset_function(assigned_dev->dev); + + pci_release_regions(assigned_dev->dev); + pci_disable_device(assigned_dev->dev); +@@ -515,7 +514,6 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, + } + + pci_reset_function(dev); +- pci_save_state(dev); + + match->assigned_dev_id = assigned_dev->assigned_dev_id; + match->host_segnr = assigned_dev->segnr; +@@ -546,7 +544,6 @@ out: + mutex_unlock(&kvm->lock); + return r; + out_list_del: +- pci_restore_state(dev); + list_del(&match->list); + pci_release_regions(dev); + out_disable: diff --git a/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-at91sam9260-reset.patch b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-at91sam9260-reset.patch new file mode 100644 index 0000000..af63d5c --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-at91sam9260-reset.patch @@ -0,0 +1,26 @@ +Index: linux-2.6.39.4/arch/arm/mach-at91/at91sam9260.c +=================================================================== +--- linux-2.6.39.4.orig/arch/arm/mach-at91/at91sam9260.c 2012-09-17 16:25:08.248303296 -0500 ++++ linux-2.6.39.4/arch/arm/mach-at91/at91sam9260.c 2012-09-17 16:25:45.316033835 -0500 +@@ -310,6 +310,11 @@ + iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc)); + } + ++static void at91sam9260_reset(void) ++{ ++ at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); ++} ++ + void __init at91sam9260_initialize(unsigned long main_clock) + { + /* Map peripherals */ +@@ -322,7 +327,8 @@ + else + iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc)); + +- at91_arch_reset = at91sam9_alt_reset; ++ // jjg: use old reset routine, alt reset is not reliable ++ at91_arch_reset = at91sam9260_reset; + pm_power_off = at91sam9260_poweroff; + at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) + | (1 << AT91SAM9260_ID_IRQ2); diff --git a/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-atmel_serial_disable_hwhs.patch b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-atmel_serial_disable_hwhs.patch new file mode 100644 index 0000000..88fd8d5 --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-atmel_serial_disable_hwhs.patch @@ -0,0 +1,32 @@ +Revert commit 8e706c4d0dab214c625a2df84a0ca69a76bae65d in linux-2.6: + avr32: add hardware handshake support to atmel_serial + +Reverting commit since it breaks hardware flow control for at91sam9g20 + +diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c +index 9d948bc..b659f2c 100644 +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -1020,8 +1020,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, + + /* Get current mode register */ + mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL +- | ATMEL_US_NBSTOP | ATMEL_US_PAR +- | ATMEL_US_USMODE); ++ | ATMEL_US_NBSTOP | ATMEL_US_PAR); + + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); + quot = uart_get_divisor(port, baud); +@@ -1066,12 +1065,6 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, + } else + mode |= ATMEL_US_PAR_NONE; + +- /* hardware handshake (RTS/CTS) */ +- if (termios->c_cflag & CRTSCTS) +- mode |= ATMEL_US_USMODE_HWHS; +- else +- mode |= ATMEL_US_USMODE_NORMAL; +- + spin_lock_irqsave(&port->lock, flags); + + port->read_status_mask = ATMEL_US_OVRE; diff --git a/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-ledtrig-netdev.patch b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-ledtrig-netdev.patch new file mode 100644 index 0000000..ab4c91b --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-ledtrig-netdev.patch @@ -0,0 +1,488 @@ +Index: linux-2.6.39.4/drivers/leds/Kconfig +=================================================================== +--- linux-2.6.39.4.orig/drivers/leds/Kconfig 2011-08-03 14:43:28.000000000 -0500 ++++ linux-2.6.39.4/drivers/leds/Kconfig 2012-12-18 13:27:23.579027264 -0600 +@@ -417,6 +417,13 @@ + load average. + If unsure, say Y. + ++config LEDS_TRIGGER_NETDEV ++ tristate "LED Network Device Trigger" ++ depends on LEDS_TRIGGERS ++ help ++ This allows LEDs to be controlled by Network Device activity. ++ If unsure, say Y. ++ + config LEDS_TRIGGER_BACKLIGHT + tristate "LED backlight Trigger" + depends on LEDS_TRIGGERS +Index: linux-2.6.39.4/drivers/leds/Makefile +=================================================================== +--- linux-2.6.39.4.orig/drivers/leds/Makefile 2011-08-03 14:43:28.000000000 -0500 ++++ linux-2.6.39.4/drivers/leds/Makefile 2012-12-18 13:27:23.579027264 -0600 +@@ -50,6 +50,7 @@ + obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o + obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o + obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o ++obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o + obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o + obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o + obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o +Index: linux-2.6.39.4/drivers/leds/ledtrig-netdev.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.39.4/drivers/leds/ledtrig-netdev.c 2012-12-18 14:40:30.078735442 -0600 +@@ -0,0 +1,453 @@ ++/* ++ * LED Kernel Netdev Trigger ++ * ++ * Toggles the LED to reflect the link and traffic state of a named net device ++ * ++ * Copyright 2007 Oliver Jowett <oliver@opencloud.com> ++ * ++ * Derived from ledtrig-timer.c which is: ++ * Copyright 2005-2006 Openedhand Ltd. ++ * Author: Richard Purdie <rpurdie@openedhand.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/jiffies.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/list.h> ++#include <linux/spinlock.h> ++#include <linux/device.h> ++#include <linux/sysdev.h> ++#include <linux/netdevice.h> ++#include <linux/timer.h> ++#include <linux/ctype.h> ++#include <linux/leds.h> ++#include <linux/version.h> ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) ++#include <net/net_namespace.h> ++#endif ++ ++#include "leds.h" ++ ++/* ++ * Configurable sysfs attributes: ++ * ++ * device_name - network device name to monitor ++ * ++ * interval - duration of LED blink, in milliseconds ++ * ++ * mode - either "none" (LED is off) or a space separated list of one or more of: ++ * link: LED's normal state reflects whether the link is up (has carrier) or not ++ * tx: LED blinks on transmitted data ++ * rx: LED blinks on receive data ++ * ++ * Some suggestions: ++ * ++ * Simple link status LED: ++ * $ echo netdev >someled/trigger ++ * $ echo eth0 >someled/device_name ++ * $ echo link >someled/mode ++ * ++ * Ethernet-style link/activity LED: ++ * $ echo netdev >someled/trigger ++ * $ echo eth0 >someled/device_name ++ * $ echo "link tx rx" >someled/mode ++ * ++ * Modem-style tx/rx LEDs: ++ * $ echo netdev >led1/trigger ++ * $ echo ppp0 >led1/device_name ++ * $ echo tx >led1/mode ++ * $ echo netdev >led2/trigger ++ * $ echo ppp0 >led2/device_name ++ * $ echo rx >led2/mode ++ * ++ */ ++ ++#define MODE_LINK 1 ++#define MODE_TX 2 ++#define MODE_RX 4 ++ ++struct led_netdev_data { ++ rwlock_t lock; ++ ++ struct timer_list timer; ++ struct notifier_block notifier; ++ ++ struct led_classdev *led_cdev; ++ struct net_device *net_dev; ++ ++ char device_name[IFNAMSIZ]; ++ unsigned interval; ++ unsigned mode; ++ unsigned link_up; ++ unsigned last_activity; ++}; ++ ++static void set_baseline_state(struct led_netdev_data *trigger_data) ++{ ++ if ((trigger_data->mode & MODE_LINK) != 0 && trigger_data->link_up) ++ led_set_brightness(trigger_data->led_cdev, LED_FULL); ++ else ++ led_set_brightness(trigger_data->led_cdev, LED_OFF); ++ ++ if ((trigger_data->mode & (MODE_TX | MODE_RX)) != 0 && trigger_data->link_up) ++ mod_timer(&trigger_data->timer, jiffies + trigger_data->interval); ++ else ++ del_timer(&trigger_data->timer); ++} ++ ++static ssize_t led_device_name_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct led_classdev *led_cdev = dev_get_drvdata(dev); ++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; ++ ++ read_lock(&trigger_data->lock); ++ sprintf(buf, "%s\n", trigger_data->device_name); ++ read_unlock(&trigger_data->lock); ++ ++ return strlen(buf) + 1; ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) ++extern struct net init_net; ++#endif ++ ++static ssize_t led_device_name_store(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t size) ++{ ++ struct led_classdev *led_cdev = dev_get_drvdata(dev); ++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; ++ ++ if (size < 0 || size >= IFNAMSIZ) ++ return -EINVAL; ++ ++ write_lock(&trigger_data->lock); ++ ++ strcpy(trigger_data->device_name, buf); ++ if (size > 0 && trigger_data->device_name[size-1] == '\n') ++ trigger_data->device_name[size-1] = 0; ++ ++ if (trigger_data->device_name[0] != 0) { ++ /* check for existing device to update from */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) ++ trigger_data->net_dev = dev_get_by_name(&init_net, trigger_data->device_name); ++#else ++ trigger_data->net_dev = dev_get_by_name(trigger_data->device_name); ++#endif ++ if (trigger_data->net_dev != NULL) ++ trigger_data->link_up = (dev_get_flags(trigger_data->net_dev) & IFF_LOWER_UP) != 0; ++ set_baseline_state(trigger_data); /* updates LEDs, may start timers */ ++ } ++ ++ write_unlock(&trigger_data->lock); ++ return size; ++} ++ ++static DEVICE_ATTR(device_name, 0644, led_device_name_show, led_device_name_store); ++ ++static ssize_t led_mode_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct led_classdev *led_cdev = dev_get_drvdata(dev); ++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; ++ ++ read_lock(&trigger_data->lock); ++ ++ if (trigger_data->mode == 0) { ++ strcpy(buf, "none\n"); ++ } else { ++ if (trigger_data->mode & MODE_LINK) ++ strcat(buf, "link "); ++ if (trigger_data->mode & MODE_TX) ++ strcat(buf, "tx "); ++ if (trigger_data->mode & MODE_RX) ++ strcat(buf, "rx "); ++ strcat(buf, "\n"); ++ } ++ ++ read_unlock(&trigger_data->lock); ++ ++ return strlen(buf)+1; ++} ++ ++static ssize_t led_mode_store(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t size) ++{ ++ struct led_classdev *led_cdev = dev_get_drvdata(dev); ++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; ++ char copybuf[1024]; ++ int new_mode = -1; ++ char *p, *token; ++ ++ /* take a copy since we don't want to trash the inbound buffer when using strsep */ ++ strncpy(copybuf, buf, sizeof(copybuf)); ++ copybuf[1023] = 0; ++ p = copybuf; ++ ++ while ((token = strsep(&p, " \t\n")) != NULL) { ++ if (!*token) ++ continue; ++ ++ if (new_mode == -1) ++ new_mode = 0; ++ ++ if (!strcmp(token, "none")) ++ new_mode = 0; ++ else if (!strcmp(token, "tx")) ++ new_mode |= MODE_TX; ++ else if (!strcmp(token, "rx")) ++ new_mode |= MODE_RX; ++ else if (!strcmp(token, "link")) ++ new_mode |= MODE_LINK; ++ else ++ return -EINVAL; ++ } ++ ++ if (new_mode == -1) ++ return -EINVAL; ++ ++ write_lock(&trigger_data->lock); ++ trigger_data->mode = new_mode; ++ set_baseline_state(trigger_data); ++ write_unlock(&trigger_data->lock); ++ ++ return size; ++} ++ ++static DEVICE_ATTR(mode, 0644, led_mode_show, led_mode_store); ++ ++static ssize_t led_interval_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct led_classdev *led_cdev = dev_get_drvdata(dev); ++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; ++ ++ read_lock(&trigger_data->lock); ++ sprintf(buf, "%u\n", jiffies_to_msecs(trigger_data->interval)); ++ read_unlock(&trigger_data->lock); ++ ++ return strlen(buf) + 1; ++} ++ ++static ssize_t led_interval_store(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t size) ++{ ++ struct led_classdev *led_cdev = dev_get_drvdata(dev); ++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; ++ int ret = -EINVAL; ++ char *after; ++ unsigned long value = simple_strtoul(buf, &after, 10); ++ size_t count = after - buf; ++ ++ if (*after && isspace(*after)) ++ count++; ++ ++ /* impose some basic bounds on the timer interval */ ++ if (count == size && value >= 5 && value <= 10000) { ++ write_lock(&trigger_data->lock); ++ trigger_data->interval = msecs_to_jiffies(value); ++ set_baseline_state(trigger_data); // resets timer ++ write_unlock(&trigger_data->lock); ++ ret = count; ++ } ++ ++ return ret; ++} ++ ++static DEVICE_ATTR(interval, 0644, led_interval_show, led_interval_store); ++ ++static int netdev_trig_notify(struct notifier_block *nb, ++ unsigned long evt, ++ void *dv) ++{ ++ struct net_device *dev = dv; ++ struct led_netdev_data *trigger_data = container_of(nb, struct led_netdev_data, notifier); ++ ++ if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER) ++ return NOTIFY_DONE; ++ ++ write_lock(&trigger_data->lock); ++ ++ if (strcmp(dev->name, trigger_data->device_name)) ++ goto done; ++ ++ if (evt == NETDEV_REGISTER) { ++ if (trigger_data->net_dev != NULL) ++ dev_put(trigger_data->net_dev); ++ dev_hold(dev); ++ trigger_data->net_dev = dev; ++ trigger_data->link_up = 0; ++ goto done; ++ } ++ ++ if (evt == NETDEV_UNREGISTER && trigger_data->net_dev != NULL) { ++ dev_put(trigger_data->net_dev); ++ trigger_data->net_dev = NULL; ++ goto done; ++ } ++ ++ /* UP / DOWN / CHANGE */ ++ ++ trigger_data->link_up = (evt != NETDEV_DOWN && netif_carrier_ok(dev)); ++ set_baseline_state(trigger_data); ++ ++done: ++ write_unlock(&trigger_data->lock); ++ return NOTIFY_DONE; ++} ++ ++/* here's the real work! */ ++static void netdev_trig_timer(unsigned long arg) ++{ ++ struct led_netdev_data *trigger_data = (struct led_netdev_data *)arg; ++ unsigned new_activity; ++ ++ struct rtnl_link_stats64 *dev_stats; ++ struct rtnl_link_stats64 temp; ++ ++ write_lock(&trigger_data->lock); ++ ++ if (!trigger_data->link_up || !trigger_data->net_dev || (trigger_data->mode & (MODE_TX | MODE_RX)) == 0) { ++ /* we don't need to do timer work, just reflect link state. */ ++ led_set_brightness(trigger_data->led_cdev, ((trigger_data->mode & MODE_LINK) != 0 && trigger_data->link_up) ? LED_FULL : LED_OFF); ++ goto no_restart; ++ } ++ ++ dev_stats = dev_get_stats(trigger_data->net_dev, &temp); ++ new_activity = ++ ((trigger_data->mode & MODE_TX) ? dev_stats->tx_packets : 0) + ++ ((trigger_data->mode & MODE_RX) ? dev_stats->rx_packets : 0); ++ ++ if (trigger_data->mode & MODE_LINK) { ++ /* base state is ON (link present) */ ++ /* if there's no link, we don't get this far and the LED is off */ ++ ++ /* OFF -> ON always */ ++ /* ON -> OFF on activity */ ++ if (trigger_data->led_cdev->brightness == LED_OFF) { ++ led_set_brightness(trigger_data->led_cdev, LED_FULL); ++ } else if (trigger_data->last_activity != new_activity) { ++ led_set_brightness(trigger_data->led_cdev, LED_OFF); ++ } ++ } else { ++ /* base state is OFF */ ++ /* ON -> OFF always */ ++ /* OFF -> ON on activity */ ++ if (trigger_data->led_cdev->brightness == LED_FULL) { ++ led_set_brightness(trigger_data->led_cdev, LED_OFF); ++ } else if (trigger_data->last_activity != new_activity) { ++ led_set_brightness(trigger_data->led_cdev, LED_FULL); ++ } ++ } ++ ++ trigger_data->last_activity = new_activity; ++ mod_timer(&trigger_data->timer, jiffies + trigger_data->interval); ++ ++no_restart: ++ write_unlock(&trigger_data->lock); ++} ++ ++static void netdev_trig_activate(struct led_classdev *led_cdev) ++{ ++ struct led_netdev_data *trigger_data; ++ int rc; ++ ++ trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); ++ if (!trigger_data) ++ return; ++ ++ rwlock_init(&trigger_data->lock); ++ ++ trigger_data->notifier.notifier_call = netdev_trig_notify; ++ trigger_data->notifier.priority = 10; ++ ++ setup_timer(&trigger_data->timer, netdev_trig_timer, (unsigned long) trigger_data); ++ ++ trigger_data->led_cdev = led_cdev; ++ trigger_data->net_dev = NULL; ++ trigger_data->device_name[0] = 0; ++ ++ trigger_data->mode = 0; ++ trigger_data->interval = msecs_to_jiffies(50); ++ trigger_data->link_up = 0; ++ trigger_data->last_activity = 0; ++ ++ led_cdev->trigger_data = trigger_data; ++ ++ rc = device_create_file(led_cdev->dev, &dev_attr_device_name); ++ if (rc) ++ goto err_out; ++ rc = device_create_file(led_cdev->dev, &dev_attr_mode); ++ if (rc) ++ goto err_out_device_name; ++ rc = device_create_file(led_cdev->dev, &dev_attr_interval); ++ if (rc) ++ goto err_out_mode; ++ ++ register_netdevice_notifier(&trigger_data->notifier); ++ return; ++ ++err_out_mode: ++ device_remove_file(led_cdev->dev, &dev_attr_mode); ++err_out_device_name: ++ device_remove_file(led_cdev->dev, &dev_attr_device_name); ++err_out: ++ led_cdev->trigger_data = NULL; ++ kfree(trigger_data); ++} ++ ++static void netdev_trig_deactivate(struct led_classdev *led_cdev) ++{ ++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; ++ ++ if (trigger_data) { ++ unregister_netdevice_notifier(&trigger_data->notifier); ++ ++ device_remove_file(led_cdev->dev, &dev_attr_device_name); ++ device_remove_file(led_cdev->dev, &dev_attr_mode); ++ device_remove_file(led_cdev->dev, &dev_attr_interval); ++ ++ write_lock(&trigger_data->lock); ++ ++ if (trigger_data->net_dev) { ++ dev_put(trigger_data->net_dev); ++ trigger_data->net_dev = NULL; ++ } ++ ++ write_unlock(&trigger_data->lock); ++ ++ del_timer_sync(&trigger_data->timer); ++ ++ kfree(trigger_data); ++ } ++} ++ ++static struct led_trigger netdev_led_trigger = { ++ .name = "netdev", ++ .activate = netdev_trig_activate, ++ .deactivate = netdev_trig_deactivate, ++}; ++ ++static int __init netdev_trig_init(void) ++{ ++ return led_trigger_register(&netdev_led_trigger); ++} ++ ++static void __exit netdev_trig_exit(void) ++{ ++ led_trigger_unregister(&netdev_led_trigger); ++} ++ ++module_init(netdev_trig_init); ++module_exit(netdev_trig_exit); ++ ++MODULE_AUTHOR("Oliver Jowett <oliver@opencloud.com>"); ++MODULE_DESCRIPTION("Netdev LED trigger"); ++MODULE_LICENSE("GPL"); diff --git a/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-option-telit.patch b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-option-telit.patch new file mode 100644 index 0000000..0a4baa1 --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/linux-2.6.39.4-option-telit.patch @@ -0,0 +1,43 @@ +From 7204cf584836c24b4b06e4ad4a8e6bb8ea84908e Mon Sep 17 00:00:00 2001 +From: Daniele Palmas <dnlplm@gmail.com> +Date: Wed, 29 Feb 2012 15:32:05 +0100 +Subject: [PATCH] USB: option driver: adding support for Telit CC864-SINGLE, + CC864-DUAL and DE910-DUAL modems + +Adding PID for Telit CC864-SINGLE, CC864-DUAL and DE910-DUAL +modems + +Signed-off-by: Daniele Palmas <dnlplm@gmail.com> +Cc: stable <stable@vger.kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/usb/serial/option.c | 6 ++++++ + 1 files changed, 6 insertions(+), 0 deletions(-) + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 005511b..f9b11fb 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -307,6 +307,9 @@ static void option_instat_callback(struct urb *urb); + #define TELIT_VENDOR_ID 0x1bc7 + #define TELIT_PRODUCT_UC864E 0x1003 + #define TELIT_PRODUCT_UC864G 0x1004 ++#define TELIT_PRODUCT_CC864_DUAL 0x1005 ++#define TELIT_PRODUCT_CC864_SINGLE 0x1006 ++#define TELIT_PRODUCT_DE910_DUAL 0x1010 + + /* ZTE PRODUCTS */ + #define ZTE_VENDOR_ID 0x19d2 +@@ -771,6 +774,9 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, ++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, +-- +1.7.7.6 + diff --git a/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/defconfig b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/defconfig new file mode 100644 index 0000000..0afdbee --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/defconfig @@ -0,0 +1,2328 @@ +# +# Automatically generated make config: don't edit +# Linux/arm 2.6.39.4 Kernel Configuration +# Tue Feb 12 17:21:58 2013 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_KTIME_SCALAR=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_VECTORS_BASE=0xffff0000 +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y +CONFIG_HAVE_IRQ_WORK=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_FHANDLE is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_HAVE_SPARSE_IRQ=y +CONFIG_GENERIC_IRQ_SHOW=y +# CONFIG_SPARSE_IRQ is not set + +# +# RCU Subsystem +# +CONFIG_TINY_RCU=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_NS is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CPUSETS is not set +# CONFIG_CGROUP_CPUACCT is not set +# CONFIG_RESOURCE_COUNTERS is not set +# CONFIG_CGROUP_SCHED is not set +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_XZ=y +CONFIG_RD_LZO=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_THROTTLING is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CFQ_GROUP_IOSCHED is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set +CONFIG_ARCH_AT91=y +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MXS is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P64X0 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_EXYNOS4 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_TCC_926 is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_VT8500 is not set + +# +# Atmel AT91 System-on-Chip +# +# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_AT91SAM9260 is not set +# CONFIG_ARCH_AT91SAM9261 is not set +# CONFIG_ARCH_AT91SAM9G10 is not set +# CONFIG_ARCH_AT91SAM9263 is not set +# CONFIG_ARCH_AT91SAM9RL is not set +# CONFIG_ARCH_AT91SAM9G20 is not set +# CONFIG_ARCH_AT91SAM9G45 is not set +CONFIG_ARCH_AT91SAM9X5=y +# CONFIG_ARCH_AT91CAP9 is not set +# CONFIG_ARCH_AT572D940HF is not set +# CONFIG_ARCH_AT91X40 is not set +CONFIG_AT91_PMC_UNIT=y + +# +# AT91SAM9x5 Series Board Type +# +CONFIG_MACH_AT91SAM9X5EK=y + +# +# AT91 Board Options +# + +# +# AT91 Feature Selections +# +CONFIG_AT91_PROGRAMMABLE_CLOCKS=y +CONFIG_AT91_SLOW_CLOCK=y +CONFIG_AT91_TIMER_HZ=100 +CONFIG_AT91_EARLY_DBGU=y +# CONFIG_AT91_EARLY_USART0 is not set +# CONFIG_AT91_EARLY_USART1 is not set +# CONFIG_AT91_EARLY_USART2 is not set +# CONFIG_GPIO_PCA953X is not set + +# +# System MMU +# + +# +# Processor Type +# +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_USE_DOMAINS=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_COMPACTION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NEED_PER_CPU_KM=y +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_LEDS=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y +CONFIG_UACCESS_WITH_MEMCPY=y +# CONFIG_SECCOMP is not set +# CONFIG_CC_STACKPROTECTOR is not set +# CONFIG_DEPRECATED_PARAM_STRUCT is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE=" quiet " +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_AUTO_ZRELADDR=y + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_PM_SLEEP=y +# CONFIG_PM_RUNTIME is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=y +CONFIG_NET_IPGRE_DEMUX=y +CONFIG_NET_IPGRE=y +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=y +CONFIG_NETFILTER_NETLINK_QUEUE=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +CONFIG_NF_CT_PROTO_GRE=y +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +# CONFIG_NF_CONNTRACK_IRC is not set +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +# CONFIG_NF_CONNTRACK_SNMP is not set +CONFIG_NF_CONNTRACK_PPTP=y +# CONFIG_NF_CONNTRACK_SANE is not set +# CONFIG_NF_CONNTRACK_SIP is not set +# CONFIG_NF_CONNTRACK_TFTP is not set +# CONFIG_NF_CT_NETLINK is not set +# CONFIG_NETFILTER_TPROXY is not set +CONFIG_NETFILTER_XTABLES=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=y +CONFIG_NETFILTER_XT_CONNMARK=y + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set +CONFIG_NETFILTER_XT_TARGET_MARK=y +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +CONFIG_NETFILTER_XT_MATCH_HL=y +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +# CONFIG_NETFILTER_XT_MATCH_POLICY is not set +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +CONFIG_NETFILTER_XT_MATCH_RECENT=y +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATE=y +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=y +# CONFIG_IP_NF_MATCH_AH is not set +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_LOG=y +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_NF_NAT=y +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_NF_NAT_PROTO_GRE=y +CONFIG_NF_NAT_FTP=y +# CONFIG_NF_NAT_IRC is not set +# CONFIG_NF_NAT_TFTP is not set +# CONFIG_NF_NAT_AMANDA is not set +CONFIG_NF_NAT_PPTP=y +CONFIG_NF_NAT_H323=y +# CONFIG_NF_NAT_SIP is not set +CONFIG_IP_NF_MANGLE=y +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_L2TP=y +# CONFIG_L2TP_V3 is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +# CONFIG_NET_SCH_HTB is not set +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFB is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_MQPRIO is not set +# CONFIG_NET_SCH_CHOKE is not set + +# +# Classification +# +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_CLS_CGROUP is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=m +CONFIG_BT_L2CAP=y +CONFIG_BT_SCO=y +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=m +# CONFIG_BT_HCIUART_H4 is not set +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set +CONFIG_BT_HCIUART_LL=y +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_MRVL is not set +# CONFIG_BT_ATH3K is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +# CONFIG_MAC80211_RC_PID is not set +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND_ECC=y +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_BCH is not set +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_ATMEL=y +CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=32768 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_SENSORS_LIS3LV02D is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +CONFIG_ATMEL_TCLIB=y +CONFIG_ATMEL_TCB_CLKSRC=y +CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 +CONFIG_ATMEL_TCB_CLKSRC_32BIT=y +# CONFIG_ICS932S401 is not set +CONFIG_ATMEL_SSC=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_IWMC3200TOP is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +CONFIG_HAVE_NET_MACB=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +# CONFIG_VETH is not set +CONFIG_MII=y +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM63XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MACB=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_FTMAC100 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_LIBERTAS_THINFIRM is not set +CONFIG_AT76C50X_USB=m +CONFIG_USB_ZD1201=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +# CONFIG_MAC80211_HWSIM is not set +CONFIG_ATH_COMMON=m +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_HTC=m +# CONFIG_AR9170_USB is not set +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +CONFIG_CARL9170_WPC=y +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +# CONFIG_HOSTAP is not set +# CONFIG_IWM is not set +# CONFIG_LIBERTAS is not set +# CONFIG_P54_COMMON is not set +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +# CONFIG_RT2800USB_UNKNOWN is not set +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_HT=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +CONFIG_RTL8192C_COMMON=m +# CONFIG_WL1251 is not set +CONFIG_WL12XX_MENU=m +CONFIG_WL12XX=m +# CONFIG_WL12XX_HT is not set +# CONFIG_WL12XX_SPI is not set +CONFIG_WL12XX_SDIO=m +CONFIG_WL12XX_SDIO_TEST=m +CONFIG_WL12XX_PLATFORM_DATA=y +# CONFIG_ZD1211RW is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +# CONFIG_USB_EPSON2888 is not set +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +# CONFIG_WAN is not set + +# +# CAIF transport drivers +# +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=y +# CONFIG_PPP_MPPE is not set +# CONFIG_PPPOE is not set +# CONFIG_PPTP is not set +# CONFIG_PPPOL2TP is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=y +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +CONFIG_SERIAL_ATMEL_DMA=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_RAMOOPS is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_MUX is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +CONFIG_I2C_GPIO=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_ATMEL=y +CONFIG_SPI_ATMEL_DMA=y +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_BASIC_MMIO is not set +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_AT91SAM9X_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_MFD_SUPPORT=y +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_REGULATOR is not set +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +# CONFIG_MEDIA_CONTROLLER is not set +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +# CONFIG_RC_CORE is not set +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_AT91SAM9X5 is not set +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y + +# +# Audio decoders +# +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m + +# +# RDS decoders +# + +# +# Video decoders +# +CONFIG_VIDEO_SAA711X=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_CX25840=m + +# +# MPEG video encoders +# +CONFIG_VIDEO_CX2341X=m + +# +# Video encoders +# + +# +# Video improvement chips +# +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_TIMBERDALE is not set +# CONFIG_VIDEO_SR030PC30 is not set +# CONFIG_VIDEO_NOON010PC30 is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +# CONFIG_USB_GSPCA_KONICA is not set +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +# CONFIG_USB_GSPCA_NW80X is not set +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +# CONFIG_USB_GSPCA_SPCA1528 is not set +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +# CONFIG_USB_GSPCA_SQ930X is not set +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +# CONFIG_USB_GSPCA_VICAM is not set +# CONFIG_USB_GSPCA_XIRLINK_CIT is not set +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_USBVISION=m +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_SN9C102 is not set +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_RADIO_ADAPTERS is not set + +# +# Graphics support +# +CONFIG_HAVE_FB_ATMEL=y +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set +# CONFIG_HID_PID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set + +# +# Special HID drivers +# +# CONFIG_HID_APPLE is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_WACOM is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_UAS is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_HP4X=m +# CONFIG_USB_SERIAL_SAFE is not set +CONFIG_USB_SERIAL_SAMBA=m +CONFIG_USB_SERIAL_SIEMENS_MPI=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_WWAN=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m +CONFIG_USB_SERIAL_ZIO=m +CONFIG_USB_SERIAL_SSU100=m +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +CONFIG_USB_SEVSEG=m +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +CONFIG_USB_LCD=m +CONFIG_USB_LED=m +# CONFIG_USB_CYPRESS_CY7C63 is not set +CONFIG_USB_CYTHERM=m +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_ATMEL_USBA=y +CONFIG_USB_ATMEL_USBA=m +# CONFIG_USB_GADGET_FUSB300 is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA_U2O is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set +# CONFIG_USB_G_NCM is not set +CONFIG_USB_GADGETFS=m +# CONFIG_USB_FUNCTIONFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +# CONFIG_MMC_CLKGATE is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=8 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set +CONFIG_MMC_ATMELMCI=m +# CONFIG_MMC_ATMELMCI_DMA is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_DW is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_NETDEV=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_NFC_DEVICES is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_AT91RM9200=y +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +# CONFIG_DW_DMAC is not set +CONFIG_AT_HDMAC=y +# CONFIG_TIMB_DMA is not set +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +CONFIG_UIO=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD=y +CONFIG_JBD2=y +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set +CONFIG_GENERIC_ACL=y + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_FS_WBUF_VERIFY=y +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +CONFIG_JFFS2_RUBIN=y +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_JFFS2_CMODE_FAVOURLZO is not set +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +# CONFIG_NFS_USE_NEW_IDMAPPER is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=y +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_HARDLOCKUP_DETECTOR is not set +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_STRICT_DEVMEM is not set +CONFIG_ARM_UNWIND=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +# CONFIG_EARLY_PRINTK is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ANUBIS=y +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_BLOWFISH=y +# CONFIG_CRYPTO_CAMELLIA is not set +CONFIG_CRYPTO_CAST5=y +CONFIG_CRYPTO_CAST6=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=y +CONFIG_CRYPTO_KHAZAD=y +CONFIG_CRYPTO_SALSA20=y +CONFIG_CRYPTO_SEED=y +CONFIG_CRYPTO_SERPENT=y +CONFIG_CRYPTO_TEA=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_TWOFISH_COMMON=y + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +CONFIG_CRC7=m +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_AVERAGE=y diff --git a/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-at91sam9_wdt-10second-timeout.patch b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-at91sam9_wdt-10second-timeout.patch new file mode 100644 index 0000000..90c906c --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-at91sam9_wdt-10second-timeout.patch @@ -0,0 +1,14 @@ +Index: linux-2.6.39.4/drivers/watchdog/at91sam9_wdt.c +=================================================================== +--- linux-2.6.39.4.orig/drivers/watchdog/at91sam9_wdt.c 2013-01-16 14:33:37.565560189 -0600 ++++ linux-2.6.39.4/drivers/watchdog/at91sam9_wdt.c 2013-01-16 14:34:26.531727425 -0600 +@@ -43,7 +43,8 @@ + #define ticks_to_ms(t) (((t + 1) * 1000) >> 8) + + /* Hardware timeout in seconds */ +-#define WDT_HW_TIMEOUT 2 ++/* MTR: use longer timeout */ ++#define WDT_HW_TIMEOUT 10 + + /* Timer heartbeat (500ms) */ + #define WDT_TIMEOUT (HZ/2) diff --git a/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-at91sam9x5-extreset.patch b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-at91sam9x5-extreset.patch new file mode 100644 index 0000000..31b7441 --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-at91sam9x5-extreset.patch @@ -0,0 +1,16 @@ +Index: linux-2.6.39.4/arch/arm/mach-at91/at91sam9x5.c +=================================================================== +--- linux-2.6.39.4.orig/arch/arm/mach-at91/at91sam9x5.c 2012-06-25 17:00:27.060489533 -0500 ++++ linux-2.6.39.4/arch/arm/mach-at91/at91sam9x5.c 2012-06-25 17:00:33.051404086 -0500 +@@ -330,7 +330,10 @@ + + static void at91sam9x5_reset(void) + { +- at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); ++ // MTR: generate an external reset (assert the NRST pin) on soft reset ++ // set reset duration to 125 ms --> set ERSTL to 0xb (0xb = 11 = 2^12 slow clock cycles = 4096 clocks = 125 ms) ++ at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY | (0xb << 8)); ++ at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST | AT91_RSTC_EXTRST); + } + + static void at91sam9x5_poweroff(void) diff --git a/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-atmel-mci-force-detect.patch b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-atmel-mci-force-detect.patch new file mode 100644 index 0000000..d59a7cc --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-atmel-mci-force-detect.patch @@ -0,0 +1,30 @@ +Index: linux-2.6.39.4/drivers/mmc/host/atmel-mci.c +=================================================================== +--- linux-2.6.39.4.orig/drivers/mmc/host/atmel-mci.c 2012-05-10 11:44:02.069173755 -0500 ++++ linux-2.6.39.4/drivers/mmc/host/atmel-mci.c 2012-05-11 11:21:42.119198300 -0500 +@@ -1059,6 +1059,10 @@ + dev_dbg(&mmc->class_dev, "card is %spresent\n", + present ? "" : "not "); + } ++ else { ++ // jjg - assume card is present if detect pin is unset ++ present = 1; ++ } + + return present; + } +@@ -1655,8 +1659,12 @@ + } + } + +- if (!gpio_is_valid(slot->detect_pin)) +- mmc->caps |= MMC_CAP_NEEDS_POLL; ++ // jjg - if detect pin isn't set, don't poll -- just assume device ++ // is there and mark it non-removable ++ if (!gpio_is_valid(slot->detect_pin)) { ++ dev_info(&host->pdev->dev,"No detect pin, marking non-removable and assuming device is present\n"); ++ mmc->caps |= MMC_CAP_NONREMOVABLE; ++ } + + if (gpio_is_valid(slot->wp_pin)) { + if (gpio_request(slot->wp_pin, "mmc_wp")) { diff --git a/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-atmel-mci-module-alias.patch b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-atmel-mci-module-alias.patch new file mode 100644 index 0000000..8081bb9 --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-atmel-mci-module-alias.patch @@ -0,0 +1,9 @@ +Index: linux-2.6.39.4/drivers/mmc/host/atmel-mci.c +=================================================================== +--- linux-2.6.39.4.orig/drivers/mmc/host/atmel-mci.c 2013-03-08 10:25:21.024073265 -0600 ++++ linux-2.6.39.4/drivers/mmc/host/atmel-mci.c 2013-03-08 10:25:25.523819243 -0600 +@@ -1973,3 +1973,4 @@ + MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver"); + MODULE_AUTHOR("Haavard Skinnemoen <haavard.skinnemoen@atmel.com>"); + MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:atmel_mci"); diff --git a/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-cdc-acm-ignore-exar-devices.patch b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-cdc-acm-ignore-exar-devices.patch new file mode 100644 index 0000000..5f9d8f7 --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-cdc-acm-ignore-exar-devices.patch @@ -0,0 +1,45 @@ +Index: linux-2.6.39.4/drivers/usb/class/cdc-acm.c +=================================================================== +--- linux-2.6.39.4.orig/drivers/usb/class/cdc-acm.c 2013-02-19 09:22:57.860051682 -0600 ++++ linux-2.6.39.4/drivers/usb/class/cdc-acm.c 2013-02-19 09:30:35.274209660 -0600 +@@ -963,6 +963,12 @@ + goto skip_normal_probe; + } + ++ /* ignore devices we don't want to support */ ++ if (quirks == IGNORE_DEVICE) { ++ dev_dbg(&intf->dev, "Ignoring device\n"); ++ return -ENODEV; ++ } ++ + /* normal probing*/ + if (!buffer) { + dev_err(&intf->dev, "Weird descriptor references\n"); +@@ -1633,6 +1639,18 @@ + .driver_info = NO_DATA_INTERFACE, + }, + ++ /* Ignore Exar XR21V141X usb serial chips ++ * This elminates conflicting with the Exar vizzini driver */ ++ { USB_DEVICE(0x04e2, 0x1410), ++ .driver_info = IGNORE_DEVICE, ++ }, ++ { USB_DEVICE(0x04e2, 0x1412), ++ .driver_info = IGNORE_DEVICE, ++ }, ++ { USB_DEVICE(0x04e2, 0x1414), ++ .driver_info = IGNORE_DEVICE, ++ }, ++ + /* control interfaces without any protocol set */ + { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, + USB_CDC_PROTO_NONE) }, +Index: linux-2.6.39.4/drivers/usb/class/cdc-acm.h +=================================================================== +--- linux-2.6.39.4.orig/drivers/usb/class/cdc-acm.h 2013-02-19 09:22:54.860050647 -0600 ++++ linux-2.6.39.4/drivers/usb/class/cdc-acm.h 2013-02-19 09:24:00.856126438 -0600 +@@ -138,3 +138,4 @@ + #define NO_CAP_LINE 4 + #define NOT_A_MODEM 8 + #define NO_DATA_INTERFACE 16 ++#define IGNORE_DEVICE 32 diff --git a/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-macb-force-link.patch b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-macb-force-link.patch new file mode 100644 index 0000000..2ef39a9 --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-macb-force-link.patch @@ -0,0 +1,87 @@ +Index: linux-2.6.39.4/drivers/net/macb.c +=================================================================== +--- linux-2.6.39.4.orig/drivers/net/macb.c 2011-08-03 14:43:28.000000000 -0500 ++++ linux-2.6.39.4/drivers/net/macb.c 2013-03-12 15:31:34.710687318 -0500 +@@ -193,7 +193,9 @@ + struct eth_platform_data *pdata; + int ret; + +- phydev = phy_find_first(bp->mii_bus); ++ // MTR2: use phy 5 ++ //phydev = phy_find_first(bp->mii_bus); ++ phydev = bp->mii_bus->phy_map[5]; + if (!phydev) { + printk (KERN_ERR "%s: no PHY found\n", dev->name); + return -1; +@@ -203,14 +205,19 @@ + /* TODO : add pin_irq */ + + /* attach the mac to the phy */ +- ret = phy_connect_direct(dev, phydev, &macb_handle_link_change, 0, ++ // MTR2: attach directly to phy and set link state ourselves ++ //ret = phy_connect_direct(dev, phydev, &macb_handle_link_change, 0, ++ phy_attach(dev, dev_name(&phydev->dev), 0, + pdata && pdata->is_rmii ? + PHY_INTERFACE_MODE_RMII : + PHY_INTERFACE_MODE_MII); ++ ++ /* + if (ret) { + printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); + return ret; + } ++ */ + + /* mask with MAC supported features */ + phydev->supported &= PHY_BASIC_FEATURES; +@@ -942,6 +949,7 @@ + { + struct macb *bp = netdev_priv(dev); + int err; ++ unsigned long flags; + + dev_dbg(&bp->pdev->dev, "open\n"); + +@@ -966,8 +974,19 @@ + macb_init_hw(bp); + + /* schedule a link state check */ +- phy_start(bp->phy_dev); ++ // MTR2: disable link updates ++ //phy_start(bp->phy_dev); ++ ++ // MTR2: force link up, 100MB, full duplex ++ printk(KERN_INFO "macb: forcing link to 100, full\n"); ++ bp->phy_dev->link = 1; ++ bp->phy_dev->speed = SPEED_100; ++ bp->phy_dev->duplex = 1; ++ macb_handle_link_change(bp->dev); + ++ spin_lock_irqsave(&bp->lock, flags); ++ netif_carrier_on(dev); ++ spin_unlock_irqrestore(&bp->lock, flags); + netif_start_queue(dev); + + return 0; +@@ -981,8 +1000,19 @@ + netif_stop_queue(dev); + napi_disable(&bp->napi); + +- if (bp->phy_dev) +- phy_stop(bp->phy_dev); ++ // MTR2: disabled since we didn't call phy_start ++ //if (bp->phy_dev) ++ // phy_stop(bp->phy_dev); ++ ++ // MTR2: set link down manually ++ if (bp->phy_dev) { ++ printk(KERN_INFO "macb: forcing link down\n"); ++ bp->phy_dev->link = 0; ++ bp->phy_dev->speed = 0; ++ bp->phy_dev->duplex = -1; ++ } ++ ++ macb_handle_link_change(bp->dev); + + spin_lock_irqsave(&bp->lock, flags); + macb_reset_hw(bp); diff --git a/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-mach-at91-mtocgd3.patch b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-mach-at91-mtocgd3.patch new file mode 100644 index 0000000..6fd737b --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-mach-at91-mtocgd3.patch @@ -0,0 +1,425 @@ +Index: linux-2.6.39.4/arch/arm/mach-at91/board-sam9x5cm.c +=================================================================== +--- linux-2.6.39.4.orig/arch/arm/mach-at91/board-sam9x5cm.c 2013-03-07 17:07:04.793136604 -0600 ++++ linux-2.6.39.4/arch/arm/mach-at91/board-sam9x5cm.c 2013-03-07 17:07:04.793136604 -0600 +@@ -18,6 +18,9 @@ + #include <linux/platform_device.h> + #include <linux/spi/flash.h> + #include <linux/spi/spi.h> ++#include <linux/spi/eeprom.h> ++#include <linux/i2c/at24.h> ++#include <linux/delay.h> + #include <linux/fb.h> + #include <linux/gpio_keys.h> + #include <linux/input.h> +@@ -103,6 +106,11 @@ + .irq = -1, + }, + #endif ++ { ++ .modalias = "mts-io-board-temp", ++ .chip_select = 1, ++ .bus_num = 1, ++ }, + #endif + }; + +@@ -111,13 +119,48 @@ + */ + static struct mtd_partition __initdata cm_nand_partition[] = { + { +- .name = "Partition 1", ++ .name = "NANDFlash", ++ .offset = 0, ++ .size = 256*1024*1024, ++ }, ++ { ++ .name = "AT91Bootstrap", + .offset = 0, +- .size = SZ_64M, ++ .size = 256*1024, ++ }, ++ { ++ .name = "UBoot", ++ .offset = 256*1024, ++ .size = 512*1024, ++ }, ++ { ++ .name = "UBoot Config", ++ .offset = 768*1024, ++ .size = 640*1024, ++ }, ++ { ++ .name = "UBoot Redundant Config", ++ .offset = 1408*1024, ++ .size = 640*1024, + }, + { +- .name = "Partition 2", +- .offset = MTDPART_OFS_NXTBLK, ++ .name = "uImage", ++ .offset = 2*1024*1024, ++ .size = 6*1024*1024, ++ }, ++ { ++ .name = "Config", ++ .offset = 8*1024*1024, ++ .size = 8*1024*1024, ++ }, ++ { ++ .name = "Oem Config", ++ .offset = 16*1024*1024, ++ .size = 8*1024*1024, ++ }, ++ { ++ .name = "Rootfs", ++ .offset = 24*1024*1024, + .size = MTDPART_SIZ_FULL, + }, + }; +@@ -135,7 +178,8 @@ + .enable_pin = AT91_PIN_PD4, + .ecc_mode = NAND_ECC_HW, + .has_pmecc = 1, +- .pmecc_corr_cap = 2, ++// MTOCGD3: 4-bit PMECC ++ .pmecc_corr_cap = 4, + .pmecc_sector_size = 512, + .pmecc_lookup_table_offset = 0x8000, + .partition_info = nand_partitions, +@@ -170,7 +214,13 @@ + else + cm_nand_smc_config.mode |= AT91_SMC_DBW_8; + ++ // MTOCGD3 Rev A ++ cm_nand_data.bus_on_d0 = 1; ++ cm_nand_data.rdy_pin = AT91_PIN_PC31; ++ ++ // MTOCGD3: disable + /* revision of board modify NAND wiring */ ++ /* + if (cm_is_revA()) { + cm_nand_data.bus_on_d0 = 1; + cm_nand_data.rdy_pin = AT91_PIN_PD6; +@@ -178,6 +228,7 @@ + cm_nand_data.bus_on_d0 = 0; + cm_nand_data.rdy_pin = AT91_PIN_PD5; + } ++ */ + + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(3, &cm_nand_smc_config); +@@ -189,25 +240,71 @@ + * LEDs + */ + static struct gpio_led cm_leds[] = { +- { /* "left" led, blue, userled1 */ +- .name = "d1", +- .gpio = AT91_PIN_PB18, ++ { /* default status LED */ ++ .name = "led-a", ++ .gpio = AT91_PIN_PA24, ++ .active_low = 1, + .default_trigger = "heartbeat", + }, +- { /* "right" led, red, userled2 */ +- .name = "d2", +- .gpio = AT91_PIN_PD21, +- .active_low = 1, +- .default_trigger = "mmc0", ++ { ++ .name = "led-b", ++ .gpio = AT91_PIN_PA29, ++ .active_low = 1 ++ }, ++ { ++ .name = "led-c", ++ .gpio = AT91_PIN_PA25, ++ .active_low = 1 ++ }, ++ { ++ .name = "led-d", ++ .gpio = AT91_PIN_PA26, ++ .active_low = 1 ++ }, ++ { ++ .name = "led-e", ++ .gpio = AT91_PIN_PA27, ++ .active_low = 1 ++ }, ++ { ++ .name = "led-f", ++ .gpio = AT91_PIN_PA28, ++ .active_low = 1 + }, + }; + ++ ++uint8_t mts_id_eeprom[512]; ++ ++EXPORT_SYMBOL(mts_id_eeprom); ++ ++static void mts_id_eeprom_load(struct memory_accessor *macc, void *context) ++{ ++ int tmp; ++ ++ memset(mts_id_eeprom, 0, sizeof(mts_id_eeprom)); ++ ++ tmp = macc->read(macc, mts_id_eeprom, 0, sizeof(mts_id_eeprom)); ++ if (tmp != sizeof(mts_id_eeprom)) { ++ printk(KERN_ERR "sam9x5: id eeprom read failed: %d\n", tmp); ++ } else { ++ printk(KERN_INFO "sam9x5: read %d bytes from id eeprom\n", tmp); ++ } ++} ++ ++static struct at24_platform_data at24c04_data = { ++ .byte_len = SZ_4K / 8, ++ .page_size = 16, ++ .setup = mts_id_eeprom_load, ++}; ++ + /* + * I2C Devices + */ + static struct i2c_board_info __initdata cm_i2c_devices[] = { + { +- I2C_BOARD_INFO("24c512", 0x50) ++ I2C_BOARD_INFO("24c04", 0x56), ++ .platform_data = &at24c04_data, + }, + }; + +@@ -234,8 +331,12 @@ + /* LEDs */ + at91_gpio_leds(cm_leds, ARRAY_SIZE(cm_leds)); + ++ printk(KERN_CRIT "AT91: MTOCGD3 board\n"); ++ ++ /* MTOCGD3: disable + if (cm_is_revA()) + printk(KERN_CRIT "AT91: CM rev A\n"); + else + printk(KERN_CRIT "AT91: CM rev B and higher\n"); ++ */ + } +Index: linux-2.6.39.4/arch/arm/mach-at91/board-sam9x5ek.c +=================================================================== +--- linux-2.6.39.4.orig/arch/arm/mach-at91/board-sam9x5ek.c 2013-03-07 17:07:03.293174822 -0600 ++++ linux-2.6.39.4/arch/arm/mach-at91/board-sam9x5ek.c 2013-03-08 10:11:42.653155621 -0600 +@@ -23,6 +23,7 @@ + #include <linux/leds.h> + #include <linux/clk.h> + #include <linux/delay.h> ++#include <linux/wl12xx.h> + #include <mach/cpu.h> + + #include <video/atmel_lcdfb.h> +@@ -53,12 +54,10 @@ + /* Initialize processor and DBGU */ + cm_map_io(); + +- /* USART0 on ttyS1. (Rx, Tx) */ +- at91_register_uart(AT91SAM9X5_ID_USART0, 1, 0); +- /* USART1 on ttyS2. (Rx, Tx) */ +- at91_register_uart(AT91SAM9X5_ID_USART1, 2, 0); +- /* USART2 on ttyS3. (Rx, Tx) */ +- at91_register_uart(AT91SAM9X5_ID_USART2, 3, 0); ++ // MTOCGD3: GPS on UART0 as ttyS1 with Rx/Tx only ++ at91_register_uart(AT91SAM9X5_ID_UART0, 1, 0); ++ // MTOCGD3 Rev A: Daughter card serial on USART1 as ttyS2 with RTS/CTS ++ at91_register_uart(AT91SAM9X5_ID_USART1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + } + + /* +@@ -89,34 +88,65 @@ + * MACB Ethernet devices + */ + static struct at91_eth_data __initdata ek_macb0_data = { +- .is_rmii = 1, ++ .is_rmii = 0, ++ .phy_irq_pin = 0, + }; + ++/* MTOCGD3: no macb1 + static struct at91_eth_data __initdata ek_macb1_data = { + .phy_irq_pin = AT91_PIN_PC26, + .is_rmii = 1, + }; ++*/ + + + /* + * MCI (SD/MMC) + */ +-/* mci0 detect_pin is revision dependent */ ++// MTOCGD3: MCI0 is BT/Wifi + static struct mci_platform_data __initdata mci0_data = { + .slot[0] = { + .bus_width = 4, ++ .detect_pin = -1, + .wp_pin = -1, + }, + }; + ++// MTOCGD3: MCI1 is SD card slot + static struct mci_platform_data __initdata mci1_data = { + .slot[0] = { + .bus_width = 4, +- .detect_pin = AT91_PIN_PD14, +- .wp_pin = -1, ++ .detect_pin = AT91_PIN_PA1, ++ .wp_pin = AT91_PIN_PA0, + }, + }; + ++// MTR: Wi-fi ++static void wl12xx_enable(int poweron) ++{ ++ if (poweron) { ++ at91_set_gpio_output_with_pullup(AT91_PIN_PC1, 0, 0); ++ msleep(10); ++ at91_set_gpio_output_with_pullup(AT91_PIN_PC1, 1, 0); ++ msleep(100); ++ printk(KERN_INFO "sam9x5: WLAN Enabled\n"); ++ } ++ else { ++ at91_set_gpio_output_with_pullup(AT91_PIN_PC1, 0, 0); ++ msleep(10); ++ printk(KERN_INFO "sam9x5: WLAN Disabled\n"); ++ } ++}; ++ ++// MTR: Wi-fi ++struct wl12xx_platform_data mtr_wlan_data __initdata = { ++ .irq = AT91_PIN_PC2, ++ /* ref clock is 38.4 MHz */ ++ .board_ref_clock = WL12XX_REFCLOCK_38, ++ /* toggles the WLAN_ENABLE pin */ ++ .set_power = wl12xx_enable, ++}; ++ + /* + * ISI + */ +@@ -326,9 +356,11 @@ + * I2C Devices + */ + static struct i2c_board_info __initdata ek_i2c_devices[] = { ++#if 0 + { + I2C_BOARD_INFO("wm8731", 0x1a) + }, ++#endif + #if defined(CONFIG_KEYBOARD_QT1070) + { + I2C_BOARD_INFO("qt1070", 0x1b), +@@ -384,18 +416,24 @@ + bool config_isi_enabled = false; + + cm_board_init(&cm_config); +- ek_board_configure_pins(); ++ // MTOCGD3: disable ++ //ek_board_configure_pins(); + /* Serial */ + at91_add_device_serial(); + /* USB HS Host */ + at91_add_device_usbh_ohci(&ek_usbh_fs_data); + at91_add_device_usbh_ehci(&ek_usbh_hs_data); + /* USB HS Device */ ++ // MTOCGD3: set usb device vcc pin ++ ek_usba_udc_data.vbus_pin = AT91_PIN_PC7; + at91_add_device_usba(&ek_usba_udc_data); + /* Ethernet */ + at91_add_device_eth(0, &ek_macb0_data); ++ /* MTOCGD3: no macb1 + at91_add_device_eth(1, &ek_macb1_data); ++ */ + /* MMC0 */ ++ // MTOCGD3: MCI0 for BT/Wifi + at91_add_device_mci(0, &mci0_data); + /* I2C */ + if (cm_config & CM_CONFIG_I2C0_ENABLE) +@@ -405,6 +443,18 @@ + at91_add_device_i2c(0, + ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); + ++ // MTOCGD3: Wi-fi ++ at91_set_gpio_input(mtr_wlan_data.irq, 0); ++ at91_set_deglitch(mtr_wlan_data.irq, 1); ++ ++ if (wl12xx_set_platform_data(&mtr_wlan_data)) ++ pr_err("error setting wl12xx data\n"); ++ ++ // MTOCGD3: enable wl1271 chip so it is detected by SDIO scan on start up ++ wl12xx_enable(1); ++ ++/* MTOCGD3: no LCD */ ++#if 0 + if (cpu_is_at91sam9g25()) { + /* ISI */ + /* NOTE: PCK0 provides ISI_MCK to the ISI module. +@@ -430,13 +480,10 @@ + /* Touch Screen */ + at91_add_device_tsadcc(&ek_tsadcc_data); + } ++#endif + +- /* MMC1 */ +- /* Conflict between SPI0, MCI1 and ISI pins. +- * add MCI1 only if SPI0 and ISI are both disabled. +- */ +- if (!(cm_config & CM_CONFIG_SPI0_ENABLE) && !config_isi_enabled) +- at91_add_device_mci(1, &mci1_data); ++ // MTOCGD3: MCI1 to SD Card ++ at91_add_device_mci(1, &mci1_data); + + #if 0 + if (cpu_is_at91sam9x25() || cpu_is_at91sam9x35()) +@@ -448,6 +495,8 @@ + at91_add_device_can(0, NULL); + #endif + ++/* MTOCGD3: disable things we don't have */ ++#if 0 + if (cpu_is_at91sam9x25() || cpu_is_at91sam9x35()) + /* this conflicts with usart.1 */ + at91_add_device_can(1, NULL); +@@ -474,6 +523,9 @@ + else if (config_isi_enabled) + printk(KERN_CRIT + "AT91: ISI conficts with MCI1, disable MCI1\n"); ++#endif ++ ++ printk(KERN_CRIT "AT91: MTOCGD3 board EK init\n"); + } + + MACHINE_START(AT91SAM9X5EK, "Atmel AT91SAM9X5-EK") +Index: linux-2.6.39.4/arch/arm/mach-at91/at91sam9x5_devices.c +=================================================================== +--- linux-2.6.39.4.orig/arch/arm/mach-at91/at91sam9x5_devices.c 2013-03-07 17:07:03.793204785 -0600 ++++ linux-2.6.39.4/arch/arm/mach-at91/at91sam9x5_devices.c 2013-03-07 17:07:04.793136604 -0600 +@@ -543,11 +543,11 @@ + #endif + + /* input/irq */ +- if (data->slot[0].detect_pin) { ++ if (data->slot[0].detect_pin > 0) { + at91_set_gpio_input(data->slot[0].detect_pin, 1); + at91_set_deglitch(data->slot[0].detect_pin, 1); + } +- if (data->slot[0].wp_pin) ++ if (data->slot[0].wp_pin > 0) + at91_set_gpio_input(data->slot[0].wp_pin, 1); + + if (mmc_id == 0) { /* MCI0 */ +@@ -849,7 +849,8 @@ + .num_resources = ARRAY_SIZE(spi1_resources), + }; + +-static const unsigned spi1_standard_cs[4] = { AT91_PIN_PA8, AT91_PIN_PA0, AT91_PIN_PA31, AT91_PIN_PA30 }; ++// MTOCGD3: SPI1 chip selects on pins SPI1_NCS1 to SPI1_NCS5 ++static const unsigned spi1_standard_cs[5] = { AT91_PIN_PC15, AT91_PIN_PC16, AT91_PIN_PC17, AT91_PIN_PC18, AT91_PIN_PC19 }; + + void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) + { diff --git a/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-wl12xx-sdio-irq.patch b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-wl12xx-sdio-irq.patch new file mode 100644 index 0000000..6c1abcd --- /dev/null +++ b/multitech/recipes/linux/linux-2.6.39-at91/mtocgd3/linux-2.6.39.4-wl12xx-sdio-irq.patch @@ -0,0 +1,15 @@ +Index: linux-2.6.39.4/drivers/net/wireless/wl12xx/sdio.c +=================================================================== +--- linux-2.6.39.4.orig/drivers/net/wireless/wl12xx/sdio.c 2012-05-10 11:49:16.349486059 -0500 ++++ linux-2.6.39.4/drivers/net/wireless/wl12xx/sdio.c 2012-05-10 16:36:15.009543390 -0500 +@@ -241,7 +242,9 @@ + wl->ref_clock = wlan_data->board_ref_clock; + + ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, +- IRQF_TRIGGER_HIGH | IRQF_ONESHOT, ++// MTR: use rising edge interrupts, level doesn't work ++// IRQF_TRIGGER_HIGH | IRQF_ONESHOT, ++ IRQF_TRIGGER_RISING, + DRIVER_NAME, wl); + if (ret < 0) { + wl1271_error("request_irq() failed: %d", ret); diff --git a/multitech/recipes/linux/linux_2.6.39-at91.bb b/multitech/recipes/linux/linux_2.6.39-at91.bb new file mode 100644 index 0000000..dc1e89f --- /dev/null +++ b/multitech/recipes/linux/linux_2.6.39-at91.bb @@ -0,0 +1,39 @@ +require recipes/linux/linux.inc + +# PR is set by MACHINE_KERNEL_PR in machine config + +# Linux 2.6.39 for AT91 +# commit Mar 17, 2013 - Serial: 9n12: Enable dbgu dma transfer +SRCREV="0fdbb8dc2ea4f6f4227a855067ed070fe3a9cff1" + +# Add 2.6.39.4 patch customized to patch against at91 branch +SRC_URI = "git://github.com/linux4sam/linux-at91.git;protocol=http;tag=${SRCREV} \ + file://linux-2.6.39.4-at91.patch" + +S = "${WORKDIR}/git" + +SRC_URI_append_mtocgd3 = " \ + file://defconfig \ + file://linux-2.6.39.4-mach-at91-mtocgd3.patch \ + file://linux-2.6.39.4-macb-force-link.patch \ + file://linux-2.6.39.4-ledtrig-netdev.patch \ + file://linux-2.6.39.4-at91sam9x5-extreset.patch \ + file://linux-2.6.39.4-atmel-mci-force-detect.patch \ + file://linux-2.6.39.4-atmel-mci-module-alias.patch \ + file://linux-2.6.39.4-wl12xx-sdio-irq.patch \ + file://linux-2.6.35.14-at91-gpio-pullup.patch \ + file://linux-2.6.32.3-atmel_spi.patch \ + file://linux-2.6.32.3-at25.patch \ + file://linux-2.6.39.4-atmel_serial_disable_hwhs.patch \ + file://linux-2.6.39.4-at91sam9_wdt-10second-timeout.patch \ + file://linux-2.6.35.14-option-zte.patch \ + file://linux-2.6.39.4-option-telit.patch \ + file://linux-2.6.38-sierra-1.7.40.patch \ + file://linux-2.6.39.4-cdc-acm-ignore-exar-devices.patch \ + " + +# add missing crypto headers +sysroot_stage_all_append() { + kerneldir=${SYSROOT_DESTDIR}${STAGING_KERNEL_DIR} + cp -fR include/crypto* $kerneldir/include/ +} |