aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_lib.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2011-01-18 04:13:11 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-02-12 11:33:08 -0500
commit63583cca745f440167bf27877182dc13e19d4bcf (patch)
treec1eb3ec5d35cd71c6373e82992710c91f2cb8bdd /drivers/scsi/scsi_lib.c
parent7a1e9d829f8bd821466c5ea834ad6f378740d2be (diff)
[SCSI] Add detailed SCSI I/O errors
Instead of just passing 'EIO' for any I/O error we should be notifying the upper layers with more details about the cause of this error. Update the possible I/O errors to: - ENOLINK: Link failure between host and target - EIO: Retryable I/O error - EREMOTEIO: Non-retryable I/O error - EBADE: I/O error restricted to the I_T_L nexus 'Retryable' in this context means that an I/O error _might_ be restricted to the I_T_L nexus (vulgo: path), so retrying on another nexus / path might succeed. 'Non-retryable' in general refers to a target failure, so this error will always be generated regardless of the I_T_L nexus it was send on. I/O errors restricted to the I_T_L nexus might be retried on another nexus / path, but they should _not_ be queued if no paths are available. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r--drivers/scsi/scsi_lib.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 9045c52abd25..8d4ef8efa3cd 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -667,6 +667,30 @@ void scsi_release_buffers(struct scsi_cmnd *cmd)
667} 667}
668EXPORT_SYMBOL(scsi_release_buffers); 668EXPORT_SYMBOL(scsi_release_buffers);
669 669
670static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)
671{
672 int error = 0;
673
674 switch(host_byte(result)) {
675 case DID_TRANSPORT_FAILFAST:
676 error = -ENOLINK;
677 break;
678 case DID_TARGET_FAILURE:
679 cmd->result |= (DID_OK << 16);
680 error = -EREMOTEIO;
681 break;
682 case DID_NEXUS_FAILURE:
683 cmd->result |= (DID_OK << 16);
684 error = -EBADE;
685 break;
686 default:
687 error = -EIO;
688 break;
689 }
690
691 return error;
692}
693
670/* 694/*
671 * Function: scsi_io_completion() 695 * Function: scsi_io_completion()
672 * 696 *
@@ -737,7 +761,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
737 req->sense_len = len; 761 req->sense_len = len;
738 } 762 }
739 if (!sense_deferred) 763 if (!sense_deferred)
740 error = -EIO; 764 error = __scsi_error_from_host_byte(cmd, result);
741 } 765 }
742 766
743 req->resid_len = scsi_get_resid(cmd); 767 req->resid_len = scsi_get_resid(cmd);
@@ -796,7 +820,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
796 if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL) 820 if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL)
797 return; 821 return;
798 822
799 error = -EIO; 823 error = __scsi_error_from_host_byte(cmd, result);
800 824
801 if (host_byte(result) == DID_RESET) { 825 if (host_byte(result) == DID_RESET) {
802 /* Third party bus reset or reset for error recovery 826 /* Third party bus reset or reset for error recovery