--- /dev/null
+From 9bb8ee66ee34d9d91f0c902e267105e87b7ea98f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Dec 2019 15:13:36 +0100
+Subject: iio: ad7949: fix channels mixups
+
+From: Andrea Merello <andrea.merello@gmail.com>
+
+[ Upstream commit 3b71f6b59508b1c9befcb43de434866aafc76520 ]
+
+Each time we need to read a sample (from the sysfs interface, since the
+driver supports only it) the driver writes the configuration register
+with the proper settings needed to perform the said read, then it runs
+another xfer to actually read the resulting value. Most notably the
+configuration register is updated to set the ADC internal MUX depending by
+which channel the read targets.
+
+Unfortunately this seems not enough to ensure correct operation because
+the ADC works in a pipelined-like fashion and the new configuration isn't
+applied in time.
+
+The ADC alternates two phases: acquisition and conversion. During the
+acquisition phase the ADC samples the analog signal in an internal
+capacitor; in the conversion phase the ADC performs the actual analog to
+digital conversion of the stored voltage. Note that of course the MUX
+needs to be set to the proper channel when the acquisition phase is
+performed.
+
+Once the conversion phase has been completed, the device automatically
+switches back to a new acquisition; on the other hand the device switches
+from acquisition to conversion on the rising edge of SPI cs signal (that
+is when the xfer finishes).
+
+Only after both two phases have been completed (with the proper settings
+already written in the configuration register since the beginning) it is
+possible to read the outcome from SPI bus.
+
+With the current driver implementation, we end up in the following
+situation:
+
+ _______ 1st xfer ____________ 2nd xfer ___________________
+SPI cs.. \_________/ \_________/
+SPI rd.. idle |(val N-2)+ idle | val N-1 + idle ...
+SPI wr.. idle | cfg N + idle | (X) + idle ...
+------------------------ + -------------------- + ------------------
+ AD .. acq N-1 + cnv N-1 | acq N + cnv N | acq N+1
+
+As shown in the diagram above, the value we read in the Nth read belongs
+to configuration setting N-1.
+
+In case the configuration is not changed (config[N] == config[N-1]), then
+we still get correct data, but in case the configuration changes (i.e.
+switching the MUX on another channel), we get wrong data (data from the
+previously selected channel).
+
+This patch fixes this by performing one more "dummy" transfer in order to
+ending up in reading the data when it's really ready, as per the following
+timing diagram.
+
+ _______ 1st xfer ____________ 2nd xfer ___________ 3rd xfer ___
+SPI cs.. \_________/ \_________/ \_________/
+SPI rd.. idle |(val N-2)+ idle |(val N-1)+ idle | val N + ..
+SPI wr.. idle | cfg N + idle | (X) + idle | (X) + ..
+------------------------ + -------------------- + ------------------- + --
+ AD .. acq N-1 + cnv N-1 | acq N + cnv N | acq N+1 | ..
+
+NOTE: in the latter case (cfg changes), the acquisition phase for the
+value to be read begins after the 1st xfer, that is after the read request
+has been issued on sysfs. On the other hand, if the cfg doesn't change,
+then we can refer to the fist diagram assuming N == (N - 1); the
+acquisition phase _begins_ before the 1st xfer (potentially a lot of time
+before the read has been issued via sysfs, but it _ends_ after the 1st
+xfer, that is _after_ the read has started. This should guarantee a
+reasonably fresh data, which value represents the voltage that the sampled
+signal has after the read start or maybe just around it.
+
+Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
+Reviewed-by: Charles-Antoine Couret <charles-antoine.couret@essensium.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/adc/ad7949.c | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c
+index 518044c31a73b..6b51bfcad0d04 100644
+--- a/drivers/iio/adc/ad7949.c
++++ b/drivers/iio/adc/ad7949.c
+@@ -89,6 +89,7 @@ static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val,
+ unsigned int channel)
+ {
+ int ret;
++ int i;
+ int bits_per_word = ad7949_adc->resolution;
+ int mask = GENMASK(ad7949_adc->resolution, 0);
+ struct spi_message msg;
+@@ -100,12 +101,23 @@ static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val,
+ },
+ };
+
+- ret = ad7949_spi_write_cfg(ad7949_adc,
+- channel << AD7949_OFFSET_CHANNEL_SEL,
+- AD7949_MASK_CHANNEL_SEL);
+- if (ret)
+- return ret;
++ /*
++ * 1: write CFG for sample N and read old data (sample N-2)
++ * 2: if CFG was not changed since sample N-1 then we'll get good data
++ * at the next xfer, so we bail out now, otherwise we write something
++ * and we read garbage (sample N-1 configuration).
++ */
++ for (i = 0; i < 2; i++) {
++ ret = ad7949_spi_write_cfg(ad7949_adc,
++ channel << AD7949_OFFSET_CHANNEL_SEL,
++ AD7949_MASK_CHANNEL_SEL);
++ if (ret)
++ return ret;
++ if (channel == ad7949_adc->current_channel)
++ break;
++ }
+
++ /* 3: write something and read actual data */
+ ad7949_adc->buffer = 0;
+ spi_message_init_with_transfers(&msg, tx, 1);
+ ret = spi_sync(ad7949_adc->spi, &msg);
+--
+2.20.1
+
--- /dev/null
+From 7bef164608b7e2d5e1c87b0e4760748f25fbbeac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2019 16:43:07 +0200
+Subject: iio: ad7949: kill pointless "readback"-handling code
+
+From: Andrea Merello <andrea.merello@gmail.com>
+
+[ Upstream commit c270bbf7bb9ddc4e2a51b3c56557c377c9ac79bc ]
+
+The device could be configured to spit out also the configuration word
+while reading the AD result value (in the same SPI xfer) - this is called
+"readback" in the device datasheet.
+
+The driver checks if readback is enabled and it eventually adjusts the SPI
+xfer length and it applies proper shifts to still get the data, discarding
+the configuration word.
+
+The readback option is actually never enabled (the driver disables it), so
+the said checks do not serve for any purpose.
+
+Since enabling the readback option seems not to provide any advantage (the
+driver entirely sets the configuration word without relying on any default
+value), just kill the said, unused, code.
+
+Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
+Reviewed-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7949.c | 27 +++------------------------
+ 1 file changed, 3 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c
+index ac0ffff6c5ae1..518044c31a73b 100644
+--- a/drivers/iio/adc/ad7949.c
++++ b/drivers/iio/adc/ad7949.c
+@@ -57,29 +57,11 @@ struct ad7949_adc_chip {
+ u32 buffer ____cacheline_aligned;
+ };
+
+-static bool ad7949_spi_cfg_is_read_back(struct ad7949_adc_chip *ad7949_adc)
+-{
+- if (!(ad7949_adc->cfg & AD7949_CFG_READ_BACK))
+- return true;
+-
+- return false;
+-}
+-
+-static int ad7949_spi_bits_per_word(struct ad7949_adc_chip *ad7949_adc)
+-{
+- int ret = ad7949_adc->resolution;
+-
+- if (ad7949_spi_cfg_is_read_back(ad7949_adc))
+- ret += AD7949_CFG_REG_SIZE_BITS;
+-
+- return ret;
+-}
+-
+ static int ad7949_spi_write_cfg(struct ad7949_adc_chip *ad7949_adc, u16 val,
+ u16 mask)
+ {
+ int ret;
+- int bits_per_word = ad7949_spi_bits_per_word(ad7949_adc);
++ int bits_per_word = ad7949_adc->resolution;
+ int shift = bits_per_word - AD7949_CFG_REG_SIZE_BITS;
+ struct spi_message msg;
+ struct spi_transfer tx[] = {
+@@ -107,7 +89,7 @@ static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val,
+ unsigned int channel)
+ {
+ int ret;
+- int bits_per_word = ad7949_spi_bits_per_word(ad7949_adc);
++ int bits_per_word = ad7949_adc->resolution;
+ int mask = GENMASK(ad7949_adc->resolution, 0);
+ struct spi_message msg;
+ struct spi_transfer tx[] = {
+@@ -138,10 +120,7 @@ static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val,
+
+ ad7949_adc->current_channel = channel;
+
+- if (ad7949_spi_cfg_is_read_back(ad7949_adc))
+- *val = (ad7949_adc->buffer >> AD7949_CFG_REG_SIZE_BITS) & mask;
+- else
+- *val = ad7949_adc->buffer & mask;
++ *val = ad7949_adc->buffer & mask;
+
+ return 0;
+ }
+--
+2.20.1
+
--- /dev/null
+From 2d2dd0ac065c401b9b6bf058d8c49130a6fbcd53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Oct 2019 19:02:30 +0100
+Subject: iio: imu: st_lsm6dsx: fix ODR check in st_lsm6dsx_write_raw
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit fc3f6ad7f5dc6c899fbda0255865737bac88c2e0 ]
+
+Since st_lsm6dsx i2c master controller relies on accel device as trigger
+and slave devices can run at different ODRs we must select an accel_odr >=
+slave_odr. Report real accel ODR in st_lsm6dsx_check_odr() in order to
+properly set sensor frequency in st_lsm6dsx_write_raw and avoid to
+report unsupported frequency
+
+Fixes: 6ffb55e5009ff ("iio: imu: st_lsm6dsx: introduce ST_LSM6DSX_ID_EXT sensor ids")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+index 41341cf2d9821..ba89cbbb73ae3 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+@@ -705,8 +705,7 @@ int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val)
+ return -EINVAL;
+
+ *val = odr_table->odr_avl[i].val;
+-
+- return 0;
++ return odr_table->odr_avl[i].hz;
+ }
+
+ static u16 st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u16 odr,
+@@ -869,8 +868,10 @@ static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
+ case IIO_CHAN_INFO_SAMP_FREQ: {
+ u8 data;
+
+- err = st_lsm6dsx_check_odr(sensor, val, &data);
+- if (!err)
++ val = st_lsm6dsx_check_odr(sensor, val, &data);
++ if (val < 0)
++ err = val;
++ else
+ sensor->odr = val;
+ break;
+ }
+--
+2.20.1
+
--- /dev/null
+From bc8ce90aee89ca119f231643f578faf5b286b5c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Jul 2019 21:22:28 +0200
+Subject: iio: imu: st_lsm6dsx: move odr_table in st_lsm6dsx_sensor_settings
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 40dd7343897760c4b617faa78d213e25652de9a6 ]
+
+Move sensor odr table in st_lsm6dsx_sensor_settings in order to support
+sensors with different odr maps. This is a preliminary patch to add
+support for LSM9DS1 sensor to st_lsm6dsx driver
+
+Tested-by: Martin Kepplinger <martin.kepplinger@puri.sm>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 +
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 196 ++++++++++++++++---
+ 2 files changed, 166 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+index c14bf533b66b3..ceee4e1aa5d4e 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+@@ -198,6 +198,7 @@ struct st_lsm6dsx_ext_dev_settings {
+ * @wai: Sensor WhoAmI default value.
+ * @max_fifo_size: Sensor max fifo length in FIFO words.
+ * @id: List of hw id/device name supported by the driver configuration.
++ * @odr_table: Hw sensors odr table (Hz + val).
+ * @decimator: List of decimator register info (addr + mask).
+ * @batch: List of FIFO batching register info (addr + mask).
+ * @fifo_ops: Sensor hw FIFO parameters.
+@@ -211,6 +212,7 @@ struct st_lsm6dsx_settings {
+ enum st_lsm6dsx_hw_id hw_id;
+ const char *name;
+ } id[ST_LSM6DSX_MAX_ID];
++ struct st_lsm6dsx_odr_table_entry odr_table[2];
+ struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID];
+ struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID];
+ struct st_lsm6dsx_fifo_ops fifo_ops;
+diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+index a6702a74570e2..41341cf2d9821 100644
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+@@ -69,33 +69,6 @@
+ #define ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR 0x24
+ #define ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR 0x26
+
+-static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = {
+- [ST_LSM6DSX_ID_ACC] = {
+- .reg = {
+- .addr = 0x10,
+- .mask = GENMASK(7, 4),
+- },
+- .odr_avl[0] = { 13, 0x01 },
+- .odr_avl[1] = { 26, 0x02 },
+- .odr_avl[2] = { 52, 0x03 },
+- .odr_avl[3] = { 104, 0x04 },
+- .odr_avl[4] = { 208, 0x05 },
+- .odr_avl[5] = { 416, 0x06 },
+- },
+- [ST_LSM6DSX_ID_GYRO] = {
+- .reg = {
+- .addr = 0x11,
+- .mask = GENMASK(7, 4),
+- },
+- .odr_avl[0] = { 13, 0x01 },
+- .odr_avl[1] = { 26, 0x02 },
+- .odr_avl[2] = { 52, 0x03 },
+- .odr_avl[3] = { 104, 0x04 },
+- .odr_avl[4] = { 208, 0x05 },
+- .odr_avl[5] = { 416, 0x06 },
+- }
+-};
+-
+ static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+@@ -129,6 +102,32 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+ .name = ST_LSM6DS3_DEV_NAME,
+ },
+ },
++ .odr_table = {
++ [ST_LSM6DSX_ID_ACC] = {
++ .reg = {
++ .addr = 0x10,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ [ST_LSM6DSX_ID_GYRO] = {
++ .reg = {
++ .addr = 0x11,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ },
+ .decimator = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .addr = 0x08,
+@@ -179,6 +178,32 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+ .name = ST_LSM6DS3H_DEV_NAME,
+ },
+ },
++ .odr_table = {
++ [ST_LSM6DSX_ID_ACC] = {
++ .reg = {
++ .addr = 0x10,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ [ST_LSM6DSX_ID_GYRO] = {
++ .reg = {
++ .addr = 0x11,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ },
+ .decimator = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .addr = 0x08,
+@@ -235,6 +260,32 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+ .name = ST_ISM330DLC_DEV_NAME,
+ },
+ },
++ .odr_table = {
++ [ST_LSM6DSX_ID_ACC] = {
++ .reg = {
++ .addr = 0x10,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ [ST_LSM6DSX_ID_GYRO] = {
++ .reg = {
++ .addr = 0x11,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ },
+ .decimator = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .addr = 0x08,
+@@ -288,6 +339,32 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+ .name = ST_LSM6DSOX_DEV_NAME,
+ },
+ },
++ .odr_table = {
++ [ST_LSM6DSX_ID_ACC] = {
++ .reg = {
++ .addr = 0x10,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ [ST_LSM6DSX_ID_GYRO] = {
++ .reg = {
++ .addr = 0x11,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ },
+ .batch = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .addr = 0x09,
+@@ -356,6 +433,32 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+ .name = ST_ASM330LHH_DEV_NAME,
+ },
+ },
++ .odr_table = {
++ [ST_LSM6DSX_ID_ACC] = {
++ .reg = {
++ .addr = 0x10,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ [ST_LSM6DSX_ID_GYRO] = {
++ .reg = {
++ .addr = 0x11,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ },
+ .batch = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .addr = 0x09,
+@@ -398,6 +501,32 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+ .name = ST_LSM6DSR_DEV_NAME,
+ },
+ },
++ .odr_table = {
++ [ST_LSM6DSX_ID_ACC] = {
++ .reg = {
++ .addr = 0x10,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ [ST_LSM6DSX_ID_GYRO] = {
++ .reg = {
++ .addr = 0x11,
++ .mask = GENMASK(7, 4),
++ },
++ .odr_avl[0] = { 13, 0x01 },
++ .odr_avl[1] = { 26, 0x02 },
++ .odr_avl[2] = { 52, 0x03 },
++ .odr_avl[3] = { 104, 0x04 },
++ .odr_avl[4] = { 208, 0x05 },
++ .odr_avl[5] = { 416, 0x06 },
++ },
++ },
+ .batch = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .addr = 0x09,
+@@ -560,20 +689,22 @@ static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
+
+ int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val)
+ {
++ const struct st_lsm6dsx_odr_table_entry *odr_table;
+ int i;
+
++ odr_table = &sensor->hw->settings->odr_table[sensor->id];
+ for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
+ /*
+ * ext devices can run at different odr respect to
+ * accel sensor
+ */
+- if (st_lsm6dsx_odr_table[sensor->id].odr_avl[i].hz >= odr)
++ if (odr_table->odr_avl[i].hz >= odr)
+ break;
+
+ if (i == ST_LSM6DSX_ODR_LIST_SIZE)
+ return -EINVAL;
+
+- *val = st_lsm6dsx_odr_table[sensor->id].odr_avl[i].val;
++ *val = odr_table->odr_avl[i].val;
+
+ return 0;
+ }
+@@ -638,7 +769,7 @@ static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 req_odr)
+ return err;
+ }
+
+- reg = &st_lsm6dsx_odr_table[ref_sensor->id].reg;
++ reg = &hw->settings->odr_table[ref_sensor->id].reg;
+ data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
+ return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
+ }
+@@ -783,11 +914,12 @@ st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
+ {
+ struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
+ enum st_lsm6dsx_sensor_id id = sensor->id;
++ struct st_lsm6dsx_hw *hw = sensor->hw;
+ int i, len = 0;
+
+ for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
+- st_lsm6dsx_odr_table[id].odr_avl[i].hz);
++ hw->settings->odr_table[id].odr_avl[i].hz);
+ buf[len - 1] = '\n';
+
+ return len;
+@@ -1037,7 +1169,7 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
+ sensor = iio_priv(iio_dev);
+ sensor->id = id;
+ sensor->hw = hw;
+- sensor->odr = st_lsm6dsx_odr_table[id].odr_avl[0].hz;
++ sensor->odr = hw->settings->odr_table[id].odr_avl[0].hz;
+ sensor->gain = st_lsm6dsx_fs_table[id].fs_avl[0].gain;
+ sensor->watermark = 1;
+
+--
+2.20.1
+
--- /dev/null
+From d4c14cea829fd910d874cf074bb4d65612a1801d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Nov 2019 11:30:39 +0100
+Subject: omap: pdata-quirks: remove openpandora quirks for mmc3 and wl1251
+
+From: H. Nikolaus Schaller <hns@goldelico.com>
+
+[ Upstream commit 2398c41d64321e62af54424fd399964f3d48cdc2 ]
+
+With a wl1251 child node of mmc3 in the device tree decoded
+in omap_hsmmc.c to handle special wl1251 initialization, we do
+no longer need to instantiate the mmc3 through pdata quirks.
+
+We also can remove the wlan regulator and reset/interrupt definitions
+and do them through device tree.
+
+Fixes: 81eef6ca9201 ("mmc: omap_hsmmc: Use dma_request_chan() for requesting DMA channel")
+Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
+Cc: <stable@vger.kernel.org> # v4.7+
+Acked-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/pdata-quirks.c | 93 ------------------------------
+ 1 file changed, 93 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
+index e5c99e33afae2..da21c589dbdf1 100644
+--- a/arch/arm/mach-omap2/pdata-quirks.c
++++ b/arch/arm/mach-omap2/pdata-quirks.c
+@@ -303,108 +303,15 @@ static void __init omap3_logicpd_torpedo_init(void)
+ }
+
+ /* omap3pandora legacy devices */
+-#define PANDORA_WIFI_IRQ_GPIO 21
+-#define PANDORA_WIFI_NRESET_GPIO 23
+
+ static struct platform_device pandora_backlight = {
+ .name = "pandora-backlight",
+ .id = -1,
+ };
+
+-static struct regulator_consumer_supply pandora_vmmc3_supply[] = {
+- REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"),
+-};
+-
+-static struct regulator_init_data pandora_vmmc3 = {
+- .constraints = {
+- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+- },
+- .num_consumer_supplies = ARRAY_SIZE(pandora_vmmc3_supply),
+- .consumer_supplies = pandora_vmmc3_supply,
+-};
+-
+-static struct fixed_voltage_config pandora_vwlan = {
+- .supply_name = "vwlan",
+- .microvolts = 1800000, /* 1.8V */
+- .gpio = PANDORA_WIFI_NRESET_GPIO,
+- .startup_delay = 50000, /* 50ms */
+- .enable_high = 1,
+- .init_data = &pandora_vmmc3,
+-};
+-
+-static struct platform_device pandora_vwlan_device = {
+- .name = "reg-fixed-voltage",
+- .id = 1,
+- .dev = {
+- .platform_data = &pandora_vwlan,
+- },
+-};
+-
+-static void pandora_wl1251_init_card(struct mmc_card *card)
+-{
+- /*
+- * We have TI wl1251 attached to MMC3. Pass this information to
+- * SDIO core because it can't be probed by normal methods.
+- */
+- if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) {
+- card->quirks |= MMC_QUIRK_NONSTD_SDIO;
+- card->cccr.wide_bus = 1;
+- card->cis.vendor = 0x104c;
+- card->cis.device = 0x9066;
+- card->cis.blksize = 512;
+- card->cis.max_dtr = 24000000;
+- card->ocr = 0x80;
+- }
+-}
+-
+-static struct omap2_hsmmc_info pandora_mmc3[] = {
+- {
+- .mmc = 3,
+- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+- .gpio_cd = -EINVAL,
+- .gpio_wp = -EINVAL,
+- .init_card = pandora_wl1251_init_card,
+- },
+- {} /* Terminator */
+-};
+-
+-static void __init pandora_wl1251_init(void)
+-{
+- struct wl1251_platform_data pandora_wl1251_pdata;
+- int ret;
+-
+- memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
+-
+- pandora_wl1251_pdata.power_gpio = -1;
+-
+- ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq");
+- if (ret < 0)
+- goto fail;
+-
+- pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO);
+- if (pandora_wl1251_pdata.irq < 0)
+- goto fail_irq;
+-
+- pandora_wl1251_pdata.use_eeprom = true;
+- ret = wl1251_set_platform_data(&pandora_wl1251_pdata);
+- if (ret < 0)
+- goto fail_irq;
+-
+- return;
+-
+-fail_irq:
+- gpio_free(PANDORA_WIFI_IRQ_GPIO);
+-fail:
+- pr_err("wl1251 board initialisation failed\n");
+-}
+-
+ static void __init omap3_pandora_legacy_init(void)
+ {
+ platform_device_register(&pandora_backlight);
+- platform_device_register(&pandora_vwlan_device);
+- omap_hsmmc_init(pandora_mmc3);
+- omap_hsmmc_late_init(pandora_mmc3);
+- pandora_wl1251_init();
+ }
+ #endif /* CONFIG_ARCH_OMAP3 */
+
+--
+2.20.1
+
--- /dev/null
+From 81aafb0a9a4a01352ec778fc57856161c21915f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Nov 2019 11:30:38 +0100
+Subject: omap: pdata-quirks: revert pandora specific gpiod additions
+
+From: H. Nikolaus Schaller <hns@goldelico.com>
+
+[ Upstream commit 4e8fad98171babe019db51c15055ec74697e9525 ]
+
+This partly reverts the commit efdfeb079cc3 ("regulator: fixed: Convert to
+use GPIO descriptor only").
+
+We must remove this from mainline first, so that the following patch
+to remove the openpandora quirks for mmc3 and wl1251 cleanly applies
+to stable v4.9, v4.14, v4.19 where the above mentioned patch is not yet
+present.
+
+Since the code affected is removed (no pandora gpios in pdata-quirks
+and more), there will be no matching revert-of-the-revert.
+
+Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/pdata-quirks.c | 19 ++++---------------
+ 1 file changed, 4 insertions(+), 15 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
+index 6c6f8fce854e2..e5c99e33afae2 100644
+--- a/arch/arm/mach-omap2/pdata-quirks.c
++++ b/arch/arm/mach-omap2/pdata-quirks.c
+@@ -7,7 +7,6 @@
+ #include <linux/clk.h>
+ #include <linux/davinci_emac.h>
+ #include <linux/gpio.h>
+-#include <linux/gpio/machine.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/of_platform.h>
+@@ -327,7 +326,9 @@ static struct regulator_init_data pandora_vmmc3 = {
+ static struct fixed_voltage_config pandora_vwlan = {
+ .supply_name = "vwlan",
+ .microvolts = 1800000, /* 1.8V */
++ .gpio = PANDORA_WIFI_NRESET_GPIO,
+ .startup_delay = 50000, /* 50ms */
++ .enable_high = 1,
+ .init_data = &pandora_vmmc3,
+ };
+
+@@ -339,19 +340,6 @@ static struct platform_device pandora_vwlan_device = {
+ },
+ };
+
+-static struct gpiod_lookup_table pandora_vwlan_gpiod_table = {
+- .dev_id = "reg-fixed-voltage.1",
+- .table = {
+- /*
+- * As this is a low GPIO number it should be at the first
+- * GPIO bank.
+- */
+- GPIO_LOOKUP("gpio-0-31", PANDORA_WIFI_NRESET_GPIO,
+- NULL, GPIO_ACTIVE_HIGH),
+- { },
+- },
+-};
+-
+ static void pandora_wl1251_init_card(struct mmc_card *card)
+ {
+ /*
+@@ -373,6 +361,8 @@ static struct omap2_hsmmc_info pandora_mmc3[] = {
+ {
+ .mmc = 3,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
++ .gpio_cd = -EINVAL,
++ .gpio_wp = -EINVAL,
+ .init_card = pandora_wl1251_init_card,
+ },
+ {} /* Terminator */
+@@ -411,7 +401,6 @@ fail:
+ static void __init omap3_pandora_legacy_init(void)
+ {
+ platform_device_register(&pandora_backlight);
+- gpiod_add_lookup_table(&pandora_vwlan_gpiod_table);
+ platform_device_register(&pandora_vwlan_device);
+ omap_hsmmc_init(pandora_mmc3);
+ omap_hsmmc_late_init(pandora_mmc3);
+--
+2.20.1
+
--- /dev/null
+From cb05df091da84826c46b437bafd6b4569d67a15a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Nov 2019 23:55:45 -0500
+Subject: Revert "scsi: qla2xxx: Fix memory leak when sending I/O fails"
+
+From: Martin K. Petersen <martin.petersen@oracle.com>
+
+[ Upstream commit 5a993e507ee65a28eca6690ee11868555c4ca46b ]
+
+This reverts commit 2f856d4e8c23f5ad5221f8da4a2f22d090627f19.
+
+This patch was found to introduce a double free regression. The issue
+it originally attempted to address was fixed in patch
+f45bca8c5052 ("scsi: qla2xxx: Fix double scsi_done for abort path").
+
+Link: https://lore.kernel.org/r/4BDE2B95-835F-43BE-A32C-2629D7E03E0A@marvell.com
+Requested-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_os.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 6be453985a12d..484045e4d194f 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -947,8 +947,6 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
+
+ qc24_host_busy_free_sp:
+ sp->free(sp);
+- CMD_SP(cmd) = NULL;
+- qla2x00_rel_sp(sp);
+
+ qc24_host_busy:
+ return SCSI_MLQUEUE_HOST_BUSY;
+@@ -1038,8 +1036,6 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
+
+ qc24_host_busy_free_sp:
+ sp->free(sp);
+- CMD_SP(cmd) = NULL;
+- qla2xxx_rel_qpair_sp(sp->qpair, sp);
+
+ qc24_host_busy:
+ return SCSI_MLQUEUE_HOST_BUSY;
+--
+2.20.1
+
--- /dev/null
+From 3e9594269f59db8caaf5f8df2a882e15f95db0a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Oct 2019 14:18:21 -0700
+Subject: scsi: lpfc: Fix bad ndlp ptr in xri aborted handling
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 324e1c402069e8d277d2a2b18ce40bde1265b96a ]
+
+In cases where I/O may be aborted, such as driver unload or link bounces,
+the system will crash based on a bad ndlp pointer.
+
+Example:
+ RIP: 0010:lpfc_sli4_abts_err_handler+0x15/0x140 [lpfc]
+ ...
+ lpfc_sli4_io_xri_aborted+0x20d/0x270 [lpfc]
+ lpfc_sli4_sp_handle_abort_xri_wcqe.isra.54+0x84/0x170 [lpfc]
+ lpfc_sli4_fp_handle_cqe+0xc2/0x480 [lpfc]
+ __lpfc_sli4_process_cq+0xc6/0x230 [lpfc]
+ __lpfc_sli4_hba_process_cq+0x29/0xc0 [lpfc]
+ process_one_work+0x14c/0x390
+
+Crash was caused by a bad ndlp address passed to I/O indicated by the XRI
+aborted CQE. The address was not NULL so the routine deferenced the ndlp
+ptr. The bad ndlp also caused the lpfc_sli4_io_xri_aborted to call an
+erroneous io handler. Root cause for the bad ndlp was an lpfc_ncmd that
+was aborted, put on the abort_io list, completed, taken off the abort_io
+list, sent to lpfc_release_nvme_buf where it was put back on the abort_io
+list because the lpfc_ncmd->flags setting LPFC_SBUF_XBUSY was not cleared
+on the final completion.
+
+Rework the exchange busy handling to ensure the flags are properly set for
+both scsi and nvme.
+
+Fixes: c490850a0947 ("scsi: lpfc: Adapt partitioned XRI lists to efficient sharing")
+Cc: <stable@vger.kernel.org> # v5.1+
+Link: https://lore.kernel.org/r/20191018211832.7917-6-jsmart2021@gmail.com
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_scsi.c | 11 +++++++----
+ drivers/scsi/lpfc/lpfc_sli.c | 5 ++++-
+ drivers/scsi/lpfc/lpfc_sli.h | 3 +--
+ 3 files changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
+index f9df800e70672..6ba4a741a8053 100644
+--- a/drivers/scsi/lpfc/lpfc_scsi.c
++++ b/drivers/scsi/lpfc/lpfc_scsi.c
+@@ -583,7 +583,7 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
+ if (psb->cur_iocbq.sli4_xritag == xri) {
+ list_del(&psb->list);
+ qp->abts_scsi_io_bufs--;
+- psb->exch_busy = 0;
++ psb->flags &= ~LPFC_SBUF_XBUSY;
+ psb->status = IOSTAT_SUCCESS;
+ spin_unlock(
+ &qp->abts_scsi_buf_list_lock);
+@@ -615,7 +615,7 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
+ if (iocbq->sli4_xritag != xri)
+ continue;
+ psb = container_of(iocbq, struct lpfc_io_buf, cur_iocbq);
+- psb->exch_busy = 0;
++ psb->flags &= ~LPFC_SBUF_XBUSY;
+ spin_unlock_irqrestore(&phba->hbalock, iflag);
+ if (!list_empty(&pring->txq))
+ lpfc_worker_wake_up(phba);
+@@ -834,7 +834,7 @@ lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *psb)
+ psb->prot_seg_cnt = 0;
+
+ qp = psb->hdwq;
+- if (psb->exch_busy) {
++ if (psb->flags & LPFC_SBUF_XBUSY) {
+ spin_lock_irqsave(&qp->abts_scsi_buf_list_lock, iflag);
+ psb->pCmd = NULL;
+ list_add_tail(&psb->list, &qp->lpfc_abts_scsi_buf_list);
+@@ -3679,7 +3679,10 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
+ lpfc_cmd->result = (pIocbOut->iocb.un.ulpWord[4] & IOERR_PARAM_MASK);
+ lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
+ /* pick up SLI4 exhange busy status from HBA */
+- lpfc_cmd->exch_busy = pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY;
++ if (pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY)
++ lpfc_cmd->flags |= LPFC_SBUF_XBUSY;
++ else
++ lpfc_cmd->flags &= ~LPFC_SBUF_XBUSY;
+
+ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+ if (lpfc_cmd->prot_data_type) {
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index c7027ecd4d19e..6f6e306ff1e6c 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -11768,7 +11768,10 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
+ !(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) {
+ lpfc_cmd = container_of(cmdiocbq, struct lpfc_io_buf,
+ cur_iocbq);
+- lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY;
++ if (rspiocbq && (rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY))
++ lpfc_cmd->flags |= LPFC_SBUF_XBUSY;
++ else
++ lpfc_cmd->flags &= ~LPFC_SBUF_XBUSY;
+ }
+
+ pdone_q = cmdiocbq->context_un.wait_queue;
+diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
+index 467b8270f7fdd..9449236c231d5 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.h
++++ b/drivers/scsi/lpfc/lpfc_sli.h
+@@ -375,14 +375,13 @@ struct lpfc_io_buf {
+
+ struct lpfc_nodelist *ndlp;
+ uint32_t timeout;
+- uint16_t flags; /* TBD convert exch_busy to flags */
++ uint16_t flags;
+ #define LPFC_SBUF_XBUSY 0x1 /* SLI4 hba reported XB on WCQE cmpl */
+ #define LPFC_SBUF_BUMP_QDEPTH 0x2 /* bumped queue depth counter */
+ /* External DIF device IO conversions */
+ #define LPFC_SBUF_NORMAL_DIF 0x4 /* normal mode to insert/strip */
+ #define LPFC_SBUF_PASS_DIF 0x8 /* insert/strip mode to passthru */
+ #define LPFC_SBUF_NOT_POSTED 0x10 /* SGL failed post to FW. */
+- uint16_t exch_busy; /* SLI4 hba reported XB on complete WCQE */
+ uint16_t status; /* From IOCB Word 7- ulpStatus */
+ uint32_t result; /* From IOCB Word 4. */
+
+--
+2.20.1
+
--- /dev/null
+From 90903cabb597d4127cf731e624c414d19cdef64e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2019 20:01:52 -0700
+Subject: scsi: qla2xxx: Always check the qla2x00_wait_for_hba_online() return
+ value
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit e6803efae5acd109fad9f2f07dab674563441a53 ]
+
+This patch fixes several Coverity complaints about not always checking
+the qla2x00_wait_for_hba_online() return value.
+
+Cc: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Tested-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_attr.c | 3 ++-
+ drivers/scsi/qla2xxx/qla_target.c | 7 +++++--
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
+index 9584c5a483975..d9a0eb1d8a1d2 100644
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -725,7 +725,8 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
+ break;
+ } else {
+ /* Make sure FC side is not in reset */
+- qla2x00_wait_for_hba_online(vha);
++ WARN_ON_ONCE(qla2x00_wait_for_hba_online(vha) !=
++ QLA_SUCCESS);
+
+ /* Issue MPI reset */
+ scsi_block_requests(vha->host);
+diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
+index 7e98d1be757dc..7c44f84a58e92 100644
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -6681,7 +6681,8 @@ qlt_enable_vha(struct scsi_qla_host *vha)
+ } else {
+ set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
+ qla2xxx_wake_dpc(base_vha);
+- qla2x00_wait_for_hba_online(base_vha);
++ WARN_ON_ONCE(qla2x00_wait_for_hba_online(base_vha) !=
++ QLA_SUCCESS);
+ }
+ mutex_unlock(&ha->optrom_mutex);
+ }
+@@ -6712,7 +6713,9 @@ static void qlt_disable_vha(struct scsi_qla_host *vha)
+
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ qla2xxx_wake_dpc(vha);
+- qla2x00_wait_for_hba_online(vha);
++ if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS)
++ ql_dbg(ql_dbg_tgt, vha, 0xe081,
++ "qla2x00_wait_for_hba_online() failed\n");
+ }
+
+ /*
+--
+2.20.1
+
--- /dev/null
+From b9911dcb6406b24cd8a533b4a12ea565fa1428d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2019 20:02:00 -0700
+Subject: scsi: qla2xxx: Check secondary image if reading the primary image
+ fails
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 0597fe601a3a7d103c35b922046251906e0349b3 ]
+
+This patch fixes several Coverity complaints about reading data that has
+not been initialized.
+
+Cc: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Tested-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 2f39ed9c66d64..bcd3411fc6be8 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -7624,8 +7624,12 @@ qla27xx_get_active_image(struct scsi_qla_host *vha,
+ goto check_sec_image;
+ }
+
+- qla24xx_read_flash_data(vha, (void *)(&pri_image_status),
+- ha->flt_region_img_status_pri, sizeof(pri_image_status) >> 2);
++ if (qla24xx_read_flash_data(vha, (void *)(&pri_image_status),
++ ha->flt_region_img_status_pri, sizeof(pri_image_status) >> 2) !=
++ QLA_SUCCESS) {
++ WARN_ON_ONCE(true);
++ goto check_sec_image;
++ }
+ qla27xx_print_image(vha, "Primary image", &pri_image_status);
+
+ if (qla27xx_check_image_status_signature(&pri_image_status)) {
+--
+2.20.1
+
--- /dev/null
+From f8341a13e516cacae8c45f09d0f9f3afa834b217 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2019 07:06:51 -0800
+Subject: scsi: qla2xxx: Do command completion on abort timeout
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 71c80b75ce8f08c0978ce9a9816b81b5c3ce5e12 ]
+
+On switch, fabric and mgt command timeout, driver send Abort to tell FW to
+return the original command. If abort is timeout, then return both Abort
+and original command for cleanup.
+
+Fixes: 219d27d7147e0 ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands")
+Cc: stable@vger.kernel.org # 5.2
+Link: https://lore.kernel.org/r/20191105150657.8092-3-hmadhani@marvell.com
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_def.h | 1 +
+ drivers/scsi/qla2xxx/qla_init.c | 18 ++++++++++++++++++
+ 2 files changed, 19 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index bb1c7b2d0ac1f..674ee2afe2b52 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -543,6 +543,7 @@ typedef struct srb {
+ const char *name;
+ int iocbs;
+ struct qla_qpair *qpair;
++ struct srb *cmd_sp;
+ struct list_head elem;
+ u32 gen1; /* scratch */
+ u32 gen2; /* scratch */
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 5df604fae7593..a75a40b14140a 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -103,8 +103,22 @@ static void qla24xx_abort_iocb_timeout(void *data)
+ u32 handle;
+ unsigned long flags;
+
++ if (sp->cmd_sp)
++ ql_dbg(ql_dbg_async, sp->vha, 0x507c,
++ "Abort timeout - cmd hdl=%x, cmd type=%x hdl=%x, type=%x\n",
++ sp->cmd_sp->handle, sp->cmd_sp->type,
++ sp->handle, sp->type);
++ else
++ ql_dbg(ql_dbg_async, sp->vha, 0x507c,
++ "Abort timeout 2 - hdl=%x, type=%x\n",
++ sp->handle, sp->type);
++
+ spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+ for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
++ if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] ==
++ sp->cmd_sp))
++ qpair->req->outstanding_cmds[handle] = NULL;
++
+ /* removing the abort */
+ if (qpair->req->outstanding_cmds[handle] == sp) {
+ qpair->req->outstanding_cmds[handle] = NULL;
+@@ -113,6 +127,9 @@ static void qla24xx_abort_iocb_timeout(void *data)
+ }
+ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+
++ if (sp->cmd_sp)
++ sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
++
+ abt->u.abt.comp_status = CS_TIMEOUT;
+ sp->done(sp, QLA_OS_TIMER_EXPIRED);
+ }
+@@ -147,6 +164,7 @@ static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
+ sp->type = SRB_ABT_CMD;
+ sp->name = "abort";
+ sp->qpair = cmd_sp->qpair;
++ sp->cmd_sp = cmd_sp;
+ if (wait)
+ sp->flags = SRB_WAKEUP_ON_COMP;
+
+--
+2.20.1
+
--- /dev/null
+From 5f24bf00b8280e18c0da9c947c2061600be9ba66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2019 20:42:26 -0800
+Subject: scsi: qla2xxx: Fix a dma_pool_free() call
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 162b805e38327135168cb0938bd37b131b481cb0 ]
+
+This patch fixes the following kernel warning:
+
+DMA-API: qla2xxx 0000:00:0a.0: device driver frees DMA memory with different size [device address=0x00000000c7b60000] [map size=4088 bytes] [unmap size=512 bytes]
+WARNING: CPU: 3 PID: 1122 at kernel/dma/debug.c:1021 check_unmap+0x4d0/0xbd0
+CPU: 3 PID: 1122 Comm: rmmod Tainted: G O 5.4.0-rc1-dbg+ #1
+RIP: 0010:check_unmap+0x4d0/0xbd0
+Call Trace:
+ debug_dma_free_coherent+0x123/0x173
+ dma_free_attrs+0x76/0xe0
+ qla2x00_mem_free+0x329/0xc40 [qla2xxx_scst]
+ qla2x00_free_device+0x170/0x1c0 [qla2xxx_scst]
+ qla2x00_remove_one+0x4f0/0x6d0 [qla2xxx_scst]
+ pci_device_remove+0xd5/0x1f0
+ device_release_driver_internal+0x159/0x280
+ driver_detach+0x8b/0xf2
+ bus_remove_driver+0x9a/0x15a
+ driver_unregister+0x51/0x70
+ pci_unregister_driver+0x2d/0x130
+ qla2x00_module_exit+0x1c/0xbc [qla2xxx_scst]
+ __x64_sys_delete_module+0x22a/0x300
+ do_syscall_64+0x6f/0x2e0
+ entry_SYSCALL_64_after_hwframe+0x49/0xbe
+
+Fixes: 3f006ac342c0 ("scsi: qla2xxx: Secure flash update support for ISP28XX") # v5.2-rc1~130^2~270.
+Cc: Michael Hernandez <mhernandez@marvell.com>
+Cc: Himanshu Madhani <hmadhani@marvell.com>
+Link: https://lore.kernel.org/r/20191106044226.5207-3-bvanassche@acm.org
+Reviewed-by: Martin Wilck <mwilck@suse.com>
+Acked-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_os.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index d2e7a4e7b3a9a..6be453985a12d 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -4703,7 +4703,8 @@ qla2x00_mem_free(struct qla_hw_data *ha)
+ ha->sfp_data = NULL;
+
+ if (ha->flt)
+- dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE,
++ dma_free_coherent(&ha->pdev->dev,
++ sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE,
+ ha->flt, ha->flt_dma);
+ ha->flt = NULL;
+ ha->flt_dma = 0;
+--
+2.20.1
+
--- /dev/null
+From 7d59d5cd13bbe64d3bdb42c797224fecd48980e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2019 20:02:06 -0700
+Subject: scsi: qla2xxx: Fix a race condition between aborting and completing a
+ SCSI command
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 85cffefa09e448906a6f0bc20f422d75a18675bd ]
+
+Instead of allocating a struct srb dynamically from inside .queuecommand(),
+set qla2xxx_driver_template.cmd_size such that struct scsi_cmnd and struct
+srb are contiguous. Do not call QLA_QPAIR_MARK_BUSY() /
+QLA_QPAIR_MARK_NOT_BUSY() for SRBs associated with SCSI commands. That is
+safe because scsi_remove_host() is called before queue pairs are deleted
+and scsi_remove_host() waits for all outstanding SCSI commands to finish.
+
+Cc: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Tested-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_def.h | 1 -
+ drivers/scsi/qla2xxx/qla_os.c | 45 ++++++----------------------------
+ 2 files changed, 8 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index 0eb1d5a790b26..ea1728fe2c768 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -562,7 +562,6 @@ typedef struct srb {
+ } srb_t;
+
+ #define GET_CMD_SP(sp) (sp->u.scmd.cmd)
+-#define SET_CMD_SP(sp, cmd) (sp->u.scmd.cmd = cmd)
+ #define GET_CMD_CTX_SP(sp) (sp->u.scmd.ctx)
+
+ #define GET_CMD_SENSE_LEN(sp) \
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 484045e4d194f..3aa2dd43945bf 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -727,7 +727,6 @@ qla2x00_sp_compl(void *ptr, int res)
+ cmd->scsi_done(cmd);
+ if (comp)
+ complete(comp);
+- qla2x00_rel_sp(sp);
+ }
+
+ void
+@@ -832,7 +831,6 @@ qla2xxx_qpair_sp_compl(void *ptr, int res)
+ cmd->scsi_done(cmd);
+ if (comp)
+ complete(comp);
+- qla2xxx_rel_qpair_sp(sp->qpair, sp);
+ }
+
+ static int
+@@ -925,9 +923,8 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
+ else
+ goto qc24_target_busy;
+
+- sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
+- if (!sp)
+- goto qc24_host_busy;
++ sp = scsi_cmd_priv(cmd);
++ qla2xxx_init_sp(sp, vha, vha->hw->base_qpair, fcport);
+
+ sp->u.scmd.cmd = cmd;
+ sp->type = SRB_SCSI_CMD;
+@@ -948,9 +945,6 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
+ qc24_host_busy_free_sp:
+ sp->free(sp);
+
+-qc24_host_busy:
+- return SCSI_MLQUEUE_HOST_BUSY;
+-
+ qc24_target_busy:
+ return SCSI_MLQUEUE_TARGET_BUSY;
+
+@@ -1011,9 +1005,8 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
+ else
+ goto qc24_target_busy;
+
+- sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC);
+- if (!sp)
+- goto qc24_host_busy;
++ sp = scsi_cmd_priv(cmd);
++ qla2xxx_init_sp(sp, vha, qpair, fcport);
+
+ sp->u.scmd.cmd = cmd;
+ sp->type = SRB_SCSI_CMD;
+@@ -1037,9 +1030,6 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
+ qc24_host_busy_free_sp:
+ sp->free(sp);
+
+-qc24_host_busy:
+- return SCSI_MLQUEUE_HOST_BUSY;
+-
+ qc24_target_busy:
+ return SCSI_MLQUEUE_TARGET_BUSY;
+
+@@ -1280,10 +1270,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ int ret;
+ unsigned int id;
+ uint64_t lun;
+- unsigned long flags;
+ int rval;
+ struct qla_hw_data *ha = vha->hw;
+- struct qla_qpair *qpair;
+
+ if (qla2x00_isp_reg_stat(ha)) {
+ ql_log(ql_log_info, vha, 0x8042,
+@@ -1295,29 +1283,11 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ if (ret != 0)
+ return ret;
+
+- sp = (srb_t *) CMD_SP(cmd);
+- if (!sp)
+- return SUCCESS;
++ sp = scsi_cmd_priv(cmd);
+
+- qpair = sp->qpair;
+- if (!qpair)
+- return SUCCESS;
+-
+- spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+- if (sp->type != SRB_SCSI_CMD || GET_CMD_SP(sp) != cmd) {
+- /* there's a chance an interrupt could clear
+- the ptr as part of done & free */
+- spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+- return SUCCESS;
+- }
+-
+- /* Get a reference to the sp and drop the lock. */
+- if (sp_get(sp)){
+- /* ref_count is already 0 */
+- spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
++ /* Return if the command has already finished. */
++ if (sp_get(sp))
+ return SUCCESS;
+- }
+- spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+
+ id = cmd->device->id;
+ lun = cmd->device->lun;
+@@ -7197,6 +7167,7 @@ struct scsi_host_template qla2xxx_driver_template = {
+
+ .supported_mode = MODE_INITIATOR,
+ .track_queue_depth = 1,
++ .cmd_size = sizeof(srb_t),
+ };
+
+ static const struct pci_error_handlers qla2xxx_err_handler = {
+--
+2.20.1
+
--- /dev/null
+From c573fe6f462f04aef3ac24932272e2682bafedbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jul 2019 09:07:28 -0700
+Subject: scsi: qla2xxx: Fix abort timeout race condition.
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 0c6df59061b23c7a951836d23977be34e896d3da ]
+
+If an abort times out, the Abort IOCB completion and Abort timer can race
+against each other. This patch provides unique error code for timer path to
+allow proper cleanup.
+
+[mkp: typo]
+
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_def.h | 1 +
+ drivers/scsi/qla2xxx/qla_init.c | 18 ++++++++++++++++--
+ 2 files changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index a2922b17b55b0..bb1c7b2d0ac1f 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -4629,6 +4629,7 @@ struct secure_flash_update_block_pk {
+ #define QLA_SUSPENDED 0x106
+ #define QLA_BUSY 0x107
+ #define QLA_ALREADY_REGISTERED 0x109
++#define QLA_OS_TIMER_EXPIRED 0x10a
+
+ #define NVRAM_DELAY() udelay(10)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index afc890bc50e4f..5df604fae7593 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -99,9 +99,22 @@ static void qla24xx_abort_iocb_timeout(void *data)
+ {
+ srb_t *sp = data;
+ struct srb_iocb *abt = &sp->u.iocb_cmd;
++ struct qla_qpair *qpair = sp->qpair;
++ u32 handle;
++ unsigned long flags;
++
++ spin_lock_irqsave(qpair->qp_lock_ptr, flags);
++ for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
++ /* removing the abort */
++ if (qpair->req->outstanding_cmds[handle] == sp) {
++ qpair->req->outstanding_cmds[handle] = NULL;
++ break;
++ }
++ }
++ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+
+ abt->u.abt.comp_status = CS_TIMEOUT;
+- sp->done(sp, QLA_FUNCTION_TIMEOUT);
++ sp->done(sp, QLA_OS_TIMER_EXPIRED);
+ }
+
+ static void qla24xx_abort_sp_done(void *ptr, int res)
+@@ -109,7 +122,8 @@ static void qla24xx_abort_sp_done(void *ptr, int res)
+ srb_t *sp = ptr;
+ struct srb_iocb *abt = &sp->u.iocb_cmd;
+
+- if (del_timer(&sp->u.iocb_cmd.timer)) {
++ if ((res == QLA_OS_TIMER_EXPIRED) ||
++ del_timer(&sp->u.iocb_cmd.timer)) {
+ if (sp->flags & SRB_WAKEUP_ON_COMP)
+ complete(&abt->u.abt.comp);
+ else
+--
+2.20.1
+
--- /dev/null
+From ef8bb7c2632a5cae888509217fa10517a4376b55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jul 2019 09:07:27 -0700
+Subject: scsi: qla2xxx: Fix different size DMA Alloc/Unmap
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit d376dbda187317d06d3a2d495b43a7983e4a3250 ]
+
+[ 17.177276] qla2xxx 0000:05:00.0: DMA-API: device driver frees DMA memory
+ with different size [device address=0x00000006198b0000] [map size=32784 bytes]
+ [unmap size=8208 bytes]
+[ 17.177390] RIP: 0010:check_unmap+0x7a2/0x1750
+[ 17.177425] Call Trace:
+[ 17.177438] debug_dma_free_coherent+0x1b5/0x2d5
+[ 17.177470] dma_free_attrs+0x7f/0x140
+[ 17.177489] qla24xx_sp_unmap+0x1e2/0x610 [qla2xxx]
+[ 17.177509] qla24xx_async_gnnft_done+0x9c6/0x17d0 [qla2xxx]
+[ 17.177535] qla2x00_do_work+0x514/0x2200 [qla2xxx]
+
+Fixes: b5f3bc39a0e8 ("scsi: qla2xxx: Fix inconsistent DMA mem alloc/free")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_gs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index 9f58e591666da..ebf223cfebbc5 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -4152,7 +4152,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
+ rspsz,
+ &sp->u.iocb_cmd.u.ctarg.rsp_dma,
+ GFP_KERNEL);
+- sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
++ sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz;
+ if (!sp->u.iocb_cmd.u.ctarg.rsp) {
+ ql_log(ql_log_warn, vha, 0xffff,
+ "Failed to allocate ct_sns request.\n");
+--
+2.20.1
+
--- /dev/null
+From e0c1bf1f50b0393eb02d7bd3c47953c7afc35151 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jul 2019 09:07:26 -0700
+Subject: scsi: qla2xxx: Fix DMA unmap leak
+
+From: Himanshu Madhani <hmadhani@marvell.com>
+
+[ Upstream commit 5d328de64d89400dcf9911125844d8adc0db697f ]
+
+With debug kernel we see following wanings indicating memory leak.
+
+[28809.523959] WARNING: CPU: 3 PID: 6790 at lib/dma-debug.c:978
+dma_debug_device_change+0x166/0x1d0
+[28809.523964] pci 0000:0c:00.6: DMA-API: device driver has pending DMA
+allocations while released from device [count=5]
+[28809.523964] One of leaked entries details: [device
+address=0x00000002aefe4000] [size=8208 bytes] [mapped with DMA_BIDIRECTIONAL]
+[mapped as coherent]
+
+Fix this by unmapping DMA memory.
+
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_bsg.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
+index 3084c2cff7bd5..ce87bbdb30907 100644
+--- a/drivers/scsi/qla2xxx/qla_bsg.c
++++ b/drivers/scsi/qla2xxx/qla_bsg.c
+@@ -341,6 +341,8 @@ qla2x00_process_els(struct bsg_job *bsg_job)
+ dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
+ bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
+ if (!req_sg_cnt) {
++ dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
++ bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
+ rval = -ENOMEM;
+ goto done_free_fcport;
+ }
+@@ -348,6 +350,8 @@ qla2x00_process_els(struct bsg_job *bsg_job)
+ rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
+ bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+ if (!rsp_sg_cnt) {
++ dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
++ bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+ rval = -ENOMEM;
+ goto done_free_fcport;
+ }
+--
+2.20.1
+
--- /dev/null
+From a5576d5dd17ee2945b2ca533b2d8714c3d322c24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2019 07:06:54 -0800
+Subject: scsi: qla2xxx: Fix double scsi_done for abort path
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit f45bca8c5052e8c59bab64ee90c44441678b9a52 ]
+
+Current code assumes abort will remove the original command from the active
+list where scsi_done will not be called. Instead, the eh_abort thread will
+do the scsi_done. That is not the case. Instead, we have a double
+scsi_done calls triggering use after free.
+
+Abort will tell FW to release the command from FW possesion. The original
+command will return to ULP with error in its normal fashion via scsi_done.
+eh_abort path would wait for the original command completion before
+returning. eh_abort path will not perform the scsi_done call.
+
+Fixes: 219d27d7147e0 ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands")
+Cc: stable@vger.kernel.org # 5.2
+Link: https://lore.kernel.org/r/20191105150657.8092-6-hmadhani@marvell.com
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Arun Easi <aeasi@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_def.h | 5 +-
+ drivers/scsi/qla2xxx/qla_isr.c | 5 ++
+ drivers/scsi/qla2xxx/qla_nvme.c | 4 +-
+ drivers/scsi/qla2xxx/qla_os.c | 118 +++++++++++++++++---------------
+ 4 files changed, 74 insertions(+), 58 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index ea1728fe2c768..29af738ca203e 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -531,13 +531,16 @@ typedef struct srb {
+ */
+ uint8_t cmd_type;
+ uint8_t pad[3];
+- atomic_t ref_count;
+ struct kref cmd_kref; /* need to migrate ref_count over to this */
+ void *priv;
+ wait_queue_head_t nvme_ls_waitq;
+ struct fc_port *fcport;
+ struct scsi_qla_host *vha;
+ unsigned int start_timer:1;
++ unsigned int abort:1;
++ unsigned int aborted:1;
++ unsigned int completed:1;
++
+ uint32_t handle;
+ uint16_t flags;
+ uint16_t type;
+diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
+index f7458d74ae3d2..9e32a90d4d773 100644
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -2473,6 +2473,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
+ return;
+ }
+
++ if (sp->abort)
++ sp->aborted = 1;
++ else
++ sp->completed = 1;
++
+ if (sp->cmd_type != TYPE_SRB) {
+ req->outstanding_cmds[handle] = NULL;
+ ql_dbg(ql_dbg_io, vha, 0x3015,
+diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
+index 963094b3c3007..672da9b838e52 100644
+--- a/drivers/scsi/qla2xxx/qla_nvme.c
++++ b/drivers/scsi/qla2xxx/qla_nvme.c
+@@ -227,8 +227,8 @@ static void qla_nvme_abort_work(struct work_struct *work)
+
+ if (ha->flags.host_shutting_down) {
+ ql_log(ql_log_info, sp->fcport->vha, 0xffff,
+- "%s Calling done on sp: %p, type: 0x%x, sp->ref_count: 0x%x\n",
+- __func__, sp, sp->type, atomic_read(&sp->ref_count));
++ "%s Calling done on sp: %p, type: 0x%x\n",
++ __func__, sp, sp->type);
+ sp->done(sp, 0);
+ goto out;
+ }
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 3aa2dd43945bf..ac2977bdc3595 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -716,11 +716,6 @@ qla2x00_sp_compl(void *ptr, int res)
+ struct scsi_cmnd *cmd = GET_CMD_SP(sp);
+ struct completion *comp = sp->comp;
+
+- if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0))
+- return;
+-
+- atomic_dec(&sp->ref_count);
+-
+ sp->free(sp);
+ cmd->result = res;
+ CMD_SP(cmd) = NULL;
+@@ -820,11 +815,6 @@ qla2xxx_qpair_sp_compl(void *ptr, int res)
+ struct scsi_cmnd *cmd = GET_CMD_SP(sp);
+ struct completion *comp = sp->comp;
+
+- if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0))
+- return;
+-
+- atomic_dec(&sp->ref_count);
+-
+ sp->free(sp);
+ cmd->result = res;
+ CMD_SP(cmd) = NULL;
+@@ -928,7 +918,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
+
+ sp->u.scmd.cmd = cmd;
+ sp->type = SRB_SCSI_CMD;
+- atomic_set(&sp->ref_count, 1);
++
+ CMD_SP(cmd) = (void *)sp;
+ sp->free = qla2x00_sp_free_dma;
+ sp->done = qla2x00_sp_compl;
+@@ -1010,11 +1000,9 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
+
+ sp->u.scmd.cmd = cmd;
+ sp->type = SRB_SCSI_CMD;
+- atomic_set(&sp->ref_count, 1);
+ CMD_SP(cmd) = (void *)sp;
+ sp->free = qla2xxx_qpair_sp_free_dma;
+ sp->done = qla2xxx_qpair_sp_compl;
+- sp->qpair = qpair;
+
+ rval = ha->isp_ops->start_scsi_mq(sp);
+ if (rval != QLA_SUCCESS) {
+@@ -1207,16 +1195,6 @@ qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
+ return return_status;
+ }
+
+-static int
+-sp_get(struct srb *sp)
+-{
+- if (!refcount_inc_not_zero((refcount_t *)&sp->ref_count))
+- /* kref get fail */
+- return ENXIO;
+- else
+- return 0;
+-}
+-
+ #define ISP_REG_DISCONNECT 0xffffffffU
+ /**************************************************************************
+ * qla2x00_isp_reg_stat
+@@ -1272,6 +1250,9 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ uint64_t lun;
+ int rval;
+ struct qla_hw_data *ha = vha->hw;
++ uint32_t ratov_j;
++ struct qla_qpair *qpair;
++ unsigned long flags;
+
+ if (qla2x00_isp_reg_stat(ha)) {
+ ql_log(ql_log_info, vha, 0x8042,
+@@ -1284,11 +1265,27 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ return ret;
+
+ sp = scsi_cmd_priv(cmd);
++ qpair = sp->qpair;
+
+- /* Return if the command has already finished. */
+- if (sp_get(sp))
++ if ((sp->fcport && sp->fcport->deleted) || !qpair)
+ return SUCCESS;
+
++ spin_lock_irqsave(qpair->qp_lock_ptr, flags);
++ if (sp->completed) {
++ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
++ return SUCCESS;
++ }
++
++ if (sp->abort || sp->aborted) {
++ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
++ return FAILED;
++ }
++
++ sp->abort = 1;
++ sp->comp = ∁
++ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
++
++
+ id = cmd->device->id;
+ lun = cmd->device->lun;
+
+@@ -1296,47 +1293,37 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n",
+ vha->host_no, id, lun, sp, cmd, sp->handle);
+
++ /*
++ * Abort will release the original Command/sp from FW. Let the
++ * original command call scsi_done. In return, he will wakeup
++ * this sleeping thread.
++ */
+ rval = ha->isp_ops->abort_command(sp);
++
+ ql_dbg(ql_dbg_taskm, vha, 0x8003,
+ "Abort command mbx cmd=%p, rval=%x.\n", cmd, rval);
+
++ /* Wait for the command completion. */
++ ratov_j = ha->r_a_tov/10 * 4 * 1000;
++ ratov_j = msecs_to_jiffies(ratov_j);
+ switch (rval) {
+ case QLA_SUCCESS:
+- /*
+- * The command has been aborted. That means that the firmware
+- * won't report a completion.
+- */
+- sp->done(sp, DID_ABORT << 16);
+- ret = SUCCESS;
+- break;
+- case QLA_FUNCTION_PARAMETER_ERROR: {
+- /* Wait for the command completion. */
+- uint32_t ratov = ha->r_a_tov/10;
+- uint32_t ratov_j = msecs_to_jiffies(4 * ratov * 1000);
+-
+- WARN_ON_ONCE(sp->comp);
+- sp->comp = ∁
+ if (!wait_for_completion_timeout(&comp, ratov_j)) {
+ ql_dbg(ql_dbg_taskm, vha, 0xffff,
+ "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n",
+- __func__, ha->r_a_tov);
++ __func__, ha->r_a_tov/10);
+ ret = FAILED;
+ } else {
+ ret = SUCCESS;
+ }
+ break;
+- }
+ default:
+- /*
+- * Either abort failed or abort and completion raced. Let
+- * the SCSI core retry the abort in the former case.
+- */
+ ret = FAILED;
+ break;
+ }
+
+ sp->comp = NULL;
+- atomic_dec(&sp->ref_count);
++
+ ql_log(ql_log_info, vha, 0x801c,
+ "Abort command issued nexus=%ld:%d:%llu -- %x.\n",
+ vha->host_no, id, lun, ret);
+@@ -1719,32 +1706,53 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
+ scsi_qla_host_t *vha = qp->vha;
+ struct qla_hw_data *ha = vha->hw;
+ int rval;
++ bool ret_cmd;
++ uint32_t ratov_j;
+
+- if (sp_get(sp))
++ if (qla2x00_chip_is_down(vha)) {
++ sp->done(sp, res);
+ return;
++ }
+
+ if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS ||
+ (sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy &&
+ !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
+ !qla2x00_isp_reg_stat(ha))) {
++ if (sp->comp) {
++ sp->done(sp, res);
++ return;
++ }
++
+ sp->comp = ∁
++ sp->abort = 1;
+ spin_unlock_irqrestore(qp->qp_lock_ptr, *flags);
+- rval = ha->isp_ops->abort_command(sp);
+
++ rval = ha->isp_ops->abort_command(sp);
++ /* Wait for command completion. */
++ ret_cmd = false;
++ ratov_j = ha->r_a_tov/10 * 4 * 1000;
++ ratov_j = msecs_to_jiffies(ratov_j);
+ switch (rval) {
+ case QLA_SUCCESS:
+- sp->done(sp, res);
++ if (wait_for_completion_timeout(&comp, ratov_j)) {
++ ql_dbg(ql_dbg_taskm, vha, 0xffff,
++ "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n",
++ __func__, ha->r_a_tov/10);
++ ret_cmd = true;
++ }
++ /* else FW return SP to driver */
+ break;
+- case QLA_FUNCTION_PARAMETER_ERROR:
+- wait_for_completion(&comp);
++ default:
++ ret_cmd = true;
+ break;
+ }
+
+ spin_lock_irqsave(qp->qp_lock_ptr, *flags);
+- sp->comp = NULL;
++ if (ret_cmd && (!sp->completed || !sp->aborted))
++ sp->done(sp, res);
++ } else {
++ sp->done(sp, res);
+ }
+-
+- atomic_dec(&sp->ref_count);
+ }
+
+ static void
+@@ -1766,7 +1774,6 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
+ for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
+ sp = req->outstanding_cmds[cnt];
+ if (sp) {
+- req->outstanding_cmds[cnt] = NULL;
+ switch (sp->cmd_type) {
+ case TYPE_SRB:
+ qla2x00_abort_srb(qp, sp, res, &flags);
+@@ -1788,6 +1795,7 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
+ default:
+ break;
+ }
++ req->outstanding_cmds[cnt] = NULL;
+ }
+ }
+ spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
+--
+2.20.1
+
--- /dev/null
+From 0d181c091ec5a53594b1107e7ba059908ae864e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Aug 2019 15:23:59 -0700
+Subject: scsi: qla2xxx: Fix driver reload for ISP82xx
+
+From: Himanshu Madhani <hmadhani@marvell.com>
+
+[ Upstream commit 32a13df21668b92f70f0673387f29251e0f285ec ]
+
+HINT_MBX_INT_PENDING is not guaranteed to be cleared by firmware. Remove
+check that prevent driver load with ISP82XX.
+
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Link: https://lore.kernel.org/r/20190830222402.23688-4-hmadhani@marvell.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_mbx.c | 16 ++--------------
+ drivers/scsi/qla2xxx/qla_nx.c | 3 ++-
+ 2 files changed, 4 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
+index ac4640f456786..45548628c6f3e 100644
+--- a/drivers/scsi/qla2xxx/qla_mbx.c
++++ b/drivers/scsi/qla2xxx/qla_mbx.c
+@@ -253,21 +253,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
+ if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
+ set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
+
+- if (IS_P3P_TYPE(ha)) {
+- if (RD_REG_DWORD(®->isp82.hint) &
+- HINT_MBX_INT_PENDING) {
+- ha->flags.mbox_busy = 0;
+- spin_unlock_irqrestore(&ha->hardware_lock,
+- flags);
+-
+- atomic_dec(&ha->num_pend_mbx_stage2);
+- ql_dbg(ql_dbg_mbx, vha, 0x1010,
+- "Pending mailbox timeout, exiting.\n");
+- rval = QLA_FUNCTION_TIMEOUT;
+- goto premature_exit;
+- }
++ if (IS_P3P_TYPE(ha))
+ WRT_REG_DWORD(®->isp82.hint, HINT_MBX_INT_PENDING);
+- } else if (IS_FWI2_CAPABLE(ha))
++ else if (IS_FWI2_CAPABLE(ha))
+ WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT);
+ else
+ WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT);
+diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
+index 6ce0f026debb1..3a23827e0f0bc 100644
+--- a/drivers/scsi/qla2xxx/qla_nx.c
++++ b/drivers/scsi/qla2xxx/qla_nx.c
+@@ -2287,7 +2287,8 @@ qla82xx_disable_intrs(struct qla_hw_data *ha)
+ {
+ scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
+
+- qla82xx_mbx_intr_disable(vha);
++ if (ha->interrupts_on)
++ qla82xx_mbx_intr_disable(vha);
+
+ spin_lock_irq(&ha->hardware_lock);
+ if (IS_QLA8044(ha))
+--
+2.20.1
+
--- /dev/null
+From 22942573995c8e4c06eddbc2a5fbad951eade712 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Aug 2019 15:23:58 -0700
+Subject: scsi: qla2xxx: Fix flash read for Qlogic ISPs
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit cb92cb1657c438efe7c88c9759f40c0a9d46c353 ]
+
+Use adapter specific callback to read flash instead of ISP adapter
+specific.
+
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Link: https://lore.kernel.org/r/20190830222402.23688-3-hmadhani@marvell.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 4 ++--
+ drivers/scsi/qla2xxx/qla_nx.c | 1 +
+ drivers/scsi/qla2xxx/qla_sup.c | 8 ++++----
+ 3 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index f4ed061b96886..fb9095179fc59 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -8385,7 +8385,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
+ active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
+ "primary" : "secondary");
+ }
+- qla24xx_read_flash_data(vha, ha->vpd, faddr, ha->vpd_size >> 2);
++ ha->isp_ops->read_optrom(vha, ha->vpd, faddr << 2, ha->vpd_size);
+
+ /* Get NVRAM data into cache and calculate checksum. */
+ faddr = ha->flt_region_nvram;
+@@ -8397,7 +8397,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
+ "Loading %s nvram image.\n",
+ active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
+ "primary" : "secondary");
+- qla24xx_read_flash_data(vha, ha->nvram, faddr, ha->nvram_size >> 2);
++ ha->isp_ops->read_optrom(vha, ha->nvram, faddr << 2, ha->nvram_size);
+
+ dptr = (uint32_t *)nv;
+ for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++)
+diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
+index c760ae354174c..6ce0f026debb1 100644
+--- a/drivers/scsi/qla2xxx/qla_nx.c
++++ b/drivers/scsi/qla2xxx/qla_nx.c
+@@ -2288,6 +2288,7 @@ qla82xx_disable_intrs(struct qla_hw_data *ha)
+ scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
+
+ qla82xx_mbx_intr_disable(vha);
++
+ spin_lock_irq(&ha->hardware_lock);
+ if (IS_QLA8044(ha))
+ qla8044_wr_reg(ha, LEG_INTR_MASK_OFFSET, 1);
+diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
+index 1eb82384d933c..81c5d3de666b0 100644
+--- a/drivers/scsi/qla2xxx/qla_sup.c
++++ b/drivers/scsi/qla2xxx/qla_sup.c
+@@ -680,8 +680,8 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
+
+ ha->flt_region_flt = flt_addr;
+ wptr = (uint16_t *)ha->flt;
+- qla24xx_read_flash_data(vha, (void *)flt, flt_addr,
+- (sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE) >> 2);
++ ha->isp_ops->read_optrom(vha, (void *)flt, flt_addr << 2,
++ (sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE));
+
+ if (le16_to_cpu(*wptr) == 0xffff)
+ goto no_flash_data;
+@@ -948,11 +948,11 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vha)
+ struct req_que *req = ha->req_q_map[0];
+ uint16_t cnt, chksum;
+ uint16_t *wptr = (void *)req->ring;
+- struct qla_fdt_layout *fdt = (void *)req->ring;
++ struct qla_fdt_layout *fdt = (struct qla_fdt_layout *)req->ring;
+ uint8_t man_id, flash_id;
+ uint16_t mid = 0, fid = 0;
+
+- qla24xx_read_flash_data(vha, (void *)fdt, ha->flt_region_fdt,
++ ha->isp_ops->read_optrom(vha, fdt, ha->flt_region_fdt << 2,
+ OPTROM_BURST_DWORDS);
+ if (le16_to_cpu(*wptr) == 0xffff)
+ goto no_flash_data;
+--
+2.20.1
+
--- /dev/null
+From 1858b07b3131e3d7d3f2e15ad3604af8bbdb4766 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jul 2019 09:07:38 -0700
+Subject: scsi: qla2xxx: Fix hang in fcport delete path
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit f00b3428a801758243693e046b34226e92bc56b3 ]
+
+A hang was observed in the fcport delete path when the device was
+responding slow and an issue-lip path (results in session termination) was
+taken.
+
+Fix this by issuing logo requests unconditionally.
+
+PID: 19491 TASK: ffff8e23e67bb150 CPU: 0 COMMAND: "kworker/0:0"
+ #0 [ffff8e2370297bf8] __schedule at ffffffffb4f7dbb0
+ #1 [ffff8e2370297c88] schedule at ffffffffb4f7e199
+ #2 [ffff8e2370297c98] schedule_timeout at ffffffffb4f7ba68
+ #3 [ffff8e2370297d40] msleep at ffffffffb48ad9ff
+ #4 [ffff8e2370297d58] qlt_free_session_done at ffffffffc0c32052 [qla2xxx]
+ #5 [ffff8e2370297e20] process_one_work at ffffffffb48bcfdf
+ #6 [ffff8e2370297e68] worker_thread at ffffffffb48bdca6
+ #7 [ffff8e2370297ec8] kthread at ffffffffb48c4f81
+
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 2c617a34ae1e7..2f39ed9c66d64 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -396,9 +396,6 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
+ struct srb_iocb *lio;
+ int rval = QLA_FUNCTION_FAILED;
+
+- if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
+- return rval;
+-
+ fcport->flags |= FCF_ASYNC_SENT;
+ sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
+ if (!sp)
+--
+2.20.1
+
--- /dev/null
+From 4fa0b08b234fb80f9ec35bf2af61486ec70433f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Aug 2019 15:23:57 -0700
+Subject: scsi: qla2xxx: Fix message indicating vectors used by driver
+
+From: Himanshu Madhani <hmadhani@marvell.com>
+
+[ Upstream commit da48b82425b8bf999fb9f7c220e967c4d661b5f8 ]
+
+This patch updates log message which indicates number of vectors used by
+the driver instead of displaying failure to get maximum requested
+vectors. Driver will always request maximum vectors during
+initialization. In the event driver is not able to get maximum requested
+vectors, it will adjust the allocated vectors. This is normal and does not
+imply failure in driver.
+
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Link: https://lore.kernel.org/r/20190830222402.23688-2-hmadhani@marvell.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_isr.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
+index 78aec50abe0f8..f7458d74ae3d2 100644
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -3471,10 +3471,8 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
+ ha->msix_count, ret);
+ goto msix_out;
+ } else if (ret < ha->msix_count) {
+- ql_log(ql_log_warn, vha, 0x00c6,
+- "MSI-X: Failed to enable support "
+- "with %d vectors, using %d vectors.\n",
+- ha->msix_count, ret);
++ ql_log(ql_log_info, vha, 0x00c6,
++ "MSI-X: Using %d vectors\n", ret);
+ ha->msix_count = ret;
+ /* Recalculate queue values */
+ if (ha->mqiobase && (ql2xmqsupport || ql2xnvmeenable)) {
+--
+2.20.1
+
--- /dev/null
+From 2333e57d3a8eb9b0ad33da6094360c8b8d8b537d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jul 2019 09:07:36 -0700
+Subject: scsi: qla2xxx: Fix NVMe port discovery after a short device port loss
+
+From: Arun Easi <aeasi@marvell.com>
+
+[ Upstream commit 9e744591ef1b8df27c25c68dac858dada8688f77 ]
+
+The following sequence of event leads to NVME port disappearing:
+
+ - device port shut
+ - nvme_fc_unregister_remoteport
+ - device port online
+ - remote port delete completes
+ - relogin is scheduled
+ - "post gidpn" message appears due to rscn generation # mismatch
+
+In short, if a device comes back online sooner than an unregister
+completion, a mismatch in rscn generation number occurs, which is not
+handled correctly during device relogin. Fix this by starting with a redo
+of GNL.
+
+When ql2xextended_error_logging is enabled, the re-plugged device's
+discovery stops with the following messages printed:
+
+--8<--
+qla2xxx [0000:41:00.0]-480d:3: Relogin scheduled.
+qla2xxx [0000:41:00.0]-4800:3: DPC handler sleeping.
+qla2xxx [0000:41:00.0]-2902:3: qla24xx_handle_relogin_event 21:00:00:24:ff:17:9e:91 DS 0 LS 7 P 0 del 2 cnfl
+ (null) rscn 1|2 login 1|2 fl 1
+qla2xxx [0000:41:00.0]-28e9:3: qla24xx_handle_relogin_event 1666 21:00:00:24:ff:17:9e:91 post gidpn
+qla2xxx [0000:41:00.0]-480e:3: Relogin end.
+--8<--
+
+Signed-off-by: Arun Easi <aeasi@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index a75a40b14140a..2c617a34ae1e7 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -1712,9 +1712,9 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
+ }
+
+ if (fcport->last_rscn_gen != fcport->rscn_gen) {
+- ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gidpn\n",
++ ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gnl\n",
+ __func__, __LINE__, fcport->port_name);
+-
++ qla24xx_post_gnl_work(vha, fcport);
+ return;
+ }
+
+--
+2.20.1
+
--- /dev/null
+From f96bc1d59f77081ce35b4b74e0b8575ff919d382 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jul 2019 09:07:33 -0700
+Subject: scsi: qla2xxx: Fix premature timer expiration
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 3a4b6cc7332130ac5cbf3b505d8cddf0aa2ea745 ]
+
+For any qla2xxx async command, the SRB buffer is used to send it. In
+setting up the SRB buffer, the timer for this command is started before all
+memory allocation has finished. Under low memory pressure, memory alloc
+can go to sleep and not wake up before the timer expires. Once timer has
+expired, the timer thread will access uninitialize fields resulting into
+NULL pointer crash.
+
+This patch fixes this crash by moving the start of timer after everything
+is setup.
+
+backtrace shows following
+
+PID: 3720 TASK: ffff996928401040 CPU: 0 COMMAND: "qla2xxx_1_dpc"
+0 [ffff99652751b698] __schedule at ffffffff965676c7
+1 [ffff99652751b728] schedule at ffffffff96567bc9
+2 [ffff99652751b738] schedule_timeout at ffffffff965655e8
+3 [ffff99652751b7e0] io_schedule_timeout at ffffffff9656726d
+4 [ffff99652751b810] congestion_wait at ffffffff95fd8d12
+5 [ffff99652751b870] isolate_migratepages_range at ffffffff95fddaf3
+6 [ffff99652751b930] compact_zone at ffffffff95fdde96
+7 [ffff99652751b980] compact_zone_order at ffffffff95fde0bc
+8 [ffff99652751ba20] try_to_compact_pages at ffffffff95fde481
+9 [ffff99652751ba80] __alloc_pages_direct_compact at ffffffff9655cc31
+10 [ffff99652751bae0] __alloc_pages_slowpath at ffffffff9655d101
+11 [ffff99652751bbd0] __alloc_pages_nodemask at ffffffff95fc0e95
+12 [ffff99652751bc80] dma_generic_alloc_coherent at ffffffff95e3217f
+13 [ffff99652751bcc8] x86_swiotlb_alloc_coherent at ffffffff95e6b7a1
+14 [ffff99652751bcf8] qla2x00_rft_id at ffffffffc055b5e0 [qla2xxx]
+15 [ffff99652751bd50] qla2x00_loop_resync at ffffffffc0533e71 [qla2xxx]
+16 [ffff99652751be68] qla2x00_do_dpc at ffffffffc05210ca [qla2xxx]
+
+PID: 0 TASK: ffffffff96a18480 CPU: 0 COMMAND: "swapper/0"
+ 0 [ffff99652fc03ae0] machine_kexec at ffffffff95e63674
+ 1 [ffff99652fc03b40] __crash_kexec at ffffffff95f1ce12
+ 2 [ffff99652fc03c10] crash_kexec at ffffffff95f1cf00
+ 3 [ffff99652fc03c28] oops_end at ffffffff9656c758
+ 4 [ffff99652fc03c50] no_context at ffffffff9655aa7e
+ 5 [ffff99652fc03ca0] __bad_area_nosemaphore at ffffffff9655ab15
+ 6 [ffff99652fc03cf0] bad_area_nosemaphore at ffffffff9655ac86
+ 7 [ffff99652fc03d00] __do_page_fault at ffffffff9656f6b0
+ 8 [ffff99652fc03d70] do_page_fault at ffffffff9656f915
+ 9 [ffff99652fc03da0] page_fault at ffffffff9656b758
+ [exception RIP: unknown or invalid address]
+ RIP: 0000000000000000 RSP: ffff99652fc03e50 RFLAGS: 00010202
+ RAX: 0000000000000000 RBX: ffff99652b79a600 RCX: ffff99652b79a760
+ RDX: ffff99652b79a600 RSI: ffffffffc0525ad0 RDI: ffff99652b79a600
+ RBP: ffff99652fc03e60 R8: ffffffff96a18a18 R9: ffffffff96ee3c00
+ R10: 0000000000000002 R11: ffff99652fc03de8 R12: ffff99652b79a760
+ R13: 0000000000000100 R14: ffffffffc0525ad0 R15: ffff99652b79a600
+ ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
+10 [ffff99652fc03e50] qla2x00_sp_timeout at ffffffffc0525af8 [qla2xxx]
+11 [ffff99652fc03e68] call_timer_fn at ffffffff95ea7f58
+12 [ffff99652fc03ea0] run_timer_softirq at ffffffff95eaa3bd
+13 [ffff99652fc03f18] __do_softirq at ffffffff95ea0f05
+14 [ffff99652fc03f88] call_softirq at ffffffff9657832c
+15 [ffff99652fc03fa0] do_softirq at ffffffff95e2e675
+16 [ffff99652fc03fc0] irq_exit at ffffffff95ea1285
+17 [ffff99652fc03fd8] smp_apic_timer_interrupt at ffffffff965796c8
+18 [ffff99652fc03ff0] apic_timer_interrupt at ffffffff96575df2
+
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_def.h | 1 +
+ drivers/scsi/qla2xxx/qla_iocb.c | 5 ++++-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index 674ee2afe2b52..0eb1d5a790b26 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -537,6 +537,7 @@ typedef struct srb {
+ wait_queue_head_t nvme_ls_waitq;
+ struct fc_port *fcport;
+ struct scsi_qla_host *vha;
++ unsigned int start_timer:1;
+ uint32_t handle;
+ uint16_t flags;
+ uint16_t type;
+diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
+index 9312b19ed708b..1886de92034c7 100644
+--- a/drivers/scsi/qla2xxx/qla_iocb.c
++++ b/drivers/scsi/qla2xxx/qla_iocb.c
+@@ -2540,7 +2540,7 @@ void qla2x00_init_timer(srb_t *sp, unsigned long tmo)
+ sp->free = qla2x00_sp_free;
+ if (IS_QLAFX00(sp->vha->hw) && sp->type == SRB_FXIOCB_DCMD)
+ init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
+- add_timer(&sp->u.iocb_cmd.timer);
++ sp->start_timer = 1;
+ }
+
+ static void
+@@ -3668,6 +3668,9 @@ qla2x00_start_sp(srb_t *sp)
+ break;
+ }
+
++ if (sp->start_timer)
++ add_timer(&sp->u.iocb_cmd.timer);
++
+ wmb();
+ qla2x00_start_iocbs(vha, qp->req);
+ done:
+--
+2.20.1
+
--- /dev/null
+From 59dc44002b0b140345a433dbe289a945c1df6cd9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2019 20:01:48 -0700
+Subject: scsi: qla2xxx: Fix qla24xx_process_bidir_cmd()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit c29282c65d1cf54daeea63be46243d7f69d72f4d ]
+
+Set the r??_data_len variables before using these instead of after.
+
+This patch fixes the following Coverity complaint:
+
+const: At condition req_data_len != rsp_data_len, the value of req_data_len
+must be equal to 0.
+const: At condition req_data_len != rsp_data_len, the value of rsp_data_len
+must be equal to 0.
+dead_error_condition: The condition req_data_len != rsp_data_len cannot be
+true.
+
+Cc: Himanshu Madhani <hmadhani@marvell.com>
+Fixes: a9b6f722f62d ("[SCSI] qla2xxx: Implementation of bidirectional.") # v3.7.
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Tested-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_bsg.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
+index ce87bbdb30907..be9eeabe965e2 100644
+--- a/drivers/scsi/qla2xxx/qla_bsg.c
++++ b/drivers/scsi/qla2xxx/qla_bsg.c
+@@ -1782,8 +1782,8 @@ qla24xx_process_bidir_cmd(struct bsg_job *bsg_job)
+ uint16_t nextlid = 0;
+ uint32_t tot_dsds;
+ srb_t *sp = NULL;
+- uint32_t req_data_len = 0;
+- uint32_t rsp_data_len = 0;
++ uint32_t req_data_len;
++ uint32_t rsp_data_len;
+
+ /* Check the type of the adapter */
+ if (!IS_BIDI_CAPABLE(ha)) {
+@@ -1888,6 +1888,9 @@ qla24xx_process_bidir_cmd(struct bsg_job *bsg_job)
+ goto done_unmap_sg;
+ }
+
++ req_data_len = bsg_job->request_payload.payload_len;
++ rsp_data_len = bsg_job->reply_payload.payload_len;
++
+ if (req_data_len != rsp_data_len) {
+ rval = EXT_STATUS_BUSY;
+ ql_log(ql_log_warn, vha, 0x70aa,
+@@ -1895,10 +1898,6 @@ qla24xx_process_bidir_cmd(struct bsg_job *bsg_job)
+ goto done_unmap_sg;
+ }
+
+- req_data_len = bsg_job->request_payload.payload_len;
+- rsp_data_len = bsg_job->reply_payload.payload_len;
+-
+-
+ /* Alloc SRB structure */
+ sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL);
+ if (!sp) {
+--
+2.20.1
+
--- /dev/null
+From 32b7b4fefa5192ddca1bc48019a0b65aeecc1e08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2019 20:01:40 -0700
+Subject: scsi: qla2xxx: Fix session lookup in qlt_abort_work()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit ac452b8e79320c9e90c78edf32ba2d42431e4daf ]
+
+Pass the correct session ID to find_sess_by_s_id() instead of passing an
+uninitialized variable.
+
+Cc: Himanshu Madhani <hmadhani@marvell.com>
+Fixes: 2d70c103fd2a ("[SCSI] qla2xxx: Add LLD target-mode infrastructure for >= 24xx series") # v3.5.
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Tested-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_target.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
+index 1bb0fc9324ead..7e98d1be757dc 100644
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -6195,7 +6195,6 @@ static void qlt_abort_work(struct qla_tgt *tgt,
+ struct qla_hw_data *ha = vha->hw;
+ struct fc_port *sess = NULL;
+ unsigned long flags = 0, flags2 = 0;
+- uint32_t be_s_id;
+ uint8_t s_id[3];
+ int rc;
+
+@@ -6208,8 +6207,7 @@ static void qlt_abort_work(struct qla_tgt *tgt,
+ s_id[1] = prm->abts.fcp_hdr_le.s_id[1];
+ s_id[2] = prm->abts.fcp_hdr_le.s_id[0];
+
+- sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
+- (unsigned char *)&be_s_id);
++ sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id);
+ if (!sess) {
+ spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
+
+--
+2.20.1
+
--- /dev/null
+From 1841b2421dede6356fef142928dd45b55b0d9569 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2019 07:06:52 -0800
+Subject: scsi: qla2xxx: Fix SRB leak on switch command timeout
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit af2a0c51b1205327f55a7e82e530403ae1d42cbb ]
+
+when GPSC/GPDB switch command fails, driver just returns without doing a
+proper cleanup. This patch fixes this memory leak by calling sp->free() in
+the error path.
+
+Link: https://lore.kernel.org/r/20191105150657.8092-4-hmadhani@marvell.com
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_gs.c | 2 +-
+ drivers/scsi/qla2xxx/qla_init.c | 11 +++++------
+ drivers/scsi/qla2xxx/qla_mbx.c | 4 ----
+ drivers/scsi/qla2xxx/qla_mid.c | 11 ++++-------
+ drivers/scsi/qla2xxx/qla_os.c | 7 ++++++-
+ 5 files changed, 16 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index dec521d726d91..97ca95cd174bc 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3029,7 +3029,7 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
+ fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
+
+ if (res == QLA_FUNCTION_TIMEOUT)
+- return;
++ goto done;
+
+ if (res == (DID_ERROR << 16)) {
+ /* entry status error */
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index d4e381f81997b..b84afef37f70b 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -1169,13 +1169,11 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)
+ "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n",
+ sp->name, res, fcport->port_name, mb[1], mb[2]);
+
+- if (res == QLA_FUNCTION_TIMEOUT) {
+- dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
+- sp->u.iocb_cmd.u.mbx.in_dma);
+- return;
+- }
+-
+ fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
++
++ if (res == QLA_FUNCTION_TIMEOUT)
++ goto done;
++
+ memset(&ea, 0, sizeof(ea));
+ ea.event = FCME_GPDB_DONE;
+ ea.fcport = fcport;
+@@ -1183,6 +1181,7 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)
+
+ qla2x00_fcport_event_handler(vha, &ea);
+
++done:
+ dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
+ sp->u.iocb_cmd.u.mbx.in_dma);
+
+diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
+index 45548628c6f3e..8601e63e4698f 100644
+--- a/drivers/scsi/qla2xxx/qla_mbx.c
++++ b/drivers/scsi/qla2xxx/qla_mbx.c
+@@ -6285,17 +6285,13 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)
+ case QLA_SUCCESS:
+ ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n",
+ __func__, sp->name);
+- sp->free(sp);
+ break;
+ default:
+ ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n",
+ __func__, sp->name, rval);
+- sp->free(sp);
+ break;
+ }
+
+- return rval;
+-
+ done_free_sp:
+ sp->free(sp);
+ done:
+diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
+index b2977e49356ba..0341dc0e06510 100644
+--- a/drivers/scsi/qla2xxx/qla_mid.c
++++ b/drivers/scsi/qla2xxx/qla_mid.c
+@@ -934,7 +934,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
+
+ sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL);
+ if (!sp)
+- goto done;
++ return rval;
+
+ sp->type = SRB_CTRL_VP;
+ sp->name = "ctrl_vp";
+@@ -950,7 +950,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
+ ql_dbg(ql_dbg_async, vha, 0xffff,
+ "%s: %s Failed submission. %x.\n",
+ __func__, sp->name, rval);
+- goto done_free_sp;
++ goto done;
+ }
+
+ ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n",
+@@ -968,16 +968,13 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
+ case QLA_SUCCESS:
+ ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s done.\n",
+ __func__, sp->name);
+- goto done_free_sp;
++ break;
+ default:
+ ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s Failed. %x.\n",
+ __func__, sp->name, rval);
+- goto done_free_sp;
++ break;
+ }
+ done:
+- return rval;
+-
+-done_free_sp:
+ sp->free(sp);
+ return rval;
+ }
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 0f51387ceebdf..d2e7a4e7b3a9a 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -1030,7 +1030,7 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
+ ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078,
+ "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd);
+ if (rval == QLA_INTERFACE_ERROR)
+- goto qc24_fail_command;
++ goto qc24_free_sp_fail_command;
+ goto qc24_host_busy_free_sp;
+ }
+
+@@ -1047,6 +1047,11 @@ qc24_host_busy:
+ qc24_target_busy:
+ return SCSI_MLQUEUE_TARGET_BUSY;
+
++qc24_free_sp_fail_command:
++ sp->free(sp);
++ CMD_SP(cmd) = NULL;
++ qla2xxx_rel_qpair_sp(sp->qpair, sp);
++
+ qc24_fail_command:
+ cmd->scsi_done(cmd);
+
+--
+2.20.1
+
--- /dev/null
+From 7e8e47ae99a11a17052394d33afb23c63536b96f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Aug 2019 15:24:01 -0700
+Subject: scsi: qla2xxx: Fix stale session
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 2037ce49d30a0d07348df406ef78f6664f4bc899 ]
+
+On fast cable pull, where driver is unable to detect device has disappeared
+and came back based on switch info, qla2xxx would not re-login while remote
+port has already invalidated the session. This causes IO timeout. This
+patch would relogin to remote device for RSCN affected port.
+
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Link: https://lore.kernel.org/r/20190830222402.23688-6-hmadhani@marvell.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_gs.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index ebf223cfebbc5..dec521d726d91 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3674,7 +3674,6 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
+ if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE))
+ continue;
+- fcport->scan_needed = 0;
+ fcport->scan_state = QLA_FCPORT_FOUND;
+ found = true;
+ /*
+@@ -3683,10 +3682,12 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
+ if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
+ qla2x00_clear_loop_id(fcport);
+ fcport->flags |= FCF_FABRIC_DEVICE;
+- } else if (fcport->d_id.b24 != rp->id.b24) {
++ } else if (fcport->d_id.b24 != rp->id.b24 ||
++ fcport->scan_needed) {
+ qlt_schedule_sess_for_deletion(fcport);
+ }
+ fcport->d_id.b24 = rp->id.b24;
++ fcport->scan_needed = 0;
+ break;
+ }
+
+--
+2.20.1
+
--- /dev/null
+From c05458c54b67750cce5a1681a80badcd7a0ea456 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Aug 2019 15:24:00 -0700
+Subject: scsi: qla2xxx: Fix stuck login session
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit ce0ba496dccfc15d3a8866b845864585b5d316ff ]
+
+Login session was stucked on cable pull. When FW is in the middle PRLI
+PENDING + driver is in Initiator mode, driver fails to check back with FW to
+see if the PRLI has completed. This patch would re-check with FW again to
+make sure PRLI would complete before pushing forward with relogin.
+
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Link: https://lore.kernel.org/r/20190830222402.23688-5-hmadhani@marvell.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index fb9095179fc59..d4e381f81997b 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -842,6 +842,15 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
+ fcport->fw_login_state = current_login_state;
+ fcport->d_id = id;
+ switch (current_login_state) {
++ case DSC_LS_PRLI_PEND:
++ /*
++ * In the middle of PRLI. Let it finish.
++ * Allow relogin code to recheck state again
++ * with GNL. Push disc_state back to DELETED
++ * so GNL can go out again
++ */
++ fcport->disc_state = DSC_DELETED;
++ break;
+ case DSC_LS_PRLI_COMP:
+ if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
+ fcport->port_type = FCT_INITIATOR;
+@@ -1517,7 +1526,7 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
+ u64 wwn;
+ u16 sec;
+
+- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x20d8,
++ ql_dbg(ql_dbg_disc, vha, 0x20d8,
+ "%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d lid %d scan %d\n",
+ __func__, fcport->port_name, fcport->disc_state,
+ fcport->fw_login_state, fcport->login_pause, fcport->flags,
+@@ -1528,6 +1537,7 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
+ return 0;
+
+ if ((fcport->loop_id != FC_NO_LOOP_ID) &&
++ qla_dual_mode_enabled(vha) &&
+ ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
+ (fcport->fw_login_state == DSC_LS_PRLI_PEND)))
+ return 0;
+@@ -1697,17 +1707,6 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
+ fcport->last_login_gen, fcport->login_gen,
+ fcport->flags);
+
+- if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
+- (fcport->fw_login_state == DSC_LS_PRLI_PEND))
+- return;
+-
+- if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
+- if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) {
+- set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+- return;
+- }
+- }
+-
+ if (fcport->last_rscn_gen != fcport->rscn_gen) {
+ ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gnl\n",
+ __func__, __LINE__, fcport->port_name);
+--
+2.20.1
+
--- /dev/null
+From ab07e6286e3031800933fe884f15e8ebb3c6b96d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2019 20:02:05 -0700
+Subject: scsi: qla2xxx: Introduce the function qla2xxx_init_sp()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit bdb61b9b944d1e5b7cee5a9fe21014363c55b811 ]
+
+This patch does not change any functionality but makes the next patch
+easier to read.
+
+Cc: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Tested-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_inline.h | 28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
+index bf063c6643523..0c3d907af7692 100644
+--- a/drivers/scsi/qla2xxx/qla_inline.h
++++ b/drivers/scsi/qla2xxx/qla_inline.h
+@@ -152,6 +152,18 @@ qla2x00_chip_is_down(scsi_qla_host_t *vha)
+ return (qla2x00_reset_active(vha) || !vha->hw->flags.fw_started);
+ }
+
++static void qla2xxx_init_sp(srb_t *sp, scsi_qla_host_t *vha,
++ struct qla_qpair *qpair, fc_port_t *fcport)
++{
++ memset(sp, 0, sizeof(*sp));
++ sp->fcport = fcport;
++ sp->iocbs = 1;
++ sp->vha = vha;
++ sp->qpair = qpair;
++ sp->cmd_type = TYPE_SRB;
++ INIT_LIST_HEAD(&sp->elem);
++}
++
+ static inline srb_t *
+ qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair,
+ fc_port_t *fcport, gfp_t flag)
+@@ -164,19 +176,9 @@ qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair,
+ return NULL;
+
+ sp = mempool_alloc(qpair->srb_mempool, flag);
+- if (!sp)
+- goto done;
+-
+- memset(sp, 0, sizeof(*sp));
+- sp->fcport = fcport;
+- sp->iocbs = 1;
+- sp->vha = vha;
+- sp->qpair = qpair;
+- sp->cmd_type = TYPE_SRB;
+- INIT_LIST_HEAD(&sp->elem);
+-
+-done:
+- if (!sp)
++ if (sp)
++ qla2xxx_init_sp(sp, vha, qpair, fcport);
++ else
+ QLA_QPAIR_MARK_NOT_BUSY(qpair);
+ return sp;
+ }
+--
+2.20.1
+
--- /dev/null
+From 53311a02d93324531726b06da226b197118907f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2019 20:01:22 -0700
+Subject: scsi: qla2xxx: Make qla2x00_abort_srb() again decrease the sp
+ reference count
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit d2d2b5a5741d317bed1fa38211f1f3b142d8cf7a ]
+
+Since qla2x00_abort_srb() starts with increasing the reference count of
+@sp, decrease that same reference count before returning.
+
+Cc: Himanshu Madhani <hmadhani@marvell.com>
+Fixes: 219d27d7147e ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands") # v5.2.
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Tested-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_os.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index ef75897b27132..82f6ae4dcfc0b 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -1751,6 +1751,8 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
+ spin_lock_irqsave(qp->qp_lock_ptr, *flags);
+ sp->comp = NULL;
+ }
++
++ atomic_dec(&sp->ref_count);
+ }
+
+ static void
+--
+2.20.1
+
--- /dev/null
+From 8669e8f7bb2f610750abb9c93afe45c03f541bf7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2019 20:02:10 -0700
+Subject: scsi: qla2xxx: Make sure that aborted commands are freed
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 0dcec41acb85da33841c2ab56dbf337ed00a3914 ]
+
+The LIO core requires that the target driver callback functions
+.queue_data_in() and .queue_status() call target_put_sess_cmd() or
+transport_generic_free_cmd(). These calls may happen synchronously or
+asynchronously. Make sure that one of these LIO functions is called in case
+a command has been aborted. This patch avoids that the code for removing a
+session hangs due to commands that do not make progress.
+
+Cc: Himanshu Madhani <hmadhani@marvell.com>
+Fixes: 694833ee00c4 ("scsi: tcm_qla2xxx: Do not allow aborted cmd to advance.") # v4.13.
+Fixes: a07100e00ac4 ("qla2xxx: Fix TMR ABORT interaction issue between qla2xxx and TCM") # v4.5.
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Tested-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_target.c | 13 ++++++++-----
+ drivers/scsi/qla2xxx/tcm_qla2xxx.c | 4 ++++
+ 2 files changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
+index 7c44f84a58e92..0b8ec4218d6bd 100644
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -3237,7 +3237,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
+ if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) ||
+ (cmd->sess && cmd->sess->deleted)) {
+ cmd->state = QLA_TGT_STATE_PROCESSED;
+- return 0;
++ res = 0;
++ goto free;
+ }
+
+ ql_dbg_qp(ql_dbg_tgt, qpair, 0xe018,
+@@ -3248,9 +3249,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
+
+ res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status,
+ &full_req_cnt);
+- if (unlikely(res != 0)) {
+- return res;
+- }
++ if (unlikely(res != 0))
++ goto free;
+
+ spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+
+@@ -3270,7 +3270,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
+ vha->flags.online, qla2x00_reset_active(vha),
+ cmd->reset_count, qpair->chip_reset);
+ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+- return 0;
++ res = 0;
++ goto free;
+ }
+
+ /* Does F/W have an IOCBs for this request */
+@@ -3373,6 +3374,8 @@ out_unmap_unlock:
+ qlt_unmap_sg(vha, cmd);
+ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+
++free:
++ vha->hw->tgt.tgt_ops->free_cmd(cmd);
+ return res;
+ }
+ EXPORT_SYMBOL(qlt_xmit_response);
+diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+index d15412d3d9bd2..0bb06e33ecab4 100644
+--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
++++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+@@ -620,6 +620,7 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
+ {
+ struct qla_tgt_cmd *cmd = container_of(se_cmd,
+ struct qla_tgt_cmd, se_cmd);
++ struct scsi_qla_host *vha = cmd->vha;
+
+ if (cmd->aborted) {
+ /* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task
+@@ -632,6 +633,7 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
+ cmd->se_cmd.transport_state,
+ cmd->se_cmd.t_state,
+ cmd->se_cmd.se_cmd_flags);
++ vha->hw->tgt.tgt_ops->free_cmd(cmd);
+ return 0;
+ }
+
+@@ -659,6 +661,7 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
+ {
+ struct qla_tgt_cmd *cmd = container_of(se_cmd,
+ struct qla_tgt_cmd, se_cmd);
++ struct scsi_qla_host *vha = cmd->vha;
+ int xmit_type = QLA_TGT_XMIT_STATUS;
+
+ if (cmd->aborted) {
+@@ -672,6 +675,7 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
+ cmd, kref_read(&cmd->se_cmd.cmd_kref),
+ cmd->se_cmd.transport_state, cmd->se_cmd.t_state,
+ cmd->se_cmd.se_cmd_flags);
++ vha->hw->tgt.tgt_ops->free_cmd(cmd);
+ return 0;
+ }
+ cmd->bufflen = se_cmd->data_length;
+--
+2.20.1
+
--- /dev/null
+From 47e546eec181c57c79168615f1fbe1258b33d64d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Aug 2019 13:28:27 +0000
+Subject: scsi: qla2xxx: qla2x00_alloc_fw_dump: set ha->eft
+
+From: Martin Wilck <mwilck@suse.com>
+
+[ Upstream commit edbd56472a636ab396f5ee6783e8438fa725a6ee ]
+
+In qla2x00_alloc_fw_dump(), an existing EFT buffer (e.g. from previous
+invocation of qla2x00_alloc_offload_mem()) is freed. The buffer is then
+re-allocated, but without setting the eft and eft_dma fields to the new
+values.
+
+Fixes: a28d9e4ef997 ("scsi: qla2xxx: Add support for multiple fwdump templates/segments")
+Cc: Joe Carnuccio <joe.carnuccio@cavium.com>
+Cc: Quinn Tran <qutran@marvell.com>
+Cc: Himanshu Madhani <hmadhani@marvell.com>
+Cc: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin Wilck <mwilck@suse.com>
+Tested-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index bcd3411fc6be8..f4ed061b96886 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -3317,6 +3317,8 @@ try_eft:
+ ql_dbg(ql_dbg_init, vha, 0x00c3,
+ "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024);
+ eft_size = EFT_SIZE;
++ ha->eft_dma = tc_dma;
++ ha->eft = tc;
+ }
+
+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
+--
+2.20.1
+
--- /dev/null
+From 8c8154cfcdc609f7b7d604198e333e408601ae63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2019 20:01:23 -0700
+Subject: scsi: qla2xxx: Really fix qla2xxx_eh_abort()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 8dd9593cc07ad7d999bef81b06789ef873a94881 ]
+
+I'm not sure how this happened but the patch that was intended to fix abort
+handling was incomplete. This patch fixes that patch as follows:
+
+ - If aborting the SCSI command failed, wait until the SCSI command
+ completes.
+
+ - Return SUCCESS instead of FAILED if an abort attempt races with SCSI
+ command completion.
+
+ - Since qla2xxx_eh_abort() increments the sp reference count by calling
+ sp_get(), decrement the sp reference count before returning.
+
+Cc: Himanshu Madhani <hmadhani@marvell.com>
+Fixes: 219d27d7147e ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Tested-by: Himanshu Madhani <hmadhani@marvell.com>
+Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_os.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 82f6ae4dcfc0b..0f51387ceebdf 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -1274,6 +1274,7 @@ static int
+ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ {
+ scsi_qla_host_t *vha = shost_priv(cmd->device->host);
++ DECLARE_COMPLETION_ONSTACK(comp);
+ srb_t *sp;
+ int ret;
+ unsigned int id;
+@@ -1309,6 +1310,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ return SUCCESS;
+ }
+
++ /* Get a reference to the sp and drop the lock. */
+ if (sp_get(sp)){
+ /* ref_count is already 0 */
+ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+@@ -1336,6 +1338,23 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ sp->done(sp, DID_ABORT << 16);
+ ret = SUCCESS;
+ break;
++ case QLA_FUNCTION_PARAMETER_ERROR: {
++ /* Wait for the command completion. */
++ uint32_t ratov = ha->r_a_tov/10;
++ uint32_t ratov_j = msecs_to_jiffies(4 * ratov * 1000);
++
++ WARN_ON_ONCE(sp->comp);
++ sp->comp = ∁
++ if (!wait_for_completion_timeout(&comp, ratov_j)) {
++ ql_dbg(ql_dbg_taskm, vha, 0xffff,
++ "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n",
++ __func__, ha->r_a_tov);
++ ret = FAILED;
++ } else {
++ ret = SUCCESS;
++ }
++ break;
++ }
+ default:
+ /*
+ * Either abort failed or abort and completion raced. Let
+@@ -1345,6 +1364,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ break;
+ }
+
++ sp->comp = NULL;
++ atomic_dec(&sp->ref_count);
+ ql_log(ql_log_info, vha, 0x801c,
+ "Abort command issued nexus=%ld:%d:%llu -- %x.\n",
+ vha->host_no, id, lun, ret);
+--
+2.20.1
+
quota-fix-livelock-in-dquot_writeback_dquots.patch
ext4-fix-credit-estimate-for-final-inode-freeing.patch
reiserfs-fix-extended-attributes-on-the-root-directory.patch
+scsi-lpfc-fix-bad-ndlp-ptr-in-xri-aborted-handling.patch
+scsi-qla2xxx-fix-abort-timeout-race-condition.patch
+scsi-qla2xxx-do-command-completion-on-abort-timeout.patch
+scsi-qla2xxx-fix-premature-timer-expiration.patch
+scsi-qla2xxx-fix-dma-unmap-leak.patch
+scsi-qla2xxx-fix-different-size-dma-alloc-unmap.patch
+scsi-qla2xxx-fix-nvme-port-discovery-after-a-short-d.patch
+scsi-qla2xxx-fix-hang-in-fcport-delete-path.patch
+scsi-qla2xxx-make-qla2x00_abort_srb-again-decrease-t.patch
+scsi-qla2xxx-really-fix-qla2xxx_eh_abort.patch
+scsi-qla2xxx-fix-session-lookup-in-qlt_abort_work.patch
+scsi-qla2xxx-fix-qla24xx_process_bidir_cmd.patch
+scsi-qla2xxx-always-check-the-qla2x00_wait_for_hba_o.patch
+scsi-qla2xxx-check-secondary-image-if-reading-the-pr.patch
+scsi-qla2xxx-make-sure-that-aborted-commands-are-fre.patch
+scsi-qla2xxx-qla2x00_alloc_fw_dump-set-ha-eft.patch
+scsi-qla2xxx-fix-message-indicating-vectors-used-by-.patch
+scsi-qla2xxx-fix-flash-read-for-qlogic-isps.patch
+scsi-qla2xxx-fix-driver-reload-for-isp82xx.patch
+scsi-qla2xxx-fix-stuck-login-session.patch
+scsi-qla2xxx-fix-stale-session.patch
+scsi-qla2xxx-fix-srb-leak-on-switch-command-timeout.patch
+scsi-qla2xxx-fix-a-dma_pool_free-call.patch
+revert-scsi-qla2xxx-fix-memory-leak-when-sending-i-o.patch
+scsi-qla2xxx-fix-a-race-condition-between-aborting-a.patch
+scsi-qla2xxx-fix-double-scsi_done-for-abort-path.patch
+scsi-qla2xxx-introduce-the-function-qla2xxx_init_sp.patch
+iio-imu-st_lsm6dsx-move-odr_table-in-st_lsm6dsx_sens.patch
+iio-imu-st_lsm6dsx-fix-odr-check-in-st_lsm6dsx_write.patch
+iio-ad7949-kill-pointless-readback-handling-code.patch
+iio-ad7949-fix-channels-mixups.patch
+omap-pdata-quirks-revert-pandora-specific-gpiod-addi.patch
+omap-pdata-quirks-remove-openpandora-quirks-for-mmc3.patch