@@ -4325,6 +4325,20 @@ static int ufshcd_update_preserves_write_order(struct ufs_hba *hba,
return -EPERM;
}
}
+ shost_for_each_device(sdev, hba->host)
+ blk_freeze_queue_start(sdev->request_queue);
+ shost_for_each_device(sdev, hba->host) {
+ struct request_queue *q = sdev->request_queue;
+
+ blk_mq_freeze_queue_wait(q);
+ q->limits.driver_preserves_write_order = preserves_write_order;
+ blk_queue_required_elevator_features(q,
+ !preserves_write_order && blk_queue_is_zoned(q) ?
+ ELEVATOR_F_ZBD_SEQ_WRITE : 0);
+ if (q->disk)
+ disk_set_zoned(q->disk, q->limits.zoned);
+ blk_mq_unfreeze_queue(q);
+ }
return 0;
}
@@ -4367,7 +4381,8 @@ int ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit)
if (!is_mcq_enabled(hba) && !prev_state && new_state) {
/*
- * Auto-hibernation will be enabled for legacy UFSHCI mode.
+ * Auto-hibernation will be enabled for legacy UFSHCI mode. Tell
+ * the block layer that write requests may be reordered.
*/
ret = ufshcd_update_preserves_write_order(hba, false);
if (ret)
@@ -4383,7 +4398,8 @@ int ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit)
}
if (!is_mcq_enabled(hba) && prev_state && !new_state) {
/*
- * Auto-hibernation has been disabled.
+ * Auto-hibernation has been disabled. Tell the block layer that
+ * the order of write requests is preserved.
*/
ret = ufshcd_update_preserves_write_order(hba, true);
WARN_ON_ONCE(ret);
@@ -5151,6 +5167,10 @@ static int ufshcd_slave_configure(struct scsi_device *sdev)
struct ufs_hba *hba = shost_priv(sdev->host);
struct request_queue *q = sdev->request_queue;
+ q->limits.driver_preserves_write_order =
+ !ufshcd_is_auto_hibern8_supported(hba) ||
+ FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, hba->ahit) == 0;
+
blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1);
if (hba->quirks & UFSHCD_QUIRK_4KB_DMA_ALIGNMENT)
blk_queue_update_dma_alignment(q, SZ_4K - 1);