Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Joe Eykholt and committed by
James Bottomley
24f089e2 251748a9

+121 -79
+1 -1
drivers/scsi/libfc/fc_elsct.c
··· 64 64 } 65 65 66 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 69 return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec); 70 70 }
+3 -3
drivers/scsi/libfc/fc_fcp.c
··· 1108 1108 1109 1109 fc_fill_fc_hdr(fp, FC_RCTL_DD_UNSOL_CMD, rport->port_id, 1110 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 1113 seq = lport->tt.exch_seq_send(lport, fp, resp, fc_fcp_pkt_destroy, 1114 1114 fsp, 0); ··· 1381 1381 fr_seq(fp) = fsp->seq_ptr; 1382 1382 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id, 1383 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 1385 if (lport->tt.elsct_send(lport, rport->port_id, fp, ELS_REC, 1386 1386 fc_fcp_rec_resp, fsp, 1387 1387 jiffies_to_msecs(FC_SCSI_REC_TOV))) { ··· 1639 1639 1640 1640 fc_fill_fc_hdr(fp, FC_RCTL_ELS4_REQ, rport->port_id, 1641 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 1644 seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL, 1645 1645 fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
+78
drivers/scsi/libfc/fc_libfc.c
··· 23 23 #include <linux/crc32.h> 24 24 25 25 #include <scsi/libfc.h> 26 + #include <scsi/fc_encode.h> 26 27 27 28 #include "fc_libfc.h" 28 29 ··· 133 132 } 134 133 return copy_len; 135 134 } 135 + 136 + /** 137 + * fc_fill_hdr() - fill FC header fields based on request 138 + * @fp: reply frame containing header to be filled in 139 + * @in_fp: request frame containing header to use in filling in reply 140 + * @r_ctl: R_CTL value for header 141 + * @f_ctl: F_CTL value for header, with 0 pad 142 + * @seq_cnt: sequence count for the header, ignored if frame has a sequence 143 + * @parm_offset: parameter / offset value 144 + */ 145 + void fc_fill_hdr(struct fc_frame *fp, const struct fc_frame *in_fp, 146 + enum fc_rctl r_ctl, u32 f_ctl, u16 seq_cnt, u32 parm_offset) 147 + { 148 + struct fc_frame_header *fh; 149 + struct fc_frame_header *in_fh; 150 + struct fc_seq *sp; 151 + u32 fill; 152 + 153 + fh = __fc_frame_header_get(fp); 154 + in_fh = __fc_frame_header_get(in_fp); 155 + 156 + if (f_ctl & FC_FC_END_SEQ) { 157 + fill = -fr_len(fp) & 3; 158 + if (fill) { 159 + /* TODO, this may be a problem with fragmented skb */ 160 + memset(skb_put(fp_skb(fp), fill), 0, fill); 161 + f_ctl |= fill; 162 + } 163 + fr_eof(fp) = FC_EOF_T; 164 + } else { 165 + WARN_ON(fr_len(fp) % 4 != 0); /* no pad to non last frame */ 166 + fr_eof(fp) = FC_EOF_N; 167 + } 168 + 169 + fh->fh_r_ctl = r_ctl; 170 + memcpy(fh->fh_d_id, in_fh->fh_s_id, sizeof(fh->fh_d_id)); 171 + memcpy(fh->fh_s_id, in_fh->fh_d_id, sizeof(fh->fh_s_id)); 172 + fh->fh_type = in_fh->fh_type; 173 + hton24(fh->fh_f_ctl, f_ctl); 174 + fh->fh_ox_id = in_fh->fh_ox_id; 175 + fh->fh_rx_id = in_fh->fh_rx_id; 176 + fh->fh_cs_ctl = 0; 177 + fh->fh_df_ctl = 0; 178 + fh->fh_parm_offset = htonl(parm_offset); 179 + 180 + sp = fr_seq(in_fp); 181 + if (sp) { 182 + fr_seq(fp) = sp; 183 + fh->fh_seq_id = sp->id; 184 + seq_cnt = sp->cnt; 185 + } else { 186 + fh->fh_seq_id = 0; 187 + } 188 + fh->fh_seq_cnt = ntohs(seq_cnt); 189 + fr_sof(fp) = seq_cnt ? FC_SOF_N3 : FC_SOF_I3; 190 + fr_encaps(fp) = fr_encaps(in_fp); 191 + } 192 + EXPORT_SYMBOL(fc_fill_hdr); 193 + 194 + /** 195 + * fc_fill_reply_hdr() - fill FC reply header fields based on request 196 + * @fp: reply frame containing header to be filled in 197 + * @in_fp: request frame containing header to use in filling in reply 198 + * @r_ctl: R_CTL value for reply 199 + * @parm_offset: parameter / offset value 200 + */ 201 + void fc_fill_reply_hdr(struct fc_frame *fp, const struct fc_frame *in_fp, 202 + enum fc_rctl r_ctl, u32 parm_offset) 203 + { 204 + struct fc_seq *sp; 205 + 206 + sp = fr_seq(in_fp); 207 + if (sp) 208 + fr_seq(fp) = fr_dev(in_fp)->tt.seq_start_next(sp); 209 + fc_fill_hdr(fp, in_fp, r_ctl, FC_FCTL_RESP, 0, parm_offset); 210 + } 211 + EXPORT_SYMBOL(fc_fill_reply_hdr);
+12 -27
drivers/scsi/libfc/fc_lport.c
··· 405 405 struct fc_lport *lport) 406 406 { 407 407 struct fc_frame *fp; 408 - struct fc_exch *ep = fc_seq_exch(sp); 409 408 unsigned int len; 410 409 void *pp; 411 410 void *dp; 412 - u32 f_ctl; 413 411 414 412 FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n", 415 413 fc_lport_state(lport)); ··· 423 425 dp = fc_frame_payload_get(fp, len); 424 426 memcpy(dp, pp, len); 425 427 *((__be32 *)dp) = htonl(ELS_LS_ACC << 24); 426 - sp = lport->tt.seq_start_next(sp); 427 - f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 428 - fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 429 - FC_TYPE_ELS, f_ctl, 0); 430 - lport->tt.seq_send(lport, sp, fp); 428 + fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0); 429 + lport->tt.frame_send(lport, fp); 431 430 } 432 431 fc_frame_free(in_fp); 433 432 } ··· 442 447 struct fc_lport *lport) 443 448 { 444 449 struct fc_frame *fp; 445 - struct fc_exch *ep = fc_seq_exch(sp); 446 450 struct fc_els_rnid *req; 447 451 struct { 448 452 struct fc_els_rnid_resp rnid; ··· 451 457 struct fc_seq_els_data rjt_data; 452 458 u8 fmt; 453 459 size_t len; 454 - u32 f_ctl; 455 460 456 461 FC_LPORT_DBG(lport, "Received RNID request while in state %s\n", 457 462 fc_lport_state(lport)); ··· 483 490 memcpy(&rp->gen, &lport->rnid_gen, 484 491 sizeof(rp->gen)); 485 492 } 486 - sp = lport->tt.seq_start_next(sp); 487 - f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 488 - f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 489 - fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 490 - FC_TYPE_ELS, f_ctl, 0); 491 - lport->tt.seq_send(lport, sp, fp); 493 + fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0); 494 + lport->tt.frame_send(lport, fp); 492 495 } 493 496 } 494 497 fc_frame_free(in_fp); ··· 789 800 struct fc_lport *lport) 790 801 { 791 802 struct fc_frame *fp; 803 + struct fc_frame_header *fh; 792 804 struct fc_seq *sp; 793 - struct fc_exch *ep; 794 805 struct fc_els_flogi *flp; 795 806 struct fc_els_flogi *new_flp; 796 807 u64 remote_wwpn; 797 808 u32 remote_fid; 798 809 u32 local_fid; 799 - u32 f_ctl; 800 810 801 811 FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n", 802 812 fc_lport_state(lport)); ··· 831 843 832 844 fp = fc_frame_alloc(lport, sizeof(*flp)); 833 845 if (fp) { 834 - sp = lport->tt.seq_start_next(fr_seq(rx_fp)); 835 846 new_flp = fc_frame_payload_get(fp, sizeof(*flp)); 836 847 fc_lport_flogi_fill(lport, new_flp, ELS_FLOGI); 837 848 new_flp->fl_cmd = (u8) ELS_LS_ACC; ··· 839 852 * Send the response. If this fails, the originator should 840 853 * repeat the sequence. 841 854 */ 842 - f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 843 - ep = fc_seq_exch(sp); 844 - fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, remote_fid, local_fid, 845 - FC_TYPE_ELS, f_ctl, 0); 846 - lport->tt.seq_send(lport, sp, fp); 855 + fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0); 856 + fh = fc_frame_header_get(fp); 857 + hton24(fh->fh_s_id, local_fid); 858 + hton24(fh->fh_d_id, remote_fid); 859 + lport->tt.frame_send(lport, fp); 847 860 848 861 } else { 849 862 fc_lport_error(lport, fp); ··· 1718 1731 hton24(fh->fh_d_id, did); 1719 1732 hton24(fh->fh_s_id, lport->port_id); 1720 1733 fh->fh_type = FC_TYPE_ELS; 1721 - hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ | 1722 - FC_FC_END_SEQ | FC_FC_SEQ_INIT); 1734 + hton24(fh->fh_f_ctl, FC_FCTL_REQ); 1723 1735 fh->fh_cs_ctl = 0; 1724 1736 fh->fh_df_ctl = 0; 1725 1737 fh->fh_parm_offset = 0; ··· 1777 1791 hton24(fh->fh_d_id, did); 1778 1792 hton24(fh->fh_s_id, lport->port_id); 1779 1793 fh->fh_type = FC_TYPE_CT; 1780 - hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ | 1781 - FC_FC_END_SEQ | FC_FC_SEQ_INIT); 1794 + hton24(fh->fh_f_ctl, FC_FCTL_REQ); 1782 1795 fh->fh_cs_ctl = 0; 1783 1796 fh->fh_df_ctl = 0; 1784 1797 fh->fh_parm_offset = 0;
+16 -48
drivers/scsi/libfc/fc_rport.c
··· 746 746 struct fc_els_flogi *flp; 747 747 struct fc_rport_priv *rdata; 748 748 struct fc_frame *fp = rx_fp; 749 - struct fc_exch *ep; 750 749 struct fc_seq_els_data rjt_data; 751 - u32 sid, f_ctl; 750 + u32 sid; 752 751 753 752 rjt_data.fp = NULL; 754 753 sid = fc_frame_sid(fp); ··· 812 813 rjt_data.explan = ELS_EXPL_NONE; 813 814 goto reject; 814 815 } 815 - fc_frame_free(rx_fp); 816 816 817 817 fp = fc_frame_alloc(lport, sizeof(*flp)); 818 818 if (!fp) ··· 822 824 flp = fc_frame_payload_get(fp, sizeof(*flp)); 823 825 flp->fl_cmd = ELS_LS_ACC; 824 826 825 - f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT; 826 - ep = fc_seq_exch(sp); 827 - fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 828 - FC_TYPE_ELS, f_ctl, 0); 829 - lport->tt.seq_send(lport, sp, fp); 827 + fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0); 828 + lport->tt.frame_send(lport, fp); 830 829 831 830 if (rdata->ids.port_name < lport->wwpn) 832 831 fc_rport_enter_plogi(rdata); ··· 832 837 out: 833 838 mutex_unlock(&rdata->rp_mutex); 834 839 mutex_unlock(&disc->disc_mutex); 840 + fc_frame_free(rx_fp); 835 841 return; 836 842 837 843 reject: 838 844 mutex_unlock(&disc->disc_mutex); 839 845 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 840 - fc_frame_free(fp); 846 + fc_frame_free(rx_fp); 841 847 } 842 848 843 849 /** ··· 1306 1310 { 1307 1311 struct fc_lport *lport = rdata->local_port; 1308 1312 struct fc_frame *fp; 1309 - struct fc_exch *ep = fc_seq_exch(sp); 1310 1313 struct fc_els_adisc *adisc; 1311 1314 struct fc_seq_els_data rjt_data; 1312 - u32 f_ctl; 1313 1315 1314 1316 FC_RPORT_DBG(rdata, "Received ADISC request\n"); 1315 1317 ··· 1326 1332 fc_adisc_fill(lport, fp); 1327 1333 adisc = fc_frame_payload_get(fp, sizeof(*adisc)); 1328 1334 adisc->adisc_cmd = ELS_LS_ACC; 1329 - sp = lport->tt.seq_start_next(sp); 1330 - f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT; 1331 - fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 1332 - FC_TYPE_ELS, f_ctl, 0); 1333 - lport->tt.seq_send(lport, sp, fp); 1335 + fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0); 1336 + lport->tt.frame_send(lport, fp); 1334 1337 drop: 1335 1338 fc_frame_free(in_fp); 1336 1339 } ··· 1347 1356 { 1348 1357 struct fc_lport *lport = rdata->local_port; 1349 1358 struct fc_frame *fp; 1350 - struct fc_exch *ep = fc_seq_exch(sp); 1351 1359 struct fc_els_rls *rls; 1352 1360 struct fc_els_rls_resp *rsp; 1353 1361 struct fc_els_lesb *lesb; 1354 1362 struct fc_seq_els_data rjt_data; 1355 1363 struct fc_host_statistics *hst; 1356 - u32 f_ctl; 1357 1364 1358 1365 FC_RPORT_DBG(rdata, "Received RLS request while in state %s\n", 1359 1366 fc_rport_state(rdata)); ··· 1388 1399 lesb->lesb_inv_crc = htonl(hst->invalid_crc_count); 1389 1400 } 1390 1401 1391 - sp = lport->tt.seq_start_next(sp); 1392 - f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 1393 - fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 1394 - FC_TYPE_ELS, f_ctl, 0); 1395 - lport->tt.seq_send(lport, sp, fp); 1402 + fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0); 1403 + lport->tt.frame_send(lport, fp); 1396 1404 goto out; 1397 1405 1398 1406 out_rjt: ··· 1535 1549 struct fc_disc *disc; 1536 1550 struct fc_rport_priv *rdata; 1537 1551 struct fc_frame *fp = rx_fp; 1538 - struct fc_exch *ep; 1539 1552 struct fc_els_flogi *pl; 1540 1553 struct fc_seq_els_data rjt_data; 1541 - u32 sid, f_ctl; 1554 + u32 sid; 1542 1555 1543 1556 rjt_data.fp = NULL; 1544 1557 sid = fc_frame_sid(fp); ··· 1617 1632 * Get session payload size from incoming PLOGI. 1618 1633 */ 1619 1634 rdata->maxframe_size = fc_plogi_get_maxframe(pl, lport->mfs); 1620 - fc_frame_free(rx_fp); 1621 1635 1622 1636 /* 1623 1637 * Send LS_ACC. If this fails, the originator should retry. 1624 1638 */ 1625 - sp = lport->tt.seq_start_next(sp); 1626 - if (!sp) 1627 - goto out; 1628 1639 fp = fc_frame_alloc(lport, sizeof(*pl)); 1629 1640 if (!fp) 1630 1641 goto out; 1631 1642 1632 1643 fc_plogi_fill(lport, fp, ELS_LS_ACC); 1633 - f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT; 1634 - ep = fc_seq_exch(sp); 1635 - fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 1636 - FC_TYPE_ELS, f_ctl, 0); 1637 - lport->tt.seq_send(lport, sp, fp); 1644 + fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0); 1645 + lport->tt.frame_send(lport, fp); 1638 1646 fc_rport_enter_prli(rdata); 1639 1647 out: 1640 1648 mutex_unlock(&rdata->rp_mutex); 1649 + fc_frame_free(rx_fp); 1641 1650 return; 1642 1651 1643 1652 reject: ··· 1652 1673 struct fc_seq *sp, struct fc_frame *rx_fp) 1653 1674 { 1654 1675 struct fc_lport *lport = rdata->local_port; 1655 - struct fc_exch *ep; 1656 1676 struct fc_frame *fp; 1657 1677 struct { 1658 1678 struct fc_els_prli prli; ··· 1663 1685 unsigned int plen; 1664 1686 enum fc_els_spp_resp resp; 1665 1687 struct fc_seq_els_data rjt_data; 1666 - u32 f_ctl; 1667 1688 u32 fcp_parm; 1668 1689 u32 roles = FC_RPORT_ROLE_UNKNOWN; 1669 1690 ··· 1691 1714 rjt_data.explan = ELS_EXPL_INSUF_RES; 1692 1715 goto reject; 1693 1716 } 1694 - sp = lport->tt.seq_start_next(sp); 1695 - WARN_ON(!sp); 1696 1717 pp = fc_frame_payload_get(fp, len); 1697 1718 WARN_ON(!pp); 1698 1719 memset(pp, 0, len); ··· 1743 1768 /* 1744 1769 * Send LS_ACC. If this fails, the originator should retry. 1745 1770 */ 1746 - f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 1747 - f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 1748 - ep = fc_seq_exch(sp); 1749 - fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 1750 - FC_TYPE_ELS, f_ctl, 0); 1751 - lport->tt.seq_send(lport, sp, fp); 1771 + fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0); 1772 + lport->tt.frame_send(lport, fp); 1752 1773 1753 1774 switch (rdata->rp_state) { 1754 1775 case RPORT_ST_PRLI: ··· 1788 1817 struct fc_els_spp *spp; /* response spp */ 1789 1818 unsigned int len; 1790 1819 unsigned int plen; 1791 - u32 f_ctl; 1792 1820 struct fc_seq_els_data rjt_data; 1793 1821 1794 1822 rjt_data.fp = NULL; ··· 1829 1859 1830 1860 fc_rport_enter_delete(rdata, RPORT_EV_LOGO); 1831 1861 1832 - f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 1833 - f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 1834 1862 ep = fc_seq_exch(sp); 1835 1863 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 1836 - FC_TYPE_ELS, f_ctl, 0); 1864 + FC_TYPE_ELS, FC_FCTL_RESP, 0); 1837 1865 lport->tt.seq_send(lport, sp, fp); 1838 1866 goto drop; 1839 1867
+7
include/scsi/fc_encode.h
··· 21 21 #define _FC_ENCODE_H_ 22 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 + 24 31 struct fc_ns_rft { 25 32 struct fc_ns_fid fid; /* port ID object */ 26 33 struct fc_ns_fts fts; /* FC4-types object */
+4
include/scsi/libfc.h
··· 1027 1027 void *arg, u32 timer_msec); 1028 1028 void fc_lport_flogi_resp(struct fc_seq *, struct fc_frame *, void *); 1029 1029 void fc_lport_logo_resp(struct fc_seq *, struct fc_frame *, void *); 1030 + void fc_fill_reply_hdr(struct fc_frame *, const struct fc_frame *, 1031 + enum fc_rctl, u32 parm_offset); 1032 + void 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 /*