aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2010-07-20 18:21:01 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-28 10:06:00 -0400
commit24f089e2f2c800f88039e9d536d558ec6e349fad (patch)
tree59cf263f112e176015a3a37c3928cc3d2a4dfcb5
parent251748a99e631a2c46edcf9e519cfc60fae8153d (diff)
[SCSI] libfc: add fc_fill_reply_hdr() and fc_fill_hdr()
Add functions to fill in an FC header given a request header. These reduces code lines in fc_lport and fc_rport and works without an exchange/sequence assigned. fc_fill_reply_hdr() fills a header for a final reply frame. fc_fill_hdr() which is similar but allows specifying the f_ctl parameter. Add defines for F_CTL values FC_FCTL_REQ and FC_FCTL_RESP. These can be used for most request and response sequences. v2 of patch adds a line to copy the frame encapsulation info from the received frame. Signed-off-by: Joe Eykholt <jeykholt@cisco.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/libfc/fc_elsct.c2
-rw-r--r--drivers/scsi/libfc/fc_fcp.c6
-rw-r--r--drivers/scsi/libfc/fc_libfc.c78
-rw-r--r--drivers/scsi/libfc/fc_lport.c39
-rw-r--r--drivers/scsi/libfc/fc_rport.c64
-rw-r--r--include/scsi/fc_encode.h7
-rw-r--r--include/scsi/libfc.h4
7 files changed, 121 insertions, 79 deletions
diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c
index e9412b710fab..9b25969e2ad0 100644
--- a/drivers/scsi/libfc/fc_elsct.c
+++ b/drivers/scsi/libfc/fc_elsct.c
@@ -64,7 +64,7 @@ struct fc_seq *fc_elsct_send(struct fc_lport *lport, u32 did,
64 } 64 }
65 65
66 fc_fill_fc_hdr(fp, r_ctl, did, lport->port_id, fh_type, 66 fc_fill_fc_hdr(fp, r_ctl, did, lport->port_id, fh_type,
67 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 67 FC_FCTL_REQ, 0);
68 68
69 return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec); 69 return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec);
70} 70}
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 61a12970bd14..eac4d09314eb 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -1108,7 +1108,7 @@ static int fc_fcp_cmd_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
1108 1108
1109 fc_fill_fc_hdr(fp, FC_RCTL_DD_UNSOL_CMD, rport->port_id, 1109 fc_fill_fc_hdr(fp, FC_RCTL_DD_UNSOL_CMD, rport->port_id,
1110 rpriv->local_port->port_id, FC_TYPE_FCP, 1110 rpriv->local_port->port_id, FC_TYPE_FCP,
1111 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 1111 FC_FCTL_REQ, 0);
1112 1112
1113 seq = lport->tt.exch_seq_send(lport, fp, resp, fc_fcp_pkt_destroy, 1113 seq = lport->tt.exch_seq_send(lport, fp, resp, fc_fcp_pkt_destroy,
1114 fsp, 0); 1114 fsp, 0);
@@ -1381,7 +1381,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
1381 fr_seq(fp) = fsp->seq_ptr; 1381 fr_seq(fp) = fsp->seq_ptr;
1382 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id, 1382 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id,
1383 rpriv->local_port->port_id, FC_TYPE_ELS, 1383 rpriv->local_port->port_id, FC_TYPE_ELS,
1384 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 1384 FC_FCTL_REQ, 0);
1385 if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC, 1385 if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC,
1386 fc_fcp_rec_resp, fsp, 1386 fc_fcp_rec_resp, fsp,
1387 jiffies_to_msecs(FC_SCSI_REC_TOV))) { 1387 jiffies_to_msecs(FC_SCSI_REC_TOV))) {
@@ -1639,7 +1639,7 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
1639 1639
1640 fc_fill_fc_hdr(fp, FC_RCTL_ELS4_REQ, rport->port_id, 1640 fc_fill_fc_hdr(fp, FC_RCTL_ELS4_REQ, rport->port_id,
1641 rpriv->local_port->port_id, FC_TYPE_FCP, 1641 rpriv->local_port->port_id, FC_TYPE_FCP,
1642 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); 1642 FC_FCTL_REQ, 0);
1643 1643
1644 seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL, 1644 seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL,
1645 fsp, jiffies_to_msecs(FC_SCSI_REC_TOV)); 1645 fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
diff --git a/drivers/scsi/libfc/fc_libfc.c b/drivers/scsi/libfc/fc_libfc.c
index 39f4b6ab04b4..6a48c28e4420 100644
--- a/drivers/scsi/libfc/fc_libfc.c
+++ b/drivers/scsi/libfc/fc_libfc.c
@@ -23,6 +23,7 @@
23#include <linux/crc32.h> 23#include <linux/crc32.h>
24 24
25#include <scsi/libfc.h> 25#include <scsi/libfc.h>
26#include <scsi/fc_encode.h>
26 27
27#include "fc_libfc.h" 28#include "fc_libfc.h"
28 29
@@ -132,3 +133,80 @@ u32 fc_copy_buffer_to_sglist(void *buf, size_t len,
132 } 133 }
133 return copy_len; 134 return copy_len;
134} 135}
136
137/**
138 * fc_fill_hdr() - fill FC header fields based on request
139 * @fp: reply frame containing header to be filled in
140 * @in_fp: request frame containing header to use in filling in reply
141 * @r_ctl: R_CTL value for header
142 * @f_ctl: F_CTL value for header, with 0 pad
143 * @seq_cnt: sequence count for the header, ignored if frame has a sequence
144 * @parm_offset: parameter / offset value
145 */
146void fc_fill_hdr(struct fc_frame *fp, const struct fc_frame *in_fp,
147 enum fc_rctl r_ctl, u32 f_ctl, u16 seq_cnt, u32 parm_offset)
148{
149 struct fc_frame_header *fh;
150 struct fc_frame_header *in_fh;
151 struct fc_seq *sp;
152 u32 fill;
153
154 fh = __fc_frame_header_get(fp);
155 in_fh = __fc_frame_header_get(in_fp);
156
157 if (f_ctl & FC_FC_END_SEQ) {
158 fill = -fr_len(fp) & 3;
159 if (fill) {
160 /* TODO, this may be a problem with fragmented skb */
161 memset(skb_put(fp_skb(fp), fill), 0, fill);
162 f_ctl |= fill;
163 }
164 fr_eof(fp) = FC_EOF_T;
165 } else {
166 WARN_ON(fr_len(fp) % 4 != 0); /* no pad to non last frame */
167 fr_eof(fp) = FC_EOF_N;
168 }
169
170 fh->fh_r_ctl = r_ctl;
171 memcpy(fh->fh_d_id, in_fh->fh_s_id, sizeof(fh->fh_d_id));
172 memcpy(fh->fh_s_id, in_fh->fh_d_id, sizeof(fh->fh_s_id));
173 fh->fh_type = in_fh->fh_type;
174 hton24(fh->fh_f_ctl, f_ctl);
175 fh->fh_ox_id = in_fh->fh_ox_id;
176 fh->fh_rx_id = in_fh->fh_rx_id;
177 fh->fh_cs_ctl = 0;
178 fh->fh_df_ctl = 0;
179 fh->fh_parm_offset = htonl(parm_offset);
180
181 sp = fr_seq(in_fp);
182 if (sp) {
183 fr_seq(fp) = sp;
184 fh->fh_seq_id = sp->id;
185 seq_cnt = sp->cnt;
186 } else {
187 fh->fh_seq_id = 0;
188 }
189 fh->fh_seq_cnt = ntohs(seq_cnt);
190 fr_sof(fp) = seq_cnt ? FC_SOF_N3 : FC_SOF_I3;
191 fr_encaps(fp) = fr_encaps(in_fp);
192}
193EXPORT_SYMBOL(fc_fill_hdr);
194
195/**
196 * fc_fill_reply_hdr() - fill FC reply header fields based on request
197 * @fp: reply frame containing header to be filled in
198 * @in_fp: request frame containing header to use in filling in reply
199 * @r_ctl: R_CTL value for reply
200 * @parm_offset: parameter / offset value
201 */
202void fc_fill_reply_hdr(struct fc_frame *fp, const struct fc_frame *in_fp,
203 enum fc_rctl r_ctl, u32 parm_offset)
204{
205 struct fc_seq *sp;
206
207 sp = fr_seq(in_fp);
208 if (sp)
209 fr_seq(fp) = fr_dev(in_fp)->tt.seq_start_next(sp);
210 fc_fill_hdr(fp, in_fp, r_ctl, FC_FCTL_RESP, 0, parm_offset);
211}
212EXPORT_SYMBOL(fc_fill_reply_hdr);
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index be3c2cee829f..e50a6606d4bf 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -405,11 +405,9 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
405 struct fc_lport *lport) 405 struct fc_lport *lport)
406{ 406{
407 struct fc_frame *fp; 407 struct fc_frame *fp;
408 struct fc_exch *ep = fc_seq_exch(sp);
409 unsigned int len; 408 unsigned int len;
410 void *pp; 409 void *pp;
411 void *dp; 410 void *dp;
412 u32 f_ctl;
413 411
414 FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n", 412 FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n",
415 fc_lport_state(lport)); 413 fc_lport_state(lport));
@@ -425,11 +423,8 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
425 dp = fc_frame_payload_get(fp, len); 423 dp = fc_frame_payload_get(fp, len);
426 memcpy(dp, pp, len); 424 memcpy(dp, pp, len);
427 *((__be32 *)dp) = htonl(ELS_LS_ACC << 24); 425 *((__be32 *)dp) = htonl(ELS_LS_ACC << 24);
428 sp = lport->tt.seq_start_next(sp); 426 fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
429 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 427 lport->tt.frame_send(lport, fp);
430 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
431 FC_TYPE_ELS, f_ctl, 0);
432 lport->tt.seq_send(lport, sp, fp);
433 } 428 }
434 fc_frame_free(in_fp); 429 fc_frame_free(in_fp);
435} 430}
@@ -447,7 +442,6 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
447 struct fc_lport *lport) 442 struct fc_lport *lport)
448{ 443{
449 struct fc_frame *fp; 444 struct fc_frame *fp;
450 struct fc_exch *ep = fc_seq_exch(sp);
451 struct fc_els_rnid *req; 445 struct fc_els_rnid *req;
452 struct { 446 struct {
453 struct fc_els_rnid_resp rnid; 447 struct fc_els_rnid_resp rnid;
@@ -457,7 +451,6 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
457 struct fc_seq_els_data rjt_data; 451 struct fc_seq_els_data rjt_data;
458 u8 fmt; 452 u8 fmt;
459 size_t len; 453 size_t len;
460 u32 f_ctl;
461 454
462 FC_LPORT_DBG(lport, "Received RNID request while in state %s\n", 455 FC_LPORT_DBG(lport, "Received RNID request while in state %s\n",
463 fc_lport_state(lport)); 456 fc_lport_state(lport));
@@ -490,12 +483,8 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
490 memcpy(&rp->gen, &lport->rnid_gen, 483 memcpy(&rp->gen, &lport->rnid_gen,
491 sizeof(rp->gen)); 484 sizeof(rp->gen));
492 } 485 }
493 sp = lport->tt.seq_start_next(sp); 486 fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
494 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 487 lport->tt.frame_send(lport, fp);
495 f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
496 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
497 FC_TYPE_ELS, f_ctl, 0);
498 lport->tt.seq_send(lport, sp, fp);
499 } 488 }
500 } 489 }
501 fc_frame_free(in_fp); 490 fc_frame_free(in_fp);
@@ -800,14 +789,13 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
800 struct fc_lport *lport) 789 struct fc_lport *lport)
801{ 790{
802 struct fc_frame *fp; 791 struct fc_frame *fp;
792 struct fc_frame_header *fh;
803 struct fc_seq *sp; 793 struct fc_seq *sp;
804 struct fc_exch *ep;
805 struct fc_els_flogi *flp; 794 struct fc_els_flogi *flp;
806 struct fc_els_flogi *new_flp; 795 struct fc_els_flogi *new_flp;
807 u64 remote_wwpn; 796 u64 remote_wwpn;
808 u32 remote_fid; 797 u32 remote_fid;
809 u32 local_fid; 798 u32 local_fid;
810 u32 f_ctl;
811 799
812 FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n", 800 FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n",
813 fc_lport_state(lport)); 801 fc_lport_state(lport));
@@ -843,7 +831,6 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
843 831
844 fp = fc_frame_alloc(lport, sizeof(*flp)); 832 fp = fc_frame_alloc(lport, sizeof(*flp));
845 if (fp) { 833 if (fp) {
846 sp = lport->tt.seq_start_next(fr_seq(rx_fp));
847 new_flp = fc_frame_payload_get(fp, sizeof(*flp)); 834 new_flp = fc_frame_payload_get(fp, sizeof(*flp));
848 fc_lport_flogi_fill(lport, new_flp, ELS_FLOGI); 835 fc_lport_flogi_fill(lport, new_flp, ELS_FLOGI);
849 new_flp->fl_cmd = (u8) ELS_LS_ACC; 836 new_flp->fl_cmd = (u8) ELS_LS_ACC;
@@ -852,11 +839,11 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
852 * Send the response. If this fails, the originator should 839 * Send the response. If this fails, the originator should
853 * repeat the sequence. 840 * repeat the sequence.
854 */ 841 */
855 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 842 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
856 ep = fc_seq_exch(sp); 843 fh = fc_frame_header_get(fp);
857 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, remote_fid, local_fid, 844 hton24(fh->fh_s_id, local_fid);
858 FC_TYPE_ELS, f_ctl, 0); 845 hton24(fh->fh_d_id, remote_fid);
859 lport->tt.seq_send(lport, sp, fp); 846 lport->tt.frame_send(lport, fp);
860 847
861 } else { 848 } else {
862 fc_lport_error(lport, fp); 849 fc_lport_error(lport, fp);
@@ -1731,8 +1718,7 @@ static int fc_lport_els_request(struct fc_bsg_job *job,
1731 hton24(fh->fh_d_id, did); 1718 hton24(fh->fh_d_id, did);
1732 hton24(fh->fh_s_id, lport->port_id); 1719 hton24(fh->fh_s_id, lport->port_id);
1733 fh->fh_type = FC_TYPE_ELS; 1720 fh->fh_type = FC_TYPE_ELS;
1734 hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ | 1721 hton24(fh->fh_f_ctl, FC_FCTL_REQ);
1735 FC_FC_END_SEQ | FC_FC_SEQ_INIT);
1736 fh->fh_cs_ctl = 0; 1722 fh->fh_cs_ctl = 0;
1737 fh->fh_df_ctl = 0; 1723 fh->fh_df_ctl = 0;
1738 fh->fh_parm_offset = 0; 1724 fh->fh_parm_offset = 0;
@@ -1791,8 +1777,7 @@ static int fc_lport_ct_request(struct fc_bsg_job *job,
1791 hton24(fh->fh_d_id, did); 1777 hton24(fh->fh_d_id, did);
1792 hton24(fh->fh_s_id, lport->port_id); 1778 hton24(fh->fh_s_id, lport->port_id);
1793 fh->fh_type = FC_TYPE_CT; 1779 fh->fh_type = FC_TYPE_CT;
1794 hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ | 1780 hton24(fh->fh_f_ctl, FC_FCTL_REQ);
1795 FC_FC_END_SEQ | FC_FC_SEQ_INIT);
1796 fh->fh_cs_ctl = 0; 1781 fh->fh_cs_ctl = 0;
1797 fh->fh_df_ctl = 0; 1782 fh->fh_df_ctl = 0;
1798 fh->fh_parm_offset = 0; 1783 fh->fh_parm_offset = 0;
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 123493166824..598795123211 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -746,9 +746,8 @@ static void fc_rport_recv_flogi_req(struct fc_lport *lport,
746 struct fc_els_flogi *flp; 746 struct fc_els_flogi *flp;
747 struct fc_rport_priv *rdata; 747 struct fc_rport_priv *rdata;
748 struct fc_frame *fp = rx_fp; 748 struct fc_frame *fp = rx_fp;
749 struct fc_exch *ep;
750 struct fc_seq_els_data rjt_data; 749 struct fc_seq_els_data rjt_data;
751 u32 sid, f_ctl; 750 u32 sid;
752 751
753 rjt_data.fp = NULL; 752 rjt_data.fp = NULL;
754 sid = fc_frame_sid(fp); 753 sid = fc_frame_sid(fp);
@@ -813,7 +812,6 @@ static void fc_rport_recv_flogi_req(struct fc_lport *lport,
813 rjt_data.explan = ELS_EXPL_NONE; 812 rjt_data.explan = ELS_EXPL_NONE;
814 goto reject; 813 goto reject;
815 } 814 }
816 fc_frame_free(rx_fp);
817 815
818 fp = fc_frame_alloc(lport, sizeof(*flp)); 816 fp = fc_frame_alloc(lport, sizeof(*flp));
819 if (!fp) 817 if (!fp)
@@ -824,11 +822,8 @@ static void fc_rport_recv_flogi_req(struct fc_lport *lport,
824 flp = fc_frame_payload_get(fp, sizeof(*flp)); 822 flp = fc_frame_payload_get(fp, sizeof(*flp));
825 flp->fl_cmd = ELS_LS_ACC; 823 flp->fl_cmd = ELS_LS_ACC;
826 824
827 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT; 825 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
828 ep = fc_seq_exch(sp); 826 lport->tt.frame_send(lport, fp);
829 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
830 FC_TYPE_ELS, f_ctl, 0);
831 lport->tt.seq_send(lport, sp, fp);
832 827
833 if (rdata->ids.port_name < lport->wwpn) 828 if (rdata->ids.port_name < lport->wwpn)
834 fc_rport_enter_plogi(rdata); 829 fc_rport_enter_plogi(rdata);
@@ -837,12 +832,13 @@ static void fc_rport_recv_flogi_req(struct fc_lport *lport,
837out: 832out:
838 mutex_unlock(&rdata->rp_mutex); 833 mutex_unlock(&rdata->rp_mutex);
839 mutex_unlock(&disc->disc_mutex); 834 mutex_unlock(&disc->disc_mutex);
835 fc_frame_free(rx_fp);
840 return; 836 return;
841 837
842reject: 838reject:
843 mutex_unlock(&disc->disc_mutex); 839 mutex_unlock(&disc->disc_mutex);
844 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 840 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
845 fc_frame_free(fp); 841 fc_frame_free(rx_fp);
846} 842}
847 843
848/** 844/**
@@ -1310,10 +1306,8 @@ static void fc_rport_recv_adisc_req(struct fc_rport_priv *rdata,
1310{ 1306{
1311 struct fc_lport *lport = rdata->local_port; 1307 struct fc_lport *lport = rdata->local_port;
1312 struct fc_frame *fp; 1308 struct fc_frame *fp;
1313 struct fc_exch *ep = fc_seq_exch(sp);
1314 struct fc_els_adisc *adisc; 1309 struct fc_els_adisc *adisc;
1315 struct fc_seq_els_data rjt_data; 1310 struct fc_seq_els_data rjt_data;
1316 u32 f_ctl;
1317 1311
1318 FC_RPORT_DBG(rdata, "Received ADISC request\n"); 1312 FC_RPORT_DBG(rdata, "Received ADISC request\n");
1319 1313
@@ -1332,11 +1326,8 @@ static void fc_rport_recv_adisc_req(struct fc_rport_priv *rdata,
1332 fc_adisc_fill(lport, fp); 1326 fc_adisc_fill(lport, fp);
1333 adisc = fc_frame_payload_get(fp, sizeof(*adisc)); 1327 adisc = fc_frame_payload_get(fp, sizeof(*adisc));
1334 adisc->adisc_cmd = ELS_LS_ACC; 1328 adisc->adisc_cmd = ELS_LS_ACC;
1335 sp = lport->tt.seq_start_next(sp); 1329 fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
1336 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT; 1330 lport->tt.frame_send(lport, fp);
1337 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
1338 FC_TYPE_ELS, f_ctl, 0);
1339 lport->tt.seq_send(lport, sp, fp);
1340drop: 1331drop:
1341 fc_frame_free(in_fp); 1332 fc_frame_free(in_fp);
1342} 1333}
@@ -1356,13 +1347,11 @@ static void fc_rport_recv_rls_req(struct fc_rport_priv *rdata,
1356{ 1347{
1357 struct fc_lport *lport = rdata->local_port; 1348 struct fc_lport *lport = rdata->local_port;
1358 struct fc_frame *fp; 1349 struct fc_frame *fp;
1359 struct fc_exch *ep = fc_seq_exch(sp);
1360 struct fc_els_rls *rls; 1350 struct fc_els_rls *rls;
1361 struct fc_els_rls_resp *rsp; 1351 struct fc_els_rls_resp *rsp;
1362 struct fc_els_lesb *lesb; 1352 struct fc_els_lesb *lesb;
1363 struct fc_seq_els_data rjt_data; 1353 struct fc_seq_els_data rjt_data;
1364 struct fc_host_statistics *hst; 1354 struct fc_host_statistics *hst;
1365 u32 f_ctl;
1366 1355
1367 FC_RPORT_DBG(rdata, "Received RLS request while in state %s\n", 1356 FC_RPORT_DBG(rdata, "Received RLS request while in state %s\n",
1368 fc_rport_state(rdata)); 1357 fc_rport_state(rdata));
@@ -1399,11 +1388,8 @@ static void fc_rport_recv_rls_req(struct fc_rport_priv *rdata,
1399 lesb->lesb_inv_crc = htonl(hst->invalid_crc_count); 1388 lesb->lesb_inv_crc = htonl(hst->invalid_crc_count);
1400 } 1389 }
1401 1390
1402 sp = lport->tt.seq_start_next(sp); 1391 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
1403 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 1392 lport->tt.frame_send(lport, fp);
1404 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
1405 FC_TYPE_ELS, f_ctl, 0);
1406 lport->tt.seq_send(lport, sp, fp);
1407 goto out; 1393 goto out;
1408 1394
1409out_rjt: 1395out_rjt:
@@ -1549,10 +1535,9 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
1549 struct fc_disc *disc; 1535 struct fc_disc *disc;
1550 struct fc_rport_priv *rdata; 1536 struct fc_rport_priv *rdata;
1551 struct fc_frame *fp = rx_fp; 1537 struct fc_frame *fp = rx_fp;
1552 struct fc_exch *ep;
1553 struct fc_els_flogi *pl; 1538 struct fc_els_flogi *pl;
1554 struct fc_seq_els_data rjt_data; 1539 struct fc_seq_els_data rjt_data;
1555 u32 sid, f_ctl; 1540 u32 sid;
1556 1541
1557 rjt_data.fp = NULL; 1542 rjt_data.fp = NULL;
1558 sid = fc_frame_sid(fp); 1543 sid = fc_frame_sid(fp);
@@ -1632,27 +1617,21 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
1632 * Get session payload size from incoming PLOGI. 1617 * Get session payload size from incoming PLOGI.
1633 */ 1618 */
1634 rdata->maxframe_size = fc_plogi_get_maxframe(pl, lport->mfs); 1619 rdata->maxframe_size = fc_plogi_get_maxframe(pl, lport->mfs);
1635 fc_frame_free(rx_fp);
1636 1620
1637 /* 1621 /*
1638 * Send LS_ACC. If this fails, the originator should retry. 1622 * Send LS_ACC. If this fails, the originator should retry.
1639 */ 1623 */
1640 sp = lport->tt.seq_start_next(sp);
1641 if (!sp)
1642 goto out;
1643 fp = fc_frame_alloc(lport, sizeof(*pl)); 1624 fp = fc_frame_alloc(lport, sizeof(*pl));
1644 if (!fp) 1625 if (!fp)
1645 goto out; 1626 goto out;
1646 1627
1647 fc_plogi_fill(lport, fp, ELS_LS_ACC); 1628 fc_plogi_fill(lport, fp, ELS_LS_ACC);
1648 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT; 1629 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
1649 ep = fc_seq_exch(sp); 1630 lport->tt.frame_send(lport, fp);
1650 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
1651 FC_TYPE_ELS, f_ctl, 0);
1652 lport->tt.seq_send(lport, sp, fp);
1653 fc_rport_enter_prli(rdata); 1631 fc_rport_enter_prli(rdata);
1654out: 1632out:
1655 mutex_unlock(&rdata->rp_mutex); 1633 mutex_unlock(&rdata->rp_mutex);
1634 fc_frame_free(rx_fp);
1656 return; 1635 return;
1657 1636
1658reject: 1637reject:
@@ -1673,7 +1652,6 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
1673 struct fc_seq *sp, struct fc_frame *rx_fp) 1652 struct fc_seq *sp, struct fc_frame *rx_fp)
1674{ 1653{
1675 struct fc_lport *lport = rdata->local_port; 1654 struct fc_lport *lport = rdata->local_port;
1676 struct fc_exch *ep;
1677 struct fc_frame *fp; 1655 struct fc_frame *fp;
1678 struct { 1656 struct {
1679 struct fc_els_prli prli; 1657 struct fc_els_prli prli;
@@ -1685,7 +1663,6 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
1685 unsigned int plen; 1663 unsigned int plen;
1686 enum fc_els_spp_resp resp; 1664 enum fc_els_spp_resp resp;
1687 struct fc_seq_els_data rjt_data; 1665 struct fc_seq_els_data rjt_data;
1688 u32 f_ctl;
1689 u32 fcp_parm; 1666 u32 fcp_parm;
1690 u32 roles = FC_RPORT_ROLE_UNKNOWN; 1667 u32 roles = FC_RPORT_ROLE_UNKNOWN;
1691 1668
@@ -1714,8 +1691,6 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
1714 rjt_data.explan = ELS_EXPL_INSUF_RES; 1691 rjt_data.explan = ELS_EXPL_INSUF_RES;
1715 goto reject; 1692 goto reject;
1716 } 1693 }
1717 sp = lport->tt.seq_start_next(sp);
1718 WARN_ON(!sp);
1719 pp = fc_frame_payload_get(fp, len); 1694 pp = fc_frame_payload_get(fp, len);
1720 WARN_ON(!pp); 1695 WARN_ON(!pp);
1721 memset(pp, 0, len); 1696 memset(pp, 0, len);
@@ -1768,12 +1743,8 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
1768 /* 1743 /*
1769 * Send LS_ACC. If this fails, the originator should retry. 1744 * Send LS_ACC. If this fails, the originator should retry.
1770 */ 1745 */
1771 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 1746 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
1772 f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 1747 lport->tt.frame_send(lport, fp);
1773 ep = fc_seq_exch(sp);
1774 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
1775 FC_TYPE_ELS, f_ctl, 0);
1776 lport->tt.seq_send(lport, sp, fp);
1777 1748
1778 switch (rdata->rp_state) { 1749 switch (rdata->rp_state) {
1779 case RPORT_ST_PRLI: 1750 case RPORT_ST_PRLI:
@@ -1817,7 +1788,6 @@ static void fc_rport_recv_prlo_req(struct fc_rport_priv *rdata,
1817 struct fc_els_spp *spp; /* response spp */ 1788 struct fc_els_spp *spp; /* response spp */
1818 unsigned int len; 1789 unsigned int len;
1819 unsigned int plen; 1790 unsigned int plen;
1820 u32 f_ctl;
1821 struct fc_seq_els_data rjt_data; 1791 struct fc_seq_els_data rjt_data;
1822 1792
1823 rjt_data.fp = NULL; 1793 rjt_data.fp = NULL;
@@ -1859,11 +1829,9 @@ static void fc_rport_recv_prlo_req(struct fc_rport_priv *rdata,
1859 1829
1860 fc_rport_enter_delete(rdata, RPORT_EV_LOGO); 1830 fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
1861 1831
1862 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
1863 f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
1864 ep = fc_seq_exch(sp); 1832 ep = fc_seq_exch(sp);
1865 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 1833 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
1866 FC_TYPE_ELS, f_ctl, 0); 1834 FC_TYPE_ELS, FC_FCTL_RESP, 0);
1867 lport->tt.seq_send(lport, sp, fp); 1835 lport->tt.seq_send(lport, sp, fp);
1868 goto drop; 1836 goto drop;
1869 1837
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
index 9b4867c9c2d2..6d293c846a46 100644
--- a/include/scsi/fc_encode.h
+++ b/include/scsi/fc_encode.h
@@ -21,6 +21,13 @@
21#define _FC_ENCODE_H_ 21#define _FC_ENCODE_H_
22#include <asm/unaligned.h> 22#include <asm/unaligned.h>
23 23
24/*
25 * F_CTL values for simple requests and responses.
26 */
27#define FC_FCTL_REQ (FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT)
28#define FC_FCTL_RESP (FC_FC_EX_CTX | FC_FC_LAST_SEQ | \
29 FC_FC_END_SEQ | FC_FC_SEQ_INIT)
30
24struct fc_ns_rft { 31struct fc_ns_rft {
25 struct fc_ns_fid fid; /* port ID object */ 32 struct fc_ns_fid fid; /* port ID object */
26 struct fc_ns_fts fts; /* FC4-types object */ 33 struct fc_ns_fts fts; /* FC4-types object */
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index f1ce793f33b3..a6414ec63809 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -1027,6 +1027,10 @@ struct fc_seq *fc_elsct_send(struct fc_lport *, u32 did,
1027 void *arg, u32 timer_msec); 1027 void *arg, u32 timer_msec);
1028void fc_lport_flogi_resp(struct fc_seq *, struct fc_frame *, void *); 1028void fc_lport_flogi_resp(struct fc_seq *, struct fc_frame *, void *);
1029void fc_lport_logo_resp(struct fc_seq *, struct fc_frame *, void *); 1029void fc_lport_logo_resp(struct fc_seq *, struct fc_frame *, void *);
1030void fc_fill_reply_hdr(struct fc_frame *, const struct fc_frame *,
1031 enum fc_rctl, u32 parm_offset);
1032void fc_fill_hdr(struct fc_frame *, const struct fc_frame *,
1033 enum fc_rctl, u32 f_ctl, u16 seq_cnt, u32 parm_offset);
1030 1034
1031 1035
1032/* 1036/*