From: Sasha Levin Date: Sun, 15 Dec 2019 21:31:08 +0000 (-0500) Subject: fixes for 5.3 X-Git-Tag: v5.4.4~52 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eace7ad53fb7508d588cac1874ad51269f8f5ac7;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 5.3 Signed-off-by: Sasha Levin --- diff --git a/queue-5.3/iio-ad7949-fix-channels-mixups.patch b/queue-5.3/iio-ad7949-fix-channels-mixups.patch new file mode 100644 index 00000000000..6cec7ed0ae3 --- /dev/null +++ b/queue-5.3/iio-ad7949-fix-channels-mixups.patch @@ -0,0 +1,128 @@ +From 9bb8ee66ee34d9d91f0c902e267105e87b7ea98f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Dec 2019 15:13:36 +0100 +Subject: iio: ad7949: fix channels mixups + +From: Andrea Merello + +[ 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 +Reviewed-by: Charles-Antoine Couret +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/iio-ad7949-kill-pointless-readback-handling-code.patch b/queue-5.3/iio-ad7949-kill-pointless-readback-handling-code.patch new file mode 100644 index 00000000000..c37e20e5239 --- /dev/null +++ b/queue-5.3/iio-ad7949-kill-pointless-readback-handling-code.patch @@ -0,0 +1,91 @@ +From 7bef164608b7e2d5e1c87b0e4760748f25fbbeac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Sep 2019 16:43:07 +0200 +Subject: iio: ad7949: kill pointless "readback"-handling code + +From: Andrea Merello + +[ 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 +Reviewed-by: Alexandru Ardelean +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/iio-imu-st_lsm6dsx-fix-odr-check-in-st_lsm6dsx_write.patch b/queue-5.3/iio-imu-st_lsm6dsx-fix-odr-check-in-st_lsm6dsx_write.patch new file mode 100644 index 00000000000..63f3e742f40 --- /dev/null +++ b/queue-5.3/iio-imu-st_lsm6dsx-fix-odr-check-in-st_lsm6dsx_write.patch @@ -0,0 +1,54 @@ +From 2d2dd0ac065c401b9b6bf058d8c49130a6fbcd53 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/iio-imu-st_lsm6dsx-move-odr_table-in-st_lsm6dsx_sens.patch b/queue-5.3/iio-imu-st_lsm6dsx-move-odr_table-in-st_lsm6dsx_sens.patch new file mode 100644 index 00000000000..e29eebc0cd0 --- /dev/null +++ b/queue-5.3/iio-imu-st_lsm6dsx-move-odr_table-in-st_lsm6dsx_sens.patch @@ -0,0 +1,338 @@ +From bc8ce90aee89ca119f231643f578faf5b286b5c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/omap-pdata-quirks-remove-openpandora-quirks-for-mmc3.patch b/queue-5.3/omap-pdata-quirks-remove-openpandora-quirks-for-mmc3.patch new file mode 100644 index 00000000000..24902026227 --- /dev/null +++ b/queue-5.3/omap-pdata-quirks-remove-openpandora-quirks-for-mmc3.patch @@ -0,0 +1,142 @@ +From d4c14cea829fd910d874cf074bb4d65612a1801d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Nov 2019 11:30:39 +0100 +Subject: omap: pdata-quirks: remove openpandora quirks for mmc3 and wl1251 + +From: H. Nikolaus Schaller + +[ 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 +Cc: # v4.7+ +Acked-by: Tony Lindgren +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/omap-pdata-quirks-revert-pandora-specific-gpiod-addi.patch b/queue-5.3/omap-pdata-quirks-revert-pandora-specific-gpiod-addi.patch new file mode 100644 index 00000000000..0ea7bc8ba0e --- /dev/null +++ b/queue-5.3/omap-pdata-quirks-revert-pandora-specific-gpiod-addi.patch @@ -0,0 +1,90 @@ +From 81aafb0a9a4a01352ec778fc57856161c21915f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Nov 2019 11:30:38 +0100 +Subject: omap: pdata-quirks: revert pandora specific gpiod additions + +From: H. Nikolaus Schaller + +[ 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 +Acked-by: Tony Lindgren +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + 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 + #include + #include +-#include + #include + #include + #include +@@ -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 + diff --git a/queue-5.3/revert-scsi-qla2xxx-fix-memory-leak-when-sending-i-o.patch b/queue-5.3/revert-scsi-qla2xxx-fix-memory-leak-when-sending-i-o.patch new file mode 100644 index 00000000000..bf567dcbfe6 --- /dev/null +++ b/queue-5.3/revert-scsi-qla2xxx-fix-memory-leak-when-sending-i-o.patch @@ -0,0 +1,48 @@ +From cb05df091da84826c46b437bafd6b4569d67a15a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-lpfc-fix-bad-ndlp-ptr-in-xri-aborted-handling.patch b/queue-5.3/scsi-lpfc-fix-bad-ndlp-ptr-in-xri-aborted-handling.patch new file mode 100644 index 00000000000..57e688c4915 --- /dev/null +++ b/queue-5.3/scsi-lpfc-fix-bad-ndlp-ptr-in-xri-aborted-handling.patch @@ -0,0 +1,129 @@ +From 3e9594269f59db8caaf5f8df2a882e15f95db0a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Oct 2019 14:18:21 -0700 +Subject: scsi: lpfc: Fix bad ndlp ptr in xri aborted handling + +From: James Smart + +[ 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: # v5.1+ +Link: https://lore.kernel.org/r/20191018211832.7917-6-jsmart2021@gmail.com +Signed-off-by: Dick Kennedy +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-always-check-the-qla2x00_wait_for_hba_o.patch b/queue-5.3/scsi-qla2xxx-always-check-the-qla2x00_wait_for_hba_o.patch new file mode 100644 index 00000000000..c013b100311 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-always-check-the-qla2x00_wait_for_hba_o.patch @@ -0,0 +1,66 @@ +From 90903cabb597d4127cf731e624c414d19cdef64e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ Upstream commit e6803efae5acd109fad9f2f07dab674563441a53 ] + +This patch fixes several Coverity complaints about not always checking +the qla2x00_wait_for_hba_online() return value. + +Cc: Himanshu Madhani +Signed-off-by: Bart Van Assche +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-check-secondary-image-if-reading-the-pr.patch b/queue-5.3/scsi-qla2xxx-check-secondary-image-if-reading-the-pr.patch new file mode 100644 index 00000000000..4ef62d43e3d --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-check-secondary-image-if-reading-the-pr.patch @@ -0,0 +1,45 @@ +From b9911dcb6406b24cd8a533b4a12ea565fa1428d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ Upstream commit 0597fe601a3a7d103c35b922046251906e0349b3 ] + +This patch fixes several Coverity complaints about reading data that has +not been initialized. + +Cc: Himanshu Madhani +Signed-off-by: Bart Van Assche +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-do-command-completion-on-abort-timeout.patch b/queue-5.3/scsi-qla2xxx-do-command-completion-on-abort-timeout.patch new file mode 100644 index 00000000000..2abbdf9113e --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-do-command-completion-on-abort-timeout.patch @@ -0,0 +1,86 @@ +From f8341a13e516cacae8c45f09d0f9f3afa834b217 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2019 07:06:51 -0800 +Subject: scsi: qla2xxx: Do command completion on abort timeout + +From: Quinn Tran + +[ 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 +Signed-off-by: Quinn Tran +Signed-off-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-a-dma_pool_free-call.patch b/queue-5.3/scsi-qla2xxx-fix-a-dma_pool_free-call.patch new file mode 100644 index 00000000000..34b0ff0d16b --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-a-dma_pool_free-call.patch @@ -0,0 +1,62 @@ +From 5f24bf00b8280e18c0da9c947c2061600be9ba66 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2019 20:42:26 -0800 +Subject: scsi: qla2xxx: Fix a dma_pool_free() call + +From: Bart Van Assche + +[ 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 +Cc: Himanshu Madhani +Link: https://lore.kernel.org/r/20191106044226.5207-3-bvanassche@acm.org +Reviewed-by: Martin Wilck +Acked-by: Himanshu Madhani +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-a-race-condition-between-aborting-a.patch b/queue-5.3/scsi-qla2xxx-fix-a-race-condition-between-aborting-a.patch new file mode 100644 index 00000000000..d402b5d5e9a --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-a-race-condition-between-aborting-a.patch @@ -0,0 +1,159 @@ +From 7d59d5cd13bbe64d3bdb42c797224fecd48980e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Bart Van Assche +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-abort-timeout-race-condition.patch b/queue-5.3/scsi-qla2xxx-fix-abort-timeout-race-condition.patch new file mode 100644 index 00000000000..d5f932b80c3 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-abort-timeout-race-condition.patch @@ -0,0 +1,77 @@ +From c573fe6f462f04aef3ac24932272e2682bafedbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jul 2019 09:07:28 -0700 +Subject: scsi: qla2xxx: Fix abort timeout race condition. + +From: Quinn Tran + +[ 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 +Signed-off-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-different-size-dma-alloc-unmap.patch b/queue-5.3/scsi-qla2xxx-fix-different-size-dma-alloc-unmap.patch new file mode 100644 index 00000000000..0936c79bb4b --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-different-size-dma-alloc-unmap.patch @@ -0,0 +1,45 @@ +From ef8bb7c2632a5cae888509217fa10517a4376b55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jul 2019 09:07:27 -0700 +Subject: scsi: qla2xxx: Fix different size DMA Alloc/Unmap + +From: Quinn Tran + +[ 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 +Signed-off-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-dma-unmap-leak.patch b/queue-5.3/scsi-qla2xxx-fix-dma-unmap-leak.patch new file mode 100644 index 00000000000..1ac6d82ea55 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-dma-unmap-leak.patch @@ -0,0 +1,54 @@ +From e0c1bf1f50b0393eb02d7bd3c47953c7afc35151 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jul 2019 09:07:26 -0700 +Subject: scsi: qla2xxx: Fix DMA unmap leak + +From: Himanshu Madhani + +[ 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 +Signed-off-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-double-scsi_done-for-abort-path.patch b/queue-5.3/scsi-qla2xxx-fix-double-scsi_done-for-abort-path.patch new file mode 100644 index 00000000000..6eefce4e957 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-double-scsi_done-for-abort-path.patch @@ -0,0 +1,334 @@ +From a5576d5dd17ee2945b2ca533b2d8714c3d322c24 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2019 07:06:54 -0800 +Subject: scsi: qla2xxx: Fix double scsi_done for abort path + +From: Quinn Tran + +[ 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 +Signed-off-by: Quinn Tran +Signed-off-by: Arun Easi +Signed-off-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-driver-reload-for-isp82xx.patch b/queue-5.3/scsi-qla2xxx-fix-driver-reload-for-isp82xx.patch new file mode 100644 index 00000000000..04b81b281c2 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-driver-reload-for-isp82xx.patch @@ -0,0 +1,68 @@ +From 0d181c091ec5a53594b1107e7ba059908ae864e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Aug 2019 15:23:59 -0700 +Subject: scsi: qla2xxx: Fix driver reload for ISP82xx + +From: Himanshu Madhani + +[ 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 +Signed-off-by: Himanshu Madhani +Reviewed-by: Ewan D. Milne +Link: https://lore.kernel.org/r/20190830222402.23688-4-hmadhani@marvell.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-flash-read-for-qlogic-isps.patch b/queue-5.3/scsi-qla2xxx-fix-flash-read-for-qlogic-isps.patch new file mode 100644 index 00000000000..4407e4ffd72 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-flash-read-for-qlogic-isps.patch @@ -0,0 +1,90 @@ +From 22942573995c8e4c06eddbc2a5fbad951eade712 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Aug 2019 15:23:58 -0700 +Subject: scsi: qla2xxx: Fix flash read for Qlogic ISPs + +From: Quinn Tran + +[ Upstream commit cb92cb1657c438efe7c88c9759f40c0a9d46c353 ] + +Use adapter specific callback to read flash instead of ISP adapter +specific. + +Signed-off-by: Quinn Tran +Signed-off-by: Himanshu Madhani +Reviewed-by: Ewan D. Milne +Link: https://lore.kernel.org/r/20190830222402.23688-3-hmadhani@marvell.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-hang-in-fcport-delete-path.patch b/queue-5.3/scsi-qla2xxx-fix-hang-in-fcport-delete-path.patch new file mode 100644 index 00000000000..d8c681a5635 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-hang-in-fcport-delete-path.patch @@ -0,0 +1,50 @@ +From 1858b07b3131e3d7d3f2e15ad3604af8bbdb4766 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jul 2019 09:07:38 -0700 +Subject: scsi: qla2xxx: Fix hang in fcport delete path + +From: Quinn Tran + +[ 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 +Signed-off-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-message-indicating-vectors-used-by-.patch b/queue-5.3/scsi-qla2xxx-fix-message-indicating-vectors-used-by-.patch new file mode 100644 index 00000000000..3e4b45f2674 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-message-indicating-vectors-used-by-.patch @@ -0,0 +1,46 @@ +From 4fa0b08b234fb80f9ec35bf2af61486ec70433f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Aug 2019 15:23:57 -0700 +Subject: scsi: qla2xxx: Fix message indicating vectors used by driver + +From: Himanshu Madhani + +[ 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 +Reviewed-by: Ewan D. Milne +Reviewed-by: Lee Duncan +Link: https://lore.kernel.org/r/20190830222402.23688-2-hmadhani@marvell.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-nvme-port-discovery-after-a-short-d.patch b/queue-5.3/scsi-qla2xxx-fix-nvme-port-discovery-after-a-short-d.patch new file mode 100644 index 00000000000..58c700acda3 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-nvme-port-discovery-after-a-short-d.patch @@ -0,0 +1,62 @@ +From 2333e57d3a8eb9b0ad33da6094360c8b8d8b537d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-premature-timer-expiration.patch b/queue-5.3/scsi-qla2xxx-fix-premature-timer-expiration.patch new file mode 100644 index 00000000000..f17565f5b6e --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-premature-timer-expiration.patch @@ -0,0 +1,116 @@ +From f96bc1d59f77081ce35b4b74e0b8575ff919d382 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jul 2019 09:07:33 -0700 +Subject: scsi: qla2xxx: Fix premature timer expiration + +From: Quinn Tran + +[ 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 +Signed-off-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-qla24xx_process_bidir_cmd.patch b/queue-5.3/scsi-qla2xxx-fix-qla24xx_process_bidir_cmd.patch new file mode 100644 index 00000000000..2a32294c56e --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-qla24xx_process_bidir_cmd.patch @@ -0,0 +1,70 @@ +From 59dc44002b0b140345a433dbe289a945c1df6cd9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Aug 2019 20:01:48 -0700 +Subject: scsi: qla2xxx: Fix qla24xx_process_bidir_cmd() + +From: Bart Van Assche + +[ 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 +Fixes: a9b6f722f62d ("[SCSI] qla2xxx: Implementation of bidirectional.") # v3.7. +Signed-off-by: Bart Van Assche +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-session-lookup-in-qlt_abort_work.patch b/queue-5.3/scsi-qla2xxx-fix-session-lookup-in-qlt_abort_work.patch new file mode 100644 index 00000000000..d9f27112b01 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-session-lookup-in-qlt_abort_work.patch @@ -0,0 +1,48 @@ +From 32b7b4fefa5192ddca1bc48019a0b65aeecc1e08 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Aug 2019 20:01:40 -0700 +Subject: scsi: qla2xxx: Fix session lookup in qlt_abort_work() + +From: Bart Van Assche + +[ Upstream commit ac452b8e79320c9e90c78edf32ba2d42431e4daf ] + +Pass the correct session ID to find_sess_by_s_id() instead of passing an +uninitialized variable. + +Cc: Himanshu Madhani +Fixes: 2d70c103fd2a ("[SCSI] qla2xxx: Add LLD target-mode infrastructure for >= 24xx series") # v3.5. +Signed-off-by: Bart Van Assche +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-srb-leak-on-switch-command-timeout.patch b/queue-5.3/scsi-qla2xxx-fix-srb-leak-on-switch-command-timeout.patch new file mode 100644 index 00000000000..bf41d9dbfbd --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-srb-leak-on-switch-command-timeout.patch @@ -0,0 +1,161 @@ +From 1841b2421dede6356fef142928dd45b55b0d9569 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2019 07:06:52 -0800 +Subject: scsi: qla2xxx: Fix SRB leak on switch command timeout + +From: Quinn Tran + +[ 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 +Signed-off-by: Quinn Tran +Signed-off-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-stale-session.patch b/queue-5.3/scsi-qla2xxx-fix-stale-session.patch new file mode 100644 index 00000000000..db45a6f3a56 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-stale-session.patch @@ -0,0 +1,53 @@ +From 7e8e47ae99a11a17052394d33afb23c63536b96f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Aug 2019 15:24:01 -0700 +Subject: scsi: qla2xxx: Fix stale session + +From: Quinn Tran + +[ 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 +Signed-off-by: Himanshu Madhani +Reviewed-by: Ewan D. Milne +Link: https://lore.kernel.org/r/20190830222402.23688-6-hmadhani@marvell.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-fix-stuck-login-session.patch b/queue-5.3/scsi-qla2xxx-fix-stuck-login-session.patch new file mode 100644 index 00000000000..ce8fcb63b9c --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-stuck-login-session.patch @@ -0,0 +1,82 @@ +From c05458c54b67750cce5a1681a80badcd7a0ea456 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Aug 2019 15:24:00 -0700 +Subject: scsi: qla2xxx: Fix stuck login session + +From: Quinn Tran + +[ 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 +Signed-off-by: Himanshu Madhani +Reviewed-by: Ewan D. Milne +Link: https://lore.kernel.org/r/20190830222402.23688-5-hmadhani@marvell.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-introduce-the-function-qla2xxx_init_sp.patch b/queue-5.3/scsi-qla2xxx-introduce-the-function-qla2xxx_init_sp.patch new file mode 100644 index 00000000000..1c774badf31 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-introduce-the-function-qla2xxx_init_sp.patch @@ -0,0 +1,71 @@ +From ab07e6286e3031800933fe884f15e8ebb3c6b96d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Aug 2019 20:02:05 -0700 +Subject: scsi: qla2xxx: Introduce the function qla2xxx_init_sp() + +From: Bart Van Assche + +[ Upstream commit bdb61b9b944d1e5b7cee5a9fe21014363c55b811 ] + +This patch does not change any functionality but makes the next patch +easier to read. + +Cc: Himanshu Madhani +Signed-off-by: Bart Van Assche +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-make-qla2x00_abort_srb-again-decrease-t.patch b/queue-5.3/scsi-qla2xxx-make-qla2x00_abort_srb-again-decrease-t.patch new file mode 100644 index 00000000000..972f61c73a7 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-make-qla2x00_abort_srb-again-decrease-t.patch @@ -0,0 +1,40 @@ +From 53311a02d93324531726b06da226b197118907f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Fixes: 219d27d7147e ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands") # v5.2. +Signed-off-by: Bart Van Assche +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-make-sure-that-aborted-commands-are-fre.patch b/queue-5.3/scsi-qla2xxx-make-sure-that-aborted-commands-are-fre.patch new file mode 100644 index 00000000000..f0368b5f47f --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-make-sure-that-aborted-commands-are-fre.patch @@ -0,0 +1,113 @@ +From 8669e8f7bb2f610750abb9c93afe45c03f541bf7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Aug 2019 20:02:10 -0700 +Subject: scsi: qla2xxx: Make sure that aborted commands are freed + +From: Bart Van Assche + +[ 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 +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 +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-qla2x00_alloc_fw_dump-set-ha-eft.patch b/queue-5.3/scsi-qla2xxx-qla2x00_alloc_fw_dump-set-ha-eft.patch new file mode 100644 index 00000000000..1d901dfa338 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-qla2x00_alloc_fw_dump-set-ha-eft.patch @@ -0,0 +1,44 @@ +From 47e546eec181c57c79168615f1fbe1258b33d64d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Aug 2019 13:28:27 +0000 +Subject: scsi: qla2xxx: qla2x00_alloc_fw_dump: set ha->eft + +From: Martin Wilck + +[ 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 +Cc: Quinn Tran +Cc: Himanshu Madhani +Cc: Bart Van Assche +Signed-off-by: Martin Wilck +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/scsi-qla2xxx-really-fix-qla2xxx_eh_abort.patch b/queue-5.3/scsi-qla2xxx-really-fix-qla2xxx_eh_abort.patch new file mode 100644 index 00000000000..f8f7457ca92 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-really-fix-qla2xxx_eh_abort.patch @@ -0,0 +1,88 @@ +From 8c8154cfcdc609f7b7d604198e333e408601ae63 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Aug 2019 20:01:23 -0700 +Subject: scsi: qla2xxx: Really fix qla2xxx_eh_abort() + +From: Bart Van Assche + +[ 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 +Fixes: 219d27d7147e ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands") +Signed-off-by: Bart Van Assche +Tested-by: Himanshu Madhani +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.3/series b/queue-5.3/series index 0474ce15b13..593a0204c04 100644 --- a/queue-5.3/series +++ b/queue-5.3/series @@ -134,3 +134,36 @@ seccomp-avoid-overflow-in-implicit-constant-conversion.patch 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