summaryrefslogtreecommitdiff
path: root/drivers/scsi/libfc/fc_fcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libfc/fc_fcp.c')
-rw-r--r--drivers/scsi/libfc/fc_fcp.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 59a4408b27b5..7a144026b49b 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -302,10 +302,13 @@ static void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp)
if (!fsp)
return;
+ if (fsp->xfer_ddp == FC_XID_UNKNOWN)
+ return;
+
lp = fsp->lp;
- if (fsp->xfer_ddp && lp->tt.ddp_done) {
+ if (lp->tt.ddp_done) {
fsp->xfer_len = lp->tt.ddp_done(lp, fsp->xfer_ddp);
- fsp->xfer_ddp = 0;
+ fsp->xfer_ddp = FC_XID_UNKNOWN;
}
}
@@ -572,7 +575,8 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
tlen -= sg_bytes;
remaining -= sg_bytes;
- if (tlen)
+ if ((skb_shinfo(fp_skb(fp))->nr_frags < FC_FRAME_SG_LEN) &&
+ (tlen))
continue;
/*
@@ -1048,7 +1052,6 @@ static int fc_fcp_cmd_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
seq = lp->tt.exch_seq_send(lp, fp, resp, fc_fcp_pkt_destroy, fsp, 0);
if (!seq) {
- fc_frame_free(fp);
rc = -1;
goto unlock;
}
@@ -1313,7 +1316,6 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
fc_fcp_pkt_hold(fsp); /* hold while REC outstanding */
return;
}
- fc_frame_free(fp);
retry:
if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
@@ -1561,10 +1563,9 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
seq = lp->tt.exch_seq_send(lp, fp, fc_fcp_srr_resp, NULL,
fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
- if (!seq) {
- fc_frame_free(fp);
+ if (!seq)
goto retry;
- }
+
fsp->recov_seq = seq;
fsp->xfer_len = offset;
fsp->xfer_contig_end = offset;
@@ -1708,6 +1709,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
fsp->cmd = sc_cmd; /* save the cmd */
fsp->lp = lp; /* save the softc ptr */
fsp->rport = rport; /* set the remote port ptr */
+ fsp->xfer_ddp = FC_XID_UNKNOWN;
sc_cmd->scsi_done = done;
/*
@@ -1846,7 +1848,8 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
* scsi status is good but transport level
* underrun.
*/
- sc_cmd->result = DID_OK << 16;
+ sc_cmd->result = (fsp->state & FC_SRB_RCV_STATUS ?
+ DID_OK : DID_ERROR) << 16;
} else {
/*
* scsi got underrun, this is an error
@@ -2046,18 +2049,16 @@ EXPORT_SYMBOL(fc_eh_host_reset);
int fc_slave_alloc(struct scsi_device *sdev)
{
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
- int queue_depth;
if (!rport || fc_remote_port_chkready(rport))
return -ENXIO;
- if (sdev->tagged_supported) {
- if (sdev->host->hostt->cmd_per_lun)
- queue_depth = sdev->host->hostt->cmd_per_lun;
- else
- queue_depth = FC_FCP_DFLT_QUEUE_DEPTH;
- scsi_activate_tcq(sdev, queue_depth);
- }
+ if (sdev->tagged_supported)
+ scsi_activate_tcq(sdev, FC_FCP_DFLT_QUEUE_DEPTH);
+ else
+ scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev),
+ FC_FCP_DFLT_QUEUE_DEPTH);
+
return 0;
}
EXPORT_SYMBOL(fc_slave_alloc);