]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 19 Jan 2020 13:49:00 +0000 (14:49 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 19 Jan 2020 13:49:00 +0000 (14:49 +0100)
added patches:
iio-adc-ad7124-fix-dt-channel-configuration.patch
iio-buffer-align-the-size-of-scan-bytes-to-size-of-the-largest-element.patch
iio-chemical-pms7003-fix-unmet-triggered-buffer-dependency.patch
iio-imu-st_lsm6dsx-fix-selection-of-st_lsm6ds3_id.patch
iio-light-vcnl4000-fix-scale-for-vcnl4040.patch
perf-correctly-handle-failed-perf_get_aux_event.patch
scsi-fnic-fix-invalid-stack-access.patch
scsi-mptfusion-fix-double-fetch-bug-in-ioctl.patch
staging-comedi-ni_routes-allow-partial-routing-information.patch
staging-comedi-ni_routes-fix-null-dereference-in-ni_find_route_source.patch
usb-serial-ch341-handle-unbound-port-at-reset_resume.patch
usb-serial-io_edgeport-add-missing-active-port-sanity-check.patch
usb-serial-io_edgeport-handle-unbound-ports-on-urb-completion.patch
usb-serial-keyspan-handle-unbound-ports.patch
usb-serial-opticon-fix-control-message-timeouts.patch
usb-serial-option-add-support-for-quectel-rm500q-in-qdl-mode.patch
usb-serial-option-add-support-for-quectel-rm500q.patch
usb-serial-quatech2-handle-unbound-ports.patch
usb-serial-simple-add-motorola-solutions-tetra-mtp3xxx-and-mtp85xx.patch
usb-serial-suppress-driver-bind-attributes.patch

21 files changed:
queue-5.4/iio-adc-ad7124-fix-dt-channel-configuration.patch [new file with mode: 0644]
queue-5.4/iio-buffer-align-the-size-of-scan-bytes-to-size-of-the-largest-element.patch [new file with mode: 0644]
queue-5.4/iio-chemical-pms7003-fix-unmet-triggered-buffer-dependency.patch [new file with mode: 0644]
queue-5.4/iio-imu-st_lsm6dsx-fix-selection-of-st_lsm6ds3_id.patch [new file with mode: 0644]
queue-5.4/iio-light-vcnl4000-fix-scale-for-vcnl4040.patch [new file with mode: 0644]
queue-5.4/perf-correctly-handle-failed-perf_get_aux_event.patch [new file with mode: 0644]
queue-5.4/scsi-fnic-fix-invalid-stack-access.patch [new file with mode: 0644]
queue-5.4/scsi-mptfusion-fix-double-fetch-bug-in-ioctl.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/staging-comedi-ni_routes-allow-partial-routing-information.patch [new file with mode: 0644]
queue-5.4/staging-comedi-ni_routes-fix-null-dereference-in-ni_find_route_source.patch [new file with mode: 0644]
queue-5.4/usb-serial-ch341-handle-unbound-port-at-reset_resume.patch [new file with mode: 0644]
queue-5.4/usb-serial-io_edgeport-add-missing-active-port-sanity-check.patch [new file with mode: 0644]
queue-5.4/usb-serial-io_edgeport-handle-unbound-ports-on-urb-completion.patch [new file with mode: 0644]
queue-5.4/usb-serial-keyspan-handle-unbound-ports.patch [new file with mode: 0644]
queue-5.4/usb-serial-opticon-fix-control-message-timeouts.patch [new file with mode: 0644]
queue-5.4/usb-serial-option-add-support-for-quectel-rm500q-in-qdl-mode.patch [new file with mode: 0644]
queue-5.4/usb-serial-option-add-support-for-quectel-rm500q.patch [new file with mode: 0644]
queue-5.4/usb-serial-quatech2-handle-unbound-ports.patch [new file with mode: 0644]
queue-5.4/usb-serial-simple-add-motorola-solutions-tetra-mtp3xxx-and-mtp85xx.patch [new file with mode: 0644]
queue-5.4/usb-serial-suppress-driver-bind-attributes.patch [new file with mode: 0644]

diff --git a/queue-5.4/iio-adc-ad7124-fix-dt-channel-configuration.patch b/queue-5.4/iio-adc-ad7124-fix-dt-channel-configuration.patch
new file mode 100644 (file)
index 0000000..28b60bd
--- /dev/null
@@ -0,0 +1,68 @@
+From d7857e4ee1ba69732b16c73b2f2dde83ecd78ee4 Mon Sep 17 00:00:00 2001
+From: Alexandru Tachici <alexandru.tachici@analog.com>
+Date: Fri, 20 Dec 2019 12:07:19 +0200
+Subject: iio: adc: ad7124: Fix DT channel configuration
+
+From: Alexandru Tachici <alexandru.tachici@analog.com>
+
+commit d7857e4ee1ba69732b16c73b2f2dde83ecd78ee4 upstream.
+
+This patch fixes device tree channel configuration.
+
+ad7124 driver reads channels configuration from the device tree.
+It expects to find channel specifications as child nodes.
+Before this patch ad7124 driver assumed that the child nodes are parsed
+by for_each_available_child_of_node in the order 0,1,2,3...
+
+This is wrong and the real order of the children can be seen by running:
+dtc -I fs /sys/firmware/devicetree/base on the machine.
+
+For example, running this on an rpi 3B+ yields the real
+children order: 4,2,0,7,5,3,1,6
+
+Before this patch the driver assigned the channel configuration
+like this:
+        - 0 <- 4
+        - 1 <- 2
+        - 2 <- 0
+        ........
+For example, the symptoms can be observed by connecting the 4th channel
+to a 1V tension and then reading the in_voltage0-voltage19_raw sysfs
+(multiplied of course by the scale) one would see that channel 0
+measures 1V and channel 4 measures only noise.
+
+Now the driver uses the reg property of each child in order to
+correctly identify to which channel the parsed configuration
+belongs to.
+
+Fixes b3af341bbd966: ("iio: adc: Add ad7124 support")
+Signed-off-by: Alexandru Tachici <alexandru.tachici@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/ad7124.c |   12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+--- a/drivers/iio/adc/ad7124.c
++++ b/drivers/iio/adc/ad7124.c
+@@ -494,13 +494,11 @@ static int ad7124_of_parse_channel_confi
+               st->channel_config[channel].buf_negative =
+                       of_property_read_bool(child, "adi,buffered-negative");
+-              *chan = ad7124_channel_template;
+-              chan->address = channel;
+-              chan->scan_index = channel;
+-              chan->channel = ain[0];
+-              chan->channel2 = ain[1];
+-
+-              chan++;
++              chan[channel] = ad7124_channel_template;
++              chan[channel].address = channel;
++              chan[channel].scan_index = channel;
++              chan[channel].channel = ain[0];
++              chan[channel].channel2 = ain[1];
+       }
+       return 0;
diff --git a/queue-5.4/iio-buffer-align-the-size-of-scan-bytes-to-size-of-the-largest-element.patch b/queue-5.4/iio-buffer-align-the-size-of-scan-bytes-to-size-of-the-largest-element.patch
new file mode 100644 (file)
index 0000000..2820fc7
--- /dev/null
@@ -0,0 +1,61 @@
+From 883f616530692d81cb70f8a32d85c0d2afc05f69 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= <lars.moellendorf@plating.de>
+Date: Fri, 13 Dec 2019 14:50:55 +0100
+Subject: iio: buffer: align the size of scan bytes to size of the largest element
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lars Möllendorf <lars.moellendorf@plating.de>
+
+commit 883f616530692d81cb70f8a32d85c0d2afc05f69 upstream.
+
+Previous versions of `iio_compute_scan_bytes` only aligned each element
+to its own length (i.e. its own natural alignment). Because multiple
+consecutive sets of scan elements are buffered this does not work in
+case the computed scan bytes do not align with the natural alignment of
+the first scan element in the set.
+
+This commit fixes this by aligning the scan bytes to the natural
+alignment of the largest scan element in the set.
+
+Fixes: 959d2952d124 ("staging:iio: make iio_sw_buffer_preenable much more general.")
+Signed-off-by: Lars Möllendorf <lars.moellendorf@plating.de>
+Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/industrialio-buffer.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/industrialio-buffer.c
++++ b/drivers/iio/industrialio-buffer.c
+@@ -566,7 +566,7 @@ static int iio_compute_scan_bytes(struct
+                               const unsigned long *mask, bool timestamp)
+ {
+       unsigned bytes = 0;
+-      int length, i;
++      int length, i, largest = 0;
+       /* How much space will the demuxed element take? */
+       for_each_set_bit(i, mask,
+@@ -574,13 +574,17 @@ static int iio_compute_scan_bytes(struct
+               length = iio_storage_bytes_for_si(indio_dev, i);
+               bytes = ALIGN(bytes, length);
+               bytes += length;
++              largest = max(largest, length);
+       }
+       if (timestamp) {
+               length = iio_storage_bytes_for_timestamp(indio_dev);
+               bytes = ALIGN(bytes, length);
+               bytes += length;
++              largest = max(largest, length);
+       }
++
++      bytes = ALIGN(bytes, largest);
+       return bytes;
+ }
diff --git a/queue-5.4/iio-chemical-pms7003-fix-unmet-triggered-buffer-dependency.patch b/queue-5.4/iio-chemical-pms7003-fix-unmet-triggered-buffer-dependency.patch
new file mode 100644 (file)
index 0000000..6cd2942
--- /dev/null
@@ -0,0 +1,37 @@
+From 217afe63ccf445fc220e5ef480683607b05c0aa5 Mon Sep 17 00:00:00 2001
+From: Tomasz Duszynski <tduszyns@gmail.com>
+Date: Fri, 13 Dec 2019 22:38:08 +0100
+Subject: iio: chemical: pms7003: fix unmet triggered buffer dependency
+
+From: Tomasz Duszynski <tduszyns@gmail.com>
+
+commit 217afe63ccf445fc220e5ef480683607b05c0aa5 upstream.
+
+IIO triggered buffer depends on IIO buffer which is missing from Kconfig
+file. This should go unnoticed most of the time because there's a
+chance something else has already enabled buffers. In some rare cases
+though one might experience kbuild warnings about unmet direct
+dependencies and build failures due to missing symbols.
+
+Fix this by selecting IIO_BUFFER explicitly.
+
+Signed-off-by: Tomasz Duszynski <tduszyns@gmail.com>
+Fixes: a1d642266c14 ("iio: chemical: add support for Plantower PMS7003 sensor")
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/chemical/Kconfig |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/iio/chemical/Kconfig
++++ b/drivers/iio/chemical/Kconfig
+@@ -65,6 +65,7 @@ config IAQCORE
+ config PMS7003
+       tristate "Plantower PMS7003 particulate matter sensor"
+       depends on SERIAL_DEV_BUS
++      select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
+       help
+         Say Y here to build support for the Plantower PMS7003 particulate
diff --git a/queue-5.4/iio-imu-st_lsm6dsx-fix-selection-of-st_lsm6ds3_id.patch b/queue-5.4/iio-imu-st_lsm6dsx-fix-selection-of-st_lsm6ds3_id.patch
new file mode 100644 (file)
index 0000000..c3acbb3
--- /dev/null
@@ -0,0 +1,52 @@
+From fb4fbc8904e786537e29329d791147389e1465a2 Mon Sep 17 00:00:00 2001
+From: Stephan Gerhold <stephan@gerhold.net>
+Date: Mon, 16 Dec 2019 13:41:20 +0100
+Subject: iio: imu: st_lsm6dsx: Fix selection of ST_LSM6DS3_ID
+
+From: Stephan Gerhold <stephan@gerhold.net>
+
+commit fb4fbc8904e786537e29329d791147389e1465a2 upstream.
+
+At the moment, attempting to probe a device with ST_LSM6DS3_ID
+(e.g. using the st,lsm6ds3 compatible) fails with:
+
+    st_lsm6dsx_i2c 1-006b: unsupported whoami [69]
+
+... even though 0x69 is the whoami listed for ST_LSM6DS3_ID.
+
+This happens because st_lsm6dsx_check_whoami() also attempts
+to match unspecified (zero-initialized) entries in the "id" array.
+ST_LSM6DS3_ID = 0 will therefore match any entry in
+st_lsm6dsx_sensor_settings (here: the first), because none of them
+actually have all 12 entries listed in the "id" array.
+
+Avoid this by additionally checking if "name" is set,
+which is only set for valid entries in the "id" array.
+
+Note: Although the problem was introduced earlier it did not surface until
+commit 52f4b1f19679 ("iio: imu: st_lsm6dsx: add support for accel/gyro unit of lsm9ds1")
+because ST_LSM6DS3_ID was the first entry in st_lsm6dsx_sensor_settings.
+
+Fixes: d068e4a0f921 ("iio: imu: st_lsm6dsx: add support to multiple devices with the same settings")
+Cc: <stable@vger.kernel.org> # 5.4
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+@@ -911,7 +911,8 @@ static int st_lsm6dsx_check_whoami(struc
+       for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
+               for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
+-                      if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
++                      if (st_lsm6dsx_sensor_settings[i].id[j].name &&
++                          id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
+                               break;
+               }
+               if (j < ST_LSM6DSX_MAX_ID)
diff --git a/queue-5.4/iio-light-vcnl4000-fix-scale-for-vcnl4040.patch b/queue-5.4/iio-light-vcnl4000-fix-scale-for-vcnl4040.patch
new file mode 100644 (file)
index 0000000..6473eb4
--- /dev/null
@@ -0,0 +1,54 @@
+From bc80573ea25bb033a58da81b3ce27205b97c088e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Guido=20G=C3=BCnther?= <agx@sigxcpu.org>
+Date: Fri, 27 Dec 2019 11:22:54 +0100
+Subject: iio: light: vcnl4000: Fix scale for vcnl4040
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Guido Günther <agx@sigxcpu.org>
+
+commit bc80573ea25bb033a58da81b3ce27205b97c088e upstream.
+
+According to the data sheet the ambient sensor's scale is 0.12 lux/step
+(not 0.024 lux/step as used by vcnl4200) when the integration time is
+80ms. The integration time is currently hardcoded in the driver to that
+value.
+
+See p. 8 in https://www.vishay.com/docs/84307/designingvcnl4040.pdf
+
+Fixes: 5a441aade5b3 ("iio: light: vcnl4000 add support for the VCNL4040 proximity and light sensor")
+Signed-off-by: Guido Günther <agx@sigxcpu.org>
+Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/light/vcnl4000.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/light/vcnl4000.c
++++ b/drivers/iio/light/vcnl4000.c
+@@ -163,7 +163,6 @@ static int vcnl4200_init(struct vcnl4000
+       if (ret < 0)
+               return ret;
+-      data->al_scale = 24000;
+       data->vcnl4200_al.reg = VCNL4200_AL_DATA;
+       data->vcnl4200_ps.reg = VCNL4200_PS_DATA;
+       switch (id) {
+@@ -172,11 +171,13 @@ static int vcnl4200_init(struct vcnl4000
+               /* show 54ms in total. */
+               data->vcnl4200_al.sampling_rate = ktime_set(0, 54000 * 1000);
+               data->vcnl4200_ps.sampling_rate = ktime_set(0, 4200 * 1000);
++              data->al_scale = 24000;
+               break;
+       case VCNL4040_PROD_ID:
+               /* Integration time is 80ms, add 10ms. */
+               data->vcnl4200_al.sampling_rate = ktime_set(0, 100000 * 1000);
+               data->vcnl4200_ps.sampling_rate = ktime_set(0, 100000 * 1000);
++              data->al_scale = 120000;
+               break;
+       }
+       data->vcnl4200_al.last_measurement = ktime_set(0, 0);
diff --git a/queue-5.4/perf-correctly-handle-failed-perf_get_aux_event.patch b/queue-5.4/perf-correctly-handle-failed-perf_get_aux_event.patch
new file mode 100644 (file)
index 0000000..7cc3fe6
--- /dev/null
@@ -0,0 +1,61 @@
+From da9ec3d3dd0f1240a48920be063448a2242dbd90 Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Mon, 6 Jan 2020 12:03:39 +0000
+Subject: perf: Correctly handle failed perf_get_aux_event()
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit da9ec3d3dd0f1240a48920be063448a2242dbd90 upstream.
+
+Vince reports a worrying issue:
+
+| so I was tracking down some odd behavior in the perf_fuzzer which turns
+| out to be because perf_even_open() sometimes returns 0 (indicating a file
+| descriptor of 0) even though as far as I can tell stdin is still open.
+
+... and further the cause:
+
+| error is triggered if aux_sample_size has non-zero value.
+|
+| seems to be this line in kernel/events/core.c:
+|
+| if (perf_need_aux_event(event) && !perf_get_aux_event(event, group_leader))
+|                goto err_locked;
+|
+| (note, err is never set)
+
+This seems to be a thinko in commit:
+
+  ab43762ef010967e ("perf: Allow normal events to output AUX data")
+
+... and we should probably return -EINVAL here, as this should only
+happen when the new event is mis-configured or does not have a
+compatible aux_event group leader.
+
+Fixes: ab43762ef010967e ("perf: Allow normal events to output AUX data")
+Reported-by: Vince Weaver <vincent.weaver@maine.edu>
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Tested-by: Vince Weaver <vincent.weaver@maine.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/events/core.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -11182,8 +11182,10 @@ SYSCALL_DEFINE5(perf_event_open,
+               }
+       }
+-      if (event->attr.aux_output && !perf_get_aux_event(event, group_leader))
++      if (event->attr.aux_output && !perf_get_aux_event(event, group_leader)) {
++              err = -EINVAL;
+               goto err_locked;
++      }
+       /*
+        * Must be under the same ctx::mutex as perf_install_in_context(),
diff --git a/queue-5.4/scsi-fnic-fix-invalid-stack-access.patch b/queue-5.4/scsi-fnic-fix-invalid-stack-access.patch
new file mode 100644 (file)
index 0000000..1e4f191
--- /dev/null
@@ -0,0 +1,122 @@
+From 42ec15ceaea74b5f7a621fc6686cbf69ca66c4cf Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Tue, 7 Jan 2020 21:15:49 +0100
+Subject: scsi: fnic: fix invalid stack access
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 42ec15ceaea74b5f7a621fc6686cbf69ca66c4cf upstream.
+
+gcc -O3 warns that some local variables are not properly initialized:
+
+drivers/scsi/fnic/vnic_dev.c: In function 'fnic_dev_hang_notify':
+drivers/scsi/fnic/vnic_dev.c:511:16: error: 'a0' is used uninitialized in this function [-Werror=uninitialized]
+  vdev->args[0] = *a0;
+  ~~~~~~~~~~~~~~^~~~~
+drivers/scsi/fnic/vnic_dev.c:691:6: note: 'a0' was declared here
+  u64 a0, a1;
+      ^~
+drivers/scsi/fnic/vnic_dev.c:512:16: error: 'a1' is used uninitialized in this function [-Werror=uninitialized]
+  vdev->args[1] = *a1;
+  ~~~~~~~~~~~~~~^~~~~
+drivers/scsi/fnic/vnic_dev.c:691:10: note: 'a1' was declared here
+  u64 a0, a1;
+          ^~
+drivers/scsi/fnic/vnic_dev.c: In function 'fnic_dev_mac_addr':
+drivers/scsi/fnic/vnic_dev.c:512:16: error: 'a1' is used uninitialized in this function [-Werror=uninitialized]
+  vdev->args[1] = *a1;
+  ~~~~~~~~~~~~~~^~~~~
+drivers/scsi/fnic/vnic_dev.c:698:10: note: 'a1' was declared here
+  u64 a0, a1;
+          ^~
+
+Apparently the code relies on the local variables occupying adjacent memory
+locations in the same order, but this is of course not guaranteed.
+
+Use an array of two u64 variables where needed to make it work correctly.
+
+I suspect there is also an endianness bug here, but have not digged in deep
+enough to be sure.
+
+Fixes: 5df6d737dd4b ("[SCSI] fnic: Add new Cisco PCI-Express FCoE HBA")
+Fixes: mmtom ("init/Kconfig: enable -O3 for all arches")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20200107201602.4096790-1-arnd@arndb.de
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/fnic/vnic_dev.c |   20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/drivers/scsi/fnic/vnic_dev.c
++++ b/drivers/scsi/fnic/vnic_dev.c
+@@ -688,26 +688,26 @@ int vnic_dev_soft_reset_done(struct vnic
+ int vnic_dev_hang_notify(struct vnic_dev *vdev)
+ {
+-      u64 a0, a1;
++      u64 a0 = 0, a1 = 0;
+       int wait = 1000;
+       return vnic_dev_cmd(vdev, CMD_HANG_NOTIFY, &a0, &a1, wait);
+ }
+ int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
+ {
+-      u64 a0, a1;
++      u64 a[2] = {};
+       int wait = 1000;
+       int err, i;
+       for (i = 0; i < ETH_ALEN; i++)
+               mac_addr[i] = 0;
+-      err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
++      err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a[0], &a[1], wait);
+       if (err)
+               return err;
+       for (i = 0; i < ETH_ALEN; i++)
+-              mac_addr[i] = ((u8 *)&a0)[i];
++              mac_addr[i] = ((u8 *)&a)[i];
+       return 0;
+ }
+@@ -732,30 +732,30 @@ void vnic_dev_packet_filter(struct vnic_
+ void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
+ {
+-      u64 a0 = 0, a1 = 0;
++      u64 a[2] = {};
+       int wait = 1000;
+       int err;
+       int i;
+       for (i = 0; i < ETH_ALEN; i++)
+-              ((u8 *)&a0)[i] = addr[i];
++              ((u8 *)&a)[i] = addr[i];
+-      err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
++      err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a[0], &a[1], wait);
+       if (err)
+               pr_err("Can't add addr [%pM], %d\n", addr, err);
+ }
+ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
+ {
+-      u64 a0 = 0, a1 = 0;
++      u64 a[2] = {};
+       int wait = 1000;
+       int err;
+       int i;
+       for (i = 0; i < ETH_ALEN; i++)
+-              ((u8 *)&a0)[i] = addr[i];
++              ((u8 *)&a)[i] = addr[i];
+-      err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait);
++      err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a[0], &a[1], wait);
+       if (err)
+               pr_err("Can't del addr [%pM], %d\n", addr, err);
+ }
diff --git a/queue-5.4/scsi-mptfusion-fix-double-fetch-bug-in-ioctl.patch b/queue-5.4/scsi-mptfusion-fix-double-fetch-bug-in-ioctl.patch
new file mode 100644 (file)
index 0000000..fd99e16
--- /dev/null
@@ -0,0 +1,577 @@
+From 28d76df18f0ad5bcf5fa48510b225f0ed262a99b Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Tue, 14 Jan 2020 15:34:14 +0300
+Subject: scsi: mptfusion: Fix double fetch bug in ioctl
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 28d76df18f0ad5bcf5fa48510b225f0ed262a99b upstream.
+
+Tom Hatskevich reported that we look up "iocp" then, in the called
+functions we do a second copy_from_user() and look it up again.
+The problem that could cause is:
+
+drivers/message/fusion/mptctl.c
+   674          /* All of these commands require an interrupt or
+   675           * are unknown/illegal.
+   676           */
+   677          if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
+                                               ^^^^
+We take this lock.
+
+   678                  return ret;
+   679
+   680          if (cmd == MPTFWDOWNLOAD)
+   681                  ret = mptctl_fw_download(arg);
+                                                 ^^^
+Then the user memory changes and we look up "iocp" again but a different
+one so now we are holding the incorrect lock and have a race condition.
+
+   682          else if (cmd == MPTCOMMAND)
+   683                  ret = mptctl_mpt_command(arg);
+
+The security impact of this bug is not as bad as it could have been
+because these operations are all privileged and root already has
+enormous destructive power.  But it's still worth fixing.
+
+This patch passes the "iocp" pointer to the functions to avoid the
+second lookup.  That deletes 100 lines of code from the driver so
+it's a nice clean up as well.
+
+Link: https://lore.kernel.org/r/20200114123414.GA7957@kadam
+Reported-by: Tom Hatskevich <tom2001tom.23@gmail.com>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/message/fusion/mptctl.c |  213 +++++++++-------------------------------
+ 1 file changed, 50 insertions(+), 163 deletions(-)
+
+--- a/drivers/message/fusion/mptctl.c
++++ b/drivers/message/fusion/mptctl.c
+@@ -100,19 +100,19 @@ struct buflist {
+  * Function prototypes. Called from OS entry point mptctl_ioctl.
+  * arg contents specific to function.
+  */
+-static int mptctl_fw_download(unsigned long arg);
+-static int mptctl_getiocinfo(unsigned long arg, unsigned int cmd);
+-static int mptctl_gettargetinfo(unsigned long arg);
+-static int mptctl_readtest(unsigned long arg);
+-static int mptctl_mpt_command(unsigned long arg);
+-static int mptctl_eventquery(unsigned long arg);
+-static int mptctl_eventenable(unsigned long arg);
+-static int mptctl_eventreport(unsigned long arg);
+-static int mptctl_replace_fw(unsigned long arg);
+-
+-static int mptctl_do_reset(unsigned long arg);
+-static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
+-static int mptctl_hp_targetinfo(unsigned long arg);
++static int mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg);
++static int mptctl_getiocinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
++static int mptctl_gettargetinfo(MPT_ADAPTER *iocp, unsigned long arg);
++static int mptctl_readtest(MPT_ADAPTER *iocp, unsigned long arg);
++static int mptctl_mpt_command(MPT_ADAPTER *iocp, unsigned long arg);
++static int mptctl_eventquery(MPT_ADAPTER *iocp, unsigned long arg);
++static int mptctl_eventenable(MPT_ADAPTER *iocp, unsigned long arg);
++static int mptctl_eventreport(MPT_ADAPTER *iocp, unsigned long arg);
++static int mptctl_replace_fw(MPT_ADAPTER *iocp, unsigned long arg);
++
++static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg);
++static int mptctl_hp_hostinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
++static int mptctl_hp_targetinfo(MPT_ADAPTER *iocp, unsigned long arg);
+ static int  mptctl_probe(struct pci_dev *, const struct pci_device_id *);
+ static void mptctl_remove(struct pci_dev *);
+@@ -123,8 +123,8 @@ static long compat_mpctl_ioctl(struct fi
+ /*
+  * Private function calls.
+  */
+-static int mptctl_do_mpt_command(struct mpt_ioctl_command karg, void __user *mfPtr);
+-static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
++static int mptctl_do_mpt_command(MPT_ADAPTER *iocp, struct mpt_ioctl_command karg, void __user *mfPtr);
++static int mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen);
+ static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags,
+               struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
+ static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
+@@ -656,19 +656,19 @@ __mptctl_ioctl(struct file *file, unsign
+        * by TM and FW reloads.
+        */
+       if ((cmd & ~IOCSIZE_MASK) == (MPTIOCINFO & ~IOCSIZE_MASK)) {
+-              return mptctl_getiocinfo(arg, _IOC_SIZE(cmd));
++              return mptctl_getiocinfo(iocp, arg, _IOC_SIZE(cmd));
+       } else if (cmd == MPTTARGETINFO) {
+-              return mptctl_gettargetinfo(arg);
++              return mptctl_gettargetinfo(iocp, arg);
+       } else if (cmd == MPTTEST) {
+-              return mptctl_readtest(arg);
++              return mptctl_readtest(iocp, arg);
+       } else if (cmd == MPTEVENTQUERY) {
+-              return mptctl_eventquery(arg);
++              return mptctl_eventquery(iocp, arg);
+       } else if (cmd == MPTEVENTENABLE) {
+-              return mptctl_eventenable(arg);
++              return mptctl_eventenable(iocp, arg);
+       } else if (cmd == MPTEVENTREPORT) {
+-              return mptctl_eventreport(arg);
++              return mptctl_eventreport(iocp, arg);
+       } else if (cmd == MPTFWREPLACE) {
+-              return mptctl_replace_fw(arg);
++              return mptctl_replace_fw(iocp, arg);
+       }
+       /* All of these commands require an interrupt or
+@@ -678,15 +678,15 @@ __mptctl_ioctl(struct file *file, unsign
+               return ret;
+       if (cmd == MPTFWDOWNLOAD)
+-              ret = mptctl_fw_download(arg);
++              ret = mptctl_fw_download(iocp, arg);
+       else if (cmd == MPTCOMMAND)
+-              ret = mptctl_mpt_command(arg);
++              ret = mptctl_mpt_command(iocp, arg);
+       else if (cmd == MPTHARDRESET)
+-              ret = mptctl_do_reset(arg);
++              ret = mptctl_do_reset(iocp, arg);
+       else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK))
+-              ret = mptctl_hp_hostinfo(arg, _IOC_SIZE(cmd));
++              ret = mptctl_hp_hostinfo(iocp, arg, _IOC_SIZE(cmd));
+       else if (cmd == HP_GETTARGETINFO)
+-              ret = mptctl_hp_targetinfo(arg);
++              ret = mptctl_hp_targetinfo(iocp, arg);
+       else
+               ret = -EINVAL;
+@@ -705,11 +705,10 @@ mptctl_ioctl(struct file *file, unsigned
+       return ret;
+ }
+-static int mptctl_do_reset(unsigned long arg)
++static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg)
+ {
+       struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
+       struct mpt_ioctl_diag_reset krinfo;
+-      MPT_ADAPTER             *iocp;
+       if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
+               printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - "
+@@ -718,12 +717,6 @@ static int mptctl_do_reset(unsigned long
+               return -EFAULT;
+       }
+-      if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) {
+-              printk(KERN_DEBUG MYNAM "%s@%d::mptctl_do_reset - ioc%d not found!\n",
+-                              __FILE__, __LINE__, krinfo.hdr.iocnum);
+-              return -ENODEV; /* (-6) No such device or address */
+-      }
+-
+       dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "mptctl_do_reset called.\n",
+           iocp->name));
+@@ -754,7 +747,7 @@ static int mptctl_do_reset(unsigned long
+  *            -ENOMSG if FW upload returned bad status
+  */
+ static int
+-mptctl_fw_download(unsigned long arg)
++mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg)
+ {
+       struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
+       struct mpt_fw_xfer       kfwdl;
+@@ -766,7 +759,7 @@ mptctl_fw_download(unsigned long arg)
+               return -EFAULT;
+       }
+-      return mptctl_do_fw_download(kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen);
++      return mptctl_do_fw_download(iocp, kfwdl.bufp, kfwdl.fwlen);
+ }
+ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+@@ -784,11 +777,10 @@ mptctl_fw_download(unsigned long arg)
+  *            -ENOMSG if FW upload returned bad status
+  */
+ static int
+-mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
++mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen)
+ {
+       FWDownload_t            *dlmsg;
+       MPT_FRAME_HDR           *mf;
+-      MPT_ADAPTER             *iocp;
+       FWDownloadTCSGE_t       *ptsge;
+       MptSge_t                *sgl, *sgIn;
+       char                    *sgOut;
+@@ -808,17 +800,10 @@ mptctl_do_fw_download(int ioc, char __us
+       pFWDownloadReply_t       ReplyMsg = NULL;
+       unsigned long            timeleft;
+-      if (mpt_verify_adapter(ioc, &iocp) < 0) {
+-              printk(KERN_DEBUG MYNAM "ioctl_fwdl - ioc%d not found!\n",
+-                               ioc);
+-              return -ENODEV; /* (-6) No such device or address */
+-      } else {
+-
+-              /*  Valid device. Get a message frame and construct the FW download message.
+-              */
+-              if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
+-                      return -EAGAIN;
+-      }
++      /*  Valid device. Get a message frame and construct the FW download message.
++      */
++      if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
++              return -EAGAIN;
+       dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT
+           "mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id));
+@@ -826,8 +811,6 @@ mptctl_do_fw_download(int ioc, char __us
+           iocp->name, ufwbuf));
+       dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n",
+           iocp->name, (int)fwlen));
+-      dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.ioc   = %04xh\n",
+-          iocp->name, ioc));
+       dlmsg = (FWDownload_t*) mf;
+       ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
+@@ -1238,13 +1221,11 @@ kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_
+  *            -ENODEV  if no such device/adapter
+  */
+ static int
+-mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
++mptctl_getiocinfo (MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
+ {
+       struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
+       struct mpt_ioctl_iocinfo *karg;
+-      MPT_ADAPTER             *ioc;
+       struct pci_dev          *pdev;
+-      int                     iocnum;
+       unsigned int            port;
+       int                     cim_rev;
+       struct scsi_device      *sdev;
+@@ -1272,14 +1253,6 @@ mptctl_getiocinfo (unsigned long arg, un
+               return PTR_ERR(karg);
+       }
+-      if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
+-          (ioc == NULL)) {
+-              printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
+-                              __FILE__, __LINE__, iocnum);
+-              kfree(karg);
+-              return -ENODEV;
+-      }
+-
+       /* Verify the data transfer size is correct. */
+       if (karg->hdr.maxDataSize != data_size) {
+               printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
+@@ -1385,15 +1358,13 @@ mptctl_getiocinfo (unsigned long arg, un
+  *            -ENODEV  if no such device/adapter
+  */
+ static int
+-mptctl_gettargetinfo (unsigned long arg)
++mptctl_gettargetinfo (MPT_ADAPTER *ioc, unsigned long arg)
+ {
+       struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
+       struct mpt_ioctl_targetinfo karg;
+-      MPT_ADAPTER             *ioc;
+       VirtDevice              *vdevice;
+       char                    *pmem;
+       int                     *pdata;
+-      int                     iocnum;
+       int                     numDevices = 0;
+       int                     lun;
+       int                     maxWordsLeft;
+@@ -1408,13 +1379,6 @@ mptctl_gettargetinfo (unsigned long arg)
+               return -EFAULT;
+       }
+-      if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+-          (ioc == NULL)) {
+-              printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
+-                              __FILE__, __LINE__, iocnum);
+-              return -ENODEV;
+-      }
+-
+       dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n",
+           ioc->name));
+       /* Get the port number and set the maximum number of bytes
+@@ -1510,12 +1474,10 @@ mptctl_gettargetinfo (unsigned long arg)
+  *            -ENODEV  if no such device/adapter
+  */
+ static int
+-mptctl_readtest (unsigned long arg)
++mptctl_readtest (MPT_ADAPTER *ioc, unsigned long arg)
+ {
+       struct mpt_ioctl_test __user *uarg = (void __user *) arg;
+       struct mpt_ioctl_test    karg;
+-      MPT_ADAPTER *ioc;
+-      int iocnum;
+       if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
+               printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
+@@ -1524,13 +1486,6 @@ mptctl_readtest (unsigned long arg)
+               return -EFAULT;
+       }
+-      if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+-          (ioc == NULL)) {
+-              printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n",
+-                              __FILE__, __LINE__, iocnum);
+-              return -ENODEV;
+-      }
+-
+       dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n",
+           ioc->name));
+       /* Fill in the data and return the structure to the calling
+@@ -1571,12 +1526,10 @@ mptctl_readtest (unsigned long arg)
+  *            -ENODEV  if no such device/adapter
+  */
+ static int
+-mptctl_eventquery (unsigned long arg)
++mptctl_eventquery (MPT_ADAPTER *ioc, unsigned long arg)
+ {
+       struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
+       struct mpt_ioctl_eventquery      karg;
+-      MPT_ADAPTER *ioc;
+-      int iocnum;
+       if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
+               printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
+@@ -1585,13 +1538,6 @@ mptctl_eventquery (unsigned long arg)
+               return -EFAULT;
+       }
+-      if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+-          (ioc == NULL)) {
+-              printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
+-                              __FILE__, __LINE__, iocnum);
+-              return -ENODEV;
+-      }
+-
+       dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventquery called.\n",
+           ioc->name));
+       karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
+@@ -1610,12 +1556,10 @@ mptctl_eventquery (unsigned long arg)
+ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+ static int
+-mptctl_eventenable (unsigned long arg)
++mptctl_eventenable (MPT_ADAPTER *ioc, unsigned long arg)
+ {
+       struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
+       struct mpt_ioctl_eventenable     karg;
+-      MPT_ADAPTER *ioc;
+-      int iocnum;
+       if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
+               printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
+@@ -1624,13 +1568,6 @@ mptctl_eventenable (unsigned long arg)
+               return -EFAULT;
+       }
+-      if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+-          (ioc == NULL)) {
+-              printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
+-                              __FILE__, __LINE__, iocnum);
+-              return -ENODEV;
+-      }
+-
+       dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventenable called.\n",
+           ioc->name));
+       if (ioc->events == NULL) {
+@@ -1658,12 +1595,10 @@ mptctl_eventenable (unsigned long arg)
+ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+ static int
+-mptctl_eventreport (unsigned long arg)
++mptctl_eventreport (MPT_ADAPTER *ioc, unsigned long arg)
+ {
+       struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
+       struct mpt_ioctl_eventreport     karg;
+-      MPT_ADAPTER              *ioc;
+-      int                      iocnum;
+       int                      numBytes, maxEvents, max;
+       if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
+@@ -1673,12 +1608,6 @@ mptctl_eventreport (unsigned long arg)
+               return -EFAULT;
+       }
+-      if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+-          (ioc == NULL)) {
+-              printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
+-                              __FILE__, __LINE__, iocnum);
+-              return -ENODEV;
+-      }
+       dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventreport called.\n",
+           ioc->name));
+@@ -1712,12 +1641,10 @@ mptctl_eventreport (unsigned long arg)
+ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+ static int
+-mptctl_replace_fw (unsigned long arg)
++mptctl_replace_fw (MPT_ADAPTER *ioc, unsigned long arg)
+ {
+       struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
+       struct mpt_ioctl_replace_fw      karg;
+-      MPT_ADAPTER              *ioc;
+-      int                      iocnum;
+       int                      newFwSize;
+       if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
+@@ -1727,13 +1654,6 @@ mptctl_replace_fw (unsigned long arg)
+               return -EFAULT;
+       }
+-      if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+-          (ioc == NULL)) {
+-              printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
+-                              __FILE__, __LINE__, iocnum);
+-              return -ENODEV;
+-      }
+-
+       dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n",
+           ioc->name));
+       /* If caching FW, Free the old FW image
+@@ -1780,12 +1700,10 @@ mptctl_replace_fw (unsigned long arg)
+  *            -ENOMEM if memory allocation error
+  */
+ static int
+-mptctl_mpt_command (unsigned long arg)
++mptctl_mpt_command (MPT_ADAPTER *ioc, unsigned long arg)
+ {
+       struct mpt_ioctl_command __user *uarg = (void __user *) arg;
+       struct mpt_ioctl_command  karg;
+-      MPT_ADAPTER     *ioc;
+-      int             iocnum;
+       int             rc;
+@@ -1796,14 +1714,7 @@ mptctl_mpt_command (unsigned long arg)
+               return -EFAULT;
+       }
+-      if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+-          (ioc == NULL)) {
+-              printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
+-                              __FILE__, __LINE__, iocnum);
+-              return -ENODEV;
+-      }
+-
+-      rc = mptctl_do_mpt_command (karg, &uarg->MF);
++      rc = mptctl_do_mpt_command (ioc, karg, &uarg->MF);
+       return rc;
+ }
+@@ -1821,9 +1732,8 @@ mptctl_mpt_command (unsigned long arg)
+  *            -EPERM if SCSI I/O and target is untagged
+  */
+ static int
+-mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
++mptctl_do_mpt_command (MPT_ADAPTER *ioc, struct mpt_ioctl_command karg, void __user *mfPtr)
+ {
+-      MPT_ADAPTER     *ioc;
+       MPT_FRAME_HDR   *mf = NULL;
+       MPIHeader_t     *hdr;
+       char            *psge;
+@@ -1832,7 +1742,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_
+       dma_addr_t      dma_addr_in;
+       dma_addr_t      dma_addr_out;
+       int             sgSize = 0;     /* Num SG elements */
+-      int             iocnum, flagsLength;
++      int             flagsLength;
+       int             sz, rc = 0;
+       int             msgContext;
+       u16             req_idx;
+@@ -1847,13 +1757,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_
+       bufIn.kptr = bufOut.kptr = NULL;
+       bufIn.len = bufOut.len = 0;
+-      if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+-          (ioc == NULL)) {
+-              printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
+-                              __FILE__, __LINE__, iocnum);
+-              return -ENODEV;
+-      }
+-
+       spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
+       if (ioc->ioc_reset_in_progress) {
+               spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
+@@ -2418,17 +2321,15 @@ done_free_mem:
+  *            -ENOMEM if memory allocation error
+  */
+ static int
+-mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
++mptctl_hp_hostinfo(MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
+ {
+       hp_host_info_t  __user *uarg = (void __user *) arg;
+-      MPT_ADAPTER             *ioc;
+       struct pci_dev          *pdev;
+       char                    *pbuf=NULL;
+       dma_addr_t              buf_dma;
+       hp_host_info_t          karg;
+       CONFIGPARMS             cfg;
+       ConfigPageHeader_t      hdr;
+-      int                     iocnum;
+       int                     rc, cim_rev;
+       ToolboxIstwiReadWriteRequest_t  *IstwiRWRequest;
+       MPT_FRAME_HDR           *mf = NULL;
+@@ -2452,12 +2353,6 @@ mptctl_hp_hostinfo(unsigned long arg, un
+               return -EFAULT;
+       }
+-      if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+-          (ioc == NULL)) {
+-              printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
+-                              __FILE__, __LINE__, iocnum);
+-              return -ENODEV;
+-      }
+       dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_hostinfo called.\n",
+           ioc->name));
+@@ -2659,15 +2554,13 @@ retry_wait:
+  *            -ENOMEM if memory allocation error
+  */
+ static int
+-mptctl_hp_targetinfo(unsigned long arg)
++mptctl_hp_targetinfo(MPT_ADAPTER *ioc, unsigned long arg)
+ {
+       hp_target_info_t __user *uarg = (void __user *) arg;
+       SCSIDevicePage0_t       *pg0_alloc;
+       SCSIDevicePage3_t       *pg3_alloc;
+-      MPT_ADAPTER             *ioc;
+       MPT_SCSI_HOST           *hd = NULL;
+       hp_target_info_t        karg;
+-      int                     iocnum;
+       int                     data_sz;
+       dma_addr_t              page_dma;
+       CONFIGPARMS             cfg;
+@@ -2681,12 +2574,6 @@ mptctl_hp_targetinfo(unsigned long arg)
+               return -EFAULT;
+       }
+-      if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+-              (ioc == NULL)) {
+-              printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
+-                              __FILE__, __LINE__, iocnum);
+-              return -ENODEV;
+-      }
+       if (karg.hdr.id >= MPT_MAX_FC_DEVICES)
+               return -EINVAL;
+       dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
+@@ -2854,7 +2741,7 @@ compat_mptfwxfer_ioctl(struct file *filp
+       kfw.fwlen = kfw32.fwlen;
+       kfw.bufp = compat_ptr(kfw32.bufp);
+-      ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
++      ret = mptctl_do_fw_download(iocp, kfw.bufp, kfw.fwlen);
+       mutex_unlock(&iocp->ioctl_cmds.mutex);
+@@ -2908,7 +2795,7 @@ compat_mpt_command(struct file *filp, un
+       /* Pass new structure to do_mpt_command
+        */
+-      ret = mptctl_do_mpt_command (karg, &uarg->MF);
++      ret = mptctl_do_mpt_command (iocp, karg, &uarg->MF);
+       mutex_unlock(&iocp->ioctl_cmds.mutex);
index 81b38eef00f5adccefac899f9ea8211e50bcbda8..6fc508855fcb0ed79ee6f376da65db49dc717572 100644 (file)
@@ -34,3 +34,23 @@ io_uring-only-allow-submit-from-owning-task.patch
 cpuidle-teo-fix-intervals-array-indexing-bug.patch
 arm-dts-am571x-idk-fix-gpios-property-to-have-the-correct-gpio-number.patch
 arm-davinci-select-config_reset_controller.patch
+perf-correctly-handle-failed-perf_get_aux_event.patch
+iio-adc-ad7124-fix-dt-channel-configuration.patch
+iio-imu-st_lsm6dsx-fix-selection-of-st_lsm6ds3_id.patch
+iio-light-vcnl4000-fix-scale-for-vcnl4040.patch
+iio-chemical-pms7003-fix-unmet-triggered-buffer-dependency.patch
+iio-buffer-align-the-size-of-scan-bytes-to-size-of-the-largest-element.patch
+usb-serial-simple-add-motorola-solutions-tetra-mtp3xxx-and-mtp85xx.patch
+usb-serial-option-add-support-for-quectel-rm500q.patch
+usb-serial-opticon-fix-control-message-timeouts.patch
+usb-serial-option-add-support-for-quectel-rm500q-in-qdl-mode.patch
+usb-serial-suppress-driver-bind-attributes.patch
+usb-serial-ch341-handle-unbound-port-at-reset_resume.patch
+usb-serial-io_edgeport-handle-unbound-ports-on-urb-completion.patch
+usb-serial-io_edgeport-add-missing-active-port-sanity-check.patch
+usb-serial-keyspan-handle-unbound-ports.patch
+usb-serial-quatech2-handle-unbound-ports.patch
+staging-comedi-ni_routes-fix-null-dereference-in-ni_find_route_source.patch
+staging-comedi-ni_routes-allow-partial-routing-information.patch
+scsi-fnic-fix-invalid-stack-access.patch
+scsi-mptfusion-fix-double-fetch-bug-in-ioctl.patch
diff --git a/queue-5.4/staging-comedi-ni_routes-allow-partial-routing-information.patch b/queue-5.4/staging-comedi-ni_routes-allow-partial-routing-information.patch
new file mode 100644 (file)
index 0000000..714af4a
--- /dev/null
@@ -0,0 +1,86 @@
+From 9fea3a40f6b07de977a2783270c8c3bc82544d45 Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Tue, 14 Jan 2020 18:25:32 +0000
+Subject: staging: comedi: ni_routes: allow partial routing information
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+commit 9fea3a40f6b07de977a2783270c8c3bc82544d45 upstream.
+
+This patch fixes a regression on setting up asynchronous commands to use
+external trigger sources when board-specific routing information is
+missing.
+
+`ni_find_device_routes()` (called via `ni_assign_device_routes()`) finds
+the table of register values for the device family and the set of valid
+routes for the specific board.  If both are found,
+`tables->route_values` is set to point to the table of register values
+for the device family and `tables->valid_routes` is set to point to the
+list of valid routes for the specific board.  If either is not found,
+both `tables->route_values` and `tables->valid_routes` are left set at
+their initial null values (initialized by `ni_assign_device_routes()`)
+and the function returns `-ENODATA`.
+
+Returning an error results in some routing functionality being disabled.
+Unfortunately, leaving `table->route_values` set to `NULL` also breaks
+the setting up of asynchronous commands that are configured to use
+external trigger sources.  Calls to `ni_check_trigger_arg()` or
+`ni_check_trigger_arg_roffs()` while checking the asynchronous command
+set-up would result in a null pointer dereference if
+`table->route_values` is `NULL`.  The null pointer dereference is fixed
+in another patch, but it now results in failure to set up the
+asynchronous command.  That is a regression from the behavior prior to
+commit 347e244884c3 ("staging: comedi: tio: implement global tio/ctr
+routing") and commit 56d0b826d39f ("staging: comedi: ni_mio_common:
+implement new routing for TRIG_EXT").
+
+Change `ni_find_device_routes()` to set `tables->route_values` and/or
+`tables->valid_routes` to valid information even if the other one can
+only be set to `NULL` due to missing information.  The function will
+still return an error in that case.  This should result in
+`tables->valid_routes` being valid for all currently supported device
+families even if the board-specific routing information is missing.
+That should be enough to fix the regression on setting up asynchronous
+commands to use external triggers for boards with missing routing
+information.
+
+Fixes: 347e244884c3 ("staging: comedi: tio: implement global tio/ctr routing")
+Fixes: 56d0b826d39f ("staging: comedi: ni_mio_common: implement new routing for TRIG_EXT").
+Cc: <stable@vger.kernel.org> # 4.20+
+Cc: Spencer E. Olson <olsonse@umich.edu>
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Link: https://lore.kernel.org/r/20200114182532.132058-3-abbotti@mev.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/comedi/drivers/ni_routes.c |    9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/staging/comedi/drivers/ni_routes.c
++++ b/drivers/staging/comedi/drivers/ni_routes.c
+@@ -74,9 +74,6 @@ static int ni_find_device_routes(const c
+               }
+       }
+-      if (!rv)
+-              return -ENODATA;
+-
+       /* Second, find the set of routes valid for this device. */
+       for (i = 0; ni_device_routes_list[i]; ++i) {
+               if (memcmp(ni_device_routes_list[i]->device, board_name,
+@@ -86,12 +83,12 @@ static int ni_find_device_routes(const c
+               }
+       }
+-      if (!dr)
+-              return -ENODATA;
+-
+       tables->route_values = rv;
+       tables->valid_routes = dr;
++      if (!rv || !dr)
++              return -ENODATA;
++
+       return 0;
+ }
diff --git a/queue-5.4/staging-comedi-ni_routes-fix-null-dereference-in-ni_find_route_source.patch b/queue-5.4/staging-comedi-ni_routes-fix-null-dereference-in-ni_find_route_source.patch
new file mode 100644 (file)
index 0000000..0adb905
--- /dev/null
@@ -0,0 +1,54 @@
+From 01e20b664f808a4f3048ca3f930911fd257209bd Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Tue, 14 Jan 2020 18:25:31 +0000
+Subject: staging: comedi: ni_routes: fix null dereference in ni_find_route_source()
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+commit 01e20b664f808a4f3048ca3f930911fd257209bd upstream.
+
+In `ni_find_route_source()`, `tables->route_values` gets dereferenced.
+However it is possible that `tables->route_values` is `NULL`, leading to
+a null pointer dereference.  `tables->route_values` will be `NULL` if
+the call to `ni_assign_device_routes()` during board initialization
+returned an error due to missing device family routing information or
+missing board-specific routing information.  For example, there is
+currently no board-specific routing information provided for the
+PCIe-6251 board and several other boards, so those are affected by this
+bug.
+
+The bug is triggered when `ni_find_route_source()` is called via
+`ni_check_trigger_arg()` or `ni_check_trigger_arg_roffs()` when checking
+the arguments for setting up asynchronous commands.  Fix it by returning
+`-EINVAL` if `tables->route_values` is `NULL`.
+
+Even with this fix, setting up asynchronous commands to use external
+trigger sources for boards with missing routing information will still
+fail gracefully.  Since `ni_find_route_source()` only depends on the
+device family routing information, it would be better if that was made
+available even if the board-specific routing information is missing.
+That will be addressed by another patch.
+
+Fixes: 4bb90c87abbe ("staging: comedi: add interface to ni routing table information")
+Cc: <stable@vger.kernel.org> # 4.20+
+Cc: Spencer E. Olson <olsonse@umich.edu>
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Link: https://lore.kernel.org/r/20200114182532.132058-2-abbotti@mev.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/comedi/drivers/ni_routes.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/staging/comedi/drivers/ni_routes.c
++++ b/drivers/staging/comedi/drivers/ni_routes.c
+@@ -489,6 +489,9 @@ int ni_find_route_source(const u8 src_se
+ {
+       int src;
++      if (!tables->route_values)
++              return -EINVAL;
++
+       dest = B(dest); /* subtract NI names offset */
+       /* ensure we are not going to under/over run the route value table */
+       if (dest < 0 || dest >= NI_NUM_NAMES)
diff --git a/queue-5.4/usb-serial-ch341-handle-unbound-port-at-reset_resume.patch b/queue-5.4/usb-serial-ch341-handle-unbound-port-at-reset_resume.patch
new file mode 100644 (file)
index 0000000..62fa750
--- /dev/null
@@ -0,0 +1,40 @@
+From 4d5ef53f75c22d28f490bcc5c771fcc610a9afa4 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Jan 2020 10:50:22 +0100
+Subject: USB: serial: ch341: handle unbound port at reset_resume
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 4d5ef53f75c22d28f490bcc5c771fcc610a9afa4 upstream.
+
+Check for NULL port data in reset_resume() to avoid dereferencing a NULL
+pointer in case the port device isn't bound to a driver (e.g. after a
+failed control request at port probe).
+
+Fixes: 1ded7ea47b88 ("USB: ch341 serial: fix port number changed after resume")
+Cc: stable <stable@vger.kernel.org>     # 2.6.30
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ch341.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/ch341.c
++++ b/drivers/usb/serial/ch341.c
+@@ -589,9 +589,13 @@ static int ch341_tiocmget(struct tty_str
+ static int ch341_reset_resume(struct usb_serial *serial)
+ {
+       struct usb_serial_port *port = serial->port[0];
+-      struct ch341_private *priv = usb_get_serial_port_data(port);
++      struct ch341_private *priv;
+       int ret;
++      priv = usb_get_serial_port_data(port);
++      if (!priv)
++              return 0;
++
+       /* reconfigure ch341 serial port after bus-reset */
+       ch341_configure(serial->dev, priv);
diff --git a/queue-5.4/usb-serial-io_edgeport-add-missing-active-port-sanity-check.patch b/queue-5.4/usb-serial-io_edgeport-add-missing-active-port-sanity-check.patch
new file mode 100644 (file)
index 0000000..c98f9bd
--- /dev/null
@@ -0,0 +1,67 @@
+From 1568c58d11a7c851bd09341aeefd6a1c308ac40d Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Jan 2020 10:50:24 +0100
+Subject: USB: serial: io_edgeport: add missing active-port sanity check
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 1568c58d11a7c851bd09341aeefd6a1c308ac40d upstream.
+
+The driver receives the active port number from the device, but never
+made sure that the port number was valid. This could lead to a
+NULL-pointer dereference or memory corruption in case a device sends
+data for an invalid port.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/io_edgeport.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -1725,7 +1725,8 @@ static void edge_break(struct tty_struct
+ static void process_rcvd_data(struct edgeport_serial *edge_serial,
+                               unsigned char *buffer, __u16 bufferLength)
+ {
+-      struct device *dev = &edge_serial->serial->dev->dev;
++      struct usb_serial *serial = edge_serial->serial;
++      struct device *dev = &serial->dev->dev;
+       struct usb_serial_port *port;
+       struct edgeport_port *edge_port;
+       __u16 lastBufferLength;
+@@ -1821,9 +1822,8 @@ static void process_rcvd_data(struct edg
+                       /* spit this data back into the tty driver if this
+                          port is open */
+-                      if (rxLen) {
+-                              port = edge_serial->serial->port[
+-                                                      edge_serial->rxPort];
++                      if (rxLen && edge_serial->rxPort < serial->num_ports) {
++                              port = serial->port[edge_serial->rxPort];
+                               edge_port = usb_get_serial_port_data(port);
+                               if (edge_port && edge_port->open) {
+                                       dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n",
+@@ -1833,8 +1833,8 @@ static void process_rcvd_data(struct edg
+                                                       rxLen);
+                                       edge_port->port->icount.rx += rxLen;
+                               }
+-                              buffer += rxLen;
+                       }
++                      buffer += rxLen;
+                       break;
+               case EXPECT_HDR3:       /* Expect 3rd byte of status header */
+@@ -1869,6 +1869,8 @@ static void process_rcvd_status(struct e
+       __u8 code = edge_serial->rxStatusCode;
+       /* switch the port pointer to the one being currently talked about */
++      if (edge_serial->rxPort >= edge_serial->serial->num_ports)
++              return;
+       port = edge_serial->serial->port[edge_serial->rxPort];
+       edge_port = usb_get_serial_port_data(port);
+       if (edge_port == NULL) {
diff --git a/queue-5.4/usb-serial-io_edgeport-handle-unbound-ports-on-urb-completion.patch b/queue-5.4/usb-serial-io_edgeport-handle-unbound-ports-on-urb-completion.patch
new file mode 100644 (file)
index 0000000..ba58f4f
--- /dev/null
@@ -0,0 +1,45 @@
+From e37d1aeda737a20b1846a91a3da3f8b0f00cf690 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Jan 2020 10:50:23 +0100
+Subject: USB: serial: io_edgeport: handle unbound ports on URB completion
+
+From: Johan Hovold <johan@kernel.org>
+
+commit e37d1aeda737a20b1846a91a3da3f8b0f00cf690 upstream.
+
+Check for NULL port data in the shared interrupt and bulk completion
+callbacks to avoid dereferencing a NULL pointer in case a device sends
+data for a port device which isn't bound to a driver (e.g. due to a
+malicious device having unexpected endpoints or after an allocation
+failure on port probe).
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/io_edgeport.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -716,7 +716,7 @@ static void edge_interrupt_callback(stru
+                       if (txCredits) {
+                               port = edge_serial->serial->port[portNumber];
+                               edge_port = usb_get_serial_port_data(port);
+-                              if (edge_port->open) {
++                              if (edge_port && edge_port->open) {
+                                       spin_lock_irqsave(&edge_port->ep_lock,
+                                                         flags);
+                                       edge_port->txCredits += txCredits;
+@@ -1825,7 +1825,7 @@ static void process_rcvd_data(struct edg
+                               port = edge_serial->serial->port[
+                                                       edge_serial->rxPort];
+                               edge_port = usb_get_serial_port_data(port);
+-                              if (edge_port->open) {
++                              if (edge_port && edge_port->open) {
+                                       dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n",
+                                               __func__, rxLen,
+                                               edge_serial->rxPort);
diff --git a/queue-5.4/usb-serial-keyspan-handle-unbound-ports.patch b/queue-5.4/usb-serial-keyspan-handle-unbound-ports.patch
new file mode 100644 (file)
index 0000000..33a2a0d
--- /dev/null
@@ -0,0 +1,45 @@
+From 3018dd3fa114b13261e9599ddb5656ef97a1fa17 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Jan 2020 10:50:25 +0100
+Subject: USB: serial: keyspan: handle unbound ports
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 3018dd3fa114b13261e9599ddb5656ef97a1fa17 upstream.
+
+Check for NULL port data in the control URB completion handlers to avoid
+dereferencing a NULL pointer in the unlikely case where a port device
+isn't bound to a driver (e.g. after an allocation failure on port
+probe()).
+
+Fixes: 0ca1268e109a ("USB Serial Keyspan: add support for USA-49WG & USA-28XG")
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/keyspan.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/serial/keyspan.c
++++ b/drivers/usb/serial/keyspan.c
+@@ -1058,6 +1058,8 @@ static void      usa49_glocont_callback(struc
+       for (i = 0; i < serial->num_ports; ++i) {
+               port = serial->port[i];
+               p_priv = usb_get_serial_port_data(port);
++              if (!p_priv)
++                      continue;
+               if (p_priv->resend_cont) {
+                       dev_dbg(&port->dev, "%s - sending setup\n", __func__);
+@@ -1459,6 +1461,8 @@ static void usa67_glocont_callback(struc
+       for (i = 0; i < serial->num_ports; ++i) {
+               port = serial->port[i];
+               p_priv = usb_get_serial_port_data(port);
++              if (!p_priv)
++                      continue;
+               if (p_priv->resend_cont) {
+                       dev_dbg(&port->dev, "%s - sending setup\n", __func__);
diff --git a/queue-5.4/usb-serial-opticon-fix-control-message-timeouts.patch b/queue-5.4/usb-serial-opticon-fix-control-message-timeouts.patch
new file mode 100644 (file)
index 0000000..321531a
--- /dev/null
@@ -0,0 +1,39 @@
+From 5e28055f340275a8616eee88ef19186631b4d136 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 13 Jan 2020 18:22:13 +0100
+Subject: USB: serial: opticon: fix control-message timeouts
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 5e28055f340275a8616eee88ef19186631b4d136 upstream.
+
+The driver was issuing synchronous uninterruptible control requests
+without using a timeout. This could lead to the driver hanging
+on open() or tiocmset() due to a malfunctioning (or malicious) device
+until the device is physically disconnected.
+
+The USB upper limit of five seconds per request should be more than
+enough.
+
+Fixes: 309a057932ab ("USB: opticon: add rts and cts support")
+Cc: stable <stable@vger.kernel.org>     # 2.6.39
+Cc: Martin Jansen <martin.jansen@opticon.com>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/opticon.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/opticon.c
++++ b/drivers/usb/serial/opticon.c
+@@ -113,7 +113,7 @@ static int send_control_msg(struct usb_s
+       retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                               requesttype,
+                               USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
+-                              0, 0, buffer, 1, 0);
++                              0, 0, buffer, 1, USB_CTRL_SET_TIMEOUT);
+       kfree(buffer);
+       if (retval < 0)
diff --git a/queue-5.4/usb-serial-option-add-support-for-quectel-rm500q-in-qdl-mode.patch b/queue-5.4/usb-serial-option-add-support-for-quectel-rm500q-in-qdl-mode.patch
new file mode 100644 (file)
index 0000000..1c7dac2
--- /dev/null
@@ -0,0 +1,45 @@
+From f3eaabbfd093c93d791eb930cc68d9b15246a65e Mon Sep 17 00:00:00 2001
+From: Reinhard Speyerer <rspmn@arcor.de>
+Date: Tue, 14 Jan 2020 14:29:23 +0100
+Subject: USB: serial: option: add support for Quectel RM500Q in QDL mode
+
+From: Reinhard Speyerer <rspmn@arcor.de>
+
+commit f3eaabbfd093c93d791eb930cc68d9b15246a65e upstream.
+
+Add support for Quectel RM500Q in QDL mode.
+
+T:  Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 24 Spd=480  MxCh= 0
+D:  Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
+P:  Vendor=2c7c ProdID=0800 Rev= 0.00
+S:  Manufacturer=Qualcomm CDMA Technologies MSM
+S:  Product=QUSB_BULK_SN:xxxxxxxx
+S:  SerialNumber=xxxxxxxx
+C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=  2mA
+I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=10 Driver=option
+E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+It is assumed that the ZLP flag required for other Qualcomm-based
+5G devices also applies to Quectel RM500Q.
+
+Signed-off-by: Reinhard Speyerer <rspmn@arcor.de>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -1107,6 +1107,8 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) },
++      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10),
++        .driver_info = ZLP },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
diff --git a/queue-5.4/usb-serial-option-add-support-for-quectel-rm500q.patch b/queue-5.4/usb-serial-option-add-support-for-quectel-rm500q.patch
new file mode 100644 (file)
index 0000000..d6760d4
--- /dev/null
@@ -0,0 +1,353 @@
+From accf227de4d211b52c830a58b2df00d5739f2389 Mon Sep 17 00:00:00 2001
+From: Kristian Evensen <kristian.evensen@gmail.com>
+Date: Mon, 13 Jan 2020 15:14:05 +0100
+Subject: USB: serial: option: Add support for Quectel RM500Q
+
+From: Kristian Evensen <kristian.evensen@gmail.com>
+
+commit accf227de4d211b52c830a58b2df00d5739f2389 upstream.
+
+RM500Q is a 5G module from Quectel, supporting both standalone and
+non-standalone modes. Unlike other recent Quectel modems, it is possible
+to identify the diagnostic interface (bInterfaceProtocol is unique).
+Thus, there is no need to check for the number of endpoints or reserve
+interfaces. The interface number is still dynamic though, so matching on
+interface number is not possible and two entries have to be added to the
+table.
+
+Output from usb-devices with all interfaces enabled (order is diag,
+nmea, at_port, modem, rmnet and adb):
+
+Bus 004 Device 007: ID 2c7c:0800 Quectel Wireless Solutions Co., Ltd.
+Device Descriptor:
+  bLength                18
+  bDescriptorType         1
+  bcdUSB               3.20
+  bDeviceClass            0 (Defined at Interface level)
+  bDeviceSubClass         0
+  bDeviceProtocol         0
+  bMaxPacketSize0         9
+  idVendor           0x2c7c Quectel Wireless Solutions Co., Ltd.
+  idProduct          0x0800
+  bcdDevice            4.14
+  iManufacturer           1 Quectel
+  iProduct                2 LTE-A Module
+  iSerial                 3 40046d60
+  bNumConfigurations      1
+  Configuration Descriptor:
+    bLength                 9
+    bDescriptorType         2
+    wTotalLength          328
+    bNumInterfaces          6
+    bConfigurationValue     1
+    iConfiguration          4 DIAG_SER_RMNET
+    bmAttributes         0xa0
+      (Bus Powered)
+      Remote Wakeup
+    MaxPower              224mA
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        0
+      bAlternateSetting       0
+      bNumEndpoints           2
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass    255 Vendor Specific Subclass
+      bInterfaceProtocol     48
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x81  EP 1 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x01  EP 1 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               0
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        1
+      bAlternateSetting       0
+      bNumEndpoints           3
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass      0
+      bInterfaceProtocol      0
+      iInterface              0
+      ** UNRECOGNIZED:  05 24 00 10 01
+      ** UNRECOGNIZED:  05 24 01 00 00
+      ** UNRECOGNIZED:  04 24 02 02
+      ** UNRECOGNIZED:  05 24 06 00 00
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x83  EP 3 IN
+        bmAttributes            3
+          Transfer Type            Interrupt
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x000a  1x 10 bytes
+        bInterval               9
+        bMaxBurst               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x82  EP 2 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x02  EP 2 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               0
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        2
+      bAlternateSetting       0
+      bNumEndpoints           3
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass      0
+      bInterfaceProtocol      0
+      iInterface              0
+      ** UNRECOGNIZED:  05 24 00 10 01
+      ** UNRECOGNIZED:  05 24 01 00 00
+      ** UNRECOGNIZED:  04 24 02 02
+      ** UNRECOGNIZED:  05 24 06 00 00
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x85  EP 5 IN
+        bmAttributes            3
+          Transfer Type            Interrupt
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x000a  1x 10 bytes
+        bInterval               9
+        bMaxBurst               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x84  EP 4 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x03  EP 3 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               0
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        3
+      bAlternateSetting       0
+      bNumEndpoints           3
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass      0
+      bInterfaceProtocol      0
+      iInterface              0
+      ** UNRECOGNIZED:  05 24 00 10 01
+      ** UNRECOGNIZED:  05 24 01 00 00
+      ** UNRECOGNIZED:  04 24 02 02
+      ** UNRECOGNIZED:  05 24 06 00 00
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x87  EP 7 IN
+        bmAttributes            3
+          Transfer Type            Interrupt
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x000a  1x 10 bytes
+        bInterval               9
+        bMaxBurst               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x86  EP 6 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x04  EP 4 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               0
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        4
+      bAlternateSetting       0
+      bNumEndpoints           3
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass    255 Vendor Specific Subclass
+      bInterfaceProtocol    255 Vendor Specific Protocol
+      iInterface              5 CDEV Serial
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x88  EP 8 IN
+        bmAttributes            3
+          Transfer Type            Interrupt
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0008  1x 8 bytes
+        bInterval               9
+        bMaxBurst               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x8e  EP 14 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               6
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x0f  EP 15 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               2
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        5
+      bAlternateSetting       0
+      bNumEndpoints           2
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass     66
+      bInterfaceProtocol      1
+      iInterface              6 ADB Interface
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x05  EP 5 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x89  EP 9 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0400  1x 1024 bytes
+        bInterval               0
+        bMaxBurst               0
+Binary Object Store Descriptor:
+  bLength                 5
+  bDescriptorType        15
+  wTotalLength           42
+  bNumDeviceCaps          3
+  USB 2.0 Extension Device Capability:
+    bLength                 7
+    bDescriptorType        16
+    bDevCapabilityType      2
+    bmAttributes   0x00000006
+      Link Power Management (LPM) Supported
+  SuperSpeed USB Device Capability:
+    bLength                10
+    bDescriptorType        16
+    bDevCapabilityType      3
+    bmAttributes         0x00
+    wSpeedsSupported   0x000f
+      Device can operate at Low Speed (1Mbps)
+      Device can operate at Full Speed (12Mbps)
+      Device can operate at High Speed (480Mbps)
+      Device can operate at SuperSpeed (5Gbps)
+    bFunctionalitySupport   1
+      Lowest fully-functional device speed is Full Speed (12Mbps)
+    bU1DevExitLat           1 micro seconds
+    bU2DevExitLat         500 micro seconds
+  ** UNRECOGNIZED:  14 10 0a 00 01 00 00 00 00 11 00 00 30 40 0a 00 b0 40 0a 00
+Device Status:     0x0000
+  (Bus Powered)
+
+Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -248,6 +248,7 @@ static void option_instat_callback(struc
+ #define QUECTEL_PRODUCT_BG96                  0x0296
+ #define QUECTEL_PRODUCT_EP06                  0x0306
+ #define QUECTEL_PRODUCT_EM12                  0x0512
++#define QUECTEL_PRODUCT_RM500Q                        0x0800
+ #define CMOTECH_VENDOR_ID                     0x16d8
+ #define CMOTECH_PRODUCT_6001                  0x6001
+@@ -1104,6 +1105,9 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff),
+         .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) },
++      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) },
++      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) },
++
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
diff --git a/queue-5.4/usb-serial-quatech2-handle-unbound-ports.patch b/queue-5.4/usb-serial-quatech2-handle-unbound-ports.patch
new file mode 100644 (file)
index 0000000..0cff9ec
--- /dev/null
@@ -0,0 +1,52 @@
+From 9715a43eea77e42678a1002623f2d9a78f5b81a1 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Jan 2020 15:35:26 +0100
+Subject: USB: serial: quatech2: handle unbound ports
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 9715a43eea77e42678a1002623f2d9a78f5b81a1 upstream.
+
+Check for NULL port data in the modem- and line-status handlers to avoid
+dereferencing a NULL pointer in the unlikely case where a port device
+isn't bound to a driver (e.g. after an allocation failure on port
+probe).
+
+Note that the other (stubbed) event handlers qt2_process_xmit_empty()
+and qt2_process_flush() would need similar sanity checks in case they
+are ever implemented.
+
+Fixes: f7a33e608d9a ("USB: serial: add quatech2 usb to serial driver")
+Cc: stable <stable@vger.kernel.org>     # 3.5
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/quatech2.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/serial/quatech2.c
++++ b/drivers/usb/serial/quatech2.c
+@@ -841,7 +841,10 @@ static void qt2_update_msr(struct usb_se
+       u8 newMSR = (u8) *ch;
+       unsigned long flags;
++      /* May be called from qt2_process_read_urb() for an unbound port. */
+       port_priv = usb_get_serial_port_data(port);
++      if (!port_priv)
++              return;
+       spin_lock_irqsave(&port_priv->lock, flags);
+       port_priv->shadowMSR = newMSR;
+@@ -869,7 +872,10 @@ static void qt2_update_lsr(struct usb_se
+       unsigned long flags;
+       u8 newLSR = (u8) *ch;
++      /* May be called from qt2_process_read_urb() for an unbound port. */
+       port_priv = usb_get_serial_port_data(port);
++      if (!port_priv)
++              return;
+       if (newLSR & UART_LSR_BI)
+               newLSR &= (u8) (UART_LSR_OE | UART_LSR_BI);
diff --git a/queue-5.4/usb-serial-simple-add-motorola-solutions-tetra-mtp3xxx-and-mtp85xx.patch b/queue-5.4/usb-serial-simple-add-motorola-solutions-tetra-mtp3xxx-and-mtp85xx.patch
new file mode 100644 (file)
index 0000000..36a972d
--- /dev/null
@@ -0,0 +1,211 @@
+From 260e41ac4dd3e5acb90be624c03ba7f019615b75 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jer=C3=B3nimo=20Borque?= <jeronimo@borque.com.ar>
+Date: Thu, 9 Jan 2020 12:23:34 -0300
+Subject: USB: serial: simple: Add Motorola Solutions TETRA MTP3xxx and MTP85xx
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jerónimo Borque <jeronimo@borque.com.ar>
+
+commit 260e41ac4dd3e5acb90be624c03ba7f019615b75 upstream.
+
+Add device-ids for the Motorola Solutions TETRA radios MTP3xxx series
+and MTP85xx series
+
+$ lsusb -vd 0cad:
+
+Bus 001 Device 009: ID 0cad:9015 Motorola CGISS TETRA PEI interface
+Device Descriptor:
+  bLength                18
+  bDescriptorType         1
+  bcdUSB               2.00
+  bDeviceClass            0
+  bDeviceSubClass         0
+  bDeviceProtocol         0
+  bMaxPacketSize0        64
+  idVendor           0x0cad Motorola CGISS
+  idProduct          0x9015
+  bcdDevice           24.16
+  iManufacturer           1
+  iProduct                2
+  iSerial                 0
+  bNumConfigurations      1
+  Configuration Descriptor:
+    bLength                 9
+    bDescriptorType         2
+    wTotalLength       0x0037
+    bNumInterfaces          2
+    bConfigurationValue     1
+    iConfiguration          3
+    bmAttributes         0x80
+      (Bus Powered)
+    MaxPower              500mA
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        0
+      bAlternateSetting       0
+      bNumEndpoints           2
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass      0
+      bInterfaceProtocol      0
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x81  EP 1 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0040  1x 64 bytes
+        bInterval               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x01  EP 1 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0040  1x 64 bytes
+        bInterval               0
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        1
+      bAlternateSetting       0
+      bNumEndpoints           2
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass      0
+      bInterfaceProtocol      0
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x82  EP 2 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0040  1x 64 bytes
+        bInterval               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x02  EP 2 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0040  1x 64 bytes
+        bInterval               0
+
+Bus 001 Device 010: ID 0cad:9013 Motorola CGISS TETRA PEI interface
+Device Descriptor:
+  bLength                18
+  bDescriptorType         1
+  bcdUSB               2.00
+  bDeviceClass            0
+  bDeviceSubClass         0
+  bDeviceProtocol         0
+  bMaxPacketSize0        64
+  idVendor           0x0cad Motorola CGISS
+  idProduct          0x9013
+  bcdDevice           24.16
+  iManufacturer           1
+  iProduct                2
+  iSerial                 0
+  bNumConfigurations      1
+  Configuration Descriptor:
+    bLength                 9
+    bDescriptorType         2
+    wTotalLength       0x0037
+    bNumInterfaces          2
+    bConfigurationValue     1
+    iConfiguration          3
+    bmAttributes         0x80
+      (Bus Powered)
+    MaxPower              500mA
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        0
+      bAlternateSetting       0
+      bNumEndpoints           2
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass      0
+      bInterfaceProtocol      0
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x81  EP 1 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x01  EP 1 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval               0
+    Interface Descriptor:
+      bLength                 9
+      bDescriptorType         4
+      bInterfaceNumber        1
+      bAlternateSetting       0
+      bNumEndpoints           2
+      bInterfaceClass       255 Vendor Specific Class
+      bInterfaceSubClass      0
+      bInterfaceProtocol      0
+      iInterface              0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x82  EP 2 IN
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval               0
+      Endpoint Descriptor:
+        bLength                 7
+        bDescriptorType         5
+        bEndpointAddress     0x02  EP 2 OUT
+        bmAttributes            2
+          Transfer Type            Bulk
+          Synch Type               None
+          Usage Type               Data
+        wMaxPacketSize     0x0200  1x 512 bytes
+        bInterval               0
+
+Signed-off-by: Jerónimo Borque <jeronimo@borque.com.ar>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/usb-serial-simple.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/usb-serial-simple.c
++++ b/drivers/usb/serial/usb-serial-simple.c
+@@ -86,6 +86,8 @@ DEVICE(moto_modem, MOTO_IDS);
+ #define MOTOROLA_TETRA_IDS()                  \
+       { USB_DEVICE(0x0cad, 0x9011) }, /* Motorola Solutions TETRA PEI */ \
+       { USB_DEVICE(0x0cad, 0x9012) }, /* MTP6550 */ \
++      { USB_DEVICE(0x0cad, 0x9013) }, /* MTP3xxx */ \
++      { USB_DEVICE(0x0cad, 0x9015) }, /* MTP85xx */ \
+       { USB_DEVICE(0x0cad, 0x9016) }  /* TPG2200 */
+ DEVICE(motorola_tetra, MOTOROLA_TETRA_IDS);
diff --git a/queue-5.4/usb-serial-suppress-driver-bind-attributes.patch b/queue-5.4/usb-serial-suppress-driver-bind-attributes.patch
new file mode 100644 (file)
index 0000000..26244ec
--- /dev/null
@@ -0,0 +1,41 @@
+From fdb838efa31e1ed9a13ae6ad0b64e30fdbd00570 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 16 Jan 2020 17:07:05 +0100
+Subject: USB: serial: suppress driver bind attributes
+
+From: Johan Hovold <johan@kernel.org>
+
+commit fdb838efa31e1ed9a13ae6ad0b64e30fdbd00570 upstream.
+
+USB-serial drivers must not be unbound from their ports before the
+corresponding USB driver is unbound from the parent interface so
+suppress the bind and unbind attributes.
+
+Unbinding a serial driver while it's port is open is a sure way to
+trigger a crash as any driver state is released on unbind while port
+hangup is handled on the parent USB interface level. Drivers for
+multiport devices where ports share a resource such as an interrupt
+endpoint also generally cannot handle individual ports going away.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/usb-serial.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -1317,6 +1317,9 @@ static int usb_serial_register(struct us
+               return -EINVAL;
+       }
++      /* Prevent individual ports from being unbound. */
++      driver->driver.suppress_bind_attrs = true;
++
+       usb_serial_operations_init(driver);
+       /* Add this device to our list of devices */