summaryrefslogtreecommitdiff
path: root/drivers/scsi/bfa/bfad_im.c
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2010-03-05 19:38:27 -0800
committerJames Bottomley <James.Bottomley@suse.de>2010-03-07 13:12:38 +0530
commit95aa060decd2472d319c3f12b0b1b699a5f35058 (patch)
treec6167c5897c92dcee5c7c624d71b5be99057ee2d /drivers/scsi/bfa/bfad_im.c
parent25e2934c26f5efaea156c9fda4457d01a8bb44e1 (diff)
[SCSI] bfa: Handle SCSI IO underrun case.
When IO is completed with underrun and with good SCSI status, check if the transferred bytes against scsi_cmnd->underflow, which is set to minimum number of bytes that must be transferred for this command, if is less than required minimum, complete the IO with DID_ERROR. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/bfa/bfad_im.c')
-rw-r--r--drivers/scsi/bfa/bfad_im.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index cee3d89d1412..fb7aefaba129 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -43,11 +43,11 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
struct bfad_s *bfad = drv;
struct bfad_itnim_data_s *itnim_data;
struct bfad_itnim_s *itnim;
+ u8 host_status = DID_OK;
switch (io_status) {
case BFI_IOIM_STS_OK:
bfa_trc(bfad, scsi_status);
- cmnd->result = ScsiResult(DID_OK, scsi_status);
scsi_set_resid(cmnd, 0);
if (sns_len > 0) {
@@ -56,8 +56,18 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
sns_len = SCSI_SENSE_BUFFERSIZE;
memcpy(cmnd->sense_buffer, sns_info, sns_len);
}
- if (residue > 0)
+ if (residue > 0) {
+ bfa_trc(bfad, residue);
scsi_set_resid(cmnd, residue);
+ if (!sns_len && (scsi_status == SAM_STAT_GOOD) &&
+ (scsi_bufflen(cmnd) - residue) <
+ cmnd->underflow) {
+ bfa_trc(bfad, 0);
+ host_status = DID_ERROR;
+ }
+ }
+ cmnd->result = ScsiResult(host_status, scsi_status);
+
break;
case BFI_IOIM_STS_ABORTED: