linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Handle errors during transitions to sleep states in sd
@ 2012-08-03 12:27 Oliver Neukum
  2012-08-03 12:27 ` [PATCH 1/5] sd: SCSI error codes must not be returned to generic code Oliver Neukum
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Oliver Neukum @ 2012-08-03 12:27 UTC (permalink / raw)
  To: JBottomley, linux-scsi, hare

During transition to sleep sd can encounter errors. They must be translated
to a form the generic layer understands, so that it knows whether an error
can be ignored (eg. medium removal) should be retried (eg. BUSY)
or the transition must be aborted.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] sd: SCSI error codes must not be returned to generic code
  2012-08-03 12:27 Handle errors during transitions to sleep states in sd Oliver Neukum
@ 2012-08-03 12:27 ` Oliver Neukum
  2012-08-03 12:27 ` [PATCH 2/5] sd: handle errors in sd_start_stop_device() Oliver Neukum
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Oliver Neukum @ 2012-08-03 12:27 UTC (permalink / raw)
  To: JBottomley, linux-scsi, hare; +Cc: Oliver Neukum, Oliver Neukum

sd_start_stop_device leaks SCSI specific error codes
to the generic driver code

Signed-off-by: Oliver Neukum <oneukum@suse.de>
---
 drivers/scsi/sd.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 4df73e5..cef06f5 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2830,7 +2830,11 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
 			sd_print_sense_hdr(sdkp, &sshdr);
 	}
 
-	return res;
+	/* SCSI error codes must not go to the generic layer */
+	if (res)
+		return -EIO;
+
+	return 0;
 }
 
 /*
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/5] sd: handle errors in sd_start_stop_device()
  2012-08-03 12:27 Handle errors during transitions to sleep states in sd Oliver Neukum
  2012-08-03 12:27 ` [PATCH 1/5] sd: SCSI error codes must not be returned to generic code Oliver Neukum
@ 2012-08-03 12:27 ` Oliver Neukum
  2012-08-03 12:27 ` [PATCH 3/5] sd: deal with removal of medium to be synched Oliver Neukum
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Oliver Neukum @ 2012-08-03 12:27 UTC (permalink / raw)
  To: JBottomley, linux-scsi, hare; +Cc: Oliver Neukum

Errors are not handled correctly in sd_start_stop_device().

First, if a device cannot be stopped because a medium has been
removed, this is not an error. This fixes a bug when suspending
the system right after pulling a medium out of a card reader.

Second, if the full system is to be suspended, a failure to stop
a device is not a good reason to abort a suspend, as that won't
improve matters.

Signed-of-by: Oliver Neukum <oneukum@suse.de>
---
 drivers/scsi/sd.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index cef06f5..a344220 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2828,6 +2828,10 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
 		sd_print_result(sdkp, res);
 		if (driver_byte(res) & DRIVER_SENSE)
 			sd_print_sense_hdr(sdkp, &sshdr);
+		if ((scsi_sense_valid(&sshdr) &&
+			/* 0x3a is medium not present */
+			sshdr.asc == 0x3a))
+			res = 0;
 	}
 
 	/* SCSI error codes must not go to the generic layer */
@@ -2884,6 +2888,10 @@ static int sd_suspend(struct device *dev, pm_message_t mesg)
 	if ((mesg.event & PM_EVENT_SLEEP) && sdkp->device->manage_start_stop) {
 		sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
 		ret = sd_start_stop_device(sdkp, 0);
+
+		/* an error is not worth aborting a system sleep */
+		if (!(mesg.event & PM_EVENT_AUTO))
+			ret = 0;
 	}
 
 done:
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/5] sd: deal with removal of medium to be synched
  2012-08-03 12:27 Handle errors during transitions to sleep states in sd Oliver Neukum
  2012-08-03 12:27 ` [PATCH 1/5] sd: SCSI error codes must not be returned to generic code Oliver Neukum
  2012-08-03 12:27 ` [PATCH 2/5] sd: handle errors in sd_start_stop_device() Oliver Neukum
@ 2012-08-03 12:27 ` Oliver Neukum
  2012-08-03 12:27 ` [PATCH 4/5] scsi: translate errors for power management Oliver Neukum
  2012-08-03 12:27 ` [PATCH 5/5] scsi: more error conditions " Oliver Neukum
  4 siblings, 0 replies; 6+ messages in thread
From: Oliver Neukum @ 2012-08-03 12:27 UTC (permalink / raw)
  To: JBottomley, linux-scsi, hare; +Cc: Oliver Neukum, Oliver Neukum

sd_sync_cache() is called for purposes of power management.
Under those circumstances a medium removal is no error.
The data is lost under any circumstances, so the system may as
well sleep.

Signed-off-by: Oliver Neukum <oneukum@suse.de>
---
 drivers/scsi/sd.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index a344220..c39a97e 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1278,8 +1278,16 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
 
 	if (res) {
 		sd_print_result(sdkp, res);
+
 		if (driver_byte(res) & DRIVER_SENSE)
 			sd_print_sense_hdr(sdkp, &sshdr);
+		/*
+		 * we need to evaluate the error return
+		 * 0x3a is medium not present
+		 * this is no error here
+		 */
+		if ((scsi_sense_valid(&sshdr) && sshdr.asc == 0x3a))
+			return 0;
 	}
 
 	if (res)
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/5] scsi: translate errors for power management
  2012-08-03 12:27 Handle errors during transitions to sleep states in sd Oliver Neukum
                   ` (2 preceding siblings ...)
  2012-08-03 12:27 ` [PATCH 3/5] sd: deal with removal of medium to be synched Oliver Neukum
@ 2012-08-03 12:27 ` Oliver Neukum
  2012-08-03 12:27 ` [PATCH 5/5] scsi: more error conditions " Oliver Neukum
  4 siblings, 0 replies; 6+ messages in thread
From: Oliver Neukum @ 2012-08-03 12:27 UTC (permalink / raw)
  To: JBottomley, linux-scsi, hare; +Cc: Oliver Neukum, Oliver Neukum

Synchronizing caches may fail. The reason for these
failures need to be translated to the generic layer
so that it nows whether to ignore a failure, retry later
or give up, aborting sleep.

Signed-off-by: Oliver Neukum <oneukum@suse.de>
---
 drivers/scsi/scsi_error.c |   32 ++++++++++++++++++++++++++++++++
 drivers/scsi/sd.c         |    3 +--
 include/scsi/scsi_eh.h    |    1 +
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 4a6381c..195cc75 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -2217,3 +2217,35 @@ void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq)
 	}
 }
 EXPORT_SYMBOL(scsi_build_sense_buffer);
+
+/**
+ * scsi_translate_errors_to_power_management - errors in a form driver core understands
+ * @res:	Result of scsi command
+ *
+ * Return value:
+ * 	error code driver core understands
+ **/
+int scsi_translate_errors_to_power_management(int res)
+{
+	switch (host_byte(res)) {
+	/* ignore errors due to racing a disconnection */
+	case DID_BAD_TARGET:
+	case DID_NO_CONNECT:
+		return 0;
+	/* signal the upper layer it might try again */
+	case DID_BUS_BUSY:
+	case DID_IMM_RETRY:
+	case DID_REQUEUE:
+	case DID_SOFT_ERROR:
+	case DID_TIME_OUT:
+	case DID_ABORT:
+	case DID_RESET:
+	case DID_TRANSPORT_DISRUPTED:
+		return -EBUSY;
+	case DID_OK:
+		return 0;
+	default:
+		return -EIO;
+	}
+}
+EXPORT_SYMBOL(scsi_translate_errors_to_power_management);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index c39a97e..8597294 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1288,10 +1288,9 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
 		 */
 		if ((scsi_sense_valid(&sshdr) && sshdr.asc == 0x3a))
 			return 0;
+		return scsi_translate_errors_to_power_management(res);
 	}
 
-	if (res)
-		return -EIO;
 	return 0;
 }
 
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
index 06a8790..bdf6d6c 100644
--- a/include/scsi/scsi_eh.h
+++ b/include/scsi/scsi_eh.h
@@ -59,6 +59,7 @@ extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len,
 				   u64 * info_out);
 
 extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq);
+extern int scsi_translate_errors_to_power_management(int res);
 
 /*
  * Reset request from external source
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/5] scsi: more error conditions for power management
  2012-08-03 12:27 Handle errors during transitions to sleep states in sd Oliver Neukum
                   ` (3 preceding siblings ...)
  2012-08-03 12:27 ` [PATCH 4/5] scsi: translate errors for power management Oliver Neukum
@ 2012-08-03 12:27 ` Oliver Neukum
  4 siblings, 0 replies; 6+ messages in thread
From: Oliver Neukum @ 2012-08-03 12:27 UTC (permalink / raw)
  To: JBottomley, linux-scsi, hare; +Cc: Oliver Neukum, Oliver Neukum

BUSY and QUEUE_FULL are retryable errors.

Signed-off-by: Oliver Neukum <oneukum@suse.de>
---
 drivers/scsi/scsi_error.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 195cc75..2f70a07 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -2227,6 +2227,12 @@ EXPORT_SYMBOL(scsi_build_sense_buffer);
  **/
 int scsi_translate_errors_to_power_management(int res)
 {
+	switch (status_byte(res)) {
+	case BUSY:
+	case QUEUE_FULL:
+		return -EBUSY;
+	}
+
 	switch (host_byte(res)) {
 	/* ignore errors due to racing a disconnection */
 	case DID_BAD_TARGET:
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-08-03 12:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-03 12:27 Handle errors during transitions to sleep states in sd Oliver Neukum
2012-08-03 12:27 ` [PATCH 1/5] sd: SCSI error codes must not be returned to generic code Oliver Neukum
2012-08-03 12:27 ` [PATCH 2/5] sd: handle errors in sd_start_stop_device() Oliver Neukum
2012-08-03 12:27 ` [PATCH 3/5] sd: deal with removal of medium to be synched Oliver Neukum
2012-08-03 12:27 ` [PATCH 4/5] scsi: translate errors for power management Oliver Neukum
2012-08-03 12:27 ` [PATCH 5/5] scsi: more error conditions " Oliver Neukum

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).