--- /dev/null
+From 4875a5f7218068cdeea5f998330dfa3d118b2fea Mon Sep 17 00:00:00 2001
+From: Hui Wang <hui.wang@canonical.com>
+Date: Tue, 11 Oct 2016 10:48:58 +0800
+Subject: ALSA: hda - Fix a failure of micmute led when having multi adcs
+
+From: Hui Wang <hui.wang@canonical.com>
+
+commit 4875a5f7218068cdeea5f998330dfa3d118b2fea upstream.
+
+On a Dell laptop, there is no global adcs for all input devices, so
+the input devices use the different adc, as a result, dyn_adc_switch
+is set to true.
+
+In this situation, it is safe to control the micmute led according to
+user's choice of muting/unmuting the current input device, since only
+current input device path is active, while other input device paths
+are inactive and powered down.
+
+Fixes: 00ef99408b6c ('ALSA: hda - add mic mute led hook for dell machines')
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/dell_wmi_helper.c | 2 +-
+ sound/pci/hda/thinkpad_helper.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/pci/hda/dell_wmi_helper.c
++++ b/sound/pci/hda/dell_wmi_helper.c
+@@ -49,7 +49,7 @@ static void alc_fixup_dell_wmi(struct hd
+ removefunc = true;
+ if (dell_led_set_func(DELL_LED_MICMUTE, false) >= 0) {
+ dell_led_value = 0;
+- if (spec->gen.num_adc_nids > 1)
++ if (spec->gen.num_adc_nids > 1 && !spec->gen.dyn_adc_switch)
+ codec_dbg(codec, "Skipping micmute LED control due to several ADCs");
+ else {
+ dell_old_cap_hook = spec->gen.cap_sync_hook;
+--- a/sound/pci/hda/thinkpad_helper.c
++++ b/sound/pci/hda/thinkpad_helper.c
+@@ -75,7 +75,7 @@ static void hda_fixup_thinkpad_acpi(stru
+ removefunc = false;
+ }
+ if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) {
+- if (spec->num_adc_nids > 1)
++ if (spec->num_adc_nids > 1 && !spec->dyn_adc_switch)
+ codec_dbg(codec,
+ "Skipping micmute LED control due to several ADCs");
+ else {
--- /dev/null
+From 1871d718a9db649b70f0929d2778dc01bc49b286 Mon Sep 17 00:00:00 2001
+From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+Date: Sun, 4 Sep 2016 09:56:33 -0300
+Subject: [media] cx231xx: don't return error on success
+
+From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+
+commit 1871d718a9db649b70f0929d2778dc01bc49b286 upstream.
+
+The cx231xx_set_agc_analog_digital_mux_select() callers
+expect it to return 0 or an error. Returning a positive value
+makes the first attempt to switch between analog/digital to fail.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/cx231xx/cx231xx-avcore.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/usb/cx231xx/cx231xx-avcore.c
++++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c
+@@ -1264,7 +1264,10 @@ int cx231xx_set_agc_analog_digital_mux_s
+ dev->board.agc_analog_digital_select_gpio,
+ analog_or_digital);
+
+- return status;
++ if (status < 0)
++ return status;
++
++ return 0;
+ }
+
+ int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3)
--- /dev/null
+From 24b923f073ac37eb744f56a2c7f77107b8219ab2 Mon Sep 17 00:00:00 2001
+From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+Date: Sun, 4 Sep 2016 10:06:39 -0300
+Subject: [media] cx231xx: fix GPIOs for Pixelview SBTVD hybrid
+
+From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+
+commit 24b923f073ac37eb744f56a2c7f77107b8219ab2 upstream.
+
+This device uses GPIOs: 28 to switch between analog and
+digital modes: on digital mode, it should be set to 1.
+
+The code that sets it on analog mode is OK, but it misses
+the logic that sets it on digital mode.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/cx231xx/cx231xx-cards.c | 2 +-
+ drivers/media/usb/cx231xx/cx231xx-core.c | 3 ++-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
++++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
+@@ -486,7 +486,7 @@ struct cx231xx_board cx231xx_boards[] =
+ .output_mode = OUT_MODE_VIP11,
+ .demod_xfer_mode = 0,
+ .ctl_pin_status_mask = 0xFFFFFFC4,
+- .agc_analog_digital_select_gpio = 0x00, /* According with PV cxPolaris.inf file */
++ .agc_analog_digital_select_gpio = 0x1c,
+ .tuner_sif_gpio = -1,
+ .tuner_scl_gpio = -1,
+ .tuner_sda_gpio = -1,
+--- a/drivers/media/usb/cx231xx/cx231xx-core.c
++++ b/drivers/media/usb/cx231xx/cx231xx-core.c
+@@ -712,6 +712,7 @@ int cx231xx_set_mode(struct cx231xx *dev
+ break;
+ case CX231XX_BOARD_CNXT_RDE_253S:
+ case CX231XX_BOARD_CNXT_RDU_253S:
++ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
+ errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1);
+ break;
+ case CX231XX_BOARD_HAUPPAUGE_EXETER:
+@@ -738,7 +739,7 @@ int cx231xx_set_mode(struct cx231xx *dev
+ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
+ case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
+ case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
+- errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
++ errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
+ break;
+ default:
+ break;
--- /dev/null
+From d50b3f43db739f03fcf8c0a00664b3d2fed0496e Mon Sep 17 00:00:00 2001
+From: Max Staudt <mstaudt@suse.de>
+Date: Mon, 13 Jun 2016 19:15:59 +0200
+Subject: fbdev/efifb: Fix 16 color palette entry calculation
+
+From: Max Staudt <mstaudt@suse.de>
+
+commit d50b3f43db739f03fcf8c0a00664b3d2fed0496e upstream.
+
+When using efifb with a 16-bit (5:6:5) visual, fbcon's text is rendered
+in the wrong colors - e.g. text gray (#aaaaaa) is rendered as green
+(#50bc50) and neighboring pixels have slightly different values
+(such as #50bc78).
+
+The reason is that fbcon loads its 16 color palette through
+efifb_setcolreg(), which in turn calculates a 32-bit value to write
+into memory for each palette index.
+Until now, this code could only handle 8-bit visuals and didn't mask
+overlapping values when ORing them.
+
+With this patch, fbcon displays the correct colors when a qemu VM is
+booted in 16-bit mode (in GRUB: "set gfxpayload=800x600x16").
+
+Fixes: 7c83172b98e5 ("x86_64 EFI boot support: EFI frame buffer driver") # v2.6.24+
+Signed-off-by: Max Staudt <mstaudt@suse.de>
+Acked-By: Peter Jones <pjones@redhat.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/video/fbdev/efifb.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/video/fbdev/efifb.c
++++ b/drivers/video/fbdev/efifb.c
+@@ -52,9 +52,9 @@ static int efifb_setcolreg(unsigned regn
+ return 1;
+
+ if (regno < 16) {
+- red >>= 8;
+- green >>= 8;
+- blue >>= 8;
++ red >>= 16 - info->var.red.length;
++ green >>= 16 - info->var.green.length;
++ blue >>= 16 - info->var.blue.length;
+ ((u32 *)(info->pseudo_palette))[regno] =
+ (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
--- /dev/null
+From 62837b3c1a95535d1a287c9c8c6563bbd8d37033 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Wed, 5 Oct 2016 22:49:30 -0700
+Subject: Input: elantech - add Fujitsu Lifebook E556 to force crc_enabled
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit 62837b3c1a95535d1a287c9c8c6563bbd8d37033 upstream.
+
+Another Lifebook machine that needs the same quirk as other similar
+models to make the driver working.
+
+Also let's reorder elantech_dmi_force_crc_enabled list so LIfebook enries
+are in alphabetical order.
+
+Reported-by: William Linna <william.linna@gmail.com>
+Tested-by: William Linna <william.linna@gmail.com>
+Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/mouse/elantech.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/input/mouse/elantech.c
++++ b/drivers/input/mouse/elantech.c
+@@ -1521,6 +1521,13 @@ static const struct dmi_system_id elante
+ },
+ },
+ {
++ /* Fujitsu LIFEBOOK E544 does not work with crc_enabled == 0 */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"),
++ },
++ },
++ {
+ /* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+@@ -1528,10 +1535,10 @@ static const struct dmi_system_id elante
+ },
+ },
+ {
+- /* Fujitsu LIFEBOOK E544 does not work with crc_enabled == 0 */
++ /* Fujitsu LIFEBOOK E556 does not work with crc_enabled == 0 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E556"),
+ },
+ },
+ {
--- /dev/null
+From f9a703a54d16ba2470391c4b12236ee56591d50c Mon Sep 17 00:00:00 2001
+From: Matti Kurkela <Matti.Kurkela@iki.fi>
+Date: Mon, 3 Oct 2016 16:48:17 -0700
+Subject: Input: elantech - force needed quirks on Fujitsu H760
+
+From: Matti Kurkela <Matti.Kurkela@iki.fi>
+
+commit f9a703a54d16ba2470391c4b12236ee56591d50c upstream.
+
+Just like Fujitsu CELSIUS H730, the H760 also has an Elantech touchpad with
+the same quirks. Without this patch, the touchpad is useless out-of-the-box
+as the mouse pointer won't move.
+
+This patch makes the driver aware of both the crc_enabled=1 requirement and
+the middle button, making the touchpad fully functional out-of-the-box.
+
+Signed-off-by: Matti Kurkela <Matti.Kurkela@iki.fi>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/mouse/elantech.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/input/mouse/elantech.c
++++ b/drivers/input/mouse/elantech.c
+@@ -1163,6 +1163,13 @@ static const struct dmi_system_id elante
+ DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"),
+ },
+ },
++ {
++ /* Fujitsu H760 also has a middle button */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"),
++ },
++ },
+ #endif
+ { }
+ };
+@@ -1507,6 +1514,13 @@ static const struct dmi_system_id elante
+ },
+ },
+ {
++ /* Fujitsu H760 does not work with crc_enabled == 0 */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"),
++ },
++ },
++ {
+ /* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
--- /dev/null
+From 930e19248e9b61da36c967687ca79c4d5f977919 Mon Sep 17 00:00:00 2001
+From: Marcos Paulo de Souza <marcos.souza.org@gmail.com>
+Date: Sat, 1 Oct 2016 12:07:35 -0700
+Subject: Input: i8042 - skip selftest on ASUS laptops
+
+From: Marcos Paulo de Souza <marcos.souza.org@gmail.com>
+
+commit 930e19248e9b61da36c967687ca79c4d5f977919 upstream.
+
+On suspend/resume cycle, selftest is executed to reset i8042 controller.
+But when this is done in Asus devices, subsequent calls to detect/init
+functions to elantech driver fails. Skipping selftest fixes this problem.
+
+An easier step to reproduce this problem is adding i8042.reset=1 as a
+kernel parameter. On Asus laptops, it'll make the system to start with the
+touchpad already stuck, since psmouse_probe forcibly calls the selftest
+function.
+
+This patch was inspired by John Hiesey's change[1], but, since this problem
+affects a lot of models of Asus, let's avoid running selftests on them.
+
+All models affected by this problem:
+A455LD
+K401LB
+K501LB
+K501LX
+R409L
+V502LX
+X302LA
+X450LCP
+X450LD
+X455LAB
+X455LDB
+X455LF
+Z450LA
+
+[1]: https://marc.info/?l=linux-input&m=144312209020616&w=2
+
+Fixes: "ETPS/2 Elantech Touchpad dies after resume from suspend"
+(https://bugzilla.kernel.org/show_bug.cgi?id=107971)
+
+Signed-off-by: Marcos Paulo de Souza <marcos.souza.org@gmail.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/kernel-parameters.txt | 9 ++-
+ drivers/input/serio/i8042-io.h | 2
+ drivers/input/serio/i8042-ip22io.h | 2
+ drivers/input/serio/i8042-ppcio.h | 2
+ drivers/input/serio/i8042-sparcio.h | 2
+ drivers/input/serio/i8042-unicore32io.h | 2
+ drivers/input/serio/i8042-x86ia64io.h | 96 +++++++++++++++++++++++++++++++-
+ drivers/input/serio/i8042.c | 55 ++++++++++++++----
+ 8 files changed, 150 insertions(+), 20 deletions(-)
+
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -1371,7 +1371,14 @@ bytes respectively. Such letter suffixes
+ i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
+ controllers
+ i8042.notimeout [HW] Ignore timeout condition signalled by controller
+- i8042.reset [HW] Reset the controller during init and cleanup
++ i8042.reset [HW] Reset the controller during init, cleanup and
++ suspend-to-ram transitions, only during s2r
++ transitions, or never reset
++ Format: { 1 | Y | y | 0 | N | n }
++ 1, Y, y: always reset controller
++ 0, N, n: don't ever reset controller
++ Default: only on s2r transitions on x86; most other
++ architectures force reset to be always executed
+ i8042.unlock [HW] Unlock (ignore) the keylock
+ i8042.kbdreset [HW] Reset device connected to KBD port
+
+--- a/drivers/input/serio/i8042-io.h
++++ b/drivers/input/serio/i8042-io.h
+@@ -81,7 +81,7 @@ static inline int i8042_platform_init(vo
+ return -EBUSY;
+ #endif
+
+- i8042_reset = 1;
++ i8042_reset = I8042_RESET_ALWAYS;
+ return 0;
+ }
+
+--- a/drivers/input/serio/i8042-ip22io.h
++++ b/drivers/input/serio/i8042-ip22io.h
+@@ -61,7 +61,7 @@ static inline int i8042_platform_init(vo
+ return -EBUSY;
+ #endif
+
+- i8042_reset = 1;
++ i8042_reset = I8042_RESET_ALWAYS;
+
+ return 0;
+ }
+--- a/drivers/input/serio/i8042-ppcio.h
++++ b/drivers/input/serio/i8042-ppcio.h
+@@ -44,7 +44,7 @@ static inline void i8042_write_command(i
+
+ static inline int i8042_platform_init(void)
+ {
+- i8042_reset = 1;
++ i8042_reset = I8042_RESET_ALWAYS;
+ return 0;
+ }
+
+--- a/drivers/input/serio/i8042-sparcio.h
++++ b/drivers/input/serio/i8042-sparcio.h
+@@ -130,7 +130,7 @@ static int __init i8042_platform_init(vo
+ }
+ }
+
+- i8042_reset = 1;
++ i8042_reset = I8042_RESET_ALWAYS;
+
+ return 0;
+ }
+--- a/drivers/input/serio/i8042-unicore32io.h
++++ b/drivers/input/serio/i8042-unicore32io.h
+@@ -61,7 +61,7 @@ static inline int i8042_platform_init(vo
+ if (!request_mem_region(I8042_REGION_START, I8042_REGION_SIZE, "i8042"))
+ return -EBUSY;
+
+- i8042_reset = 1;
++ i8042_reset = I8042_RESET_ALWAYS;
+ return 0;
+ }
+
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -510,6 +510,90 @@ static const struct dmi_system_id __init
+ { }
+ };
+
++/*
++ * On some Asus laptops, just running self tests cause problems.
++ */
++static const struct dmi_system_id i8042_dmi_noselftest_table[] = {
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "A455LD"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "K401LB"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "K501LB"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "K501LX"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "R409L"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "V502LX"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "X302LA"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "X450LD"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "X455LAB"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "X455LDB"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "X455LF"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Z450LA"),
++ },
++ },
++ { }
++};
+ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
+ {
+ /* MSI Wind U-100 */
+@@ -1072,12 +1156,18 @@ static int __init i8042_platform_init(vo
+ return retval;
+
+ #if defined(__ia64__)
+- i8042_reset = true;
++ i8042_reset = I8042_RESET_ALWAYS;
+ #endif
+
+ #ifdef CONFIG_X86
+- if (dmi_check_system(i8042_dmi_reset_table))
+- i8042_reset = true;
++ /* Honor module parameter when value is not default */
++ if (i8042_reset == I8042_RESET_DEFAULT) {
++ if (dmi_check_system(i8042_dmi_reset_table))
++ i8042_reset = I8042_RESET_ALWAYS;
++
++ if (dmi_check_system(i8042_dmi_noselftest_table))
++ i8042_reset = I8042_RESET_NEVER;
++ }
+
+ if (dmi_check_system(i8042_dmi_noloop_table))
+ i8042_noloop = true;
+--- a/drivers/input/serio/i8042.c
++++ b/drivers/input/serio/i8042.c
+@@ -48,9 +48,39 @@ static bool i8042_unlock;
+ module_param_named(unlock, i8042_unlock, bool, 0);
+ MODULE_PARM_DESC(unlock, "Ignore keyboard lock.");
+
+-static bool i8042_reset;
+-module_param_named(reset, i8042_reset, bool, 0);
+-MODULE_PARM_DESC(reset, "Reset controller during init and cleanup.");
++enum i8042_controller_reset_mode {
++ I8042_RESET_NEVER,
++ I8042_RESET_ALWAYS,
++ I8042_RESET_ON_S2RAM,
++#define I8042_RESET_DEFAULT I8042_RESET_ON_S2RAM
++};
++static enum i8042_controller_reset_mode i8042_reset = I8042_RESET_DEFAULT;
++static int i8042_set_reset(const char *val, const struct kernel_param *kp)
++{
++ enum i8042_controller_reset_mode *arg = kp->arg;
++ int error;
++ bool reset;
++
++ if (val) {
++ error = kstrtobool(val, &reset);
++ if (error)
++ return error;
++ } else {
++ reset = true;
++ }
++
++ *arg = reset ? I8042_RESET_ALWAYS : I8042_RESET_NEVER;
++ return 0;
++}
++
++static const struct kernel_param_ops param_ops_reset_param = {
++ .flags = KERNEL_PARAM_OPS_FL_NOARG,
++ .set = i8042_set_reset,
++};
++#define param_check_reset_param(name, p) \
++ __param_check(name, p, enum i8042_controller_reset_mode)
++module_param_named(reset, i8042_reset, reset_param, 0);
++MODULE_PARM_DESC(reset, "Reset controller on resume, cleanup or both");
+
+ static bool i8042_direct;
+ module_param_named(direct, i8042_direct, bool, 0);
+@@ -1019,7 +1049,7 @@ static int i8042_controller_init(void)
+ * Reset the controller and reset CRT to the original value set by BIOS.
+ */
+
+-static void i8042_controller_reset(bool force_reset)
++static void i8042_controller_reset(bool s2r_wants_reset)
+ {
+ i8042_flush();
+
+@@ -1044,8 +1074,10 @@ static void i8042_controller_reset(bool
+ * Reset the controller if requested.
+ */
+
+- if (i8042_reset || force_reset)
++ if (i8042_reset == I8042_RESET_ALWAYS ||
++ (i8042_reset == I8042_RESET_ON_S2RAM && s2r_wants_reset)) {
+ i8042_controller_selftest();
++ }
+
+ /*
+ * Restore the original control register setting.
+@@ -1110,7 +1142,7 @@ static void i8042_dritek_enable(void)
+ * before suspending.
+ */
+
+-static int i8042_controller_resume(bool force_reset)
++static int i8042_controller_resume(bool s2r_wants_reset)
+ {
+ int error;
+
+@@ -1118,7 +1150,8 @@ static int i8042_controller_resume(bool
+ if (error)
+ return error;
+
+- if (i8042_reset || force_reset) {
++ if (i8042_reset == I8042_RESET_ALWAYS ||
++ (i8042_reset == I8042_RESET_ON_S2RAM && s2r_wants_reset)) {
+ error = i8042_controller_selftest();
+ if (error)
+ return error;
+@@ -1195,7 +1228,7 @@ static int i8042_pm_resume_noirq(struct
+
+ static int i8042_pm_resume(struct device *dev)
+ {
+- bool force_reset;
++ bool want_reset;
+ int i;
+
+ for (i = 0; i < I8042_NUM_PORTS; i++) {
+@@ -1218,9 +1251,9 @@ static int i8042_pm_resume(struct device
+ * off control to the platform firmware, otherwise we can simply restore
+ * the mode.
+ */
+- force_reset = pm_resume_via_firmware();
++ want_reset = pm_resume_via_firmware();
+
+- return i8042_controller_resume(force_reset);
++ return i8042_controller_resume(want_reset);
+ }
+
+ static int i8042_pm_thaw(struct device *dev)
+@@ -1482,7 +1515,7 @@ static int __init i8042_probe(struct pla
+
+ i8042_platform_device = dev;
+
+- if (i8042_reset) {
++ if (i8042_reset == I8042_RESET_ALWAYS) {
+ error = i8042_controller_selftest();
+ if (error)
+ return error;
--- /dev/null
+From 505a0ea706fc1db4381baa6c6bd2e596e730a55e Mon Sep 17 00:00:00 2001
+From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+Date: Sun, 4 Sep 2016 10:43:53 -0300
+Subject: [media] mb86a20s: fix demod settings
+
+From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+
+commit 505a0ea706fc1db4381baa6c6bd2e596e730a55e upstream.
+
+With the current settings, only one channel locks properly.
+That's likely because, when this driver was written, Brazil
+were still using experimental transmissions.
+
+Change it to reproduce the settings used by the newer drivers.
+That makes it lock on other channels.
+
+Tested with both PixelView SBTVD Hybrid (cx231xx-based) and
+C3Tech Digital Duo HDTV/SDTV (em28xx-based) devices.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/dvb-frontends/mb86a20s.c | 92 +++++++++++++++------------------
+ 1 file changed, 42 insertions(+), 50 deletions(-)
+
+--- a/drivers/media/dvb-frontends/mb86a20s.c
++++ b/drivers/media/dvb-frontends/mb86a20s.c
+@@ -71,25 +71,27 @@ static struct regdata mb86a20s_init1[] =
+ };
+
+ static struct regdata mb86a20s_init2[] = {
+- { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 },
++ { 0x50, 0xd1 }, { 0x51, 0x22 },
++ { 0x39, 0x01 },
++ { 0x71, 0x00 },
+ { 0x3b, 0x21 },
+- { 0x3c, 0x38 },
++ { 0x3c, 0x3a },
+ { 0x01, 0x0d },
+- { 0x04, 0x08 }, { 0x05, 0x03 },
++ { 0x04, 0x08 }, { 0x05, 0x05 },
+ { 0x04, 0x0e }, { 0x05, 0x00 },
+- { 0x04, 0x0f }, { 0x05, 0x37 },
+- { 0x04, 0x0b }, { 0x05, 0x78 },
++ { 0x04, 0x0f }, { 0x05, 0x14 },
++ { 0x04, 0x0b }, { 0x05, 0x8c },
+ { 0x04, 0x00 }, { 0x05, 0x00 },
+- { 0x04, 0x01 }, { 0x05, 0x1e },
+- { 0x04, 0x02 }, { 0x05, 0x07 },
+- { 0x04, 0x03 }, { 0x05, 0xd0 },
++ { 0x04, 0x01 }, { 0x05, 0x07 },
++ { 0x04, 0x02 }, { 0x05, 0x0f },
++ { 0x04, 0x03 }, { 0x05, 0xa0 },
+ { 0x04, 0x09 }, { 0x05, 0x00 },
+ { 0x04, 0x0a }, { 0x05, 0xff },
+- { 0x04, 0x27 }, { 0x05, 0x00 },
++ { 0x04, 0x27 }, { 0x05, 0x64 },
+ { 0x04, 0x28 }, { 0x05, 0x00 },
+- { 0x04, 0x1e }, { 0x05, 0x00 },
+- { 0x04, 0x29 }, { 0x05, 0x64 },
+- { 0x04, 0x32 }, { 0x05, 0x02 },
++ { 0x04, 0x1e }, { 0x05, 0xff },
++ { 0x04, 0x29 }, { 0x05, 0x0a },
++ { 0x04, 0x32 }, { 0x05, 0x0a },
+ { 0x04, 0x14 }, { 0x05, 0x02 },
+ { 0x04, 0x04 }, { 0x05, 0x00 },
+ { 0x04, 0x05 }, { 0x05, 0x22 },
+@@ -97,8 +99,6 @@ static struct regdata mb86a20s_init2[] =
+ { 0x04, 0x07 }, { 0x05, 0xd8 },
+ { 0x04, 0x12 }, { 0x05, 0x00 },
+ { 0x04, 0x13 }, { 0x05, 0xff },
+- { 0x04, 0x15 }, { 0x05, 0x4e },
+- { 0x04, 0x16 }, { 0x05, 0x20 },
+
+ /*
+ * On this demod, when the bit count reaches the count below,
+@@ -152,42 +152,36 @@ static struct regdata mb86a20s_init2[] =
+ { 0x50, 0x51 }, { 0x51, 0x04 }, /* MER symbol 4 */
+ { 0x45, 0x04 }, /* CN symbol 4 */
+ { 0x48, 0x04 }, /* CN manual mode */
+-
++ { 0x50, 0xd5 }, { 0x51, 0x01 },
+ { 0x50, 0xd6 }, { 0x51, 0x1f },
+ { 0x50, 0xd2 }, { 0x51, 0x03 },
+- { 0x50, 0xd7 }, { 0x51, 0xbf },
+- { 0x28, 0x74 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xff },
+- { 0x28, 0x46 }, { 0x29, 0x00 }, { 0x2a, 0x1a }, { 0x2b, 0x0c },
+-
+- { 0x04, 0x40 }, { 0x05, 0x00 },
+- { 0x28, 0x00 }, { 0x2b, 0x08 },
+- { 0x28, 0x05 }, { 0x2b, 0x00 },
++ { 0x50, 0xd7 }, { 0x51, 0x3f },
+ { 0x1c, 0x01 },
+- { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x1f },
+- { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x18 },
+- { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x12 },
+- { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x30 },
+- { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x37 },
+- { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 },
+- { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x09 },
+- { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x06 },
+- { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7b },
+- { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x76 },
+- { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7d },
+- { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x08 },
+- { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0b },
+- { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 },
+- { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf2 },
+- { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf3 },
+- { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x05 },
+- { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 },
+- { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f },
+- { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xef },
+- { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xd8 },
+- { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xf1 },
+- { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x3d },
+- { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x94 },
+- { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xba },
++ { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x03 },
++ { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0d },
++ { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 },
++ { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x01 },
++ { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x21 },
++ { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x29 },
++ { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 },
++ { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x31 },
++ { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0e },
++ { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x4e },
++ { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x46 },
++ { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f },
++ { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x56 },
++ { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x35 },
++ { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbe },
++ { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0x84 },
++ { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x03 }, { 0x2b, 0xee },
++ { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x98 },
++ { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x9f },
++ { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xb2 },
++ { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0xc2 },
++ { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0x4a },
++ { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbc },
++ { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x04 }, { 0x2b, 0xba },
++ { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0x14 },
+ { 0x50, 0x1e }, { 0x51, 0x5d },
+ { 0x50, 0x22 }, { 0x51, 0x00 },
+ { 0x50, 0x23 }, { 0x51, 0xc8 },
+@@ -196,9 +190,7 @@ static struct regdata mb86a20s_init2[] =
+ { 0x50, 0x26 }, { 0x51, 0x00 },
+ { 0x50, 0x27 }, { 0x51, 0xc3 },
+ { 0x50, 0x39 }, { 0x51, 0x02 },
+- { 0xec, 0x0f },
+- { 0xeb, 0x1f },
+- { 0x28, 0x6a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 },
++ { 0x50, 0xd5 }, { 0x51, 0x01 },
+ { 0xd0, 0x00 },
+ };
+
--- /dev/null
+From dafb65fb98d85d8e78405e82c83e81975e5d5480 Mon Sep 17 00:00:00 2001
+From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+Date: Sun, 4 Sep 2016 10:16:18 -0300
+Subject: [media] mb86a20s: fix the locking logic
+
+From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+
+commit dafb65fb98d85d8e78405e82c83e81975e5d5480 upstream.
+
+On this frontend, it takes a while to start output normal
+TS data. That only happens on state S9. On S8, the TS output
+is enabled, but it is not reliable enough.
+
+However, the zigzag loop is too fast to let it sync.
+
+As, on practical tests, the zigzag software loop doesn't
+seem to be helping, but just slowing down the tuning, let's
+switch to hardware algorithm, as the tuners used on such
+devices are capable of work with frequency drifts without
+any help from software.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/dvb-frontends/mb86a20s.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/dvb-frontends/mb86a20s.c
++++ b/drivers/media/dvb-frontends/mb86a20s.c
+@@ -317,7 +317,11 @@ static int mb86a20s_read_status(struct d
+ if (val >= 7)
+ *status |= FE_HAS_SYNC;
+
+- if (val >= 8) /* Maybe 9? */
++ /*
++ * Actually, on state S8, it starts receiving TS, but the TS
++ * output is only on normal state after the transition to S9.
++ */
++ if (val >= 9)
+ *status |= FE_HAS_LOCK;
+
+ dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n",
+@@ -2067,6 +2071,11 @@ static void mb86a20s_release(struct dvb_
+ kfree(state);
+ }
+
++static int mb86a20s_get_frontend_algo(struct dvb_frontend *fe)
++{
++ return DVBFE_ALGO_HW;
++}
++
+ static struct dvb_frontend_ops mb86a20s_ops;
+
+ struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
+@@ -2140,6 +2149,7 @@ static struct dvb_frontend_ops mb86a20s_
+ .read_status = mb86a20s_read_status_and_stats,
+ .read_signal_strength = mb86a20s_read_signal_strength_from_cache,
+ .tune = mb86a20s_tune,
++ .get_frontend_algo = mb86a20s_get_frontend_algo,
+ };
+
+ MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
--- /dev/null
+From 034827c727f7f3946a18355b63995b402c226c82 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Thu, 6 Oct 2016 23:10:41 +0100
+Subject: MIPS: Fix -mabi=64 build of vdso.lds
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 034827c727f7f3946a18355b63995b402c226c82 upstream.
+
+The native ABI vDSO linker script vdso.lds is built by preprocessing
+vdso.lds.S, with the native -mabi flag passed in to get the correct ABI
+definitions. Unfortunately however certain toolchains choke on -mabi=64
+without a corresponding compatible -march flag, for example:
+
+cc1: error: ‘-march=mips32r2’ is not compatible with the selected ABI
+scripts/Makefile.build:338: recipe for target 'arch/mips/vdso/vdso.lds' failed
+
+Fix this by including ccflags-vdso in the KBUILD_CPPFLAGS for vdso.lds,
+which includes the appropriate -march flag.
+
+Fixes: ebb5e78cc634 ("MIPS: Initial implementation of a VDSO")
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Reviewed-by: Maciej W. Rozycki <macro@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/14368/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/vdso/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/vdso/Makefile
++++ b/arch/mips/vdso/Makefile
+@@ -75,7 +75,7 @@ obj-vdso := $(obj-vdso-y:%.o=$(obj)/%.o)
+ $(obj-vdso): KBUILD_CFLAGS := $(cflags-vdso) $(native-abi)
+ $(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi)
+
+-$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(native-abi)
++$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi)
+
+ $(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
+ $(call if_changed,vdsold)
--- /dev/null
+From 74f1077b5b783e7bf4fa3007cefdc8dbd6c07518 Mon Sep 17 00:00:00 2001
+From: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
+Date: Wed, 12 Oct 2016 09:32:56 +0200
+Subject: MIPS: ptrace: Fix regs_return_value for kernel context
+
+From: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
+
+commit 74f1077b5b783e7bf4fa3007cefdc8dbd6c07518 upstream.
+
+Currently regs_return_value always negates reg[2] if it determines
+the syscall has failed, but when called in kernel context this check is
+invalid and may result in returning a wrong value.
+
+This fixes errors reported by CONFIG_KPROBES_SANITY_TEST
+
+Fixes: d7e7528bcd45 ("Audit: push audit success and retcode into arch ptrace.h")
+Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/14381/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/asm/ptrace.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/include/asm/ptrace.h
++++ b/arch/mips/include/asm/ptrace.h
+@@ -152,7 +152,7 @@ static inline int is_syscall_success(str
+
+ static inline long regs_return_value(struct pt_regs *regs)
+ {
+- if (is_syscall_success(regs))
++ if (is_syscall_success(regs) || !user_mode(regs))
+ return regs->regs[2];
+ else
+ return -regs->regs[2];
--- /dev/null
+From b3f9e7239074613aa6bdafa4caf7c104fe1e7276 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Thu, 22 Sep 2016 13:38:53 -0400
+Subject: NFSv4: Don't report revoked delegations as valid in nfs_have_delegation()
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit b3f9e7239074613aa6bdafa4caf7c104fe1e7276 upstream.
+
+If the delegation is revoked, then it can't be used for caching.
+
+Fixes: 869f9dfa4d6d ("NFSv4: Fix races between nfs_remove_bad_delegation()...")
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Tested-by: Oleg Drokin <green@linuxhacker.ru>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/delegation.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -51,6 +51,7 @@ nfs4_do_check_delegation(struct inode *i
+ rcu_read_lock();
+ delegation = rcu_dereference(NFS_I(inode)->delegation);
+ if (delegation != NULL && (delegation->type & flags) == flags &&
++ !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
+ !test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
+ if (mark)
+ nfs_mark_delegation_referenced(delegation);
--- /dev/null
+From aa05c87f23efe417adc7ff9b4193b7201ec0dd79 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Thu, 22 Sep 2016 13:38:54 -0400
+Subject: NFSv4: nfs4_copy_delegation_stateid() must fail if the delegation is invalid
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit aa05c87f23efe417adc7ff9b4193b7201ec0dd79 upstream.
+
+We must not allow the use of delegations that have been revoked or are
+being returned.
+
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Fixes: 869f9dfa4d6d ("NFSv4: Fix races between nfs_remove_bad_delegation()...")
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Tested-by: Oleg Drokin <green@linuxhacker.ru>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/delegation.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -41,6 +41,17 @@ void nfs_mark_delegation_referenced(stru
+ set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
+ }
+
++static bool
++nfs4_is_valid_delegation(const struct nfs_delegation *delegation,
++ fmode_t flags)
++{
++ if (delegation != NULL && (delegation->type & flags) == flags &&
++ !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
++ !test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
++ return true;
++ return false;
++}
++
+ static int
+ nfs4_do_check_delegation(struct inode *inode, fmode_t flags, bool mark)
+ {
+@@ -50,9 +61,7 @@ nfs4_do_check_delegation(struct inode *i
+ flags &= FMODE_READ|FMODE_WRITE;
+ rcu_read_lock();
+ delegation = rcu_dereference(NFS_I(inode)->delegation);
+- if (delegation != NULL && (delegation->type & flags) == flags &&
+- !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
+- !test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
++ if (nfs4_is_valid_delegation(delegation, flags)) {
+ if (mark)
+ nfs_mark_delegation_referenced(delegation);
+ ret = 1;
+@@ -893,7 +902,7 @@ bool nfs4_copy_delegation_stateid(nfs4_s
+ flags &= FMODE_READ|FMODE_WRITE;
+ rcu_read_lock();
+ delegation = rcu_dereference(nfsi->delegation);
+- ret = (delegation != NULL && (delegation->type & flags) == flags);
++ ret = nfs4_is_valid_delegation(delegation, flags);
+ if (ret) {
+ nfs4_stateid_copy(dst, &delegation->stateid);
+ nfs_mark_delegation_referenced(delegation);
--- /dev/null
+From 304020fe48c6c7fff8b5a38f382b54404f0f79d3 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Thu, 22 Sep 2016 13:39:18 -0400
+Subject: NFSv4: Open state recovery must account for file permission changes
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit 304020fe48c6c7fff8b5a38f382b54404f0f79d3 upstream.
+
+If the file permissions change on the server, then we may not be able to
+recover open state. If so, we need to ensure that we mark the file
+descriptor appropriately.
+
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Tested-by: Oleg Drokin <green@linuxhacker.ru>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4state.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1493,6 +1493,9 @@ restart:
+ __func__, status);
+ case -ENOENT:
+ case -ENOMEM:
++ case -EACCES:
++ case -EROFS:
++ case -EIO:
+ case -ESTALE:
+ /* Open state on this file cannot be recovered */
+ nfs4_state_mark_recovery_failed(state, status);
--- /dev/null
+From 3f807e5ae5597bd65a6fff684083e8eaa21f3fa7 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@poochiereds.net>
+Date: Tue, 4 Oct 2016 00:07:43 -0400
+Subject: NFSv4.2: Fix a reference leak in nfs42_proc_layoutstats_generic
+
+From: Jeff Layton <jlayton@poochiereds.net>
+
+commit 3f807e5ae5597bd65a6fff684083e8eaa21f3fa7 upstream.
+
+The caller of rpc_run_task also gets a reference that must be put.
+
+Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs42proc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/nfs/nfs42proc.c
++++ b/fs/nfs/nfs42proc.c
+@@ -269,6 +269,7 @@ int nfs42_proc_layoutstats_generic(struc
+ task = rpc_run_task(&task_setup);
+ if (IS_ERR(task))
+ return PTR_ERR(task);
++ rpc_put_task(task);
+ return 0;
+ }
+
--- /dev/null
+From 8b326c61de08f5ca4bc454a168f19e7e43c4cc2a Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Fri, 16 Sep 2016 14:12:11 +0200
+Subject: ovl: copy_up_xattr(): use strnlen
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 8b326c61de08f5ca4bc454a168f19e7e43c4cc2a upstream.
+
+Be defensive about what underlying fs provides us in the returned xattr
+list buffer. strlen() may overrun the buffer, so use strnlen() and WARN if
+the contents are not properly null terminated.
+
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/copy_up.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -25,6 +25,7 @@ int ovl_copy_xattr(struct dentry *old, s
+ ssize_t list_size, size, value_size = 0;
+ char *buf, *name, *value = NULL;
+ int uninitialized_var(error);
++ size_t slen;
+
+ if (!old->d_inode->i_op->getxattr ||
+ !new->d_inode->i_op->getxattr)
+@@ -47,7 +48,16 @@ int ovl_copy_xattr(struct dentry *old, s
+ goto out;
+ }
+
+- for (name = buf; name < (buf + list_size); name += strlen(name) + 1) {
++ for (name = buf; list_size; name += slen) {
++ slen = strnlen(name, list_size) + 1;
++
++ /* underlying fs providing us with an broken xattr list? */
++ if (WARN_ON(slen > list_size)) {
++ error = -EIO;
++ break;
++ }
++ list_size -= slen;
++
+ if (ovl_is_private_xattr(name))
+ continue;
+ retry:
--- /dev/null
+From 6a45b3628ce4dcf7498b39c87d475bab6e2a9b24 Mon Sep 17 00:00:00 2001
+From: Richard Weinberger <richard@nod.at>
+Date: Fri, 16 Sep 2016 11:45:24 +0200
+Subject: ovl: Fix info leak in ovl_lookup_temp()
+
+From: Richard Weinberger <richard@nod.at>
+
+commit 6a45b3628ce4dcf7498b39c87d475bab6e2a9b24 upstream.
+
+The function uses the memory address of a struct dentry as unique id.
+While the address-based directory entry is only visible to root it is IMHO
+still worth fixing since the temporary name does not have to be a kernel
+address. It can be any unique number. Replace it by an atomic integer
+which is allowed to wrap around.
+
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Fixes: e9be9d5e76e3 ("overlay filesystem")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/dir.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -12,6 +12,7 @@
+ #include <linux/xattr.h>
+ #include <linux/security.h>
+ #include <linux/cred.h>
++#include <linux/atomic.h>
+ #include "overlayfs.h"
+
+ void ovl_cleanup(struct inode *wdir, struct dentry *wdentry)
+@@ -35,8 +36,10 @@ struct dentry *ovl_lookup_temp(struct de
+ {
+ struct dentry *temp;
+ char name[20];
++ static atomic_t temp_id = ATOMIC_INIT(0);
+
+- snprintf(name, sizeof(name), "#%lx", (unsigned long) dentry);
++ /* counter is allowed to wrap, since temp dentries are ephemeral */
++ snprintf(name, sizeof(name), "#%x", atomic_inc_return(&temp_id));
+
+ temp = lookup_one_len(name, workdir, strlen(name));
+ if (!IS_ERR(temp) && temp->d_inode) {
--- /dev/null
+From bcd8f2e94808fcddf6ef3af5f060a36820dcc432 Mon Sep 17 00:00:00 2001
+From: Ming Lei <tom.leiming@gmail.com>
+Date: Sun, 9 Oct 2016 13:23:27 +0800
+Subject: scsi: Fix use-after-free
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+commit bcd8f2e94808fcddf6ef3af5f060a36820dcc432 upstream.
+
+This patch fixes one use-after-free report[1] by KASAN.
+
+In __scsi_scan_target(), when a type 31 device is probed,
+SCSI_SCAN_TARGET_PRESENT is returned and the target will be scanned
+again.
+
+Inside the following scsi_report_lun_scan(), one new scsi_device
+instance is allocated, and scsi_probe_and_add_lun() is called again to
+probe the target and still see type 31 device, finally
+__scsi_remove_device() is called to remove & free the device at the end
+of scsi_probe_and_add_lun(), so cause use-after-free in
+scsi_report_lun_scan().
+
+And the following SCSI log can be observed:
+
+ scsi 0:0:2:0: scsi scan: INQUIRY pass 1 length 36
+ scsi 0:0:2:0: scsi scan: INQUIRY successful with code 0x0
+ scsi 0:0:2:0: scsi scan: peripheral device type of 31, no device added
+ scsi 0:0:2:0: scsi scan: Sending REPORT LUNS to (try 0)
+ scsi 0:0:2:0: scsi scan: REPORT LUNS successful (try 0) result 0x0
+ scsi 0:0:2:0: scsi scan: REPORT LUN scan
+ scsi 0:0:2:0: scsi scan: INQUIRY pass 1 length 36
+ scsi 0:0:2:0: scsi scan: INQUIRY successful with code 0x0
+ scsi 0:0:2:0: scsi scan: peripheral device type of 31, no device added
+ BUG: KASAN: use-after-free in __scsi_scan_target+0xbf8/0xe40 at addr ffff88007b44a104
+
+This patch fixes the issue by moving the putting reference at
+the end of scsi_report_lun_scan().
+
+[1] KASAN report
+==================================================================
+[ 3.274597] PM: Adding info for serio:serio1
+[ 3.275127] BUG: KASAN: use-after-free in __scsi_scan_target+0xd87/0xdf0 at addr ffff880254d8c304
+[ 3.275653] Read of size 4 by task kworker/u10:0/27
+[ 3.275903] CPU: 3 PID: 27 Comm: kworker/u10:0 Not tainted 4.8.0 #2121
+[ 3.276258] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
+[ 3.276797] Workqueue: events_unbound async_run_entry_fn
+[ 3.277083] ffff880254d8c380 ffff880259a37870 ffffffff94bbc6c1 ffff880078402d80
+[ 3.277532] ffff880254d8bb80 ffff880259a37898 ffffffff9459fec1 ffff880259a37930
+[ 3.277989] ffff880254d8bb80 ffff880078402d80 ffff880259a37920 ffffffff945a0165
+[ 3.278436] Call Trace:
+[ 3.278528] [<ffffffff94bbc6c1>] dump_stack+0x65/0x84
+[ 3.278797] [<ffffffff9459fec1>] kasan_object_err+0x21/0x70
+[ 3.279063] device: 'psaux': device_add
+[ 3.279616] [<ffffffff945a0165>] kasan_report_error+0x205/0x500
+[ 3.279651] PM: Adding info for No Bus:psaux
+[ 3.280202] [<ffffffff944ecd22>] ? kfree_const+0x22/0x30
+[ 3.280486] [<ffffffff94bc2dc9>] ? kobject_release+0x119/0x370
+[ 3.280805] [<ffffffff945a0543>] __asan_report_load4_noabort+0x43/0x50
+[ 3.281170] [<ffffffff9507e1f7>] ? __scsi_scan_target+0xd87/0xdf0
+[ 3.281506] [<ffffffff9507e1f7>] __scsi_scan_target+0xd87/0xdf0
+[ 3.281848] [<ffffffff9507d470>] ? scsi_add_device+0x30/0x30
+[ 3.282156] [<ffffffff94f7f660>] ? pm_runtime_autosuspend_expiration+0x60/0x60
+[ 3.282570] [<ffffffff956ddb07>] ? _raw_spin_lock+0x17/0x40
+[ 3.282880] [<ffffffff9507e505>] scsi_scan_channel+0x105/0x160
+[ 3.283200] [<ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
+[ 3.283563] [<ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
+[ 3.283882] [<ffffffff9507efc1>] do_scan_async+0x41/0x450
+[ 3.284173] [<ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
+[ 3.284492] [<ffffffff941a8954>] ? pwq_dec_nr_in_flight+0x124/0x2a0
+[ 3.284876] [<ffffffff941d1770>] ? preempt_count_add+0x130/0x160
+[ 3.285207] [<ffffffff941a9a84>] process_one_work+0x544/0x12d0
+[ 3.285526] [<ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
+[ 3.285844] [<ffffffff941aa810>] ? process_one_work+0x12d0/0x12d0
+[ 3.286182] [<ffffffff941bb365>] kthread+0x1c5/0x260
+[ 3.286443] [<ffffffff940855cd>] ? __switch_to+0x88d/0x1430
+[ 3.286745] [<ffffffff941bb1a0>] ? kthread_worker_fn+0x5a0/0x5a0
+[ 3.287085] [<ffffffff956dde9f>] ret_from_fork+0x1f/0x40
+[ 3.287368] [<ffffffff941bb1a0>] ? kthread_worker_fn+0x5a0/0x5a0
+[ 3.287697] Object at ffff880254d8bb80, in cache kmalloc-2048 size: 2048
+[ 3.288064] Allocated:
+[ 3.288147] PID = 27
+[ 3.288218] [<ffffffff940b27ab>] save_stack_trace+0x2b/0x50
+[ 3.288531] [<ffffffff9459f246>] save_stack+0x46/0xd0
+[ 3.288806] [<ffffffff9459f4bd>] kasan_kmalloc+0xad/0xe0
+[ 3.289098] [<ffffffff9459c07e>] __kmalloc+0x13e/0x250
+[ 3.289378] [<ffffffff95078e5a>] scsi_alloc_sdev+0xea/0xcf0
+[ 3.289701] [<ffffffff9507de76>] __scsi_scan_target+0xa06/0xdf0
+[ 3.290034] [<ffffffff9507e505>] scsi_scan_channel+0x105/0x160
+[ 3.290362] [<ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
+[ 3.290724] [<ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
+[ 3.291055] [<ffffffff9507efc1>] do_scan_async+0x41/0x450
+[ 3.291354] [<ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
+[ 3.291695] [<ffffffff941a9a84>] process_one_work+0x544/0x12d0
+[ 3.292022] [<ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
+[ 3.292325] [<ffffffff941bb365>] kthread+0x1c5/0x260
+[ 3.292594] [<ffffffff956dde9f>] ret_from_fork+0x1f/0x40
+[ 3.292886] Freed:
+[ 3.292945] PID = 27
+[ 3.293016] [<ffffffff940b27ab>] save_stack_trace+0x2b/0x50
+[ 3.293327] [<ffffffff9459f246>] save_stack+0x46/0xd0
+[ 3.293600] [<ffffffff9459fa61>] kasan_slab_free+0x71/0xb0
+[ 3.293916] [<ffffffff9459bac2>] kfree+0xa2/0x1f0
+[ 3.294168] [<ffffffff9508158a>] scsi_device_dev_release_usercontext+0x50a/0x730
+[ 3.294598] [<ffffffff941ace9a>] execute_in_process_context+0xda/0x130
+[ 3.294974] [<ffffffff9508107c>] scsi_device_dev_release+0x1c/0x20
+[ 3.295322] [<ffffffff94f566f6>] device_release+0x76/0x1e0
+[ 3.295626] [<ffffffff94bc2db7>] kobject_release+0x107/0x370
+[ 3.295942] [<ffffffff94bc29ce>] kobject_put+0x4e/0xa0
+[ 3.296222] [<ffffffff94f56e17>] put_device+0x17/0x20
+[ 3.296497] [<ffffffff9505201c>] scsi_device_put+0x7c/0xa0
+[ 3.296801] [<ffffffff9507e1bc>] __scsi_scan_target+0xd4c/0xdf0
+[ 3.297132] [<ffffffff9507e505>] scsi_scan_channel+0x105/0x160
+[ 3.297458] [<ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
+[ 3.297829] [<ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
+[ 3.298156] [<ffffffff9507efc1>] do_scan_async+0x41/0x450
+[ 3.298453] [<ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
+[ 3.298777] [<ffffffff941a9a84>] process_one_work+0x544/0x12d0
+[ 3.299105] [<ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
+[ 3.299408] [<ffffffff941bb365>] kthread+0x1c5/0x260
+[ 3.299676] [<ffffffff956dde9f>] ret_from_fork+0x1f/0x40
+[ 3.299967] Memory state around the buggy address:
+[ 3.300209] ffff880254d8c200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 3.300608] ffff880254d8c280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 3.300986] >ffff880254d8c300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 3.301408] ^
+[ 3.301550] ffff880254d8c380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 3.301987] ffff880254d8c400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 3.302396]
+==================================================================
+
+Cc: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/scsi_scan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -1459,12 +1459,12 @@ retry:
+ out_err:
+ kfree(lun_data);
+ out:
+- scsi_device_put(sdev);
+ if (scsi_device_created(sdev))
+ /*
+ * the sdev we used didn't appear in the report luns scan
+ */
+ __scsi_remove_device(sdev);
++ scsi_device_put(sdev);
+ return ret;
+ }
+
--- /dev/null
+From e7cb08e894a0b876443ef8fdb0706575dc00a5d2 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Fri, 14 Oct 2016 16:18:39 -0400
+Subject: scsi: zfcp: spin_lock_irqsave() is not nestable
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit e7cb08e894a0b876443ef8fdb0706575dc00a5d2 upstream.
+
+We accidentally overwrite the original saved value of "flags" so that we
+can't re-enable IRQs at the end of the function. Presumably this
+function is mostly called with IRQs disabled or it would be obvious in
+testing.
+
+Fixes: aceeffbb59bb ("zfcp: trace full payload of all SAN records (req,resp,iels)")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_dbf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -384,7 +384,7 @@ void zfcp_dbf_san(char *tag, struct zfcp
+ /* if (len > rec_len):
+ * dump data up to cap_len ignoring small duplicate in rec->payload
+ */
+- spin_lock_irqsave(&dbf->pay_lock, flags);
++ spin_lock(&dbf->pay_lock);
+ memset(payload, 0, sizeof(*payload));
+ memcpy(payload->area, paytag, ZFCP_DBF_TAG_LEN);
+ payload->fsf_req_id = req_id;
powerpc-64-fix-incorrect-return-value-from-__copy_tofrom_user.patch
powerpc-pseries-fix-stack-corruption-in-htpe-code.patch
ubi-deal-with-interrupted-erasures-in-wl.patch
+zfcp-fix-fc_host-port_type-with-npiv.patch
+zfcp-fix-els-gs-request-response-length-for-hardware-data-router.patch
+zfcp-close-window-with-unblocked-rport-during-rport-gone.patch
+zfcp-retain-trace-level-for-scsi-and-hba-fsf-response-records.patch
+zfcp-restore-dont-use-0-to-indicate-invalid-lun-in-rec-trace.patch
+zfcp-trace-on-request-for-open-and-close-of-wka-port.patch
+zfcp-restore-tracing-of-handle-for-port-and-lun-with-hba-records.patch
+zfcp-fix-d_id-field-with-actual-value-on-tracing-san-responses.patch
+zfcp-fix-payload-trace-length-for-san-request-response.patch
+zfcp-trace-full-payload-of-all-san-records-req-resp-iels.patch
+scsi-zfcp-spin_lock_irqsave-is-not-nestable.patch
+fbdev-efifb-fix-16-color-palette-entry-calculation.patch
+ovl-fix-info-leak-in-ovl_lookup_temp.patch
+ovl-copy_up_xattr-use-strnlen.patch
+mb86a20s-fix-the-locking-logic.patch
+mb86a20s-fix-demod-settings.patch
+cx231xx-don-t-return-error-on-success.patch
+cx231xx-fix-gpios-for-pixelview-sbtvd-hybrid.patch
+alsa-hda-fix-a-failure-of-micmute-led-when-having-multi-adcs.patch
+mips-fix-mabi-64-build-of-vdso.lds.patch
+mips-ptrace-fix-regs_return_value-for-kernel-context.patch
+input-i8042-skip-selftest-on-asus-laptops.patch
+input-elantech-force-needed-quirks-on-fujitsu-h760.patch
+input-elantech-add-fujitsu-lifebook-e556-to-force-crc_enabled.patch
+sunrpc-fix-write-space-race-causing-stalls.patch
+nfsv4-don-t-report-revoked-delegations-as-valid-in-nfs_have_delegation.patch
+nfsv4-nfs4_copy_delegation_stateid-must-fail-if-the-delegation-is-invalid.patch
+nfsv4-open-state-recovery-must-account-for-file-permission-changes.patch
+nfsv4.2-fix-a-reference-leak-in-nfs42_proc_layoutstats_generic.patch
+scsi-fix-use-after-free.patch
--- /dev/null
+From d48f9ce73c997573e1b512893fa6eddf353a6f69 Mon Sep 17 00:00:00 2001
+From: David Vrabel <david.vrabel@citrix.com>
+Date: Mon, 19 Sep 2016 13:58:30 +0100
+Subject: sunrpc: fix write space race causing stalls
+
+From: David Vrabel <david.vrabel@citrix.com>
+
+commit d48f9ce73c997573e1b512893fa6eddf353a6f69 upstream.
+
+Write space becoming available may race with putting the task to sleep
+in xprt_wait_for_buffer_space(). The existing mechanism to avoid the
+race does not work.
+
+This (edited) partial trace illustrates the problem:
+
+ [1] rpc_task_run_action: task:43546@5 ... action=call_transmit
+ [2] xs_write_space <-xs_tcp_write_space
+ [3] xprt_write_space <-xs_write_space
+ [4] rpc_task_sleep: task:43546@5 ...
+ [5] xs_write_space <-xs_tcp_write_space
+
+[1] Task 43546 runs but is out of write space.
+
+[2] Space becomes available, xs_write_space() clears the
+ SOCKWQ_ASYNC_NOSPACE bit.
+
+[3] xprt_write_space() attemts to wake xprt->snd_task (== 43546), but
+ this has not yet been queued and the wake up is lost.
+
+[4] xs_nospace() is called which calls xprt_wait_for_buffer_space()
+ which queues task 43546.
+
+[5] The call to sk->sk_write_space() at the end of xs_nospace() (which
+ is supposed to handle the above race) does not call
+ xprt_write_space() as the SOCKWQ_ASYNC_NOSPACE bit is clear and
+ thus the task is not woken.
+
+Fix the race by resetting the SOCKWQ_ASYNC_NOSPACE bit in xs_nospace()
+so the second call to sk->sk_write_space() calls xprt_write_space().
+
+Suggested-by: Trond Myklebust <trondmy@primarydata.com>
+Signed-off-by: David Vrabel <david.vrabel@citrix.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/xprtsock.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -474,7 +474,16 @@ static int xs_nospace(struct rpc_task *t
+ spin_unlock_bh(&xprt->transport_lock);
+
+ /* Race breaker in case memory is freed before above code is called */
+- sk->sk_write_space(sk);
++ if (ret == -EAGAIN) {
++ struct socket_wq *wq;
++
++ rcu_read_lock();
++ wq = rcu_dereference(sk->sk_wq);
++ set_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags);
++ rcu_read_unlock();
++
++ sk->sk_write_space(sk);
++ }
+ return ret;
+ }
+
--- /dev/null
+From 4eeaa4f3f1d6c47b69f70e222297a4df4743363e Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Wed, 10 Aug 2016 18:30:46 +0200
+Subject: zfcp: close window with unblocked rport during rport gone
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 4eeaa4f3f1d6c47b69f70e222297a4df4743363e upstream.
+
+On a successful end of reopen port forced,
+zfcp_erp_strategy_followup_success() re-uses the port erp_action
+and the subsequent zfcp_erp_action_cleanup() now
+sees ZFCP_ERP_SUCCEEDED with
+erp_action->action==ZFCP_ERP_ACTION_REOPEN_PORT
+instead of ZFCP_ERP_ACTION_REOPEN_PORT_FORCED
+but must not perform zfcp_scsi_schedule_rport_register().
+
+We can detect this because the fresh port reopen erp_action
+is in its very first step ZFCP_ERP_STEP_UNINITIALIZED.
+
+Otherwise this opens a time window with unblocked rport
+(until the followup port reopen recovery would block it again).
+If a scsi_cmnd timeout occurs during this time window
+fc_timed_out() cannot work as desired and such command
+would indeed time out and trigger scsi_eh. This prevents
+a clean and timely path failover.
+This should not happen if the path issue can be recovered
+on FC transport layer such as path issues involving RSCNs.
+
+Also, unnecessary and repeated DID_IMM_RETRY for pending and
+undesired new requests occur because internally zfcp still
+has its zfcp_port blocked.
+
+As follow-on errors with scsi_eh, it can cause,
+in the worst case, permanently lost paths due to one of:
+sd <scsidev>: [<scsidisk>] Medium access timeout failure. Offlining disk!
+sd <scsidev>: Device offlined - not ready after error recovery
+
+For fix validation and to aid future debugging with other recoveries
+we now also trace (un)blocking of rports.
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 5767620c383a ("[SCSI] zfcp: Do not unblock rport from REOPEN_PORT_FORCED")
+Fixes: a2fa0aede07c ("[SCSI] zfcp: Block FC transport rports early on errors")
+Fixes: 5f852be9e11d ("[SCSI] zfcp: Fix deadlock between zfcp ERP and SCSI")
+Fixes: 338151e06608 ("[SCSI] zfcp: make use of fc_remote_port_delete when target port is unavailable")
+Fixes: 3859f6a248cb ("[PATCH] zfcp: add rports to enable scsi_add_device to work again")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_dbf.h | 7 ++++++-
+ drivers/s390/scsi/zfcp_erp.c | 12 +++++++++---
+ drivers/s390/scsi/zfcp_scsi.c | 8 +++++++-
+ 3 files changed, 22 insertions(+), 5 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.h
++++ b/drivers/s390/scsi/zfcp_dbf.h
+@@ -2,7 +2,7 @@
+ * zfcp device driver
+ * debug feature declarations
+ *
+- * Copyright IBM Corp. 2008, 2010
++ * Copyright IBM Corp. 2008, 2015
+ */
+
+ #ifndef ZFCP_DBF_H
+@@ -17,6 +17,11 @@
+
+ #define ZFCP_DBF_INVALID_LUN 0xFFFFFFFFFFFFFFFFull
+
++enum zfcp_dbf_pseudo_erp_act_type {
++ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD = 0xff,
++ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL = 0xfe,
++};
++
+ /**
+ * struct zfcp_dbf_rec_trigger - trace record for triggered recovery action
+ * @ready: number of ready recovery actions
+--- a/drivers/s390/scsi/zfcp_erp.c
++++ b/drivers/s390/scsi/zfcp_erp.c
+@@ -3,7 +3,7 @@
+ *
+ * Error Recovery Procedures (ERP).
+ *
+- * Copyright IBM Corp. 2002, 2010
++ * Copyright IBM Corp. 2002, 2015
+ */
+
+ #define KMSG_COMPONENT "zfcp"
+@@ -1217,8 +1217,14 @@ static void zfcp_erp_action_cleanup(stru
+ break;
+
+ case ZFCP_ERP_ACTION_REOPEN_PORT:
+- if (result == ZFCP_ERP_SUCCEEDED)
+- zfcp_scsi_schedule_rport_register(port);
++ /* This switch case might also happen after a forced reopen
++ * was successfully done and thus overwritten with a new
++ * non-forced reopen at `ersfs_2'. In this case, we must not
++ * do the clean-up of the non-forced version.
++ */
++ if (act->step != ZFCP_ERP_STEP_UNINITIALIZED)
++ if (result == ZFCP_ERP_SUCCEEDED)
++ zfcp_scsi_schedule_rport_register(port);
+ /* fall through */
+ case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
+ put_device(&port->dev);
+--- a/drivers/s390/scsi/zfcp_scsi.c
++++ b/drivers/s390/scsi/zfcp_scsi.c
+@@ -3,7 +3,7 @@
+ *
+ * Interface to Linux SCSI midlayer.
+ *
+- * Copyright IBM Corp. 2002, 2013
++ * Copyright IBM Corp. 2002, 2015
+ */
+
+ #define KMSG_COMPONENT "zfcp"
+@@ -556,6 +556,9 @@ static void zfcp_scsi_rport_register(str
+ ids.port_id = port->d_id;
+ ids.roles = FC_RPORT_ROLE_FCP_TARGET;
+
++ zfcp_dbf_rec_trig("scpaddy", port->adapter, port, NULL,
++ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD,
++ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD);
+ rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids);
+ if (!rport) {
+ dev_err(&port->adapter->ccw_device->dev,
+@@ -577,6 +580,9 @@ static void zfcp_scsi_rport_block(struct
+ struct fc_rport *rport = port->rport;
+
+ if (rport) {
++ zfcp_dbf_rec_trig("scpdely", port->adapter, port, NULL,
++ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL,
++ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL);
+ fc_remote_port_delete(rport);
+ port->rport = NULL;
+ }
--- /dev/null
+From 771bf03537ddfa4a4dde62ef9dfbc82e4f77ab20 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Wed, 10 Aug 2016 18:30:51 +0200
+Subject: zfcp: fix D_ID field with actual value on tracing SAN responses
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 771bf03537ddfa4a4dde62ef9dfbc82e4f77ab20 upstream.
+
+With commit 2c55b750a884b86dea8b4cc5f15e1484cc47a25c
+("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
+we lost the N_Port-ID where an ELS response comes from.
+With commit 7c7dc196814b9e1d5cc254dc579a5fa78ae524f7
+("[SCSI] zfcp: Simplify handling of ct and els requests")
+we lost the N_Port-ID where a CT response comes from.
+It's especially useful if the request SAN trace record
+with D_ID was already lost due to trace buffer wrap.
+
+GS uses an open WKA port handle and ELS just a D_ID, and
+only for ELS we could get D_ID from QTCB bottom via zfcp_fsf_req.
+To cover both cases, add a new field to zfcp_fsf_ct_els
+and fill it in on request to use in SAN response trace.
+Strictly speaking the D_ID on SAN response is the FC frame's S_ID.
+We don't need a field for the other end which is always us.
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 2c55b750a884 ("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
+Fixes: 7c7dc196814b ("[SCSI] zfcp: Simplify handling of ct and els requests")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_dbf.c | 2 +-
+ drivers/s390/scsi/zfcp_fsf.c | 2 ++
+ drivers/s390/scsi/zfcp_fsf.h | 4 +++-
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -407,7 +407,7 @@ void zfcp_dbf_san_res(char *tag, struct
+
+ length = (u16)(ct_els->resp->length + FC_CT_HDR_LEN);
+ zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length,
+- fsf->req_id, 0);
++ fsf->req_id, ct_els->d_id);
+ }
+
+ /**
+--- a/drivers/s390/scsi/zfcp_fsf.c
++++ b/drivers/s390/scsi/zfcp_fsf.c
+@@ -1079,6 +1079,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_
+
+ req->handler = zfcp_fsf_send_ct_handler;
+ req->qtcb->header.port_handle = wka_port->handle;
++ ct->d_id = wka_port->d_id;
+ req->data = ct;
+
+ zfcp_dbf_san_req("fssct_1", req, wka_port->d_id);
+@@ -1175,6 +1176,7 @@ int zfcp_fsf_send_els(struct zfcp_adapte
+
+ hton24(req->qtcb->bottom.support.d_id, d_id);
+ req->handler = zfcp_fsf_send_els_handler;
++ els->d_id = d_id;
+ req->data = els;
+
+ zfcp_dbf_san_req("fssels1", req, d_id);
+--- a/drivers/s390/scsi/zfcp_fsf.h
++++ b/drivers/s390/scsi/zfcp_fsf.h
+@@ -3,7 +3,7 @@
+ *
+ * Interface to the FSF support functions.
+ *
+- * Copyright IBM Corp. 2002, 2010
++ * Copyright IBM Corp. 2002, 2015
+ */
+
+ #ifndef FSF_H
+@@ -436,6 +436,7 @@ struct zfcp_blk_drv_data {
+ * @handler_data: data passed to handler function
+ * @port: Optional pointer to port for zfcp internal ELS (only test link ADISC)
+ * @status: used to pass error status to calling function
++ * @d_id: Destination ID of either open WKA port for CT or of D_ID for ELS
+ */
+ struct zfcp_fsf_ct_els {
+ struct scatterlist *req;
+@@ -444,6 +445,7 @@ struct zfcp_fsf_ct_els {
+ void *handler_data;
+ struct zfcp_port *port;
+ int status;
++ u32 d_id;
+ };
+
+ #endif /* FSF_H */
--- /dev/null
+From 70369f8e15b220f50a16348c79a61d3f7054813c Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Wed, 10 Aug 2016 18:30:45 +0200
+Subject: zfcp: fix ELS/GS request&response length for hardware data router
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 70369f8e15b220f50a16348c79a61d3f7054813c upstream.
+
+In the hardware data router case, introduced with kernel 3.2
+commit 86a9668a8d29 ("[SCSI] zfcp: support for hardware data router")
+the ELS/GS request&response length needs to be initialized
+as in the chained SBAL case.
+
+Otherwise, the FCP channel rejects ELS requests with
+FSF_REQUEST_SIZE_TOO_LARGE.
+
+Such ELS requests can be issued by user space through BSG / HBA API,
+or zfcp itself uses ADISC ELS for remote port link test on RSCN.
+The latter can cause a short path outage due to
+unnecessary remote target port recovery because the always
+failing ADISC cannot detect extremely short path interruptions
+beyond the local FCP channel.
+
+Below example is decoded with zfcpdbf from s390-tools:
+
+Timestamp : ...
+Area : SAN
+Subarea : 00
+Level : 1
+Exception : -
+CPU id : ..
+Caller : zfcp_dbf_san_req+0408
+Record id : 1
+Tag : fssels1
+Request id : 0x<reqid>
+Destination ID : 0x00<target d_id>
+Payload info : 52000000 00000000 <our wwpn > [ADISC]
+ <our wwnn > 00<s_id> 00000000
+ 00000000 00000000 00000000 00000000
+
+Timestamp : ...
+Area : HBA
+Subarea : 00
+Level : 1
+Exception : -
+CPU id : ..
+Caller : zfcp_dbf_hba_fsf_res+0740
+Record id : 1
+Tag : fs_ferr
+Request id : 0x<reqid>
+Request status : 0x00000010
+FSF cmnd : 0x0000000b [FSF_QTCB_SEND_ELS]
+FSF sequence no: 0x...
+FSF issued : ...
+FSF stat : 0x00000061 [FSF_REQUEST_SIZE_TOO_LARGE]
+FSF stat qual : 00000000 00000000 00000000 00000000
+Prot stat : 0x00000100
+Prot stat qual : 00000000 00000000 00000000 00000000
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 86a9668a8d29 ("[SCSI] zfcp: support for hardware data router")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_fsf.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/s390/scsi/zfcp_fsf.c
++++ b/drivers/s390/scsi/zfcp_fsf.c
+@@ -984,8 +984,12 @@ static int zfcp_fsf_setup_ct_els_sbals(s
+ if (zfcp_adapter_multi_buffer_active(adapter)) {
+ if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_req))
+ return -EIO;
++ qtcb->bottom.support.req_buf_length =
++ zfcp_qdio_real_bytes(sg_req);
+ if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_resp))
+ return -EIO;
++ qtcb->bottom.support.resp_buf_length =
++ zfcp_qdio_real_bytes(sg_resp);
+
+ zfcp_qdio_set_data_div(qdio, &req->qdio_req,
+ zfcp_qdio_sbale_count(sg_req));
--- /dev/null
+From bd77befa5bcff8c51613de271913639edf85fbc2 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Wed, 10 Aug 2016 18:30:44 +0200
+Subject: zfcp: fix fc_host port_type with NPIV
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit bd77befa5bcff8c51613de271913639edf85fbc2 upstream.
+
+For an NPIV-enabled FCP device, zfcp can erroneously show
+"NPort (fabric via point-to-point)" instead of "NPIV VPORT"
+for the port_type sysfs attribute of the corresponding
+fc_host.
+s390-tools that can be affected are dbginfo.sh and ziomon.
+
+zfcp_fsf_exchange_config_evaluate() ignores
+fsf_qtcb_bottom_config.connection_features indicating NPIV
+and only sets fc_host_port_type to FC_PORTTYPE_NPORT if
+fsf_qtcb_bottom_config.fc_topology is FSF_TOPO_FABRIC.
+
+Only the independent zfcp_fsf_exchange_port_evaluate()
+evaluates connection_features to overwrite fc_host_port_type
+to FC_PORTTYPE_NPIV in case of NPIV.
+Code was introduced with upstream kernel 2.6.30
+commit 0282985da5923fa6365adcc1a1586ae0c13c1617
+("[SCSI] zfcp: Report fc_host_port_type as NPIV").
+
+This works during FCP device recovery (such as set online)
+because it performs FSF_QTCB_EXCHANGE_CONFIG_DATA followed by
+FSF_QTCB_EXCHANGE_PORT_DATA in sequence.
+
+However, the zfcp-specific scsi host sysfs attributes
+"requests", "megabytes", or "seconds_active" trigger only
+zfcp_fsf_exchange_config_evaluate() resetting fc_host
+port_type to FC_PORTTYPE_NPORT despite NPIV.
+
+The zfcp-specific scsi host sysfs attribute "utilization"
+triggers only zfcp_fsf_exchange_port_evaluate() correcting
+the fc_host port_type again in case of NPIV.
+
+Evaluate fsf_qtcb_bottom_config.connection_features
+in zfcp_fsf_exchange_config_evaluate() where it belongs to.
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 0282985da592 ("[SCSI] zfcp: Report fc_host_port_type as NPIV")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_fsf.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_fsf.c
++++ b/drivers/s390/scsi/zfcp_fsf.c
+@@ -3,7 +3,7 @@
+ *
+ * Implementation of FSF commands.
+ *
+- * Copyright IBM Corp. 2002, 2013
++ * Copyright IBM Corp. 2002, 2015
+ */
+
+ #define KMSG_COMPONENT "zfcp"
+@@ -508,7 +508,10 @@ static int zfcp_fsf_exchange_config_eval
+ fc_host_port_type(shost) = FC_PORTTYPE_PTP;
+ break;
+ case FSF_TOPO_FABRIC:
+- fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
++ if (bottom->connection_features & FSF_FEATURE_NPIV_MODE)
++ fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
++ else
++ fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
+ break;
+ case FSF_TOPO_AL:
+ fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
+@@ -613,7 +616,6 @@ static void zfcp_fsf_exchange_port_evalu
+
+ if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) {
+ fc_host_permanent_port_name(shost) = bottom->wwpn;
+- fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
+ } else
+ fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
+ fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
--- /dev/null
+From 94db3725f049ead24c96226df4a4fb375b880a77 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Wed, 10 Aug 2016 18:30:52 +0200
+Subject: zfcp: fix payload trace length for SAN request&response
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 94db3725f049ead24c96226df4a4fb375b880a77 upstream.
+
+commit 2c55b750a884b86dea8b4cc5f15e1484cc47a25c
+("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
+started to add FC_CT_HDR_LEN which made zfcp dump random data
+out of bounds for RSPN GS responses because u.rspn.rsp
+is the largest and last field in the union of struct zfcp_fc_req.
+Other request/response types only happened to stay within bounds
+due to the padding of the union or
+due to the trace capping of u.gspn.rsp to ZFCP_DBF_SAN_MAX_PAYLOAD.
+
+Timestamp : ...
+Area : SAN
+Subarea : 00
+Level : 1
+Exception : -
+CPU id : ..
+Caller : ...
+Record id : 2
+Tag : fsscth2
+Request id : 0x...
+Destination ID : 0x00fffffc
+Payload short : 01000000 fc020000 80020000 00000000
+ xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx <===
+ 00000000 00000000 00000000 00000000
+Payload length : 32 <===
+
+struct zfcp_fc_req {
+ [0] struct zfcp_fsf_ct_els ct_els;
+ [56] struct scatterlist sg_req;
+ [96] struct scatterlist sg_rsp;
+ union {
+ struct {req; rsp;} adisc; SIZE: 28+28= 56
+ struct {req; rsp;} gid_pn; SIZE: 24+20= 44
+ struct {rspsg; req;} gpn_ft; SIZE: 40*4+20=180
+ struct {req; rsp;} gspn; SIZE: 20+273= 293
+ struct {req; rsp;} rspn; SIZE: 277+16= 293
+ [136] } u;
+}
+SIZE: 432
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 2c55b750a884 ("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
+Reviewed-by: Alexey Ishchuk <aishchuk@linux.vnet.ibm.com>
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_dbf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -389,7 +389,7 @@ void zfcp_dbf_san_req(char *tag, struct
+ struct zfcp_fsf_ct_els *ct_els = fsf->data;
+ u16 length;
+
+- length = (u16)(ct_els->req->length + FC_CT_HDR_LEN);
++ length = (u16)(ct_els->req->length);
+ zfcp_dbf_san(tag, dbf, sg_virt(ct_els->req), ZFCP_DBF_SAN_REQ, length,
+ fsf->req_id, d_id);
+ }
+@@ -405,7 +405,7 @@ void zfcp_dbf_san_res(char *tag, struct
+ struct zfcp_fsf_ct_els *ct_els = fsf->data;
+ u16 length;
+
+- length = (u16)(ct_els->resp->length + FC_CT_HDR_LEN);
++ length = (u16)(ct_els->resp->length);
+ zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length,
+ fsf->req_id, ct_els->d_id);
+ }
--- /dev/null
+From 0102a30a6ff60f4bb4c07358ca3b1f92254a6c25 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Wed, 10 Aug 2016 18:30:48 +0200
+Subject: zfcp: restore: Dont use 0 to indicate invalid LUN in rec trace
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 0102a30a6ff60f4bb4c07358ca3b1f92254a6c25 upstream.
+
+bring back
+commit d21e9daa63e009ce5b87bbcaa6d11ce48e07bbbe
+("[SCSI] zfcp: Dont use 0 to indicate invalid LUN in rec trace")
+which was lost with
+commit ae0904f60fab7cb20c48d32eefdd735e478b91fb
+("[SCSI] zfcp: Redesign of the debug tracing for recovery actions.")
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: ae0904f60fab ("[SCSI] zfcp: Redesign of the debug tracing for recovery actions.")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_dbf.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -241,7 +241,8 @@ static void zfcp_dbf_set_common(struct z
+ if (sdev) {
+ rec->lun_status = atomic_read(&sdev_to_zfcp(sdev)->status);
+ rec->lun = zfcp_scsi_dev_lun(sdev);
+- }
++ } else
++ rec->lun = ZFCP_DBF_INVALID_LUN;
+ }
+
+ /**
--- /dev/null
+From 7c964ffe586bc0c3d9febe9bf97a2e4b2866e5b7 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Wed, 10 Aug 2016 18:30:50 +0200
+Subject: zfcp: restore tracing of handle for port and LUN with HBA records
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 7c964ffe586bc0c3d9febe9bf97a2e4b2866e5b7 upstream.
+
+This information was lost with
+commit a54ca0f62f953898b05549391ac2a8a4dad6482b
+("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")
+but is required to debug e.g. invalid handle situations.
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: a54ca0f62f95 ("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_dbf.c | 2 ++
+ drivers/s390/scsi/zfcp_dbf.h | 2 ++
+ 2 files changed, 4 insertions(+)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -85,6 +85,8 @@ void zfcp_dbf_hba_fsf_res(char *tag, int
+ rec->u.res.req_issued = req->issued;
+ rec->u.res.prot_status = q_pref->prot_status;
+ rec->u.res.fsf_status = q_head->fsf_status;
++ rec->u.res.port_handle = q_head->port_handle;
++ rec->u.res.lun_handle = q_head->lun_handle;
+
+ memcpy(rec->u.res.prot_status_qual, &q_pref->prot_status_qual,
+ FSF_PROT_STATUS_QUAL_SIZE);
+--- a/drivers/s390/scsi/zfcp_dbf.h
++++ b/drivers/s390/scsi/zfcp_dbf.h
+@@ -131,6 +131,8 @@ struct zfcp_dbf_hba_res {
+ u8 prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
+ u32 fsf_status;
+ u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
++ u32 port_handle;
++ u32 lun_handle;
+ } __packed;
+
+ /**
--- /dev/null
+From 35f040df97fa0e94c7851c054ec71533c88b4b81 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Wed, 10 Aug 2016 18:30:47 +0200
+Subject: zfcp: retain trace level for SCSI and HBA FSF response records
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit 35f040df97fa0e94c7851c054ec71533c88b4b81 upstream.
+
+While retaining the actual filtering according to trace level,
+the following commits started to write such filtered records
+with a hardcoded record level of 1 instead of the actual record level:
+commit 250a1352b95e1db3216e5c5d4f4365bea5122f4a
+("[SCSI] zfcp: Redesign of the debug tracing for SCSI records.")
+commit a54ca0f62f953898b05549391ac2a8a4dad6482b
+("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")
+
+Now we can distinguish written records again for offline level filtering.
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 250a1352b95e ("[SCSI] zfcp: Redesign of the debug tracing for SCSI records.")
+Fixes: a54ca0f62f95 ("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_dbf.c | 11 ++++++-----
+ drivers/s390/scsi/zfcp_dbf.h | 4 ++--
+ drivers/s390/scsi/zfcp_ext.h | 7 ++++---
+ 3 files changed, 12 insertions(+), 10 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -3,7 +3,7 @@
+ *
+ * Debug traces for zfcp.
+ *
+- * Copyright IBM Corp. 2002, 2013
++ * Copyright IBM Corp. 2002, 2015
+ */
+
+ #define KMSG_COMPONENT "zfcp"
+@@ -65,7 +65,7 @@ void zfcp_dbf_pl_write(struct zfcp_dbf *
+ * @tag: tag indicating which kind of unsolicited status has been received
+ * @req: request for which a response was received
+ */
+-void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req)
++void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req)
+ {
+ struct zfcp_dbf *dbf = req->adapter->dbf;
+ struct fsf_qtcb_prefix *q_pref = &req->qtcb->prefix;
+@@ -97,7 +97,7 @@ void zfcp_dbf_hba_fsf_res(char *tag, str
+ rec->pl_len, "fsf_res", req->req_id);
+ }
+
+- debug_event(dbf->hba, 1, rec, sizeof(*rec));
++ debug_event(dbf->hba, level, rec, sizeof(*rec));
+ spin_unlock_irqrestore(&dbf->hba_lock, flags);
+ }
+
+@@ -399,7 +399,8 @@ void zfcp_dbf_san_in_els(char *tag, stru
+ * @sc: pointer to struct scsi_cmnd
+ * @fsf: pointer to struct zfcp_fsf_req
+ */
+-void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf)
++void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc,
++ struct zfcp_fsf_req *fsf)
+ {
+ struct zfcp_adapter *adapter =
+ (struct zfcp_adapter *) sc->device->host->hostdata[0];
+@@ -442,7 +443,7 @@ void zfcp_dbf_scsi(char *tag, struct scs
+ }
+ }
+
+- debug_event(dbf->scsi, 1, rec, sizeof(*rec));
++ debug_event(dbf->scsi, level, rec, sizeof(*rec));
+ spin_unlock_irqrestore(&dbf->scsi_lock, flags);
+ }
+
+--- a/drivers/s390/scsi/zfcp_dbf.h
++++ b/drivers/s390/scsi/zfcp_dbf.h
+@@ -284,7 +284,7 @@ static inline
+ void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
+ {
+ if (debug_level_enabled(req->adapter->dbf->hba, level))
+- zfcp_dbf_hba_fsf_res(tag, req);
++ zfcp_dbf_hba_fsf_res(tag, level, req);
+ }
+
+ /**
+@@ -323,7 +323,7 @@ void _zfcp_dbf_scsi(char *tag, int level
+ scmd->device->host->hostdata[0];
+
+ if (debug_level_enabled(adapter->dbf->scsi, level))
+- zfcp_dbf_scsi(tag, scmd, req);
++ zfcp_dbf_scsi(tag, level, scmd, req);
+ }
+
+ /**
+--- a/drivers/s390/scsi/zfcp_ext.h
++++ b/drivers/s390/scsi/zfcp_ext.h
+@@ -3,7 +3,7 @@
+ *
+ * External function declarations.
+ *
+- * Copyright IBM Corp. 2002, 2010
++ * Copyright IBM Corp. 2002, 2015
+ */
+
+ #ifndef ZFCP_EXT_H
+@@ -36,7 +36,7 @@ extern void zfcp_dbf_rec_trig(char *, st
+ struct zfcp_port *, struct scsi_device *, u8, u8);
+ extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *);
+ extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *);
+-extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *);
++extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *);
+ extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
+ extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
+ extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **);
+@@ -44,7 +44,8 @@ extern void zfcp_dbf_hba_basic(char *, s
+ extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
+ extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *);
+ extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *);
+-extern void zfcp_dbf_scsi(char *, struct scsi_cmnd *, struct zfcp_fsf_req *);
++extern void zfcp_dbf_scsi(char *, int, struct scsi_cmnd *,
++ struct zfcp_fsf_req *);
+
+ /* zfcp_erp.c */
+ extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
--- /dev/null
+From aceeffbb59bb91404a0bda32a542d7ebf878433a Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Wed, 10 Aug 2016 18:30:53 +0200
+Subject: zfcp: trace full payload of all SAN records (req,resp,iels)
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit aceeffbb59bb91404a0bda32a542d7ebf878433a upstream.
+
+This was lost with commit 2c55b750a884b86dea8b4cc5f15e1484cc47a25c
+("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
+but is necessary for problem determination, e.g. to see the
+currently active zone set during automatic port scan.
+
+For the large GPN_FT response (4 pages), save space by not dumping
+any empty residual entries.
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: 2c55b750a884 ("[SCSI] zfcp: Redesign of the debug tracing for SAN records.")
+Reviewed-by: Alexey Ishchuk <aishchuk@linux.vnet.ibm.com>
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_dbf.c | 116 ++++++++++++++++++++++++++++++++++++++-----
+ drivers/s390/scsi/zfcp_dbf.h | 1
+ 2 files changed, 104 insertions(+), 13 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -3,7 +3,7 @@
+ *
+ * Debug traces for zfcp.
+ *
+- * Copyright IBM Corp. 2002, 2015
++ * Copyright IBM Corp. 2002, 2016
+ */
+
+ #define KMSG_COMPONENT "zfcp"
+@@ -356,12 +356,15 @@ void zfcp_dbf_rec_run_wka(char *tag, str
+ }
+
+ static inline
+-void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len,
+- u64 req_id, u32 d_id)
++void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf,
++ char *paytag, struct scatterlist *sg, u8 id, u16 len,
++ u64 req_id, u32 d_id, u16 cap_len)
+ {
+ struct zfcp_dbf_san *rec = &dbf->san_buf;
+ u16 rec_len;
+ unsigned long flags;
++ struct zfcp_dbf_pay *payload = &dbf->pay_buf;
++ u16 pay_sum = 0;
+
+ spin_lock_irqsave(&dbf->san_lock, flags);
+ memset(rec, 0, sizeof(*rec));
+@@ -369,10 +372,41 @@ void zfcp_dbf_san(char *tag, struct zfcp
+ rec->id = id;
+ rec->fsf_req_id = req_id;
+ rec->d_id = d_id;
+- rec_len = min(len, (u16)ZFCP_DBF_SAN_MAX_PAYLOAD);
+- memcpy(rec->payload, data, rec_len);
+ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
++ rec->pl_len = len; /* full length even if we cap pay below */
++ if (!sg)
++ goto out;
++ rec_len = min_t(unsigned int, sg->length, ZFCP_DBF_SAN_MAX_PAYLOAD);
++ memcpy(rec->payload, sg_virt(sg), rec_len); /* part of 1st sg entry */
++ if (len <= rec_len)
++ goto out; /* skip pay record if full content in rec->payload */
++
++ /* if (len > rec_len):
++ * dump data up to cap_len ignoring small duplicate in rec->payload
++ */
++ spin_lock_irqsave(&dbf->pay_lock, flags);
++ memset(payload, 0, sizeof(*payload));
++ memcpy(payload->area, paytag, ZFCP_DBF_TAG_LEN);
++ payload->fsf_req_id = req_id;
++ payload->counter = 0;
++ for (; sg && pay_sum < cap_len; sg = sg_next(sg)) {
++ u16 pay_len, offset = 0;
++
++ while (offset < sg->length && pay_sum < cap_len) {
++ pay_len = min((u16)ZFCP_DBF_PAY_MAX_REC,
++ (u16)(sg->length - offset));
++ /* cap_len <= pay_sum < cap_len+ZFCP_DBF_PAY_MAX_REC */
++ memcpy(payload->data, sg_virt(sg) + offset, pay_len);
++ debug_event(dbf->pay, 1, payload,
++ zfcp_dbf_plen(pay_len));
++ payload->counter++;
++ offset += pay_len;
++ pay_sum += pay_len;
++ }
++ }
++ spin_unlock(&dbf->pay_lock);
+
++out:
+ debug_event(dbf->san, 1, rec, sizeof(*rec));
+ spin_unlock_irqrestore(&dbf->san_lock, flags);
+ }
+@@ -389,9 +423,62 @@ void zfcp_dbf_san_req(char *tag, struct
+ struct zfcp_fsf_ct_els *ct_els = fsf->data;
+ u16 length;
+
+- length = (u16)(ct_els->req->length);
+- zfcp_dbf_san(tag, dbf, sg_virt(ct_els->req), ZFCP_DBF_SAN_REQ, length,
+- fsf->req_id, d_id);
++ length = (u16)zfcp_qdio_real_bytes(ct_els->req);
++ zfcp_dbf_san(tag, dbf, "san_req", ct_els->req, ZFCP_DBF_SAN_REQ,
++ length, fsf->req_id, d_id, length);
++}
++
++static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag,
++ struct zfcp_fsf_req *fsf,
++ u16 len)
++{
++ struct zfcp_fsf_ct_els *ct_els = fsf->data;
++ struct fc_ct_hdr *reqh = sg_virt(ct_els->req);
++ struct fc_ns_gid_ft *reqn = (struct fc_ns_gid_ft *)(reqh + 1);
++ struct scatterlist *resp_entry = ct_els->resp;
++ struct fc_gpn_ft_resp *acc;
++ int max_entries, x, last = 0;
++
++ if (!(memcmp(tag, "fsscth2", 7) == 0
++ && ct_els->d_id == FC_FID_DIR_SERV
++ && reqh->ct_rev == FC_CT_REV
++ && reqh->ct_in_id[0] == 0
++ && reqh->ct_in_id[1] == 0
++ && reqh->ct_in_id[2] == 0
++ && reqh->ct_fs_type == FC_FST_DIR
++ && reqh->ct_fs_subtype == FC_NS_SUBTYPE
++ && reqh->ct_options == 0
++ && reqh->_ct_resvd1 == 0
++ && reqh->ct_cmd == FC_NS_GPN_FT
++ /* reqh->ct_mr_size can vary so do not match but read below */
++ && reqh->_ct_resvd2 == 0
++ && reqh->ct_reason == 0
++ && reqh->ct_explan == 0
++ && reqh->ct_vendor == 0
++ && reqn->fn_resvd == 0
++ && reqn->fn_domain_id_scope == 0
++ && reqn->fn_area_id_scope == 0
++ && reqn->fn_fc4_type == FC_TYPE_FCP))
++ return len; /* not GPN_FT response so do not cap */
++
++ acc = sg_virt(resp_entry);
++ max_entries = (reqh->ct_mr_size * 4 / sizeof(struct fc_gpn_ft_resp))
++ + 1 /* zfcp_fc_scan_ports: bytes correct, entries off-by-one
++ * to account for header as 1st pseudo "entry" */;
++
++ /* the basic CT_IU preamble is the same size as one entry in the GPN_FT
++ * response, allowing us to skip special handling for it - just skip it
++ */
++ for (x = 1; x < max_entries && !last; x++) {
++ if (x % (ZFCP_FC_GPN_FT_ENT_PAGE + 1))
++ acc++;
++ else
++ acc = sg_virt(++resp_entry);
++
++ last = acc->fp_flags & FC_NS_FID_LAST;
++ }
++ len = min(len, (u16)(x * sizeof(struct fc_gpn_ft_resp)));
++ return len; /* cap after last entry */
+ }
+
+ /**
+@@ -405,9 +492,10 @@ void zfcp_dbf_san_res(char *tag, struct
+ struct zfcp_fsf_ct_els *ct_els = fsf->data;
+ u16 length;
+
+- length = (u16)(ct_els->resp->length);
+- zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length,
+- fsf->req_id, ct_els->d_id);
++ length = (u16)zfcp_qdio_real_bytes(ct_els->resp);
++ zfcp_dbf_san(tag, dbf, "san_res", ct_els->resp, ZFCP_DBF_SAN_RES,
++ length, fsf->req_id, ct_els->d_id,
++ zfcp_dbf_san_res_cap_len_if_gpn_ft(tag, fsf, length));
+ }
+
+ /**
+@@ -421,11 +509,13 @@ void zfcp_dbf_san_in_els(char *tag, stru
+ struct fsf_status_read_buffer *srb =
+ (struct fsf_status_read_buffer *) fsf->data;
+ u16 length;
++ struct scatterlist sg;
+
+ length = (u16)(srb->length -
+ offsetof(struct fsf_status_read_buffer, payload));
+- zfcp_dbf_san(tag, dbf, srb->payload.data, ZFCP_DBF_SAN_ELS, length,
+- fsf->req_id, ntoh24(srb->d_id));
++ sg_init_one(&sg, srb->payload.data, length);
++ zfcp_dbf_san(tag, dbf, "san_els", &sg, ZFCP_DBF_SAN_ELS, length,
++ fsf->req_id, ntoh24(srb->d_id), length);
+ }
+
+ /**
+--- a/drivers/s390/scsi/zfcp_dbf.h
++++ b/drivers/s390/scsi/zfcp_dbf.h
+@@ -115,6 +115,7 @@ struct zfcp_dbf_san {
+ u32 d_id;
+ #define ZFCP_DBF_SAN_MAX_PAYLOAD (FC_CT_HDR_LEN + 32)
+ char payload[ZFCP_DBF_SAN_MAX_PAYLOAD];
++ u16 pl_len;
+ } __packed;
+
+ /**
--- /dev/null
+From d27a7cb91960cf1fdd11b10071e601828cbf4b1f Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+Date: Wed, 10 Aug 2016 18:30:49 +0200
+Subject: zfcp: trace on request for open and close of WKA port
+
+From: Steffen Maier <maier@linux.vnet.ibm.com>
+
+commit d27a7cb91960cf1fdd11b10071e601828cbf4b1f upstream.
+
+Since commit a54ca0f62f953898b05549391ac2a8a4dad6482b
+("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")
+HBA records no longer contain WWPN, D_ID, or LUN
+to reduce duplicate information which is already in REC records.
+In contrast to "regular" target ports, we don't use recovery to open
+WKA ports such as directory/nameserver, so we don't get REC records.
+Therefore, introduce pseudo REC running records without any
+actual recovery action but including D_ID of WKA port on open/close.
+
+Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
+Fixes: a54ca0f62f95 ("[SCSI] zfcp: Redesign of the debug tracing for HBA records.")
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_dbf.c | 32 ++++++++++++++++++++++++++++++++
+ drivers/s390/scsi/zfcp_ext.h | 1 +
+ drivers/s390/scsi/zfcp_fsf.c | 8 ++++++--
+ 3 files changed, 39 insertions(+), 2 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -321,6 +321,38 @@ void zfcp_dbf_rec_run(char *tag, struct
+ spin_unlock_irqrestore(&dbf->rec_lock, flags);
+ }
+
++/**
++ * zfcp_dbf_rec_run_wka - trace wka port event with info like running recovery
++ * @tag: identifier for event
++ * @wka_port: well known address port
++ * @req_id: request ID to correlate with potential HBA trace record
++ */
++void zfcp_dbf_rec_run_wka(char *tag, struct zfcp_fc_wka_port *wka_port,
++ u64 req_id)
++{
++ struct zfcp_dbf *dbf = wka_port->adapter->dbf;
++ struct zfcp_dbf_rec *rec = &dbf->rec_buf;
++ unsigned long flags;
++
++ spin_lock_irqsave(&dbf->rec_lock, flags);
++ memset(rec, 0, sizeof(*rec));
++
++ rec->id = ZFCP_DBF_REC_RUN;
++ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
++ rec->port_status = wka_port->status;
++ rec->d_id = wka_port->d_id;
++ rec->lun = ZFCP_DBF_INVALID_LUN;
++
++ rec->u.run.fsf_req_id = req_id;
++ rec->u.run.rec_status = ~0;
++ rec->u.run.rec_step = ~0;
++ rec->u.run.rec_action = ~0;
++ rec->u.run.rec_count = ~0;
++
++ debug_event(dbf->rec, 1, rec, sizeof(*rec));
++ spin_unlock_irqrestore(&dbf->rec_lock, flags);
++}
++
+ static inline
+ void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len,
+ u64 req_id, u32 d_id)
+--- a/drivers/s390/scsi/zfcp_ext.h
++++ b/drivers/s390/scsi/zfcp_ext.h
+@@ -35,6 +35,7 @@ extern void zfcp_dbf_adapter_unregister(
+ extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *,
+ struct zfcp_port *, struct scsi_device *, u8, u8);
+ extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *);
++extern void zfcp_dbf_rec_run_wka(char *, struct zfcp_fc_wka_port *, u64);
+ extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *);
+ extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *);
+ extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
+--- a/drivers/s390/scsi/zfcp_fsf.c
++++ b/drivers/s390/scsi/zfcp_fsf.c
+@@ -1581,7 +1581,7 @@ out:
+ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
+ {
+ struct zfcp_qdio *qdio = wka_port->adapter->qdio;
+- struct zfcp_fsf_req *req;
++ struct zfcp_fsf_req *req = NULL;
+ int retval = -EIO;
+
+ spin_lock_irq(&qdio->req_q_lock);
+@@ -1610,6 +1610,8 @@ int zfcp_fsf_open_wka_port(struct zfcp_f
+ zfcp_fsf_req_free(req);
+ out:
+ spin_unlock_irq(&qdio->req_q_lock);
++ if (req && !IS_ERR(req))
++ zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id);
+ return retval;
+ }
+
+@@ -1634,7 +1636,7 @@ static void zfcp_fsf_close_wka_port_hand
+ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
+ {
+ struct zfcp_qdio *qdio = wka_port->adapter->qdio;
+- struct zfcp_fsf_req *req;
++ struct zfcp_fsf_req *req = NULL;
+ int retval = -EIO;
+
+ spin_lock_irq(&qdio->req_q_lock);
+@@ -1663,6 +1665,8 @@ int zfcp_fsf_close_wka_port(struct zfcp_
+ zfcp_fsf_req_free(req);
+ out:
+ spin_unlock_irq(&qdio->req_q_lock);
++ if (req && !IS_ERR(req))
++ zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id);
+ return retval;
+ }
+