@@ -1366,6 +1366,7 @@ scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
ret = BLKPREP_DEFER;
break;
case SDEV_SUSPENDED:
+ case SDEV_QUIESCED_SUSPENDED:
/* Process RQF_PM requests only. */
if (!(req->rq_flags & RQF_PM))
ret = BLKPREP_DEFER;
@@ -2683,6 +2684,17 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
break;
case SDEV_QUIESCE:
+ switch (oldstate) {
+ case SDEV_RUNNING:
+ case SDEV_QUIESCED_SUSPENDED:
+ case SDEV_OFFLINE:
+ case SDEV_TRANSPORT_OFFLINE:
+ break;
+ default:
+ goto illegal;
+ }
+ break;
+
case SDEV_SUSPENDED:
switch (oldstate) {
case SDEV_RUNNING:
@@ -2694,6 +2706,15 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
}
break;
+ case SDEV_QUIESCED_SUSPENDED:
+ switch (oldstate) {
+ case SDEV_QUIESCE:
+ break;
+ default:
+ goto illegal;
+ }
+ break;
+
case SDEV_OFFLINE:
case SDEV_TRANSPORT_OFFLINE:
switch (oldstate) {
@@ -2994,8 +3015,13 @@ scsi_device_suspend(struct scsi_device *sdev)
struct request_queue *q = sdev->request_queue;
int err;
- if (sdev->sdev_state == SDEV_SUSPENDED)
+ switch (sdev->sdev_state) {
+ case SDEV_SUSPENDED:
+ case SDEV_QUIESCED_SUSPENDED:
return 0;
+ default:
+ break;
+ }
blk_set_pm_only(q);
@@ -3011,6 +3037,8 @@ scsi_device_suspend(struct scsi_device *sdev)
mutex_lock(&sdev->state_mutex);
err = scsi_device_set_state(sdev, SDEV_SUSPENDED);
+ if (err)
+ err = scsi_device_set_state(sdev, SDEV_QUIESCED_SUSPENDED);
if (err)
blk_clear_pm_only(q);
mutex_unlock(&sdev->state_mutex);
@@ -3031,8 +3059,13 @@ void scsi_device_unsuspend(struct scsi_device *sdev)
{
mutex_lock(&sdev->state_mutex);
blk_clear_pm_only(sdev->request_queue);
- if (sdev->sdev_state == SDEV_SUSPENDED)
+ switch (sdev->sdev_state) {
+ case SDEV_SUSPENDED:
+ case SDEV_QUIESCED_SUSPENDED:
scsi_device_set_state(sdev, SDEV_RUNNING);
+ default:
+ break;
+ }
mutex_unlock(&sdev->state_mutex);
}
EXPORT_SYMBOL(scsi_device_unsuspend);
@@ -37,6 +37,7 @@ static const struct {
{ SDEV_DEL, "deleted" },
{ SDEV_QUIESCE, "quiesce" },
{ SDEV_SUSPENDED, "suspended" },
+ { SDEV_QUIESCED_SUSPENDED, "quiesced-suspended" },
{ SDEV_OFFLINE, "offline" },
{ SDEV_TRANSPORT_OFFLINE, "transport-offline" },
{ SDEV_BLOCK, "blocked" },
@@ -26,7 +26,6 @@
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
-#include <linux/suspend.h>
#include <scsi/scsi.h>
#include "scsi_priv.h"
#include <scsi/scsi_device.h>
@@ -1008,19 +1007,11 @@ spi_dv_device(struct scsi_device *sdev)
u8 *buffer;
const int len = SPI_MAX_ECHO_BUFFER_SIZE*2;
- /*
- * Because this function and the power management code both call
- * scsi_device_quiesce(), it is not safe to perform domain validation
- * while suspend or resume is in progress. Hence the
- * lock/unlock_system_sleep() calls.
- */
- lock_system_sleep();
-
if (unlikely(starget->spi_dv_context))
- goto unlock;
+ return;
if (unlikely(scsi_device_get(sdev)))
- goto unlock;
+ return;
buffer = kzalloc(len, GFP_KERNEL);
@@ -1056,8 +1047,6 @@ spi_dv_device(struct scsi_device *sdev)
kfree(buffer);
out_put:
scsi_device_put(sdev);
-unlock:
- unlock_system_sleep();
}
EXPORT_SYMBOL(spi_dv_device);
@@ -44,6 +44,7 @@ enum scsi_device_state {
* no commands allowed */
SDEV_QUIESCE, /* Only RQF_DV requests are accepted. */
SDEV_SUSPENDED, /* Only RQF_PM requests are accepted. */
+ SDEV_QUIESCED_SUSPENDED,/* Only RQF_PM requests are accepted. */
SDEV_OFFLINE, /* Device offlined (by error handling or
* user request */
SDEV_TRANSPORT_OFFLINE, /* Offlined by transport class error handler */
Now that SCSI power management and SPI domain validation use different mechanisms for blocking SCSI command execution, remove the mechanism again that prevents system suspend during SPI domain validation. This patch reverts 203f8c250e21 ("block, scsi: Fix race between SPI domain validation and system suspend"). Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com> Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: Woody Suwalski <terraluna977@gmail.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Ming Lei <ming.lei@redhat.com> Cc: Jianchao Wang <jianchao.w.wang@oracle.com> Cc: Hannes Reinecke <hare@suse.com> Cc: Johannes Thumshirn <jthumshirn@suse.de> Cc: Alan Stern <stern@rowland.harvard.edu> --- drivers/scsi/scsi_lib.c | 37 +++++++++++++++++++++++++++++-- drivers/scsi/scsi_sysfs.c | 1 + drivers/scsi/scsi_transport_spi.c | 15 ++----------- include/scsi/scsi_device.h | 1 + 4 files changed, 39 insertions(+), 15 deletions(-)