]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Oct 2017 15:30:16 +0000 (17:30 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Oct 2017 15:30:16 +0000 (17:30 +0200)
added patches:
dm-ioctl-fix-alignment-of-event-number-in-the-device-list.patch
iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch
iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch
scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch

queue-4.9/dm-ioctl-fix-alignment-of-event-number-in-the-device-list.patch [new file with mode: 0644]
queue-4.9/iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch [new file with mode: 0644]
queue-4.9/iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch [new file with mode: 0644]
queue-4.9/scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/dm-ioctl-fix-alignment-of-event-number-in-the-device-list.patch b/queue-4.9/dm-ioctl-fix-alignment-of-event-number-in-the-device-list.patch
new file mode 100644 (file)
index 0000000..d4eadf2
--- /dev/null
@@ -0,0 +1,203 @@
+From 62e082430ea4bb5b28909ca4375bb683931e22aa Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 20 Sep 2017 07:29:49 -0400
+Subject: dm ioctl: fix alignment of event number in the device list
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 62e082430ea4bb5b28909ca4375bb683931e22aa upstream.
+
+The size of struct dm_name_list is different on 32-bit and 64-bit
+kernels (so "(nl + 1)" differs between 32-bit and 64-bit kernels).
+
+This mismatch caused some harmless difference in padding when using 32-bit
+or 64-bit kernel. Commit 23d70c5e52dd ("dm ioctl: report event number in
+DM_LIST_DEVICES") added reporting event number in the output of
+DM_LIST_DEVICES_CMD. This difference in padding makes it impossible for
+userspace to determine the location of the event number (the location
+would be different when running on 32-bit and 64-bit kernels).
+
+Fix the padding by using offsetof(struct dm_name_list, name) instead of
+sizeof(struct dm_name_list) to determine the location of entries.
+
+Also, the ioctl version number is incremented to 37 so that userspace
+can use the version number to determine that the event number is present
+and correctly located.
+
+In addition, a global event is now raised when a DM device is created,
+removed, renamed or when table is swapped, so that the user can monitor
+for device changes.
+
+Reported-by: Eugene Syromiatnikov <esyr@redhat.com>
+Fixes: 23d70c5e52dd ("dm ioctl: report event number in DM_LIST_DEVICES")
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h
+index 24eddbdf2ab4..203144762f36 100644
+--- a/drivers/md/dm-core.h
++++ b/drivers/md/dm-core.h
+@@ -149,5 +149,6 @@ static inline bool dm_message_test_buffer_overflow(char *result, unsigned maxlen
+ extern atomic_t dm_global_event_nr;
+ extern wait_queue_head_t dm_global_eventq;
++void dm_issue_global_event(void);
+ #endif
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 8756a6850431..e52676fa9832 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -477,9 +477,13 @@ static int remove_all(struct file *filp, struct dm_ioctl *param, size_t param_si
+  * Round up the ptr to an 8-byte boundary.
+  */
+ #define ALIGN_MASK 7
++static inline size_t align_val(size_t val)
++{
++      return (val + ALIGN_MASK) & ~ALIGN_MASK;
++}
+ static inline void *align_ptr(void *ptr)
+ {
+-      return (void *) (((size_t) (ptr + ALIGN_MASK)) & ~ALIGN_MASK);
++      return (void *)align_val((size_t)ptr);
+ }
+ /*
+@@ -505,7 +509,7 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_
+       struct hash_cell *hc;
+       size_t len, needed = 0;
+       struct gendisk *disk;
+-      struct dm_name_list *nl, *old_nl = NULL;
++      struct dm_name_list *orig_nl, *nl, *old_nl = NULL;
+       uint32_t *event_nr;
+       down_write(&_hash_lock);
+@@ -516,17 +520,15 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_
+        */
+       for (i = 0; i < NUM_BUCKETS; i++) {
+               list_for_each_entry (hc, _name_buckets + i, name_list) {
+-                      needed += sizeof(struct dm_name_list);
+-                      needed += strlen(hc->name) + 1;
+-                      needed += ALIGN_MASK;
+-                      needed += (sizeof(uint32_t) + ALIGN_MASK) & ~ALIGN_MASK;
++                      needed += align_val(offsetof(struct dm_name_list, name) + strlen(hc->name) + 1);
++                      needed += align_val(sizeof(uint32_t));
+               }
+       }
+       /*
+        * Grab our output buffer.
+        */
+-      nl = get_result_buffer(param, param_size, &len);
++      nl = orig_nl = get_result_buffer(param, param_size, &len);
+       if (len < needed) {
+               param->flags |= DM_BUFFER_FULL_FLAG;
+               goto out;
+@@ -549,11 +551,16 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_
+                       strcpy(nl->name, hc->name);
+                       old_nl = nl;
+-                      event_nr = align_ptr(((void *) (nl + 1)) + strlen(hc->name) + 1);
++                      event_nr = align_ptr(nl->name + strlen(hc->name) + 1);
+                       *event_nr = dm_get_event_nr(hc->md);
+                       nl = align_ptr(event_nr + 1);
+               }
+       }
++      /*
++       * If mismatch happens, security may be compromised due to buffer
++       * overflow, so it's better to crash.
++       */
++      BUG_ON((char *)nl - (char *)orig_nl != needed);
+  out:
+       up_write(&_hash_lock);
+@@ -1621,7 +1628,8 @@ static int target_message(struct file *filp, struct dm_ioctl *param, size_t para
+  * which has a variable size, is not used by the function processing
+  * the ioctl.
+  */
+-#define IOCTL_FLAGS_NO_PARAMS 1
++#define IOCTL_FLAGS_NO_PARAMS         1
++#define IOCTL_FLAGS_ISSUE_GLOBAL_EVENT        2
+ /*-----------------------------------------------------------------
+  * Implementation of open/close/ioctl on the special char
+@@ -1635,12 +1643,12 @@ static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags)
+               ioctl_fn fn;
+       } _ioctls[] = {
+               {DM_VERSION_CMD, 0, NULL}, /* version is dealt with elsewhere */
+-              {DM_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS, remove_all},
++              {DM_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, remove_all},
+               {DM_LIST_DEVICES_CMD, 0, list_devices},
+-              {DM_DEV_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_create},
+-              {DM_DEV_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_remove},
+-              {DM_DEV_RENAME_CMD, 0, dev_rename},
++              {DM_DEV_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, dev_create},
++              {DM_DEV_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, dev_remove},
++              {DM_DEV_RENAME_CMD, IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, dev_rename},
+               {DM_DEV_SUSPEND_CMD, IOCTL_FLAGS_NO_PARAMS, dev_suspend},
+               {DM_DEV_STATUS_CMD, IOCTL_FLAGS_NO_PARAMS, dev_status},
+               {DM_DEV_WAIT_CMD, 0, dev_wait},
+@@ -1869,6 +1877,9 @@ static int ctl_ioctl(struct file *file, uint command, struct dm_ioctl __user *us
+           unlikely(ioctl_flags & IOCTL_FLAGS_NO_PARAMS))
+               DMERR("ioctl %d tried to output some data but has IOCTL_FLAGS_NO_PARAMS set", cmd);
++      if (!r && ioctl_flags & IOCTL_FLAGS_ISSUE_GLOBAL_EVENT)
++              dm_issue_global_event();
++
+       /*
+        * Copy the results back to userland.
+        */
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 6e54145969c5..4be85324f44d 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -52,6 +52,12 @@ static struct workqueue_struct *deferred_remove_workqueue;
+ atomic_t dm_global_event_nr = ATOMIC_INIT(0);
+ DECLARE_WAIT_QUEUE_HEAD(dm_global_eventq);
++void dm_issue_global_event(void)
++{
++      atomic_inc(&dm_global_event_nr);
++      wake_up(&dm_global_eventq);
++}
++
+ /*
+  * One of these is allocated per bio.
+  */
+@@ -1865,9 +1871,8 @@ static void event_callback(void *context)
+       dm_send_uevents(&uevents, &disk_to_dev(md->disk)->kobj);
+       atomic_inc(&md->event_nr);
+-      atomic_inc(&dm_global_event_nr);
+       wake_up(&md->eventq);
+-      wake_up(&dm_global_eventq);
++      dm_issue_global_event();
+ }
+ /*
+@@ -2283,6 +2288,7 @@ struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table)
+       }
+       map = __bind(md, table, &limits);
++      dm_issue_global_event();
+ out:
+       mutex_unlock(&md->suspend_lock);
+diff --git a/include/uapi/linux/dm-ioctl.h b/include/uapi/linux/dm-ioctl.h
+index 412c06a624c8..ccaea525340b 100644
+--- a/include/uapi/linux/dm-ioctl.h
++++ b/include/uapi/linux/dm-ioctl.h
+@@ -269,9 +269,9 @@ enum {
+ #define DM_DEV_SET_GEOMETRY   _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
+ #define DM_VERSION_MAJOR      4
+-#define DM_VERSION_MINOR      36
++#define DM_VERSION_MINOR      37
+ #define DM_VERSION_PATCHLEVEL 0
+-#define DM_VERSION_EXTRA      "-ioctl (2017-06-09)"
++#define DM_VERSION_EXTRA      "-ioctl (2017-09-20)"
+ /* Status bits */
+ #define DM_READONLY_FLAG      (1 << 0) /* In/Out */
diff --git a/queue-4.9/iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch b/queue-4.9/iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch
new file mode 100644 (file)
index 0000000..876542d
--- /dev/null
@@ -0,0 +1,172 @@
+From 01a9c948a09348950515bf2abb6113ed83e696d8 Mon Sep 17 00:00:00 2001
+From: Luca Coelho <luciano.coelho@intel.com>
+Date: Tue, 15 Aug 2017 20:48:41 +0300
+Subject: iwlwifi: add workaround to disable wide channels in 5GHz
+
+From: Luca Coelho <luciano.coelho@intel.com>
+
+commit 01a9c948a09348950515bf2abb6113ed83e696d8 upstream.
+
+The OTP in some SKUs have erroneously allowed 40MHz and 80MHz channels
+in the 5.2GHz band.  The firmware has been modified to not allow this
+in those SKUs, so the driver needs to do the same otherwise the
+firmware will assert when we try to use it.
+
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c |   66 +++++++++++++++++----
+ 1 file changed, 55 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+@@ -78,6 +78,7 @@
+ /* NVM offsets (in words) definitions */
+ enum wkp_nvm_offsets {
+       /* NVM HW-Section offset (in words) definitions */
++      SUBSYSTEM_ID = 0x0A,
+       HW_ADDR = 0x15,
+       /* NVM SW-Section offset (in words) definitions */
+@@ -262,13 +263,12 @@ static u32 iwl_get_channel_flags(u8 ch_n
+ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
+                               struct iwl_nvm_data *data,
+                               const __le16 * const nvm_ch_flags,
+-                              bool lar_supported)
++                              bool lar_supported, bool no_wide_in_5ghz)
+ {
+       int ch_idx;
+       int n_channels = 0;
+       struct ieee80211_channel *channel;
+       u16 ch_flags;
+-      bool is_5ghz;
+       int num_of_ch, num_2ghz_channels;
+       const u8 *nvm_chan;
+@@ -283,12 +283,20 @@ static int iwl_init_channel_map(struct d
+       }
+       for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
++              bool is_5ghz = (ch_idx >= num_2ghz_channels);
++
+               ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
+-              if (ch_idx >= num_2ghz_channels &&
+-                  !data->sku_cap_band_52GHz_enable)
++              if (is_5ghz && !data->sku_cap_band_52GHz_enable)
+                       continue;
++              /* workaround to disable wide channels in 5GHz */
++              if (no_wide_in_5ghz && is_5ghz) {
++                      ch_flags &= ~(NVM_CHANNEL_40MHZ |
++                                   NVM_CHANNEL_80MHZ |
++                                   NVM_CHANNEL_160MHZ);
++              }
++
+               if (ch_flags & NVM_CHANNEL_160MHZ)
+                       data->vht160_supported = true;
+@@ -311,8 +319,8 @@ static int iwl_init_channel_map(struct d
+               n_channels++;
+               channel->hw_value = nvm_chan[ch_idx];
+-              channel->band = (ch_idx < num_2ghz_channels) ?
+-                              NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
++              channel->band = is_5ghz ?
++                              NL80211_BAND_5GHZ : NL80211_BAND_2GHZ;
+               channel->center_freq =
+                       ieee80211_channel_to_frequency(
+                               channel->hw_value, channel->band);
+@@ -324,7 +332,6 @@ static int iwl_init_channel_map(struct d
+                * is not used in mvm, and is used for backwards compatibility
+                */
+               channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
+-              is_5ghz = channel->band == NL80211_BAND_5GHZ;
+               /* don't put limitations in case we're using LAR */
+               if (!lar_supported)
+@@ -441,7 +448,8 @@ static void iwl_init_vht_hw_capab(const
+ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
+                           struct iwl_nvm_data *data,
+                           const __le16 *ch_section,
+-                          u8 tx_chains, u8 rx_chains, bool lar_supported)
++                          u8 tx_chains, u8 rx_chains, bool lar_supported,
++                          bool no_wide_in_5ghz)
+ {
+       int n_channels;
+       int n_used = 0;
+@@ -450,12 +458,14 @@ static void iwl_init_sbands(struct devic
+       if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
+               n_channels = iwl_init_channel_map(
+                               dev, cfg, data,
+-                              &ch_section[NVM_CHANNELS], lar_supported);
++                              &ch_section[NVM_CHANNELS], lar_supported,
++                              no_wide_in_5ghz);
+       else
+               n_channels = iwl_init_channel_map(
+                               dev, cfg, data,
+                               &ch_section[NVM_CHANNELS_FAMILY_8000],
+-                              lar_supported);
++                              lar_supported,
++                              no_wide_in_5ghz);
+       sband = &data->bands[NL80211_BAND_2GHZ];
+       sband->band = NL80211_BAND_2GHZ;
+@@ -658,6 +668,39 @@ static int iwl_set_hw_address(struct iwl
+       return 0;
+ }
++static bool
++iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
++                      const __le16 *nvm_hw)
++{
++      /*
++       * Workaround a bug in Indonesia SKUs where the regulatory in
++       * some 7000-family OTPs erroneously allow wide channels in
++       * 5GHz.  To check for Indonesia, we take the SKU value from
++       * bits 1-4 in the subsystem ID and check if it is either 5 or
++       * 9.  In those cases, we need to force-disable wide channels
++       * in 5GHz otherwise the FW will throw a sysassert when we try
++       * to use them.
++       */
++      if (cfg->device_family == IWL_DEVICE_FAMILY_7000) {
++              /*
++               * Unlike the other sections in the NVM, the hw
++               * section uses big-endian.
++               */
++              u16 subsystem_id = be16_to_cpup((const __be16 *)nvm_hw
++                                              + SUBSYSTEM_ID);
++              u8 sku = (subsystem_id & 0x1e) >> 1;
++
++              if (sku == 5 || sku == 9) {
++                      IWL_DEBUG_EEPROM(dev,
++                                       "disabling wide channels in 5GHz (0x%0x %d)\n",
++                                       subsystem_id, sku);
++                      return true;
++              }
++      }
++
++      return false;
++}
++
+ struct iwl_nvm_data *
+ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
+                  const __le16 *nvm_hw, const __le16 *nvm_sw,
+@@ -668,6 +711,7 @@ iwl_parse_nvm_data(struct iwl_trans *tra
+       struct device *dev = trans->dev;
+       struct iwl_nvm_data *data;
+       bool lar_enabled;
++      bool no_wide_in_5ghz = iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw);
+       u32 sku, radio_cfg;
+       u16 lar_config;
+       const __le16 *ch_section;
+@@ -738,7 +782,7 @@ iwl_parse_nvm_data(struct iwl_trans *tra
+       }
+       iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
+-                      lar_fw_supported && lar_enabled);
++                      lar_fw_supported && lar_enabled, no_wide_in_5ghz);
+       data->calib_version = 255;
+       return data;
diff --git a/queue-4.9/iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch b/queue-4.9/iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch
new file mode 100644 (file)
index 0000000..f1fb2fb
--- /dev/null
@@ -0,0 +1,51 @@
+From 97bce57bd7f96e1218751996f549a6e61f18cc8c Mon Sep 17 00:00:00 2001
+From: Luca Coelho <luciano.coelho@intel.com>
+Date: Fri, 1 Sep 2017 17:59:15 +0300
+Subject: iwlwifi: mvm: use IWL_HCMD_NOCOPY for MCAST_FILTER_CMD
+
+From: Luca Coelho <luciano.coelho@intel.com>
+
+commit 97bce57bd7f96e1218751996f549a6e61f18cc8c upstream.
+
+The MCAST_FILTER_CMD can get quite large when we have many mcast
+addresses to set (we support up to 255).  So the command should be
+send as NOCOPY to prevent a warning caused by too-long commands:
+
+WARNING: CPU: 0 PID: 9700 at /root/iwlwifi/stack-dev/drivers/net/wireless/intel/iwlwifi/pcie/tx.c:1550 iwl_pcie_enqueue_hcmd+0x8c7/0xb40 [iwlwifi]
+Command MCAST_FILTER_CMD (0x1d0) is too large (328 bytes)
+
+This fixes: https://bugzilla.kernel.org/show_bug.cgi?id=196743
+
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -1548,6 +1548,11 @@ static void iwl_mvm_mc_iface_iterator(vo
+       struct iwl_mvm_mc_iter_data *data = _data;
+       struct iwl_mvm *mvm = data->mvm;
+       struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd;
++      struct iwl_host_cmd hcmd = {
++              .id = MCAST_FILTER_CMD,
++              .flags = CMD_ASYNC,
++              .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
++      };
+       int ret, len;
+       /* if we don't have free ports, mcast frames will be dropped */
+@@ -1562,7 +1567,10 @@ static void iwl_mvm_mc_iface_iterator(vo
+       memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
+       len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);
+-      ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd);
++      hcmd.len[0] = len;
++      hcmd.data[0] = cmd;
++
++      ret = iwl_mvm_send_cmd(mvm, &hcmd);
+       if (ret)
+               IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
+ }
diff --git a/queue-4.9/scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch b/queue-4.9/scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch
new file mode 100644 (file)
index 0000000..54a5713
--- /dev/null
@@ -0,0 +1,70 @@
+From 77082ca503bed061f7fbda7cfd7c93beda967a41 Mon Sep 17 00:00:00 2001
+From: "Martin K. Petersen" <martin.petersen@oracle.com>
+Date: Wed, 27 Sep 2017 21:38:59 -0400
+Subject: scsi: sd: Do not override max_sectors_kb sysfs setting
+
+From: Martin K. Petersen <martin.petersen@oracle.com>
+
+commit 77082ca503bed061f7fbda7cfd7c93beda967a41 upstream.
+
+A user may lower the max_sectors_kb setting in sysfs to accommodate
+certain workloads. Previously we would always set the max I/O size to
+either the block layer default or the optional preferred I/O size
+reported by the device.
+
+Keep the current heuristics for the initial setting of max_sectors_kb.
+For subsequent invocations, only update the current queue limit if it
+exceeds the capabilities of the hardware.
+
+Reported-by: Don Brace <don.brace@microsemi.com>
+Reviewed-by: Martin Wilck <mwilck@suse.com>
+Tested-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sd.c |   19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -2867,8 +2867,6 @@ static int sd_revalidate_disk(struct gen
+               sd_read_write_same(sdkp, buffer);
+       }
+-      sdkp->first_scan = 0;
+-
+       /*
+        * We now have all cache related info, determine how we deal
+        * with flush requests.
+@@ -2883,7 +2881,7 @@ static int sd_revalidate_disk(struct gen
+       q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max);
+       /*
+-       * Use the device's preferred I/O size for reads and writes
++       * Determine the device's preferred I/O size for reads and writes
+        * unless the reported value is unreasonably small, large, or
+        * garbage.
+        */
+@@ -2897,8 +2895,19 @@ static int sd_revalidate_disk(struct gen
+               rw_max = min_not_zero(logical_to_sectors(sdp, dev_max),
+                                     (sector_t)BLK_DEF_MAX_SECTORS);
+-      /* Combine with controller limits */
+-      q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q));
++      /* Do not exceed controller limit */
++      rw_max = min(rw_max, queue_max_hw_sectors(q));
++
++      /*
++       * Only update max_sectors if previously unset or if the current value
++       * exceeds the capabilities of the hardware.
++       */
++      if (sdkp->first_scan ||
++          q->limits.max_sectors > q->limits.max_dev_sectors ||
++          q->limits.max_sectors > q->limits.max_hw_sectors)
++              q->limits.max_sectors = rw_max;
++
++      sdkp->first_scan = 0;
+       set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity));
+       sd_config_write_same(sdkp);
index 4d6d141fdbb6959d523d1a7e5ac7f44641018fe0..6e693f9b57c41abf1e5ec1638ff6c83d5886dd98 100644 (file)
@@ -90,3 +90,7 @@ hid-wacom-always-increment-hdev-refcount-within-wacom_get_hdev_data.patch
 hid-wacom-bits-shifted-too-much-for-9th-and-10th-buttons.patch
 rocker-fix-rocker_tlv_put_-functions-for-kasan.patch
 netlink-fix-nla_put_-u8-u16-u32-for-kasan.patch
+iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch
+iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch
+scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch
+dm-ioctl-fix-alignment-of-event-number-in-the-device-list.patch