public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:4.4 commit in: /
Date: Sun, 12 Mar 2017 12:17:45 +0000 (UTC)	[thread overview]
Message-ID: <1489321057.91367744ce5b3751a6e8288292d5d2692aaff55f.mpagano@gentoo> (raw)

commit:     91367744ce5b3751a6e8288292d5d2692aaff55f
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Mar 12 12:17:37 2017 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Mar 12 12:17:37 2017 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=91367744

Linux patch 4.4.53

 0000_README             |    4 +
 1052_linux-4.4.53.patch | 8444 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 8448 insertions(+)

diff --git a/0000_README b/0000_README
index 747896b..ef8c400 100644
--- a/0000_README
+++ b/0000_README
@@ -251,6 +251,10 @@ Patch:  1051_linux-4.4.52.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.4.52
 
+Patch:  1052_linux-4.4.53.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.4.53
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1052_linux-4.4.53.patch b/1052_linux-4.4.53.patch
new file mode 100644
index 0000000..cdd968b
--- /dev/null
+++ b/1052_linux-4.4.53.patch
@@ -0,0 +1,8444 @@
+diff --git a/Documentation/Makefile b/Documentation/Makefile
+index bc0548201755..fc759598c4c9 100644
+--- a/Documentation/Makefile
++++ b/Documentation/Makefile
+@@ -1,4 +1,4 @@
+ subdir-y := accounting auxdisplay blackfin connector \
+-	filesystems filesystems ia64 laptops mic misc-devices \
++	filesystems filesystems ia64 laptops misc-devices \
+ 	networking pcmcia prctl ptp spi timers vDSO video4linux \
+ 	watchdog
+diff --git a/Documentation/mic/Makefile b/Documentation/mic/Makefile
+deleted file mode 100644
+index a191d453badf..000000000000
+--- a/Documentation/mic/Makefile
++++ /dev/null
+@@ -1 +0,0 @@
+-subdir-y := mpssd
+diff --git a/Documentation/mic/mpssd/.gitignore b/Documentation/mic/mpssd/.gitignore
+deleted file mode 100644
+index 8b7c72f07c92..000000000000
+--- a/Documentation/mic/mpssd/.gitignore
++++ /dev/null
+@@ -1 +0,0 @@
+-mpssd
+diff --git a/Documentation/mic/mpssd/Makefile b/Documentation/mic/mpssd/Makefile
+deleted file mode 100644
+index 06871b0c08a6..000000000000
+--- a/Documentation/mic/mpssd/Makefile
++++ /dev/null
+@@ -1,21 +0,0 @@
+-ifndef CROSS_COMPILE
+-# List of programs to build
+-hostprogs-$(CONFIG_X86_64) := mpssd
+-
+-mpssd-objs := mpssd.o sysfs.o
+-
+-# Tell kbuild to always build the programs
+-always := $(hostprogs-y)
+-
+-HOSTCFLAGS += -I$(objtree)/usr/include -I$(srctree)/tools/include
+-
+-ifdef DEBUG
+-HOSTCFLAGS += -DDEBUG=$(DEBUG)
+-endif
+-
+-HOSTLOADLIBES_mpssd := -lpthread
+-
+-install:
+-	install mpssd /usr/sbin/mpssd
+-	install micctrl /usr/sbin/micctrl
+-endif
+diff --git a/Documentation/mic/mpssd/micctrl b/Documentation/mic/mpssd/micctrl
+deleted file mode 100755
+index 8f2629b41c5f..000000000000
+--- a/Documentation/mic/mpssd/micctrl
++++ /dev/null
+@@ -1,173 +0,0 @@
+-#!/bin/bash
+-# Intel MIC Platform Software Stack (MPSS)
+-#
+-# Copyright(c) 2013 Intel Corporation.
+-#
+-# 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.
+-#
+-# This program is distributed in the hope that it will be useful, but
+-# WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+-# General Public License for more details.
+-#
+-# The full GNU General Public License is included in this distribution in
+-# the file called "COPYING".
+-#
+-# Intel MIC User Space Tools.
+-#
+-# micctrl - Controls MIC boot/start/stop.
+-#
+-# chkconfig: 2345 95 05
+-# description: start MPSS stack processing.
+-#
+-### BEGIN INIT INFO
+-# Provides: micctrl
+-### END INIT INFO
+-
+-# Source function library.
+-. /etc/init.d/functions
+-
+-sysfs="/sys/class/mic"
+-
+-_status()
+-{
+-	f=$sysfs/$1
+-	echo -e $1 state: "`cat $f/state`" shutdown_status: "`cat $f/shutdown_status`"
+-}
+-
+-status()
+-{
+-	if [ "`echo $1 | head -c3`" == "mic" ]; then
+-		_status $1
+-		return $?
+-	fi
+-	for f in $sysfs/*
+-	do
+-		_status `basename $f`
+-		RETVAL=$?
+-		[ $RETVAL -ne 0 ] && return $RETVAL
+-	done
+-	return 0
+-}
+-
+-_reset()
+-{
+-	f=$sysfs/$1
+-	echo reset > $f/state
+-}
+-
+-reset()
+-{
+-	if [ "`echo $1 | head -c3`" == "mic" ]; then
+-		_reset $1
+-		return $?
+-	fi
+-	for f in $sysfs/*
+-	do
+-		_reset `basename $f`
+-		RETVAL=$?
+-		[ $RETVAL -ne 0 ] && return $RETVAL
+-	done
+-	return 0
+-}
+-
+-_boot()
+-{
+-	f=$sysfs/$1
+-	echo "linux" > $f/bootmode
+-	echo "mic/uos.img" > $f/firmware
+-	echo "mic/$1.image" > $f/ramdisk
+-	echo "boot" > $f/state
+-}
+-
+-boot()
+-{
+-	if [ "`echo $1 | head -c3`" == "mic" ]; then
+-		_boot $1
+-		return $?
+-	fi
+-	for f in $sysfs/*
+-	do
+-		_boot `basename $f`
+-		RETVAL=$?
+-		[ $RETVAL -ne 0 ] && return $RETVAL
+-	done
+-	return 0
+-}
+-
+-_shutdown()
+-{
+-	f=$sysfs/$1
+-	echo shutdown > $f/state
+-}
+-
+-shutdown()
+-{
+-	if [ "`echo $1 | head -c3`" == "mic" ]; then
+-		_shutdown $1
+-		return $?
+-	fi
+-	for f in $sysfs/*
+-	do
+-		_shutdown `basename $f`
+-		RETVAL=$?
+-		[ $RETVAL -ne 0 ] && return $RETVAL
+-	done
+-	return 0
+-}
+-
+-_wait()
+-{
+-	f=$sysfs/$1
+-	while [ "`cat $f/state`" != "offline" -a "`cat $f/state`" != "online" ]
+-	do
+-		sleep 1
+-		echo -e "Waiting for $1 to go offline"
+-	done
+-}
+-
+-wait()
+-{
+-	if [ "`echo $1 | head -c3`" == "mic" ]; then
+-		_wait $1
+-		return $?
+-	fi
+-	# Wait for the cards to go offline
+-	for f in $sysfs/*
+-	do
+-		_wait `basename $f`
+-		RETVAL=$?
+-		[ $RETVAL -ne 0 ] && return $RETVAL
+-	done
+-	return 0
+-}
+-
+-if [ ! -d "$sysfs" ]; then
+-	echo -e $"Module unloaded "
+-	exit 3
+-fi
+-
+-case $1 in
+-	-s)
+-		status $2
+-		;;
+-	-r)
+-		reset $2
+-		;;
+-	-b)
+-		boot $2
+-		;;
+-	-S)
+-		shutdown $2
+-		;;
+-	-w)
+-		wait $2
+-		;;
+-	*)
+-		echo $"Usage: $0 {-s (status) |-r (reset) |-b (boot) |-S (shutdown) |-w (wait)}"
+-		exit 2
+-esac
+-
+-exit $?
+diff --git a/Documentation/mic/mpssd/mpss b/Documentation/mic/mpssd/mpss
+deleted file mode 100755
+index 09ea90931649..000000000000
+--- a/Documentation/mic/mpssd/mpss
++++ /dev/null
+@@ -1,200 +0,0 @@
+-#!/bin/bash
+-# Intel MIC Platform Software Stack (MPSS)
+-#
+-# Copyright(c) 2013 Intel Corporation.
+-#
+-# 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.
+-#
+-# This program is distributed in the hope that it will be useful, but
+-# WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+-# General Public License for more details.
+-#
+-# The full GNU General Public License is included in this distribution in
+-# the file called "COPYING".
+-#
+-# Intel MIC User Space Tools.
+-#
+-# mpss	Start mpssd.
+-#
+-# chkconfig: 2345 95 05
+-# description: start MPSS stack processing.
+-#
+-### BEGIN INIT INFO
+-# Provides: mpss
+-# Required-Start:
+-# Required-Stop:
+-# Short-Description: MPSS stack control
+-# Description: MPSS stack control
+-### END INIT INFO
+-
+-# Source function library.
+-. /etc/init.d/functions
+-
+-exec=/usr/sbin/mpssd
+-sysfs="/sys/class/mic"
+-mic_modules="mic_host mic_x100_dma scif"
+-
+-start()
+-{
+-	[ -x $exec ] || exit 5
+-
+-	if [ "`ps -e | awk '{print $4}' | grep mpssd | head -1`" = "mpssd" ]; then
+-		echo -e $"MPSSD already running! "
+-		success
+-		echo
+-		return 0
+-	fi
+-
+-	echo -e $"Starting MPSS Stack"
+-	echo -e $"Loading MIC drivers:" $mic_modules
+-
+-	modprobe -a $mic_modules
+-	RETVAL=$?
+-	if [ $RETVAL -ne 0 ]; then
+-		failure
+-		echo
+-		return $RETVAL
+-	fi
+-
+-	# Start the daemon
+-	echo -n $"Starting MPSSD "
+-	$exec
+-	RETVAL=$?
+-	if [ $RETVAL -ne 0 ]; then
+-		failure
+-		echo
+-		return $RETVAL
+-	fi
+-	success
+-	echo
+-
+-	sleep 5
+-
+-	# Boot the cards
+-	micctrl -b
+-
+-	# Wait till ping works
+-	for f in $sysfs/*
+-	do
+-		count=100
+-		ipaddr=`cat $f/cmdline`
+-		ipaddr=${ipaddr#*address,}
+-		ipaddr=`echo $ipaddr | cut -d, -f1 | cut -d\; -f1`
+-		while [ $count -ge 0 ]
+-		do
+-			echo -e "Pinging "`basename $f`" "
+-			ping -c 1 $ipaddr &> /dev/null
+-			RETVAL=$?
+-			if [ $RETVAL -eq 0 ]; then
+-				success
+-				break
+-			fi
+-			sleep 1
+-			count=`expr $count - 1`
+-		done
+-		[ $RETVAL -ne 0 ] && failure || success
+-		echo
+-	done
+-	return $RETVAL
+-}
+-
+-stop()
+-{
+-	echo -e $"Shutting down MPSS Stack: "
+-
+-	# Bail out if module is unloaded
+-	if [ ! -d "$sysfs" ]; then
+-		echo -n $"Module unloaded "
+-		success
+-		echo
+-		return 0
+-	fi
+-
+-	# Shut down the cards.
+-	micctrl -S
+-
+-	# Wait for the cards to go offline
+-	for f in $sysfs/*
+-	do
+-		while [ "`cat $f/state`" != "ready" ]
+-		do
+-			sleep 1
+-			echo -e "Waiting for "`basename $f`" to become ready"
+-		done
+-	done
+-
+-	# Display the status of the cards
+-	micctrl -s
+-
+-	# Kill MPSSD now
+-	echo -n $"Killing MPSSD"
+-	killall -9 mpssd 2>/dev/null
+-	RETVAL=$?
+-	[ $RETVAL -ne 0 ] && failure || success
+-	echo
+-	return $RETVAL
+-}
+-
+-restart()
+-{
+-	stop
+-	sleep 5
+-	start
+-}
+-
+-status()
+-{
+-	micctrl -s
+-	if [ "`ps -e | awk '{print $4}' | grep mpssd | head -n 1`" = "mpssd" ]; then
+-		echo "mpssd is running"
+-	else
+-		echo "mpssd is stopped"
+-	fi
+-	return 0
+-}
+-
+-unload()
+-{
+-	if [ ! -d "$sysfs" ]; then
+-		echo -n $"No MIC_HOST Module: "
+-		success
+-		echo
+-		return
+-	fi
+-
+-	stop
+-
+-	sleep 5
+-	echo -n $"Removing MIC drivers:" $mic_modules
+-	modprobe -r $mic_modules
+-	RETVAL=$?
+-	[ $RETVAL -ne 0 ] && failure || success
+-	echo
+-	return $RETVAL
+-}
+-
+-case $1 in
+-	start)
+-		start
+-		;;
+-	stop)
+-		stop
+-		;;
+-	restart)
+-		restart
+-		;;
+-	status)
+-		status
+-		;;
+-	unload)
+-		unload
+-		;;
+-	*)
+-		echo $"Usage: $0 {start|stop|restart|status|unload}"
+-		exit 2
+-esac
+-
+-exit $?
+diff --git a/Documentation/mic/mpssd/mpssd.c b/Documentation/mic/mpssd/mpssd.c
+deleted file mode 100644
+index c99a75968c01..000000000000
+--- a/Documentation/mic/mpssd/mpssd.c
++++ /dev/null
+@@ -1,1826 +0,0 @@
+-/*
+- * Intel MIC Platform Software Stack (MPSS)
+- *
+- * Copyright(c) 2013 Intel Corporation.
+- *
+- * 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.
+- *
+- * This program is distributed in the hope that it will be useful, but
+- * WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+- * General Public License for more details.
+- *
+- * The full GNU General Public License is included in this distribution in
+- * the file called "COPYING".
+- *
+- * Intel MIC User Space Tools.
+- */
+-
+-#define _GNU_SOURCE
+-
+-#include <stdlib.h>
+-#include <fcntl.h>
+-#include <getopt.h>
+-#include <assert.h>
+-#include <unistd.h>
+-#include <stdbool.h>
+-#include <signal.h>
+-#include <poll.h>
+-#include <features.h>
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <sys/mman.h>
+-#include <sys/socket.h>
+-#include <linux/virtio_ring.h>
+-#include <linux/virtio_net.h>
+-#include <linux/virtio_console.h>
+-#include <linux/virtio_blk.h>
+-#include <linux/version.h>
+-#include "mpssd.h"
+-#include <linux/mic_ioctl.h>
+-#include <linux/mic_common.h>
+-#include <tools/endian.h>
+-
+-static void *init_mic(void *arg);
+-
+-static FILE *logfp;
+-static struct mic_info mic_list;
+-
+-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+-
+-#define min_t(type, x, y) ({				\
+-		type __min1 = (x);                      \
+-		type __min2 = (y);                      \
+-		__min1 < __min2 ? __min1 : __min2; })
+-
+-/* align addr on a size boundary - adjust address up/down if needed */
+-#define _ALIGN_DOWN(addr, size)  ((addr)&(~((size)-1)))
+-#define _ALIGN_UP(addr, size)    _ALIGN_DOWN(addr + size - 1, size)
+-
+-/* align addr on a size boundary - adjust address up if needed */
+-#define _ALIGN(addr, size)     _ALIGN_UP(addr, size)
+-
+-/* to align the pointer to the (next) page boundary */
+-#define PAGE_ALIGN(addr)        _ALIGN(addr, PAGE_SIZE)
+-
+-#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+-
+-#define GSO_ENABLED		1
+-#define MAX_GSO_SIZE		(64 * 1024)
+-#define ETH_H_LEN		14
+-#define MAX_NET_PKT_SIZE	(_ALIGN_UP(MAX_GSO_SIZE + ETH_H_LEN, 64))
+-#define MIC_DEVICE_PAGE_END	0x1000
+-
+-#ifndef VIRTIO_NET_HDR_F_DATA_VALID
+-#define VIRTIO_NET_HDR_F_DATA_VALID	2	/* Csum is valid */
+-#endif
+-
+-static struct {
+-	struct mic_device_desc dd;
+-	struct mic_vqconfig vqconfig[2];
+-	__u32 host_features, guest_acknowledgements;
+-	struct virtio_console_config cons_config;
+-} virtcons_dev_page = {
+-	.dd = {
+-		.type = VIRTIO_ID_CONSOLE,
+-		.num_vq = ARRAY_SIZE(virtcons_dev_page.vqconfig),
+-		.feature_len = sizeof(virtcons_dev_page.host_features),
+-		.config_len = sizeof(virtcons_dev_page.cons_config),
+-	},
+-	.vqconfig[0] = {
+-		.num = htole16(MIC_VRING_ENTRIES),
+-	},
+-	.vqconfig[1] = {
+-		.num = htole16(MIC_VRING_ENTRIES),
+-	},
+-};
+-
+-static struct {
+-	struct mic_device_desc dd;
+-	struct mic_vqconfig vqconfig[2];
+-	__u32 host_features, guest_acknowledgements;
+-	struct virtio_net_config net_config;
+-} virtnet_dev_page = {
+-	.dd = {
+-		.type = VIRTIO_ID_NET,
+-		.num_vq = ARRAY_SIZE(virtnet_dev_page.vqconfig),
+-		.feature_len = sizeof(virtnet_dev_page.host_features),
+-		.config_len = sizeof(virtnet_dev_page.net_config),
+-	},
+-	.vqconfig[0] = {
+-		.num = htole16(MIC_VRING_ENTRIES),
+-	},
+-	.vqconfig[1] = {
+-		.num = htole16(MIC_VRING_ENTRIES),
+-	},
+-#if GSO_ENABLED
+-	.host_features = htole32(
+-		1 << VIRTIO_NET_F_CSUM |
+-		1 << VIRTIO_NET_F_GSO |
+-		1 << VIRTIO_NET_F_GUEST_TSO4 |
+-		1 << VIRTIO_NET_F_GUEST_TSO6 |
+-		1 << VIRTIO_NET_F_GUEST_ECN),
+-#else
+-		.host_features = 0,
+-#endif
+-};
+-
+-static const char *mic_config_dir = "/etc/mpss";
+-static const char *virtblk_backend = "VIRTBLK_BACKEND";
+-static struct {
+-	struct mic_device_desc dd;
+-	struct mic_vqconfig vqconfig[1];
+-	__u32 host_features, guest_acknowledgements;
+-	struct virtio_blk_config blk_config;
+-} virtblk_dev_page = {
+-	.dd = {
+-		.type = VIRTIO_ID_BLOCK,
+-		.num_vq = ARRAY_SIZE(virtblk_dev_page.vqconfig),
+-		.feature_len = sizeof(virtblk_dev_page.host_features),
+-		.config_len = sizeof(virtblk_dev_page.blk_config),
+-	},
+-	.vqconfig[0] = {
+-		.num = htole16(MIC_VRING_ENTRIES),
+-	},
+-	.host_features =
+-		htole32(1<<VIRTIO_BLK_F_SEG_MAX),
+-	.blk_config = {
+-		.seg_max = htole32(MIC_VRING_ENTRIES - 2),
+-		.capacity = htole64(0),
+-	 }
+-};
+-
+-static char *myname;
+-
+-static int
+-tap_configure(struct mic_info *mic, char *dev)
+-{
+-	pid_t pid;
+-	char *ifargv[7];
+-	char ipaddr[IFNAMSIZ];
+-	int ret = 0;
+-
+-	pid = fork();
+-	if (pid == 0) {
+-		ifargv[0] = "ip";
+-		ifargv[1] = "link";
+-		ifargv[2] = "set";
+-		ifargv[3] = dev;
+-		ifargv[4] = "up";
+-		ifargv[5] = NULL;
+-		mpsslog("Configuring %s\n", dev);
+-		ret = execvp("ip", ifargv);
+-		if (ret < 0) {
+-			mpsslog("%s execvp failed errno %s\n",
+-				mic->name, strerror(errno));
+-			return ret;
+-		}
+-	}
+-	if (pid < 0) {
+-		mpsslog("%s fork failed errno %s\n",
+-			mic->name, strerror(errno));
+-		return ret;
+-	}
+-
+-	ret = waitpid(pid, NULL, 0);
+-	if (ret < 0) {
+-		mpsslog("%s waitpid failed errno %s\n",
+-			mic->name, strerror(errno));
+-		return ret;
+-	}
+-
+-	snprintf(ipaddr, IFNAMSIZ, "172.31.%d.254/24", mic->id + 1);
+-
+-	pid = fork();
+-	if (pid == 0) {
+-		ifargv[0] = "ip";
+-		ifargv[1] = "addr";
+-		ifargv[2] = "add";
+-		ifargv[3] = ipaddr;
+-		ifargv[4] = "dev";
+-		ifargv[5] = dev;
+-		ifargv[6] = NULL;
+-		mpsslog("Configuring %s ipaddr %s\n", dev, ipaddr);
+-		ret = execvp("ip", ifargv);
+-		if (ret < 0) {
+-			mpsslog("%s execvp failed errno %s\n",
+-				mic->name, strerror(errno));
+-			return ret;
+-		}
+-	}
+-	if (pid < 0) {
+-		mpsslog("%s fork failed errno %s\n",
+-			mic->name, strerror(errno));
+-		return ret;
+-	}
+-
+-	ret = waitpid(pid, NULL, 0);
+-	if (ret < 0) {
+-		mpsslog("%s waitpid failed errno %s\n",
+-			mic->name, strerror(errno));
+-		return ret;
+-	}
+-	mpsslog("MIC name %s %s %d DONE!\n",
+-		mic->name, __func__, __LINE__);
+-	return 0;
+-}
+-
+-static int tun_alloc(struct mic_info *mic, char *dev)
+-{
+-	struct ifreq ifr;
+-	int fd, err;
+-#if GSO_ENABLED
+-	unsigned offload;
+-#endif
+-	fd = open("/dev/net/tun", O_RDWR);
+-	if (fd < 0) {
+-		mpsslog("Could not open /dev/net/tun %s\n", strerror(errno));
+-		goto done;
+-	}
+-
+-	memset(&ifr, 0, sizeof(ifr));
+-
+-	ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
+-	if (*dev)
+-		strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+-
+-	err = ioctl(fd, TUNSETIFF, (void *)&ifr);
+-	if (err < 0) {
+-		mpsslog("%s %s %d TUNSETIFF failed %s\n",
+-			mic->name, __func__, __LINE__, strerror(errno));
+-		close(fd);
+-		return err;
+-	}
+-#if GSO_ENABLED
+-	offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_TSO_ECN;
+-
+-	err = ioctl(fd, TUNSETOFFLOAD, offload);
+-	if (err < 0) {
+-		mpsslog("%s %s %d TUNSETOFFLOAD failed %s\n",
+-			mic->name, __func__, __LINE__, strerror(errno));
+-		close(fd);
+-		return err;
+-	}
+-#endif
+-	strcpy(dev, ifr.ifr_name);
+-	mpsslog("Created TAP %s\n", dev);
+-done:
+-	return fd;
+-}
+-
+-#define NET_FD_VIRTIO_NET 0
+-#define NET_FD_TUN 1
+-#define MAX_NET_FD 2
+-
+-static void set_dp(struct mic_info *mic, int type, void *dp)
+-{
+-	switch (type) {
+-	case VIRTIO_ID_CONSOLE:
+-		mic->mic_console.console_dp = dp;
+-		return;
+-	case VIRTIO_ID_NET:
+-		mic->mic_net.net_dp = dp;
+-		return;
+-	case VIRTIO_ID_BLOCK:
+-		mic->mic_virtblk.block_dp = dp;
+-		return;
+-	}
+-	mpsslog("%s %s %d not found\n", mic->name, __func__, type);
+-	assert(0);
+-}
+-
+-static void *get_dp(struct mic_info *mic, int type)
+-{
+-	switch (type) {
+-	case VIRTIO_ID_CONSOLE:
+-		return mic->mic_console.console_dp;
+-	case VIRTIO_ID_NET:
+-		return mic->mic_net.net_dp;
+-	case VIRTIO_ID_BLOCK:
+-		return mic->mic_virtblk.block_dp;
+-	}
+-	mpsslog("%s %s %d not found\n", mic->name, __func__, type);
+-	assert(0);
+-	return NULL;
+-}
+-
+-static struct mic_device_desc *get_device_desc(struct mic_info *mic, int type)
+-{
+-	struct mic_device_desc *d;
+-	int i;
+-	void *dp = get_dp(mic, type);
+-
+-	for (i = sizeof(struct mic_bootparam); i < PAGE_SIZE;
+-		i += mic_total_desc_size(d)) {
+-		d = dp + i;
+-
+-		/* End of list */
+-		if (d->type == 0)
+-			break;
+-
+-		if (d->type == -1)
+-			continue;
+-
+-		mpsslog("%s %s d-> type %d d %p\n",
+-			mic->name, __func__, d->type, d);
+-
+-		if (d->type == (__u8)type)
+-			return d;
+-	}
+-	mpsslog("%s %s %d not found\n", mic->name, __func__, type);
+-	return NULL;
+-}
+-
+-/* See comments in vhost.c for explanation of next_desc() */
+-static unsigned next_desc(struct vring_desc *desc)
+-{
+-	unsigned int next;
+-
+-	if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT))
+-		return -1U;
+-	next = le16toh(desc->next);
+-	return next;
+-}
+-
+-/* Sum up all the IOVEC length */
+-static ssize_t
+-sum_iovec_len(struct mic_copy_desc *copy)
+-{
+-	ssize_t sum = 0;
+-	int i;
+-
+-	for (i = 0; i < copy->iovcnt; i++)
+-		sum += copy->iov[i].iov_len;
+-	return sum;
+-}
+-
+-static inline void verify_out_len(struct mic_info *mic,
+-	struct mic_copy_desc *copy)
+-{
+-	if (copy->out_len != sum_iovec_len(copy)) {
+-		mpsslog("%s %s %d BUG copy->out_len 0x%x len 0x%zx\n",
+-			mic->name, __func__, __LINE__,
+-			copy->out_len, sum_iovec_len(copy));
+-		assert(copy->out_len == sum_iovec_len(copy));
+-	}
+-}
+-
+-/* Display an iovec */
+-static void
+-disp_iovec(struct mic_info *mic, struct mic_copy_desc *copy,
+-	   const char *s, int line)
+-{
+-	int i;
+-
+-	for (i = 0; i < copy->iovcnt; i++)
+-		mpsslog("%s %s %d copy->iov[%d] addr %p len 0x%zx\n",
+-			mic->name, s, line, i,
+-			copy->iov[i].iov_base, copy->iov[i].iov_len);
+-}
+-
+-static inline __u16 read_avail_idx(struct mic_vring *vr)
+-{
+-	return ACCESS_ONCE(vr->info->avail_idx);
+-}
+-
+-static inline void txrx_prepare(int type, bool tx, struct mic_vring *vr,
+-				struct mic_copy_desc *copy, ssize_t len)
+-{
+-	copy->vr_idx = tx ? 0 : 1;
+-	copy->update_used = true;
+-	if (type == VIRTIO_ID_NET)
+-		copy->iov[1].iov_len = len - sizeof(struct virtio_net_hdr);
+-	else
+-		copy->iov[0].iov_len = len;
+-}
+-
+-/* Central API which triggers the copies */
+-static int
+-mic_virtio_copy(struct mic_info *mic, int fd,
+-		struct mic_vring *vr, struct mic_copy_desc *copy)
+-{
+-	int ret;
+-
+-	ret = ioctl(fd, MIC_VIRTIO_COPY_DESC, copy);
+-	if (ret) {
+-		mpsslog("%s %s %d errno %s ret %d\n",
+-			mic->name, __func__, __LINE__,
+-			strerror(errno), ret);
+-	}
+-	return ret;
+-}
+-
+-static inline unsigned _vring_size(unsigned int num, unsigned long align)
+-{
+-	return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num)
+-				+ align - 1) & ~(align - 1))
+-		+ sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num;
+-}
+-
+-/*
+- * This initialization routine requires at least one
+- * vring i.e. vr0. vr1 is optional.
+- */
+-static void *
+-init_vr(struct mic_info *mic, int fd, int type,
+-	struct mic_vring *vr0, struct mic_vring *vr1, int num_vq)
+-{
+-	int vr_size;
+-	char *va;
+-
+-	vr_size = PAGE_ALIGN(_vring_size(MIC_VRING_ENTRIES,
+-					 MIC_VIRTIO_RING_ALIGN) +
+-			     sizeof(struct _mic_vring_info));
+-	va = mmap(NULL, MIC_DEVICE_PAGE_END + vr_size * num_vq,
+-		PROT_READ, MAP_SHARED, fd, 0);
+-	if (MAP_FAILED == va) {
+-		mpsslog("%s %s %d mmap failed errno %s\n",
+-			mic->name, __func__, __LINE__,
+-			strerror(errno));
+-		goto done;
+-	}
+-	set_dp(mic, type, va);
+-	vr0->va = (struct mic_vring *)&va[MIC_DEVICE_PAGE_END];
+-	vr0->info = vr0->va +
+-		_vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN);
+-	vring_init(&vr0->vr,
+-		   MIC_VRING_ENTRIES, vr0->va, MIC_VIRTIO_RING_ALIGN);
+-	mpsslog("%s %s vr0 %p vr0->info %p vr_size 0x%x vring 0x%x ",
+-		__func__, mic->name, vr0->va, vr0->info, vr_size,
+-		_vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
+-	mpsslog("magic 0x%x expected 0x%x\n",
+-		le32toh(vr0->info->magic), MIC_MAGIC + type);
+-	assert(le32toh(vr0->info->magic) == MIC_MAGIC + type);
+-	if (vr1) {
+-		vr1->va = (struct mic_vring *)
+-			&va[MIC_DEVICE_PAGE_END + vr_size];
+-		vr1->info = vr1->va + _vring_size(MIC_VRING_ENTRIES,
+-			MIC_VIRTIO_RING_ALIGN);
+-		vring_init(&vr1->vr,
+-			   MIC_VRING_ENTRIES, vr1->va, MIC_VIRTIO_RING_ALIGN);
+-		mpsslog("%s %s vr1 %p vr1->info %p vr_size 0x%x vring 0x%x ",
+-			__func__, mic->name, vr1->va, vr1->info, vr_size,
+-			_vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
+-		mpsslog("magic 0x%x expected 0x%x\n",
+-			le32toh(vr1->info->magic), MIC_MAGIC + type + 1);
+-		assert(le32toh(vr1->info->magic) == MIC_MAGIC + type + 1);
+-	}
+-done:
+-	return va;
+-}
+-
+-static int
+-wait_for_card_driver(struct mic_info *mic, int fd, int type)
+-{
+-	struct pollfd pollfd;
+-	int err;
+-	struct mic_device_desc *desc = get_device_desc(mic, type);
+-	__u8 prev_status;
+-
+-	if (!desc)
+-		return -ENODEV;
+-	prev_status = desc->status;
+-	pollfd.fd = fd;
+-	mpsslog("%s %s Waiting .... desc-> type %d status 0x%x\n",
+-		mic->name, __func__, type, desc->status);
+-
+-	while (1) {
+-		pollfd.events = POLLIN;
+-		pollfd.revents = 0;
+-		err = poll(&pollfd, 1, -1);
+-		if (err < 0) {
+-			mpsslog("%s %s poll failed %s\n",
+-				mic->name, __func__, strerror(errno));
+-			continue;
+-		}
+-
+-		if (pollfd.revents) {
+-			if (desc->status != prev_status) {
+-				mpsslog("%s %s Waiting... desc-> type %d "
+-					"status 0x%x\n",
+-					mic->name, __func__, type,
+-					desc->status);
+-				prev_status = desc->status;
+-			}
+-			if (desc->status & VIRTIO_CONFIG_S_DRIVER_OK) {
+-				mpsslog("%s %s poll.revents %d\n",
+-					mic->name, __func__, pollfd.revents);
+-				mpsslog("%s %s desc-> type %d status 0x%x\n",
+-					mic->name, __func__, type,
+-					desc->status);
+-				break;
+-			}
+-		}
+-	}
+-	return 0;
+-}
+-
+-/* Spin till we have some descriptors */
+-static void
+-spin_for_descriptors(struct mic_info *mic, struct mic_vring *vr)
+-{
+-	__u16 avail_idx = read_avail_idx(vr);
+-
+-	while (avail_idx == le16toh(ACCESS_ONCE(vr->vr.avail->idx))) {
+-#ifdef DEBUG
+-		mpsslog("%s %s waiting for desc avail %d info_avail %d\n",
+-			mic->name, __func__,
+-			le16toh(vr->vr.avail->idx), vr->info->avail_idx);
+-#endif
+-		sched_yield();
+-	}
+-}
+-
+-static void *
+-virtio_net(void *arg)
+-{
+-	static __u8 vnet_hdr[2][sizeof(struct virtio_net_hdr)];
+-	static __u8 vnet_buf[2][MAX_NET_PKT_SIZE] __attribute__ ((aligned(64)));
+-	struct iovec vnet_iov[2][2] = {
+-		{ { .iov_base = vnet_hdr[0], .iov_len = sizeof(vnet_hdr[0]) },
+-		  { .iov_base = vnet_buf[0], .iov_len = sizeof(vnet_buf[0]) } },
+-		{ { .iov_base = vnet_hdr[1], .iov_len = sizeof(vnet_hdr[1]) },
+-		  { .iov_base = vnet_buf[1], .iov_len = sizeof(vnet_buf[1]) } },
+-	};
+-	struct iovec *iov0 = vnet_iov[0], *iov1 = vnet_iov[1];
+-	struct mic_info *mic = (struct mic_info *)arg;
+-	char if_name[IFNAMSIZ];
+-	struct pollfd net_poll[MAX_NET_FD];
+-	struct mic_vring tx_vr, rx_vr;
+-	struct mic_copy_desc copy;
+-	struct mic_device_desc *desc;
+-	int err;
+-
+-	snprintf(if_name, IFNAMSIZ, "mic%d", mic->id);
+-	mic->mic_net.tap_fd = tun_alloc(mic, if_name);
+-	if (mic->mic_net.tap_fd < 0)
+-		goto done;
+-
+-	if (tap_configure(mic, if_name))
+-		goto done;
+-	mpsslog("MIC name %s id %d\n", mic->name, mic->id);
+-
+-	net_poll[NET_FD_VIRTIO_NET].fd = mic->mic_net.virtio_net_fd;
+-	net_poll[NET_FD_VIRTIO_NET].events = POLLIN;
+-	net_poll[NET_FD_TUN].fd = mic->mic_net.tap_fd;
+-	net_poll[NET_FD_TUN].events = POLLIN;
+-
+-	if (MAP_FAILED == init_vr(mic, mic->mic_net.virtio_net_fd,
+-				  VIRTIO_ID_NET, &tx_vr, &rx_vr,
+-		virtnet_dev_page.dd.num_vq)) {
+-		mpsslog("%s init_vr failed %s\n",
+-			mic->name, strerror(errno));
+-		goto done;
+-	}
+-
+-	copy.iovcnt = 2;
+-	desc = get_device_desc(mic, VIRTIO_ID_NET);
+-
+-	while (1) {
+-		ssize_t len;
+-
+-		net_poll[NET_FD_VIRTIO_NET].revents = 0;
+-		net_poll[NET_FD_TUN].revents = 0;
+-
+-		/* Start polling for data from tap and virtio net */
+-		err = poll(net_poll, 2, -1);
+-		if (err < 0) {
+-			mpsslog("%s poll failed %s\n",
+-				__func__, strerror(errno));
+-			continue;
+-		}
+-		if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+-			err = wait_for_card_driver(mic,
+-						   mic->mic_net.virtio_net_fd,
+-						   VIRTIO_ID_NET);
+-			if (err) {
+-				mpsslog("%s %s %d Exiting...\n",
+-					mic->name, __func__, __LINE__);
+-				break;
+-			}
+-		}
+-		/*
+-		 * Check if there is data to be read from TUN and write to
+-		 * virtio net fd if there is.
+-		 */
+-		if (net_poll[NET_FD_TUN].revents & POLLIN) {
+-			copy.iov = iov0;
+-			len = readv(net_poll[NET_FD_TUN].fd,
+-				copy.iov, copy.iovcnt);
+-			if (len > 0) {
+-				struct virtio_net_hdr *hdr
+-					= (struct virtio_net_hdr *)vnet_hdr[0];
+-
+-				/* Disable checksums on the card since we are on
+-				   a reliable PCIe link */
+-				hdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;
+-#ifdef DEBUG
+-				mpsslog("%s %s %d hdr->flags 0x%x ", mic->name,
+-					__func__, __LINE__, hdr->flags);
+-				mpsslog("copy.out_len %d hdr->gso_type 0x%x\n",
+-					copy.out_len, hdr->gso_type);
+-#endif
+-#ifdef DEBUG
+-				disp_iovec(mic, copy, __func__, __LINE__);
+-				mpsslog("%s %s %d read from tap 0x%lx\n",
+-					mic->name, __func__, __LINE__,
+-					len);
+-#endif
+-				spin_for_descriptors(mic, &tx_vr);
+-				txrx_prepare(VIRTIO_ID_NET, 1, &tx_vr, &copy,
+-					     len);
+-
+-				err = mic_virtio_copy(mic,
+-					mic->mic_net.virtio_net_fd, &tx_vr,
+-					&copy);
+-				if (err < 0) {
+-					mpsslog("%s %s %d mic_virtio_copy %s\n",
+-						mic->name, __func__, __LINE__,
+-						strerror(errno));
+-				}
+-				if (!err)
+-					verify_out_len(mic, &copy);
+-#ifdef DEBUG
+-				disp_iovec(mic, copy, __func__, __LINE__);
+-				mpsslog("%s %s %d wrote to net 0x%lx\n",
+-					mic->name, __func__, __LINE__,
+-					sum_iovec_len(&copy));
+-#endif
+-				/* Reinitialize IOV for next run */
+-				iov0[1].iov_len = MAX_NET_PKT_SIZE;
+-			} else if (len < 0) {
+-				disp_iovec(mic, &copy, __func__, __LINE__);
+-				mpsslog("%s %s %d read failed %s ", mic->name,
+-					__func__, __LINE__, strerror(errno));
+-				mpsslog("cnt %d sum %zd\n",
+-					copy.iovcnt, sum_iovec_len(&copy));
+-			}
+-		}
+-
+-		/*
+-		 * Check if there is data to be read from virtio net and
+-		 * write to TUN if there is.
+-		 */
+-		if (net_poll[NET_FD_VIRTIO_NET].revents & POLLIN) {
+-			while (rx_vr.info->avail_idx !=
+-				le16toh(rx_vr.vr.avail->idx)) {
+-				copy.iov = iov1;
+-				txrx_prepare(VIRTIO_ID_NET, 0, &rx_vr, &copy,
+-					     MAX_NET_PKT_SIZE
+-					+ sizeof(struct virtio_net_hdr));
+-
+-				err = mic_virtio_copy(mic,
+-					mic->mic_net.virtio_net_fd, &rx_vr,
+-					&copy);
+-				if (!err) {
+-#ifdef DEBUG
+-					struct virtio_net_hdr *hdr
+-						= (struct virtio_net_hdr *)
+-							vnet_hdr[1];
+-
+-					mpsslog("%s %s %d hdr->flags 0x%x, ",
+-						mic->name, __func__, __LINE__,
+-						hdr->flags);
+-					mpsslog("out_len %d gso_type 0x%x\n",
+-						copy.out_len,
+-						hdr->gso_type);
+-#endif
+-					/* Set the correct output iov_len */
+-					iov1[1].iov_len = copy.out_len -
+-						sizeof(struct virtio_net_hdr);
+-					verify_out_len(mic, &copy);
+-#ifdef DEBUG
+-					disp_iovec(mic, copy, __func__,
+-						   __LINE__);
+-					mpsslog("%s %s %d ",
+-						mic->name, __func__, __LINE__);
+-					mpsslog("read from net 0x%lx\n",
+-						sum_iovec_len(copy));
+-#endif
+-					len = writev(net_poll[NET_FD_TUN].fd,
+-						copy.iov, copy.iovcnt);
+-					if (len != sum_iovec_len(&copy)) {
+-						mpsslog("Tun write failed %s ",
+-							strerror(errno));
+-						mpsslog("len 0x%zx ", len);
+-						mpsslog("read_len 0x%zx\n",
+-							sum_iovec_len(&copy));
+-					} else {
+-#ifdef DEBUG
+-						disp_iovec(mic, &copy, __func__,
+-							   __LINE__);
+-						mpsslog("%s %s %d ",
+-							mic->name, __func__,
+-							__LINE__);
+-						mpsslog("wrote to tap 0x%lx\n",
+-							len);
+-#endif
+-					}
+-				} else {
+-					mpsslog("%s %s %d mic_virtio_copy %s\n",
+-						mic->name, __func__, __LINE__,
+-						strerror(errno));
+-					break;
+-				}
+-			}
+-		}
+-		if (net_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
+-			mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
+-	}
+-done:
+-	pthread_exit(NULL);
+-}
+-
+-/* virtio_console */
+-#define VIRTIO_CONSOLE_FD 0
+-#define MONITOR_FD (VIRTIO_CONSOLE_FD + 1)
+-#define MAX_CONSOLE_FD (MONITOR_FD + 1)  /* must be the last one + 1 */
+-#define MAX_BUFFER_SIZE PAGE_SIZE
+-
+-static void *
+-virtio_console(void *arg)
+-{
+-	static __u8 vcons_buf[2][PAGE_SIZE];
+-	struct iovec vcons_iov[2] = {
+-		{ .iov_base = vcons_buf[0], .iov_len = sizeof(vcons_buf[0]) },
+-		{ .iov_base = vcons_buf[1], .iov_len = sizeof(vcons_buf[1]) },
+-	};
+-	struct iovec *iov0 = &vcons_iov[0], *iov1 = &vcons_iov[1];
+-	struct mic_info *mic = (struct mic_info *)arg;
+-	int err;
+-	struct pollfd console_poll[MAX_CONSOLE_FD];
+-	int pty_fd;
+-	char *pts_name;
+-	ssize_t len;
+-	struct mic_vring tx_vr, rx_vr;
+-	struct mic_copy_desc copy;
+-	struct mic_device_desc *desc;
+-
+-	pty_fd = posix_openpt(O_RDWR);
+-	if (pty_fd < 0) {
+-		mpsslog("can't open a pseudoterminal master device: %s\n",
+-			strerror(errno));
+-		goto _return;
+-	}
+-	pts_name = ptsname(pty_fd);
+-	if (pts_name == NULL) {
+-		mpsslog("can't get pts name\n");
+-		goto _close_pty;
+-	}
+-	printf("%s console message goes to %s\n", mic->name, pts_name);
+-	mpsslog("%s console message goes to %s\n", mic->name, pts_name);
+-	err = grantpt(pty_fd);
+-	if (err < 0) {
+-		mpsslog("can't grant access: %s %s\n",
+-			pts_name, strerror(errno));
+-		goto _close_pty;
+-	}
+-	err = unlockpt(pty_fd);
+-	if (err < 0) {
+-		mpsslog("can't unlock a pseudoterminal: %s %s\n",
+-			pts_name, strerror(errno));
+-		goto _close_pty;
+-	}
+-	console_poll[MONITOR_FD].fd = pty_fd;
+-	console_poll[MONITOR_FD].events = POLLIN;
+-
+-	console_poll[VIRTIO_CONSOLE_FD].fd = mic->mic_console.virtio_console_fd;
+-	console_poll[VIRTIO_CONSOLE_FD].events = POLLIN;
+-
+-	if (MAP_FAILED == init_vr(mic, mic->mic_console.virtio_console_fd,
+-				  VIRTIO_ID_CONSOLE, &tx_vr, &rx_vr,
+-		virtcons_dev_page.dd.num_vq)) {
+-		mpsslog("%s init_vr failed %s\n",
+-			mic->name, strerror(errno));
+-		goto _close_pty;
+-	}
+-
+-	copy.iovcnt = 1;
+-	desc = get_device_desc(mic, VIRTIO_ID_CONSOLE);
+-
+-	for (;;) {
+-		console_poll[MONITOR_FD].revents = 0;
+-		console_poll[VIRTIO_CONSOLE_FD].revents = 0;
+-		err = poll(console_poll, MAX_CONSOLE_FD, -1);
+-		if (err < 0) {
+-			mpsslog("%s %d: poll failed: %s\n", __func__, __LINE__,
+-				strerror(errno));
+-			continue;
+-		}
+-		if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+-			err = wait_for_card_driver(mic,
+-					mic->mic_console.virtio_console_fd,
+-					VIRTIO_ID_CONSOLE);
+-			if (err) {
+-				mpsslog("%s %s %d Exiting...\n",
+-					mic->name, __func__, __LINE__);
+-				break;
+-			}
+-		}
+-
+-		if (console_poll[MONITOR_FD].revents & POLLIN) {
+-			copy.iov = iov0;
+-			len = readv(pty_fd, copy.iov, copy.iovcnt);
+-			if (len > 0) {
+-#ifdef DEBUG
+-				disp_iovec(mic, copy, __func__, __LINE__);
+-				mpsslog("%s %s %d read from tap 0x%lx\n",
+-					mic->name, __func__, __LINE__,
+-					len);
+-#endif
+-				spin_for_descriptors(mic, &tx_vr);
+-				txrx_prepare(VIRTIO_ID_CONSOLE, 1, &tx_vr,
+-					     &copy, len);
+-
+-				err = mic_virtio_copy(mic,
+-					mic->mic_console.virtio_console_fd,
+-					&tx_vr, &copy);
+-				if (err < 0) {
+-					mpsslog("%s %s %d mic_virtio_copy %s\n",
+-						mic->name, __func__, __LINE__,
+-						strerror(errno));
+-				}
+-				if (!err)
+-					verify_out_len(mic, &copy);
+-#ifdef DEBUG
+-				disp_iovec(mic, copy, __func__, __LINE__);
+-				mpsslog("%s %s %d wrote to net 0x%lx\n",
+-					mic->name, __func__, __LINE__,
+-					sum_iovec_len(copy));
+-#endif
+-				/* Reinitialize IOV for next run */
+-				iov0->iov_len = PAGE_SIZE;
+-			} else if (len < 0) {
+-				disp_iovec(mic, &copy, __func__, __LINE__);
+-				mpsslog("%s %s %d read failed %s ",
+-					mic->name, __func__, __LINE__,
+-					strerror(errno));
+-				mpsslog("cnt %d sum %zd\n",
+-					copy.iovcnt, sum_iovec_len(&copy));
+-			}
+-		}
+-
+-		if (console_poll[VIRTIO_CONSOLE_FD].revents & POLLIN) {
+-			while (rx_vr.info->avail_idx !=
+-				le16toh(rx_vr.vr.avail->idx)) {
+-				copy.iov = iov1;
+-				txrx_prepare(VIRTIO_ID_CONSOLE, 0, &rx_vr,
+-					     &copy, PAGE_SIZE);
+-
+-				err = mic_virtio_copy(mic,
+-					mic->mic_console.virtio_console_fd,
+-					&rx_vr, &copy);
+-				if (!err) {
+-					/* Set the correct output iov_len */
+-					iov1->iov_len = copy.out_len;
+-					verify_out_len(mic, &copy);
+-#ifdef DEBUG
+-					disp_iovec(mic, copy, __func__,
+-						   __LINE__);
+-					mpsslog("%s %s %d ",
+-						mic->name, __func__, __LINE__);
+-					mpsslog("read from net 0x%lx\n",
+-						sum_iovec_len(copy));
+-#endif
+-					len = writev(pty_fd,
+-						copy.iov, copy.iovcnt);
+-					if (len != sum_iovec_len(&copy)) {
+-						mpsslog("Tun write failed %s ",
+-							strerror(errno));
+-						mpsslog("len 0x%zx ", len);
+-						mpsslog("read_len 0x%zx\n",
+-							sum_iovec_len(&copy));
+-					} else {
+-#ifdef DEBUG
+-						disp_iovec(mic, copy, __func__,
+-							   __LINE__);
+-						mpsslog("%s %s %d ",
+-							mic->name, __func__,
+-							__LINE__);
+-						mpsslog("wrote to tap 0x%lx\n",
+-							len);
+-#endif
+-					}
+-				} else {
+-					mpsslog("%s %s %d mic_virtio_copy %s\n",
+-						mic->name, __func__, __LINE__,
+-						strerror(errno));
+-					break;
+-				}
+-			}
+-		}
+-		if (console_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
+-			mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
+-	}
+-_close_pty:
+-	close(pty_fd);
+-_return:
+-	pthread_exit(NULL);
+-}
+-
+-static void
+-add_virtio_device(struct mic_info *mic, struct mic_device_desc *dd)
+-{
+-	char path[PATH_MAX];
+-	int fd, err;
+-
+-	snprintf(path, PATH_MAX, "/dev/mic%d", mic->id);
+-	fd = open(path, O_RDWR);
+-	if (fd < 0) {
+-		mpsslog("Could not open %s %s\n", path, strerror(errno));
+-		return;
+-	}
+-
+-	err = ioctl(fd, MIC_VIRTIO_ADD_DEVICE, dd);
+-	if (err < 0) {
+-		mpsslog("Could not add %d %s\n", dd->type, strerror(errno));
+-		close(fd);
+-		return;
+-	}
+-	switch (dd->type) {
+-	case VIRTIO_ID_NET:
+-		mic->mic_net.virtio_net_fd = fd;
+-		mpsslog("Added VIRTIO_ID_NET for %s\n", mic->name);
+-		break;
+-	case VIRTIO_ID_CONSOLE:
+-		mic->mic_console.virtio_console_fd = fd;
+-		mpsslog("Added VIRTIO_ID_CONSOLE for %s\n", mic->name);
+-		break;
+-	case VIRTIO_ID_BLOCK:
+-		mic->mic_virtblk.virtio_block_fd = fd;
+-		mpsslog("Added VIRTIO_ID_BLOCK for %s\n", mic->name);
+-		break;
+-	}
+-}
+-
+-static bool
+-set_backend_file(struct mic_info *mic)
+-{
+-	FILE *config;
+-	char buff[PATH_MAX], *line, *evv, *p;
+-
+-	snprintf(buff, PATH_MAX, "%s/mpssd%03d.conf", mic_config_dir, mic->id);
+-	config = fopen(buff, "r");
+-	if (config == NULL)
+-		return false;
+-	do {  /* look for "virtblk_backend=XXXX" */
+-		line = fgets(buff, PATH_MAX, config);
+-		if (line == NULL)
+-			break;
+-		if (*line == '#')
+-			continue;
+-		p = strchr(line, '\n');
+-		if (p)
+-			*p = '\0';
+-	} while (strncmp(line, virtblk_backend, strlen(virtblk_backend)) != 0);
+-	fclose(config);
+-	if (line == NULL)
+-		return false;
+-	evv = strchr(line, '=');
+-	if (evv == NULL)
+-		return false;
+-	mic->mic_virtblk.backend_file = malloc(strlen(evv) + 1);
+-	if (mic->mic_virtblk.backend_file == NULL) {
+-		mpsslog("%s %d can't allocate memory\n", mic->name, mic->id);
+-		return false;
+-	}
+-	strcpy(mic->mic_virtblk.backend_file, evv + 1);
+-	return true;
+-}
+-
+-#define SECTOR_SIZE 512
+-static bool
+-set_backend_size(struct mic_info *mic)
+-{
+-	mic->mic_virtblk.backend_size = lseek(mic->mic_virtblk.backend, 0,
+-		SEEK_END);
+-	if (mic->mic_virtblk.backend_size < 0) {
+-		mpsslog("%s: can't seek: %s\n",
+-			mic->name, mic->mic_virtblk.backend_file);
+-		return false;
+-	}
+-	virtblk_dev_page.blk_config.capacity =
+-		mic->mic_virtblk.backend_size / SECTOR_SIZE;
+-	if ((mic->mic_virtblk.backend_size % SECTOR_SIZE) != 0)
+-		virtblk_dev_page.blk_config.capacity++;
+-
+-	virtblk_dev_page.blk_config.capacity =
+-		htole64(virtblk_dev_page.blk_config.capacity);
+-
+-	return true;
+-}
+-
+-static bool
+-open_backend(struct mic_info *mic)
+-{
+-	if (!set_backend_file(mic))
+-		goto _error_exit;
+-	mic->mic_virtblk.backend = open(mic->mic_virtblk.backend_file, O_RDWR);
+-	if (mic->mic_virtblk.backend < 0) {
+-		mpsslog("%s: can't open: %s\n", mic->name,
+-			mic->mic_virtblk.backend_file);
+-		goto _error_free;
+-	}
+-	if (!set_backend_size(mic))
+-		goto _error_close;
+-	mic->mic_virtblk.backend_addr = mmap(NULL,
+-		mic->mic_virtblk.backend_size,
+-		PROT_READ|PROT_WRITE, MAP_SHARED,
+-		mic->mic_virtblk.backend, 0L);
+-	if (mic->mic_virtblk.backend_addr == MAP_FAILED) {
+-		mpsslog("%s: can't map: %s %s\n",
+-			mic->name, mic->mic_virtblk.backend_file,
+-			strerror(errno));
+-		goto _error_close;
+-	}
+-	return true;
+-
+- _error_close:
+-	close(mic->mic_virtblk.backend);
+- _error_free:
+-	free(mic->mic_virtblk.backend_file);
+- _error_exit:
+-	return false;
+-}
+-
+-static void
+-close_backend(struct mic_info *mic)
+-{
+-	munmap(mic->mic_virtblk.backend_addr, mic->mic_virtblk.backend_size);
+-	close(mic->mic_virtblk.backend);
+-	free(mic->mic_virtblk.backend_file);
+-}
+-
+-static bool
+-start_virtblk(struct mic_info *mic, struct mic_vring *vring)
+-{
+-	if (((unsigned long)&virtblk_dev_page.blk_config % 8) != 0) {
+-		mpsslog("%s: blk_config is not 8 byte aligned.\n",
+-			mic->name);
+-		return false;
+-	}
+-	add_virtio_device(mic, &virtblk_dev_page.dd);
+-	if (MAP_FAILED == init_vr(mic, mic->mic_virtblk.virtio_block_fd,
+-				  VIRTIO_ID_BLOCK, vring, NULL,
+-				  virtblk_dev_page.dd.num_vq)) {
+-		mpsslog("%s init_vr failed %s\n",
+-			mic->name, strerror(errno));
+-		return false;
+-	}
+-	return true;
+-}
+-
+-static void
+-stop_virtblk(struct mic_info *mic)
+-{
+-	int vr_size, ret;
+-
+-	vr_size = PAGE_ALIGN(_vring_size(MIC_VRING_ENTRIES,
+-					 MIC_VIRTIO_RING_ALIGN) +
+-			     sizeof(struct _mic_vring_info));
+-	ret = munmap(mic->mic_virtblk.block_dp,
+-		MIC_DEVICE_PAGE_END + vr_size * virtblk_dev_page.dd.num_vq);
+-	if (ret < 0)
+-		mpsslog("%s munmap errno %d\n", mic->name, errno);
+-	close(mic->mic_virtblk.virtio_block_fd);
+-}
+-
+-static __u8
+-header_error_check(struct vring_desc *desc)
+-{
+-	if (le32toh(desc->len) != sizeof(struct virtio_blk_outhdr)) {
+-		mpsslog("%s() %d: length is not sizeof(virtio_blk_outhd)\n",
+-			__func__, __LINE__);
+-		return -EIO;
+-	}
+-	if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT)) {
+-		mpsslog("%s() %d: alone\n",
+-			__func__, __LINE__);
+-		return -EIO;
+-	}
+-	if (le16toh(desc->flags) & VRING_DESC_F_WRITE) {
+-		mpsslog("%s() %d: not read\n",
+-			__func__, __LINE__);
+-		return -EIO;
+-	}
+-	return 0;
+-}
+-
+-static int
+-read_header(int fd, struct virtio_blk_outhdr *hdr, __u32 desc_idx)
+-{
+-	struct iovec iovec;
+-	struct mic_copy_desc copy;
+-
+-	iovec.iov_len = sizeof(*hdr);
+-	iovec.iov_base = hdr;
+-	copy.iov = &iovec;
+-	copy.iovcnt = 1;
+-	copy.vr_idx = 0;  /* only one vring on virtio_block */
+-	copy.update_used = false;  /* do not update used index */
+-	return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
+-}
+-
+-static int
+-transfer_blocks(int fd, struct iovec *iovec, __u32 iovcnt)
+-{
+-	struct mic_copy_desc copy;
+-
+-	copy.iov = iovec;
+-	copy.iovcnt = iovcnt;
+-	copy.vr_idx = 0;  /* only one vring on virtio_block */
+-	copy.update_used = false;  /* do not update used index */
+-	return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
+-}
+-
+-static __u8
+-status_error_check(struct vring_desc *desc)
+-{
+-	if (le32toh(desc->len) != sizeof(__u8)) {
+-		mpsslog("%s() %d: length is not sizeof(status)\n",
+-			__func__, __LINE__);
+-		return -EIO;
+-	}
+-	return 0;
+-}
+-
+-static int
+-write_status(int fd, __u8 *status)
+-{
+-	struct iovec iovec;
+-	struct mic_copy_desc copy;
+-
+-	iovec.iov_base = status;
+-	iovec.iov_len = sizeof(*status);
+-	copy.iov = &iovec;
+-	copy.iovcnt = 1;
+-	copy.vr_idx = 0;  /* only one vring on virtio_block */
+-	copy.update_used = true; /* Update used index */
+-	return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
+-}
+-
+-#ifndef VIRTIO_BLK_T_GET_ID
+-#define VIRTIO_BLK_T_GET_ID    8
+-#endif
+-
+-static void *
+-virtio_block(void *arg)
+-{
+-	struct mic_info *mic = (struct mic_info *)arg;
+-	int ret;
+-	struct pollfd block_poll;
+-	struct mic_vring vring;
+-	__u16 avail_idx;
+-	__u32 desc_idx;
+-	struct vring_desc *desc;
+-	struct iovec *iovec, *piov;
+-	__u8 status;
+-	__u32 buffer_desc_idx;
+-	struct virtio_blk_outhdr hdr;
+-	void *fos;
+-
+-	for (;;) {  /* forever */
+-		if (!open_backend(mic)) { /* No virtblk */
+-			for (mic->mic_virtblk.signaled = 0;
+-				!mic->mic_virtblk.signaled;)
+-				sleep(1);
+-			continue;
+-		}
+-
+-		/* backend file is specified. */
+-		if (!start_virtblk(mic, &vring))
+-			goto _close_backend;
+-		iovec = malloc(sizeof(*iovec) *
+-			le32toh(virtblk_dev_page.blk_config.seg_max));
+-		if (!iovec) {
+-			mpsslog("%s: can't alloc iovec: %s\n",
+-				mic->name, strerror(ENOMEM));
+-			goto _stop_virtblk;
+-		}
+-
+-		block_poll.fd = mic->mic_virtblk.virtio_block_fd;
+-		block_poll.events = POLLIN;
+-		for (mic->mic_virtblk.signaled = 0;
+-		     !mic->mic_virtblk.signaled;) {
+-			block_poll.revents = 0;
+-					/* timeout in 1 sec to see signaled */
+-			ret = poll(&block_poll, 1, 1000);
+-			if (ret < 0) {
+-				mpsslog("%s %d: poll failed: %s\n",
+-					__func__, __LINE__,
+-					strerror(errno));
+-				continue;
+-			}
+-
+-			if (!(block_poll.revents & POLLIN)) {
+-#ifdef DEBUG
+-				mpsslog("%s %d: block_poll.revents=0x%x\n",
+-					__func__, __LINE__, block_poll.revents);
+-#endif
+-				continue;
+-			}
+-
+-			/* POLLIN */
+-			while (vring.info->avail_idx !=
+-				le16toh(vring.vr.avail->idx)) {
+-				/* read header element */
+-				avail_idx =
+-					vring.info->avail_idx &
+-					(vring.vr.num - 1);
+-				desc_idx = le16toh(
+-					vring.vr.avail->ring[avail_idx]);
+-				desc = &vring.vr.desc[desc_idx];
+-#ifdef DEBUG
+-				mpsslog("%s() %d: avail_idx=%d ",
+-					__func__, __LINE__,
+-					vring.info->avail_idx);
+-				mpsslog("vring.vr.num=%d desc=%p\n",
+-					vring.vr.num, desc);
+-#endif
+-				status = header_error_check(desc);
+-				ret = read_header(
+-					mic->mic_virtblk.virtio_block_fd,
+-					&hdr, desc_idx);
+-				if (ret < 0) {
+-					mpsslog("%s() %d %s: ret=%d %s\n",
+-						__func__, __LINE__,
+-						mic->name, ret,
+-						strerror(errno));
+-					break;
+-				}
+-				/* buffer element */
+-				piov = iovec;
+-				status = 0;
+-				fos = mic->mic_virtblk.backend_addr +
+-					(hdr.sector * SECTOR_SIZE);
+-				buffer_desc_idx = next_desc(desc);
+-				desc_idx = buffer_desc_idx;
+-				for (desc = &vring.vr.desc[buffer_desc_idx];
+-				     desc->flags & VRING_DESC_F_NEXT;
+-				     desc_idx = next_desc(desc),
+-					     desc = &vring.vr.desc[desc_idx]) {
+-					piov->iov_len = desc->len;
+-					piov->iov_base = fos;
+-					piov++;
+-					fos += desc->len;
+-				}
+-				/* Returning NULLs for VIRTIO_BLK_T_GET_ID. */
+-				if (hdr.type & ~(VIRTIO_BLK_T_OUT |
+-					VIRTIO_BLK_T_GET_ID)) {
+-					/*
+-					  VIRTIO_BLK_T_IN - does not do
+-					  anything. Probably for documenting.
+-					  VIRTIO_BLK_T_SCSI_CMD - for
+-					  virtio_scsi.
+-					  VIRTIO_BLK_T_FLUSH - turned off in
+-					  config space.
+-					  VIRTIO_BLK_T_BARRIER - defined but not
+-					  used in anywhere.
+-					*/
+-					mpsslog("%s() %d: type %x ",
+-						__func__, __LINE__,
+-						hdr.type);
+-					mpsslog("is not supported\n");
+-					status = -ENOTSUP;
+-
+-				} else {
+-					ret = transfer_blocks(
+-					mic->mic_virtblk.virtio_block_fd,
+-						iovec,
+-						piov - iovec);
+-					if (ret < 0 &&
+-					    status != 0)
+-						status = ret;
+-				}
+-				/* write status and update used pointer */
+-				if (status != 0)
+-					status = status_error_check(desc);
+-				ret = write_status(
+-					mic->mic_virtblk.virtio_block_fd,
+-					&status);
+-#ifdef DEBUG
+-				mpsslog("%s() %d: write status=%d on desc=%p\n",
+-					__func__, __LINE__,
+-					status, desc);
+-#endif
+-			}
+-		}
+-		free(iovec);
+-_stop_virtblk:
+-		stop_virtblk(mic);
+-_close_backend:
+-		close_backend(mic);
+-	}  /* forever */
+-
+-	pthread_exit(NULL);
+-}
+-
+-static void
+-reset(struct mic_info *mic)
+-{
+-#define RESET_TIMEOUT 120
+-	int i = RESET_TIMEOUT;
+-	setsysfs(mic->name, "state", "reset");
+-	while (i) {
+-		char *state;
+-		state = readsysfs(mic->name, "state");
+-		if (!state)
+-			goto retry;
+-		mpsslog("%s: %s %d state %s\n",
+-			mic->name, __func__, __LINE__, state);
+-
+-		if (!strcmp(state, "ready")) {
+-			free(state);
+-			break;
+-		}
+-		free(state);
+-retry:
+-		sleep(1);
+-		i--;
+-	}
+-}
+-
+-static int
+-get_mic_shutdown_status(struct mic_info *mic, char *shutdown_status)
+-{
+-	if (!strcmp(shutdown_status, "nop"))
+-		return MIC_NOP;
+-	if (!strcmp(shutdown_status, "crashed"))
+-		return MIC_CRASHED;
+-	if (!strcmp(shutdown_status, "halted"))
+-		return MIC_HALTED;
+-	if (!strcmp(shutdown_status, "poweroff"))
+-		return MIC_POWER_OFF;
+-	if (!strcmp(shutdown_status, "restart"))
+-		return MIC_RESTART;
+-	mpsslog("%s: BUG invalid status %s\n", mic->name, shutdown_status);
+-	/* Invalid state */
+-	assert(0);
+-};
+-
+-static int get_mic_state(struct mic_info *mic)
+-{
+-	char *state = NULL;
+-	enum mic_states mic_state;
+-
+-	while (!state) {
+-		state = readsysfs(mic->name, "state");
+-		sleep(1);
+-	}
+-	mpsslog("%s: %s %d state %s\n",
+-		mic->name, __func__, __LINE__, state);
+-
+-	if (!strcmp(state, "ready")) {
+-		mic_state = MIC_READY;
+-	} else if (!strcmp(state, "booting")) {
+-		mic_state = MIC_BOOTING;
+-	} else if (!strcmp(state, "online")) {
+-		mic_state = MIC_ONLINE;
+-	} else if (!strcmp(state, "shutting_down")) {
+-		mic_state = MIC_SHUTTING_DOWN;
+-	} else if (!strcmp(state, "reset_failed")) {
+-		mic_state = MIC_RESET_FAILED;
+-	} else if (!strcmp(state, "resetting")) {
+-		mic_state = MIC_RESETTING;
+-	} else {
+-		mpsslog("%s: BUG invalid state %s\n", mic->name, state);
+-		assert(0);
+-	}
+-
+-	free(state);
+-	return mic_state;
+-};
+-
+-static void mic_handle_shutdown(struct mic_info *mic)
+-{
+-#define SHUTDOWN_TIMEOUT 60
+-	int i = SHUTDOWN_TIMEOUT;
+-	char *shutdown_status;
+-	while (i) {
+-		shutdown_status = readsysfs(mic->name, "shutdown_status");
+-		if (!shutdown_status) {
+-			sleep(1);
+-			continue;
+-		}
+-		mpsslog("%s: %s %d shutdown_status %s\n",
+-			mic->name, __func__, __LINE__, shutdown_status);
+-		switch (get_mic_shutdown_status(mic, shutdown_status)) {
+-		case MIC_RESTART:
+-			mic->restart = 1;
+-		case MIC_HALTED:
+-		case MIC_POWER_OFF:
+-		case MIC_CRASHED:
+-			free(shutdown_status);
+-			goto reset;
+-		default:
+-			break;
+-		}
+-		free(shutdown_status);
+-		sleep(1);
+-		i--;
+-	}
+-reset:
+-	if (!i)
+-		mpsslog("%s: %s %d timing out waiting for shutdown_status %s\n",
+-			mic->name, __func__, __LINE__, shutdown_status);
+-	reset(mic);
+-}
+-
+-static int open_state_fd(struct mic_info *mic)
+-{
+-	char pathname[PATH_MAX];
+-	int fd;
+-
+-	snprintf(pathname, PATH_MAX - 1, "%s/%s/%s",
+-		 MICSYSFSDIR, mic->name, "state");
+-
+-	fd = open(pathname, O_RDONLY);
+-	if (fd < 0)
+-		mpsslog("%s: opening file %s failed %s\n",
+-			mic->name, pathname, strerror(errno));
+-	return fd;
+-}
+-
+-static int block_till_state_change(int fd, struct mic_info *mic)
+-{
+-	struct pollfd ufds[1];
+-	char value[PAGE_SIZE];
+-	int ret;
+-
+-	ufds[0].fd = fd;
+-	ufds[0].events = POLLERR | POLLPRI;
+-	ret = poll(ufds, 1, -1);
+-	if (ret < 0) {
+-		mpsslog("%s: %s %d poll failed %s\n",
+-			mic->name, __func__, __LINE__, strerror(errno));
+-		return ret;
+-	}
+-
+-	ret = lseek(fd, 0, SEEK_SET);
+-	if (ret < 0) {
+-		mpsslog("%s: %s %d Failed to seek to 0: %s\n",
+-			mic->name, __func__, __LINE__, strerror(errno));
+-		return ret;
+-	}
+-
+-	ret = read(fd, value, sizeof(value));
+-	if (ret < 0) {
+-		mpsslog("%s: %s %d Failed to read sysfs entry: %s\n",
+-			mic->name, __func__, __LINE__, strerror(errno));
+-		return ret;
+-	}
+-
+-	return 0;
+-}
+-
+-static void *
+-mic_config(void *arg)
+-{
+-	struct mic_info *mic = (struct mic_info *)arg;
+-	int fd, ret, stat = 0;
+-
+-	fd = open_state_fd(mic);
+-	if (fd < 0) {
+-		mpsslog("%s: %s %d open state fd failed %s\n",
+-			mic->name, __func__, __LINE__, strerror(errno));
+-		goto exit;
+-	}
+-
+-	do {
+-		ret = block_till_state_change(fd, mic);
+-		if (ret < 0) {
+-			mpsslog("%s: %s %d block_till_state_change error %s\n",
+-				mic->name, __func__, __LINE__, strerror(errno));
+-			goto close_exit;
+-		}
+-
+-		switch (get_mic_state(mic)) {
+-		case MIC_SHUTTING_DOWN:
+-			mic_handle_shutdown(mic);
+-			break;
+-		case MIC_READY:
+-		case MIC_RESET_FAILED:
+-			ret = kill(mic->pid, SIGTERM);
+-			mpsslog("%s: %s %d kill pid %d ret %d\n",
+-				mic->name, __func__, __LINE__,
+-				mic->pid, ret);
+-			if (!ret) {
+-				ret = waitpid(mic->pid, &stat,
+-					      WIFSIGNALED(stat));
+-				mpsslog("%s: %s %d waitpid ret %d pid %d\n",
+-					mic->name, __func__, __LINE__,
+-					ret, mic->pid);
+-			}
+-			if (mic->boot_on_resume) {
+-				setsysfs(mic->name, "state", "boot");
+-				mic->boot_on_resume = 0;
+-			}
+-			goto close_exit;
+-		default:
+-			break;
+-		}
+-	} while (1);
+-
+-close_exit:
+-	close(fd);
+-exit:
+-	init_mic(mic);
+-	pthread_exit(NULL);
+-}
+-
+-static void
+-set_cmdline(struct mic_info *mic)
+-{
+-	char buffer[PATH_MAX];
+-	int len;
+-
+-	len = snprintf(buffer, PATH_MAX,
+-		"clocksource=tsc highres=off nohz=off ");
+-	len += snprintf(buffer + len, PATH_MAX - len,
+-		"cpufreq_on;corec6_off;pc3_off;pc6_off ");
+-	len += snprintf(buffer + len, PATH_MAX - len,
+-		"ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0",
+-		mic->id + 1);
+-
+-	setsysfs(mic->name, "cmdline", buffer);
+-	mpsslog("%s: Command line: \"%s\"\n", mic->name, buffer);
+-	snprintf(buffer, PATH_MAX, "172.31.%d.1", mic->id + 1);
+-	mpsslog("%s: IPADDR: \"%s\"\n", mic->name, buffer);
+-}
+-
+-static void
+-set_log_buf_info(struct mic_info *mic)
+-{
+-	int fd;
+-	off_t len;
+-	char system_map[] = "/lib/firmware/mic/System.map";
+-	char *map, *temp, log_buf[17] = {'\0'};
+-
+-	fd = open(system_map, O_RDONLY);
+-	if (fd < 0) {
+-		mpsslog("%s: Opening System.map failed: %d\n",
+-			mic->name, errno);
+-		return;
+-	}
+-	len = lseek(fd, 0, SEEK_END);
+-	if (len < 0) {
+-		mpsslog("%s: Reading System.map size failed: %d\n",
+-			mic->name, errno);
+-		close(fd);
+-		return;
+-	}
+-	map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
+-	if (map == MAP_FAILED) {
+-		mpsslog("%s: mmap of System.map failed: %d\n",
+-			mic->name, errno);
+-		close(fd);
+-		return;
+-	}
+-	temp = strstr(map, "__log_buf");
+-	if (!temp) {
+-		mpsslog("%s: __log_buf not found: %d\n", mic->name, errno);
+-		munmap(map, len);
+-		close(fd);
+-		return;
+-	}
+-	strncpy(log_buf, temp - 19, 16);
+-	setsysfs(mic->name, "log_buf_addr", log_buf);
+-	mpsslog("%s: log_buf_addr: %s\n", mic->name, log_buf);
+-	temp = strstr(map, "log_buf_len");
+-	if (!temp) {
+-		mpsslog("%s: log_buf_len not found: %d\n", mic->name, errno);
+-		munmap(map, len);
+-		close(fd);
+-		return;
+-	}
+-	strncpy(log_buf, temp - 19, 16);
+-	setsysfs(mic->name, "log_buf_len", log_buf);
+-	mpsslog("%s: log_buf_len: %s\n", mic->name, log_buf);
+-	munmap(map, len);
+-	close(fd);
+-}
+-
+-static void
+-change_virtblk_backend(int x, siginfo_t *siginfo, void *p)
+-{
+-	struct mic_info *mic;
+-
+-	for (mic = mic_list.next; mic != NULL; mic = mic->next)
+-		mic->mic_virtblk.signaled = 1/* true */;
+-}
+-
+-static void
+-set_mic_boot_params(struct mic_info *mic)
+-{
+-	set_log_buf_info(mic);
+-	set_cmdline(mic);
+-}
+-
+-static void *
+-init_mic(void *arg)
+-{
+-	struct mic_info *mic = (struct mic_info *)arg;
+-	struct sigaction ignore = {
+-		.sa_flags = 0,
+-		.sa_handler = SIG_IGN
+-	};
+-	struct sigaction act = {
+-		.sa_flags = SA_SIGINFO,
+-		.sa_sigaction = change_virtblk_backend,
+-	};
+-	char buffer[PATH_MAX];
+-	int err, fd;
+-
+-	/*
+-	 * Currently, one virtio block device is supported for each MIC card
+-	 * at a time. Any user (or test) can send a SIGUSR1 to the MIC daemon.
+-	 * The signal informs the virtio block backend about a change in the
+-	 * configuration file which specifies the virtio backend file name on
+-	 * the host. Virtio block backend then re-reads the configuration file
+-	 * and switches to the new block device. This signalling mechanism may
+-	 * not be required once multiple virtio block devices are supported by
+-	 * the MIC daemon.
+-	 */
+-	sigaction(SIGUSR1, &ignore, NULL);
+-retry:
+-	fd = open_state_fd(mic);
+-	if (fd < 0) {
+-		mpsslog("%s: %s %d open state fd failed %s\n",
+-			mic->name, __func__, __LINE__, strerror(errno));
+-		sleep(2);
+-		goto retry;
+-	}
+-
+-	if (mic->restart) {
+-		snprintf(buffer, PATH_MAX, "boot");
+-		setsysfs(mic->name, "state", buffer);
+-		mpsslog("%s restarting mic %d\n",
+-			mic->name, mic->restart);
+-		mic->restart = 0;
+-	}
+-
+-	while (1) {
+-		while (block_till_state_change(fd, mic)) {
+-			mpsslog("%s: %s %d block_till_state_change error %s\n",
+-				mic->name, __func__, __LINE__, strerror(errno));
+-			sleep(2);
+-			continue;
+-		}
+-
+-		if (get_mic_state(mic) == MIC_BOOTING)
+-			break;
+-	}
+-
+-	mic->pid = fork();
+-	switch (mic->pid) {
+-	case 0:
+-		add_virtio_device(mic, &virtcons_dev_page.dd);
+-		add_virtio_device(mic, &virtnet_dev_page.dd);
+-		err = pthread_create(&mic->mic_console.console_thread, NULL,
+-			virtio_console, mic);
+-		if (err)
+-			mpsslog("%s virtcons pthread_create failed %s\n",
+-				mic->name, strerror(err));
+-		err = pthread_create(&mic->mic_net.net_thread, NULL,
+-			virtio_net, mic);
+-		if (err)
+-			mpsslog("%s virtnet pthread_create failed %s\n",
+-				mic->name, strerror(err));
+-		err = pthread_create(&mic->mic_virtblk.block_thread, NULL,
+-			virtio_block, mic);
+-		if (err)
+-			mpsslog("%s virtblk pthread_create failed %s\n",
+-				mic->name, strerror(err));
+-		sigemptyset(&act.sa_mask);
+-		err = sigaction(SIGUSR1, &act, NULL);
+-		if (err)
+-			mpsslog("%s sigaction SIGUSR1 failed %s\n",
+-				mic->name, strerror(errno));
+-		while (1)
+-			sleep(60);
+-	case -1:
+-		mpsslog("fork failed MIC name %s id %d errno %d\n",
+-			mic->name, mic->id, errno);
+-		break;
+-	default:
+-		err = pthread_create(&mic->config_thread, NULL,
+-				     mic_config, mic);
+-		if (err)
+-			mpsslog("%s mic_config pthread_create failed %s\n",
+-				mic->name, strerror(err));
+-	}
+-
+-	return NULL;
+-}
+-
+-static void
+-start_daemon(void)
+-{
+-	struct mic_info *mic;
+-	int err;
+-
+-	for (mic = mic_list.next; mic; mic = mic->next) {
+-		set_mic_boot_params(mic);
+-		err = pthread_create(&mic->init_thread, NULL, init_mic, mic);
+-		if (err)
+-			mpsslog("%s init_mic pthread_create failed %s\n",
+-				mic->name, strerror(err));
+-	}
+-
+-	while (1)
+-		sleep(60);
+-}
+-
+-static int
+-init_mic_list(void)
+-{
+-	struct mic_info *mic = &mic_list;
+-	struct dirent *file;
+-	DIR *dp;
+-	int cnt = 0;
+-
+-	dp = opendir(MICSYSFSDIR);
+-	if (!dp)
+-		return 0;
+-
+-	while ((file = readdir(dp)) != NULL) {
+-		if (!strncmp(file->d_name, "mic", 3)) {
+-			mic->next = calloc(1, sizeof(struct mic_info));
+-			if (mic->next) {
+-				mic = mic->next;
+-				mic->id = atoi(&file->d_name[3]);
+-				mic->name = malloc(strlen(file->d_name) + 16);
+-				if (mic->name)
+-					strcpy(mic->name, file->d_name);
+-				mpsslog("MIC name %s id %d\n", mic->name,
+-					mic->id);
+-				cnt++;
+-			}
+-		}
+-	}
+-
+-	closedir(dp);
+-	return cnt;
+-}
+-
+-void
+-mpsslog(char *format, ...)
+-{
+-	va_list args;
+-	char buffer[4096];
+-	char ts[52], *ts1;
+-	time_t t;
+-
+-	if (logfp == NULL)
+-		return;
+-
+-	va_start(args, format);
+-	vsprintf(buffer, format, args);
+-	va_end(args);
+-
+-	time(&t);
+-	ts1 = ctime_r(&t, ts);
+-	ts1[strlen(ts1) - 1] = '\0';
+-	fprintf(logfp, "%s: %s", ts1, buffer);
+-
+-	fflush(logfp);
+-}
+-
+-int
+-main(int argc, char *argv[])
+-{
+-	int cnt;
+-	pid_t pid;
+-
+-	myname = argv[0];
+-
+-	logfp = fopen(LOGFILE_NAME, "a+");
+-	if (!logfp) {
+-		fprintf(stderr, "cannot open logfile '%s'\n", LOGFILE_NAME);
+-		exit(1);
+-	}
+-	pid = fork();
+-	switch (pid) {
+-	case 0:
+-		break;
+-	case -1:
+-		exit(2);
+-	default:
+-		exit(0);
+-	}
+-
+-	mpsslog("MIC Daemon start\n");
+-
+-	cnt = init_mic_list();
+-	if (cnt == 0) {
+-		mpsslog("MIC module not loaded\n");
+-		exit(3);
+-	}
+-	mpsslog("MIC found %d devices\n", cnt);
+-
+-	start_daemon();
+-
+-	exit(0);
+-}
+diff --git a/Documentation/mic/mpssd/mpssd.h b/Documentation/mic/mpssd/mpssd.h
+deleted file mode 100644
+index 8bd64944aacc..000000000000
+--- a/Documentation/mic/mpssd/mpssd.h
++++ /dev/null
+@@ -1,103 +0,0 @@
+-/*
+- * Intel MIC Platform Software Stack (MPSS)
+- *
+- * Copyright(c) 2013 Intel Corporation.
+- *
+- * 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.
+- *
+- * This program is distributed in the hope that it will be useful, but
+- * WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+- * General Public License for more details.
+- *
+- * The full GNU General Public License is included in this distribution in
+- * the file called "COPYING".
+- *
+- * Intel MIC User Space Tools.
+- */
+-#ifndef _MPSSD_H_
+-#define _MPSSD_H_
+-
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <fcntl.h>
+-#include <unistd.h>
+-#include <dirent.h>
+-#include <libgen.h>
+-#include <pthread.h>
+-#include <stdarg.h>
+-#include <time.h>
+-#include <errno.h>
+-#include <sys/dir.h>
+-#include <sys/ioctl.h>
+-#include <sys/poll.h>
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <sys/mman.h>
+-#include <sys/utsname.h>
+-#include <sys/wait.h>
+-#include <netinet/in.h>
+-#include <arpa/inet.h>
+-#include <netdb.h>
+-#include <pthread.h>
+-#include <signal.h>
+-#include <limits.h>
+-#include <syslog.h>
+-#include <getopt.h>
+-#include <net/if.h>
+-#include <linux/if_tun.h>
+-#include <linux/if_tun.h>
+-#include <linux/virtio_ids.h>
+-
+-#define MICSYSFSDIR "/sys/class/mic"
+-#define LOGFILE_NAME "/var/log/mpssd"
+-#define PAGE_SIZE 4096
+-
+-struct mic_console_info {
+-	pthread_t       console_thread;
+-	int		virtio_console_fd;
+-	void		*console_dp;
+-};
+-
+-struct mic_net_info {
+-	pthread_t       net_thread;
+-	int		virtio_net_fd;
+-	int		tap_fd;
+-	void		*net_dp;
+-};
+-
+-struct mic_virtblk_info {
+-	pthread_t       block_thread;
+-	int		virtio_block_fd;
+-	void		*block_dp;
+-	volatile sig_atomic_t	signaled;
+-	char		*backend_file;
+-	int		backend;
+-	void		*backend_addr;
+-	long		backend_size;
+-};
+-
+-struct mic_info {
+-	int		id;
+-	char		*name;
+-	pthread_t       config_thread;
+-	pthread_t       init_thread;
+-	pid_t		pid;
+-	struct mic_console_info	mic_console;
+-	struct mic_net_info	mic_net;
+-	struct mic_virtblk_info	mic_virtblk;
+-	int		restart;
+-	int		boot_on_resume;
+-	struct mic_info *next;
+-};
+-
+-__attribute__((format(printf, 1, 2)))
+-void mpsslog(char *format, ...);
+-char *readsysfs(char *dir, char *entry);
+-int setsysfs(char *dir, char *entry, char *value);
+-#endif
+diff --git a/Documentation/mic/mpssd/sysfs.c b/Documentation/mic/mpssd/sysfs.c
+deleted file mode 100644
+index 8dd326936083..000000000000
+--- a/Documentation/mic/mpssd/sysfs.c
++++ /dev/null
+@@ -1,102 +0,0 @@
+-/*
+- * Intel MIC Platform Software Stack (MPSS)
+- *
+- * Copyright(c) 2013 Intel Corporation.
+- *
+- * 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.
+- *
+- * This program is distributed in the hope that it will be useful, but
+- * WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+- * General Public License for more details.
+- *
+- * The full GNU General Public License is included in this distribution in
+- * the file called "COPYING".
+- *
+- * Intel MIC User Space Tools.
+- */
+-
+-#include "mpssd.h"
+-
+-#define PAGE_SIZE 4096
+-
+-char *
+-readsysfs(char *dir, char *entry)
+-{
+-	char filename[PATH_MAX];
+-	char value[PAGE_SIZE];
+-	char *string = NULL;
+-	int fd;
+-	int len;
+-
+-	if (dir == NULL)
+-		snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
+-	else
+-		snprintf(filename, PATH_MAX,
+-			 "%s/%s/%s", MICSYSFSDIR, dir, entry);
+-
+-	fd = open(filename, O_RDONLY);
+-	if (fd < 0) {
+-		mpsslog("Failed to open sysfs entry '%s': %s\n",
+-			filename, strerror(errno));
+-		return NULL;
+-	}
+-
+-	len = read(fd, value, sizeof(value));
+-	if (len < 0) {
+-		mpsslog("Failed to read sysfs entry '%s': %s\n",
+-			filename, strerror(errno));
+-		goto readsys_ret;
+-	}
+-	if (len == 0)
+-		goto readsys_ret;
+-
+-	value[len - 1] = '\0';
+-
+-	string = malloc(strlen(value) + 1);
+-	if (string)
+-		strcpy(string, value);
+-
+-readsys_ret:
+-	close(fd);
+-	return string;
+-}
+-
+-int
+-setsysfs(char *dir, char *entry, char *value)
+-{
+-	char filename[PATH_MAX];
+-	char *oldvalue;
+-	int fd, ret = 0;
+-
+-	if (dir == NULL)
+-		snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
+-	else
+-		snprintf(filename, PATH_MAX, "%s/%s/%s",
+-			 MICSYSFSDIR, dir, entry);
+-
+-	oldvalue = readsysfs(dir, entry);
+-
+-	fd = open(filename, O_RDWR);
+-	if (fd < 0) {
+-		ret = errno;
+-		mpsslog("Failed to open sysfs entry '%s': %s\n",
+-			filename, strerror(errno));
+-		goto done;
+-	}
+-
+-	if (!oldvalue || strcmp(value, oldvalue)) {
+-		if (write(fd, value, strlen(value)) < 0) {
+-			ret = errno;
+-			mpsslog("Failed to write new sysfs entry '%s': %s\n",
+-				filename, strerror(errno));
+-		}
+-	}
+-	close(fd);
+-done:
+-	if (oldvalue)
+-		free(oldvalue);
+-	return ret;
+-}
+diff --git a/Makefile b/Makefile
+index 671e183bd507..10aec937e9e4 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 4
+-SUBLEVEL = 52
++SUBLEVEL = 53
+ EXTRAVERSION =
+ NAME = Blurry Fish Butt
+ 
+diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+index e74df327cdd3..20618a897c99 100644
+--- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
++++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+@@ -122,6 +122,8 @@
+ 			uart1: serial@f8020000 {
+ 				pinctrl-names = "default";
+ 				pinctrl-0 = <&pinctrl_uart1_default>;
++				atmel,use-dma-rx;
++				atmel,use-dma-tx;
+ 				status = "okay";
+ 			};
+ 
+diff --git a/arch/arm/boot/dts/at91-sama5d4_xplained.dts b/arch/arm/boot/dts/at91-sama5d4_xplained.dts
+index da84e65b56ef..e27024cdf48b 100644
+--- a/arch/arm/boot/dts/at91-sama5d4_xplained.dts
++++ b/arch/arm/boot/dts/at91-sama5d4_xplained.dts
+@@ -110,6 +110,8 @@
+ 			};
+ 
+ 			usart3: serial@fc00c000 {
++				atmel,use-dma-rx;
++				atmel,use-dma-tx;
+ 				status = "okay";
+ 			};
+ 
+diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
+index 405aa1883307..23d5cad56ddc 100644
+--- a/arch/arm/include/asm/kvm_mmu.h
++++ b/arch/arm/include/asm/kvm_mmu.h
+@@ -204,18 +204,12 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
+ 	 * and iterate over the range.
+ 	 */
+ 
+-	bool need_flush = !vcpu_has_cache_enabled(vcpu) || ipa_uncached;
+-
+ 	VM_BUG_ON(size & ~PAGE_MASK);
+ 
+-	if (!need_flush && !icache_is_pipt())
+-		goto vipt_cache;
+-
+ 	while (size) {
+ 		void *va = kmap_atomic_pfn(pfn);
+ 
+-		if (need_flush)
+-			kvm_flush_dcache_to_poc(va, PAGE_SIZE);
++		kvm_flush_dcache_to_poc(va, PAGE_SIZE);
+ 
+ 		if (icache_is_pipt())
+ 			__cpuc_coherent_user_range((unsigned long)va,
+@@ -227,7 +221,6 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
+ 		kunmap_atomic(va);
+ 	}
+ 
+-vipt_cache:
+ 	if (!icache_is_pipt() && !icache_is_vivt_asid_tagged()) {
+ 		/* any kind of VIPT cache */
+ 		__flush_icache_all();
+diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
+index 61505676d085..819b21a9851c 100644
+--- a/arch/arm64/include/asm/kvm_mmu.h
++++ b/arch/arm64/include/asm/kvm_mmu.h
+@@ -236,8 +236,7 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
+ {
+ 	void *va = page_address(pfn_to_page(pfn));
+ 
+-	if (!vcpu_has_cache_enabled(vcpu) || ipa_uncached)
+-		kvm_flush_dcache_to_poc(va, size);
++	kvm_flush_dcache_to_poc(va, size);
+ 
+ 	if (!icache_is_aliasing()) {		/* PIPT */
+ 		flush_icache_range((unsigned long)va,
+diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c
+index 52caa75bfe4e..e2f50d690624 100644
+--- a/arch/mips/bcm47xx/buttons.c
++++ b/arch/mips/bcm47xx/buttons.c
+@@ -17,6 +17,12 @@
+ 		.active_low	= 1,					\
+ 	}
+ 
++#define BCM47XX_GPIO_KEY_H(_gpio, _code)				\
++	{								\
++		.code		= _code,				\
++		.gpio		= _gpio,				\
++	}
++
+ /* Asus */
+ 
+ static const struct gpio_keys_button
+@@ -79,8 +85,8 @@ bcm47xx_buttons_asus_wl500gpv2[] __initconst = {
+ 
+ static const struct gpio_keys_button
+ bcm47xx_buttons_asus_wl500w[] __initconst = {
+-	BCM47XX_GPIO_KEY(6, KEY_RESTART),
+-	BCM47XX_GPIO_KEY(7, KEY_WPS_BUTTON),
++	BCM47XX_GPIO_KEY_H(6, KEY_RESTART),
++	BCM47XX_GPIO_KEY_H(7, KEY_WPS_BUTTON),
+ };
+ 
+ static const struct gpio_keys_button
+diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S b/arch/mips/cavium-octeon/octeon-memcpy.S
+index 64e08df51d65..8b7004132491 100644
+--- a/arch/mips/cavium-octeon/octeon-memcpy.S
++++ b/arch/mips/cavium-octeon/octeon-memcpy.S
+@@ -208,18 +208,18 @@ EXC(	STORE	t2, UNIT(6)(dst),	s_exc_p10u)
+ 	ADD	src, src, 16*NBYTES
+ EXC(	STORE	t3, UNIT(7)(dst),	s_exc_p9u)
+ 	ADD	dst, dst, 16*NBYTES
+-EXC(	LOAD	t0, UNIT(-8)(src),	l_exc_copy)
+-EXC(	LOAD	t1, UNIT(-7)(src),	l_exc_copy)
+-EXC(	LOAD	t2, UNIT(-6)(src),	l_exc_copy)
+-EXC(	LOAD	t3, UNIT(-5)(src),	l_exc_copy)
++EXC(	LOAD	t0, UNIT(-8)(src),	l_exc_copy_rewind16)
++EXC(	LOAD	t1, UNIT(-7)(src),	l_exc_copy_rewind16)
++EXC(	LOAD	t2, UNIT(-6)(src),	l_exc_copy_rewind16)
++EXC(	LOAD	t3, UNIT(-5)(src),	l_exc_copy_rewind16)
+ EXC(	STORE	t0, UNIT(-8)(dst),	s_exc_p8u)
+ EXC(	STORE	t1, UNIT(-7)(dst),	s_exc_p7u)
+ EXC(	STORE	t2, UNIT(-6)(dst),	s_exc_p6u)
+ EXC(	STORE	t3, UNIT(-5)(dst),	s_exc_p5u)
+-EXC(	LOAD	t0, UNIT(-4)(src),	l_exc_copy)
+-EXC(	LOAD	t1, UNIT(-3)(src),	l_exc_copy)
+-EXC(	LOAD	t2, UNIT(-2)(src),	l_exc_copy)
+-EXC(	LOAD	t3, UNIT(-1)(src),	l_exc_copy)
++EXC(	LOAD	t0, UNIT(-4)(src),	l_exc_copy_rewind16)
++EXC(	LOAD	t1, UNIT(-3)(src),	l_exc_copy_rewind16)
++EXC(	LOAD	t2, UNIT(-2)(src),	l_exc_copy_rewind16)
++EXC(	LOAD	t3, UNIT(-1)(src),	l_exc_copy_rewind16)
+ EXC(	STORE	t0, UNIT(-4)(dst),	s_exc_p4u)
+ EXC(	STORE	t1, UNIT(-3)(dst),	s_exc_p3u)
+ EXC(	STORE	t2, UNIT(-2)(dst),	s_exc_p2u)
+@@ -383,6 +383,10 @@ done:
+ 	 nop
+ 	END(memcpy)
+ 
++l_exc_copy_rewind16:
++	/* Rewind src and dst by 16*NBYTES for l_exc_copy */
++	SUB	src, src, 16*NBYTES
++	SUB	dst, dst, 16*NBYTES
+ l_exc_copy:
+ 	/*
+ 	 * Copy bytes from src until faulting load address (or until a
+diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h
+index 3ceacde5eb6e..17f89f9670b2 100644
+--- a/arch/mips/include/asm/checksum.h
++++ b/arch/mips/include/asm/checksum.h
+@@ -186,7 +186,9 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr,
+ 	"	daddu	%0, %4		\n"
+ 	"	dsll32	$1, %0, 0	\n"
+ 	"	daddu	%0, $1		\n"
++	"	sltu	$1, %0, $1	\n"
+ 	"	dsra32	%0, %0, 0	\n"
++	"	addu	%0, $1		\n"
+ #endif
+ 	"	.set	pop"
+ 	: "=r" (sum)
+diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
+index 44a6f25e902e..fc537d1b649d 100644
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -191,11 +191,9 @@ struct mips_frame_info {
+ #define J_TARGET(pc,target)	\
+ 		(((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
+ 
+-static inline int is_ra_save_ins(union mips_instruction *ip)
++static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)
+ {
+ #ifdef CONFIG_CPU_MICROMIPS
+-	union mips_instruction mmi;
+-
+ 	/*
+ 	 * swsp ra,offset
+ 	 * swm16 reglist,offset(sp)
+@@ -205,29 +203,71 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
+ 	 *
+ 	 * microMIPS is way more fun...
+ 	 */
+-	if (mm_insn_16bit(ip->halfword[0])) {
+-		mmi.word = (ip->halfword[0] << 16);
+-		return (mmi.mm16_r5_format.opcode == mm_swsp16_op &&
+-			mmi.mm16_r5_format.rt == 31) ||
+-		       (mmi.mm16_m_format.opcode == mm_pool16c_op &&
+-			mmi.mm16_m_format.func == mm_swm16_op);
++	if (mm_insn_16bit(ip->halfword[1])) {
++		switch (ip->mm16_r5_format.opcode) {
++		case mm_swsp16_op:
++			if (ip->mm16_r5_format.rt != 31)
++				return 0;
++
++			*poff = ip->mm16_r5_format.simmediate;
++			*poff = (*poff << 2) / sizeof(ulong);
++			return 1;
++
++		case mm_pool16c_op:
++			switch (ip->mm16_m_format.func) {
++			case mm_swm16_op:
++				*poff = ip->mm16_m_format.imm;
++				*poff += 1 + ip->mm16_m_format.rlist;
++				*poff = (*poff << 2) / sizeof(ulong);
++				return 1;
++
++			default:
++				return 0;
++			}
++
++		default:
++			return 0;
++		}
+ 	}
+-	else {
+-		mmi.halfword[0] = ip->halfword[1];
+-		mmi.halfword[1] = ip->halfword[0];
+-		return (mmi.mm_m_format.opcode == mm_pool32b_op &&
+-			mmi.mm_m_format.rd > 9 &&
+-			mmi.mm_m_format.base == 29 &&
+-			mmi.mm_m_format.func == mm_swm32_func) ||
+-		       (mmi.i_format.opcode == mm_sw32_op &&
+-			mmi.i_format.rs == 29 &&
+-			mmi.i_format.rt == 31);
++
++	switch (ip->i_format.opcode) {
++	case mm_sw32_op:
++		if (ip->i_format.rs != 29)
++			return 0;
++		if (ip->i_format.rt != 31)
++			return 0;
++
++		*poff = ip->i_format.simmediate / sizeof(ulong);
++		return 1;
++
++	case mm_pool32b_op:
++		switch (ip->mm_m_format.func) {
++		case mm_swm32_func:
++			if (ip->mm_m_format.rd < 0x10)
++				return 0;
++			if (ip->mm_m_format.base != 29)
++				return 0;
++
++			*poff = ip->mm_m_format.simmediate;
++			*poff += (ip->mm_m_format.rd & 0xf) * sizeof(u32);
++			*poff /= sizeof(ulong);
++			return 1;
++		default:
++			return 0;
++		}
++
++	default:
++		return 0;
+ 	}
+ #else
+ 	/* sw / sd $ra, offset($sp) */
+-	return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
+-		ip->i_format.rs == 29 &&
+-		ip->i_format.rt == 31;
++	if ((ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
++		ip->i_format.rs == 29 && ip->i_format.rt == 31) {
++		*poff = ip->i_format.simmediate / sizeof(ulong);
++		return 1;
++	}
++
++	return 0;
+ #endif
+ }
+ 
+@@ -242,13 +282,16 @@ static inline int is_jump_ins(union mips_instruction *ip)
+ 	 *
+ 	 * microMIPS is kind of more fun...
+ 	 */
+-	union mips_instruction mmi;
+-
+-	mmi.word = (ip->halfword[0] << 16);
++	if (mm_insn_16bit(ip->halfword[1])) {
++		if ((ip->mm16_r5_format.opcode == mm_pool16c_op &&
++		    (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op))
++			return 1;
++		return 0;
++	}
+ 
+-	if ((mmi.mm16_r5_format.opcode == mm_pool16c_op &&
+-	    (mmi.mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) ||
+-	    ip->j_format.opcode == mm_jal32_op)
++	if (ip->j_format.opcode == mm_j32_op)
++		return 1;
++	if (ip->j_format.opcode == mm_jal32_op)
+ 		return 1;
+ 	if (ip->r_format.opcode != mm_pool32a_op ||
+ 			ip->r_format.func != mm_pool32axf_op)
+@@ -276,15 +319,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
+ 	 *
+ 	 * microMIPS is not more fun...
+ 	 */
+-	if (mm_insn_16bit(ip->halfword[0])) {
+-		union mips_instruction mmi;
+-
+-		mmi.word = (ip->halfword[0] << 16);
+-		return (mmi.mm16_r3_format.opcode == mm_pool16d_op &&
+-			mmi.mm16_r3_format.simmediate && mm_addiusp_func) ||
+-		       (mmi.mm16_r5_format.opcode == mm_pool16d_op &&
+-			mmi.mm16_r5_format.rt == 29);
++	if (mm_insn_16bit(ip->halfword[1])) {
++		return (ip->mm16_r3_format.opcode == mm_pool16d_op &&
++			ip->mm16_r3_format.simmediate && mm_addiusp_func) ||
++		       (ip->mm16_r5_format.opcode == mm_pool16d_op &&
++			ip->mm16_r5_format.rt == 29);
+ 	}
++
+ 	return ip->mm_i_format.opcode == mm_addiu32_op &&
+ 	       ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29;
+ #else
+@@ -299,30 +340,36 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
+ 
+ static int get_frame_info(struct mips_frame_info *info)
+ {
+-#ifdef CONFIG_CPU_MICROMIPS
+-	union mips_instruction *ip = (void *) (((char *) info->func) - 1);
+-#else
+-	union mips_instruction *ip = info->func;
+-#endif
+-	unsigned max_insns = info->func_size / sizeof(union mips_instruction);
+-	unsigned i;
++	bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS);
++	union mips_instruction insn, *ip, *ip_end;
++	const unsigned int max_insns = 128;
++	unsigned int i;
+ 
+ 	info->pc_offset = -1;
+ 	info->frame_size = 0;
+ 
++	ip = (void *)msk_isa16_mode((ulong)info->func);
+ 	if (!ip)
+ 		goto err;
+ 
+-	if (max_insns == 0)
+-		max_insns = 128U;	/* unknown function size */
+-	max_insns = min(128U, max_insns);
++	ip_end = (void *)ip + info->func_size;
+ 
+-	for (i = 0; i < max_insns; i++, ip++) {
++	for (i = 0; i < max_insns && ip < ip_end; i++, ip++) {
++		if (is_mmips && mm_insn_16bit(ip->halfword[0])) {
++			insn.halfword[0] = 0;
++			insn.halfword[1] = ip->halfword[0];
++		} else if (is_mmips) {
++			insn.halfword[0] = ip->halfword[1];
++			insn.halfword[1] = ip->halfword[0];
++		} else {
++			insn.word = ip->word;
++		}
+ 
+-		if (is_jump_ins(ip))
++		if (is_jump_ins(&insn))
+ 			break;
++
+ 		if (!info->frame_size) {
+-			if (is_sp_move_ins(ip))
++			if (is_sp_move_ins(&insn))
+ 			{
+ #ifdef CONFIG_CPU_MICROMIPS
+ 				if (mm_insn_16bit(ip->halfword[0]))
+@@ -345,11 +392,9 @@ static int get_frame_info(struct mips_frame_info *info)
+ 			}
+ 			continue;
+ 		}
+-		if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
+-			info->pc_offset =
+-				ip->i_format.simmediate / sizeof(long);
++		if (info->pc_offset == -1 &&
++		    is_ra_save_ins(&insn, &info->pc_offset))
+ 			break;
+-		}
+ 	}
+ 	if (info->frame_size && info->pc_offset >= 0) /* nested */
+ 		return 0;
+diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
+index 80554e8f6037..3e390a4e3897 100644
+--- a/arch/mips/lantiq/xway/sysctrl.c
++++ b/arch/mips/lantiq/xway/sysctrl.c
+@@ -545,7 +545,7 @@ void __init ltq_soc_init(void)
+ 		clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI);
+ 		clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI);
+ 		clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL);
+-		clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH | PMU_PPE_DP);
++		clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP);
+ 		clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+ 		clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+ 	} else if (of_machine_is_compatible("lantiq,ar10")) {
+@@ -553,7 +553,7 @@ void __init ltq_soc_init(void)
+ 				  ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz());
+ 		clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+ 		clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
+-		clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH |
++		clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH |
+ 			       PMU_PPE_DP | PMU_PPE_TC);
+ 		clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+ 		clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
+@@ -575,11 +575,11 @@ void __init ltq_soc_init(void)
+ 		clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS);
+ 
+ 		clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+-		clkdev_add_pmu("1e108000.eth", NULL, 1, 0,
++		clkdev_add_pmu("1e108000.eth", NULL, 0, 0,
+ 				PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
+ 				PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
+ 				PMU_PPE_QSB | PMU_PPE_TOP);
+-		clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
++		clkdev_add_pmu("1f203000.rcu", "gphy", 0, 0, PMU_GPHY);
+ 		clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
+ 		clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+ 		clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
+diff --git a/arch/mips/mm/sc-ip22.c b/arch/mips/mm/sc-ip22.c
+index dc7c5a5214a9..efaf364fe581 100644
+--- a/arch/mips/mm/sc-ip22.c
++++ b/arch/mips/mm/sc-ip22.c
+@@ -31,26 +31,40 @@ static inline void indy_sc_wipe(unsigned long first, unsigned long last)
+ 	unsigned long tmp;
+ 
+ 	__asm__ __volatile__(
+-	".set\tpush\t\t\t# indy_sc_wipe\n\t"
+-	".set\tnoreorder\n\t"
+-	".set\tmips3\n\t"
+-	".set\tnoat\n\t"
+-	"mfc0\t%2, $12\n\t"
+-	"li\t$1, 0x80\t\t\t# Go 64 bit\n\t"
+-	"mtc0\t$1, $12\n\t"
+-
+-	"dli\t$1, 0x9000000080000000\n\t"
+-	"or\t%0, $1\t\t\t# first line to flush\n\t"
+-	"or\t%1, $1\t\t\t# last line to flush\n\t"
+-	".set\tat\n\t"
+-
+-	"1:\tsw\t$0, 0(%0)\n\t"
+-	"bne\t%0, %1, 1b\n\t"
+-	" daddu\t%0, 32\n\t"
+-
+-	"mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t"
+-	"nop; nop; nop; nop;\n\t"
+-	".set\tpop"
++	"	.set	push			# indy_sc_wipe		\n"
++	"	.set	noreorder					\n"
++	"	.set	mips3						\n"
++	"	.set	noat						\n"
++	"	mfc0	%2, $12						\n"
++	"	li	$1, 0x80		# Go 64 bit		\n"
++	"	mtc0	$1, $12						\n"
++	"								\n"
++	"	#							\n"
++	"	# Open code a dli $1, 0x9000000080000000		\n"
++	"	#							\n"
++	"	# Required because binutils 2.25 will happily accept	\n"
++	"	# 64 bit instructions in .set mips3 mode but puke on	\n"
++	"	# 64 bit constants when generating 32 bit ELF		\n"
++	"	#							\n"
++	"	lui	$1,0x9000					\n"
++	"	dsll	$1,$1,0x10					\n"
++	"	ori	$1,$1,0x8000					\n"
++	"	dsll	$1,$1,0x10					\n"
++	"								\n"
++	"	or	%0, $1			# first line to flush	\n"
++	"	or	%1, $1			# last line to flush	\n"
++	"	.set	at						\n"
++	"								\n"
++	"1:	sw	$0, 0(%0)					\n"
++	"	bne	%0, %1, 1b					\n"
++	"	 daddu	%0, 32						\n"
++	"								\n"
++	"	mtc0	%2, $12			# Back to 32 bit	\n"
++	"	nop				# pipeline hazard	\n"
++	"	nop							\n"
++	"	nop							\n"
++	"	nop							\n"
++	"	.set	pop						\n"
+ 	: "=r" (first), "=r" (last), "=&r" (tmp)
+ 	: "0" (first), "1" (last));
+ }
+diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
+index 05e804cdecaa..fdf48785d3e9 100644
+--- a/arch/powerpc/kernel/hw_breakpoint.c
++++ b/arch/powerpc/kernel/hw_breakpoint.c
+@@ -227,8 +227,10 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
+ 	rcu_read_lock();
+ 
+ 	bp = __this_cpu_read(bp_per_reg);
+-	if (!bp)
++	if (!bp) {
++		rc = NOTIFY_DONE;
+ 		goto out;
++	}
+ 	info = counter_arch_bp(bp);
+ 
+ 	/*
+diff --git a/crypto/testmgr.h b/crypto/testmgr.h
+index da0a8fd765f4..0e02c60a57b6 100644
+--- a/crypto/testmgr.h
++++ b/crypto/testmgr.h
+@@ -21778,7 +21778,7 @@ static struct aead_testvec aes_ccm_enc_tv_template[] = {
+ 			  "\x09\x75\x9a\x9b\x3c\x9b\x27\x39",
+ 		.klen	= 32,
+ 		.iv	= "\x03\xf9\xd9\x4e\x63\xb5\x3d\x9d"
+-			  "\x43\xf6\x1e\x50",
++			  "\x43\xf6\x1e\x50\0\0\0\0",
+ 		.assoc	= "\x57\xf5\x6b\x8b\x57\x5c\x3d\x3b"
+ 			  "\x13\x02\x01\x0c\x83\x4c\x96\x35"
+ 			  "\x8e\xd6\x39\xcf\x7d\x14\x9b\x94"
+diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
+index 59d8d0d14824..327f9e374b44 100644
+--- a/drivers/bcma/main.c
++++ b/drivers/bcma/main.c
+@@ -640,8 +640,11 @@ static int bcma_device_probe(struct device *dev)
+ 					       drv);
+ 	int err = 0;
+ 
++	get_device(dev);
+ 	if (adrv->probe)
+ 		err = adrv->probe(core);
++	if (err)
++		put_device(dev);
+ 
+ 	return err;
+ }
+@@ -654,6 +657,7 @@ static int bcma_device_remove(struct device *dev)
+ 
+ 	if (adrv->remove)
+ 		adrv->remove(core);
++	put_device(dev);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index ab0b2dd3f629..cec36d5c24f5 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1108,9 +1108,12 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
+ 	if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
+ 		return -EINVAL;
+ 
++	/* I/O need to be drained during transfer transition */
++	blk_mq_freeze_queue(lo->lo_queue);
++
+ 	err = loop_release_xfer(lo);
+ 	if (err)
+-		return err;
++		goto exit;
+ 
+ 	if (info->lo_encrypt_type) {
+ 		unsigned int type = info->lo_encrypt_type;
+@@ -1125,12 +1128,14 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
+ 
+ 	err = loop_init_xfer(lo, xfer, info);
+ 	if (err)
+-		return err;
++		goto exit;
+ 
+ 	if (lo->lo_offset != info->lo_offset ||
+ 	    lo->lo_sizelimit != info->lo_sizelimit)
+-		if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit))
+-			return -EFBIG;
++		if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
++			err = -EFBIG;
++			goto exit;
++		}
+ 
+ 	loop_config_discard(lo);
+ 
+@@ -1148,13 +1153,6 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
+ 	     (info->lo_flags & LO_FLAGS_AUTOCLEAR))
+ 		lo->lo_flags ^= LO_FLAGS_AUTOCLEAR;
+ 
+-	if ((info->lo_flags & LO_FLAGS_PARTSCAN) &&
+-	     !(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
+-		lo->lo_flags |= LO_FLAGS_PARTSCAN;
+-		lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
+-		loop_reread_partitions(lo, lo->lo_device);
+-	}
+-
+ 	lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
+ 	lo->lo_init[0] = info->lo_init[0];
+ 	lo->lo_init[1] = info->lo_init[1];
+@@ -1167,7 +1165,17 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
+ 	/* update dio if lo_offset or transfer is changed */
+ 	__loop_update_dio(lo, lo->use_dio);
+ 
+-	return 0;
++ exit:
++	blk_mq_unfreeze_queue(lo->lo_queue);
++
++	if (!err && (info->lo_flags & LO_FLAGS_PARTSCAN) &&
++	     !(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
++		lo->lo_flags |= LO_FLAGS_PARTSCAN;
++		lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
++		loop_reread_partitions(lo, lo->lo_device);
++	}
++
++	return err;
+ }
+ 
+ static int
+diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
+index dd184b50e5b4..284627806b88 100644
+--- a/drivers/dma/ipu/ipu_irq.c
++++ b/drivers/dma/ipu/ipu_irq.c
+@@ -272,7 +272,7 @@ static void ipu_irq_handler(struct irq_desc *desc)
+ 	u32 status;
+ 	int i, line;
+ 
+-	for (i = IPU_IRQ_NR_FN_BANKS; i < IPU_IRQ_NR_BANKS; i++) {
++	for (i = 0; i < IPU_IRQ_NR_BANKS; i++) {
+ 		struct ipu_irq_bank *bank = irq_bank + i;
+ 
+ 		raw_spin_lock(&bank_lock);
+diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
+index 63194a9a7189..89fd0113aa5c 100644
+--- a/drivers/hv/hv.c
++++ b/drivers/hv/hv.c
+@@ -422,7 +422,7 @@ int hv_synic_alloc(void)
+ 		goto err;
+ 	}
+ 
+-	for_each_online_cpu(cpu) {
++	for_each_present_cpu(cpu) {
+ 		hv_context.event_dpc[cpu] = kmalloc(size, GFP_ATOMIC);
+ 		if (hv_context.event_dpc[cpu] == NULL) {
+ 			pr_err("Unable to allocate event dpc\n");
+@@ -461,6 +461,8 @@ int hv_synic_alloc(void)
+ 			pr_err("Unable to allocate post msg page\n");
+ 			goto err;
+ 		}
++
++		INIT_LIST_HEAD(&hv_context.percpu_list[cpu]);
+ 	}
+ 
+ 	return 0;
+@@ -485,7 +487,7 @@ void hv_synic_free(void)
+ 	int cpu;
+ 
+ 	kfree(hv_context.hv_numa_map);
+-	for_each_online_cpu(cpu)
++	for_each_present_cpu(cpu)
+ 		hv_synic_free_cpu(cpu);
+ }
+ 
+@@ -555,8 +557,6 @@ void hv_synic_init(void *arg)
+ 	rdmsrl(HV_X64_MSR_VP_INDEX, vp_index);
+ 	hv_context.vp_index[cpu] = (u32)vp_index;
+ 
+-	INIT_LIST_HEAD(&hv_context.percpu_list[cpu]);
+-
+ 	/*
+ 	 * Register the per-cpu clockevent source.
+ 	 */
+diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c
+index c37a71e13de0..1fb02dcbc500 100644
+--- a/drivers/hv/hv_fcopy.c
++++ b/drivers/hv/hv_fcopy.c
+@@ -61,6 +61,7 @@ static DECLARE_WORK(fcopy_send_work, fcopy_send_data);
+ static const char fcopy_devname[] = "vmbus/hv_fcopy";
+ static u8 *recv_buffer;
+ static struct hvutil_transport *hvt;
++static struct completion release_event;
+ /*
+  * This state maintains the version number registered by the daemon.
+  */
+@@ -312,12 +313,14 @@ static void fcopy_on_reset(void)
+ 
+ 	if (cancel_delayed_work_sync(&fcopy_timeout_work))
+ 		fcopy_respond_to_host(HV_E_FAIL);
++	complete(&release_event);
+ }
+ 
+ int hv_fcopy_init(struct hv_util_service *srv)
+ {
+ 	recv_buffer = srv->recv_buffer;
+ 
++	init_completion(&release_event);
+ 	/*
+ 	 * When this driver loads, the user level daemon that
+ 	 * processes the host requests may not yet be running.
+@@ -339,4 +342,5 @@ void hv_fcopy_deinit(void)
+ 	fcopy_transaction.state = HVUTIL_DEVICE_DYING;
+ 	cancel_delayed_work_sync(&fcopy_timeout_work);
+ 	hvutil_transport_destroy(hvt);
++	wait_for_completion(&release_event);
+ }
+diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
+index 2a3420c4ca59..ce4d3a935491 100644
+--- a/drivers/hv/hv_kvp.c
++++ b/drivers/hv/hv_kvp.c
+@@ -86,6 +86,7 @@ static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
+ static const char kvp_devname[] = "vmbus/hv_kvp";
+ static u8 *recv_buffer;
+ static struct hvutil_transport *hvt;
++static struct completion release_event;
+ /*
+  * Register the kernel component with the user-level daemon.
+  * As part of this registration, pass the LIC version number.
+@@ -682,6 +683,7 @@ static void kvp_on_reset(void)
+ 	if (cancel_delayed_work_sync(&kvp_timeout_work))
+ 		kvp_respond_to_host(NULL, HV_E_FAIL);
+ 	kvp_transaction.state = HVUTIL_DEVICE_INIT;
++	complete(&release_event);
+ }
+ 
+ int
+@@ -689,6 +691,7 @@ hv_kvp_init(struct hv_util_service *srv)
+ {
+ 	recv_buffer = srv->recv_buffer;
+ 
++	init_completion(&release_event);
+ 	/*
+ 	 * When this driver loads, the user level daemon that
+ 	 * processes the host requests may not yet be running.
+@@ -711,4 +714,5 @@ void hv_kvp_deinit(void)
+ 	cancel_delayed_work_sync(&kvp_timeout_work);
+ 	cancel_work_sync(&kvp_sendkey_work);
+ 	hvutil_transport_destroy(hvt);
++	wait_for_completion(&release_event);
+ }
+diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
+index 81882d4848bd..faad79ae318a 100644
+--- a/drivers/hv/hv_snapshot.c
++++ b/drivers/hv/hv_snapshot.c
+@@ -66,6 +66,7 @@ static int dm_reg_value;
+ static const char vss_devname[] = "vmbus/hv_vss";
+ static __u8 *recv_buffer;
+ static struct hvutil_transport *hvt;
++static struct completion release_event;
+ 
+ static void vss_send_op(struct work_struct *dummy);
+ static void vss_timeout_func(struct work_struct *dummy);
+@@ -326,11 +327,13 @@ static void vss_on_reset(void)
+ 	if (cancel_delayed_work_sync(&vss_timeout_work))
+ 		vss_respond_to_host(HV_E_FAIL);
+ 	vss_transaction.state = HVUTIL_DEVICE_INIT;
++	complete(&release_event);
+ }
+ 
+ int
+ hv_vss_init(struct hv_util_service *srv)
+ {
++	init_completion(&release_event);
+ 	if (vmbus_proto_version < VERSION_WIN8_1) {
+ 		pr_warn("Integration service 'Backup (volume snapshot)'"
+ 			" not supported on this host version.\n");
+@@ -360,4 +363,5 @@ void hv_vss_deinit(void)
+ 	cancel_delayed_work_sync(&vss_timeout_work);
+ 	cancel_work_sync(&vss_send_op_work);
+ 	hvutil_transport_destroy(hvt);
++	wait_for_completion(&release_event);
+ }
+diff --git a/drivers/iio/pressure/mpl115.c b/drivers/iio/pressure/mpl115.c
+index a0d7deeac62f..3f90985d545e 100644
+--- a/drivers/iio/pressure/mpl115.c
++++ b/drivers/iio/pressure/mpl115.c
+@@ -136,6 +136,7 @@ static const struct iio_chan_spec mpl115_channels[] = {
+ 	{
+ 		.type = IIO_TEMP,
+ 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++		.info_mask_shared_by_type =
+ 			BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE),
+ 	},
+ };
+diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c
+index 01b2e0b18878..0f5b8767ec2e 100644
+--- a/drivers/iio/pressure/mpl3115.c
++++ b/drivers/iio/pressure/mpl3115.c
+@@ -182,7 +182,7 @@ static const struct iio_chan_spec mpl3115_channels[] = {
+ 	{
+ 		.type = IIO_PRESSURE,
+ 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+-			BIT(IIO_CHAN_INFO_SCALE),
++		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ 		.scan_index = 0,
+ 		.scan_type = {
+ 			.sign = 'u',
+@@ -195,7 +195,7 @@ static const struct iio_chan_spec mpl3115_channels[] = {
+ 	{
+ 		.type = IIO_TEMP,
+ 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+-			BIT(IIO_CHAN_INFO_SCALE),
++		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ 		.scan_index = 1,
+ 		.scan_type = {
+ 			.sign = 's',
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index c9dcad6a53bf..3f5741a3e728 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -3349,6 +3349,9 @@ static int cma_accept_iw(struct rdma_id_private *id_priv,
+ 	struct iw_cm_conn_param iw_param;
+ 	int ret;
+ 
++	if (!conn_param)
++		return -EINVAL;
++
+ 	ret = cma_modify_qp_rtr(id_priv, conn_param);
+ 	if (ret)
+ 		return ret;
+diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
+index 9413b0726237..f0fc6f7b5d98 100644
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -3238,13 +3238,14 @@ static int __init init_dmars(void)
+ 	iommu_identity_mapping |= IDENTMAP_GFX;
+ #endif
+ 
++	check_tylersburg_isoch();
++
+ 	if (iommu_identity_mapping) {
+ 		ret = si_domain_init(hw_pass_through);
+ 		if (ret)
+ 			goto free_iommu;
+ 	}
+ 
+-	check_tylersburg_isoch();
+ 
+ 	/*
+ 	 * If we copied translations from a previous kernel in the kdump
+diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
+index 515f83e7d9ab..b59615ddf6ba 100644
+--- a/drivers/md/dm-cache-target.c
++++ b/drivers/md/dm-cache-target.c
+@@ -251,7 +251,7 @@ struct cache {
+ 	/*
+ 	 * Fields for converting from sectors to blocks.
+ 	 */
+-	uint32_t sectors_per_block;
++	sector_t sectors_per_block;
+ 	int sectors_per_block_shift;
+ 
+ 	spinlock_t lock;
+@@ -3547,11 +3547,11 @@ static void cache_status(struct dm_target *ti, status_type_t type,
+ 
+ 		residency = policy_residency(cache->policy);
+ 
+-		DMEMIT("%u %llu/%llu %u %llu/%llu %u %u %u %u %u %u %lu ",
++		DMEMIT("%u %llu/%llu %llu %llu/%llu %u %u %u %u %u %u %lu ",
+ 		       (unsigned)DM_CACHE_METADATA_BLOCK_SIZE,
+ 		       (unsigned long long)(nr_blocks_metadata - nr_free_blocks_metadata),
+ 		       (unsigned long long)nr_blocks_metadata,
+-		       cache->sectors_per_block,
++		       (unsigned long long)cache->sectors_per_block,
+ 		       (unsigned long long) from_cblock(residency),
+ 		       (unsigned long long) from_cblock(cache->cache_size),
+ 		       (unsigned) atomic_read(&cache->stats.read_hit),
+diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c
+index 8289804ccd99..d5ea9f28ae70 100644
+--- a/drivers/md/dm-stats.c
++++ b/drivers/md/dm-stats.c
+@@ -175,6 +175,7 @@ static void dm_stat_free(struct rcu_head *head)
+ 	int cpu;
+ 	struct dm_stat *s = container_of(head, struct dm_stat, rcu_head);
+ 
++	kfree(s->histogram_boundaries);
+ 	kfree(s->program_id);
+ 	kfree(s->aux_data);
+ 	for_each_possible_cpu(cpu) {
+diff --git a/drivers/md/linear.c b/drivers/md/linear.c
+index b7fe7e9fc777..6ba3227e29b2 100644
+--- a/drivers/md/linear.c
++++ b/drivers/md/linear.c
+@@ -52,18 +52,26 @@ static inline struct dev_info *which_dev(struct mddev *mddev, sector_t sector)
+ 	return conf->disks + lo;
+ }
+ 
++/*
++ * In linear_congested() conf->raid_disks is used as a copy of
++ * mddev->raid_disks to iterate conf->disks[], because conf->raid_disks
++ * and conf->disks[] are created in linear_conf(), they are always
++ * consitent with each other, but mddev->raid_disks does not.
++ */
+ static int linear_congested(struct mddev *mddev, int bits)
+ {
+ 	struct linear_conf *conf;
+ 	int i, ret = 0;
+ 
+-	conf = mddev->private;
++	rcu_read_lock();
++	conf = rcu_dereference(mddev->private);
+ 
+-	for (i = 0; i < mddev->raid_disks && !ret ; i++) {
++	for (i = 0; i < conf->raid_disks && !ret ; i++) {
+ 		struct request_queue *q = bdev_get_queue(conf->disks[i].rdev->bdev);
+ 		ret |= bdi_congested(&q->backing_dev_info, bits);
+ 	}
+ 
++	rcu_read_unlock();
+ 	return ret;
+ }
+ 
+@@ -143,6 +151,19 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
+ 			conf->disks[i-1].end_sector +
+ 			conf->disks[i].rdev->sectors;
+ 
++	/*
++	 * conf->raid_disks is copy of mddev->raid_disks. The reason to
++	 * keep a copy of mddev->raid_disks in struct linear_conf is,
++	 * mddev->raid_disks may not be consistent with pointers number of
++	 * conf->disks[] when it is updated in linear_add() and used to
++	 * iterate old conf->disks[] earray in linear_congested().
++	 * Here conf->raid_disks is always consitent with number of
++	 * pointers in conf->disks[] array, and mddev->private is updated
++	 * with rcu_assign_pointer() in linear_addr(), such race can be
++	 * avoided.
++	 */
++	conf->raid_disks = raid_disks;
++
+ 	return conf;
+ 
+ out:
+@@ -195,15 +216,23 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
+ 	if (!newconf)
+ 		return -ENOMEM;
+ 
++	/* newconf->raid_disks already keeps a copy of * the increased
++	 * value of mddev->raid_disks, WARN_ONCE() is just used to make
++	 * sure of this. It is possible that oldconf is still referenced
++	 * in linear_congested(), therefore kfree_rcu() is used to free
++	 * oldconf until no one uses it anymore.
++	 */
+ 	mddev_suspend(mddev);
+-	oldconf = mddev->private;
++	oldconf = rcu_dereference(mddev->private);
+ 	mddev->raid_disks++;
+-	mddev->private = newconf;
++	WARN_ONCE(mddev->raid_disks != newconf->raid_disks,
++		"copied raid_disks doesn't match mddev->raid_disks");
++	rcu_assign_pointer(mddev->private, newconf);
+ 	md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
+ 	set_capacity(mddev->gendisk, mddev->array_sectors);
+ 	mddev_resume(mddev);
+ 	revalidate_disk(mddev->gendisk);
+-	kfree(oldconf);
++	kfree_rcu(oldconf, rcu);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/md/linear.h b/drivers/md/linear.h
+index b685ddd7d7f7..8d392e6098b3 100644
+--- a/drivers/md/linear.h
++++ b/drivers/md/linear.h
+@@ -10,6 +10,7 @@ struct linear_conf
+ {
+ 	struct rcu_head		rcu;
+ 	sector_t		array_sectors;
++	int			raid_disks; /* a copy of mddev->raid_disks */
+ 	struct dev_info		disks[0];
+ };
+ #endif
+diff --git a/drivers/media/pci/dm1105/Kconfig b/drivers/media/pci/dm1105/Kconfig
+index 173daf0c0847..14fa7e40f2a6 100644
+--- a/drivers/media/pci/dm1105/Kconfig
++++ b/drivers/media/pci/dm1105/Kconfig
+@@ -1,6 +1,6 @@
+ config DVB_DM1105
+ 	tristate "SDMC DM1105 based PCI cards"
+-	depends on DVB_CORE && PCI && I2C
++	depends on DVB_CORE && PCI && I2C && I2C_ALGOBIT
+ 	select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ 	select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ 	select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
+diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
+index ba780c45f645..572bc043b62d 100644
+--- a/drivers/media/platform/am437x/am437x-vpfe.c
++++ b/drivers/media/platform/am437x/am437x-vpfe.c
+@@ -1576,7 +1576,7 @@ static int vpfe_s_fmt(struct file *file, void *priv,
+ 		return -EBUSY;
+ 	}
+ 
+-	ret = vpfe_try_fmt(file, priv, &format);
++	ret = __vpfe_get_format(vpfe, &format, &bpp);
+ 	if (ret)
+ 		return ret;
+ 
+diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
+index cfb868a48b5f..ff6feff21e94 100644
+--- a/drivers/media/usb/uvc/uvc_queue.c
++++ b/drivers/media/usb/uvc/uvc_queue.c
+@@ -416,7 +416,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
+ 		nextbuf = NULL;
+ 	spin_unlock_irqrestore(&queue->irqlock, flags);
+ 
+-	buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
++	buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
+ 	vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
+ 	vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
+ 
+diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
+index a731720f1d13..449b2a47f9a8 100644
+--- a/drivers/net/can/usb/usb_8dev.c
++++ b/drivers/net/can/usb/usb_8dev.c
+@@ -954,8 +954,8 @@ static int usb_8dev_probe(struct usb_interface *intf,
+ 	for (i = 0; i < MAX_TX_URBS; i++)
+ 		priv->tx_contexts[i].echo_index = MAX_TX_URBS;
+ 
+-	priv->cmd_msg_buffer = kzalloc(sizeof(struct usb_8dev_cmd_msg),
+-				      GFP_KERNEL);
++	priv->cmd_msg_buffer = devm_kzalloc(&intf->dev, sizeof(struct usb_8dev_cmd_msg),
++					    GFP_KERNEL);
+ 	if (!priv->cmd_msg_buffer)
+ 		goto cleanup_candev;
+ 
+@@ -969,7 +969,7 @@ static int usb_8dev_probe(struct usb_interface *intf,
+ 	if (err) {
+ 		netdev_err(netdev,
+ 			"couldn't register CAN device: %d\n", err);
+-		goto cleanup_cmd_msg_buffer;
++		goto cleanup_candev;
+ 	}
+ 
+ 	err = usb_8dev_cmd_version(priv, &version);
+@@ -990,9 +990,6 @@ static int usb_8dev_probe(struct usb_interface *intf,
+ cleanup_unregister_candev:
+ 	unregister_netdev(priv->netdev);
+ 
+-cleanup_cmd_msg_buffer:
+-	kfree(priv->cmd_msg_buffer);
+-
+ cleanup_candev:
+ 	free_candev(netdev);
+ 
+diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+index dc44cfef7517..16e052d02c94 100644
+--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+@@ -502,8 +502,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ 			break;
+ 		return -EOPNOTSUPP;
+ 	default:
+-		WARN_ON(1);
+-		return -EINVAL;
++		return -EOPNOTSUPP;
+ 	}
+ 
+ 	mutex_lock(&ah->lock);
+diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+index 694ca2e680e5..74670e08e6da 100644
+--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+@@ -73,13 +73,13 @@
+ #define AR9300_OTP_BASE \
+ 		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
+ #define AR9300_OTP_STATUS \
+-		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
++		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x31018 : 0x15f18)
+ #define AR9300_OTP_STATUS_TYPE		0x7
+ #define AR9300_OTP_STATUS_VALID		0x4
+ #define AR9300_OTP_STATUS_ACCESS_BUSY	0x2
+ #define AR9300_OTP_STATUS_SM_BUSY	0x1
+ #define AR9300_OTP_READ_DATA \
+-		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
++		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3101c : 0x15f1c)
+ 
+ enum targetPowerHTRates {
+ 	HT_TARGET_RATE_0_8_16,
+diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
+index b42f4a963ef4..a660e40f2df1 100644
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -959,6 +959,7 @@ struct ath_softc {
+ 	struct survey_info *cur_survey;
+ 	struct survey_info survey[ATH9K_NUM_CHANNELS];
+ 
++	spinlock_t intr_lock;
+ 	struct tasklet_struct intr_tq;
+ 	struct tasklet_struct bcon_tasklet;
+ 	struct ath_hw *sc_ah;
+diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
+index bc70ce62bc03..0f5672f5c9ba 100644
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -619,6 +619,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
+ 		common->bt_ant_diversity = 1;
+ 
+ 	spin_lock_init(&common->cc_lock);
++	spin_lock_init(&sc->intr_lock);
+ 	spin_lock_init(&sc->sc_serial_rw);
+ 	spin_lock_init(&sc->sc_pm_lock);
+ 	spin_lock_init(&sc->chan_lock);
+diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
+index bba85d1a6cd1..d937c39b3a0b 100644
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -805,21 +805,12 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah)
+ }
+ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
+ 
+-void ath9k_hw_enable_interrupts(struct ath_hw *ah)
++static void __ath9k_hw_enable_interrupts(struct ath_hw *ah)
+ {
+ 	struct ath_common *common = ath9k_hw_common(ah);
+ 	u32 sync_default = AR_INTR_SYNC_DEFAULT;
+ 	u32 async_mask;
+ 
+-	if (!(ah->imask & ATH9K_INT_GLOBAL))
+-		return;
+-
+-	if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
+-		ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
+-			atomic_read(&ah->intr_ref_cnt));
+-		return;
+-	}
+-
+ 	if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
+ 	    AR_SREV_9561(ah))
+ 		sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+@@ -841,6 +832,39 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
+ 	ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+ 		REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+ }
++
++void ath9k_hw_resume_interrupts(struct ath_hw *ah)
++{
++	struct ath_common *common = ath9k_hw_common(ah);
++
++	if (!(ah->imask & ATH9K_INT_GLOBAL))
++		return;
++
++	if (atomic_read(&ah->intr_ref_cnt) != 0) {
++		ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
++			atomic_read(&ah->intr_ref_cnt));
++		return;
++	}
++
++	__ath9k_hw_enable_interrupts(ah);
++}
++EXPORT_SYMBOL(ath9k_hw_resume_interrupts);
++
++void ath9k_hw_enable_interrupts(struct ath_hw *ah)
++{
++	struct ath_common *common = ath9k_hw_common(ah);
++
++	if (!(ah->imask & ATH9K_INT_GLOBAL))
++		return;
++
++	if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
++		ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
++			atomic_read(&ah->intr_ref_cnt));
++		return;
++	}
++
++	__ath9k_hw_enable_interrupts(ah);
++}
+ EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
+ 
+ void ath9k_hw_set_interrupts(struct ath_hw *ah)
+diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
+index 7fbf7f965f61..1b63d26f30ce 100644
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -748,6 +748,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah);
+ void ath9k_hw_enable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_disable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_kill_interrupts(struct ath_hw *ah);
++void ath9k_hw_resume_interrupts(struct ath_hw *ah);
+ 
+ void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
+ 
+diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
+index 8c5d2cf9c979..b114e57a823f 100644
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -373,21 +373,20 @@ void ath9k_tasklet(unsigned long data)
+ 	struct ath_common *common = ath9k_hw_common(ah);
+ 	enum ath_reset_type type;
+ 	unsigned long flags;
+-	u32 status = sc->intrstatus;
++	u32 status;
+ 	u32 rxmask;
+ 
++	spin_lock_irqsave(&sc->intr_lock, flags);
++	status = sc->intrstatus;
++	sc->intrstatus = 0;
++	spin_unlock_irqrestore(&sc->intr_lock, flags);
++
+ 	ath9k_ps_wakeup(sc);
+ 	spin_lock(&sc->sc_pcu_lock);
+ 
+ 	if (status & ATH9K_INT_FATAL) {
+ 		type = RESET_TYPE_FATAL_INT;
+ 		ath9k_queue_reset(sc, type);
+-
+-		/*
+-		 * Increment the ref. counter here so that
+-		 * interrupts are enabled in the reset routine.
+-		 */
+-		atomic_inc(&ah->intr_ref_cnt);
+ 		ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
+ 		goto out;
+ 	}
+@@ -403,11 +402,6 @@ void ath9k_tasklet(unsigned long data)
+ 			type = RESET_TYPE_BB_WATCHDOG;
+ 			ath9k_queue_reset(sc, type);
+ 
+-			/*
+-			 * Increment the ref. counter here so that
+-			 * interrupts are enabled in the reset routine.
+-			 */
+-			atomic_inc(&ah->intr_ref_cnt);
+ 			ath_dbg(common, RESET,
+ 				"BB_WATCHDOG: Skipping interrupts\n");
+ 			goto out;
+@@ -420,7 +414,6 @@ void ath9k_tasklet(unsigned long data)
+ 		if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
+ 			type = RESET_TYPE_TX_GTT;
+ 			ath9k_queue_reset(sc, type);
+-			atomic_inc(&ah->intr_ref_cnt);
+ 			ath_dbg(common, RESET,
+ 				"GTT: Skipping interrupts\n");
+ 			goto out;
+@@ -477,7 +470,7 @@ void ath9k_tasklet(unsigned long data)
+ 	ath9k_btcoex_handle_interrupt(sc, status);
+ 
+ 	/* re-enable hardware interrupt */
+-	ath9k_hw_enable_interrupts(ah);
++	ath9k_hw_resume_interrupts(ah);
+ out:
+ 	spin_unlock(&sc->sc_pcu_lock);
+ 	ath9k_ps_restore(sc);
+@@ -541,7 +534,9 @@ irqreturn_t ath_isr(int irq, void *dev)
+ 		return IRQ_NONE;
+ 
+ 	/* Cache the status */
+-	sc->intrstatus = status;
++	spin_lock(&sc->intr_lock);
++	sc->intrstatus |= status;
++	spin_unlock(&sc->intr_lock);
+ 
+ 	if (status & SCHED_INTR)
+ 		sched = true;
+@@ -587,7 +582,7 @@ chip_reset:
+ 
+ 	if (sched) {
+ 		/* turn off every interrupt */
+-		ath9k_hw_disable_interrupts(ah);
++		ath9k_hw_kill_interrupts(ah);
+ 		tasklet_schedule(&sc->intr_tq);
+ 	}
+ 
+diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.h b/drivers/net/wireless/realtek/rtlwifi/pci.h
+index 5da6703942d9..672f81ea02d0 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/pci.h
++++ b/drivers/net/wireless/realtek/rtlwifi/pci.h
+@@ -275,10 +275,10 @@ struct mp_adapter {
+ };
+ 
+ struct rtl_pci_priv {
++	struct bt_coexist_info bt_coexist;
++	struct rtl_led_ctl ledctl;
+ 	struct rtl_pci dev;
+ 	struct mp_adapter ndis_adapter;
+-	struct rtl_led_ctl ledctl;
+-	struct bt_coexist_info bt_coexist;
+ };
+ 
+ #define rtl_pcipriv(hw)		(((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
+index 5f14308e8eb3..b1601441991d 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
+@@ -1003,7 +1003,7 @@ static void _rtl92ee_hw_configure(struct ieee80211_hw *hw)
+ 	rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x100a);
+ 
+ 	/* Note Data sheet don't define */
+-	rtl_write_word(rtlpriv, 0x4C7, 0x80);
++	rtl_write_byte(rtlpriv, 0x4C7, 0x80);
+ 
+ 	rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
+ 
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+index bbb789f8990b..c2103e7a8132 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+@@ -1127,7 +1127,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
+ 	}
+ 	if (0 == tmp) {
+ 		read_addr = REG_DBI_RDATA + addr % 4;
+-		ret = rtl_read_word(rtlpriv, read_addr);
++		ret = rtl_read_byte(rtlpriv, read_addr);
+ 	}
+ 	return ret;
+ }
+diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.h b/drivers/net/wireless/realtek/rtlwifi/usb.h
+index 685273ca9561..441c4412130c 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/usb.h
++++ b/drivers/net/wireless/realtek/rtlwifi/usb.h
+@@ -150,8 +150,9 @@ struct rtl_usb {
+ };
+ 
+ struct rtl_usb_priv {
+-	struct rtl_usb dev;
++	struct bt_coexist_info bt_coexist;
+ 	struct rtl_led_ctl ledctl;
++	struct rtl_usb dev;
+ };
+ 
+ #define rtl_usbpriv(hw)	 (((struct rtl_usb_priv *)(rtl_priv(hw))->priv))
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 732ac71b82cd..88dbbeb8569b 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -4273,12 +4273,13 @@ static void regulator_summary_show_subtree(struct seq_file *s,
+ 	seq_puts(s, "\n");
+ 
+ 	list_for_each_entry(consumer, &rdev->consumer_list, list) {
+-		if (consumer->dev->class == &regulator_class)
++		if (consumer->dev && consumer->dev->class == &regulator_class)
+ 			continue;
+ 
+ 		seq_printf(s, "%*s%-*s ",
+ 			   (level + 1) * 3 + 1, "",
+-			   30 - (level + 1) * 3, dev_name(consumer->dev));
++			   30 - (level + 1) * 3,
++			   consumer->dev ? dev_name(consumer->dev) : "deviceless");
+ 
+ 		switch (rdev->desc->type) {
+ 		case REGULATOR_VOLTAGE:
+diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
+index c169a2cd4727..e29cc9fca0bf 100644
+--- a/drivers/rtc/rtc-sun6i.c
++++ b/drivers/rtc/rtc-sun6i.c
+@@ -37,9 +37,11 @@
+ 
+ /* Control register */
+ #define SUN6I_LOSC_CTRL				0x0000
++#define SUN6I_LOSC_CTRL_KEY			(0x16aa << 16)
+ #define SUN6I_LOSC_CTRL_ALM_DHMS_ACC		BIT(9)
+ #define SUN6I_LOSC_CTRL_RTC_HMS_ACC		BIT(8)
+ #define SUN6I_LOSC_CTRL_RTC_YMD_ACC		BIT(7)
++#define SUN6I_LOSC_CTRL_EXT_OSC			BIT(0)
+ #define SUN6I_LOSC_CTRL_ACC_MASK		GENMASK(9, 7)
+ 
+ /* RTC */
+@@ -114,13 +116,17 @@ struct sun6i_rtc_dev {
+ 	void __iomem *base;
+ 	int irq;
+ 	unsigned long alarm;
++
++	spinlock_t lock;
+ };
+ 
+ static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
+ {
+ 	struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
++	irqreturn_t ret = IRQ_NONE;
+ 	u32 val;
+ 
++	spin_lock(&chip->lock);
+ 	val = readl(chip->base + SUN6I_ALRM_IRQ_STA);
+ 
+ 	if (val & SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND) {
+@@ -129,10 +135,11 @@ static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
+ 
+ 		rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
+ 
+-		return IRQ_HANDLED;
++		ret = IRQ_HANDLED;
+ 	}
++	spin_unlock(&chip->lock);
+ 
+-	return IRQ_NONE;
++	return ret;
+ }
+ 
+ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
+@@ -140,6 +147,7 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
+ 	u32 alrm_val = 0;
+ 	u32 alrm_irq_val = 0;
+ 	u32 alrm_wake_val = 0;
++	unsigned long flags;
+ 
+ 	if (to) {
+ 		alrm_val = SUN6I_ALRM_EN_CNT_EN;
+@@ -150,9 +158,11 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
+ 		       chip->base + SUN6I_ALRM_IRQ_STA);
+ 	}
+ 
++	spin_lock_irqsave(&chip->lock, flags);
+ 	writel(alrm_val, chip->base + SUN6I_ALRM_EN);
+ 	writel(alrm_irq_val, chip->base + SUN6I_ALRM_IRQ_EN);
+ 	writel(alrm_wake_val, chip->base + SUN6I_ALARM_CONFIG);
++	spin_unlock_irqrestore(&chip->lock, flags);
+ }
+ 
+ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
+@@ -191,11 +201,15 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
+ static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+ {
+ 	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
++	unsigned long flags;
+ 	u32 alrm_st;
+ 	u32 alrm_en;
+ 
++	spin_lock_irqsave(&chip->lock, flags);
+ 	alrm_en = readl(chip->base + SUN6I_ALRM_IRQ_EN);
+ 	alrm_st = readl(chip->base + SUN6I_ALRM_IRQ_STA);
++	spin_unlock_irqrestore(&chip->lock, flags);
++
+ 	wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN);
+ 	wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN);
+ 	rtc_time_to_tm(chip->alarm, &wkalrm->time);
+@@ -356,6 +370,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
+ 	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+ 	if (!chip)
+ 		return -ENOMEM;
++	spin_lock_init(&chip->lock);
+ 
+ 	platform_set_drvdata(pdev, chip);
+ 	chip->dev = &pdev->dev;
+@@ -404,6 +419,10 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
+ 	/* disable alarm wakeup */
+ 	writel(0, chip->base + SUN6I_ALARM_CONFIG);
+ 
++	/* switch to the external, more precise, oscillator */
++	writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
++	       chip->base + SUN6I_LOSC_CTRL);
++
+ 	chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
+ 					&sun6i_rtc_ops, THIS_MODULE);
+ 	if (IS_ERR(chip->rtc)) {
+diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
+index bc0203f3d243..e415e1c58eb5 100644
+--- a/drivers/scsi/aacraid/src.c
++++ b/drivers/scsi/aacraid/src.c
+@@ -413,16 +413,23 @@ static int aac_src_check_health(struct aac_dev *dev)
+ 	u32 status = src_readl(dev, MUnit.OMR);
+ 
+ 	/*
++	 *	Check to see if the board panic'd.
++	 */
++	if (unlikely(status & KERNEL_PANIC))
++		goto err_blink;
++
++	/*
+ 	 *	Check to see if the board failed any self tests.
+ 	 */
+ 	if (unlikely(status & SELF_TEST_FAILED))
+-		return -1;
++		goto err_out;
+ 
+ 	/*
+-	 *	Check to see if the board panic'd.
++	 *	Check to see if the board failed any self tests.
+ 	 */
+-	if (unlikely(status & KERNEL_PANIC))
+-		return (status >> 16) & 0xFF;
++	if (unlikely(status & MONITOR_PANIC))
++		goto err_out;
++
+ 	/*
+ 	 *	Wait for the adapter to be up and running.
+ 	 */
+@@ -432,6 +439,12 @@ static int aac_src_check_health(struct aac_dev *dev)
+ 	 *	Everything is OK
+ 	 */
+ 	return 0;
++
++err_out:
++	return -1;
++
++err_blink:
++	return (status > 16) & 0xFF;
+ }
+ 
+ /**
+diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
+index 33ec4fa39ccb..f224cdb2fce4 100644
+--- a/drivers/scsi/lpfc/lpfc_hw4.h
++++ b/drivers/scsi/lpfc/lpfc_hw4.h
+@@ -1182,6 +1182,7 @@ struct lpfc_mbx_wq_create {
+ #define lpfc_mbx_wq_create_page_size_SHIFT	0
+ #define lpfc_mbx_wq_create_page_size_MASK	0x000000FF
+ #define lpfc_mbx_wq_create_page_size_WORD	word1
++#define LPFC_WQ_PAGE_SIZE_4096	0x1
+ #define lpfc_mbx_wq_create_wqe_size_SHIFT	8
+ #define lpfc_mbx_wq_create_wqe_size_MASK	0x0000000F
+ #define lpfc_mbx_wq_create_wqe_size_WORD	word1
+@@ -1253,6 +1254,7 @@ struct rq_context {
+ #define lpfc_rq_context_page_size_SHIFT	0		/* Version 1 Only */
+ #define lpfc_rq_context_page_size_MASK	0x000000FF
+ #define lpfc_rq_context_page_size_WORD	word0
++#define	LPFC_RQ_PAGE_SIZE_4096	0x1
+ 	uint32_t reserved1;
+ 	uint32_t word2;
+ #define lpfc_rq_context_cq_id_SHIFT	16
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 92dfd6a5178c..f5aeda8f014f 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -13475,7 +13475,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
+ 			       LPFC_WQ_WQE_SIZE_128);
+ 			bf_set(lpfc_mbx_wq_create_page_size,
+ 			       &wq_create->u.request_1,
+-			       (PAGE_SIZE/SLI4_PAGE_SIZE));
++			       LPFC_WQ_PAGE_SIZE_4096);
+ 			page = wq_create->u.request_1.page;
+ 			break;
+ 		}
+@@ -13501,8 +13501,9 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
+ 			       LPFC_WQ_WQE_SIZE_128);
+ 			break;
+ 		}
+-		bf_set(lpfc_mbx_wq_create_page_size, &wq_create->u.request_1,
+-		       (PAGE_SIZE/SLI4_PAGE_SIZE));
++		bf_set(lpfc_mbx_wq_create_page_size,
++		       &wq_create->u.request_1,
++		       LPFC_WQ_PAGE_SIZE_4096);
+ 		page = wq_create->u.request_1.page;
+ 		break;
+ 	default:
+@@ -13688,7 +13689,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
+ 		       LPFC_RQE_SIZE_8);
+ 		bf_set(lpfc_rq_context_page_size,
+ 		       &rq_create->u.request.context,
+-		       (PAGE_SIZE/SLI4_PAGE_SIZE));
++		       LPFC_RQ_PAGE_SIZE_4096);
+ 	} else {
+ 		switch (hrq->entry_count) {
+ 		default:
+diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c
+index e7649ed3f667..4d655b568269 100644
+--- a/drivers/scsi/scsi_dh.c
++++ b/drivers/scsi/scsi_dh.c
+@@ -289,20 +289,6 @@ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
+ }
+ EXPORT_SYMBOL_GPL(scsi_unregister_device_handler);
+ 
+-static struct scsi_device *get_sdev_from_queue(struct request_queue *q)
+-{
+-	struct scsi_device *sdev;
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(q->queue_lock, flags);
+-	sdev = q->queuedata;
+-	if (!sdev || !get_device(&sdev->sdev_gendev))
+-		sdev = NULL;
+-	spin_unlock_irqrestore(q->queue_lock, flags);
+-
+-	return sdev;
+-}
+-
+ /*
+  * scsi_dh_activate - activate the path associated with the scsi_device
+  *      corresponding to the given request queue.
+@@ -321,7 +307,7 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
+ 	struct scsi_device *sdev;
+ 	int err = SCSI_DH_NOSYS;
+ 
+-	sdev = get_sdev_from_queue(q);
++	sdev = scsi_device_from_queue(q);
+ 	if (!sdev) {
+ 		if (fn)
+ 			fn(data, err);
+@@ -368,7 +354,7 @@ int scsi_dh_set_params(struct request_queue *q, const char *params)
+ 	struct scsi_device *sdev;
+ 	int err = -SCSI_DH_NOSYS;
+ 
+-	sdev = get_sdev_from_queue(q);
++	sdev = scsi_device_from_queue(q);
+ 	if (!sdev)
+ 		return err;
+ 
+@@ -391,7 +377,7 @@ int scsi_dh_attach(struct request_queue *q, const char *name)
+ 	struct scsi_device_handler *scsi_dh;
+ 	int err = 0;
+ 
+-	sdev = get_sdev_from_queue(q);
++	sdev = scsi_device_from_queue(q);
+ 	if (!sdev)
+ 		return -ENODEV;
+ 
+@@ -429,7 +415,7 @@ const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
+ 	struct scsi_device *sdev;
+ 	const char *handler_name = NULL;
+ 
+-	sdev = get_sdev_from_queue(q);
++	sdev = scsi_device_from_queue(q);
+ 	if (!sdev)
+ 		return NULL;
+ 
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 8558e3886960..887045ae5d10 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -2215,6 +2215,29 @@ void scsi_mq_destroy_tags(struct Scsi_Host *shost)
+ 	blk_mq_free_tag_set(&shost->tag_set);
+ }
+ 
++/**
++ * scsi_device_from_queue - return sdev associated with a request_queue
++ * @q: The request queue to return the sdev from
++ *
++ * Return the sdev associated with a request queue or NULL if the
++ * request_queue does not reference a SCSI device.
++ */
++struct scsi_device *scsi_device_from_queue(struct request_queue *q)
++{
++	struct scsi_device *sdev = NULL;
++
++	if (q->mq_ops) {
++		if (q->mq_ops == &scsi_mq_ops)
++			sdev = q->queuedata;
++	} else if (q->request_fn == scsi_request_fn)
++		sdev = q->queuedata;
++	if (!sdev || !get_device(&sdev->sdev_gendev))
++		sdev = NULL;
++
++	return sdev;
++}
++EXPORT_SYMBOL_GPL(scsi_device_from_queue);
++
+ /*
+  * Function:    scsi_block_requests()
+  *
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index 6ee50742f6a5..78430ef28ea4 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -1398,11 +1398,15 @@ static int media_not_present(struct scsi_disk *sdkp,
+  **/
+ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
+ {
+-	struct scsi_disk *sdkp = scsi_disk(disk);
+-	struct scsi_device *sdp = sdkp->device;
++	struct scsi_disk *sdkp = scsi_disk_get(disk);
++	struct scsi_device *sdp;
+ 	struct scsi_sense_hdr *sshdr = NULL;
+ 	int retval;
+ 
++	if (!sdkp)
++		return 0;
++
++	sdp = sdkp->device;
+ 	SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n"));
+ 
+ 	/*
+@@ -1459,6 +1463,7 @@ out:
+ 	kfree(sshdr);
+ 	retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0;
+ 	sdp->changed = 0;
++	scsi_disk_put(sdkp);
+ 	return retval;
+ }
+ 
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
+index 0f636cc4c809..cd5c1c060481 100644
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -135,6 +135,8 @@ struct hv_fc_wwn_packet {
+ #define SRB_FLAGS_PORT_DRIVER_RESERVED		0x0F000000
+ #define SRB_FLAGS_CLASS_DRIVER_RESERVED		0xF0000000
+ 
++#define SP_UNTAGGED			((unsigned char) ~0)
++#define SRB_SIMPLE_TAG_REQUEST		0x20
+ 
+ /*
+  * Platform neutral description of a scsi request -
+@@ -354,6 +356,7 @@ enum storvsc_request_type {
+ #define SRB_STATUS_SUCCESS	0x01
+ #define SRB_STATUS_ABORTED	0x02
+ #define SRB_STATUS_ERROR	0x04
++#define SRB_STATUS_DATA_OVERRUN	0x12
+ 
+ #define SRB_STATUS(status) \
+ 	(status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
+@@ -864,6 +867,13 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
+ 	switch (SRB_STATUS(vm_srb->srb_status)) {
+ 	case SRB_STATUS_ERROR:
+ 		/*
++		 * Let upper layer deal with error when
++		 * sense message is present.
++		 */
++
++		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)
++			break;
++		/*
+ 		 * If there is an error; offline the device since all
+ 		 * error recovery strategies would have already been
+ 		 * deployed on the host side. However, if the command
+@@ -927,6 +937,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
+ 	struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
+ 	struct scsi_sense_hdr sense_hdr;
+ 	struct vmscsi_request *vm_srb;
++	u32 data_transfer_length;
+ 	struct Scsi_Host *host;
+ 	struct storvsc_device *stor_dev;
+ 	struct hv_device *dev = host_dev->dev;
+@@ -937,6 +948,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
+ 	host = stor_dev->host;
+ 
+ 	vm_srb = &cmd_request->vstor_packet.vm_srb;
++	data_transfer_length = vm_srb->data_transfer_length;
+ 
+ 	scmnd->result = vm_srb->scsi_status;
+ 
+@@ -947,13 +959,20 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
+ 					     &sense_hdr);
+ 	}
+ 
+-	if (vm_srb->srb_status != SRB_STATUS_SUCCESS)
++	if (vm_srb->srb_status != SRB_STATUS_SUCCESS) {
+ 		storvsc_handle_error(vm_srb, scmnd, host, sense_hdr.asc,
+ 					 sense_hdr.ascq);
++		/*
++		 * The Windows driver set data_transfer_length on
++		 * SRB_STATUS_DATA_OVERRUN. On other errors, this value
++		 * is untouched.  In these cases we set it to 0.
++		 */
++		if (vm_srb->srb_status != SRB_STATUS_DATA_OVERRUN)
++			data_transfer_length = 0;
++	}
+ 
+ 	scsi_set_resid(scmnd,
+-		cmd_request->payload->range.len -
+-		vm_srb->data_transfer_length);
++		cmd_request->payload->range.len - data_transfer_length);
+ 
+ 	scmnd->scsi_done(scmnd);
+ 
+@@ -1409,6 +1428,13 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
+ 	vm_srb->win8_extension.srb_flags |=
+ 		SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
+ 
++	if (scmnd->device->tagged_supported) {
++		vm_srb->win8_extension.srb_flags |=
++		(SRB_FLAGS_QUEUE_ACTION_ENABLE | SRB_FLAGS_NO_QUEUE_FREEZE);
++		vm_srb->win8_extension.queue_tag = SP_UNTAGGED;
++		vm_srb->win8_extension.queue_action = SRB_SIMPLE_TAG_REQUEST;
++	}
++
+ 	/* Build the SRB */
+ 	switch (scmnd->sc_data_direction) {
+ 	case DMA_TO_DEVICE:
+diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c
+index 110b8c0b6cd7..0f2fe34e14c2 100644
+--- a/drivers/staging/rtl8188eu/core/rtw_recv.c
++++ b/drivers/staging/rtl8188eu/core/rtw_recv.c
+@@ -1405,6 +1405,9 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe)
+ 		ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
+ 	}
+ 
++	if (!ptr)
++		return _FAIL;
++
+ 	memcpy(ptr, pattrib->dst, ETH_ALEN);
+ 	memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
+ 
+diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c
+index 4ff530155187..04ac23cc47a8 100644
+--- a/drivers/staging/rtl8712/rtl871x_recv.c
++++ b/drivers/staging/rtl8712/rtl871x_recv.c
+@@ -641,11 +641,16 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe)
+ 		/* append rx status for mp test packets */
+ 		ptr = recvframe_pull(precvframe, (rmv_len -
+ 		      sizeof(struct ethhdr) + 2) - 24);
++		if (!ptr)
++			return _FAIL;
+ 		memcpy(ptr, get_rxmem(precvframe), 24);
+ 		ptr += 24;
+-	} else
++	} else {
+ 		ptr = recvframe_pull(precvframe, (rmv_len -
+ 		      sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
++		if (!ptr)
++			return _FAIL;
++	}
+ 
+ 	memcpy(ptr, pattrib->dst, ETH_ALEN);
+ 	memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
+diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
+index bd810c109277..6ed80b05d674 100644
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -3436,7 +3436,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
+ 
+ 			if ((tpg->tpg_attrib.generate_node_acls == 0) &&
+ 			    (tpg->tpg_attrib.demo_mode_discovery == 0) &&
+-			    (!core_tpg_get_initiator_node_acl(&tpg->tpg_se_tpg,
++			    (!target_tpg_has_node_acl(&tpg->tpg_se_tpg,
+ 				cmd->conn->sess->sess_ops->InitiatorName))) {
+ 				continue;
+ 			}
+diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
+index 5fb9dd7f08bb..028854cda97b 100644
+--- a/drivers/target/target_core_tpg.c
++++ b/drivers/target/target_core_tpg.c
+@@ -75,9 +75,21 @@ struct se_node_acl *core_tpg_get_initiator_node_acl(
+ 	unsigned char *initiatorname)
+ {
+ 	struct se_node_acl *acl;
+-
++	/*
++	 * Obtain se_node_acl->acl_kref using fabric driver provided
++	 * initiatorname[] during node acl endpoint lookup driven by
++	 * new se_session login.
++	 *
++	 * The reference is held until se_session shutdown -> release
++	 * occurs via fabric driver invoked transport_deregister_session()
++	 * or transport_free_session() code.
++	 */
+ 	mutex_lock(&tpg->acl_node_mutex);
+ 	acl = __core_tpg_get_initiator_node_acl(tpg, initiatorname);
++	if (acl) {
++		if (!kref_get_unless_zero(&acl->acl_kref))
++			acl = NULL;
++	}
+ 	mutex_unlock(&tpg->acl_node_mutex);
+ 
+ 	return acl;
+@@ -232,6 +244,25 @@ static void target_add_node_acl(struct se_node_acl *acl)
+ 		acl->initiatorname);
+ }
+ 
++bool target_tpg_has_node_acl(struct se_portal_group *tpg,
++			     const char *initiatorname)
++{
++	struct se_node_acl *acl;
++	bool found = false;
++
++	mutex_lock(&tpg->acl_node_mutex);
++	list_for_each_entry(acl, &tpg->acl_node_list, acl_list) {
++		if (!strcmp(acl->initiatorname, initiatorname)) {
++			found = true;
++			break;
++		}
++	}
++	mutex_unlock(&tpg->acl_node_mutex);
++
++	return found;
++}
++EXPORT_SYMBOL(target_tpg_has_node_acl);
++
+ struct se_node_acl *core_tpg_check_initiator_node_acl(
+ 	struct se_portal_group *tpg,
+ 	unsigned char *initiatorname)
+@@ -248,6 +279,15 @@ struct se_node_acl *core_tpg_check_initiator_node_acl(
+ 	acl = target_alloc_node_acl(tpg, initiatorname);
+ 	if (!acl)
+ 		return NULL;
++	/*
++	 * When allocating a dynamically generated node_acl, go ahead
++	 * and take the extra kref now before returning to the fabric
++	 * driver caller.
++	 *
++	 * Note this reference will be released at session shutdown
++	 * time within transport_free_session() code.
++	 */
++	kref_get(&acl->acl_kref);
+ 	acl->dynamic_node_acl = 1;
+ 
+ 	/*
+diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
+index aa517c4fadb9..befe22744802 100644
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -341,7 +341,6 @@ void __transport_register_session(
+ 					&buf[0], PR_REG_ISID_LEN);
+ 			se_sess->sess_bin_isid = get_unaligned_be64(&buf[0]);
+ 		}
+-		kref_get(&se_nacl->acl_kref);
+ 
+ 		spin_lock_irq(&se_nacl->nacl_sess_lock);
+ 		/*
+@@ -424,14 +423,27 @@ static void target_complete_nacl(struct kref *kref)
+ {
+ 	struct se_node_acl *nacl = container_of(kref,
+ 				struct se_node_acl, acl_kref);
++	struct se_portal_group *se_tpg = nacl->se_tpg;
+ 
+-	complete(&nacl->acl_free_comp);
++	if (!nacl->dynamic_stop) {
++		complete(&nacl->acl_free_comp);
++		return;
++	}
++
++	mutex_lock(&se_tpg->acl_node_mutex);
++	list_del(&nacl->acl_list);
++	mutex_unlock(&se_tpg->acl_node_mutex);
++
++	core_tpg_wait_for_nacl_pr_ref(nacl);
++	core_free_device_list_for_node(nacl, se_tpg);
++	kfree(nacl);
+ }
+ 
+ void target_put_nacl(struct se_node_acl *nacl)
+ {
+ 	kref_put(&nacl->acl_kref, target_complete_nacl);
+ }
++EXPORT_SYMBOL(target_put_nacl);
+ 
+ void transport_deregister_session_configfs(struct se_session *se_sess)
+ {
+@@ -464,6 +476,42 @@ EXPORT_SYMBOL(transport_deregister_session_configfs);
+ 
+ void transport_free_session(struct se_session *se_sess)
+ {
++	struct se_node_acl *se_nacl = se_sess->se_node_acl;
++
++	/*
++	 * Drop the se_node_acl->nacl_kref obtained from within
++	 * core_tpg_get_initiator_node_acl().
++	 */
++	if (se_nacl) {
++		struct se_portal_group *se_tpg = se_nacl->se_tpg;
++		const struct target_core_fabric_ops *se_tfo = se_tpg->se_tpg_tfo;
++		unsigned long flags;
++
++		se_sess->se_node_acl = NULL;
++
++		/*
++		 * Also determine if we need to drop the extra ->cmd_kref if
++		 * it had been previously dynamically generated, and
++		 * the endpoint is not caching dynamic ACLs.
++		 */
++		mutex_lock(&se_tpg->acl_node_mutex);
++		if (se_nacl->dynamic_node_acl &&
++		    !se_tfo->tpg_check_demo_mode_cache(se_tpg)) {
++			spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags);
++			if (list_empty(&se_nacl->acl_sess_list))
++				se_nacl->dynamic_stop = true;
++			spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags);
++
++			if (se_nacl->dynamic_stop)
++				list_del(&se_nacl->acl_list);
++		}
++		mutex_unlock(&se_tpg->acl_node_mutex);
++
++		if (se_nacl->dynamic_stop)
++			target_put_nacl(se_nacl);
++
++		target_put_nacl(se_nacl);
++	}
+ 	if (se_sess->sess_cmd_map) {
+ 		percpu_ida_destroy(&se_sess->sess_tag_pool);
+ 		kvfree(se_sess->sess_cmd_map);
+@@ -475,16 +523,12 @@ EXPORT_SYMBOL(transport_free_session);
+ void transport_deregister_session(struct se_session *se_sess)
+ {
+ 	struct se_portal_group *se_tpg = se_sess->se_tpg;
+-	const struct target_core_fabric_ops *se_tfo;
+-	struct se_node_acl *se_nacl;
+ 	unsigned long flags;
+-	bool comp_nacl = true, drop_nacl = false;
+ 
+ 	if (!se_tpg) {
+ 		transport_free_session(se_sess);
+ 		return;
+ 	}
+-	se_tfo = se_tpg->se_tpg_tfo;
+ 
+ 	spin_lock_irqsave(&se_tpg->session_lock, flags);
+ 	list_del(&se_sess->sess_list);
+@@ -492,37 +536,16 @@ void transport_deregister_session(struct se_session *se_sess)
+ 	se_sess->fabric_sess_ptr = NULL;
+ 	spin_unlock_irqrestore(&se_tpg->session_lock, flags);
+ 
+-	/*
+-	 * Determine if we need to do extra work for this initiator node's
+-	 * struct se_node_acl if it had been previously dynamically generated.
+-	 */
+-	se_nacl = se_sess->se_node_acl;
+-
+-	mutex_lock(&se_tpg->acl_node_mutex);
+-	if (se_nacl && se_nacl->dynamic_node_acl) {
+-		if (!se_tfo->tpg_check_demo_mode_cache(se_tpg)) {
+-			list_del(&se_nacl->acl_list);
+-			se_tpg->num_node_acls--;
+-			drop_nacl = true;
+-		}
+-	}
+-	mutex_unlock(&se_tpg->acl_node_mutex);
+-
+-	if (drop_nacl) {
+-		core_tpg_wait_for_nacl_pr_ref(se_nacl);
+-		core_free_device_list_for_node(se_nacl, se_tpg);
+-		kfree(se_nacl);
+-		comp_nacl = false;
+-	}
+ 	pr_debug("TARGET_CORE[%s]: Deregistered fabric_sess\n",
+ 		se_tpg->se_tpg_tfo->get_fabric_name());
+ 	/*
+ 	 * If last kref is dropping now for an explicit NodeACL, awake sleeping
+ 	 * ->acl_free_comp caller to wakeup configfs se_node_acl->acl_group
+-	 * removal context.
++	 * removal context from within transport_free_session() code.
++	 *
++	 * For dynamic ACL, target_put_nacl() uses target_complete_nacl()
++	 * to release all remaining generate_node_acl=1 created ACL resources.
+ 	 */
+-	if (se_nacl && comp_nacl)
+-		target_put_nacl(se_nacl);
+ 
+ 	transport_free_session(se_sess);
+ }
+diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c
+index aab5221d6c2e..aac0ce8aeb0b 100644
+--- a/drivers/usb/gadget/udc/fsl_udc_core.c
++++ b/drivers/usb/gadget/udc/fsl_udc_core.c
+@@ -1249,6 +1249,12 @@ static const struct usb_gadget_ops fsl_gadget_ops = {
+ 	.udc_stop = fsl_udc_stop,
+ };
+ 
++/*
++ * Empty complete function used by this driver to fill in the req->complete
++ * field when creating a request since the complete field is mandatory.
++ */
++static void fsl_noop_complete(struct usb_ep *ep, struct usb_request *req) { }
++
+ /* Set protocol stall on ep0, protocol stall will automatically be cleared
+    on new transaction */
+ static void ep0stall(struct fsl_udc *udc)
+@@ -1283,7 +1289,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
+ 	req->req.length = 0;
+ 	req->req.status = -EINPROGRESS;
+ 	req->req.actual = 0;
+-	req->req.complete = NULL;
++	req->req.complete = fsl_noop_complete;
+ 	req->dtd_count = 0;
+ 
+ 	ret = usb_gadget_map_request(&ep->udc->gadget, &req->req, ep_is_in(ep));
+@@ -1366,7 +1372,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
+ 	req->req.length = 2;
+ 	req->req.status = -EINPROGRESS;
+ 	req->req.actual = 0;
+-	req->req.complete = NULL;
++	req->req.complete = fsl_noop_complete;
+ 	req->dtd_count = 0;
+ 
+ 	ret = usb_gadget_map_request(&ep->udc->gadget, &req->req, ep_is_in(ep));
+diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
+index 4fe7c9b56bc0..19cb32a65161 100644
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -162,9 +162,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
+ 			(pdata && pdata->usb3_lpm_capable))
+ 		xhci->quirks |= XHCI_LPM_SUPPORT;
+ 
+-	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
+-		xhci->shared_hcd->can_do_streams = 1;
+-
+ 	hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
+ 	if (IS_ERR(hcd->usb_phy)) {
+ 		ret = PTR_ERR(hcd->usb_phy);
+@@ -181,6 +178,9 @@ static int xhci_plat_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		goto disable_usb_phy;
+ 
++	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
++		xhci->shared_hcd->can_do_streams = 1;
++
+ 	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
+ 	if (ret)
+ 		goto dealloc_usb2_hcd;
+diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
+index b03d3b867fca..9a9c82a4d35d 100644
+--- a/drivers/usb/musb/da8xx.c
++++ b/drivers/usb/musb/da8xx.c
+@@ -458,15 +458,11 @@ static int da8xx_musb_exit(struct musb *musb)
+ }
+ 
+ static const struct musb_platform_ops da8xx_ops = {
+-	.quirks		= MUSB_DMA_CPPI | MUSB_INDEXED_EP,
++	.quirks		= MUSB_INDEXED_EP,
+ 	.init		= da8xx_musb_init,
+ 	.exit		= da8xx_musb_exit,
+ 
+ 	.fifo_mode	= 2,
+-#ifdef CONFIG_USB_TI_CPPI_DMA
+-	.dma_init	= cppi_dma_controller_create,
+-	.dma_exit	= cppi_dma_controller_destroy,
+-#endif
+ 	.enable		= da8xx_musb_enable,
+ 	.disable	= da8xx_musb_disable,
+ 
+diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c
+index 049a884a756f..59d74d1b47a8 100644
+--- a/drivers/w1/masters/ds2490.c
++++ b/drivers/w1/masters/ds2490.c
+@@ -153,6 +153,9 @@ struct ds_device
+ 	 */
+ 	u16			spu_bit;
+ 
++	u8			st_buf[ST_SIZE];
++	u8			byte_buf;
++
+ 	struct w1_bus_master	master;
+ };
+ 
+@@ -174,7 +177,6 @@ struct ds_status
+ 	u8			data_in_buffer_status;
+ 	u8			reserved1;
+ 	u8			reserved2;
+-
+ };
+ 
+ static struct usb_device_id ds_id_table [] = {
+@@ -244,28 +246,6 @@ static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
+ 	return err;
+ }
+ 
+-static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
+-				 unsigned char *buf, int size)
+-{
+-	int count, err;
+-
+-	memset(st, 0, sizeof(*st));
+-
+-	count = 0;
+-	err = usb_interrupt_msg(dev->udev, usb_rcvintpipe(dev->udev,
+-		dev->ep[EP_STATUS]), buf, size, &count, 1000);
+-	if (err < 0) {
+-		pr_err("Failed to read 1-wire data from 0x%x: err=%d.\n",
+-		       dev->ep[EP_STATUS], err);
+-		return err;
+-	}
+-
+-	if (count >= sizeof(*st))
+-		memcpy(st, buf, sizeof(*st));
+-
+-	return count;
+-}
+-
+ static inline void ds_print_msg(unsigned char *buf, unsigned char *str, int off)
+ {
+ 	pr_info("%45s: %8x\n", str, buf[off]);
+@@ -324,6 +304,35 @@ static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count)
+ 	}
+ }
+ 
++static int ds_recv_status(struct ds_device *dev, struct ds_status *st,
++			  bool dump)
++{
++	int count, err;
++
++	if (st)
++		memset(st, 0, sizeof(*st));
++
++	count = 0;
++	err = usb_interrupt_msg(dev->udev,
++				usb_rcvintpipe(dev->udev,
++					       dev->ep[EP_STATUS]),
++				dev->st_buf, sizeof(dev->st_buf),
++				&count, 1000);
++	if (err < 0) {
++		pr_err("Failed to read 1-wire data from 0x%x: err=%d.\n",
++		       dev->ep[EP_STATUS], err);
++		return err;
++	}
++
++	if (dump)
++		ds_dump_status(dev, dev->st_buf, count);
++
++	if (st && count >= sizeof(*st))
++		memcpy(st, dev->st_buf, sizeof(*st));
++
++	return count;
++}
++
+ static void ds_reset_device(struct ds_device *dev)
+ {
+ 	ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
+@@ -344,7 +353,6 @@ static void ds_reset_device(struct ds_device *dev)
+ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
+ {
+ 	int count, err;
+-	struct ds_status st;
+ 
+ 	/* Careful on size.  If size is less than what is available in
+ 	 * the input buffer, the device fails the bulk transfer and
+@@ -359,14 +367,9 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
+ 	err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
+ 				buf, size, &count, 1000);
+ 	if (err < 0) {
+-		u8 buf[ST_SIZE];
+-		int count;
+-
+ 		pr_info("Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
+ 		usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));
+-
+-		count = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));
+-		ds_dump_status(dev, buf, count);
++		ds_recv_status(dev, NULL, true);
+ 		return err;
+ 	}
+ 
+@@ -404,7 +407,6 @@ int ds_stop_pulse(struct ds_device *dev, int limit)
+ {
+ 	struct ds_status st;
+ 	int count = 0, err = 0;
+-	u8 buf[ST_SIZE];
+ 
+ 	do {
+ 		err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0);
+@@ -413,7 +415,7 @@ int ds_stop_pulse(struct ds_device *dev, int limit)
+ 		err = ds_send_control(dev, CTL_RESUME_EXE, 0);
+ 		if (err)
+ 			break;
+-		err = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));
++		err = ds_recv_status(dev, &st, false);
+ 		if (err)
+ 			break;
+ 
+@@ -456,18 +458,17 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
+ 
+ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
+ {
+-	u8 buf[ST_SIZE];
+ 	int err, count = 0;
+ 
+ 	do {
+ 		st->status = 0;
+-		err = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
++		err = ds_recv_status(dev, st, false);
+ #if 0
+ 		if (err >= 0) {
+ 			int i;
+ 			printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err);
+ 			for (i=0; i<err; ++i)
+-				printk("%02x ", buf[i]);
++				printk("%02x ", dev->st_buf[i]);
+ 			printk("\n");
+ 		}
+ #endif
+@@ -485,7 +486,7 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
+ 	 * can do something with it).
+ 	 */
+ 	if (err > 16 || count >= 100 || err < 0)
+-		ds_dump_status(dev, buf, err);
++		ds_dump_status(dev, dev->st_buf, err);
+ 
+ 	/* Extended data isn't an error.  Well, a short is, but the dump
+ 	 * would have already told the user that and we can't do anything
+@@ -608,7 +609,6 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
+ {
+ 	int err;
+ 	struct ds_status st;
+-	u8 rbyte;
+ 
+ 	err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | dev->spu_bit, byte);
+ 	if (err)
+@@ -621,11 +621,11 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
+ 	if (err)
+ 		return err;
+ 
+-	err = ds_recv_data(dev, &rbyte, sizeof(rbyte));
++	err = ds_recv_data(dev, &dev->byte_buf, 1);
+ 	if (err < 0)
+ 		return err;
+ 
+-	return !(byte == rbyte);
++	return !(byte == dev->byte_buf);
+ }
+ 
+ static int ds_read_byte(struct ds_device *dev, u8 *byte)
+@@ -712,7 +712,6 @@ static void ds9490r_search(void *data, struct w1_master *master,
+ 	int err;
+ 	u16 value, index;
+ 	struct ds_status st;
+-	u8 st_buf[ST_SIZE];
+ 	int search_limit;
+ 	int found = 0;
+ 	int i;
+@@ -724,7 +723,12 @@ static void ds9490r_search(void *data, struct w1_master *master,
+ 	/* FIFO 128 bytes, bulk packet size 64, read a multiple of the
+ 	 * packet size.
+ 	 */
+-	u64 buf[2*64/8];
++	const size_t bufsize = 2 * 64;
++	u64 *buf;
++
++	buf = kmalloc(bufsize, GFP_KERNEL);
++	if (!buf)
++		return;
+ 
+ 	mutex_lock(&master->bus_mutex);
+ 
+@@ -745,10 +749,9 @@ static void ds9490r_search(void *data, struct w1_master *master,
+ 	do {
+ 		schedule_timeout(jtime);
+ 
+-		if (ds_recv_status_nodump(dev, &st, st_buf, sizeof(st_buf)) <
+-			sizeof(st)) {
++		err = ds_recv_status(dev, &st, false);
++		if (err < 0 || err < sizeof(st))
+ 			break;
+-		}
+ 
+ 		if (st.data_in_buffer_status) {
+ 			/* Bulk in can receive partial ids, but when it does
+@@ -758,7 +761,7 @@ static void ds9490r_search(void *data, struct w1_master *master,
+ 			 * bulk without first checking if status says there
+ 			 * is data to read.
+ 			 */
+-			err = ds_recv_data(dev, (u8 *)buf, sizeof(buf));
++			err = ds_recv_data(dev, (u8 *)buf, bufsize);
+ 			if (err < 0)
+ 				break;
+ 			for (i = 0; i < err/8; ++i) {
+@@ -794,9 +797,14 @@ static void ds9490r_search(void *data, struct w1_master *master,
+ 	}
+ search_out:
+ 	mutex_unlock(&master->bus_mutex);
++	kfree(buf);
+ }
+ 
+ #if 0
++/*
++ * FIXME: if this disabled code is ever used in the future all ds_send_data()
++ * calls must be changed to use a DMAable buffer.
++ */
+ static int ds_match_access(struct ds_device *dev, u64 init)
+ {
+ 	int err;
+@@ -845,13 +853,12 @@ static int ds_set_path(struct ds_device *dev, u64 init)
+ 
+ static u8 ds9490r_touch_bit(void *data, u8 bit)
+ {
+-	u8 ret;
+ 	struct ds_device *dev = data;
+ 
+-	if (ds_touch_bit(dev, bit, &ret))
++	if (ds_touch_bit(dev, bit, &dev->byte_buf))
+ 		return 0;
+ 
+-	return ret;
++	return dev->byte_buf;
+ }
+ 
+ #if 0
+@@ -866,13 +873,12 @@ static u8 ds9490r_read_bit(void *data)
+ {
+ 	struct ds_device *dev = data;
+ 	int err;
+-	u8 bit = 0;
+ 
+-	err = ds_touch_bit(dev, 1, &bit);
++	err = ds_touch_bit(dev, 1, &dev->byte_buf);
+ 	if (err)
+ 		return 0;
+ 
+-	return bit & 1;
++	return dev->byte_buf & 1;
+ }
+ #endif
+ 
+@@ -887,32 +893,52 @@ static u8 ds9490r_read_byte(void *data)
+ {
+ 	struct ds_device *dev = data;
+ 	int err;
+-	u8 byte = 0;
+ 
+-	err = ds_read_byte(dev, &byte);
++	err = ds_read_byte(dev, &dev->byte_buf);
+ 	if (err)
+ 		return 0;
+ 
+-	return byte;
++	return dev->byte_buf;
+ }
+ 
+ static void ds9490r_write_block(void *data, const u8 *buf, int len)
+ {
+ 	struct ds_device *dev = data;
++	u8 *tbuf;
++
++	if (len <= 0)
++		return;
++
++	tbuf = kmalloc(len, GFP_KERNEL);
++	if (!tbuf)
++		return;
+ 
+-	ds_write_block(dev, (u8 *)buf, len);
++	memcpy(tbuf, buf, len);
++	ds_write_block(dev, tbuf, len);
++
++	kfree(tbuf);
+ }
+ 
+ static u8 ds9490r_read_block(void *data, u8 *buf, int len)
+ {
+ 	struct ds_device *dev = data;
+ 	int err;
++	u8 *tbuf;
+ 
+-	err = ds_read_block(dev, buf, len);
+-	if (err < 0)
++	if (len <= 0)
++		return 0;
++
++	tbuf = kmalloc(len, GFP_KERNEL);
++	if (!tbuf)
+ 		return 0;
+ 
+-	return len;
++	err = ds_read_block(dev, tbuf, len);
++	if (err >= 0)
++		memcpy(buf, tbuf, len);
++
++	kfree(tbuf);
++
++	return err >= 0 ? len : 0;
+ }
+ 
+ static u8 ds9490r_reset(void *data)
+diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
+index c9a7ff67d395..39886edfa222 100644
+--- a/drivers/w1/w1.c
++++ b/drivers/w1/w1.c
+@@ -763,6 +763,7 @@ int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
+ 		dev_err(&dev->dev, "%s: Attaching %s failed.\n", __func__,
+ 			 sl->name);
+ 		w1_family_put(sl->family);
++		atomic_dec(&sl->master->refcnt);
+ 		kfree(sl);
+ 		return err;
+ 	}
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 9da42ace762a..8a456f9b8a44 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5362,7 +5362,8 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+ 	ext4_lblk_t stop, *iterator, ex_start, ex_end;
+ 
+ 	/* Let path point to the last extent */
+-	path = ext4_find_extent(inode, EXT_MAX_BLOCKS - 1, NULL, 0);
++	path = ext4_find_extent(inode, EXT_MAX_BLOCKS - 1, NULL,
++				EXT4_EX_NOCACHE);
+ 	if (IS_ERR(path))
+ 		return PTR_ERR(path);
+ 
+@@ -5371,15 +5372,15 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+ 	if (!extent)
+ 		goto out;
+ 
+-	stop = le32_to_cpu(extent->ee_block) +
+-			ext4_ext_get_actual_len(extent);
++	stop = le32_to_cpu(extent->ee_block);
+ 
+        /*
+ 	 * In case of left shift, Don't start shifting extents until we make
+ 	 * sure the hole is big enough to accommodate the shift.
+ 	*/
+ 	if (SHIFT == SHIFT_LEFT) {
+-		path = ext4_find_extent(inode, start - 1, &path, 0);
++		path = ext4_find_extent(inode, start - 1, &path,
++					EXT4_EX_NOCACHE);
+ 		if (IS_ERR(path))
+ 			return PTR_ERR(path);
+ 		depth = path->p_depth;
+@@ -5411,9 +5412,14 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+ 	else
+ 		iterator = &stop;
+ 
+-	/* Its safe to start updating extents */
+-	while (start < stop) {
+-		path = ext4_find_extent(inode, *iterator, &path, 0);
++	/*
++	 * Its safe to start updating extents.  Start and stop are unsigned, so
++	 * in case of right shift if extent with 0 block is reached, iterator
++	 * becomes NULL to indicate the end of the loop.
++	 */
++	while (iterator && start <= stop) {
++		path = ext4_find_extent(inode, *iterator, &path,
++					EXT4_EX_NOCACHE);
+ 		if (IS_ERR(path))
+ 			return PTR_ERR(path);
+ 		depth = path->p_depth;
+@@ -5440,8 +5446,11 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+ 					ext4_ext_get_actual_len(extent);
+ 		} else {
+ 			extent = EXT_FIRST_EXTENT(path[depth].p_hdr);
+-			*iterator =  le32_to_cpu(extent->ee_block) > 0 ?
+-				le32_to_cpu(extent->ee_block) - 1 : 0;
++			if (le32_to_cpu(extent->ee_block) > 0)
++				*iterator = le32_to_cpu(extent->ee_block) - 1;
++			else
++				/* Beginning is reached, end of the loop */
++				iterator = NULL;
+ 			/* Update path extent in case we need to stop */
+ 			while (le32_to_cpu(extent->ee_block) < start)
+ 				extent++;
+diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
+index 8968a93e2150..d4be4e23bc21 100644
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -933,8 +933,15 @@ int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
+ 				  struct page *page)
+ {
+ 	int i_size_changed = 0;
++	int ret;
+ 
+-	copied = ext4_write_inline_data_end(inode, pos, len, copied, page);
++	ret = ext4_write_inline_data_end(inode, pos, len, copied, page);
++	if (ret < 0) {
++		unlock_page(page);
++		put_page(page);
++		return ret;
++	}
++	copied = ret;
+ 
+ 	/*
+ 	 * No need to use i_size_read() here, the i_size
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 10690e5ba2eb..e0f862146793 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1165,8 +1165,11 @@ static int ext4_write_end(struct file *file,
+ 	if (ext4_has_inline_data(inode)) {
+ 		ret = ext4_write_inline_data_end(inode, pos, len,
+ 						 copied, page);
+-		if (ret < 0)
++		if (ret < 0) {
++			unlock_page(page);
++			put_page(page);
+ 			goto errout;
++		}
+ 		copied = ret;
+ 	} else
+ 		copied = block_write_end(file, mapping, pos,
+@@ -1220,7 +1223,9 @@ errout:
+  * set the buffer to be dirty, since in data=journalled mode we need
+  * to call ext4_handle_dirty_metadata() instead.
+  */
+-static void zero_new_buffers(struct page *page, unsigned from, unsigned to)
++static void ext4_journalled_zero_new_buffers(handle_t *handle,
++					    struct page *page,
++					    unsigned from, unsigned to)
+ {
+ 	unsigned int block_start = 0, block_end;
+ 	struct buffer_head *head, *bh;
+@@ -1237,7 +1242,7 @@ static void zero_new_buffers(struct page *page, unsigned from, unsigned to)
+ 					size = min(to, block_end) - start;
+ 
+ 					zero_user(page, start, size);
+-					set_buffer_uptodate(bh);
++					write_end_fn(handle, bh);
+ 				}
+ 				clear_buffer_new(bh);
+ 			}
+@@ -1266,18 +1271,25 @@ static int ext4_journalled_write_end(struct file *file,
+ 
+ 	BUG_ON(!ext4_handle_valid(handle));
+ 
+-	if (ext4_has_inline_data(inode))
+-		copied = ext4_write_inline_data_end(inode, pos, len,
+-						    copied, page);
+-	else {
+-		if (copied < len) {
+-			if (!PageUptodate(page))
+-				copied = 0;
+-			zero_new_buffers(page, from+copied, to);
++	if (ext4_has_inline_data(inode)) {
++		ret = ext4_write_inline_data_end(inode, pos, len,
++						 copied, page);
++		if (ret < 0) {
++			unlock_page(page);
++			put_page(page);
++			goto errout;
+ 		}
+-
++		copied = ret;
++	} else if (unlikely(copied < len) && !PageUptodate(page)) {
++		copied = 0;
++		ext4_journalled_zero_new_buffers(handle, page, from, to);
++	} else {
++		if (unlikely(copied < len))
++			ext4_journalled_zero_new_buffers(handle, page,
++							 from + copied, to);
+ 		ret = ext4_walk_page_buffers(handle, page_buffers(page), from,
+-					     to, &partial, write_end_fn);
++					     from + copied, &partial,
++					     write_end_fn);
+ 		if (!partial)
+ 			SetPageUptodate(page);
+ 	}
+@@ -1303,6 +1315,7 @@ static int ext4_journalled_write_end(struct file *file,
+ 		 */
+ 		ext4_orphan_add(handle, inode);
+ 
++errout:
+ 	ret2 = ext4_journal_stop(handle);
+ 	if (!ret)
+ 		ret = ret2;
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index b7a3957a9dca..84cd77663e1f 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -3120,6 +3120,13 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
+ 	if (ar->pright && start + size - 1 >= ar->lright)
+ 		size -= start + size - ar->lright;
+ 
++	/*
++	 * Trim allocation request for filesystems with artificially small
++	 * groups.
++	 */
++	if (size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb))
++		size = EXT4_BLOCKS_PER_GROUP(ac->ac_sb);
++
+ 	end = start + size;
+ 
+ 	/* check we don't cross already preallocated blocks */
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index b405a7b74ce0..6fe8e30eeb99 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -793,6 +793,7 @@ static void ext4_put_super(struct super_block *sb)
+ {
+ 	struct ext4_sb_info *sbi = EXT4_SB(sb);
+ 	struct ext4_super_block *es = sbi->s_es;
++	int aborted = 0;
+ 	int i, err;
+ 
+ 	ext4_unregister_li_request(sb);
+@@ -802,9 +803,10 @@ static void ext4_put_super(struct super_block *sb)
+ 	destroy_workqueue(sbi->rsv_conversion_wq);
+ 
+ 	if (sbi->s_journal) {
++		aborted = is_journal_aborted(sbi->s_journal);
+ 		err = jbd2_journal_destroy(sbi->s_journal);
+ 		sbi->s_journal = NULL;
+-		if (err < 0)
++		if ((err < 0) && !aborted)
+ 			ext4_abort(sb, "Couldn't clean up the journal");
+ 	}
+ 
+@@ -816,7 +818,7 @@ static void ext4_put_super(struct super_block *sb)
+ 	ext4_ext_release(sb);
+ 	ext4_xattr_put_super(sb);
+ 
+-	if (!(sb->s_flags & MS_RDONLY)) {
++	if (!(sb->s_flags & MS_RDONLY) && !aborted) {
+ 		ext4_clear_feature_journal_needs_recovery(sb);
+ 		es->s_state = cpu_to_le16(sbi->s_mount_state);
+ 	}
+@@ -3746,7 +3748,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 	 * root first: it may be modified in the journal!
+ 	 */
+ 	if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) {
+-		if (ext4_load_journal(sb, es, journal_devnum))
++		err = ext4_load_journal(sb, es, journal_devnum);
++		if (err)
+ 			goto failed_mount3a;
+ 	} else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
+ 		   ext4_has_feature_journal_needs_recovery(sb)) {
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 8821c380a71a..11538a8be9f0 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -100,6 +100,7 @@ static void fuse_file_put(struct fuse_file *ff, bool sync)
+ 			iput(req->misc.release.inode);
+ 			fuse_put_request(ff->fc, req);
+ 		} else if (sync) {
++			__set_bit(FR_FORCE, &req->flags);
+ 			__clear_bit(FR_BACKGROUND, &req->flags);
+ 			fuse_request_send(ff->fc, req);
+ 			iput(req->misc.release.inode);
+diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
+index 32e74710b1aa..9cd8c92b953d 100644
+--- a/fs/gfs2/glock.c
++++ b/fs/gfs2/glock.c
+@@ -651,9 +651,11 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
+ 	struct kmem_cache *cachep;
+ 	int ret, tries = 0;
+ 
++	rcu_read_lock();
+ 	gl = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms);
+ 	if (gl && !lockref_get_not_dead(&gl->gl_lockref))
+ 		gl = NULL;
++	rcu_read_unlock();
+ 
+ 	*glp = gl;
+ 	if (gl)
+@@ -721,15 +723,18 @@ again:
+ 
+ 	if (ret == -EEXIST) {
+ 		ret = 0;
++		rcu_read_lock();
+ 		tmp = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms);
+ 		if (tmp == NULL || !lockref_get_not_dead(&tmp->gl_lockref)) {
+ 			if (++tries < 100) {
++				rcu_read_unlock();
+ 				cond_resched();
+ 				goto again;
+ 			}
+ 			tmp = NULL;
+ 			ret = -ENOMEM;
+ 		}
++		rcu_read_unlock();
+ 	} else {
+ 		WARN_ON_ONCE(ret);
+ 	}
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index fa1b8e0dcacf..a2e724053919 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1876,7 +1876,9 @@ static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
+ 
+ 	__blist_del_buffer(list, jh);
+ 	jh->b_jlist = BJ_None;
+-	if (test_clear_buffer_jbddirty(bh))
++	if (transaction && is_journal_aborted(transaction->t_journal))
++		clear_buffer_jbddirty(bh);
++	else if (test_clear_buffer_jbddirty(bh))
+ 		mark_buffer_dirty(bh);	/* Expose it to the VM */
+ }
+ 
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 9a524e763c3e..4e3679b25b9b 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -2452,6 +2452,7 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
+ 	ret = PTR_ERR(state);
+ 	if (IS_ERR(state))
+ 		goto out;
++	ctx->state = state;
+ 	if (server->caps & NFS_CAP_POSIX_LOCK)
+ 		set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
+ 
+@@ -2474,7 +2475,6 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
+ 	if (ret != 0)
+ 		goto out;
+ 
+-	ctx->state = state;
+ 	if (d_inode(dentry) == state->inode) {
+ 		nfs_inode_attach_open_context(ctx);
+ 		if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
+@@ -4711,7 +4711,7 @@ out:
+  */
+ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
+ {
+-	struct page *pages[NFS4ACL_MAXPAGES] = {NULL, };
++	struct page *pages[NFS4ACL_MAXPAGES + 1] = {NULL, };
+ 	struct nfs_getaclargs args = {
+ 		.fh = NFS_FH(inode),
+ 		.acl_pages = pages,
+@@ -4725,13 +4725,9 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
+ 		.rpc_argp = &args,
+ 		.rpc_resp = &res,
+ 	};
+-	unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE);
++	unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1;
+ 	int ret = -ENOMEM, i;
+ 
+-	/* As long as we're doing a round trip to the server anyway,
+-	 * let's be prepared for a page of acl data. */
+-	if (npages == 0)
+-		npages = 1;
+ 	if (npages > ARRAY_SIZE(pages))
+ 		return -ERANGE;
+ 
+diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
+index 4e4441216804..1cb50bb898b0 100644
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -2487,7 +2487,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
+ 	encode_compound_hdr(xdr, req, &hdr);
+ 	encode_sequence(xdr, &args->seq_args, &hdr);
+ 	encode_putfh(xdr, args->fh, &hdr);
+-	replen = hdr.replen + op_decode_hdr_maxsz + 1;
++	replen = hdr.replen + op_decode_hdr_maxsz;
+ 	encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr);
+ 
+ 	xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index 994d66fbb446..91e0c5429b4d 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -369,7 +369,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
+ 	__be32		err;
+ 	int		host_err;
+ 	bool		get_write_count;
+-	int		size_change = 0;
++	bool		size_change = (iap->ia_valid & ATTR_SIZE);
+ 
+ 	if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
+ 		accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE;
+@@ -382,11 +382,11 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
+ 	/* Get inode */
+ 	err = fh_verify(rqstp, fhp, ftype, accmode);
+ 	if (err)
+-		goto out;
++		return err;
+ 	if (get_write_count) {
+ 		host_err = fh_want_write(fhp);
+ 		if (host_err)
+-			return nfserrno(host_err);
++			goto out;
+ 	}
+ 
+ 	dentry = fhp->fh_dentry;
+@@ -397,20 +397,28 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
+ 		iap->ia_valid &= ~ATTR_MODE;
+ 
+ 	if (!iap->ia_valid)
+-		goto out;
++		return 0;
+ 
+ 	nfsd_sanitize_attrs(inode, iap);
+ 
++	if (check_guard && guardtime != inode->i_ctime.tv_sec)
++		return nfserr_notsync;
++
+ 	/*
+ 	 * The size case is special, it changes the file in addition to the
+-	 * attributes.
++	 * attributes, and file systems don't expect it to be mixed with
++	 * "random" attribute changes.  We thus split out the size change
++	 * into a separate call to ->setattr, and do the rest as a separate
++	 * setattr call.
+ 	 */
+-	if (iap->ia_valid & ATTR_SIZE) {
++	if (size_change) {
+ 		err = nfsd_get_write_access(rqstp, fhp, iap);
+ 		if (err)
+-			goto out;
+-		size_change = 1;
++			return err;
++	}
+ 
++	fh_lock(fhp);
++	if (size_change) {
+ 		/*
+ 		 * RFC5661, Section 18.30.4:
+ 		 *   Changing the size of a file with SETATTR indirectly
+@@ -418,29 +426,36 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
+ 		 *
+ 		 * (and similar for the older RFCs)
+ 		 */
+-		if (iap->ia_size != i_size_read(inode))
+-			iap->ia_valid |= ATTR_MTIME;
+-	}
++		struct iattr size_attr = {
++			.ia_valid	= ATTR_SIZE | ATTR_CTIME | ATTR_MTIME,
++			.ia_size	= iap->ia_size,
++		};
+ 
+-	iap->ia_valid |= ATTR_CTIME;
++		host_err = notify_change(dentry, &size_attr, NULL);
++		if (host_err)
++			goto out_unlock;
++		iap->ia_valid &= ~ATTR_SIZE;
+ 
+-	if (check_guard && guardtime != inode->i_ctime.tv_sec) {
+-		err = nfserr_notsync;
+-		goto out_put_write_access;
++		/*
++		 * Avoid the additional setattr call below if the only other
++		 * attribute that the client sends is the mtime, as we update
++		 * it as part of the size change above.
++		 */
++		if ((iap->ia_valid & ~ATTR_MTIME) == 0)
++			goto out_unlock;
+ 	}
+ 
+-	fh_lock(fhp);
++	iap->ia_valid |= ATTR_CTIME;
+ 	host_err = notify_change(dentry, iap, NULL);
+-	fh_unlock(fhp);
+-	err = nfserrno(host_err);
+ 
+-out_put_write_access:
++out_unlock:
++	fh_unlock(fhp);
+ 	if (size_change)
+ 		put_write_access(inode);
+-	if (!err)
+-		err = nfserrno(commit_metadata(fhp));
+ out:
+-	return err;
++	if (!host_err)
++		host_err = commit_metadata(fhp);
++	return nfserrno(host_err);
+ }
+ 
+ #if defined(CONFIG_NFSD_V4)
+diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
+index d49e26c6cdc7..23e129ef6726 100644
+--- a/include/linux/intel-iommu.h
++++ b/include/linux/intel-iommu.h
+@@ -153,8 +153,8 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
+ #define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60)
+ #define DMA_TLB_DSI_FLUSH (((u64)2) << 60)
+ #define DMA_TLB_PSI_FLUSH (((u64)3) << 60)
+-#define DMA_TLB_IIRG(type) ((type >> 60) & 7)
+-#define DMA_TLB_IAIG(val) (((val) >> 57) & 7)
++#define DMA_TLB_IIRG(type) ((type >> 60) & 3)
++#define DMA_TLB_IAIG(val) (((val) >> 57) & 3)
+ #define DMA_TLB_READ_DRAIN (((u64)1) << 49)
+ #define DMA_TLB_WRITE_DRAIN (((u64)1) << 48)
+ #define DMA_TLB_DID(id)	(((u64)((id) & 0xffff)) << 32)
+@@ -164,9 +164,9 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
+ 
+ /* INVALID_DESC */
+ #define DMA_CCMD_INVL_GRANU_OFFSET  61
+-#define DMA_ID_TLB_GLOBAL_FLUSH	(((u64)1) << 3)
+-#define DMA_ID_TLB_DSI_FLUSH	(((u64)2) << 3)
+-#define DMA_ID_TLB_PSI_FLUSH	(((u64)3) << 3)
++#define DMA_ID_TLB_GLOBAL_FLUSH	(((u64)1) << 4)
++#define DMA_ID_TLB_DSI_FLUSH	(((u64)2) << 4)
++#define DMA_ID_TLB_PSI_FLUSH	(((u64)3) << 4)
+ #define DMA_ID_TLB_READ_DRAIN	(((u64)1) << 7)
+ #define DMA_ID_TLB_WRITE_DRAIN	(((u64)1) << 6)
+ #define DMA_ID_TLB_DID(id)	(((u64)((id & 0xffff) << 16)))
+@@ -316,8 +316,8 @@ enum {
+ #define QI_DEV_EIOTLB_SIZE	(((u64)1) << 11)
+ #define QI_DEV_EIOTLB_GLOB(g)	((u64)g)
+ #define QI_DEV_EIOTLB_PASID(p)	(((u64)p) << 32)
+-#define QI_DEV_EIOTLB_SID(sid)	((u64)((sid) & 0xffff) << 32)
+-#define QI_DEV_EIOTLB_QDEP(qd)	(((qd) & 0x1f) << 16)
++#define QI_DEV_EIOTLB_SID(sid)	((u64)((sid) & 0xffff) << 16)
++#define QI_DEV_EIOTLB_QDEP(qd)	((u64)((qd) & 0x1f) << 4)
+ #define QI_DEV_EIOTLB_MAX_INVS	32
+ 
+ #define QI_PGRP_IDX(idx)	(((u64)(idx)) << 55)
+diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
+index 301969552d0a..b43e64d69734 100644
+--- a/include/rdma/ib_sa.h
++++ b/include/rdma/ib_sa.h
+@@ -138,12 +138,12 @@ struct ib_sa_path_rec {
+ 	union ib_gid sgid;
+ 	__be16       dlid;
+ 	__be16       slid;
+-	int          raw_traffic;
++	u8           raw_traffic;
+ 	/* reserved */
+ 	__be32       flow_label;
+ 	u8           hop_limit;
+ 	u8           traffic_class;
+-	int          reversible;
++	u8           reversible;
+ 	u8           numb_path;
+ 	__be16       pkey;
+ 	__be16       qos_class;
+@@ -204,7 +204,7 @@ struct ib_sa_mcmember_rec {
+ 	u8           hop_limit;
+ 	u8           scope;
+ 	u8           join_state;
+-	int          proxy_join;
++	u8           proxy_join;
+ };
+ 
+ /* Service Record Component Mask Sec 15.2.5.14 Ver 1.1	*/
+diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
+index 4f6ba34cdee6..293b9a7f53bc 100644
+--- a/include/scsi/scsi_device.h
++++ b/include/scsi/scsi_device.h
+@@ -307,6 +307,7 @@ extern void scsi_remove_device(struct scsi_device *);
+ extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh);
+ void scsi_attach_vpd(struct scsi_device *sdev);
+ 
++extern struct scsi_device *scsi_device_from_queue(struct request_queue *q);
+ extern int scsi_device_get(struct scsi_device *);
+ extern void scsi_device_put(struct scsi_device *);
+ extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *,
+diff --git a/include/soc/at91/at91sam9_ddrsdr.h b/include/soc/at91/at91sam9_ddrsdr.h
+index dc10c52e0e91..393362bdb860 100644
+--- a/include/soc/at91/at91sam9_ddrsdr.h
++++ b/include/soc/at91/at91sam9_ddrsdr.h
+@@ -81,6 +81,7 @@
+ #define			AT91_DDRSDRC_LPCB_POWER_DOWN		2
+ #define			AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN	3
+ #define		AT91_DDRSDRC_CLKFR	(1 << 2)	/* Clock Frozen */
++#define		AT91_DDRSDRC_LPDDR2_PWOFF	(1 << 3)	/* LPDDR Power Off */
+ #define		AT91_DDRSDRC_PASR	(7 << 4)	/* Partial Array Self Refresh */
+ #define		AT91_DDRSDRC_TCSR	(3 << 8)	/* Temperature Compensated Self Refresh */
+ #define		AT91_DDRSDRC_DS		(3 << 10)	/* Drive Strength */
+@@ -96,7 +97,9 @@
+ #define			AT91_DDRSDRC_MD_SDR		0
+ #define			AT91_DDRSDRC_MD_LOW_POWER_SDR	1
+ #define			AT91_DDRSDRC_MD_LOW_POWER_DDR	3
++#define			AT91_DDRSDRC_MD_LPDDR3		5
+ #define			AT91_DDRSDRC_MD_DDR2		6	/* [SAM9 Only] */
++#define			AT91_DDRSDRC_MD_LPDDR2		7
+ #define		AT91_DDRSDRC_DBW	(1 << 4)		/* Data Bus Width */
+ #define			AT91_DDRSDRC_DBW_32BITS		(0 <<  4)
+ #define			AT91_DDRSDRC_DBW_16BITS		(1 <<  4)
+diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
+index 6afc6f388edf..800fe16cc36f 100644
+--- a/include/target/target_core_base.h
++++ b/include/target/target_core_base.h
+@@ -544,6 +544,7 @@ struct se_node_acl {
+ 	/* Used to signal demo mode created ACL, disabled by default */
+ 	bool			dynamic_node_acl;
+ 	bool			acl_stop:1;
++	bool			dynamic_stop;
+ 	u32			queue_depth;
+ 	u32			acl_index;
+ 	enum target_prot_type	saved_prot_type;
+diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
+index ce9ea736f1d7..97069ecabe49 100644
+--- a/include/target/target_core_fabric.h
++++ b/include/target/target_core_fabric.h
+@@ -168,6 +168,8 @@ void	core_allocate_nexus_loss_ua(struct se_node_acl *acl);
+ 
+ struct se_node_acl *core_tpg_get_initiator_node_acl(struct se_portal_group *tpg,
+ 		unsigned char *);
++bool	target_tpg_has_node_acl(struct se_portal_group *tpg,
++		const char *);
+ struct se_node_acl *core_tpg_check_initiator_node_acl(struct se_portal_group *,
+ 		unsigned char *);
+ int	core_tpg_set_initiator_node_queue_depth(struct se_portal_group *,
+diff --git a/ipc/shm.c b/ipc/shm.c
+index 3174634ca4e5..4982a4e7f009 100644
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -1083,8 +1083,8 @@ out_unlock1:
+  * "raddr" thing points to kernel space, and there has to be a wrapper around
+  * this.
+  */
+-long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
+-	      unsigned long shmlba)
++long do_shmat(int shmid, char __user *shmaddr, int shmflg,
++	      ulong *raddr, unsigned long shmlba)
+ {
+ 	struct shmid_kernel *shp;
+ 	unsigned long addr;
+@@ -1105,8 +1105,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
+ 		goto out;
+ 	else if ((addr = (ulong)shmaddr)) {
+ 		if (addr & (shmlba - 1)) {
+-			if (shmflg & SHM_RND)
+-				addr &= ~(shmlba - 1);	   /* round down */
++			/*
++			 * Round down to the nearest multiple of shmlba.
++			 * For sane do_mmap_pgoff() parameters, avoid
++			 * round downs that trigger nil-page and MAP_FIXED.
++			 */
++			if ((shmflg & SHM_RND) && addr >= shmlba)
++				addr &= ~(shmlba - 1);
+ 			else
+ #ifndef __ARCH_FORCE_SHMLBA
+ 				if (addr & ~PAGE_MASK)
+diff --git a/kernel/membarrier.c b/kernel/membarrier.c
+index 536c727a56e9..9f9284f37f8d 100644
+--- a/kernel/membarrier.c
++++ b/kernel/membarrier.c
+@@ -16,6 +16,7 @@
+ 
+ #include <linux/syscalls.h>
+ #include <linux/membarrier.h>
++#include <linux/tick.h>
+ 
+ /*
+  * Bitmask made from a "or" of all commands within enum membarrier_cmd,
+@@ -51,6 +52,9 @@
+  */
+ SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
+ {
++	/* MEMBARRIER_CMD_SHARED is not compatible with nohz_full. */
++	if (tick_nohz_full_enabled())
++		return -ENOSYS;
+ 	if (unlikely(flags))
+ 		return -EINVAL;
+ 	switch (cmd) {
+diff --git a/mm/filemap.c b/mm/filemap.c
+index c33c31d75a2b..69f75c77c098 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -865,9 +865,12 @@ void page_endio(struct page *page, int rw, int err)
+ 		unlock_page(page);
+ 	} else { /* rw == WRITE */
+ 		if (err) {
++			struct address_space *mapping;
++
+ 			SetPageError(page);
+-			if (page->mapping)
+-				mapping_set_error(page->mapping, err);
++			mapping = page_mapping(page);
++			if (mapping)
++				mapping_set_error(mapping, err);
+ 		}
+ 		end_page_writeback(page);
+ 	}
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 6a117213feb8..6f9005dcca2e 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -2467,7 +2467,7 @@ static bool zone_local(struct zone *local_zone, struct zone *zone)
+ 
+ static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone)
+ {
+-	return node_distance(zone_to_nid(local_zone), zone_to_nid(zone)) <
++	return node_distance(zone_to_nid(local_zone), zone_to_nid(zone)) <=
+ 				RECLAIM_DISTANCE;
+ }
+ #else	/* CONFIG_NUMA */
+diff --git a/mm/vmpressure.c b/mm/vmpressure.c
+index c5afd573d7da..3fb15c25af87 100644
+--- a/mm/vmpressure.c
++++ b/mm/vmpressure.c
+@@ -112,9 +112,16 @@ static enum vmpressure_levels vmpressure_calc_level(unsigned long scanned,
+ 						    unsigned long reclaimed)
+ {
+ 	unsigned long scale = scanned + reclaimed;
+-	unsigned long pressure;
++	unsigned long pressure = 0;
+ 
+ 	/*
++	 * reclaimed can be greater than scanned in cases
++	 * like THP, where the scanned is 1 and reclaimed
++	 * could be 512
++	 */
++	if (reclaimed >= scanned)
++		goto out;
++	/*
+ 	 * We calculate the ratio (in percents) of how many pages were
+ 	 * scanned vs. reclaimed in a given time frame (window). Note that
+ 	 * time is in VM reclaimer's "ticks", i.e. number of pages
+@@ -124,6 +131,7 @@ static enum vmpressure_levels vmpressure_calc_level(unsigned long scanned,
+ 	pressure = scale - (reclaimed * scale / scanned);
+ 	pressure = pressure * 100 / scale;
+ 
++out:
+ 	pr_debug("%s: %3lu  (s: %lu  r: %lu)\n", __func__, pressure,
+ 		 scanned, reclaimed);
+ 
+diff --git a/samples/mic/mpssd/.gitignore b/samples/mic/mpssd/.gitignore
+new file mode 100644
+index 000000000000..8b7c72f07c92
+--- /dev/null
++++ b/samples/mic/mpssd/.gitignore
+@@ -0,0 +1 @@
++mpssd
+diff --git a/samples/mic/mpssd/Makefile b/samples/mic/mpssd/Makefile
+new file mode 100644
+index 000000000000..3e3ef91fed6b
+--- /dev/null
++++ b/samples/mic/mpssd/Makefile
+@@ -0,0 +1,27 @@
++ifndef CROSS_COMPILE
++uname_M := $(shell uname -m 2>/dev/null || echo not)
++ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
++
++ifeq ($(ARCH),x86)
++
++PROGS := mpssd
++CC = $(CROSS_COMPILE)gcc
++CFLAGS := -I../../../usr/include -I../../../tools/include
++
++ifdef DEBUG
++CFLAGS += -DDEBUG=$(DEBUG)
++endif
++
++all: $(PROGS)
++mpssd: mpssd.c sysfs.c
++	$(CC) $(CFLAGS) mpssd.c sysfs.c -o mpssd -lpthread
++
++install:
++	install mpssd /usr/sbin/mpssd
++	install micctrl /usr/sbin/micctrl
++
++clean:
++	rm -fr $(PROGS)
++
++endif
++endif
+diff --git a/samples/mic/mpssd/micctrl b/samples/mic/mpssd/micctrl
+new file mode 100644
+index 000000000000..8f2629b41c5f
+--- /dev/null
++++ b/samples/mic/mpssd/micctrl
+@@ -0,0 +1,173 @@
++#!/bin/bash
++# Intel MIC Platform Software Stack (MPSS)
++#
++# Copyright(c) 2013 Intel Corporation.
++#
++# 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.
++#
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
++#
++# The full GNU General Public License is included in this distribution in
++# the file called "COPYING".
++#
++# Intel MIC User Space Tools.
++#
++# micctrl - Controls MIC boot/start/stop.
++#
++# chkconfig: 2345 95 05
++# description: start MPSS stack processing.
++#
++### BEGIN INIT INFO
++# Provides: micctrl
++### END INIT INFO
++
++# Source function library.
++. /etc/init.d/functions
++
++sysfs="/sys/class/mic"
++
++_status()
++{
++	f=$sysfs/$1
++	echo -e $1 state: "`cat $f/state`" shutdown_status: "`cat $f/shutdown_status`"
++}
++
++status()
++{
++	if [ "`echo $1 | head -c3`" == "mic" ]; then
++		_status $1
++		return $?
++	fi
++	for f in $sysfs/*
++	do
++		_status `basename $f`
++		RETVAL=$?
++		[ $RETVAL -ne 0 ] && return $RETVAL
++	done
++	return 0
++}
++
++_reset()
++{
++	f=$sysfs/$1
++	echo reset > $f/state
++}
++
++reset()
++{
++	if [ "`echo $1 | head -c3`" == "mic" ]; then
++		_reset $1
++		return $?
++	fi
++	for f in $sysfs/*
++	do
++		_reset `basename $f`
++		RETVAL=$?
++		[ $RETVAL -ne 0 ] && return $RETVAL
++	done
++	return 0
++}
++
++_boot()
++{
++	f=$sysfs/$1
++	echo "linux" > $f/bootmode
++	echo "mic/uos.img" > $f/firmware
++	echo "mic/$1.image" > $f/ramdisk
++	echo "boot" > $f/state
++}
++
++boot()
++{
++	if [ "`echo $1 | head -c3`" == "mic" ]; then
++		_boot $1
++		return $?
++	fi
++	for f in $sysfs/*
++	do
++		_boot `basename $f`
++		RETVAL=$?
++		[ $RETVAL -ne 0 ] && return $RETVAL
++	done
++	return 0
++}
++
++_shutdown()
++{
++	f=$sysfs/$1
++	echo shutdown > $f/state
++}
++
++shutdown()
++{
++	if [ "`echo $1 | head -c3`" == "mic" ]; then
++		_shutdown $1
++		return $?
++	fi
++	for f in $sysfs/*
++	do
++		_shutdown `basename $f`
++		RETVAL=$?
++		[ $RETVAL -ne 0 ] && return $RETVAL
++	done
++	return 0
++}
++
++_wait()
++{
++	f=$sysfs/$1
++	while [ "`cat $f/state`" != "offline" -a "`cat $f/state`" != "online" ]
++	do
++		sleep 1
++		echo -e "Waiting for $1 to go offline"
++	done
++}
++
++wait()
++{
++	if [ "`echo $1 | head -c3`" == "mic" ]; then
++		_wait $1
++		return $?
++	fi
++	# Wait for the cards to go offline
++	for f in $sysfs/*
++	do
++		_wait `basename $f`
++		RETVAL=$?
++		[ $RETVAL -ne 0 ] && return $RETVAL
++	done
++	return 0
++}
++
++if [ ! -d "$sysfs" ]; then
++	echo -e $"Module unloaded "
++	exit 3
++fi
++
++case $1 in
++	-s)
++		status $2
++		;;
++	-r)
++		reset $2
++		;;
++	-b)
++		boot $2
++		;;
++	-S)
++		shutdown $2
++		;;
++	-w)
++		wait $2
++		;;
++	*)
++		echo $"Usage: $0 {-s (status) |-r (reset) |-b (boot) |-S (shutdown) |-w (wait)}"
++		exit 2
++esac
++
++exit $?
+diff --git a/samples/mic/mpssd/mpss b/samples/mic/mpssd/mpss
+new file mode 100644
+index 000000000000..09ea90931649
+--- /dev/null
++++ b/samples/mic/mpssd/mpss
+@@ -0,0 +1,200 @@
++#!/bin/bash
++# Intel MIC Platform Software Stack (MPSS)
++#
++# Copyright(c) 2013 Intel Corporation.
++#
++# 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.
++#
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
++#
++# The full GNU General Public License is included in this distribution in
++# the file called "COPYING".
++#
++# Intel MIC User Space Tools.
++#
++# mpss	Start mpssd.
++#
++# chkconfig: 2345 95 05
++# description: start MPSS stack processing.
++#
++### BEGIN INIT INFO
++# Provides: mpss
++# Required-Start:
++# Required-Stop:
++# Short-Description: MPSS stack control
++# Description: MPSS stack control
++### END INIT INFO
++
++# Source function library.
++. /etc/init.d/functions
++
++exec=/usr/sbin/mpssd
++sysfs="/sys/class/mic"
++mic_modules="mic_host mic_x100_dma scif"
++
++start()
++{
++	[ -x $exec ] || exit 5
++
++	if [ "`ps -e | awk '{print $4}' | grep mpssd | head -1`" = "mpssd" ]; then
++		echo -e $"MPSSD already running! "
++		success
++		echo
++		return 0
++	fi
++
++	echo -e $"Starting MPSS Stack"
++	echo -e $"Loading MIC drivers:" $mic_modules
++
++	modprobe -a $mic_modules
++	RETVAL=$?
++	if [ $RETVAL -ne 0 ]; then
++		failure
++		echo
++		return $RETVAL
++	fi
++
++	# Start the daemon
++	echo -n $"Starting MPSSD "
++	$exec
++	RETVAL=$?
++	if [ $RETVAL -ne 0 ]; then
++		failure
++		echo
++		return $RETVAL
++	fi
++	success
++	echo
++
++	sleep 5
++
++	# Boot the cards
++	micctrl -b
++
++	# Wait till ping works
++	for f in $sysfs/*
++	do
++		count=100
++		ipaddr=`cat $f/cmdline`
++		ipaddr=${ipaddr#*address,}
++		ipaddr=`echo $ipaddr | cut -d, -f1 | cut -d\; -f1`
++		while [ $count -ge 0 ]
++		do
++			echo -e "Pinging "`basename $f`" "
++			ping -c 1 $ipaddr &> /dev/null
++			RETVAL=$?
++			if [ $RETVAL -eq 0 ]; then
++				success
++				break
++			fi
++			sleep 1
++			count=`expr $count - 1`
++		done
++		[ $RETVAL -ne 0 ] && failure || success
++		echo
++	done
++	return $RETVAL
++}
++
++stop()
++{
++	echo -e $"Shutting down MPSS Stack: "
++
++	# Bail out if module is unloaded
++	if [ ! -d "$sysfs" ]; then
++		echo -n $"Module unloaded "
++		success
++		echo
++		return 0
++	fi
++
++	# Shut down the cards.
++	micctrl -S
++
++	# Wait for the cards to go offline
++	for f in $sysfs/*
++	do
++		while [ "`cat $f/state`" != "ready" ]
++		do
++			sleep 1
++			echo -e "Waiting for "`basename $f`" to become ready"
++		done
++	done
++
++	# Display the status of the cards
++	micctrl -s
++
++	# Kill MPSSD now
++	echo -n $"Killing MPSSD"
++	killall -9 mpssd 2>/dev/null
++	RETVAL=$?
++	[ $RETVAL -ne 0 ] && failure || success
++	echo
++	return $RETVAL
++}
++
++restart()
++{
++	stop
++	sleep 5
++	start
++}
++
++status()
++{
++	micctrl -s
++	if [ "`ps -e | awk '{print $4}' | grep mpssd | head -n 1`" = "mpssd" ]; then
++		echo "mpssd is running"
++	else
++		echo "mpssd is stopped"
++	fi
++	return 0
++}
++
++unload()
++{
++	if [ ! -d "$sysfs" ]; then
++		echo -n $"No MIC_HOST Module: "
++		success
++		echo
++		return
++	fi
++
++	stop
++
++	sleep 5
++	echo -n $"Removing MIC drivers:" $mic_modules
++	modprobe -r $mic_modules
++	RETVAL=$?
++	[ $RETVAL -ne 0 ] && failure || success
++	echo
++	return $RETVAL
++}
++
++case $1 in
++	start)
++		start
++		;;
++	stop)
++		stop
++		;;
++	restart)
++		restart
++		;;
++	status)
++		status
++		;;
++	unload)
++		unload
++		;;
++	*)
++		echo $"Usage: $0 {start|stop|restart|status|unload}"
++		exit 2
++esac
++
++exit $?
+diff --git a/samples/mic/mpssd/mpssd.c b/samples/mic/mpssd/mpssd.c
+new file mode 100644
+index 000000000000..c99a75968c01
+--- /dev/null
++++ b/samples/mic/mpssd/mpssd.c
+@@ -0,0 +1,1826 @@
++/*
++ * Intel MIC Platform Software Stack (MPSS)
++ *
++ * Copyright(c) 2013 Intel Corporation.
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * The full GNU General Public License is included in this distribution in
++ * the file called "COPYING".
++ *
++ * Intel MIC User Space Tools.
++ */
++
++#define _GNU_SOURCE
++
++#include <stdlib.h>
++#include <fcntl.h>
++#include <getopt.h>
++#include <assert.h>
++#include <unistd.h>
++#include <stdbool.h>
++#include <signal.h>
++#include <poll.h>
++#include <features.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/mman.h>
++#include <sys/socket.h>
++#include <linux/virtio_ring.h>
++#include <linux/virtio_net.h>
++#include <linux/virtio_console.h>
++#include <linux/virtio_blk.h>
++#include <linux/version.h>
++#include "mpssd.h"
++#include <linux/mic_ioctl.h>
++#include <linux/mic_common.h>
++#include <tools/endian.h>
++
++static void *init_mic(void *arg);
++
++static FILE *logfp;
++static struct mic_info mic_list;
++
++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
++
++#define min_t(type, x, y) ({				\
++		type __min1 = (x);                      \
++		type __min2 = (y);                      \
++		__min1 < __min2 ? __min1 : __min2; })
++
++/* align addr on a size boundary - adjust address up/down if needed */
++#define _ALIGN_DOWN(addr, size)  ((addr)&(~((size)-1)))
++#define _ALIGN_UP(addr, size)    _ALIGN_DOWN(addr + size - 1, size)
++
++/* align addr on a size boundary - adjust address up if needed */
++#define _ALIGN(addr, size)     _ALIGN_UP(addr, size)
++
++/* to align the pointer to the (next) page boundary */
++#define PAGE_ALIGN(addr)        _ALIGN(addr, PAGE_SIZE)
++
++#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
++
++#define GSO_ENABLED		1
++#define MAX_GSO_SIZE		(64 * 1024)
++#define ETH_H_LEN		14
++#define MAX_NET_PKT_SIZE	(_ALIGN_UP(MAX_GSO_SIZE + ETH_H_LEN, 64))
++#define MIC_DEVICE_PAGE_END	0x1000
++
++#ifndef VIRTIO_NET_HDR_F_DATA_VALID
++#define VIRTIO_NET_HDR_F_DATA_VALID	2	/* Csum is valid */
++#endif
++
++static struct {
++	struct mic_device_desc dd;
++	struct mic_vqconfig vqconfig[2];
++	__u32 host_features, guest_acknowledgements;
++	struct virtio_console_config cons_config;
++} virtcons_dev_page = {
++	.dd = {
++		.type = VIRTIO_ID_CONSOLE,
++		.num_vq = ARRAY_SIZE(virtcons_dev_page.vqconfig),
++		.feature_len = sizeof(virtcons_dev_page.host_features),
++		.config_len = sizeof(virtcons_dev_page.cons_config),
++	},
++	.vqconfig[0] = {
++		.num = htole16(MIC_VRING_ENTRIES),
++	},
++	.vqconfig[1] = {
++		.num = htole16(MIC_VRING_ENTRIES),
++	},
++};
++
++static struct {
++	struct mic_device_desc dd;
++	struct mic_vqconfig vqconfig[2];
++	__u32 host_features, guest_acknowledgements;
++	struct virtio_net_config net_config;
++} virtnet_dev_page = {
++	.dd = {
++		.type = VIRTIO_ID_NET,
++		.num_vq = ARRAY_SIZE(virtnet_dev_page.vqconfig),
++		.feature_len = sizeof(virtnet_dev_page.host_features),
++		.config_len = sizeof(virtnet_dev_page.net_config),
++	},
++	.vqconfig[0] = {
++		.num = htole16(MIC_VRING_ENTRIES),
++	},
++	.vqconfig[1] = {
++		.num = htole16(MIC_VRING_ENTRIES),
++	},
++#if GSO_ENABLED
++	.host_features = htole32(
++		1 << VIRTIO_NET_F_CSUM |
++		1 << VIRTIO_NET_F_GSO |
++		1 << VIRTIO_NET_F_GUEST_TSO4 |
++		1 << VIRTIO_NET_F_GUEST_TSO6 |
++		1 << VIRTIO_NET_F_GUEST_ECN),
++#else
++		.host_features = 0,
++#endif
++};
++
++static const char *mic_config_dir = "/etc/mpss";
++static const char *virtblk_backend = "VIRTBLK_BACKEND";
++static struct {
++	struct mic_device_desc dd;
++	struct mic_vqconfig vqconfig[1];
++	__u32 host_features, guest_acknowledgements;
++	struct virtio_blk_config blk_config;
++} virtblk_dev_page = {
++	.dd = {
++		.type = VIRTIO_ID_BLOCK,
++		.num_vq = ARRAY_SIZE(virtblk_dev_page.vqconfig),
++		.feature_len = sizeof(virtblk_dev_page.host_features),
++		.config_len = sizeof(virtblk_dev_page.blk_config),
++	},
++	.vqconfig[0] = {
++		.num = htole16(MIC_VRING_ENTRIES),
++	},
++	.host_features =
++		htole32(1<<VIRTIO_BLK_F_SEG_MAX),
++	.blk_config = {
++		.seg_max = htole32(MIC_VRING_ENTRIES - 2),
++		.capacity = htole64(0),
++	 }
++};
++
++static char *myname;
++
++static int
++tap_configure(struct mic_info *mic, char *dev)
++{
++	pid_t pid;
++	char *ifargv[7];
++	char ipaddr[IFNAMSIZ];
++	int ret = 0;
++
++	pid = fork();
++	if (pid == 0) {
++		ifargv[0] = "ip";
++		ifargv[1] = "link";
++		ifargv[2] = "set";
++		ifargv[3] = dev;
++		ifargv[4] = "up";
++		ifargv[5] = NULL;
++		mpsslog("Configuring %s\n", dev);
++		ret = execvp("ip", ifargv);
++		if (ret < 0) {
++			mpsslog("%s execvp failed errno %s\n",
++				mic->name, strerror(errno));
++			return ret;
++		}
++	}
++	if (pid < 0) {
++		mpsslog("%s fork failed errno %s\n",
++			mic->name, strerror(errno));
++		return ret;
++	}
++
++	ret = waitpid(pid, NULL, 0);
++	if (ret < 0) {
++		mpsslog("%s waitpid failed errno %s\n",
++			mic->name, strerror(errno));
++		return ret;
++	}
++
++	snprintf(ipaddr, IFNAMSIZ, "172.31.%d.254/24", mic->id + 1);
++
++	pid = fork();
++	if (pid == 0) {
++		ifargv[0] = "ip";
++		ifargv[1] = "addr";
++		ifargv[2] = "add";
++		ifargv[3] = ipaddr;
++		ifargv[4] = "dev";
++		ifargv[5] = dev;
++		ifargv[6] = NULL;
++		mpsslog("Configuring %s ipaddr %s\n", dev, ipaddr);
++		ret = execvp("ip", ifargv);
++		if (ret < 0) {
++			mpsslog("%s execvp failed errno %s\n",
++				mic->name, strerror(errno));
++			return ret;
++		}
++	}
++	if (pid < 0) {
++		mpsslog("%s fork failed errno %s\n",
++			mic->name, strerror(errno));
++		return ret;
++	}
++
++	ret = waitpid(pid, NULL, 0);
++	if (ret < 0) {
++		mpsslog("%s waitpid failed errno %s\n",
++			mic->name, strerror(errno));
++		return ret;
++	}
++	mpsslog("MIC name %s %s %d DONE!\n",
++		mic->name, __func__, __LINE__);
++	return 0;
++}
++
++static int tun_alloc(struct mic_info *mic, char *dev)
++{
++	struct ifreq ifr;
++	int fd, err;
++#if GSO_ENABLED
++	unsigned offload;
++#endif
++	fd = open("/dev/net/tun", O_RDWR);
++	if (fd < 0) {
++		mpsslog("Could not open /dev/net/tun %s\n", strerror(errno));
++		goto done;
++	}
++
++	memset(&ifr, 0, sizeof(ifr));
++
++	ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
++	if (*dev)
++		strncpy(ifr.ifr_name, dev, IFNAMSIZ);
++
++	err = ioctl(fd, TUNSETIFF, (void *)&ifr);
++	if (err < 0) {
++		mpsslog("%s %s %d TUNSETIFF failed %s\n",
++			mic->name, __func__, __LINE__, strerror(errno));
++		close(fd);
++		return err;
++	}
++#if GSO_ENABLED
++	offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_TSO_ECN;
++
++	err = ioctl(fd, TUNSETOFFLOAD, offload);
++	if (err < 0) {
++		mpsslog("%s %s %d TUNSETOFFLOAD failed %s\n",
++			mic->name, __func__, __LINE__, strerror(errno));
++		close(fd);
++		return err;
++	}
++#endif
++	strcpy(dev, ifr.ifr_name);
++	mpsslog("Created TAP %s\n", dev);
++done:
++	return fd;
++}
++
++#define NET_FD_VIRTIO_NET 0
++#define NET_FD_TUN 1
++#define MAX_NET_FD 2
++
++static void set_dp(struct mic_info *mic, int type, void *dp)
++{
++	switch (type) {
++	case VIRTIO_ID_CONSOLE:
++		mic->mic_console.console_dp = dp;
++		return;
++	case VIRTIO_ID_NET:
++		mic->mic_net.net_dp = dp;
++		return;
++	case VIRTIO_ID_BLOCK:
++		mic->mic_virtblk.block_dp = dp;
++		return;
++	}
++	mpsslog("%s %s %d not found\n", mic->name, __func__, type);
++	assert(0);
++}
++
++static void *get_dp(struct mic_info *mic, int type)
++{
++	switch (type) {
++	case VIRTIO_ID_CONSOLE:
++		return mic->mic_console.console_dp;
++	case VIRTIO_ID_NET:
++		return mic->mic_net.net_dp;
++	case VIRTIO_ID_BLOCK:
++		return mic->mic_virtblk.block_dp;
++	}
++	mpsslog("%s %s %d not found\n", mic->name, __func__, type);
++	assert(0);
++	return NULL;
++}
++
++static struct mic_device_desc *get_device_desc(struct mic_info *mic, int type)
++{
++	struct mic_device_desc *d;
++	int i;
++	void *dp = get_dp(mic, type);
++
++	for (i = sizeof(struct mic_bootparam); i < PAGE_SIZE;
++		i += mic_total_desc_size(d)) {
++		d = dp + i;
++
++		/* End of list */
++		if (d->type == 0)
++			break;
++
++		if (d->type == -1)
++			continue;
++
++		mpsslog("%s %s d-> type %d d %p\n",
++			mic->name, __func__, d->type, d);
++
++		if (d->type == (__u8)type)
++			return d;
++	}
++	mpsslog("%s %s %d not found\n", mic->name, __func__, type);
++	return NULL;
++}
++
++/* See comments in vhost.c for explanation of next_desc() */
++static unsigned next_desc(struct vring_desc *desc)
++{
++	unsigned int next;
++
++	if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT))
++		return -1U;
++	next = le16toh(desc->next);
++	return next;
++}
++
++/* Sum up all the IOVEC length */
++static ssize_t
++sum_iovec_len(struct mic_copy_desc *copy)
++{
++	ssize_t sum = 0;
++	int i;
++
++	for (i = 0; i < copy->iovcnt; i++)
++		sum += copy->iov[i].iov_len;
++	return sum;
++}
++
++static inline void verify_out_len(struct mic_info *mic,
++	struct mic_copy_desc *copy)
++{
++	if (copy->out_len != sum_iovec_len(copy)) {
++		mpsslog("%s %s %d BUG copy->out_len 0x%x len 0x%zx\n",
++			mic->name, __func__, __LINE__,
++			copy->out_len, sum_iovec_len(copy));
++		assert(copy->out_len == sum_iovec_len(copy));
++	}
++}
++
++/* Display an iovec */
++static void
++disp_iovec(struct mic_info *mic, struct mic_copy_desc *copy,
++	   const char *s, int line)
++{
++	int i;
++
++	for (i = 0; i < copy->iovcnt; i++)
++		mpsslog("%s %s %d copy->iov[%d] addr %p len 0x%zx\n",
++			mic->name, s, line, i,
++			copy->iov[i].iov_base, copy->iov[i].iov_len);
++}
++
++static inline __u16 read_avail_idx(struct mic_vring *vr)
++{
++	return ACCESS_ONCE(vr->info->avail_idx);
++}
++
++static inline void txrx_prepare(int type, bool tx, struct mic_vring *vr,
++				struct mic_copy_desc *copy, ssize_t len)
++{
++	copy->vr_idx = tx ? 0 : 1;
++	copy->update_used = true;
++	if (type == VIRTIO_ID_NET)
++		copy->iov[1].iov_len = len - sizeof(struct virtio_net_hdr);
++	else
++		copy->iov[0].iov_len = len;
++}
++
++/* Central API which triggers the copies */
++static int
++mic_virtio_copy(struct mic_info *mic, int fd,
++		struct mic_vring *vr, struct mic_copy_desc *copy)
++{
++	int ret;
++
++	ret = ioctl(fd, MIC_VIRTIO_COPY_DESC, copy);
++	if (ret) {
++		mpsslog("%s %s %d errno %s ret %d\n",
++			mic->name, __func__, __LINE__,
++			strerror(errno), ret);
++	}
++	return ret;
++}
++
++static inline unsigned _vring_size(unsigned int num, unsigned long align)
++{
++	return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num)
++				+ align - 1) & ~(align - 1))
++		+ sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num;
++}
++
++/*
++ * This initialization routine requires at least one
++ * vring i.e. vr0. vr1 is optional.
++ */
++static void *
++init_vr(struct mic_info *mic, int fd, int type,
++	struct mic_vring *vr0, struct mic_vring *vr1, int num_vq)
++{
++	int vr_size;
++	char *va;
++
++	vr_size = PAGE_ALIGN(_vring_size(MIC_VRING_ENTRIES,
++					 MIC_VIRTIO_RING_ALIGN) +
++			     sizeof(struct _mic_vring_info));
++	va = mmap(NULL, MIC_DEVICE_PAGE_END + vr_size * num_vq,
++		PROT_READ, MAP_SHARED, fd, 0);
++	if (MAP_FAILED == va) {
++		mpsslog("%s %s %d mmap failed errno %s\n",
++			mic->name, __func__, __LINE__,
++			strerror(errno));
++		goto done;
++	}
++	set_dp(mic, type, va);
++	vr0->va = (struct mic_vring *)&va[MIC_DEVICE_PAGE_END];
++	vr0->info = vr0->va +
++		_vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN);
++	vring_init(&vr0->vr,
++		   MIC_VRING_ENTRIES, vr0->va, MIC_VIRTIO_RING_ALIGN);
++	mpsslog("%s %s vr0 %p vr0->info %p vr_size 0x%x vring 0x%x ",
++		__func__, mic->name, vr0->va, vr0->info, vr_size,
++		_vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
++	mpsslog("magic 0x%x expected 0x%x\n",
++		le32toh(vr0->info->magic), MIC_MAGIC + type);
++	assert(le32toh(vr0->info->magic) == MIC_MAGIC + type);
++	if (vr1) {
++		vr1->va = (struct mic_vring *)
++			&va[MIC_DEVICE_PAGE_END + vr_size];
++		vr1->info = vr1->va + _vring_size(MIC_VRING_ENTRIES,
++			MIC_VIRTIO_RING_ALIGN);
++		vring_init(&vr1->vr,
++			   MIC_VRING_ENTRIES, vr1->va, MIC_VIRTIO_RING_ALIGN);
++		mpsslog("%s %s vr1 %p vr1->info %p vr_size 0x%x vring 0x%x ",
++			__func__, mic->name, vr1->va, vr1->info, vr_size,
++			_vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
++		mpsslog("magic 0x%x expected 0x%x\n",
++			le32toh(vr1->info->magic), MIC_MAGIC + type + 1);
++		assert(le32toh(vr1->info->magic) == MIC_MAGIC + type + 1);
++	}
++done:
++	return va;
++}
++
++static int
++wait_for_card_driver(struct mic_info *mic, int fd, int type)
++{
++	struct pollfd pollfd;
++	int err;
++	struct mic_device_desc *desc = get_device_desc(mic, type);
++	__u8 prev_status;
++
++	if (!desc)
++		return -ENODEV;
++	prev_status = desc->status;
++	pollfd.fd = fd;
++	mpsslog("%s %s Waiting .... desc-> type %d status 0x%x\n",
++		mic->name, __func__, type, desc->status);
++
++	while (1) {
++		pollfd.events = POLLIN;
++		pollfd.revents = 0;
++		err = poll(&pollfd, 1, -1);
++		if (err < 0) {
++			mpsslog("%s %s poll failed %s\n",
++				mic->name, __func__, strerror(errno));
++			continue;
++		}
++
++		if (pollfd.revents) {
++			if (desc->status != prev_status) {
++				mpsslog("%s %s Waiting... desc-> type %d "
++					"status 0x%x\n",
++					mic->name, __func__, type,
++					desc->status);
++				prev_status = desc->status;
++			}
++			if (desc->status & VIRTIO_CONFIG_S_DRIVER_OK) {
++				mpsslog("%s %s poll.revents %d\n",
++					mic->name, __func__, pollfd.revents);
++				mpsslog("%s %s desc-> type %d status 0x%x\n",
++					mic->name, __func__, type,
++					desc->status);
++				break;
++			}
++		}
++	}
++	return 0;
++}
++
++/* Spin till we have some descriptors */
++static void
++spin_for_descriptors(struct mic_info *mic, struct mic_vring *vr)
++{
++	__u16 avail_idx = read_avail_idx(vr);
++
++	while (avail_idx == le16toh(ACCESS_ONCE(vr->vr.avail->idx))) {
++#ifdef DEBUG
++		mpsslog("%s %s waiting for desc avail %d info_avail %d\n",
++			mic->name, __func__,
++			le16toh(vr->vr.avail->idx), vr->info->avail_idx);
++#endif
++		sched_yield();
++	}
++}
++
++static void *
++virtio_net(void *arg)
++{
++	static __u8 vnet_hdr[2][sizeof(struct virtio_net_hdr)];
++	static __u8 vnet_buf[2][MAX_NET_PKT_SIZE] __attribute__ ((aligned(64)));
++	struct iovec vnet_iov[2][2] = {
++		{ { .iov_base = vnet_hdr[0], .iov_len = sizeof(vnet_hdr[0]) },
++		  { .iov_base = vnet_buf[0], .iov_len = sizeof(vnet_buf[0]) } },
++		{ { .iov_base = vnet_hdr[1], .iov_len = sizeof(vnet_hdr[1]) },
++		  { .iov_base = vnet_buf[1], .iov_len = sizeof(vnet_buf[1]) } },
++	};
++	struct iovec *iov0 = vnet_iov[0], *iov1 = vnet_iov[1];
++	struct mic_info *mic = (struct mic_info *)arg;
++	char if_name[IFNAMSIZ];
++	struct pollfd net_poll[MAX_NET_FD];
++	struct mic_vring tx_vr, rx_vr;
++	struct mic_copy_desc copy;
++	struct mic_device_desc *desc;
++	int err;
++
++	snprintf(if_name, IFNAMSIZ, "mic%d", mic->id);
++	mic->mic_net.tap_fd = tun_alloc(mic, if_name);
++	if (mic->mic_net.tap_fd < 0)
++		goto done;
++
++	if (tap_configure(mic, if_name))
++		goto done;
++	mpsslog("MIC name %s id %d\n", mic->name, mic->id);
++
++	net_poll[NET_FD_VIRTIO_NET].fd = mic->mic_net.virtio_net_fd;
++	net_poll[NET_FD_VIRTIO_NET].events = POLLIN;
++	net_poll[NET_FD_TUN].fd = mic->mic_net.tap_fd;
++	net_poll[NET_FD_TUN].events = POLLIN;
++
++	if (MAP_FAILED == init_vr(mic, mic->mic_net.virtio_net_fd,
++				  VIRTIO_ID_NET, &tx_vr, &rx_vr,
++		virtnet_dev_page.dd.num_vq)) {
++		mpsslog("%s init_vr failed %s\n",
++			mic->name, strerror(errno));
++		goto done;
++	}
++
++	copy.iovcnt = 2;
++	desc = get_device_desc(mic, VIRTIO_ID_NET);
++
++	while (1) {
++		ssize_t len;
++
++		net_poll[NET_FD_VIRTIO_NET].revents = 0;
++		net_poll[NET_FD_TUN].revents = 0;
++
++		/* Start polling for data from tap and virtio net */
++		err = poll(net_poll, 2, -1);
++		if (err < 0) {
++			mpsslog("%s poll failed %s\n",
++				__func__, strerror(errno));
++			continue;
++		}
++		if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
++			err = wait_for_card_driver(mic,
++						   mic->mic_net.virtio_net_fd,
++						   VIRTIO_ID_NET);
++			if (err) {
++				mpsslog("%s %s %d Exiting...\n",
++					mic->name, __func__, __LINE__);
++				break;
++			}
++		}
++		/*
++		 * Check if there is data to be read from TUN and write to
++		 * virtio net fd if there is.
++		 */
++		if (net_poll[NET_FD_TUN].revents & POLLIN) {
++			copy.iov = iov0;
++			len = readv(net_poll[NET_FD_TUN].fd,
++				copy.iov, copy.iovcnt);
++			if (len > 0) {
++				struct virtio_net_hdr *hdr
++					= (struct virtio_net_hdr *)vnet_hdr[0];
++
++				/* Disable checksums on the card since we are on
++				   a reliable PCIe link */
++				hdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;
++#ifdef DEBUG
++				mpsslog("%s %s %d hdr->flags 0x%x ", mic->name,
++					__func__, __LINE__, hdr->flags);
++				mpsslog("copy.out_len %d hdr->gso_type 0x%x\n",
++					copy.out_len, hdr->gso_type);
++#endif
++#ifdef DEBUG
++				disp_iovec(mic, copy, __func__, __LINE__);
++				mpsslog("%s %s %d read from tap 0x%lx\n",
++					mic->name, __func__, __LINE__,
++					len);
++#endif
++				spin_for_descriptors(mic, &tx_vr);
++				txrx_prepare(VIRTIO_ID_NET, 1, &tx_vr, &copy,
++					     len);
++
++				err = mic_virtio_copy(mic,
++					mic->mic_net.virtio_net_fd, &tx_vr,
++					&copy);
++				if (err < 0) {
++					mpsslog("%s %s %d mic_virtio_copy %s\n",
++						mic->name, __func__, __LINE__,
++						strerror(errno));
++				}
++				if (!err)
++					verify_out_len(mic, &copy);
++#ifdef DEBUG
++				disp_iovec(mic, copy, __func__, __LINE__);
++				mpsslog("%s %s %d wrote to net 0x%lx\n",
++					mic->name, __func__, __LINE__,
++					sum_iovec_len(&copy));
++#endif
++				/* Reinitialize IOV for next run */
++				iov0[1].iov_len = MAX_NET_PKT_SIZE;
++			} else if (len < 0) {
++				disp_iovec(mic, &copy, __func__, __LINE__);
++				mpsslog("%s %s %d read failed %s ", mic->name,
++					__func__, __LINE__, strerror(errno));
++				mpsslog("cnt %d sum %zd\n",
++					copy.iovcnt, sum_iovec_len(&copy));
++			}
++		}
++
++		/*
++		 * Check if there is data to be read from virtio net and
++		 * write to TUN if there is.
++		 */
++		if (net_poll[NET_FD_VIRTIO_NET].revents & POLLIN) {
++			while (rx_vr.info->avail_idx !=
++				le16toh(rx_vr.vr.avail->idx)) {
++				copy.iov = iov1;
++				txrx_prepare(VIRTIO_ID_NET, 0, &rx_vr, &copy,
++					     MAX_NET_PKT_SIZE
++					+ sizeof(struct virtio_net_hdr));
++
++				err = mic_virtio_copy(mic,
++					mic->mic_net.virtio_net_fd, &rx_vr,
++					&copy);
++				if (!err) {
++#ifdef DEBUG
++					struct virtio_net_hdr *hdr
++						= (struct virtio_net_hdr *)
++							vnet_hdr[1];
++
++					mpsslog("%s %s %d hdr->flags 0x%x, ",
++						mic->name, __func__, __LINE__,
++						hdr->flags);
++					mpsslog("out_len %d gso_type 0x%x\n",
++						copy.out_len,
++						hdr->gso_type);
++#endif
++					/* Set the correct output iov_len */
++					iov1[1].iov_len = copy.out_len -
++						sizeof(struct virtio_net_hdr);
++					verify_out_len(mic, &copy);
++#ifdef DEBUG
++					disp_iovec(mic, copy, __func__,
++						   __LINE__);
++					mpsslog("%s %s %d ",
++						mic->name, __func__, __LINE__);
++					mpsslog("read from net 0x%lx\n",
++						sum_iovec_len(copy));
++#endif
++					len = writev(net_poll[NET_FD_TUN].fd,
++						copy.iov, copy.iovcnt);
++					if (len != sum_iovec_len(&copy)) {
++						mpsslog("Tun write failed %s ",
++							strerror(errno));
++						mpsslog("len 0x%zx ", len);
++						mpsslog("read_len 0x%zx\n",
++							sum_iovec_len(&copy));
++					} else {
++#ifdef DEBUG
++						disp_iovec(mic, &copy, __func__,
++							   __LINE__);
++						mpsslog("%s %s %d ",
++							mic->name, __func__,
++							__LINE__);
++						mpsslog("wrote to tap 0x%lx\n",
++							len);
++#endif
++					}
++				} else {
++					mpsslog("%s %s %d mic_virtio_copy %s\n",
++						mic->name, __func__, __LINE__,
++						strerror(errno));
++					break;
++				}
++			}
++		}
++		if (net_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
++			mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
++	}
++done:
++	pthread_exit(NULL);
++}
++
++/* virtio_console */
++#define VIRTIO_CONSOLE_FD 0
++#define MONITOR_FD (VIRTIO_CONSOLE_FD + 1)
++#define MAX_CONSOLE_FD (MONITOR_FD + 1)  /* must be the last one + 1 */
++#define MAX_BUFFER_SIZE PAGE_SIZE
++
++static void *
++virtio_console(void *arg)
++{
++	static __u8 vcons_buf[2][PAGE_SIZE];
++	struct iovec vcons_iov[2] = {
++		{ .iov_base = vcons_buf[0], .iov_len = sizeof(vcons_buf[0]) },
++		{ .iov_base = vcons_buf[1], .iov_len = sizeof(vcons_buf[1]) },
++	};
++	struct iovec *iov0 = &vcons_iov[0], *iov1 = &vcons_iov[1];
++	struct mic_info *mic = (struct mic_info *)arg;
++	int err;
++	struct pollfd console_poll[MAX_CONSOLE_FD];
++	int pty_fd;
++	char *pts_name;
++	ssize_t len;
++	struct mic_vring tx_vr, rx_vr;
++	struct mic_copy_desc copy;
++	struct mic_device_desc *desc;
++
++	pty_fd = posix_openpt(O_RDWR);
++	if (pty_fd < 0) {
++		mpsslog("can't open a pseudoterminal master device: %s\n",
++			strerror(errno));
++		goto _return;
++	}
++	pts_name = ptsname(pty_fd);
++	if (pts_name == NULL) {
++		mpsslog("can't get pts name\n");
++		goto _close_pty;
++	}
++	printf("%s console message goes to %s\n", mic->name, pts_name);
++	mpsslog("%s console message goes to %s\n", mic->name, pts_name);
++	err = grantpt(pty_fd);
++	if (err < 0) {
++		mpsslog("can't grant access: %s %s\n",
++			pts_name, strerror(errno));
++		goto _close_pty;
++	}
++	err = unlockpt(pty_fd);
++	if (err < 0) {
++		mpsslog("can't unlock a pseudoterminal: %s %s\n",
++			pts_name, strerror(errno));
++		goto _close_pty;
++	}
++	console_poll[MONITOR_FD].fd = pty_fd;
++	console_poll[MONITOR_FD].events = POLLIN;
++
++	console_poll[VIRTIO_CONSOLE_FD].fd = mic->mic_console.virtio_console_fd;
++	console_poll[VIRTIO_CONSOLE_FD].events = POLLIN;
++
++	if (MAP_FAILED == init_vr(mic, mic->mic_console.virtio_console_fd,
++				  VIRTIO_ID_CONSOLE, &tx_vr, &rx_vr,
++		virtcons_dev_page.dd.num_vq)) {
++		mpsslog("%s init_vr failed %s\n",
++			mic->name, strerror(errno));
++		goto _close_pty;
++	}
++
++	copy.iovcnt = 1;
++	desc = get_device_desc(mic, VIRTIO_ID_CONSOLE);
++
++	for (;;) {
++		console_poll[MONITOR_FD].revents = 0;
++		console_poll[VIRTIO_CONSOLE_FD].revents = 0;
++		err = poll(console_poll, MAX_CONSOLE_FD, -1);
++		if (err < 0) {
++			mpsslog("%s %d: poll failed: %s\n", __func__, __LINE__,
++				strerror(errno));
++			continue;
++		}
++		if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
++			err = wait_for_card_driver(mic,
++					mic->mic_console.virtio_console_fd,
++					VIRTIO_ID_CONSOLE);
++			if (err) {
++				mpsslog("%s %s %d Exiting...\n",
++					mic->name, __func__, __LINE__);
++				break;
++			}
++		}
++
++		if (console_poll[MONITOR_FD].revents & POLLIN) {
++			copy.iov = iov0;
++			len = readv(pty_fd, copy.iov, copy.iovcnt);
++			if (len > 0) {
++#ifdef DEBUG
++				disp_iovec(mic, copy, __func__, __LINE__);
++				mpsslog("%s %s %d read from tap 0x%lx\n",
++					mic->name, __func__, __LINE__,
++					len);
++#endif
++				spin_for_descriptors(mic, &tx_vr);
++				txrx_prepare(VIRTIO_ID_CONSOLE, 1, &tx_vr,
++					     &copy, len);
++
++				err = mic_virtio_copy(mic,
++					mic->mic_console.virtio_console_fd,
++					&tx_vr, &copy);
++				if (err < 0) {
++					mpsslog("%s %s %d mic_virtio_copy %s\n",
++						mic->name, __func__, __LINE__,
++						strerror(errno));
++				}
++				if (!err)
++					verify_out_len(mic, &copy);
++#ifdef DEBUG
++				disp_iovec(mic, copy, __func__, __LINE__);
++				mpsslog("%s %s %d wrote to net 0x%lx\n",
++					mic->name, __func__, __LINE__,
++					sum_iovec_len(copy));
++#endif
++				/* Reinitialize IOV for next run */
++				iov0->iov_len = PAGE_SIZE;
++			} else if (len < 0) {
++				disp_iovec(mic, &copy, __func__, __LINE__);
++				mpsslog("%s %s %d read failed %s ",
++					mic->name, __func__, __LINE__,
++					strerror(errno));
++				mpsslog("cnt %d sum %zd\n",
++					copy.iovcnt, sum_iovec_len(&copy));
++			}
++		}
++
++		if (console_poll[VIRTIO_CONSOLE_FD].revents & POLLIN) {
++			while (rx_vr.info->avail_idx !=
++				le16toh(rx_vr.vr.avail->idx)) {
++				copy.iov = iov1;
++				txrx_prepare(VIRTIO_ID_CONSOLE, 0, &rx_vr,
++					     &copy, PAGE_SIZE);
++
++				err = mic_virtio_copy(mic,
++					mic->mic_console.virtio_console_fd,
++					&rx_vr, &copy);
++				if (!err) {
++					/* Set the correct output iov_len */
++					iov1->iov_len = copy.out_len;
++					verify_out_len(mic, &copy);
++#ifdef DEBUG
++					disp_iovec(mic, copy, __func__,
++						   __LINE__);
++					mpsslog("%s %s %d ",
++						mic->name, __func__, __LINE__);
++					mpsslog("read from net 0x%lx\n",
++						sum_iovec_len(copy));
++#endif
++					len = writev(pty_fd,
++						copy.iov, copy.iovcnt);
++					if (len != sum_iovec_len(&copy)) {
++						mpsslog("Tun write failed %s ",
++							strerror(errno));
++						mpsslog("len 0x%zx ", len);
++						mpsslog("read_len 0x%zx\n",
++							sum_iovec_len(&copy));
++					} else {
++#ifdef DEBUG
++						disp_iovec(mic, copy, __func__,
++							   __LINE__);
++						mpsslog("%s %s %d ",
++							mic->name, __func__,
++							__LINE__);
++						mpsslog("wrote to tap 0x%lx\n",
++							len);
++#endif
++					}
++				} else {
++					mpsslog("%s %s %d mic_virtio_copy %s\n",
++						mic->name, __func__, __LINE__,
++						strerror(errno));
++					break;
++				}
++			}
++		}
++		if (console_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
++			mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
++	}
++_close_pty:
++	close(pty_fd);
++_return:
++	pthread_exit(NULL);
++}
++
++static void
++add_virtio_device(struct mic_info *mic, struct mic_device_desc *dd)
++{
++	char path[PATH_MAX];
++	int fd, err;
++
++	snprintf(path, PATH_MAX, "/dev/mic%d", mic->id);
++	fd = open(path, O_RDWR);
++	if (fd < 0) {
++		mpsslog("Could not open %s %s\n", path, strerror(errno));
++		return;
++	}
++
++	err = ioctl(fd, MIC_VIRTIO_ADD_DEVICE, dd);
++	if (err < 0) {
++		mpsslog("Could not add %d %s\n", dd->type, strerror(errno));
++		close(fd);
++		return;
++	}
++	switch (dd->type) {
++	case VIRTIO_ID_NET:
++		mic->mic_net.virtio_net_fd = fd;
++		mpsslog("Added VIRTIO_ID_NET for %s\n", mic->name);
++		break;
++	case VIRTIO_ID_CONSOLE:
++		mic->mic_console.virtio_console_fd = fd;
++		mpsslog("Added VIRTIO_ID_CONSOLE for %s\n", mic->name);
++		break;
++	case VIRTIO_ID_BLOCK:
++		mic->mic_virtblk.virtio_block_fd = fd;
++		mpsslog("Added VIRTIO_ID_BLOCK for %s\n", mic->name);
++		break;
++	}
++}
++
++static bool
++set_backend_file(struct mic_info *mic)
++{
++	FILE *config;
++	char buff[PATH_MAX], *line, *evv, *p;
++
++	snprintf(buff, PATH_MAX, "%s/mpssd%03d.conf", mic_config_dir, mic->id);
++	config = fopen(buff, "r");
++	if (config == NULL)
++		return false;
++	do {  /* look for "virtblk_backend=XXXX" */
++		line = fgets(buff, PATH_MAX, config);
++		if (line == NULL)
++			break;
++		if (*line == '#')
++			continue;
++		p = strchr(line, '\n');
++		if (p)
++			*p = '\0';
++	} while (strncmp(line, virtblk_backend, strlen(virtblk_backend)) != 0);
++	fclose(config);
++	if (line == NULL)
++		return false;
++	evv = strchr(line, '=');
++	if (evv == NULL)
++		return false;
++	mic->mic_virtblk.backend_file = malloc(strlen(evv) + 1);
++	if (mic->mic_virtblk.backend_file == NULL) {
++		mpsslog("%s %d can't allocate memory\n", mic->name, mic->id);
++		return false;
++	}
++	strcpy(mic->mic_virtblk.backend_file, evv + 1);
++	return true;
++}
++
++#define SECTOR_SIZE 512
++static bool
++set_backend_size(struct mic_info *mic)
++{
++	mic->mic_virtblk.backend_size = lseek(mic->mic_virtblk.backend, 0,
++		SEEK_END);
++	if (mic->mic_virtblk.backend_size < 0) {
++		mpsslog("%s: can't seek: %s\n",
++			mic->name, mic->mic_virtblk.backend_file);
++		return false;
++	}
++	virtblk_dev_page.blk_config.capacity =
++		mic->mic_virtblk.backend_size / SECTOR_SIZE;
++	if ((mic->mic_virtblk.backend_size % SECTOR_SIZE) != 0)
++		virtblk_dev_page.blk_config.capacity++;
++
++	virtblk_dev_page.blk_config.capacity =
++		htole64(virtblk_dev_page.blk_config.capacity);
++
++	return true;
++}
++
++static bool
++open_backend(struct mic_info *mic)
++{
++	if (!set_backend_file(mic))
++		goto _error_exit;
++	mic->mic_virtblk.backend = open(mic->mic_virtblk.backend_file, O_RDWR);
++	if (mic->mic_virtblk.backend < 0) {
++		mpsslog("%s: can't open: %s\n", mic->name,
++			mic->mic_virtblk.backend_file);
++		goto _error_free;
++	}
++	if (!set_backend_size(mic))
++		goto _error_close;
++	mic->mic_virtblk.backend_addr = mmap(NULL,
++		mic->mic_virtblk.backend_size,
++		PROT_READ|PROT_WRITE, MAP_SHARED,
++		mic->mic_virtblk.backend, 0L);
++	if (mic->mic_virtblk.backend_addr == MAP_FAILED) {
++		mpsslog("%s: can't map: %s %s\n",
++			mic->name, mic->mic_virtblk.backend_file,
++			strerror(errno));
++		goto _error_close;
++	}
++	return true;
++
++ _error_close:
++	close(mic->mic_virtblk.backend);
++ _error_free:
++	free(mic->mic_virtblk.backend_file);
++ _error_exit:
++	return false;
++}
++
++static void
++close_backend(struct mic_info *mic)
++{
++	munmap(mic->mic_virtblk.backend_addr, mic->mic_virtblk.backend_size);
++	close(mic->mic_virtblk.backend);
++	free(mic->mic_virtblk.backend_file);
++}
++
++static bool
++start_virtblk(struct mic_info *mic, struct mic_vring *vring)
++{
++	if (((unsigned long)&virtblk_dev_page.blk_config % 8) != 0) {
++		mpsslog("%s: blk_config is not 8 byte aligned.\n",
++			mic->name);
++		return false;
++	}
++	add_virtio_device(mic, &virtblk_dev_page.dd);
++	if (MAP_FAILED == init_vr(mic, mic->mic_virtblk.virtio_block_fd,
++				  VIRTIO_ID_BLOCK, vring, NULL,
++				  virtblk_dev_page.dd.num_vq)) {
++		mpsslog("%s init_vr failed %s\n",
++			mic->name, strerror(errno));
++		return false;
++	}
++	return true;
++}
++
++static void
++stop_virtblk(struct mic_info *mic)
++{
++	int vr_size, ret;
++
++	vr_size = PAGE_ALIGN(_vring_size(MIC_VRING_ENTRIES,
++					 MIC_VIRTIO_RING_ALIGN) +
++			     sizeof(struct _mic_vring_info));
++	ret = munmap(mic->mic_virtblk.block_dp,
++		MIC_DEVICE_PAGE_END + vr_size * virtblk_dev_page.dd.num_vq);
++	if (ret < 0)
++		mpsslog("%s munmap errno %d\n", mic->name, errno);
++	close(mic->mic_virtblk.virtio_block_fd);
++}
++
++static __u8
++header_error_check(struct vring_desc *desc)
++{
++	if (le32toh(desc->len) != sizeof(struct virtio_blk_outhdr)) {
++		mpsslog("%s() %d: length is not sizeof(virtio_blk_outhd)\n",
++			__func__, __LINE__);
++		return -EIO;
++	}
++	if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT)) {
++		mpsslog("%s() %d: alone\n",
++			__func__, __LINE__);
++		return -EIO;
++	}
++	if (le16toh(desc->flags) & VRING_DESC_F_WRITE) {
++		mpsslog("%s() %d: not read\n",
++			__func__, __LINE__);
++		return -EIO;
++	}
++	return 0;
++}
++
++static int
++read_header(int fd, struct virtio_blk_outhdr *hdr, __u32 desc_idx)
++{
++	struct iovec iovec;
++	struct mic_copy_desc copy;
++
++	iovec.iov_len = sizeof(*hdr);
++	iovec.iov_base = hdr;
++	copy.iov = &iovec;
++	copy.iovcnt = 1;
++	copy.vr_idx = 0;  /* only one vring on virtio_block */
++	copy.update_used = false;  /* do not update used index */
++	return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
++}
++
++static int
++transfer_blocks(int fd, struct iovec *iovec, __u32 iovcnt)
++{
++	struct mic_copy_desc copy;
++
++	copy.iov = iovec;
++	copy.iovcnt = iovcnt;
++	copy.vr_idx = 0;  /* only one vring on virtio_block */
++	copy.update_used = false;  /* do not update used index */
++	return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
++}
++
++static __u8
++status_error_check(struct vring_desc *desc)
++{
++	if (le32toh(desc->len) != sizeof(__u8)) {
++		mpsslog("%s() %d: length is not sizeof(status)\n",
++			__func__, __LINE__);
++		return -EIO;
++	}
++	return 0;
++}
++
++static int
++write_status(int fd, __u8 *status)
++{
++	struct iovec iovec;
++	struct mic_copy_desc copy;
++
++	iovec.iov_base = status;
++	iovec.iov_len = sizeof(*status);
++	copy.iov = &iovec;
++	copy.iovcnt = 1;
++	copy.vr_idx = 0;  /* only one vring on virtio_block */
++	copy.update_used = true; /* Update used index */
++	return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
++}
++
++#ifndef VIRTIO_BLK_T_GET_ID
++#define VIRTIO_BLK_T_GET_ID    8
++#endif
++
++static void *
++virtio_block(void *arg)
++{
++	struct mic_info *mic = (struct mic_info *)arg;
++	int ret;
++	struct pollfd block_poll;
++	struct mic_vring vring;
++	__u16 avail_idx;
++	__u32 desc_idx;
++	struct vring_desc *desc;
++	struct iovec *iovec, *piov;
++	__u8 status;
++	__u32 buffer_desc_idx;
++	struct virtio_blk_outhdr hdr;
++	void *fos;
++
++	for (;;) {  /* forever */
++		if (!open_backend(mic)) { /* No virtblk */
++			for (mic->mic_virtblk.signaled = 0;
++				!mic->mic_virtblk.signaled;)
++				sleep(1);
++			continue;
++		}
++
++		/* backend file is specified. */
++		if (!start_virtblk(mic, &vring))
++			goto _close_backend;
++		iovec = malloc(sizeof(*iovec) *
++			le32toh(virtblk_dev_page.blk_config.seg_max));
++		if (!iovec) {
++			mpsslog("%s: can't alloc iovec: %s\n",
++				mic->name, strerror(ENOMEM));
++			goto _stop_virtblk;
++		}
++
++		block_poll.fd = mic->mic_virtblk.virtio_block_fd;
++		block_poll.events = POLLIN;
++		for (mic->mic_virtblk.signaled = 0;
++		     !mic->mic_virtblk.signaled;) {
++			block_poll.revents = 0;
++					/* timeout in 1 sec to see signaled */
++			ret = poll(&block_poll, 1, 1000);
++			if (ret < 0) {
++				mpsslog("%s %d: poll failed: %s\n",
++					__func__, __LINE__,
++					strerror(errno));
++				continue;
++			}
++
++			if (!(block_poll.revents & POLLIN)) {
++#ifdef DEBUG
++				mpsslog("%s %d: block_poll.revents=0x%x\n",
++					__func__, __LINE__, block_poll.revents);
++#endif
++				continue;
++			}
++
++			/* POLLIN */
++			while (vring.info->avail_idx !=
++				le16toh(vring.vr.avail->idx)) {
++				/* read header element */
++				avail_idx =
++					vring.info->avail_idx &
++					(vring.vr.num - 1);
++				desc_idx = le16toh(
++					vring.vr.avail->ring[avail_idx]);
++				desc = &vring.vr.desc[desc_idx];
++#ifdef DEBUG
++				mpsslog("%s() %d: avail_idx=%d ",
++					__func__, __LINE__,
++					vring.info->avail_idx);
++				mpsslog("vring.vr.num=%d desc=%p\n",
++					vring.vr.num, desc);
++#endif
++				status = header_error_check(desc);
++				ret = read_header(
++					mic->mic_virtblk.virtio_block_fd,
++					&hdr, desc_idx);
++				if (ret < 0) {
++					mpsslog("%s() %d %s: ret=%d %s\n",
++						__func__, __LINE__,
++						mic->name, ret,
++						strerror(errno));
++					break;
++				}
++				/* buffer element */
++				piov = iovec;
++				status = 0;
++				fos = mic->mic_virtblk.backend_addr +
++					(hdr.sector * SECTOR_SIZE);
++				buffer_desc_idx = next_desc(desc);
++				desc_idx = buffer_desc_idx;
++				for (desc = &vring.vr.desc[buffer_desc_idx];
++				     desc->flags & VRING_DESC_F_NEXT;
++				     desc_idx = next_desc(desc),
++					     desc = &vring.vr.desc[desc_idx]) {
++					piov->iov_len = desc->len;
++					piov->iov_base = fos;
++					piov++;
++					fos += desc->len;
++				}
++				/* Returning NULLs for VIRTIO_BLK_T_GET_ID. */
++				if (hdr.type & ~(VIRTIO_BLK_T_OUT |
++					VIRTIO_BLK_T_GET_ID)) {
++					/*
++					  VIRTIO_BLK_T_IN - does not do
++					  anything. Probably for documenting.
++					  VIRTIO_BLK_T_SCSI_CMD - for
++					  virtio_scsi.
++					  VIRTIO_BLK_T_FLUSH - turned off in
++					  config space.
++					  VIRTIO_BLK_T_BARRIER - defined but not
++					  used in anywhere.
++					*/
++					mpsslog("%s() %d: type %x ",
++						__func__, __LINE__,
++						hdr.type);
++					mpsslog("is not supported\n");
++					status = -ENOTSUP;
++
++				} else {
++					ret = transfer_blocks(
++					mic->mic_virtblk.virtio_block_fd,
++						iovec,
++						piov - iovec);
++					if (ret < 0 &&
++					    status != 0)
++						status = ret;
++				}
++				/* write status and update used pointer */
++				if (status != 0)
++					status = status_error_check(desc);
++				ret = write_status(
++					mic->mic_virtblk.virtio_block_fd,
++					&status);
++#ifdef DEBUG
++				mpsslog("%s() %d: write status=%d on desc=%p\n",
++					__func__, __LINE__,
++					status, desc);
++#endif
++			}
++		}
++		free(iovec);
++_stop_virtblk:
++		stop_virtblk(mic);
++_close_backend:
++		close_backend(mic);
++	}  /* forever */
++
++	pthread_exit(NULL);
++}
++
++static void
++reset(struct mic_info *mic)
++{
++#define RESET_TIMEOUT 120
++	int i = RESET_TIMEOUT;
++	setsysfs(mic->name, "state", "reset");
++	while (i) {
++		char *state;
++		state = readsysfs(mic->name, "state");
++		if (!state)
++			goto retry;
++		mpsslog("%s: %s %d state %s\n",
++			mic->name, __func__, __LINE__, state);
++
++		if (!strcmp(state, "ready")) {
++			free(state);
++			break;
++		}
++		free(state);
++retry:
++		sleep(1);
++		i--;
++	}
++}
++
++static int
++get_mic_shutdown_status(struct mic_info *mic, char *shutdown_status)
++{
++	if (!strcmp(shutdown_status, "nop"))
++		return MIC_NOP;
++	if (!strcmp(shutdown_status, "crashed"))
++		return MIC_CRASHED;
++	if (!strcmp(shutdown_status, "halted"))
++		return MIC_HALTED;
++	if (!strcmp(shutdown_status, "poweroff"))
++		return MIC_POWER_OFF;
++	if (!strcmp(shutdown_status, "restart"))
++		return MIC_RESTART;
++	mpsslog("%s: BUG invalid status %s\n", mic->name, shutdown_status);
++	/* Invalid state */
++	assert(0);
++};
++
++static int get_mic_state(struct mic_info *mic)
++{
++	char *state = NULL;
++	enum mic_states mic_state;
++
++	while (!state) {
++		state = readsysfs(mic->name, "state");
++		sleep(1);
++	}
++	mpsslog("%s: %s %d state %s\n",
++		mic->name, __func__, __LINE__, state);
++
++	if (!strcmp(state, "ready")) {
++		mic_state = MIC_READY;
++	} else if (!strcmp(state, "booting")) {
++		mic_state = MIC_BOOTING;
++	} else if (!strcmp(state, "online")) {
++		mic_state = MIC_ONLINE;
++	} else if (!strcmp(state, "shutting_down")) {
++		mic_state = MIC_SHUTTING_DOWN;
++	} else if (!strcmp(state, "reset_failed")) {
++		mic_state = MIC_RESET_FAILED;
++	} else if (!strcmp(state, "resetting")) {
++		mic_state = MIC_RESETTING;
++	} else {
++		mpsslog("%s: BUG invalid state %s\n", mic->name, state);
++		assert(0);
++	}
++
++	free(state);
++	return mic_state;
++};
++
++static void mic_handle_shutdown(struct mic_info *mic)
++{
++#define SHUTDOWN_TIMEOUT 60
++	int i = SHUTDOWN_TIMEOUT;
++	char *shutdown_status;
++	while (i) {
++		shutdown_status = readsysfs(mic->name, "shutdown_status");
++		if (!shutdown_status) {
++			sleep(1);
++			continue;
++		}
++		mpsslog("%s: %s %d shutdown_status %s\n",
++			mic->name, __func__, __LINE__, shutdown_status);
++		switch (get_mic_shutdown_status(mic, shutdown_status)) {
++		case MIC_RESTART:
++			mic->restart = 1;
++		case MIC_HALTED:
++		case MIC_POWER_OFF:
++		case MIC_CRASHED:
++			free(shutdown_status);
++			goto reset;
++		default:
++			break;
++		}
++		free(shutdown_status);
++		sleep(1);
++		i--;
++	}
++reset:
++	if (!i)
++		mpsslog("%s: %s %d timing out waiting for shutdown_status %s\n",
++			mic->name, __func__, __LINE__, shutdown_status);
++	reset(mic);
++}
++
++static int open_state_fd(struct mic_info *mic)
++{
++	char pathname[PATH_MAX];
++	int fd;
++
++	snprintf(pathname, PATH_MAX - 1, "%s/%s/%s",
++		 MICSYSFSDIR, mic->name, "state");
++
++	fd = open(pathname, O_RDONLY);
++	if (fd < 0)
++		mpsslog("%s: opening file %s failed %s\n",
++			mic->name, pathname, strerror(errno));
++	return fd;
++}
++
++static int block_till_state_change(int fd, struct mic_info *mic)
++{
++	struct pollfd ufds[1];
++	char value[PAGE_SIZE];
++	int ret;
++
++	ufds[0].fd = fd;
++	ufds[0].events = POLLERR | POLLPRI;
++	ret = poll(ufds, 1, -1);
++	if (ret < 0) {
++		mpsslog("%s: %s %d poll failed %s\n",
++			mic->name, __func__, __LINE__, strerror(errno));
++		return ret;
++	}
++
++	ret = lseek(fd, 0, SEEK_SET);
++	if (ret < 0) {
++		mpsslog("%s: %s %d Failed to seek to 0: %s\n",
++			mic->name, __func__, __LINE__, strerror(errno));
++		return ret;
++	}
++
++	ret = read(fd, value, sizeof(value));
++	if (ret < 0) {
++		mpsslog("%s: %s %d Failed to read sysfs entry: %s\n",
++			mic->name, __func__, __LINE__, strerror(errno));
++		return ret;
++	}
++
++	return 0;
++}
++
++static void *
++mic_config(void *arg)
++{
++	struct mic_info *mic = (struct mic_info *)arg;
++	int fd, ret, stat = 0;
++
++	fd = open_state_fd(mic);
++	if (fd < 0) {
++		mpsslog("%s: %s %d open state fd failed %s\n",
++			mic->name, __func__, __LINE__, strerror(errno));
++		goto exit;
++	}
++
++	do {
++		ret = block_till_state_change(fd, mic);
++		if (ret < 0) {
++			mpsslog("%s: %s %d block_till_state_change error %s\n",
++				mic->name, __func__, __LINE__, strerror(errno));
++			goto close_exit;
++		}
++
++		switch (get_mic_state(mic)) {
++		case MIC_SHUTTING_DOWN:
++			mic_handle_shutdown(mic);
++			break;
++		case MIC_READY:
++		case MIC_RESET_FAILED:
++			ret = kill(mic->pid, SIGTERM);
++			mpsslog("%s: %s %d kill pid %d ret %d\n",
++				mic->name, __func__, __LINE__,
++				mic->pid, ret);
++			if (!ret) {
++				ret = waitpid(mic->pid, &stat,
++					      WIFSIGNALED(stat));
++				mpsslog("%s: %s %d waitpid ret %d pid %d\n",
++					mic->name, __func__, __LINE__,
++					ret, mic->pid);
++			}
++			if (mic->boot_on_resume) {
++				setsysfs(mic->name, "state", "boot");
++				mic->boot_on_resume = 0;
++			}
++			goto close_exit;
++		default:
++			break;
++		}
++	} while (1);
++
++close_exit:
++	close(fd);
++exit:
++	init_mic(mic);
++	pthread_exit(NULL);
++}
++
++static void
++set_cmdline(struct mic_info *mic)
++{
++	char buffer[PATH_MAX];
++	int len;
++
++	len = snprintf(buffer, PATH_MAX,
++		"clocksource=tsc highres=off nohz=off ");
++	len += snprintf(buffer + len, PATH_MAX - len,
++		"cpufreq_on;corec6_off;pc3_off;pc6_off ");
++	len += snprintf(buffer + len, PATH_MAX - len,
++		"ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0",
++		mic->id + 1);
++
++	setsysfs(mic->name, "cmdline", buffer);
++	mpsslog("%s: Command line: \"%s\"\n", mic->name, buffer);
++	snprintf(buffer, PATH_MAX, "172.31.%d.1", mic->id + 1);
++	mpsslog("%s: IPADDR: \"%s\"\n", mic->name, buffer);
++}
++
++static void
++set_log_buf_info(struct mic_info *mic)
++{
++	int fd;
++	off_t len;
++	char system_map[] = "/lib/firmware/mic/System.map";
++	char *map, *temp, log_buf[17] = {'\0'};
++
++	fd = open(system_map, O_RDONLY);
++	if (fd < 0) {
++		mpsslog("%s: Opening System.map failed: %d\n",
++			mic->name, errno);
++		return;
++	}
++	len = lseek(fd, 0, SEEK_END);
++	if (len < 0) {
++		mpsslog("%s: Reading System.map size failed: %d\n",
++			mic->name, errno);
++		close(fd);
++		return;
++	}
++	map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
++	if (map == MAP_FAILED) {
++		mpsslog("%s: mmap of System.map failed: %d\n",
++			mic->name, errno);
++		close(fd);
++		return;
++	}
++	temp = strstr(map, "__log_buf");
++	if (!temp) {
++		mpsslog("%s: __log_buf not found: %d\n", mic->name, errno);
++		munmap(map, len);
++		close(fd);
++		return;
++	}
++	strncpy(log_buf, temp - 19, 16);
++	setsysfs(mic->name, "log_buf_addr", log_buf);
++	mpsslog("%s: log_buf_addr: %s\n", mic->name, log_buf);
++	temp = strstr(map, "log_buf_len");
++	if (!temp) {
++		mpsslog("%s: log_buf_len not found: %d\n", mic->name, errno);
++		munmap(map, len);
++		close(fd);
++		return;
++	}
++	strncpy(log_buf, temp - 19, 16);
++	setsysfs(mic->name, "log_buf_len", log_buf);
++	mpsslog("%s: log_buf_len: %s\n", mic->name, log_buf);
++	munmap(map, len);
++	close(fd);
++}
++
++static void
++change_virtblk_backend(int x, siginfo_t *siginfo, void *p)
++{
++	struct mic_info *mic;
++
++	for (mic = mic_list.next; mic != NULL; mic = mic->next)
++		mic->mic_virtblk.signaled = 1/* true */;
++}
++
++static void
++set_mic_boot_params(struct mic_info *mic)
++{
++	set_log_buf_info(mic);
++	set_cmdline(mic);
++}
++
++static void *
++init_mic(void *arg)
++{
++	struct mic_info *mic = (struct mic_info *)arg;
++	struct sigaction ignore = {
++		.sa_flags = 0,
++		.sa_handler = SIG_IGN
++	};
++	struct sigaction act = {
++		.sa_flags = SA_SIGINFO,
++		.sa_sigaction = change_virtblk_backend,
++	};
++	char buffer[PATH_MAX];
++	int err, fd;
++
++	/*
++	 * Currently, one virtio block device is supported for each MIC card
++	 * at a time. Any user (or test) can send a SIGUSR1 to the MIC daemon.
++	 * The signal informs the virtio block backend about a change in the
++	 * configuration file which specifies the virtio backend file name on
++	 * the host. Virtio block backend then re-reads the configuration file
++	 * and switches to the new block device. This signalling mechanism may
++	 * not be required once multiple virtio block devices are supported by
++	 * the MIC daemon.
++	 */
++	sigaction(SIGUSR1, &ignore, NULL);
++retry:
++	fd = open_state_fd(mic);
++	if (fd < 0) {
++		mpsslog("%s: %s %d open state fd failed %s\n",
++			mic->name, __func__, __LINE__, strerror(errno));
++		sleep(2);
++		goto retry;
++	}
++
++	if (mic->restart) {
++		snprintf(buffer, PATH_MAX, "boot");
++		setsysfs(mic->name, "state", buffer);
++		mpsslog("%s restarting mic %d\n",
++			mic->name, mic->restart);
++		mic->restart = 0;
++	}
++
++	while (1) {
++		while (block_till_state_change(fd, mic)) {
++			mpsslog("%s: %s %d block_till_state_change error %s\n",
++				mic->name, __func__, __LINE__, strerror(errno));
++			sleep(2);
++			continue;
++		}
++
++		if (get_mic_state(mic) == MIC_BOOTING)
++			break;
++	}
++
++	mic->pid = fork();
++	switch (mic->pid) {
++	case 0:
++		add_virtio_device(mic, &virtcons_dev_page.dd);
++		add_virtio_device(mic, &virtnet_dev_page.dd);
++		err = pthread_create(&mic->mic_console.console_thread, NULL,
++			virtio_console, mic);
++		if (err)
++			mpsslog("%s virtcons pthread_create failed %s\n",
++				mic->name, strerror(err));
++		err = pthread_create(&mic->mic_net.net_thread, NULL,
++			virtio_net, mic);
++		if (err)
++			mpsslog("%s virtnet pthread_create failed %s\n",
++				mic->name, strerror(err));
++		err = pthread_create(&mic->mic_virtblk.block_thread, NULL,
++			virtio_block, mic);
++		if (err)
++			mpsslog("%s virtblk pthread_create failed %s\n",
++				mic->name, strerror(err));
++		sigemptyset(&act.sa_mask);
++		err = sigaction(SIGUSR1, &act, NULL);
++		if (err)
++			mpsslog("%s sigaction SIGUSR1 failed %s\n",
++				mic->name, strerror(errno));
++		while (1)
++			sleep(60);
++	case -1:
++		mpsslog("fork failed MIC name %s id %d errno %d\n",
++			mic->name, mic->id, errno);
++		break;
++	default:
++		err = pthread_create(&mic->config_thread, NULL,
++				     mic_config, mic);
++		if (err)
++			mpsslog("%s mic_config pthread_create failed %s\n",
++				mic->name, strerror(err));
++	}
++
++	return NULL;
++}
++
++static void
++start_daemon(void)
++{
++	struct mic_info *mic;
++	int err;
++
++	for (mic = mic_list.next; mic; mic = mic->next) {
++		set_mic_boot_params(mic);
++		err = pthread_create(&mic->init_thread, NULL, init_mic, mic);
++		if (err)
++			mpsslog("%s init_mic pthread_create failed %s\n",
++				mic->name, strerror(err));
++	}
++
++	while (1)
++		sleep(60);
++}
++
++static int
++init_mic_list(void)
++{
++	struct mic_info *mic = &mic_list;
++	struct dirent *file;
++	DIR *dp;
++	int cnt = 0;
++
++	dp = opendir(MICSYSFSDIR);
++	if (!dp)
++		return 0;
++
++	while ((file = readdir(dp)) != NULL) {
++		if (!strncmp(file->d_name, "mic", 3)) {
++			mic->next = calloc(1, sizeof(struct mic_info));
++			if (mic->next) {
++				mic = mic->next;
++				mic->id = atoi(&file->d_name[3]);
++				mic->name = malloc(strlen(file->d_name) + 16);
++				if (mic->name)
++					strcpy(mic->name, file->d_name);
++				mpsslog("MIC name %s id %d\n", mic->name,
++					mic->id);
++				cnt++;
++			}
++		}
++	}
++
++	closedir(dp);
++	return cnt;
++}
++
++void
++mpsslog(char *format, ...)
++{
++	va_list args;
++	char buffer[4096];
++	char ts[52], *ts1;
++	time_t t;
++
++	if (logfp == NULL)
++		return;
++
++	va_start(args, format);
++	vsprintf(buffer, format, args);
++	va_end(args);
++
++	time(&t);
++	ts1 = ctime_r(&t, ts);
++	ts1[strlen(ts1) - 1] = '\0';
++	fprintf(logfp, "%s: %s", ts1, buffer);
++
++	fflush(logfp);
++}
++
++int
++main(int argc, char *argv[])
++{
++	int cnt;
++	pid_t pid;
++
++	myname = argv[0];
++
++	logfp = fopen(LOGFILE_NAME, "a+");
++	if (!logfp) {
++		fprintf(stderr, "cannot open logfile '%s'\n", LOGFILE_NAME);
++		exit(1);
++	}
++	pid = fork();
++	switch (pid) {
++	case 0:
++		break;
++	case -1:
++		exit(2);
++	default:
++		exit(0);
++	}
++
++	mpsslog("MIC Daemon start\n");
++
++	cnt = init_mic_list();
++	if (cnt == 0) {
++		mpsslog("MIC module not loaded\n");
++		exit(3);
++	}
++	mpsslog("MIC found %d devices\n", cnt);
++
++	start_daemon();
++
++	exit(0);
++}
+diff --git a/samples/mic/mpssd/mpssd.h b/samples/mic/mpssd/mpssd.h
+new file mode 100644
+index 000000000000..8bd64944aacc
+--- /dev/null
++++ b/samples/mic/mpssd/mpssd.h
+@@ -0,0 +1,103 @@
++/*
++ * Intel MIC Platform Software Stack (MPSS)
++ *
++ * Copyright(c) 2013 Intel Corporation.
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * The full GNU General Public License is included in this distribution in
++ * the file called "COPYING".
++ *
++ * Intel MIC User Space Tools.
++ */
++#ifndef _MPSSD_H_
++#define _MPSSD_H_
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <fcntl.h>
++#include <unistd.h>
++#include <dirent.h>
++#include <libgen.h>
++#include <pthread.h>
++#include <stdarg.h>
++#include <time.h>
++#include <errno.h>
++#include <sys/dir.h>
++#include <sys/ioctl.h>
++#include <sys/poll.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <sys/mman.h>
++#include <sys/utsname.h>
++#include <sys/wait.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#include <netdb.h>
++#include <pthread.h>
++#include <signal.h>
++#include <limits.h>
++#include <syslog.h>
++#include <getopt.h>
++#include <net/if.h>
++#include <linux/if_tun.h>
++#include <linux/if_tun.h>
++#include <linux/virtio_ids.h>
++
++#define MICSYSFSDIR "/sys/class/mic"
++#define LOGFILE_NAME "/var/log/mpssd"
++#define PAGE_SIZE 4096
++
++struct mic_console_info {
++	pthread_t       console_thread;
++	int		virtio_console_fd;
++	void		*console_dp;
++};
++
++struct mic_net_info {
++	pthread_t       net_thread;
++	int		virtio_net_fd;
++	int		tap_fd;
++	void		*net_dp;
++};
++
++struct mic_virtblk_info {
++	pthread_t       block_thread;
++	int		virtio_block_fd;
++	void		*block_dp;
++	volatile sig_atomic_t	signaled;
++	char		*backend_file;
++	int		backend;
++	void		*backend_addr;
++	long		backend_size;
++};
++
++struct mic_info {
++	int		id;
++	char		*name;
++	pthread_t       config_thread;
++	pthread_t       init_thread;
++	pid_t		pid;
++	struct mic_console_info	mic_console;
++	struct mic_net_info	mic_net;
++	struct mic_virtblk_info	mic_virtblk;
++	int		restart;
++	int		boot_on_resume;
++	struct mic_info *next;
++};
++
++__attribute__((format(printf, 1, 2)))
++void mpsslog(char *format, ...);
++char *readsysfs(char *dir, char *entry);
++int setsysfs(char *dir, char *entry, char *value);
++#endif
+diff --git a/samples/mic/mpssd/sysfs.c b/samples/mic/mpssd/sysfs.c
+new file mode 100644
+index 000000000000..8dd326936083
+--- /dev/null
++++ b/samples/mic/mpssd/sysfs.c
+@@ -0,0 +1,102 @@
++/*
++ * Intel MIC Platform Software Stack (MPSS)
++ *
++ * Copyright(c) 2013 Intel Corporation.
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * The full GNU General Public License is included in this distribution in
++ * the file called "COPYING".
++ *
++ * Intel MIC User Space Tools.
++ */
++
++#include "mpssd.h"
++
++#define PAGE_SIZE 4096
++
++char *
++readsysfs(char *dir, char *entry)
++{
++	char filename[PATH_MAX];
++	char value[PAGE_SIZE];
++	char *string = NULL;
++	int fd;
++	int len;
++
++	if (dir == NULL)
++		snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
++	else
++		snprintf(filename, PATH_MAX,
++			 "%s/%s/%s", MICSYSFSDIR, dir, entry);
++
++	fd = open(filename, O_RDONLY);
++	if (fd < 0) {
++		mpsslog("Failed to open sysfs entry '%s': %s\n",
++			filename, strerror(errno));
++		return NULL;
++	}
++
++	len = read(fd, value, sizeof(value));
++	if (len < 0) {
++		mpsslog("Failed to read sysfs entry '%s': %s\n",
++			filename, strerror(errno));
++		goto readsys_ret;
++	}
++	if (len == 0)
++		goto readsys_ret;
++
++	value[len - 1] = '\0';
++
++	string = malloc(strlen(value) + 1);
++	if (string)
++		strcpy(string, value);
++
++readsys_ret:
++	close(fd);
++	return string;
++}
++
++int
++setsysfs(char *dir, char *entry, char *value)
++{
++	char filename[PATH_MAX];
++	char *oldvalue;
++	int fd, ret = 0;
++
++	if (dir == NULL)
++		snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
++	else
++		snprintf(filename, PATH_MAX, "%s/%s/%s",
++			 MICSYSFSDIR, dir, entry);
++
++	oldvalue = readsysfs(dir, entry);
++
++	fd = open(filename, O_RDWR);
++	if (fd < 0) {
++		ret = errno;
++		mpsslog("Failed to open sysfs entry '%s': %s\n",
++			filename, strerror(errno));
++		goto done;
++	}
++
++	if (!oldvalue || strcmp(value, oldvalue)) {
++		if (write(fd, value, strlen(value)) < 0) {
++			ret = errno;
++			mpsslog("Failed to write new sysfs entry '%s': %s\n",
++				filename, strerror(errno));
++		}
++	}
++	close(fd);
++done:
++	if (oldvalue)
++		free(oldvalue);
++	return ret;
++}
+diff --git a/samples/seccomp/bpf-helper.h b/samples/seccomp/bpf-helper.h
+index 38ee70f3cd5b..1d8de9edd858 100644
+--- a/samples/seccomp/bpf-helper.h
++++ b/samples/seccomp/bpf-helper.h
+@@ -138,7 +138,7 @@ union arg64 {
+ #define ARG_32(idx) \
+ 	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx))
+ 
+-/* Loads hi into A and lo in X */
++/* Loads lo into M[0] and hi into M[1] and A */
+ #define ARG_64(idx) \
+ 	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx)), \
+ 	BPF_STMT(BPF_ST, 0), /* lo -> M[0] */ \
+@@ -153,88 +153,107 @@ union arg64 {
+ 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 1, 0), \
+ 	jt
+ 
+-/* Checks the lo, then swaps to check the hi. A=lo,X=hi */
++#define JA32(value, jt) \
++	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
++	jt
++
++#define JGE32(value, jt) \
++	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
++	jt
++
++#define JGT32(value, jt) \
++	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
++	jt
++
++#define JLE32(value, jt) \
++	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
++	jt
++
++#define JLT32(value, jt) \
++	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
++	jt
++
++/*
++ * All the JXX64 checks assume lo is saved in M[0] and hi is saved in both
++ * A and M[1]. This invariant is kept by restoring A if necessary.
++ */
+ #define JEQ64(lo, hi, jt) \
++	/* if (hi != arg.hi) goto NOMATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+ 	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++	/* if (lo != arg.lo) goto NOMATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 0, 2), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++	BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ 	jt, \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++	BPF_STMT(BPF_LD+BPF_MEM, 1)
+ 
+ #define JNE64(lo, hi, jt) \
+-	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 5, 0), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++	/* if (hi != arg.hi) goto MATCH; */ \
++	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
++	BPF_STMT(BPF_LD+BPF_MEM, 0), \
++	/* if (lo != arg.lo) goto MATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 2, 0), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++	BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ 	jt, \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+-
+-#define JA32(value, jt) \
+-	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
+-	jt
++	BPF_STMT(BPF_LD+BPF_MEM, 1)
+ 
+ #define JA64(lo, hi, jt) \
++	/* if (hi & arg.hi) goto MATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (hi), 3, 0), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++	BPF_STMT(BPF_LD+BPF_MEM, 0), \
++	/* if (lo & arg.lo) goto MATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (lo), 0, 2), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++	BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ 	jt, \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++	BPF_STMT(BPF_LD+BPF_MEM, 1)
+ 
+-#define JGE32(value, jt) \
+-	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
+-	jt
+-
+-#define JLT32(value, jt) \
+-	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
+-	jt
+-
+-/* Shortcut checking if hi > arg.hi. */
+ #define JGE64(lo, hi, jt) \
++	/* if (hi > arg.hi) goto MATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
++	/* if (hi != arg.hi) goto NOMATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++	BPF_STMT(BPF_LD+BPF_MEM, 0), \
++	/* if (lo >= arg.lo) goto MATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 0, 2), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+-	jt, \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+-
+-#define JLT64(lo, hi, jt) \
+-	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
+-	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+-	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++	BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ 	jt, \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++	BPF_STMT(BPF_LD+BPF_MEM, 1)
+ 
+-#define JGT32(value, jt) \
+-	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
+-	jt
+-
+-#define JLE32(value, jt) \
+-	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
+-	jt
+-
+-/* Check hi > args.hi first, then do the GE checking */
+ #define JGT64(lo, hi, jt) \
++	/* if (hi > arg.hi) goto MATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
++	/* if (hi != arg.hi) goto NOMATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++	BPF_STMT(BPF_LD+BPF_MEM, 0), \
++	/* if (lo > arg.lo) goto MATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 0, 2), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++	BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ 	jt, \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++	BPF_STMT(BPF_LD+BPF_MEM, 1)
+ 
+ #define JLE64(lo, hi, jt) \
+-	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 6, 0), \
+-	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++	/* if (hi < arg.hi) goto MATCH; */ \
++	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
++	/* if (hi != arg.hi) goto NOMATCH; */ \
++	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
++	BPF_STMT(BPF_LD+BPF_MEM, 0), \
++	/* if (lo <= arg.lo) goto MATCH; */ \
+ 	BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++	BPF_STMT(BPF_LD+BPF_MEM, 1), \
++	jt, \
++	BPF_STMT(BPF_LD+BPF_MEM, 1)
++
++#define JLT64(lo, hi, jt) \
++	/* if (hi < arg.hi) goto MATCH; */ \
++	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
++	/* if (hi != arg.hi) goto NOMATCH; */ \
++	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
++	BPF_STMT(BPF_LD+BPF_MEM, 0), \
++	/* if (lo < arg.lo) goto MATCH; */ \
++	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 2, 0), \
++	BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ 	jt, \
+-	BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++	BPF_STMT(BPF_LD+BPF_MEM, 1)
+ 
+ #define LOAD_SYSCALL_NR \
+ 	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
+diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
+index 1d5acbe0c08b..86240d02b530 100644
+--- a/sound/core/seq/seq_fifo.c
++++ b/sound/core/seq/seq_fifo.c
+@@ -135,6 +135,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
+ 	f->tail = cell;
+ 	if (f->head == NULL)
+ 		f->head = cell;
++	cell->next = NULL;
+ 	f->cells++;
+ 	spin_unlock_irqrestore(&f->lock, flags);
+ 
+@@ -214,6 +215,8 @@ void snd_seq_fifo_cell_putback(struct snd_seq_fifo *f,
+ 		spin_lock_irqsave(&f->lock, flags);
+ 		cell->next = f->head;
+ 		f->head = cell;
++		if (!f->tail)
++			f->tail = cell;
+ 		f->cells++;
+ 		spin_unlock_irqrestore(&f->lock, flags);
+ 	}
+diff --git a/sound/core/timer.c b/sound/core/timer.c
+index ae4ea2e2e7fe..278a332f97bd 100644
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -1700,9 +1700,21 @@ static int snd_timer_user_params(struct file *file,
+ 		return -EBADFD;
+ 	if (copy_from_user(&params, _params, sizeof(params)))
+ 		return -EFAULT;
+-	if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) {
+-		err = -EINVAL;
+-		goto _end;
++	if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
++		u64 resolution;
++
++		if (params.ticks < 1) {
++			err = -EINVAL;
++			goto _end;
++		}
++
++		/* Don't allow resolution less than 1ms */
++		resolution = snd_timer_resolution(tu->timeri);
++		resolution *= params.ticks;
++		if (resolution < 1000000) {
++			err = -EINVAL;
++			goto _end;
++		}
+ 	}
+ 	if (params.queue_size > 0 &&
+ 	    (params.queue_size < 32 || params.queue_size > 1024)) {
+diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
+index 9667cbfb0ca2..ab4cdab5cfa5 100644
+--- a/sound/pci/ctxfi/cthw20k1.c
++++ b/sound/pci/ctxfi/cthw20k1.c
+@@ -27,12 +27,6 @@
+ #include "cthw20k1.h"
+ #include "ct20k1reg.h"
+ 
+-#if BITS_PER_LONG == 32
+-#define CT_XFI_DMA_MASK		DMA_BIT_MASK(32) /* 32 bit PTE */
+-#else
+-#define CT_XFI_DMA_MASK		DMA_BIT_MASK(64) /* 64 bit PTE */
+-#endif
+-
+ struct hw20k1 {
+ 	struct hw hw;
+ 	spinlock_t reg_20k1_lock;
+@@ -1904,19 +1898,18 @@ static int hw_card_start(struct hw *hw)
+ {
+ 	int err;
+ 	struct pci_dev *pci = hw->pci;
++	const unsigned int dma_bits = BITS_PER_LONG;
+ 
+ 	err = pci_enable_device(pci);
+ 	if (err < 0)
+ 		return err;
+ 
+ 	/* Set DMA transfer mask */
+-	if (dma_set_mask(&pci->dev, CT_XFI_DMA_MASK) < 0 ||
+-	    dma_set_coherent_mask(&pci->dev, CT_XFI_DMA_MASK) < 0) {
+-		dev_err(hw->card->dev,
+-			"architecture does not support PCI busmaster DMA with mask 0x%llx\n",
+-			CT_XFI_DMA_MASK);
+-		err = -ENXIO;
+-		goto error1;
++	if (dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
++		dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits));
++	} else {
++		dma_set_mask(&pci->dev, DMA_BIT_MASK(32));
++		dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32));
+ 	}
+ 
+ 	if (!hw->io_base) {
+diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
+index 9dc2950e1ab7..d86678c2a957 100644
+--- a/sound/pci/ctxfi/cthw20k2.c
++++ b/sound/pci/ctxfi/cthw20k2.c
+@@ -26,12 +26,6 @@
+ #include "cthw20k2.h"
+ #include "ct20k2reg.h"
+ 
+-#if BITS_PER_LONG == 32
+-#define CT_XFI_DMA_MASK		DMA_BIT_MASK(32) /* 32 bit PTE */
+-#else
+-#define CT_XFI_DMA_MASK		DMA_BIT_MASK(64) /* 64 bit PTE */
+-#endif
+-
+ struct hw20k2 {
+ 	struct hw hw;
+ 	/* for i2c */
+@@ -2029,19 +2023,18 @@ static int hw_card_start(struct hw *hw)
+ 	int err = 0;
+ 	struct pci_dev *pci = hw->pci;
+ 	unsigned int gctl;
++	const unsigned int dma_bits = BITS_PER_LONG;
+ 
+ 	err = pci_enable_device(pci);
+ 	if (err < 0)
+ 		return err;
+ 
+ 	/* Set DMA transfer mask */
+-	if (dma_set_mask(&pci->dev, CT_XFI_DMA_MASK) < 0 ||
+-	    dma_set_coherent_mask(&pci->dev, CT_XFI_DMA_MASK) < 0) {
+-		dev_err(hw->card->dev,
+-			"architecture does not support PCI busmaster DMA with mask 0x%llx\n",
+-			CT_XFI_DMA_MASK);
+-		err = -ENXIO;
+-		goto error1;
++	if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
++		dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits));
++	} else {
++		dma_set_mask(&pci->dev, DMA_BIT_MASK(32));
++		dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32));
+ 	}
+ 
+ 	if (!hw->io_base) {
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index ad4a1e9a3ae1..8f3e5e9d8bdb 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2208,9 +2208,9 @@ static const struct pci_device_id azx_ids[] = {
+ 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
+ 	/* Lewisburg */
+ 	{ PCI_DEVICE(0x8086, 0xa1f0),
+-	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
++	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+ 	{ PCI_DEVICE(0x8086, 0xa270),
+-	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
++	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+ 	/* Lynx Point-LP */
+ 	{ PCI_DEVICE(0x8086, 0x9c20),
+ 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 00c50d58f108..cf0785ddbd14 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5560,6 +5560,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
+ 	SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
+ 	SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
++	SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
+ 	SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
+@@ -5674,6 +5675,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
+ 	SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
+ 	SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
++	SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
+ 	SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
+ 	SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
+ 	SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
+@@ -6047,6 +6049,12 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ 	SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		ALC298_STANDARD_PINS,
+ 		{0x17, 0x90170150}),
++	SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
++		{0x12, 0xb7a60140},
++		{0x13, 0xb7a60150},
++		{0x17, 0x90170110},
++		{0x1a, 0x03011020},
++		{0x21, 0x03211030}),
+ 	{}
+ };
+ 


             reply	other threads:[~2017-03-12 12:17 UTC|newest]

Thread overview: 355+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-12 12:17 Mike Pagano [this message]
  -- strict thread matches above, loose matches on Subject: below --
2022-02-03 11:46 [gentoo-commits] proj/linux-patches:4.4 commit in: / Mike Pagano
2022-01-29 17:47 Mike Pagano
2022-01-27 11:42 Mike Pagano
2022-01-11 12:57 Mike Pagano
2022-01-05 12:57 Mike Pagano
2021-12-29 13:13 Mike Pagano
2021-12-22 14:09 Mike Pagano
2021-12-14 10:38 Mike Pagano
2021-12-08 12:58 Mike Pagano
2021-11-26 12:02 Mike Pagano
2021-11-12 13:39 Mike Pagano
2021-11-02 17:07 Mike Pagano
2021-10-27 12:01 Mike Pagano
2021-10-17 13:15 Mike Pagano
2021-10-09 21:36 Mike Pagano
2021-10-07 10:37 Mike Pagano
2021-10-06 11:33 Mike Pagano
2021-09-26 14:16 Mike Pagano
2021-09-22 11:43 Mike Pagano
2021-09-20 22:07 Mike Pagano
2021-09-03 11:26 Mike Pagano
2021-08-26 14:02 Mike Pagano
2021-08-25 23:20 Mike Pagano
2021-08-15 20:12 Mike Pagano
2021-08-10 16:22 Mike Pagano
2021-08-08 13:47 Mike Pagano
2021-08-04 11:56 Mike Pagano
2021-08-03 12:51 Mike Pagano
2021-07-28 12:39 Mike Pagano
2021-07-20 15:17 Alice Ferrazzi
2021-07-11 14:48 Mike Pagano
2021-06-30 14:29 Mike Pagano
2021-06-17 11:05 Alice Ferrazzi
2021-06-10 11:09 Mike Pagano
2021-06-03 10:43 Alice Ferrazzi
2021-05-26 11:59 Mike Pagano
2021-05-22 10:00 Mike Pagano
2021-04-28 11:08 Alice Ferrazzi
2021-04-16 11:20 Alice Ferrazzi
2021-04-10 13:21 Mike Pagano
2021-04-07 12:10 Mike Pagano
2021-03-30 14:13 Mike Pagano
2021-03-24 12:06 Mike Pagano
2021-03-17 15:39 Mike Pagano
2021-03-11 13:34 Mike Pagano
2021-03-07 15:12 Mike Pagano
2021-03-03 16:34 Alice Ferrazzi
2021-02-23 13:46 Mike Pagano
2021-02-10 10:17 Alice Ferrazzi
2021-02-05 14:57 Alice Ferrazzi
2021-02-03 23:23 Mike Pagano
2021-01-30 13:11 Alice Ferrazzi
2021-01-23 16:33 Mike Pagano
2021-01-17 16:23 Mike Pagano
2021-01-12 20:08 Mike Pagano
2021-01-09 12:53 Mike Pagano
2020-12-29 14:16 Mike Pagano
2020-12-11 12:54 Mike Pagano
2020-12-02 12:17 Mike Pagano
2020-11-24 13:29 Mike Pagano
2020-11-22 19:08 Mike Pagano
2020-11-18 19:21 Mike Pagano
2020-11-11 15:27 Mike Pagano
2020-11-10 13:53 Mike Pagano
2020-10-29 11:14 Mike Pagano
2020-10-17 10:13 Mike Pagano
2020-10-14 20:30 Mike Pagano
2020-10-01 11:41 Mike Pagano
2020-10-01 11:24 Mike Pagano
2020-09-24 16:04 Mike Pagano
2020-09-23 11:51 Mike Pagano
2020-09-23 11:50 Mike Pagano
2020-09-12 17:08 Mike Pagano
2020-09-03 11:32 Mike Pagano
2020-08-26 11:12 Mike Pagano
2020-08-21 11:11 Alice Ferrazzi
2020-07-31 16:10 Mike Pagano
2020-07-22 12:24 Mike Pagano
2020-07-09 12:05 Mike Pagano
2020-07-01 12:09 Mike Pagano
2020-06-22 14:43 Mike Pagano
2020-06-11 11:25 Mike Pagano
2020-06-03 11:35 Mike Pagano
2020-05-27 15:26 Mike Pagano
2020-05-20 11:20 Mike Pagano
2020-05-13 13:01 Mike Pagano
2020-05-11 22:52 Mike Pagano
2020-05-05 17:37 Mike Pagano
2020-05-02 19:20 Mike Pagano
2020-04-24 11:59 Mike Pagano
2020-04-15 18:24 Mike Pagano
2020-04-13 11:14 Mike Pagano
2020-04-02 18:55 Mike Pagano
2020-03-20 11:53 Mike Pagano
2020-03-20 11:51 Mike Pagano
2020-03-20 11:49 Mike Pagano
2020-03-11 10:14 Mike Pagano
2020-02-28 15:24 Mike Pagano
2020-02-14 23:34 Mike Pagano
2020-02-05 14:47 Mike Pagano
2020-01-29 12:36 Mike Pagano
2020-01-23 11:00 Mike Pagano
2020-01-14 22:24 Mike Pagano
2020-01-12 14:48 Mike Pagano
2020-01-04 16:46 Mike Pagano
2019-12-21 14:51 Mike Pagano
2019-12-05 14:47 Alice Ferrazzi
2019-11-29 21:41 Thomas Deutschmann
2019-11-28 23:49 Mike Pagano
2019-11-25 16:25 Mike Pagano
2019-11-16 10:54 Mike Pagano
2019-11-12 20:57 Mike Pagano
2019-11-10 16:13 Mike Pagano
2019-11-06 14:22 Mike Pagano
2019-10-29 10:08 Mike Pagano
2019-10-17 22:18 Mike Pagano
2019-10-07 21:03 Mike Pagano
2019-10-05 20:43 Mike Pagano
2019-09-21 15:56 Mike Pagano
2019-09-20 15:50 Mike Pagano
2019-09-16 12:21 Mike Pagano
2019-09-10 11:10 Mike Pagano
2019-09-06 17:17 Mike Pagano
2019-08-25 17:33 Mike Pagano
2019-08-11 10:58 Mike Pagano
2019-08-06 19:14 Mike Pagano
2019-08-04 16:03 Mike Pagano
2019-07-21 14:36 Mike Pagano
2019-07-10 11:01 Mike Pagano
2019-06-27 11:11 Mike Pagano
2019-06-22 19:01 Mike Pagano
2019-06-17 19:18 Mike Pagano
2019-06-11 17:30 Mike Pagano
2019-06-11 12:38 Mike Pagano
2019-05-16 23:01 Mike Pagano
2019-04-27 17:28 Mike Pagano
2019-04-03 10:49 Mike Pagano
2019-04-03 10:49 Mike Pagano
2019-03-23 14:17 Mike Pagano
2019-02-23 14:40 Mike Pagano
2019-02-20 11:14 Mike Pagano
2019-02-15 23:38 Mike Pagano
2019-02-15 23:35 Mike Pagano
2019-02-08 15:21 Mike Pagano
2019-02-06 20:51 Mike Pagano
2019-02-06  0:05 Mike Pagano
2019-01-26 14:59 Mike Pagano
2019-01-16 23:27 Mike Pagano
2019-01-13 19:46 Mike Pagano
2019-01-13 19:24 Mike Pagano
2018-12-29 22:56 Mike Pagano
2018-12-21 14:40 Mike Pagano
2018-12-17 21:56 Mike Pagano
2018-12-13 11:35 Mike Pagano
2018-12-01 18:35 Mike Pagano
2018-12-01 15:02 Mike Pagano
2018-11-27 16:59 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 12:18 Mike Pagano
2018-11-10 21:27 Mike Pagano
2018-10-20 12:33 Mike Pagano
2018-10-13 16:35 Mike Pagano
2018-10-10 11:20 Mike Pagano
2018-09-29 13:32 Mike Pagano
2018-09-26 10:44 Mike Pagano
2018-09-19 22:37 Mike Pagano
2018-09-15 10:09 Mike Pagano
2018-09-09 23:26 Mike Pagano
2018-09-05 15:21 Mike Pagano
2018-08-28 22:32 Mike Pagano
2018-08-24 11:41 Mike Pagano
2018-08-22 10:08 Alice Ferrazzi
2018-08-18 18:06 Mike Pagano
2018-08-17 19:24 Mike Pagano
2018-08-15 16:44 Mike Pagano
2018-08-09 10:49 Mike Pagano
2018-08-07 18:14 Mike Pagano
2018-07-28 10:37 Mike Pagano
2018-07-22 15:15 Mike Pagano
2018-07-19 15:27 Mike Pagano
2018-07-17 10:24 Mike Pagano
2018-07-12 16:21 Alice Ferrazzi
2018-07-04 14:26 Mike Pagano
2018-06-16 15:41 Mike Pagano
2018-06-13 14:54 Mike Pagano
2018-06-06 18:00 Mike Pagano
2018-05-30 22:35 Mike Pagano
2018-05-30 11:38 Mike Pagano
2018-05-26 13:43 Mike Pagano
2018-05-16 10:22 Mike Pagano
2018-05-02 16:11 Mike Pagano
2018-04-29 11:48 Mike Pagano
2018-04-24 11:28 Mike Pagano
2018-04-13 22:20 Mike Pagano
2018-04-08 14:25 Mike Pagano
2018-03-31 23:00 Mike Pagano
2018-03-31 22:16 Mike Pagano
2018-03-25 13:42 Mike Pagano
2018-03-22 12:54 Mike Pagano
2018-03-11 18:25 Mike Pagano
2018-03-05  2:52 Alice Ferrazzi
2018-02-28 15:05 Alice Ferrazzi
2018-02-25 15:46 Mike Pagano
2018-02-22 23:20 Mike Pagano
2018-02-17 15:10 Alice Ferrazzi
2018-02-03 21:23 Mike Pagano
2018-01-31 13:36 Alice Ferrazzi
2018-01-23 21:15 Mike Pagano
2018-01-17 10:20 Alice Ferrazzi
2018-01-17  9:18 Alice Ferrazzi
2018-01-15 15:01 Alice Ferrazzi
2018-01-10 11:56 Mike Pagano
2018-01-10 11:48 Mike Pagano
2018-01-05 15:59 Alice Ferrazzi
2018-01-05 15:05 Alice Ferrazzi
2018-01-02 20:12 Mike Pagano
2017-12-25 14:41 Alice Ferrazzi
2017-12-20 12:45 Mike Pagano
2017-12-16 11:46 Alice Ferrazzi
2017-12-09 18:50 Alice Ferrazzi
2017-12-05 11:39 Mike Pagano
2017-11-30 12:25 Alice Ferrazzi
2017-11-24 10:49 Alice Ferrazzi
2017-11-24  9:46 Alice Ferrazzi
2017-11-21  8:40 Alice Ferrazzi
2017-11-18 18:12 Mike Pagano
2017-11-15 16:44 Alice Ferrazzi
2017-11-08 13:50 Mike Pagano
2017-11-02 10:02 Mike Pagano
2017-10-27 10:33 Mike Pagano
2017-10-21 20:13 Mike Pagano
2017-10-18 13:44 Mike Pagano
2017-10-12 12:22 Mike Pagano
2017-10-08 14:25 Mike Pagano
2017-10-05 11:39 Mike Pagano
2017-09-27 10:38 Mike Pagano
2017-09-14 13:37 Mike Pagano
2017-09-13 22:26 Mike Pagano
2017-09-13 14:33 Mike Pagano
2017-09-07 22:42 Mike Pagano
2017-09-02 17:14 Mike Pagano
2017-08-30 10:08 Mike Pagano
2017-08-25 10:53 Mike Pagano
2017-08-16 22:30 Mike Pagano
2017-08-13 16:52 Mike Pagano
2017-08-11 17:44 Mike Pagano
2017-08-07 10:25 Mike Pagano
2017-05-14 13:32 Mike Pagano
2017-05-08 10:40 Mike Pagano
2017-05-03 17:41 Mike Pagano
2017-04-30 18:08 Mike Pagano
2017-04-30 17:59 Mike Pagano
2017-04-27  8:18 Alice Ferrazzi
2017-04-22 17:00 Mike Pagano
2017-04-18 10:21 Mike Pagano
2017-04-12 17:59 Mike Pagano
2017-04-08 13:56 Mike Pagano
2017-03-31 10:43 Mike Pagano
2017-03-30 18:16 Mike Pagano
2017-03-26 11:53 Mike Pagano
2017-03-22 12:28 Mike Pagano
2017-03-18 14:32 Mike Pagano
2017-03-15 14:39 Mike Pagano
2017-03-02 16:29 Mike Pagano
2017-03-02 16:29 Mike Pagano
2017-02-26 20:45 Mike Pagano
2017-02-24  0:38 Mike Pagano
2017-02-23 20:12 Mike Pagano
2017-02-18 16:27 Alice Ferrazzi
2017-02-15 16:22 Alice Ferrazzi
2017-02-09  8:05 Alice Ferrazzi
2017-02-04 13:47 Alice Ferrazzi
2017-02-01 12:59 Alice Ferrazzi
2017-01-26  8:24 Alice Ferrazzi
2017-01-20 12:45 Alice Ferrazzi
2017-01-15 22:57 Mike Pagano
2017-01-14 14:46 Mike Pagano
2017-01-12 12:11 Mike Pagano
2017-01-09 12:46 Mike Pagano
2017-01-06 23:13 Mike Pagano
2016-12-15 23:41 Mike Pagano
2016-12-11 15:02 Alice Ferrazzi
2016-12-09 13:57 Alice Ferrazzi
2016-12-08  0:03 Mike Pagano
2016-12-02 16:21 Mike Pagano
2016-11-26 18:51 Mike Pagano
2016-11-26 18:40 Mike Pagano
2016-11-22  0:14 Mike Pagano
2016-11-19 11:03 Mike Pagano
2016-11-15 10:05 Alice Ferrazzi
2016-11-10 18:13 Alice Ferrazzi
2016-11-01  3:14 Alice Ferrazzi
2016-10-31 14:09 Alice Ferrazzi
2016-10-28 18:27 Alice Ferrazzi
2016-10-22 13:05 Mike Pagano
2016-10-21 11:10 Mike Pagano
2016-10-16 19:25 Mike Pagano
2016-10-08 19:55 Mike Pagano
2016-09-30 19:07 Mike Pagano
2016-09-24 10:51 Mike Pagano
2016-09-16 19:10 Mike Pagano
2016-09-15 13:58 Mike Pagano
2016-09-09 19:20 Mike Pagano
2016-08-20 16:31 Mike Pagano
2016-08-17 11:48 Mike Pagano
2016-08-10 12:56 Mike Pagano
2016-07-27 19:19 Mike Pagano
2016-07-11 19:59 Mike Pagano
2016-07-02 15:30 Mike Pagano
2016-07-01  0:55 Mike Pagano
2016-06-24 20:40 Mike Pagano
2016-06-08 13:38 Mike Pagano
2016-06-02 18:24 Mike Pagano
2016-05-19 13:00 Mike Pagano
2016-05-12  0:14 Mike Pagano
2016-05-04 23:51 Mike Pagano
2016-04-20 11:27 Mike Pagano
2016-04-12 18:59 Mike Pagano
2016-03-22 22:47 Mike Pagano
2016-03-16 19:43 Mike Pagano
2016-03-10  0:51 Mike Pagano
2016-03-04 11:15 Mike Pagano
2016-02-26  0:02 Mike Pagano
2016-02-19 23:33 Mike Pagano
2016-02-18  0:20 Mike Pagano
2016-02-01  0:19 Mike Pagano
2016-02-01  0:13 Mike Pagano
2016-01-31 23:33 Mike Pagano
2016-01-20 12:38 Mike Pagano
2016-01-10 17:19 Mike Pagano

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1489321057.91367744ce5b3751a6e8288292d5d2692aaff55f.mpagano@gentoo \
    --to=mpagano@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

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

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