X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=drivers%2Fscsi%2Flibfc%2Ffc_fcp.c;h=a67f53a5026c9fe1eba9cd958c85b236d46370b3;hb=8f550f937e9fdafa5c37e348e214aecec851ef3f;hp=59a4408b27b5b4d4bd3eb248e66442a9c7c98ba7;hpb=7cce2f4cb7f5f641f78c8e3eea4e7b1b96cb71c0;p=linux-2.6-block.git diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 59a4408b27b5..a67f53a5026c 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -285,7 +285,6 @@ void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid) fsp->xfer_ddp = xid; } } -EXPORT_SYMBOL(fc_fcp_ddp_setup); /* * fc_fcp_ddp_done - calls to LLD's ddp_done to release any @@ -302,10 +301,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 +574,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 +1051,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; } @@ -1095,7 +1097,7 @@ unlock: * Scsi abort handler- calls to send an abort * and then wait for abort completion */ -static int fc_fcp_pkt_abort(struct fc_lport *lp, struct fc_fcp_pkt *fsp) +static int fc_fcp_pkt_abort(struct fc_fcp_pkt *fsp) { int rc = FAILED; @@ -1313,7 +1315,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 +1562,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 +1708,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 +1847,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 @@ -1942,7 +1944,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd) goto release_pkt; } - rc = fc_fcp_pkt_abort(lp, fsp); + rc = fc_fcp_pkt_abort(fsp); fc_fcp_unlock_pkt(fsp); release_pkt: