[SCSI] bfa: Handle SCSI IO underrun case.
authorKrishna Gudipati <kgudipat@brocade.com>
Sat, 6 Mar 2010 03:38:27 +0000 (19:38 -0800)
committerJames Bottomley <James.Bottomley@suse.de>
Sun, 7 Mar 2010 07:42:38 +0000 (13:12 +0530)
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>
drivers/scsi/bfa/bfad_im.c

index cee3d89d14127454771cc304d70709c9e25f081d..fb7aefaba129102628f7ce3dcfd5d5f42483c08a 100644 (file)
@@ -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: