[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>
This commit is contained in:
Krishna Gudipati 2010-03-05 19:38:27 -08:00 committed by James Bottomley
parent 25e2934c26
commit 95aa060dec

View File

@ -43,11 +43,11 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
struct bfad_s *bfad = drv; struct bfad_s *bfad = drv;
struct bfad_itnim_data_s *itnim_data; struct bfad_itnim_data_s *itnim_data;
struct bfad_itnim_s *itnim; struct bfad_itnim_s *itnim;
u8 host_status = DID_OK;
switch (io_status) { switch (io_status) {
case BFI_IOIM_STS_OK: case BFI_IOIM_STS_OK:
bfa_trc(bfad, scsi_status); bfa_trc(bfad, scsi_status);
cmnd->result = ScsiResult(DID_OK, scsi_status);
scsi_set_resid(cmnd, 0); scsi_set_resid(cmnd, 0);
if (sns_len > 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; sns_len = SCSI_SENSE_BUFFERSIZE;
memcpy(cmnd->sense_buffer, sns_info, sns_len); memcpy(cmnd->sense_buffer, sns_info, sns_len);
} }
if (residue > 0) if (residue > 0) {
bfa_trc(bfad, residue);
scsi_set_resid(cmnd, 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; break;
case BFI_IOIM_STS_ABORTED: case BFI_IOIM_STS_ABORTED: