1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <linux/export.h>
25#include <asm/unaligned.h>
26#include <scsi/fc/fc_gs.h>
27#include <scsi/fc/fc_ns.h>
28#include <scsi/fc/fc_els.h>
29#include <scsi/libfc.h>
30#include <scsi/fc_encode.h>
31#include "fc_libfc.h"
32
33
34
35
36
37
38
39
40
41
42
43struct fc_seq *fc_elsct_send(struct fc_lport *lport, u32 did,
44 struct fc_frame *fp, unsigned int op,
45 void (*resp)(struct fc_seq *,
46 struct fc_frame *,
47 void *),
48 void *arg, u32 timer_msec)
49{
50 enum fc_rctl r_ctl;
51 enum fc_fh_type fh_type;
52 int rc;
53
54
55 if ((op >= ELS_LS_RJT) && (op <= ELS_AUTH_ELS))
56 rc = fc_els_fill(lport, did, fp, op, &r_ctl, &fh_type);
57 else {
58
59 rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type, &did);
60 }
61
62 if (rc) {
63 fc_frame_free(fp);
64 return NULL;
65 }
66
67 fc_fill_fc_hdr(fp, r_ctl, did, lport->port_id, fh_type,
68 FC_FCTL_REQ, 0);
69
70 return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec);
71}
72EXPORT_SYMBOL(fc_elsct_send);
73
74
75
76
77
78int fc_elsct_init(struct fc_lport *lport)
79{
80 if (!lport->tt.elsct_send)
81 lport->tt.elsct_send = fc_elsct_send;
82
83 return 0;
84}
85EXPORT_SYMBOL(fc_elsct_init);
86
87
88
89
90
91const char *fc_els_resp_type(struct fc_frame *fp)
92{
93 const char *msg;
94 struct fc_frame_header *fh;
95 struct fc_ct_hdr *ct;
96
97 if (IS_ERR(fp)) {
98 switch (-PTR_ERR(fp)) {
99 case FC_NO_ERR:
100 msg = "response no error";
101 break;
102 case FC_EX_TIMEOUT:
103 msg = "response timeout";
104 break;
105 case FC_EX_CLOSED:
106 msg = "response closed";
107 break;
108 default:
109 msg = "response unknown error";
110 break;
111 }
112 } else {
113 fh = fc_frame_header_get(fp);
114 switch (fh->fh_type) {
115 case FC_TYPE_ELS:
116 switch (fc_frame_payload_op(fp)) {
117 case ELS_LS_ACC:
118 msg = "accept";
119 break;
120 case ELS_LS_RJT:
121 msg = "reject";
122 break;
123 default:
124 msg = "response unknown ELS";
125 break;
126 }
127 break;
128 case FC_TYPE_CT:
129 ct = fc_frame_payload_get(fp, sizeof(*ct));
130 if (ct) {
131 switch (ntohs(ct->ct_cmd)) {
132 case FC_FS_ACC:
133 msg = "CT accept";
134 break;
135 case FC_FS_RJT:
136 msg = "CT reject";
137 break;
138 default:
139 msg = "response unknown CT";
140 break;
141 }
142 } else {
143 msg = "short CT response";
144 }
145 break;
146 default:
147 msg = "response not ELS or CT";
148 break;
149 }
150 }
151 return msg;
152}
153