aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/storvsc_drv.c')
-rw-r--r--drivers/scsi/storvsc_drv.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 0f636cc4c809..cd5c1c060481 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -135,6 +135,8 @@ struct hv_fc_wwn_packet {
135#define SRB_FLAGS_PORT_DRIVER_RESERVED 0x0F000000 135#define SRB_FLAGS_PORT_DRIVER_RESERVED 0x0F000000
136#define SRB_FLAGS_CLASS_DRIVER_RESERVED 0xF0000000 136#define SRB_FLAGS_CLASS_DRIVER_RESERVED 0xF0000000
137 137
138#define SP_UNTAGGED ((unsigned char) ~0)
139#define SRB_SIMPLE_TAG_REQUEST 0x20
138 140
139/* 141/*
140 * Platform neutral description of a scsi request - 142 * Platform neutral description of a scsi request -
@@ -354,6 +356,7 @@ enum storvsc_request_type {
354#define SRB_STATUS_SUCCESS 0x01 356#define SRB_STATUS_SUCCESS 0x01
355#define SRB_STATUS_ABORTED 0x02 357#define SRB_STATUS_ABORTED 0x02
356#define SRB_STATUS_ERROR 0x04 358#define SRB_STATUS_ERROR 0x04
359#define SRB_STATUS_DATA_OVERRUN 0x12
357 360
358#define SRB_STATUS(status) \ 361#define SRB_STATUS(status) \
359 (status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN)) 362 (status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
@@ -864,6 +867,13 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
864 switch (SRB_STATUS(vm_srb->srb_status)) { 867 switch (SRB_STATUS(vm_srb->srb_status)) {
865 case SRB_STATUS_ERROR: 868 case SRB_STATUS_ERROR:
866 /* 869 /*
870 * Let upper layer deal with error when
871 * sense message is present.
872 */
873
874 if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)
875 break;
876 /*
867 * If there is an error; offline the device since all 877 * If there is an error; offline the device since all
868 * error recovery strategies would have already been 878 * error recovery strategies would have already been
869 * deployed on the host side. However, if the command 879 * deployed on the host side. However, if the command
@@ -927,6 +937,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
927 struct hv_host_device *host_dev = shost_priv(scmnd->device->host); 937 struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
928 struct scsi_sense_hdr sense_hdr; 938 struct scsi_sense_hdr sense_hdr;
929 struct vmscsi_request *vm_srb; 939 struct vmscsi_request *vm_srb;
940 u32 data_transfer_length;
930 struct Scsi_Host *host; 941 struct Scsi_Host *host;
931 struct storvsc_device *stor_dev; 942 struct storvsc_device *stor_dev;
932 struct hv_device *dev = host_dev->dev; 943 struct hv_device *dev = host_dev->dev;
@@ -937,6 +948,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
937 host = stor_dev->host; 948 host = stor_dev->host;
938 949
939 vm_srb = &cmd_request->vstor_packet.vm_srb; 950 vm_srb = &cmd_request->vstor_packet.vm_srb;
951 data_transfer_length = vm_srb->data_transfer_length;
940 952
941 scmnd->result = vm_srb->scsi_status; 953 scmnd->result = vm_srb->scsi_status;
942 954
@@ -947,13 +959,20 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
947 &sense_hdr); 959 &sense_hdr);
948 } 960 }
949 961
950 if (vm_srb->srb_status != SRB_STATUS_SUCCESS) 962 if (vm_srb->srb_status != SRB_STATUS_SUCCESS) {
951 storvsc_handle_error(vm_srb, scmnd, host, sense_hdr.asc, 963 storvsc_handle_error(vm_srb, scmnd, host, sense_hdr.asc,
952 sense_hdr.ascq); 964 sense_hdr.ascq);
965 /*
966 * The Windows driver set data_transfer_length on
967 * SRB_STATUS_DATA_OVERRUN. On other errors, this value
968 * is untouched. In these cases we set it to 0.
969 */
970 if (vm_srb->srb_status != SRB_STATUS_DATA_OVERRUN)
971 data_transfer_length = 0;
972 }
953 973
954 scsi_set_resid(scmnd, 974 scsi_set_resid(scmnd,
955 cmd_request->payload->range.len - 975 cmd_request->payload->range.len - data_transfer_length);
956 vm_srb->data_transfer_length);
957 976
958 scmnd->scsi_done(scmnd); 977 scmnd->scsi_done(scmnd);
959 978
@@ -1409,6 +1428,13 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
1409 vm_srb->win8_extension.srb_flags |= 1428 vm_srb->win8_extension.srb_flags |=
1410 SRB_FLAGS_DISABLE_SYNCH_TRANSFER; 1429 SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
1411 1430
1431 if (scmnd->device->tagged_supported) {
1432 vm_srb->win8_extension.srb_flags |=
1433 (SRB_FLAGS_QUEUE_ACTION_ENABLE | SRB_FLAGS_NO_QUEUE_FREEZE);
1434 vm_srb->win8_extension.queue_tag = SP_UNTAGGED;
1435 vm_srb->win8_extension.queue_action = SRB_SIMPLE_TAG_REQUEST;
1436 }
1437
1412 /* Build the SRB */ 1438 /* Build the SRB */
1413 switch (scmnd->sc_data_direction) { 1439 switch (scmnd->sc_data_direction) {
1414 case DMA_TO_DEVICE: 1440 case DMA_TO_DEVICE: