]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/scsi/scsi_lib.c
Merge tag 'mfd-fixes-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
[karo-tx-linux.git] / drivers / scsi / scsi_lib.c
index 448ebdaa3d694758dd899b1c06ce379d0676898a..126a48c6431e5a5d9798aed3472916b06ef476c8 100644 (file)
@@ -31,6 +31,7 @@
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_dh.h>
 
 #include <trace/events/scsi.h>
 
@@ -1248,9 +1249,8 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
 {
        struct scsi_cmnd *cmd = req->special;
 
-       if (unlikely(sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh
-                        && sdev->scsi_dh_data->scsi_dh->prep_fn)) {
-               int ret = sdev->scsi_dh_data->scsi_dh->prep_fn(sdev, req);
+       if (unlikely(sdev->handler && sdev->handler->prep_fn)) {
+               int ret = sdev->handler->prep_fn(sdev, req);
                if (ret != BLKPREP_OK)
                        return ret;
        }
@@ -1957,7 +1957,7 @@ static int scsi_mq_prep_fn(struct request *req)
 static void scsi_mq_done(struct scsi_cmnd *cmd)
 {
        trace_scsi_dispatch_cmd_done(cmd);
-       blk_mq_complete_request(cmd->request);
+       blk_mq_complete_request(cmd->request, cmd->request->errors);
 }
 
 static int scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
@@ -2423,7 +2423,7 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
        unsigned char cmd[12];
        int use_10_for_ms;
        int header_length;
-       int result;
+       int result, retry_count = retries;
        struct scsi_sense_hdr my_sshdr;
 
        memset(data, 0, sizeof(*data));
@@ -2502,6 +2502,11 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
                        data->block_descriptor_length = buffer[3];
                }
                data->header_length = header_length;
+       } else if ((status_byte(result) == CHECK_CONDITION) &&
+                  scsi_sense_valid(sshdr) &&
+                  sshdr->sense_key == UNIT_ATTENTION && retry_count) {
+               retry_count--;
+               goto retry;
        }
 
        return result;
@@ -2707,6 +2712,9 @@ static void scsi_evt_emit(struct scsi_device *sdev, struct scsi_event *evt)
        case SDEV_EVT_LUN_CHANGE_REPORTED:
                envp[idx++] = "SDEV_UA=REPORTED_LUNS_DATA_HAS_CHANGED";
                break;
+       case SDEV_EVT_ALUA_STATE_CHANGE_REPORTED:
+               envp[idx++] = "SDEV_UA=ASYMMETRIC_ACCESS_STATE_CHANGED";
+               break;
        default:
                /* do nothing */
                break;
@@ -2810,6 +2818,7 @@ struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type,
        case SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED:
        case SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED:
        case SDEV_EVT_LUN_CHANGE_REPORTED:
+       case SDEV_EVT_ALUA_STATE_CHANGE_REPORTED:
        default:
                /* do nothing */
                break;