diff options
Diffstat (limited to 'include/scsi/libfc.h')
-rw-r--r-- | include/scsi/libfc.h | 244 |
1 files changed, 128 insertions, 116 deletions
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index b92584a8843a..65dc9aacbf70 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h | |||
@@ -51,55 +51,49 @@ do { \ | |||
51 | do { \ | 51 | do { \ |
52 | CMD; \ | 52 | CMD; \ |
53 | } while (0); \ | 53 | } while (0); \ |
54 | } while (0); | 54 | } while (0) |
55 | 55 | ||
56 | #define FC_LIBFC_DBG(fmt, args...) \ | 56 | #define FC_LIBFC_DBG(fmt, args...) \ |
57 | FC_CHECK_LOGGING(FC_LIBFC_LOGGING, \ | 57 | FC_CHECK_LOGGING(FC_LIBFC_LOGGING, \ |
58 | printk(KERN_INFO "libfc: " fmt, ##args);) | 58 | printk(KERN_INFO "libfc: " fmt, ##args)) |
59 | 59 | ||
60 | #define FC_LPORT_DBG(lport, fmt, args...) \ | 60 | #define FC_LPORT_DBG(lport, fmt, args...) \ |
61 | FC_CHECK_LOGGING(FC_LPORT_LOGGING, \ | 61 | FC_CHECK_LOGGING(FC_LPORT_LOGGING, \ |
62 | printk(KERN_INFO "lport: %6x: " fmt, \ | 62 | printk(KERN_INFO "host%u: lport %6x: " fmt, \ |
63 | fc_host_port_id(lport->host), ##args);) | 63 | (lport)->host->host_no, \ |
64 | fc_host_port_id((lport)->host), ##args)) | ||
64 | 65 | ||
65 | #define FC_DISC_DBG(disc, fmt, args...) \ | 66 | #define FC_DISC_DBG(disc, fmt, args...) \ |
66 | FC_CHECK_LOGGING(FC_DISC_LOGGING, \ | 67 | FC_CHECK_LOGGING(FC_DISC_LOGGING, \ |
67 | printk(KERN_INFO "disc: %6x: " fmt, \ | 68 | printk(KERN_INFO "host%u: disc: " fmt, \ |
68 | fc_host_port_id(disc->lport->host), \ | 69 | (disc)->lport->host->host_no, \ |
69 | ##args);) | 70 | ##args)) |
70 | 71 | ||
71 | #define FC_RPORT_DBG(rport, fmt, args...) \ | 72 | #define FC_RPORT_ID_DBG(lport, port_id, fmt, args...) \ |
72 | do { \ | ||
73 | struct fc_rport_libfc_priv *rdata = rport->dd_data; \ | ||
74 | struct fc_lport *lport = rdata->local_port; \ | ||
75 | FC_CHECK_LOGGING(FC_RPORT_LOGGING, \ | 73 | FC_CHECK_LOGGING(FC_RPORT_LOGGING, \ |
76 | printk(KERN_INFO "rport: %6x: %6x: " fmt, \ | 74 | printk(KERN_INFO "host%u: rport %6x: " fmt, \ |
77 | fc_host_port_id(lport->host), \ | 75 | (lport)->host->host_no, \ |
78 | rport->port_id, ##args);) \ | 76 | (port_id), ##args)) |
79 | } while (0); | 77 | |
78 | #define FC_RPORT_DBG(rdata, fmt, args...) \ | ||
79 | FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args) | ||
80 | 80 | ||
81 | #define FC_FCP_DBG(pkt, fmt, args...) \ | 81 | #define FC_FCP_DBG(pkt, fmt, args...) \ |
82 | FC_CHECK_LOGGING(FC_FCP_LOGGING, \ | 82 | FC_CHECK_LOGGING(FC_FCP_LOGGING, \ |
83 | printk(KERN_INFO "fcp: %6x: %6x: " fmt, \ | 83 | printk(KERN_INFO "host%u: fcp: %6x: " fmt, \ |
84 | fc_host_port_id(pkt->lp->host), \ | 84 | (pkt)->lp->host->host_no, \ |
85 | pkt->rport->port_id, ##args);) | 85 | pkt->rport->port_id, ##args)) |
86 | |||
87 | #define FC_EM_DBG(em, fmt, args...) \ | ||
88 | FC_CHECK_LOGGING(FC_EM_LOGGING, \ | ||
89 | printk(KERN_INFO "em: %6x: " fmt, \ | ||
90 | fc_host_port_id(em->lp->host), \ | ||
91 | ##args);) | ||
92 | 86 | ||
93 | #define FC_EXCH_DBG(exch, fmt, args...) \ | 87 | #define FC_EXCH_DBG(exch, fmt, args...) \ |
94 | FC_CHECK_LOGGING(FC_EXCH_LOGGING, \ | 88 | FC_CHECK_LOGGING(FC_EXCH_LOGGING, \ |
95 | printk(KERN_INFO "exch: %6x: %4x: " fmt, \ | 89 | printk(KERN_INFO "host%u: xid %4x: " fmt, \ |
96 | fc_host_port_id(exch->lp->host), \ | 90 | (exch)->lp->host->host_no, \ |
97 | exch->xid, ##args);) | 91 | exch->xid, ##args)) |
98 | 92 | ||
99 | #define FC_SCSI_DBG(lport, fmt, args...) \ | 93 | #define FC_SCSI_DBG(lport, fmt, args...) \ |
100 | FC_CHECK_LOGGING(FC_SCSI_LOGGING, \ | 94 | FC_CHECK_LOGGING(FC_SCSI_LOGGING, \ |
101 | printk(KERN_INFO "scsi: %6x: " fmt, \ | 95 | printk(KERN_INFO "host%u: scsi: " fmt, \ |
102 | fc_host_port_id(lport->host), ##args);) | 96 | (lport)->host->host_no, ##args)) |
103 | 97 | ||
104 | /* | 98 | /* |
105 | * libfc error codes | 99 | * libfc error codes |
@@ -125,7 +119,7 @@ do { \ | |||
125 | * FC HBA status | 119 | * FC HBA status |
126 | */ | 120 | */ |
127 | enum fc_lport_state { | 121 | enum fc_lport_state { |
128 | LPORT_ST_NONE = 0, | 122 | LPORT_ST_DISABLED = 0, |
129 | LPORT_ST_FLOGI, | 123 | LPORT_ST_FLOGI, |
130 | LPORT_ST_DNS, | 124 | LPORT_ST_DNS, |
131 | LPORT_ST_RPN_ID, | 125 | LPORT_ST_RPN_ID, |
@@ -143,53 +137,74 @@ enum fc_disc_event { | |||
143 | }; | 137 | }; |
144 | 138 | ||
145 | enum fc_rport_state { | 139 | enum fc_rport_state { |
146 | RPORT_ST_NONE = 0, | ||
147 | RPORT_ST_INIT, /* initialized */ | 140 | RPORT_ST_INIT, /* initialized */ |
148 | RPORT_ST_PLOGI, /* waiting for PLOGI completion */ | 141 | RPORT_ST_PLOGI, /* waiting for PLOGI completion */ |
149 | RPORT_ST_PRLI, /* waiting for PRLI completion */ | 142 | RPORT_ST_PRLI, /* waiting for PRLI completion */ |
150 | RPORT_ST_RTV, /* waiting for RTV completion */ | 143 | RPORT_ST_RTV, /* waiting for RTV completion */ |
151 | RPORT_ST_READY, /* ready for use */ | 144 | RPORT_ST_READY, /* ready for use */ |
152 | RPORT_ST_LOGO, /* port logout sent */ | 145 | RPORT_ST_LOGO, /* port logout sent */ |
153 | }; | 146 | RPORT_ST_ADISC, /* Discover Address sent */ |
154 | 147 | RPORT_ST_DELETE, /* port being deleted */ | |
155 | enum fc_rport_trans_state { | ||
156 | FC_PORTSTATE_ROGUE, | ||
157 | FC_PORTSTATE_REAL, | ||
158 | }; | 148 | }; |
159 | 149 | ||
160 | /** | 150 | /** |
161 | * struct fc_disc_port - temporary discovery port to hold rport identifiers | 151 | * struct fc_disc_port - temporary discovery port to hold rport identifiers |
162 | * @lp: Fibre Channel host port instance | 152 | * @lp: Fibre Channel host port instance |
163 | * @peers: node for list management during discovery and RSCN processing | 153 | * @peers: Node for list management during discovery and RSCN processing |
164 | * @ids: identifiers structure to pass to fc_remote_port_add() | 154 | * @rport_work: Work struct for starting the rport state machine |
165 | * @rport_work: work struct for starting the rport state machine | 155 | * @port_id: Port ID of the discovered port |
166 | */ | 156 | */ |
167 | struct fc_disc_port { | 157 | struct fc_disc_port { |
168 | struct fc_lport *lp; | 158 | struct fc_lport *lp; |
169 | struct list_head peers; | 159 | struct list_head peers; |
170 | struct fc_rport_identifiers ids; | ||
171 | struct work_struct rport_work; | 160 | struct work_struct rport_work; |
161 | u32 port_id; | ||
172 | }; | 162 | }; |
173 | 163 | ||
174 | enum fc_rport_event { | 164 | enum fc_rport_event { |
175 | RPORT_EV_NONE = 0, | 165 | RPORT_EV_NONE = 0, |
176 | RPORT_EV_CREATED, | 166 | RPORT_EV_READY, |
177 | RPORT_EV_FAILED, | 167 | RPORT_EV_FAILED, |
178 | RPORT_EV_STOP, | 168 | RPORT_EV_STOP, |
179 | RPORT_EV_LOGO | 169 | RPORT_EV_LOGO |
180 | }; | 170 | }; |
181 | 171 | ||
172 | struct fc_rport_priv; | ||
173 | |||
182 | struct fc_rport_operations { | 174 | struct fc_rport_operations { |
183 | void (*event_callback)(struct fc_lport *, struct fc_rport *, | 175 | void (*event_callback)(struct fc_lport *, struct fc_rport_priv *, |
184 | enum fc_rport_event); | 176 | enum fc_rport_event); |
185 | }; | 177 | }; |
186 | 178 | ||
187 | /** | 179 | /** |
188 | * struct fc_rport_libfc_priv - libfc internal information about a remote port | 180 | * struct fc_rport_libfc_priv - libfc internal information about a remote port |
189 | * @local_port: Fibre Channel host port instance | 181 | * @local_port: Fibre Channel host port instance |
182 | * @rp_state: indicates READY for I/O or DELETE when blocked. | ||
183 | * @flags: REC and RETRY supported flags | ||
184 | * @e_d_tov: error detect timeout value (in msec) | ||
185 | * @r_a_tov: resource allocation timeout value (in msec) | ||
186 | */ | ||
187 | struct fc_rport_libfc_priv { | ||
188 | struct fc_lport *local_port; | ||
189 | enum fc_rport_state rp_state; | ||
190 | u16 flags; | ||
191 | #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0) | ||
192 | #define FC_RP_FLAGS_RETRY (1 << 1) | ||
193 | unsigned int e_d_tov; | ||
194 | unsigned int r_a_tov; | ||
195 | }; | ||
196 | |||
197 | /** | ||
198 | * struct fc_rport_priv - libfc rport and discovery info about a remote port | ||
199 | * @local_port: Fibre Channel host port instance | ||
200 | * @rport: transport remote port | ||
201 | * @kref: reference counter | ||
190 | * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges | 202 | * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges |
203 | * @ids: remote port identifiers and roles | ||
191 | * @flags: REC and RETRY supported flags | 204 | * @flags: REC and RETRY supported flags |
192 | * @max_seq: maximum number of concurrent sequences | 205 | * @max_seq: maximum number of concurrent sequences |
206 | * @disc_id: discovery identifier | ||
207 | * @maxframe_size: maximum frame size | ||
193 | * @retries: retry count in current state | 208 | * @retries: retry count in current state |
194 | * @e_d_tov: error detect timeout value (in msec) | 209 | * @e_d_tov: error detect timeout value (in msec) |
195 | * @r_a_tov: resource allocation timeout value (in msec) | 210 | * @r_a_tov: resource allocation timeout value (in msec) |
@@ -197,38 +212,28 @@ struct fc_rport_operations { | |||
197 | * @retry_work: | 212 | * @retry_work: |
198 | * @event_callback: Callback for rport READY, FAILED or LOGO | 213 | * @event_callback: Callback for rport READY, FAILED or LOGO |
199 | */ | 214 | */ |
200 | struct fc_rport_libfc_priv { | 215 | struct fc_rport_priv { |
201 | struct fc_lport *local_port; | 216 | struct fc_lport *local_port; |
217 | struct fc_rport *rport; | ||
218 | struct kref kref; | ||
202 | enum fc_rport_state rp_state; | 219 | enum fc_rport_state rp_state; |
220 | struct fc_rport_identifiers ids; | ||
203 | u16 flags; | 221 | u16 flags; |
204 | #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0) | ||
205 | #define FC_RP_FLAGS_RETRY (1 << 1) | ||
206 | u16 max_seq; | 222 | u16 max_seq; |
223 | u16 disc_id; | ||
224 | u16 maxframe_size; | ||
207 | unsigned int retries; | 225 | unsigned int retries; |
208 | unsigned int e_d_tov; | 226 | unsigned int e_d_tov; |
209 | unsigned int r_a_tov; | 227 | unsigned int r_a_tov; |
210 | enum fc_rport_trans_state trans_state; | ||
211 | struct mutex rp_mutex; | 228 | struct mutex rp_mutex; |
212 | struct delayed_work retry_work; | 229 | struct delayed_work retry_work; |
213 | enum fc_rport_event event; | 230 | enum fc_rport_event event; |
214 | struct fc_rport_operations *ops; | 231 | struct fc_rport_operations *ops; |
215 | struct list_head peers; | 232 | struct list_head peers; |
216 | struct work_struct event_work; | 233 | struct work_struct event_work; |
234 | u32 supported_classes; | ||
217 | }; | 235 | }; |
218 | 236 | ||
219 | #define PRIV_TO_RPORT(x) \ | ||
220 | (struct fc_rport *)((void *)x - sizeof(struct fc_rport)); | ||
221 | #define RPORT_TO_PRIV(x) \ | ||
222 | (struct fc_rport_libfc_priv *)((void *)x + sizeof(struct fc_rport)); | ||
223 | |||
224 | struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *); | ||
225 | |||
226 | static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn) | ||
227 | { | ||
228 | rport->node_name = wwnn; | ||
229 | rport->port_name = wwpn; | ||
230 | } | ||
231 | |||
232 | /* | 237 | /* |
233 | * fcoe stats structure | 238 | * fcoe stats structure |
234 | */ | 239 | */ |
@@ -344,6 +349,8 @@ static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp) | |||
344 | */ | 349 | */ |
345 | 350 | ||
346 | struct fc_exch_mgr; | 351 | struct fc_exch_mgr; |
352 | struct fc_exch_mgr_anchor; | ||
353 | extern u16 fc_cpu_mask; /* cpu mask for possible cpus */ | ||
347 | 354 | ||
348 | /* | 355 | /* |
349 | * Sequence. | 356 | * Sequence. |
@@ -368,6 +375,7 @@ struct fc_seq { | |||
368 | */ | 375 | */ |
369 | struct fc_exch { | 376 | struct fc_exch { |
370 | struct fc_exch_mgr *em; /* exchange manager */ | 377 | struct fc_exch_mgr *em; /* exchange manager */ |
378 | struct fc_exch_pool *pool; /* per cpu exches pool */ | ||
371 | u32 state; /* internal driver state */ | 379 | u32 state; /* internal driver state */ |
372 | u16 xid; /* our exchange ID */ | 380 | u16 xid; /* our exchange ID */ |
373 | struct list_head ex_list; /* free or busy list linkage */ | 381 | struct list_head ex_list; /* free or busy list linkage */ |
@@ -415,7 +423,7 @@ struct libfc_function_template { | |||
415 | * STATUS: OPTIONAL | 423 | * STATUS: OPTIONAL |
416 | */ | 424 | */ |
417 | struct fc_seq *(*elsct_send)(struct fc_lport *lport, | 425 | struct fc_seq *(*elsct_send)(struct fc_lport *lport, |
418 | struct fc_rport *rport, | 426 | u32 did, |
419 | struct fc_frame *fp, | 427 | struct fc_frame *fp, |
420 | unsigned int op, | 428 | unsigned int op, |
421 | void (*resp)(struct fc_seq *, | 429 | void (*resp)(struct fc_seq *, |
@@ -519,25 +527,6 @@ struct libfc_function_template { | |||
519 | void (*exch_done)(struct fc_seq *sp); | 527 | void (*exch_done)(struct fc_seq *sp); |
520 | 528 | ||
521 | /* | 529 | /* |
522 | * Assigns a EM and a free XID for an new exchange and then | ||
523 | * allocates a new exchange and sequence pair. | ||
524 | * The fp can be used to determine free XID. | ||
525 | * | ||
526 | * STATUS: OPTIONAL | ||
527 | */ | ||
528 | struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp); | ||
529 | |||
530 | /* | ||
531 | * Release previously assigned XID by exch_get API. | ||
532 | * The LLD may implement this if XID is assigned by LLD | ||
533 | * in exch_get(). | ||
534 | * | ||
535 | * STATUS: OPTIONAL | ||
536 | */ | ||
537 | void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp, | ||
538 | u16 ex_id); | ||
539 | |||
540 | /* | ||
541 | * Start a new sequence on the same exchange/sequence tuple. | 530 | * Start a new sequence on the same exchange/sequence tuple. |
542 | * | 531 | * |
543 | * STATUS: OPTIONAL | 532 | * STATUS: OPTIONAL |
@@ -577,9 +566,11 @@ struct libfc_function_template { | |||
577 | int (*lport_reset)(struct fc_lport *); | 566 | int (*lport_reset)(struct fc_lport *); |
578 | 567 | ||
579 | /* | 568 | /* |
580 | * Create a remote port | 569 | * Create a remote port with a given port ID |
570 | * | ||
571 | * STATUS: OPTIONAL | ||
581 | */ | 572 | */ |
582 | struct fc_rport *(*rport_create)(struct fc_disc_port *); | 573 | struct fc_rport_priv *(*rport_create)(struct fc_lport *, u32); |
583 | 574 | ||
584 | /* | 575 | /* |
585 | * Initiates the RP state machine. It is called from the LP module. | 576 | * Initiates the RP state machine. It is called from the LP module. |
@@ -592,7 +583,7 @@ struct libfc_function_template { | |||
592 | * | 583 | * |
593 | * STATUS: OPTIONAL | 584 | * STATUS: OPTIONAL |
594 | */ | 585 | */ |
595 | int (*rport_login)(struct fc_rport *rport); | 586 | int (*rport_login)(struct fc_rport_priv *); |
596 | 587 | ||
597 | /* | 588 | /* |
598 | * Logoff, and remove the rport from the transport if | 589 | * Logoff, and remove the rport from the transport if |
@@ -600,7 +591,7 @@ struct libfc_function_template { | |||
600 | * | 591 | * |
601 | * STATUS: OPTIONAL | 592 | * STATUS: OPTIONAL |
602 | */ | 593 | */ |
603 | int (*rport_logoff)(struct fc_rport *rport); | 594 | int (*rport_logoff)(struct fc_rport_priv *); |
604 | 595 | ||
605 | /* | 596 | /* |
606 | * Recieve a request from a remote port. | 597 | * Recieve a request from a remote port. |
@@ -608,14 +599,20 @@ struct libfc_function_template { | |||
608 | * STATUS: OPTIONAL | 599 | * STATUS: OPTIONAL |
609 | */ | 600 | */ |
610 | void (*rport_recv_req)(struct fc_seq *, struct fc_frame *, | 601 | void (*rport_recv_req)(struct fc_seq *, struct fc_frame *, |
611 | struct fc_rport *); | 602 | struct fc_lport *); |
612 | 603 | ||
613 | /* | 604 | /* |
614 | * lookup an rport by it's port ID. | 605 | * lookup an rport by it's port ID. |
615 | * | 606 | * |
616 | * STATUS: OPTIONAL | 607 | * STATUS: OPTIONAL |
617 | */ | 608 | */ |
618 | struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32); | 609 | struct fc_rport_priv *(*rport_lookup)(const struct fc_lport *, u32); |
610 | |||
611 | /* | ||
612 | * Destroy an rport after final kref_put(). | ||
613 | * The argument is a pointer to the kref inside the fc_rport_priv. | ||
614 | */ | ||
615 | void (*rport_destroy)(struct kref *); | ||
619 | 616 | ||
620 | /* | 617 | /* |
621 | * Send a fcp cmd from fsp pkt. | 618 | * Send a fcp cmd from fsp pkt. |
@@ -681,18 +678,16 @@ struct libfc_function_template { | |||
681 | /* information used by the discovery layer */ | 678 | /* information used by the discovery layer */ |
682 | struct fc_disc { | 679 | struct fc_disc { |
683 | unsigned char retry_count; | 680 | unsigned char retry_count; |
684 | unsigned char delay; | ||
685 | unsigned char pending; | 681 | unsigned char pending; |
686 | unsigned char requested; | 682 | unsigned char requested; |
687 | unsigned short seq_count; | 683 | unsigned short seq_count; |
688 | unsigned char buf_len; | 684 | unsigned char buf_len; |
689 | enum fc_disc_event event; | 685 | u16 disc_id; |
690 | 686 | ||
691 | void (*disc_callback)(struct fc_lport *, | 687 | void (*disc_callback)(struct fc_lport *, |
692 | enum fc_disc_event); | 688 | enum fc_disc_event); |
693 | 689 | ||
694 | struct list_head rports; | 690 | struct list_head rports; |
695 | struct list_head rogue_rports; | ||
696 | struct fc_lport *lport; | 691 | struct fc_lport *lport; |
697 | struct mutex disc_mutex; | 692 | struct mutex disc_mutex; |
698 | struct fc_gpn_ft_resp partial_buf; /* partial name buffer */ | 693 | struct fc_gpn_ft_resp partial_buf; /* partial name buffer */ |
@@ -704,9 +699,9 @@ struct fc_lport { | |||
704 | 699 | ||
705 | /* Associations */ | 700 | /* Associations */ |
706 | struct Scsi_Host *host; | 701 | struct Scsi_Host *host; |
707 | struct fc_exch_mgr *emp; | 702 | struct list_head ema_list; |
708 | struct fc_rport *dns_rp; | 703 | struct fc_rport_priv *dns_rp; |
709 | struct fc_rport *ptp_rp; | 704 | struct fc_rport_priv *ptp_rp; |
710 | void *scsi_priv; | 705 | void *scsi_priv; |
711 | struct fc_disc disc; | 706 | struct fc_disc disc; |
712 | 707 | ||
@@ -960,6 +955,28 @@ int fc_elsct_init(struct fc_lport *lp); | |||
960 | int fc_exch_init(struct fc_lport *lp); | 955 | int fc_exch_init(struct fc_lport *lp); |
961 | 956 | ||
962 | /* | 957 | /* |
958 | * Adds Exchange Manager (EM) mp to lport. | ||
959 | * | ||
960 | * Adds specified mp to lport using struct fc_exch_mgr_anchor, | ||
961 | * the struct fc_exch_mgr_anchor allows same EM sharing by | ||
962 | * more than one lport with their specified match function, | ||
963 | * the match function is used in allocating exchange from | ||
964 | * added mp. | ||
965 | */ | ||
966 | struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport, | ||
967 | struct fc_exch_mgr *mp, | ||
968 | bool (*match)(struct fc_frame *)); | ||
969 | |||
970 | /* | ||
971 | * Deletes Exchange Manager (EM) from lport by removing | ||
972 | * its anchor ema from lport. | ||
973 | * | ||
974 | * If removed anchor ema was the last user of its associated EM | ||
975 | * then also destroys associated EM. | ||
976 | */ | ||
977 | void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema); | ||
978 | |||
979 | /* | ||
963 | * Allocates an Exchange Manager (EM). | 980 | * Allocates an Exchange Manager (EM). |
964 | * | 981 | * |
965 | * The EM manages exchanges for their allocation and | 982 | * The EM manages exchanges for their allocation and |
@@ -974,27 +991,25 @@ int fc_exch_init(struct fc_lport *lp); | |||
974 | * a new exchange. | 991 | * a new exchange. |
975 | * The LLD may choose to have multiple EMs, | 992 | * The LLD may choose to have multiple EMs, |
976 | * e.g. one EM instance per CPU receive thread in LLD. | 993 | * e.g. one EM instance per CPU receive thread in LLD. |
977 | * The LLD can use exch_get() of struct libfc_function_template | ||
978 | * to specify XID for a new exchange within | ||
979 | * a specified EM instance. | ||
980 | * | 994 | * |
981 | * The em_idx to uniquely identify an EM instance. | 995 | * Specified match function is used in allocating exchanges |
996 | * from newly allocated EM. | ||
982 | */ | 997 | */ |
983 | struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, | 998 | struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, |
984 | enum fc_class class, | 999 | enum fc_class class, |
985 | u16 min_xid, | 1000 | u16 min_xid, |
986 | u16 max_xid); | 1001 | u16 max_xid, |
1002 | bool (*match)(struct fc_frame *)); | ||
987 | 1003 | ||
988 | /* | 1004 | /* |
989 | * Free an exchange manager. | 1005 | * Free all exchange managers of a lport. |
990 | */ | 1006 | */ |
991 | void fc_exch_mgr_free(struct fc_exch_mgr *mp); | 1007 | void fc_exch_mgr_free(struct fc_lport *lport); |
992 | 1008 | ||
993 | /* | 1009 | /* |
994 | * Receive a frame on specified local port and exchange manager. | 1010 | * Receive a frame on specified local port and exchange manager. |
995 | */ | 1011 | */ |
996 | void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, | 1012 | void fc_exch_recv(struct fc_lport *lp, struct fc_frame *fp); |
997 | struct fc_frame *fp); | ||
998 | 1013 | ||
999 | /* | 1014 | /* |
1000 | * This function is for exch_seq_send function pointer in | 1015 | * This function is for exch_seq_send function pointer in |
@@ -1036,28 +1051,20 @@ int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec); | |||
1036 | void fc_exch_done(struct fc_seq *sp); | 1051 | void fc_exch_done(struct fc_seq *sp); |
1037 | 1052 | ||
1038 | /* | 1053 | /* |
1039 | * Assigns a EM and XID for a frame and then allocates | ||
1040 | * a new exchange and sequence pair. | ||
1041 | * The fp can be used to determine free XID. | ||
1042 | */ | ||
1043 | struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp); | ||
1044 | |||
1045 | /* | ||
1046 | * Allocate a new exchange and sequence pair. | 1054 | * Allocate a new exchange and sequence pair. |
1047 | * if ex_id is zero then next free exchange id | ||
1048 | * from specified exchange manger mp will be assigned. | ||
1049 | */ | 1055 | */ |
1050 | struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, | 1056 | struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp); |
1051 | struct fc_frame *fp, u16 ex_id); | ||
1052 | /* | 1057 | /* |
1053 | * Start a new sequence on the same exchange as the supplied sequence. | 1058 | * Start a new sequence on the same exchange as the supplied sequence. |
1054 | */ | 1059 | */ |
1055 | struct fc_seq *fc_seq_start_next(struct fc_seq *sp); | 1060 | struct fc_seq *fc_seq_start_next(struct fc_seq *sp); |
1056 | 1061 | ||
1062 | |||
1057 | /* | 1063 | /* |
1058 | * Reset an exchange manager, completing all sequences and exchanges. | 1064 | * Reset all EMs of a lport, releasing its all sequences and |
1059 | * If s_id is non-zero, reset only exchanges originating from that FID. | 1065 | * exchanges. If sid is non-zero, then reset only exchanges |
1060 | * If d_id is non-zero, reset only exchanges sending to that FID. | 1066 | * we sourced from that FID. If did is non-zero, reset only |
1067 | * exchanges destined to that FID. | ||
1061 | */ | 1068 | */ |
1062 | void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id); | 1069 | void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id); |
1063 | 1070 | ||
@@ -1078,4 +1085,9 @@ void fc_destroy_exch_mgr(void); | |||
1078 | int fc_setup_rport(void); | 1085 | int fc_setup_rport(void); |
1079 | void fc_destroy_rport(void); | 1086 | void fc_destroy_rport(void); |
1080 | 1087 | ||
1088 | /* | ||
1089 | * Internal libfc functions. | ||
1090 | */ | ||
1091 | const char *fc_els_resp_type(struct fc_frame *); | ||
1092 | |||
1081 | #endif /* _LIBFC_H_ */ | 1093 | #endif /* _LIBFC_H_ */ |