]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Wed, 26 Jun 2024 19:04:39 +0000 (15:04 -0400)
committerSasha Levin <sashal@kernel.org>
Thu, 27 Jun 2024 14:02:04 +0000 (10:02 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.19/iio-dac-ad5592r-base-replace-indio_dev-mlock-with-ow.patch [new file with mode: 0644]
queue-4.19/iio-dac-ad5592r-fix-temperature-channel-scaling-valu.patch [new file with mode: 0644]
queue-4.19/iio-dac-ad5592r-un-indent-code-block-for-scale-read.patch [new file with mode: 0644]
queue-4.19/mm-memblock-replace-dereferences-of-memblock_region..patch [new file with mode: 0644]
queue-4.19/scsi-mpt3sas-add-ioc_-level-logging-macros.patch [new file with mode: 0644]
queue-4.19/scsi-mpt3sas-avoid-test-set_bit-operating-in-non-all.patch [new file with mode: 0644]
queue-4.19/scsi-mpt3sas-gracefully-handle-online-firmware-updat.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/x86-mm-numa-use-numa_no_node-when-calling-memblock_s.patch [new file with mode: 0644]
queue-4.19/xhci-set-correct-transferred-length-for-cancelled-bu.patch [new file with mode: 0644]
queue-4.19/xhci-use-soft-retry-to-recover-faster-from-transacti.patch [new file with mode: 0644]

diff --git a/queue-4.19/iio-dac-ad5592r-base-replace-indio_dev-mlock-with-ow.patch b/queue-4.19/iio-dac-ad5592r-base-replace-indio_dev-mlock-with-ow.patch
new file mode 100644 (file)
index 0000000..81188c6
--- /dev/null
@@ -0,0 +1,171 @@
+From d0031edcb841638bb995afdc6f0514421a48b5d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2020 15:02:01 +0300
+Subject: iio: dac: ad5592r-base: Replace indio_dev->mlock with own device lock
+
+From: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
+
+[ Upstream commit 33c53cbf8f7bc8d62f6146a19da97c8594376ff0 ]
+
+As part of the general cleanup of indio_dev->mlock, this change replaces
+it with a local lock on the device's state structure.
+This also removes unused iio_dev pointers.
+
+Signed-off-by: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 279428df8883 ("iio: dac: ad5592r: fix temperature channel scaling value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5592r-base.c | 30 +++++++++++++++---------------
+ drivers/iio/dac/ad5592r-base.h |  1 +
+ 2 files changed, 16 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/iio/dac/ad5592r-base.c b/drivers/iio/dac/ad5592r-base.c
+index 8011245a01d77..87824c03c0124 100644
+--- a/drivers/iio/dac/ad5592r-base.c
++++ b/drivers/iio/dac/ad5592r-base.c
+@@ -158,7 +158,6 @@ static void ad5592r_gpio_cleanup(struct ad5592r_state *st)
+ static int ad5592r_reset(struct ad5592r_state *st)
+ {
+       struct gpio_desc *gpio;
+-      struct iio_dev *iio_dev = iio_priv_to_dev(st);
+       gpio = devm_gpiod_get_optional(st->dev, "reset", GPIOD_OUT_LOW);
+       if (IS_ERR(gpio))
+@@ -168,10 +167,10 @@ static int ad5592r_reset(struct ad5592r_state *st)
+               udelay(1);
+               gpiod_set_value(gpio, 1);
+       } else {
+-              mutex_lock(&iio_dev->mlock);
++              mutex_lock(&st->lock);
+               /* Writing this magic value resets the device */
+               st->ops->reg_write(st, AD5592R_REG_RESET, 0xdac);
+-              mutex_unlock(&iio_dev->mlock);
++              mutex_unlock(&st->lock);
+       }
+       udelay(250);
+@@ -199,7 +198,6 @@ static int ad5592r_set_channel_modes(struct ad5592r_state *st)
+       const struct ad5592r_rw_ops *ops = st->ops;
+       int ret;
+       unsigned i;
+-      struct iio_dev *iio_dev = iio_priv_to_dev(st);
+       u8 pulldown = 0, tristate = 0, dac = 0, adc = 0;
+       u16 read_back;
+@@ -249,7 +247,7 @@ static int ad5592r_set_channel_modes(struct ad5592r_state *st)
+               }
+       }
+-      mutex_lock(&iio_dev->mlock);
++      mutex_lock(&st->lock);
+       /* Pull down unused pins to GND */
+       ret = ops->reg_write(st, AD5592R_REG_PULLDOWN, pulldown);
+@@ -287,7 +285,7 @@ static int ad5592r_set_channel_modes(struct ad5592r_state *st)
+               ret = -EIO;
+ err_unlock:
+-      mutex_unlock(&iio_dev->mlock);
++      mutex_unlock(&st->lock);
+       return ret;
+ }
+@@ -316,11 +314,11 @@ static int ad5592r_write_raw(struct iio_dev *iio_dev,
+               if (!chan->output)
+                       return -EINVAL;
+-              mutex_lock(&iio_dev->mlock);
++              mutex_lock(&st->lock);
+               ret = st->ops->write_dac(st, chan->channel, val);
+               if (!ret)
+                       st->cached_dac[chan->channel] = val;
+-              mutex_unlock(&iio_dev->mlock);
++              mutex_unlock(&st->lock);
+               return ret;
+       case IIO_CHAN_INFO_SCALE:
+               if (chan->type == IIO_VOLTAGE) {
+@@ -335,12 +333,12 @@ static int ad5592r_write_raw(struct iio_dev *iio_dev,
+                       else
+                               return -EINVAL;
+-                      mutex_lock(&iio_dev->mlock);
++                      mutex_lock(&st->lock);
+                       ret = st->ops->reg_read(st, AD5592R_REG_CTRL,
+                                               &st->cached_gp_ctrl);
+                       if (ret < 0) {
+-                              mutex_unlock(&iio_dev->mlock);
++                              mutex_unlock(&st->lock);
+                               return ret;
+                       }
+@@ -362,7 +360,7 @@ static int ad5592r_write_raw(struct iio_dev *iio_dev,
+                       ret = st->ops->reg_write(st, AD5592R_REG_CTRL,
+                                                st->cached_gp_ctrl);
+-                      mutex_unlock(&iio_dev->mlock);
++                      mutex_unlock(&st->lock);
+                       return ret;
+               }
+@@ -384,7 +382,7 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
+       switch (m) {
+       case IIO_CHAN_INFO_RAW:
+-              mutex_lock(&iio_dev->mlock);
++              mutex_lock(&st->lock);
+               if (!chan->output) {
+                       ret = st->ops->read_adc(st, chan->channel, &read_val);
+@@ -421,7 +419,7 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
+               } else {
+                       int mult;
+-                      mutex_lock(&iio_dev->mlock);
++                      mutex_lock(&st->lock);
+                       if (chan->output)
+                               mult = !!(st->cached_gp_ctrl &
+@@ -439,7 +437,7 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
+       case IIO_CHAN_INFO_OFFSET:
+               ret = ad5592r_get_vref(st);
+-              mutex_lock(&iio_dev->mlock);
++              mutex_lock(&st->lock);
+               if (st->cached_gp_ctrl & AD5592R_REG_CTRL_ADC_RANGE)
+                       *val = (-34365 * 25) / ret;
+@@ -452,7 +450,7 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
+       }
+ unlock:
+-      mutex_unlock(&iio_dev->mlock);
++      mutex_unlock(&st->lock);
+       return ret;
+ }
+@@ -627,6 +625,8 @@ int ad5592r_probe(struct device *dev, const char *name,
+       iio_dev->info = &ad5592r_info;
+       iio_dev->modes = INDIO_DIRECT_MODE;
++      mutex_init(&st->lock);
++
+       ad5592r_init_scales(st, ad5592r_get_vref(st));
+       ret = ad5592r_reset(st);
+diff --git a/drivers/iio/dac/ad5592r-base.h b/drivers/iio/dac/ad5592r-base.h
+index 841457e93f851..046936068b638 100644
+--- a/drivers/iio/dac/ad5592r-base.h
++++ b/drivers/iio/dac/ad5592r-base.h
+@@ -53,6 +53,7 @@ struct ad5592r_state {
+       struct regulator *reg;
+       struct gpio_chip gpiochip;
+       struct mutex gpio_lock; /* Protect cached gpio_out, gpio_val, etc. */
++      struct mutex lock;
+       unsigned int num_channels;
+       const struct ad5592r_rw_ops *ops;
+       int scale_avail[2][2];
+-- 
+2.43.0
+
diff --git a/queue-4.19/iio-dac-ad5592r-fix-temperature-channel-scaling-valu.patch b/queue-4.19/iio-dac-ad5592r-fix-temperature-channel-scaling-valu.patch
new file mode 100644 (file)
index 0000000..df5922b
--- /dev/null
@@ -0,0 +1,71 @@
+From 2ede9689d47b3f1a4b74f776d8cc8eab16afdf88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 May 2024 11:05:54 -0400
+Subject: iio: dac: ad5592r: fix temperature channel scaling value
+
+From: Marc Ferland <marc.ferland@sonatest.com>
+
+[ Upstream commit 279428df888319bf68f2686934897301a250bb84 ]
+
+The scale value for the temperature channel is (assuming Vref=2.5 and
+the datasheet):
+
+    376.7897513
+
+When calculating both val and val2 for the temperature scale we
+use (3767897513/25) and multiply it by Vref (here I assume 2500mV) to
+obtain:
+
+  2500 * (3767897513/25) ==> 376789751300
+
+Finally we divide with remainder by 10^9 to get:
+
+    val = 376
+    val2 = 789751300
+
+However, we return IIO_VAL_INT_PLUS_MICRO (should have been NANO) as
+the scale type. So when converting the raw temperature value to the
+'processed' temperature value we will get (assuming raw=810,
+offset=-753):
+
+    processed = (raw + offset) * scale_val
+              = (810 + -753) * 376
+             = 21432
+
+    processed += div((raw + offset) * scale_val2, 10^6)
+              += div((810 + -753) * 789751300, 10^6)
+             += 45015
+    ==> 66447
+    ==> 66.4 Celcius
+
+instead of the expected 21.5 Celsius.
+
+Fix this issue by changing IIO_VAL_INT_PLUS_MICRO to
+IIO_VAL_INT_PLUS_NANO.
+
+Fixes: 56ca9db862bf ("iio: dac: Add support for the AD5592R/AD5593R ADCs/DACs")
+Signed-off-by: Marc Ferland <marc.ferland@sonatest.com>
+Link: https://lore.kernel.org/r/20240501150554.1871390-1-marc.ferland@sonatest.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5592r-base.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/ad5592r-base.c b/drivers/iio/dac/ad5592r-base.c
+index 427946be41872..414134412a5f8 100644
+--- a/drivers/iio/dac/ad5592r-base.c
++++ b/drivers/iio/dac/ad5592r-base.c
+@@ -415,7 +415,7 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
+                       s64 tmp = *val * (3767897513LL / 25LL);
+                       *val = div_s64_rem(tmp, 1000000000LL, val2);
+-                      return IIO_VAL_INT_PLUS_MICRO;
++                      return IIO_VAL_INT_PLUS_NANO;
+               }
+               mutex_lock(&st->lock);
+-- 
+2.43.0
+
diff --git a/queue-4.19/iio-dac-ad5592r-un-indent-code-block-for-scale-read.patch b/queue-4.19/iio-dac-ad5592r-un-indent-code-block-for-scale-read.patch
new file mode 100644 (file)
index 0000000..4b81b30
--- /dev/null
@@ -0,0 +1,75 @@
+From a73e7ea06cd10a0061499754927891928f635dc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2020 14:02:58 +0300
+Subject: iio: dac: ad5592r: un-indent code-block for scale read
+
+From: Alexandru Ardelean <alexandru.ardelean@analog.com>
+
+[ Upstream commit b004fe33034cc64f72c20923be71cf1e6c9a624c ]
+
+The next rework may require an unindentation of a code block in
+ad5592r_read_raw(), which would make review a bit more difficult.
+
+This change unindents the code block for reading the scale of the
+non-temperature channels.
+
+Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Link: https://lore.kernel.org/r/20200706110259.23947-2-alexandru.ardelean@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 279428df8883 ("iio: dac: ad5592r: fix temperature channel scaling value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5592r-base.c | 26 ++++++++++++--------------
+ 1 file changed, 12 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/iio/dac/ad5592r-base.c b/drivers/iio/dac/ad5592r-base.c
+index 87824c03c0124..427946be41872 100644
+--- a/drivers/iio/dac/ad5592r-base.c
++++ b/drivers/iio/dac/ad5592r-base.c
+@@ -378,7 +378,7 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
+ {
+       struct ad5592r_state *st = iio_priv(iio_dev);
+       u16 read_val;
+-      int ret;
++      int ret, mult;
+       switch (m) {
+       case IIO_CHAN_INFO_RAW:
+@@ -416,23 +416,21 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
+                       *val = div_s64_rem(tmp, 1000000000LL, val2);
+                       return IIO_VAL_INT_PLUS_MICRO;
+-              } else {
+-                      int mult;
++              }
+-                      mutex_lock(&st->lock);
++              mutex_lock(&st->lock);
+-                      if (chan->output)
+-                              mult = !!(st->cached_gp_ctrl &
+-                                      AD5592R_REG_CTRL_DAC_RANGE);
+-                      else
+-                              mult = !!(st->cached_gp_ctrl &
+-                                      AD5592R_REG_CTRL_ADC_RANGE);
++              if (chan->output)
++                      mult = !!(st->cached_gp_ctrl &
++                              AD5592R_REG_CTRL_DAC_RANGE);
++              else
++                      mult = !!(st->cached_gp_ctrl &
++                              AD5592R_REG_CTRL_ADC_RANGE);
+-                      *val *= ++mult;
++              *val *= ++mult;
+-                      *val2 = chan->scan_type.realbits;
+-                      ret = IIO_VAL_FRACTIONAL_LOG2;
+-              }
++              *val2 = chan->scan_type.realbits;
++              ret = IIO_VAL_FRACTIONAL_LOG2;
+               break;
+       case IIO_CHAN_INFO_OFFSET:
+               ret = ad5592r_get_vref(st);
+-- 
+2.43.0
+
diff --git a/queue-4.19/mm-memblock-replace-dereferences-of-memblock_region..patch b/queue-4.19/mm-memblock-replace-dereferences-of-memblock_region..patch
new file mode 100644 (file)
index 0000000..d8d04f2
--- /dev/null
@@ -0,0 +1,193 @@
+From d57f56efe757cf1ca1ab585b8542bb9964e46b3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2020 15:56:53 -0700
+Subject: mm: memblock: replace dereferences of memblock_region.nid with API
+ calls
+
+From: Mike Rapoport <rppt@linux.ibm.com>
+
+[ Upstream commit d622abf74f3d81365e41c3bfdbbda50ecd99ba3d ]
+
+Patch series "mm: rework free_area_init*() funcitons".
+
+After the discussion [1] about removal of CONFIG_NODES_SPAN_OTHER_NODES
+and CONFIG_HAVE_MEMBLOCK_NODE_MAP options, I took it a bit further and
+updated the node/zone initialization.
+
+Since all architectures have memblock, it is possible to use only the
+newer version of free_area_init_node() that calculates the zone and node
+boundaries based on memblock node mapping and architectural limits on
+possible zone PFNs.
+
+The architectures that still determined zone and hole sizes can be
+switched to the generic code and the old code that took those zone and
+hole sizes can be simply removed.
+
+And, since it all started from the removal of
+CONFIG_NODES_SPAN_OTHER_NODES, the memmap_init() is now updated to iterate
+over memblocks and so it does not need to perform early_pfn_to_nid() query
+for every PFN.
+
+[1] https://lore.kernel.org/lkml/1585420282-25630-1-git-send-email-Hoan@os.amperecomputing.com
+
+This patch (of 21):
+
+There are several places in the code that directly dereference
+memblock_region.nid despite this field being defined only when
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y.
+
+Replace these with calls to memblock_get_region_nid() to improve code
+robustness and to avoid possible breakage when
+CONFIG_HAVE_MEMBLOCK_NODE_MAP will be removed.
+
+Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Tested-by: Hoan Tran <hoan@os.amperecomputing.com>     [arm64]
+Reviewed-by: Baoquan He <bhe@redhat.com>
+Cc: Brian Cain <bcain@codeaurora.org>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Geert Uytterhoeven <geert@linux-m68k.org>
+Cc: Greentime Hu <green.hu@gmail.com>
+Cc: Greg Ungerer <gerg@linux-m68k.org>
+Cc: Guan Xuetao <gxt@pku.edu.cn>
+Cc: Guo Ren <guoren@kernel.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Helge Deller <deller@gmx.de>
+Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Ley Foon Tan <ley.foon.tan@intel.com>
+Cc: Mark Salter <msalter@redhat.com>
+Cc: Matt Turner <mattst88@gmail.com>
+Cc: Max Filippov <jcmvbkbc@gmail.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Michal Simek <monstr@monstr.eu>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Nick Hu <nickhu@andestech.com>
+Cc: Paul Walmsley <paul.walmsley@sifive.com>
+Cc: Richard Weinberger <richard@nod.at>
+Cc: Rich Felker <dalias@libc.org>
+Cc: Russell King <linux@armlinux.org.uk>
+Cc: Stafford Horne <shorne@gmail.com>
+Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Cc: Tony Luck <tony.luck@intel.com>
+Cc: Vineet Gupta <vgupta@synopsys.com>
+Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
+Link: http://lkml.kernel.org/r/20200412194859.12663-1-rppt@kernel.org
+Link: http://lkml.kernel.org/r/20200412194859.12663-2-rppt@kernel.org
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: 3ac36aa73073 ("x86/mm/numa: Use NUMA_NO_NODE when calling memblock_set_node()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/mm/numa.c | 9 ++++++---
+ arch/x86/mm/numa.c   | 6 ++++--
+ mm/memblock.c        | 8 +++++---
+ mm/page_alloc.c      | 4 ++--
+ 4 files changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
+index 15eaf1e09d0ca..f2f4c056822a7 100644
+--- a/arch/arm64/mm/numa.c
++++ b/arch/arm64/mm/numa.c
+@@ -365,13 +365,16 @@ static int __init numa_register_nodes(void)
+       struct memblock_region *mblk;
+       /* Check that valid nid is set to memblks */
+-      for_each_memblock(memory, mblk)
+-              if (mblk->nid == NUMA_NO_NODE || mblk->nid >= MAX_NUMNODES) {
++      for_each_memblock(memory, mblk) {
++              int mblk_nid = memblock_get_region_node(mblk);
++
++              if (mblk_nid == NUMA_NO_NODE || mblk_nid >= MAX_NUMNODES) {
+                       pr_warn("Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
+-                              mblk->nid, mblk->base,
++                              mblk_nid, mblk->base,
+                               mblk->base + mblk->size - 1);
+                       return -EINVAL;
+               }
++      }
+       /* Finally register nodes. */
+       for_each_node_mask(nid, numa_nodes_parsed) {
+diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
+index a830d49341ecc..411ded8664a9e 100644
+--- a/arch/x86/mm/numa.c
++++ b/arch/x86/mm/numa.c
+@@ -506,8 +506,10 @@ static void __init numa_clear_kernel_node_hotplug(void)
+        *   reserve specific pages for Sandy Bridge graphics. ]
+        */
+       for_each_memblock(reserved, mb_region) {
+-              if (mb_region->nid != MAX_NUMNODES)
+-                      node_set(mb_region->nid, reserved_nodemask);
++              int nid = memblock_get_region_node(mb_region);
++
++              if (nid != MAX_NUMNODES)
++                      node_set(nid, reserved_nodemask);
+       }
+       /*
+diff --git a/mm/memblock.c b/mm/memblock.c
+index 4d471da3cc479..0510d6c7ad14c 100644
+--- a/mm/memblock.c
++++ b/mm/memblock.c
+@@ -1147,13 +1147,15 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid,
+ {
+       struct memblock_type *type = &memblock.memory;
+       struct memblock_region *r;
++      int r_nid;
+       while (++*idx < type->cnt) {
+               r = &type->regions[*idx];
++              r_nid = memblock_get_region_node(r);
+               if (PFN_UP(r->base) >= PFN_DOWN(r->base + r->size))
+                       continue;
+-              if (nid == MAX_NUMNODES || nid == r->nid)
++              if (nid == MAX_NUMNODES || nid == r_nid)
+                       break;
+       }
+       if (*idx >= type->cnt) {
+@@ -1166,7 +1168,7 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid,
+       if (out_end_pfn)
+               *out_end_pfn = PFN_DOWN(r->base + r->size);
+       if (out_nid)
+-              *out_nid = r->nid;
++              *out_nid = r_nid;
+ }
+ /**
+@@ -1714,7 +1716,7 @@ int __init_memblock memblock_search_pfn_nid(unsigned long pfn,
+       *start_pfn = PFN_DOWN(type->regions[mid].base);
+       *end_pfn = PFN_DOWN(type->regions[mid].base + type->regions[mid].size);
+-      return type->regions[mid].nid;
++      return memblock_get_region_node(&type->regions[mid]);
+ }
+ #endif
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 147b67d31431d..b8cccd1a9965e 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -6743,7 +6743,7 @@ static void __init find_zone_movable_pfns_for_nodes(void)
+                       if (!memblock_is_hotpluggable(r))
+                               continue;
+-                      nid = r->nid;
++                      nid = memblock_get_region_node(r);
+                       usable_startpfn = PFN_DOWN(r->base);
+                       zone_movable_pfn[nid] = zone_movable_pfn[nid] ?
+@@ -6764,7 +6764,7 @@ static void __init find_zone_movable_pfns_for_nodes(void)
+                       if (memblock_is_mirror(r))
+                               continue;
+-                      nid = r->nid;
++                      nid = memblock_get_region_node(r);
+                       usable_startpfn = memblock_region_memory_base_pfn(r);
+-- 
+2.43.0
+
diff --git a/queue-4.19/scsi-mpt3sas-add-ioc_-level-logging-macros.patch b/queue-4.19/scsi-mpt3sas-add-ioc_-level-logging-macros.patch
new file mode 100644 (file)
index 0000000..a3ad6e0
--- /dev/null
@@ -0,0 +1,44 @@
+From cb46c1bbc6ca0b6ddf0fc572b9a533bec68e056d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Sep 2018 08:01:08 -0700
+Subject: scsi: mpt3sas: Add ioc_<level> logging macros
+
+From: Joe Perches <joe@perches.com>
+
+[ Upstream commit 645a20c6821cd1ab58af8a1f99659e619c216efd ]
+
+These macros can help identify specific logging uses and eventually perhaps
+reduce object sizes.
+
+Signed-off-by: Joe Perches <joe@perches.com>
+Acked-by: Suganath Prabu <suganath-prabu.subramani@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 4254dfeda82f ("scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpt3sas/mpt3sas_base.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
+index 96dc15e90bd83..941a4faf20be0 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
+@@ -160,6 +160,15 @@ struct mpt3sas_nvme_cmd {
+  */
+ #define MPT3SAS_FMT                   "%s: "
++#define ioc_err(ioc, fmt, ...)                                                \
++      pr_err("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
++#define ioc_notice(ioc, fmt, ...)                                     \
++      pr_notice("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
++#define ioc_warn(ioc, fmt, ...)                                               \
++      pr_warn("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
++#define ioc_info(ioc, fmt, ...)                                               \
++      pr_info("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
++
+ /*
+  *  WarpDrive Specific Log codes
+  */
+-- 
+2.43.0
+
diff --git a/queue-4.19/scsi-mpt3sas-avoid-test-set_bit-operating-in-non-all.patch b/queue-4.19/scsi-mpt3sas-avoid-test-set_bit-operating-in-non-all.patch
new file mode 100644 (file)
index 0000000..747cd7f
--- /dev/null
@@ -0,0 +1,85 @@
+From a4769c3002e64f7127afd2d5b79cded80dacd4be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jun 2024 01:55:29 -0700
+Subject: scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 4254dfeda82f20844299dca6c38cbffcfd499f41 ]
+
+There is a potential out-of-bounds access when using test_bit() on a single
+word. The test_bit() and set_bit() functions operate on long values, and
+when testing or setting a single word, they can exceed the word
+boundary. KASAN detects this issue and produces a dump:
+
+        BUG: KASAN: slab-out-of-bounds in _scsih_add_device.constprop.0 (./arch/x86/include/asm/bitops.h:60 ./include/asm-generic/bitops/instrumented-atomic.h:29 drivers/scsi/mpt3sas/mpt3sas_scsih.c:7331) mpt3sas
+
+        Write of size 8 at addr ffff8881d26e3c60 by task kworker/u1536:2/2965
+
+For full log, please look at [1].
+
+Make the allocation at least the size of sizeof(unsigned long) so that
+set_bit() and test_bit() have sufficient room for read/write operations
+without overwriting unallocated memory.
+
+[1] Link: https://lore.kernel.org/all/ZkNcALr3W3KGYYJG@gmail.com/
+
+Fixes: c696f7b83ede ("scsi: mpt3sas: Implement device_remove_in_progress check in IOCTL path")
+Cc: stable@vger.kernel.org
+Suggested-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Link: https://lore.kernel.org/r/20240605085530.499432-1-leitao@debian.org
+Reviewed-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpt3sas/mpt3sas_base.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
+index 54faddb637c46..b4495023edb71 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
+@@ -6612,6 +6612,12 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
+       ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8);
+       if (ioc->facts.MaxDevHandle % 8)
+               ioc->pd_handles_sz++;
++      /*
++       * pd_handles_sz should have, at least, the minimal room for
++       * set_bit()/test_bit(), otherwise out-of-memory touch may occur.
++       */
++      ioc->pd_handles_sz = ALIGN(ioc->pd_handles_sz, sizeof(unsigned long));
++
+       ioc->pd_handles = kzalloc(ioc->pd_handles_sz,
+           GFP_KERNEL);
+       if (!ioc->pd_handles) {
+@@ -6629,6 +6635,13 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
+       ioc->pend_os_device_add_sz = (ioc->facts.MaxDevHandle / 8);
+       if (ioc->facts.MaxDevHandle % 8)
+               ioc->pend_os_device_add_sz++;
++
++      /*
++       * pend_os_device_add_sz should have, at least, the minimal room for
++       * set_bit()/test_bit(), otherwise out-of-memory may occur.
++       */
++      ioc->pend_os_device_add_sz = ALIGN(ioc->pend_os_device_add_sz,
++                                         sizeof(unsigned long));
+       ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz,
+           GFP_KERNEL);
+       if (!ioc->pend_os_device_add) {
+@@ -6911,6 +6924,12 @@ _base_check_ioc_facts_changes(struct MPT3SAS_ADAPTER *ioc)
+               if (ioc->facts.MaxDevHandle % 8)
+                       pd_handles_sz++;
++              /*
++               * pd_handles should have, at least, the minimal room for
++               * set_bit()/test_bit(), otherwise out-of-memory touch may
++               * occur.
++               */
++              pd_handles_sz = ALIGN(pd_handles_sz, sizeof(unsigned long));
+               pd_handles = krealloc(ioc->pd_handles, pd_handles_sz,
+                   GFP_KERNEL);
+               if (!pd_handles) {
+-- 
+2.43.0
+
diff --git a/queue-4.19/scsi-mpt3sas-gracefully-handle-online-firmware-updat.patch b/queue-4.19/scsi-mpt3sas-gracefully-handle-online-firmware-updat.patch
new file mode 100644 (file)
index 0000000..63ae1c3
--- /dev/null
@@ -0,0 +1,174 @@
+From 320ce11c45ce39043c4159989e715a3f1c2e1891 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Aug 2019 09:59:48 -0400
+Subject: scsi: mpt3sas: Gracefully handle online firmware update
+
+From: Suganath Prabu <suganath-prabu.subramani@broadcom.com>
+
+[ Upstream commit ffedeae1fa545a1d07e6827180c3923bf67af59f ]
+
+Issue:
+
+During online Firmware upgrade operations it is possible that MaxDevHandles
+filled in IOCFacts may change with new FW.  With this we may observe kernel
+panics when driver try to access the pd_handles or blocking_handles buffers
+at offset greater than the old firmware's MaxDevHandle value.
+
+Fix:
+
+_base_check_ioc_facts_changes() looks for increase/decrease in IOCFacts
+attributes during online firmware upgrade and increases the pd_handles,
+blocking_handles, etc buffer sizes to new firmware's MaxDevHandle value if
+this new firmware's MaxDevHandle value is greater than the old firmware's
+MaxDevHandle value.
+
+Signed-off-by: Suganath Prabu <suganath-prabu.subramani@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 4254dfeda82f ("scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpt3sas/mpt3sas_base.c | 93 +++++++++++++++++++++++++++++
+ drivers/scsi/mpt3sas/mpt3sas_base.h |  2 +
+ 2 files changed, 95 insertions(+)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
+index 7588c2c11a879..54faddb637c46 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
+@@ -6719,6 +6719,13 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
+       if (r)
+               goto out_free_resources;
++      /*
++       * Copy current copy of IOCFacts in prev_fw_facts
++       * and it will be used during online firmware upgrade.
++       */
++      memcpy(&ioc->prev_fw_facts, &ioc->facts,
++          sizeof(struct mpt3sas_facts));
++
+       ioc->non_operational_loop = 0;
+       ioc->got_task_abort_from_ioctl = 0;
+       return 0;
+@@ -6884,6 +6891,85 @@ mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc)
+       wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 10 * HZ);
+ }
++/**
++ * _base_check_ioc_facts_changes - Look for increase/decrease of IOCFacts
++ *     attributes during online firmware upgrade and update the corresponding
++ *     IOC variables accordingly.
++ *
++ * @ioc: Pointer to MPT_ADAPTER structure
++ */
++static int
++_base_check_ioc_facts_changes(struct MPT3SAS_ADAPTER *ioc)
++{
++      u16 pd_handles_sz;
++      void *pd_handles = NULL, *blocking_handles = NULL;
++      void *pend_os_device_add = NULL, *device_remove_in_progress = NULL;
++      struct mpt3sas_facts *old_facts = &ioc->prev_fw_facts;
++
++      if (ioc->facts.MaxDevHandle > old_facts->MaxDevHandle) {
++              pd_handles_sz = (ioc->facts.MaxDevHandle / 8);
++              if (ioc->facts.MaxDevHandle % 8)
++                      pd_handles_sz++;
++
++              pd_handles = krealloc(ioc->pd_handles, pd_handles_sz,
++                  GFP_KERNEL);
++              if (!pd_handles) {
++                      ioc_info(ioc,
++                          "Unable to allocate the memory for pd_handles of sz: %d\n",
++                          pd_handles_sz);
++                      return -ENOMEM;
++              }
++              memset(pd_handles + ioc->pd_handles_sz, 0,
++                  (pd_handles_sz - ioc->pd_handles_sz));
++              ioc->pd_handles = pd_handles;
++
++              blocking_handles = krealloc(ioc->blocking_handles,
++                  pd_handles_sz, GFP_KERNEL);
++              if (!blocking_handles) {
++                      ioc_info(ioc,
++                          "Unable to allocate the memory for "
++                          "blocking_handles of sz: %d\n",
++                          pd_handles_sz);
++                      return -ENOMEM;
++              }
++              memset(blocking_handles + ioc->pd_handles_sz, 0,
++                  (pd_handles_sz - ioc->pd_handles_sz));
++              ioc->blocking_handles = blocking_handles;
++              ioc->pd_handles_sz = pd_handles_sz;
++
++              pend_os_device_add = krealloc(ioc->pend_os_device_add,
++                  pd_handles_sz, GFP_KERNEL);
++              if (!pend_os_device_add) {
++                      ioc_info(ioc,
++                          "Unable to allocate the memory for pend_os_device_add of sz: %d\n",
++                          pd_handles_sz);
++                      return -ENOMEM;
++              }
++              memset(pend_os_device_add + ioc->pend_os_device_add_sz, 0,
++                  (pd_handles_sz - ioc->pend_os_device_add_sz));
++              ioc->pend_os_device_add = pend_os_device_add;
++              ioc->pend_os_device_add_sz = pd_handles_sz;
++
++              device_remove_in_progress = krealloc(
++                  ioc->device_remove_in_progress, pd_handles_sz, GFP_KERNEL);
++              if (!device_remove_in_progress) {
++                      ioc_info(ioc,
++                          "Unable to allocate the memory for "
++                          "device_remove_in_progress of sz: %d\n "
++                          , pd_handles_sz);
++                      return -ENOMEM;
++              }
++              memset(device_remove_in_progress +
++                  ioc->device_remove_in_progress_sz, 0,
++                  (pd_handles_sz - ioc->device_remove_in_progress_sz));
++              ioc->device_remove_in_progress = device_remove_in_progress;
++              ioc->device_remove_in_progress_sz = pd_handles_sz;
++      }
++
++      memcpy(&ioc->prev_fw_facts, &ioc->facts, sizeof(struct mpt3sas_facts));
++      return 0;
++}
++
+ /**
+  * mpt3sas_base_hard_reset_handler - reset controller
+  * @ioc: Pointer to MPT_ADAPTER structure
+@@ -6949,6 +7035,13 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
+       if (r)
+               goto out;
++      r = _base_check_ioc_facts_changes(ioc);
++      if (r) {
++              ioc_info(ioc,
++                  "Some of the parameters got changed in this new firmware"
++                  " image and it requires system reboot\n");
++              goto out;
++      }
+       if (ioc->rdpq_array_enable && !ioc->rdpq_array_capable)
+               panic("%s: Issue occurred with flashing controller firmware."
+                     "Please reboot the system and ensure that the correct"
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
+index 941a4faf20be0..b0297a9c92389 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
+@@ -1032,6 +1032,7 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
+  * @event_log: event log pointer
+  * @event_masks: events that are masked
+  * @facts: static facts data
++ * @prev_fw_facts: previous fw facts data
+  * @pfacts: static port facts data
+  * @manu_pg0: static manufacturing page 0
+  * @manu_pg10: static manufacturing page 10
+@@ -1235,6 +1236,7 @@ struct MPT3SAS_ADAPTER {
+       /* static config pages */
+       struct mpt3sas_facts facts;
++      struct mpt3sas_facts prev_fw_facts;
+       struct mpt3sas_port_facts *pfacts;
+       Mpi2ManufacturingPage0_t manu_pg0;
+       struct Mpi2ManufacturingPage10_t manu_pg10;
+-- 
+2.43.0
+
index becb269dc24353084d5673cd0cef743028e163f3..b930a8c3daff22db1375bd86edc22193ae675be6 100644 (file)
@@ -94,3 +94,13 @@ tracing-add-module_description-to-preemptirq_delay_t.patch
 perf-core-fix-missing-wakeup-when-waiting-for-contex.patch
 pci-add-pci_error_response-and-related-definitions.patch
 x86-amd_nb-check-for-invalid-smn-reads.patch
+iio-dac-ad5592r-base-replace-indio_dev-mlock-with-ow.patch
+iio-dac-ad5592r-un-indent-code-block-for-scale-read.patch
+iio-dac-ad5592r-fix-temperature-channel-scaling-valu.patch
+scsi-mpt3sas-add-ioc_-level-logging-macros.patch
+scsi-mpt3sas-gracefully-handle-online-firmware-updat.patch
+scsi-mpt3sas-avoid-test-set_bit-operating-in-non-all.patch
+mm-memblock-replace-dereferences-of-memblock_region..patch
+x86-mm-numa-use-numa_no_node-when-calling-memblock_s.patch
+xhci-use-soft-retry-to-recover-faster-from-transacti.patch
+xhci-set-correct-transferred-length-for-cancelled-bu.patch
diff --git a/queue-4.19/x86-mm-numa-use-numa_no_node-when-calling-memblock_s.patch b/queue-4.19/x86-mm-numa-use-numa_no_node-when-calling-memblock_s.patch
new file mode 100644 (file)
index 0000000..e53ad3e
--- /dev/null
@@ -0,0 +1,58 @@
+From d6322292e8cd794c12927256eb1390d2415370ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 May 2024 09:42:05 +0200
+Subject: x86/mm/numa: Use NUMA_NO_NODE when calling memblock_set_node()
+
+From: Jan Beulich <jbeulich@suse.com>
+
+[ Upstream commit 3ac36aa7307363b7247ccb6f6a804e11496b2b36 ]
+
+memblock_set_node() warns about using MAX_NUMNODES, see
+
+  e0eec24e2e19 ("memblock: make memblock_set_node() also warn about use of MAX_NUMNODES")
+
+for details.
+
+Reported-by: Narasimhan V <Narasimhan.V@amd.com>
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Cc: stable@vger.kernel.org
+[bp: commit message]
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Mike Rapoport (IBM) <rppt@kernel.org>
+Tested-by: Paul E. McKenney <paulmck@kernel.org>
+Link: https://lore.kernel.org/r/20240603141005.23261-1-bp@kernel.org
+Link: https://lore.kernel.org/r/abadb736-a239-49e4-ab42-ace7acdd4278@suse.com
+Signed-off-by: Mike Rapoport (IBM) <rppt@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/mm/numa.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
+index 411ded8664a9e..b018eac5e4191 100644
+--- a/arch/x86/mm/numa.c
++++ b/arch/x86/mm/numa.c
+@@ -508,7 +508,7 @@ static void __init numa_clear_kernel_node_hotplug(void)
+       for_each_memblock(reserved, mb_region) {
+               int nid = memblock_get_region_node(mb_region);
+-              if (nid != MAX_NUMNODES)
++              if (nid != NUMA_NO_NODE)
+                       node_set(nid, reserved_nodemask);
+       }
+@@ -628,9 +628,9 @@ static int __init numa_init(int (*init_func)(void))
+       nodes_clear(node_online_map);
+       memset(&numa_meminfo, 0, sizeof(numa_meminfo));
+       WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.memory,
+-                                MAX_NUMNODES));
++                                NUMA_NO_NODE));
+       WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.reserved,
+-                                MAX_NUMNODES));
++                                NUMA_NO_NODE));
+       /* In case that parsing SRAT failed. */
+       WARN_ON(memblock_clear_hotplug(0, ULLONG_MAX));
+       numa_reset_distance();
+-- 
+2.43.0
+
diff --git a/queue-4.19/xhci-set-correct-transferred-length-for-cancelled-bu.patch b/queue-4.19/xhci-set-correct-transferred-length-for-cancelled-bu.patch
new file mode 100644 (file)
index 0000000..df4bbfd
--- /dev/null
@@ -0,0 +1,58 @@
+From 01e13cbf55110bb2d791e9ce7cee087b7725edbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jun 2024 15:06:07 +0300
+Subject: xhci: Set correct transferred length for cancelled bulk transfers
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit f0260589b439e2637ad54a2b25f00a516ef28a57 ]
+
+The transferred length is set incorrectly for cancelled bulk
+transfer TDs in case the bulk transfer ring stops on the last transfer
+block with a 'Stop - Length Invalid' completion code.
+
+length essentially ends up being set to the requested length:
+urb->actual_length = urb->transfer_buffer_length
+
+Length for 'Stop - Length Invalid' cases should be the sum of all
+TRB transfer block lengths up to the one the ring stopped on,
+_excluding_ the one stopped on.
+
+Fix this by always summing up TRB lengths for 'Stop - Length Invalid'
+bulk cases.
+
+This issue was discovered by Alan Stern while debugging
+https://bugzilla.kernel.org/show_bug.cgi?id=218890, but does not
+solve that bug. Issue is older than 4.10 kernel but fix won't apply
+to those due to major reworks in that area.
+
+Tested-by: Pierre Tomon <pierretom+12@ik.me>
+Cc: stable@vger.kernel.org # v4.10+
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20240611120610.3264502-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-ring.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 614fb89ddef61..26e57a9918995 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2288,9 +2288,8 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
+               goto finish_td;
+       case COMP_STOPPED_LENGTH_INVALID:
+               /* stopped on ep trb with invalid length, exclude it */
+-              ep_trb_len      = 0;
+-              remaining       = 0;
+-              break;
++              td->urb->actual_length = sum_trb_lengths(xhci, ep_ring, ep_trb);
++              goto finish_td;
+       case COMP_USB_TRANSACTION_ERROR:
+               if ((ep_ring->err_count++ > MAX_SOFT_RETRY) ||
+                   le32_to_cpu(slot_ctx->tt_info) & TT_SLOT)
+-- 
+2.43.0
+
diff --git a/queue-4.19/xhci-use-soft-retry-to-recover-faster-from-transacti.patch b/queue-4.19/xhci-use-soft-retry-to-recover-faster-from-transacti.patch
new file mode 100644 (file)
index 0000000..4104712
--- /dev/null
@@ -0,0 +1,113 @@
+From 295e0a3fdaff1ed32450d4fcab20c59c550c4ec2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Sep 2018 19:13:37 +0300
+Subject: xhci: Use soft retry to recover faster from transaction errors
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit f8f80be501aa2f10669585c3e328fad079d8cb3a ]
+
+Use soft retry to recover from a USB Transaction Errors that are caused by
+temporary error conditions. The USB device is not aware that the xHC
+has halted the endpoint, and will be waiting for another retry
+
+A Soft Retry perform additional retries and recover from an error which has
+caused the xHC to halt an endpoint.
+
+Soft retry has some limitations:
+Soft Retry attempts shall not be performed on Isoch endpoints
+Soft Retry attempts shall not be performed if the device is behind a TT in
+a HS Hub
+
+Software shall limit the number of unsuccessful Soft Retry attempts to
+prevent an infinite loop.
+
+For more details on Soft retry see xhci specs  4.6.8.1
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: f0260589b439 ("xhci: Set correct transferred length for cancelled bulk transfers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-ring.c | 19 +++++++++++++++++++
+ drivers/usb/host/xhci.h      |  2 ++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 8723c7f1c24fe..614fb89ddef61 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1213,6 +1213,10 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
+               /* Clear our internal halted state */
+               ep->ep_state &= ~EP_HALTED;
+       }
++
++      /* if this was a soft reset, then restart */
++      if ((le32_to_cpu(trb->generic.field[3])) & TRB_TSP)
++              ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
+ }
+ static void xhci_handle_cmd_enable_slot(struct xhci_hcd *xhci, int slot_id,
+@@ -2245,10 +2249,16 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
+       union xhci_trb *ep_trb, struct xhci_transfer_event *event,
+       struct xhci_virt_ep *ep, int *status)
+ {
++      struct xhci_slot_ctx *slot_ctx;
+       struct xhci_ring *ep_ring;
+       u32 trb_comp_code;
+       u32 remaining, requested, ep_trb_len;
++      unsigned int slot_id;
++      int ep_index;
++      slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
++      slot_ctx = xhci_get_slot_ctx(xhci, xhci->devs[slot_id]->out_ctx);
++      ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1;
+       ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer));
+       trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
+       remaining = EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+@@ -2257,6 +2267,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
+       switch (trb_comp_code) {
+       case COMP_SUCCESS:
++              ep_ring->err_count = 0;
+               /* handle success with untransferred data as short packet */
+               if (ep_trb != td->last_trb || remaining) {
+                       xhci_warn(xhci, "WARN Successful completion on short TX\n");
+@@ -2280,6 +2291,14 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
+               ep_trb_len      = 0;
+               remaining       = 0;
+               break;
++      case COMP_USB_TRANSACTION_ERROR:
++              if ((ep_ring->err_count++ > MAX_SOFT_RETRY) ||
++                  le32_to_cpu(slot_ctx->tt_info) & TT_SLOT)
++                      break;
++              *status = 0;
++              xhci_cleanup_halted_endpoint(xhci, slot_id, ep_index,
++                                      ep_ring->stream_id, td, EP_SOFT_RESET);
++              return 0;
+       default:
+               /* do nothing */
+               break;
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index f2bf3431cd6f4..cd5eb506ddd18 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1517,6 +1517,7 @@ static inline const char *xhci_trb_type_string(u8 type)
+ /* How much data is left before the 64KB boundary? */
+ #define TRB_BUFF_LEN_UP_TO_BOUNDARY(addr)     (TRB_MAX_BUFF_SIZE - \
+                                       (addr & (TRB_MAX_BUFF_SIZE - 1)))
++#define MAX_SOFT_RETRY                3
+ struct xhci_segment {
+       union xhci_trb          *trbs;
+@@ -1604,6 +1605,7 @@ struct xhci_ring {
+        * if we own the TRB (if we are the consumer).  See section 4.9.1.
+        */
+       u32                     cycle_state;
++      unsigned int            err_count;
+       unsigned int            stream_id;
+       unsigned int            num_segs;
+       unsigned int            num_trbs_free;
+-- 
+2.43.0
+