2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 * Maintained at www.Open-FCoE.org
23 * These comments only apply to the 'port code' which consists of the lport,
24 * disc and rport blocks.
28 * The lport, disc and rport blocks all have mutexes that are used to protect
29 * those objects. The main motivation for these locks is to prevent from
30 * having an lport reset just before we send a frame. In that scenario the
31 * lport's FID would get set to zero and then we'd send a frame with an
32 * invalid SID. We also need to ensure that states don't change unexpectedly
33 * while processing another state.
37 * The following heirarchy defines the locking rules. A greater lock
38 * may be held before acquiring a lesser lock, but a lesser lock should never
39 * be held while attempting to acquire a greater lock. Here is the heirarchy-
41 * lport > disc, lport > rport, disc > rport
45 * The callbacks cause complications with this scheme. There is a callback
46 * from the rport (to either lport or disc) and a callback from disc
49 * As rports exit the rport state machine a callback is made to the owner of
50 * the rport to notify success or failure. Since the callback is likely to
51 * cause the lport or disc to grab its lock we cannot hold the rport lock
52 * while making the callback. To ensure that the rport is not free'd while
53 * processing the callback the rport callbacks are serialized through a
54 * single-threaded workqueue. An rport would never be free'd while in a
55 * callback handler becuase no other rport work in this queue can be executed
58 * When discovery succeeds or fails a callback is made to the lport as
59 * notification. Currently, succesful discovery causes the lport to take no
60 * action. A failure will cause the lport to reset. There is likely a circular
61 * locking problem with this implementation.
67 * The critical sections protected by the lport's mutex are quite broad and
68 * may be improved upon in the future. The lport code and its locking doesn't
69 * influence the I/O path, so excessive locking doesn't penalize I/O
72 * The strategy is to lock whenever processing a request or response. Note
73 * that every _enter_* function corresponds to a state change. They generally
74 * change the lports state and then send a request out on the wire. We lock
75 * before calling any of these functions to protect that state change. This
76 * means that the entry points into the lport block manage the locks while
77 * the state machine can transition between states (i.e. _enter_* functions)
78 * while always staying protected.
80 * When handling responses we also hold the lport mutex broadly. When the
81 * lport receives the response frame it locks the mutex and then calls the
82 * appropriate handler for the particuar response. Generally a response will
83 * trigger a state change and so the lock must already be held.
85 * Retries also have to consider the locking. The retries occur from a work
86 * context and the work function will lock the lport and then retry the state
87 * (i.e. _enter_* function).
90 #include <linux/timer.h>
91 #include <asm/unaligned.h>
93 #include <scsi/fc/fc_gs.h>
95 #include <scsi/libfc.h>
96 #include <scsi/fc_encode.h>
98 /* Fabric IDs to use for point-to-point mode, chosen on whims. */
99 #define FC_LOCAL_PTP_FID_LO 0x010101
100 #define FC_LOCAL_PTP_FID_HI 0x010102
102 #define DNS_DELAY 3 /* Discovery delay after RSCN (in seconds)*/
104 static void fc_lport_error(struct fc_lport
*, struct fc_frame
*);
106 static void fc_lport_enter_reset(struct fc_lport
*);
107 static void fc_lport_enter_flogi(struct fc_lport
*);
108 static void fc_lport_enter_dns(struct fc_lport
*);
109 static void fc_lport_enter_rpn_id(struct fc_lport
*);
110 static void fc_lport_enter_rft_id(struct fc_lport
*);
111 static void fc_lport_enter_scr(struct fc_lport
*);
112 static void fc_lport_enter_ready(struct fc_lport
*);
113 static void fc_lport_enter_logo(struct fc_lport
*);
115 static const char *fc_lport_state_names
[] = {
116 [LPORT_ST_DISABLED
] = "disabled",
117 [LPORT_ST_FLOGI
] = "FLOGI",
118 [LPORT_ST_DNS
] = "dNS",
119 [LPORT_ST_RPN_ID
] = "RPN_ID",
120 [LPORT_ST_RFT_ID
] = "RFT_ID",
121 [LPORT_ST_SCR
] = "SCR",
122 [LPORT_ST_READY
] = "Ready",
123 [LPORT_ST_LOGO
] = "LOGO",
124 [LPORT_ST_RESET
] = "reset",
127 static int fc_frame_drop(struct fc_lport
*lport
, struct fc_frame
*fp
)
134 * fc_lport_rport_callback() - Event handler for rport events
135 * @lport: The lport which is receiving the event
136 * @rdata: private remote port data
137 * @event: The event that occured
139 * Locking Note: The rport lock should not be held when calling
142 static void fc_lport_rport_callback(struct fc_lport
*lport
,
143 struct fc_rport_priv
*rdata
,
144 enum fc_rport_event event
)
146 struct fc_rport
*rport
= PRIV_TO_RPORT(rdata
);
148 FC_LPORT_DBG(lport
, "Received a %d event for port (%6x)\n", event
,
152 case RPORT_EV_CREATED
:
153 if (rport
->port_id
== FC_FID_DIR_SERV
) {
154 mutex_lock(&lport
->lp_mutex
);
155 if (lport
->state
== LPORT_ST_DNS
) {
156 lport
->dns_rp
= rdata
;
157 fc_lport_enter_rpn_id(lport
);
159 FC_LPORT_DBG(lport
, "Received an CREATED event "
160 "on port (%6x) for the directory "
161 "server, but the lport is not "
162 "in the DNS state, it's in the "
163 "%d state", rport
->port_id
,
165 lport
->tt
.rport_logoff(rdata
);
167 mutex_unlock(&lport
->lp_mutex
);
169 FC_LPORT_DBG(lport
, "Received an event for port (%6x) "
170 "which is not the directory server\n",
174 case RPORT_EV_FAILED
:
176 if (rport
->port_id
== FC_FID_DIR_SERV
) {
177 mutex_lock(&lport
->lp_mutex
);
178 lport
->dns_rp
= NULL
;
179 mutex_unlock(&lport
->lp_mutex
);
182 FC_LPORT_DBG(lport
, "Received an event for port (%6x) "
183 "which is not the directory server\n",
192 * fc_lport_state() - Return a string which represents the lport's state
193 * @lport: The lport whose state is to converted to a string
195 static const char *fc_lport_state(struct fc_lport
*lport
)
199 cp
= fc_lport_state_names
[lport
->state
];
206 * fc_lport_ptp_setup() - Create an rport for point-to-point mode
207 * @lport: The lport to attach the ptp rport to
208 * @fid: The FID of the ptp rport
209 * @remote_wwpn: The WWPN of the ptp rport
210 * @remote_wwnn: The WWNN of the ptp rport
212 static void fc_lport_ptp_setup(struct fc_lport
*lport
,
213 u32 remote_fid
, u64 remote_wwpn
,
216 struct fc_rport_identifiers ids
;
218 ids
.port_id
= remote_fid
;
219 ids
.port_name
= remote_wwpn
;
220 ids
.node_name
= remote_wwnn
;
221 ids
.roles
= FC_RPORT_ROLE_UNKNOWN
;
224 lport
->tt
.rport_logoff(lport
->ptp_rp
);
225 lport
->ptp_rp
= NULL
;
228 lport
->ptp_rp
= lport
->tt
.rport_create(lport
, &ids
);
230 lport
->tt
.rport_login(lport
->ptp_rp
);
232 fc_lport_enter_ready(lport
);
235 void fc_get_host_port_type(struct Scsi_Host
*shost
)
237 /* TODO - currently just NPORT */
238 fc_host_port_type(shost
) = FC_PORTTYPE_NPORT
;
240 EXPORT_SYMBOL(fc_get_host_port_type
);
242 void fc_get_host_port_state(struct Scsi_Host
*shost
)
244 struct fc_lport
*lp
= shost_priv(shost
);
247 fc_host_port_state(shost
) = FC_PORTSTATE_ONLINE
;
249 fc_host_port_state(shost
) = FC_PORTSTATE_OFFLINE
;
251 EXPORT_SYMBOL(fc_get_host_port_state
);
253 void fc_get_host_speed(struct Scsi_Host
*shost
)
255 struct fc_lport
*lport
= shost_priv(shost
);
257 fc_host_speed(shost
) = lport
->link_speed
;
259 EXPORT_SYMBOL(fc_get_host_speed
);
261 struct fc_host_statistics
*fc_get_host_stats(struct Scsi_Host
*shost
)
263 struct fc_host_statistics
*fcoe_stats
;
264 struct fc_lport
*lp
= shost_priv(shost
);
265 struct timespec v0
, v1
;
268 fcoe_stats
= &lp
->host_stats
;
269 memset(fcoe_stats
, 0, sizeof(struct fc_host_statistics
));
271 jiffies_to_timespec(jiffies
, &v0
);
272 jiffies_to_timespec(lp
->boot_time
, &v1
);
273 fcoe_stats
->seconds_since_last_reset
= (v0
.tv_sec
- v1
.tv_sec
);
275 for_each_possible_cpu(cpu
) {
276 struct fcoe_dev_stats
*stats
;
278 stats
= per_cpu_ptr(lp
->dev_stats
, cpu
);
280 fcoe_stats
->tx_frames
+= stats
->TxFrames
;
281 fcoe_stats
->tx_words
+= stats
->TxWords
;
282 fcoe_stats
->rx_frames
+= stats
->RxFrames
;
283 fcoe_stats
->rx_words
+= stats
->RxWords
;
284 fcoe_stats
->error_frames
+= stats
->ErrorFrames
;
285 fcoe_stats
->invalid_crc_count
+= stats
->InvalidCRCCount
;
286 fcoe_stats
->fcp_input_requests
+= stats
->InputRequests
;
287 fcoe_stats
->fcp_output_requests
+= stats
->OutputRequests
;
288 fcoe_stats
->fcp_control_requests
+= stats
->ControlRequests
;
289 fcoe_stats
->fcp_input_megabytes
+= stats
->InputMegabytes
;
290 fcoe_stats
->fcp_output_megabytes
+= stats
->OutputMegabytes
;
291 fcoe_stats
->link_failure_count
+= stats
->LinkFailureCount
;
293 fcoe_stats
->lip_count
= -1;
294 fcoe_stats
->nos_count
= -1;
295 fcoe_stats
->loss_of_sync_count
= -1;
296 fcoe_stats
->loss_of_signal_count
= -1;
297 fcoe_stats
->prim_seq_protocol_err_count
= -1;
298 fcoe_stats
->dumped_frames
= -1;
301 EXPORT_SYMBOL(fc_get_host_stats
);
304 * Fill in FLOGI command for request.
307 fc_lport_flogi_fill(struct fc_lport
*lport
, struct fc_els_flogi
*flogi
,
310 struct fc_els_csp
*sp
;
311 struct fc_els_cssp
*cp
;
313 memset(flogi
, 0, sizeof(*flogi
));
314 flogi
->fl_cmd
= (u8
) op
;
315 put_unaligned_be64(lport
->wwpn
, &flogi
->fl_wwpn
);
316 put_unaligned_be64(lport
->wwnn
, &flogi
->fl_wwnn
);
318 sp
->sp_hi_ver
= 0x20;
319 sp
->sp_lo_ver
= 0x20;
320 sp
->sp_bb_cred
= htons(10); /* this gets set by gateway */
321 sp
->sp_bb_data
= htons((u16
) lport
->mfs
);
322 cp
= &flogi
->fl_cssp
[3 - 1]; /* class 3 parameters */
323 cp
->cp_class
= htons(FC_CPC_VALID
| FC_CPC_SEQ
);
324 if (op
!= ELS_FLOGI
) {
325 sp
->sp_features
= htons(FC_SP_FT_CIRO
);
326 sp
->sp_tot_seq
= htons(255); /* seq. we accept */
327 sp
->sp_rel_off
= htons(0x1f);
328 sp
->sp_e_d_tov
= htonl(lport
->e_d_tov
);
330 cp
->cp_rdfs
= htons((u16
) lport
->mfs
);
331 cp
->cp_con_seq
= htons(255);
337 * Add a supported FC-4 type.
339 static void fc_lport_add_fc4_type(struct fc_lport
*lport
, enum fc_fh_type type
)
343 mp
= &lport
->fcts
.ff_type_map
[type
/ FC_NS_BPW
];
344 *mp
= htonl(ntohl(*mp
) | 1UL << (type
% FC_NS_BPW
));
348 * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report.
349 * @lport: Fibre Channel local port recieving the RLIR
350 * @sp: current sequence in the RLIR exchange
351 * @fp: RLIR request frame
353 * Locking Note: The lport lock is exected to be held before calling
356 static void fc_lport_recv_rlir_req(struct fc_seq
*sp
, struct fc_frame
*fp
,
357 struct fc_lport
*lport
)
359 FC_LPORT_DBG(lport
, "Received RLIR request while in state %s\n",
360 fc_lport_state(lport
));
362 lport
->tt
.seq_els_rsp_send(sp
, ELS_LS_ACC
, NULL
);
367 * fc_lport_recv_echo_req() - Handle received ECHO request
368 * @lport: Fibre Channel local port recieving the ECHO
369 * @sp: current sequence in the ECHO exchange
370 * @fp: ECHO request frame
372 * Locking Note: The lport lock is exected to be held before calling
375 static void fc_lport_recv_echo_req(struct fc_seq
*sp
, struct fc_frame
*in_fp
,
376 struct fc_lport
*lport
)
379 struct fc_exch
*ep
= fc_seq_exch(sp
);
385 FC_LPORT_DBG(lport
, "Received RLIR request while in state %s\n",
386 fc_lport_state(lport
));
388 len
= fr_len(in_fp
) - sizeof(struct fc_frame_header
);
389 pp
= fc_frame_payload_get(in_fp
, len
);
391 if (len
< sizeof(__be32
))
392 len
= sizeof(__be32
);
394 fp
= fc_frame_alloc(lport
, len
);
396 dp
= fc_frame_payload_get(fp
, len
);
398 *((u32
*)dp
) = htonl(ELS_LS_ACC
<< 24);
399 sp
= lport
->tt
.seq_start_next(sp
);
400 f_ctl
= FC_FC_EX_CTX
| FC_FC_LAST_SEQ
| FC_FC_END_SEQ
;
401 fc_fill_fc_hdr(fp
, FC_RCTL_ELS_REP
, ep
->did
, ep
->sid
,
402 FC_TYPE_ELS
, f_ctl
, 0);
403 lport
->tt
.seq_send(lport
, sp
, fp
);
405 fc_frame_free(in_fp
);
409 * fc_lport_recv_echo_req() - Handle received Request Node ID data request
410 * @lport: Fibre Channel local port recieving the RNID
411 * @sp: current sequence in the RNID exchange
412 * @fp: RNID request frame
414 * Locking Note: The lport lock is exected to be held before calling
417 static void fc_lport_recv_rnid_req(struct fc_seq
*sp
, struct fc_frame
*in_fp
,
418 struct fc_lport
*lport
)
421 struct fc_exch
*ep
= fc_seq_exch(sp
);
422 struct fc_els_rnid
*req
;
424 struct fc_els_rnid_resp rnid
;
425 struct fc_els_rnid_cid cid
;
426 struct fc_els_rnid_gen gen
;
428 struct fc_seq_els_data rjt_data
;
433 FC_LPORT_DBG(lport
, "Received RNID request while in state %s\n",
434 fc_lport_state(lport
));
436 req
= fc_frame_payload_get(in_fp
, sizeof(*req
));
439 rjt_data
.reason
= ELS_RJT_LOGIC
;
440 rjt_data
.explan
= ELS_EXPL_NONE
;
441 lport
->tt
.seq_els_rsp_send(sp
, ELS_LS_RJT
, &rjt_data
);
445 if (fmt
!= ELS_RNIDF_GEN
||
446 ntohl(lport
->rnid_gen
.rnid_atype
) == 0) {
447 fmt
= ELS_RNIDF_NONE
; /* nothing to provide */
448 len
-= sizeof(rp
->gen
);
450 fp
= fc_frame_alloc(lport
, len
);
452 rp
= fc_frame_payload_get(fp
, len
);
454 rp
->rnid
.rnid_cmd
= ELS_LS_ACC
;
455 rp
->rnid
.rnid_fmt
= fmt
;
456 rp
->rnid
.rnid_cid_len
= sizeof(rp
->cid
);
457 rp
->cid
.rnid_wwpn
= htonll(lport
->wwpn
);
458 rp
->cid
.rnid_wwnn
= htonll(lport
->wwnn
);
459 if (fmt
== ELS_RNIDF_GEN
) {
460 rp
->rnid
.rnid_sid_len
= sizeof(rp
->gen
);
461 memcpy(&rp
->gen
, &lport
->rnid_gen
,
464 sp
= lport
->tt
.seq_start_next(sp
);
465 f_ctl
= FC_FC_EX_CTX
| FC_FC_LAST_SEQ
;
466 f_ctl
|= FC_FC_END_SEQ
| FC_FC_SEQ_INIT
;
467 fc_fill_fc_hdr(fp
, FC_RCTL_ELS_REP
, ep
->did
, ep
->sid
,
468 FC_TYPE_ELS
, f_ctl
, 0);
469 lport
->tt
.seq_send(lport
, sp
, fp
);
472 fc_frame_free(in_fp
);
476 * fc_lport_recv_adisc_req() - Handle received Address Discovery Request
477 * @lport: Fibre Channel local port recieving the ADISC
478 * @sp: current sequence in the ADISC exchange
479 * @fp: ADISC request frame
481 * Locking Note: The lport lock is expected to be held before calling
484 static void fc_lport_recv_adisc_req(struct fc_seq
*sp
, struct fc_frame
*in_fp
,
485 struct fc_lport
*lport
)
488 struct fc_exch
*ep
= fc_seq_exch(sp
);
489 struct fc_els_adisc
*req
, *rp
;
490 struct fc_seq_els_data rjt_data
;
494 FC_LPORT_DBG(lport
, "Received ADISC request while in state %s\n",
495 fc_lport_state(lport
));
497 req
= fc_frame_payload_get(in_fp
, sizeof(*req
));
500 rjt_data
.reason
= ELS_RJT_LOGIC
;
501 rjt_data
.explan
= ELS_EXPL_NONE
;
502 lport
->tt
.seq_els_rsp_send(sp
, ELS_LS_RJT
, &rjt_data
);
505 fp
= fc_frame_alloc(lport
, len
);
507 rp
= fc_frame_payload_get(fp
, len
);
509 rp
->adisc_cmd
= ELS_LS_ACC
;
510 rp
->adisc_wwpn
= htonll(lport
->wwpn
);
511 rp
->adisc_wwnn
= htonll(lport
->wwnn
);
512 hton24(rp
->adisc_port_id
,
513 fc_host_port_id(lport
->host
));
514 sp
= lport
->tt
.seq_start_next(sp
);
515 f_ctl
= FC_FC_EX_CTX
| FC_FC_LAST_SEQ
;
516 f_ctl
|= FC_FC_END_SEQ
| FC_FC_SEQ_INIT
;
517 fc_fill_fc_hdr(fp
, FC_RCTL_ELS_REP
, ep
->did
, ep
->sid
,
518 FC_TYPE_ELS
, f_ctl
, 0);
519 lport
->tt
.seq_send(lport
, sp
, fp
);
522 fc_frame_free(in_fp
);
526 * fc_lport_recv_logo_req() - Handle received fabric LOGO request
527 * @lport: Fibre Channel local port recieving the LOGO
528 * @sp: current sequence in the LOGO exchange
529 * @fp: LOGO request frame
531 * Locking Note: The lport lock is exected to be held before calling
534 static void fc_lport_recv_logo_req(struct fc_seq
*sp
, struct fc_frame
*fp
,
535 struct fc_lport
*lport
)
537 lport
->tt
.seq_els_rsp_send(sp
, ELS_LS_ACC
, NULL
);
538 fc_lport_enter_reset(lport
);
543 * fc_fabric_login() - Start the lport state machine
544 * @lport: The lport that should log into the fabric
546 * Locking Note: This function should not be called
547 * with the lport lock held.
549 int fc_fabric_login(struct fc_lport
*lport
)
553 mutex_lock(&lport
->lp_mutex
);
554 if (lport
->state
== LPORT_ST_DISABLED
) {
555 fc_lport_enter_reset(lport
);
558 mutex_unlock(&lport
->lp_mutex
);
562 EXPORT_SYMBOL(fc_fabric_login
);
565 * fc_linkup() - Handler for transport linkup events
566 * @lport: The lport whose link is up
568 void fc_linkup(struct fc_lport
*lport
)
570 printk(KERN_INFO
"libfc: Link up on port (%6x)\n",
571 fc_host_port_id(lport
->host
));
573 mutex_lock(&lport
->lp_mutex
);
574 if (!lport
->link_up
) {
577 if (lport
->state
== LPORT_ST_RESET
)
578 fc_lport_enter_flogi(lport
);
580 mutex_unlock(&lport
->lp_mutex
);
582 EXPORT_SYMBOL(fc_linkup
);
585 * fc_linkdown() - Handler for transport linkdown events
586 * @lport: The lport whose link is down
588 void fc_linkdown(struct fc_lport
*lport
)
590 mutex_lock(&lport
->lp_mutex
);
591 printk(KERN_INFO
"libfc: Link down on port (%6x)\n",
592 fc_host_port_id(lport
->host
));
594 if (lport
->link_up
) {
596 fc_lport_enter_reset(lport
);
597 lport
->tt
.fcp_cleanup(lport
);
599 mutex_unlock(&lport
->lp_mutex
);
601 EXPORT_SYMBOL(fc_linkdown
);
604 * fc_fabric_logoff() - Logout of the fabric
605 * @lport: fc_lport pointer to logoff the fabric
608 * 0 for success, -1 for failure
610 int fc_fabric_logoff(struct fc_lport
*lport
)
612 lport
->tt
.disc_stop_final(lport
);
613 mutex_lock(&lport
->lp_mutex
);
615 lport
->tt
.rport_logoff(lport
->dns_rp
);
616 mutex_unlock(&lport
->lp_mutex
);
617 lport
->tt
.rport_flush_queue();
618 mutex_lock(&lport
->lp_mutex
);
619 fc_lport_enter_logo(lport
);
620 mutex_unlock(&lport
->lp_mutex
);
621 cancel_delayed_work_sync(&lport
->retry_work
);
624 EXPORT_SYMBOL(fc_fabric_logoff
);
627 * fc_lport_destroy() - unregister a fc_lport
628 * @lport: fc_lport pointer to unregister
633 * exit routine for fc_lport instance
634 * clean-up all the allocated memory
635 * and free up other system resources.
638 int fc_lport_destroy(struct fc_lport
*lport
)
640 mutex_lock(&lport
->lp_mutex
);
641 lport
->state
= LPORT_ST_DISABLED
;
643 lport
->tt
.frame_send
= fc_frame_drop
;
644 mutex_unlock(&lport
->lp_mutex
);
646 lport
->tt
.fcp_abort_io(lport
);
647 lport
->tt
.disc_stop_final(lport
);
648 lport
->tt
.exch_mgr_reset(lport
, 0, 0);
651 EXPORT_SYMBOL(fc_lport_destroy
);
654 * fc_set_mfs() - sets up the mfs for the corresponding fc_lport
655 * @lport: fc_lport pointer to unregister
656 * @mfs: the new mfs for fc_lport
658 * Set mfs for the given fc_lport to the new mfs.
660 * Return: 0 for success
662 int fc_set_mfs(struct fc_lport
*lport
, u32 mfs
)
664 unsigned int old_mfs
;
667 mutex_lock(&lport
->lp_mutex
);
669 old_mfs
= lport
->mfs
;
671 if (mfs
>= FC_MIN_MAX_FRAME
) {
673 if (mfs
> FC_MAX_FRAME
)
675 mfs
-= sizeof(struct fc_frame_header
);
680 if (!rc
&& mfs
< old_mfs
)
681 fc_lport_enter_reset(lport
);
683 mutex_unlock(&lport
->lp_mutex
);
687 EXPORT_SYMBOL(fc_set_mfs
);
690 * fc_lport_disc_callback() - Callback for discovery events
691 * @lport: FC local port
692 * @event: The discovery event
694 void fc_lport_disc_callback(struct fc_lport
*lport
, enum fc_disc_event event
)
697 case DISC_EV_SUCCESS
:
698 FC_LPORT_DBG(lport
, "Discovery succeeded\n");
701 printk(KERN_ERR
"libfc: Discovery failed for port (%6x)\n",
702 fc_host_port_id(lport
->host
));
703 mutex_lock(&lport
->lp_mutex
);
704 fc_lport_enter_reset(lport
);
705 mutex_unlock(&lport
->lp_mutex
);
714 * fc_rport_enter_ready() - Enter the ready state and start discovery
715 * @lport: Fibre Channel local port that is ready
717 * Locking Note: The lport lock is expected to be held before calling
720 static void fc_lport_enter_ready(struct fc_lport
*lport
)
722 FC_LPORT_DBG(lport
, "Entered READY from state %s\n",
723 fc_lport_state(lport
));
725 fc_lport_state_enter(lport
, LPORT_ST_READY
);
727 lport
->tt
.disc_start(fc_lport_disc_callback
, lport
);
731 * fc_lport_recv_flogi_req() - Receive a FLOGI request
732 * @sp_in: The sequence the FLOGI is on
733 * @rx_fp: The frame the FLOGI is in
734 * @lport: The lport that recieved the request
736 * A received FLOGI request indicates a point-to-point connection.
737 * Accept it with the common service parameters indicating our N port.
738 * Set up to do a PLOGI if we have the higher-number WWPN.
740 * Locking Note: The lport lock is exected to be held before calling
743 static void fc_lport_recv_flogi_req(struct fc_seq
*sp_in
,
744 struct fc_frame
*rx_fp
,
745 struct fc_lport
*lport
)
748 struct fc_frame_header
*fh
;
751 struct fc_els_flogi
*flp
;
752 struct fc_els_flogi
*new_flp
;
758 FC_LPORT_DBG(lport
, "Received FLOGI request while in state %s\n",
759 fc_lport_state(lport
));
761 fh
= fc_frame_header_get(rx_fp
);
762 remote_fid
= ntoh24(fh
->fh_s_id
);
763 flp
= fc_frame_payload_get(rx_fp
, sizeof(*flp
));
766 remote_wwpn
= get_unaligned_be64(&flp
->fl_wwpn
);
767 if (remote_wwpn
== lport
->wwpn
) {
768 printk(KERN_WARNING
"libfc: Received FLOGI from port "
769 "with same WWPN %llx\n", remote_wwpn
);
772 FC_LPORT_DBG(lport
, "FLOGI from port WWPN %llx\n", remote_wwpn
);
775 * XXX what is the right thing to do for FIDs?
776 * The originator might expect our S_ID to be 0xfffffe.
777 * But if so, both of us could end up with the same FID.
779 local_fid
= FC_LOCAL_PTP_FID_LO
;
780 if (remote_wwpn
< lport
->wwpn
) {
781 local_fid
= FC_LOCAL_PTP_FID_HI
;
782 if (!remote_fid
|| remote_fid
== local_fid
)
783 remote_fid
= FC_LOCAL_PTP_FID_LO
;
784 } else if (!remote_fid
) {
785 remote_fid
= FC_LOCAL_PTP_FID_HI
;
788 fc_host_port_id(lport
->host
) = local_fid
;
790 fp
= fc_frame_alloc(lport
, sizeof(*flp
));
792 sp
= lport
->tt
.seq_start_next(fr_seq(rx_fp
));
793 new_flp
= fc_frame_payload_get(fp
, sizeof(*flp
));
794 fc_lport_flogi_fill(lport
, new_flp
, ELS_FLOGI
);
795 new_flp
->fl_cmd
= (u8
) ELS_LS_ACC
;
798 * Send the response. If this fails, the originator should
799 * repeat the sequence.
801 f_ctl
= FC_FC_EX_CTX
| FC_FC_LAST_SEQ
| FC_FC_END_SEQ
;
802 ep
= fc_seq_exch(sp
);
803 fc_fill_fc_hdr(fp
, FC_RCTL_ELS_REP
, ep
->did
, ep
->sid
,
804 FC_TYPE_ELS
, f_ctl
, 0);
805 lport
->tt
.seq_send(lport
, sp
, fp
);
808 fc_lport_error(lport
, fp
);
810 fc_lport_ptp_setup(lport
, remote_fid
, remote_wwpn
,
811 get_unaligned_be64(&flp
->fl_wwnn
));
813 lport
->tt
.disc_start(fc_lport_disc_callback
, lport
);
817 fc_frame_free(rx_fp
);
821 * fc_lport_recv_req() - The generic lport request handler
822 * @lport: The lport that received the request
823 * @sp: The sequence the request is on
824 * @fp: The frame the request is in
826 * This function will see if the lport handles the request or
827 * if an rport should handle the request.
829 * Locking Note: This function should not be called with the lport
830 * lock held becuase it will grab the lock.
832 static void fc_lport_recv_req(struct fc_lport
*lport
, struct fc_seq
*sp
,
835 struct fc_frame_header
*fh
= fc_frame_header_get(fp
);
836 void (*recv
) (struct fc_seq
*, struct fc_frame
*, struct fc_lport
*);
837 struct fc_rport_priv
*rdata
;
840 struct fc_seq_els_data rjt_data
;
842 mutex_lock(&lport
->lp_mutex
);
845 * Handle special ELS cases like FLOGI, LOGO, and
846 * RSCN here. These don't require a session.
847 * Even if we had a session, it might not be ready.
851 else if (fh
->fh_type
== FC_TYPE_ELS
&&
852 fh
->fh_r_ctl
== FC_RCTL_ELS_REQ
) {
857 switch (fc_frame_payload_op(fp
)) {
859 recv
= fc_lport_recv_flogi_req
;
862 fh
= fc_frame_header_get(fp
);
863 if (ntoh24(fh
->fh_s_id
) == FC_FID_FLOGI
)
864 recv
= fc_lport_recv_logo_req
;
867 recv
= lport
->tt
.disc_recv_req
;
870 recv
= fc_lport_recv_echo_req
;
873 recv
= fc_lport_recv_rlir_req
;
876 recv
= fc_lport_recv_rnid_req
;
879 recv
= fc_lport_recv_adisc_req
;
888 * If this is a new incoming PLOGI, we won't find it.
890 s_id
= ntoh24(fh
->fh_s_id
);
891 d_id
= ntoh24(fh
->fh_d_id
);
893 rdata
= lport
->tt
.rport_lookup(lport
, s_id
);
895 lport
->tt
.rport_recv_req(sp
, fp
, rdata
);
898 rjt_data
.reason
= ELS_RJT_UNAB
;
899 rjt_data
.explan
= ELS_EXPL_NONE
;
900 lport
->tt
.seq_els_rsp_send(sp
,
907 FC_LPORT_DBG(lport
, "dropping invalid frame (eof %x)\n",
911 mutex_unlock(&lport
->lp_mutex
);
914 * The common exch_done for all request may not be good
915 * if any request requires longer hold on exhange. XXX
917 lport
->tt
.exch_done(sp
);
921 * fc_lport_reset() - Reset an lport
922 * @lport: The lport which should be reset
924 * Locking Note: This functions should not be called with the
927 int fc_lport_reset(struct fc_lport
*lport
)
929 cancel_delayed_work_sync(&lport
->retry_work
);
930 mutex_lock(&lport
->lp_mutex
);
931 fc_lport_enter_reset(lport
);
932 mutex_unlock(&lport
->lp_mutex
);
935 EXPORT_SYMBOL(fc_lport_reset
);
938 * fc_lport_reset_locked() - Reset the local port
939 * @lport: Fibre Channel local port to be reset
941 * Locking Note: The lport lock is expected to be held before calling
944 static void fc_lport_reset_locked(struct fc_lport
*lport
)
947 lport
->tt
.rport_logoff(lport
->dns_rp
);
950 lport
->tt
.rport_logoff(lport
->ptp_rp
);
951 lport
->ptp_rp
= NULL
;
954 lport
->tt
.disc_stop(lport
);
956 lport
->tt
.exch_mgr_reset(lport
, 0, 0);
957 fc_host_fabric_name(lport
->host
) = 0;
958 fc_host_port_id(lport
->host
) = 0;
962 * fc_lport_enter_reset() - Reset the local port
963 * @lport: Fibre Channel local port to be reset
965 * Locking Note: The lport lock is expected to be held before calling
968 static void fc_lport_enter_reset(struct fc_lport
*lport
)
970 FC_LPORT_DBG(lport
, "Entered RESET state from %s state\n",
971 fc_lport_state(lport
));
973 fc_lport_state_enter(lport
, LPORT_ST_RESET
);
974 fc_lport_reset_locked(lport
);
976 fc_lport_enter_flogi(lport
);
980 * fc_lport_enter_disabled() - disable the local port
981 * @lport: Fibre Channel local port to be reset
983 * Locking Note: The lport lock is expected to be held before calling
986 static void fc_lport_enter_disabled(struct fc_lport
*lport
)
988 FC_LPORT_DBG(lport
, "Entered disabled state from %s state\n",
989 fc_lport_state(lport
));
991 fc_lport_state_enter(lport
, LPORT_ST_DISABLED
);
992 fc_lport_reset_locked(lport
);
996 * fc_lport_error() - Handler for any errors
997 * @lport: The fc_lport object
998 * @fp: The frame pointer
1000 * If the error was caused by a resource allocation failure
1001 * then wait for half a second and retry, otherwise retry
1002 * after the e_d_tov time.
1004 static void fc_lport_error(struct fc_lport
*lport
, struct fc_frame
*fp
)
1006 unsigned long delay
= 0;
1007 FC_LPORT_DBG(lport
, "Error %ld in state %s, retries %d\n",
1008 PTR_ERR(fp
), fc_lport_state(lport
),
1009 lport
->retry_count
);
1011 if (!fp
|| PTR_ERR(fp
) == -FC_EX_TIMEOUT
) {
1013 * Memory allocation failure, or the exchange timed out.
1016 if (lport
->retry_count
< lport
->max_retry_count
) {
1017 lport
->retry_count
++;
1019 delay
= msecs_to_jiffies(500);
1021 delay
= msecs_to_jiffies(lport
->e_d_tov
);
1023 schedule_delayed_work(&lport
->retry_work
, delay
);
1025 switch (lport
->state
) {
1026 case LPORT_ST_DISABLED
:
1027 case LPORT_ST_READY
:
1028 case LPORT_ST_RESET
:
1029 case LPORT_ST_RPN_ID
:
1030 case LPORT_ST_RFT_ID
:
1033 case LPORT_ST_FLOGI
:
1035 fc_lport_enter_reset(lport
);
1043 * fc_lport_rft_id_resp() - Handle response to Register Fibre
1044 * Channel Types by ID (RPN_ID) request
1045 * @sp: current sequence in RPN_ID exchange
1046 * @fp: response frame
1047 * @lp_arg: Fibre Channel host port instance
1049 * Locking Note: This function will be called without the lport lock
1050 * held, but it will lock, call an _enter_* function or fc_lport_error
1051 * and then unlock the lport.
1053 static void fc_lport_rft_id_resp(struct fc_seq
*sp
, struct fc_frame
*fp
,
1056 struct fc_lport
*lport
= lp_arg
;
1057 struct fc_frame_header
*fh
;
1058 struct fc_ct_hdr
*ct
;
1060 if (fp
== ERR_PTR(-FC_EX_CLOSED
))
1063 mutex_lock(&lport
->lp_mutex
);
1065 FC_LPORT_DBG(lport
, "Received a RFT_ID response\n");
1067 if (lport
->state
!= LPORT_ST_RFT_ID
) {
1068 FC_LPORT_DBG(lport
, "Received a RFT_ID response, but in state "
1069 "%s\n", fc_lport_state(lport
));
1076 fc_lport_error(lport
, fp
);
1080 fh
= fc_frame_header_get(fp
);
1081 ct
= fc_frame_payload_get(fp
, sizeof(*ct
));
1083 if (fh
&& ct
&& fh
->fh_type
== FC_TYPE_CT
&&
1084 ct
->ct_fs_type
== FC_FST_DIR
&&
1085 ct
->ct_fs_subtype
== FC_NS_SUBTYPE
&&
1086 ntohs(ct
->ct_cmd
) == FC_FS_ACC
)
1087 fc_lport_enter_scr(lport
);
1089 fc_lport_error(lport
, fp
);
1093 mutex_unlock(&lport
->lp_mutex
);
1097 * fc_lport_rpn_id_resp() - Handle response to Register Port
1098 * Name by ID (RPN_ID) request
1099 * @sp: current sequence in RPN_ID exchange
1100 * @fp: response frame
1101 * @lp_arg: Fibre Channel host port instance
1103 * Locking Note: This function will be called without the lport lock
1104 * held, but it will lock, call an _enter_* function or fc_lport_error
1105 * and then unlock the lport.
1107 static void fc_lport_rpn_id_resp(struct fc_seq
*sp
, struct fc_frame
*fp
,
1110 struct fc_lport
*lport
= lp_arg
;
1111 struct fc_frame_header
*fh
;
1112 struct fc_ct_hdr
*ct
;
1114 if (fp
== ERR_PTR(-FC_EX_CLOSED
))
1117 mutex_lock(&lport
->lp_mutex
);
1119 FC_LPORT_DBG(lport
, "Received a RPN_ID response\n");
1121 if (lport
->state
!= LPORT_ST_RPN_ID
) {
1122 FC_LPORT_DBG(lport
, "Received a RPN_ID response, but in state "
1123 "%s\n", fc_lport_state(lport
));
1130 fc_lport_error(lport
, fp
);
1134 fh
= fc_frame_header_get(fp
);
1135 ct
= fc_frame_payload_get(fp
, sizeof(*ct
));
1136 if (fh
&& ct
&& fh
->fh_type
== FC_TYPE_CT
&&
1137 ct
->ct_fs_type
== FC_FST_DIR
&&
1138 ct
->ct_fs_subtype
== FC_NS_SUBTYPE
&&
1139 ntohs(ct
->ct_cmd
) == FC_FS_ACC
)
1140 fc_lport_enter_rft_id(lport
);
1142 fc_lport_error(lport
, fp
);
1147 mutex_unlock(&lport
->lp_mutex
);
1151 * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request
1152 * @sp: current sequence in SCR exchange
1153 * @fp: response frame
1154 * @lp_arg: Fibre Channel lport port instance that sent the registration request
1156 * Locking Note: This function will be called without the lport lock
1157 * held, but it will lock, call an _enter_* function or fc_lport_error
1158 * and then unlock the lport.
1160 static void fc_lport_scr_resp(struct fc_seq
*sp
, struct fc_frame
*fp
,
1163 struct fc_lport
*lport
= lp_arg
;
1166 if (fp
== ERR_PTR(-FC_EX_CLOSED
))
1169 mutex_lock(&lport
->lp_mutex
);
1171 FC_LPORT_DBG(lport
, "Received a SCR response\n");
1173 if (lport
->state
!= LPORT_ST_SCR
) {
1174 FC_LPORT_DBG(lport
, "Received a SCR response, but in state "
1175 "%s\n", fc_lport_state(lport
));
1182 fc_lport_error(lport
, fp
);
1186 op
= fc_frame_payload_op(fp
);
1187 if (op
== ELS_LS_ACC
)
1188 fc_lport_enter_ready(lport
);
1190 fc_lport_error(lport
, fp
);
1195 mutex_unlock(&lport
->lp_mutex
);
1199 * fc_lport_enter_scr() - Send a State Change Register (SCR) request
1200 * @lport: Fibre Channel local port to register for state changes
1202 * Locking Note: The lport lock is expected to be held before calling
1205 static void fc_lport_enter_scr(struct fc_lport
*lport
)
1207 struct fc_frame
*fp
;
1209 FC_LPORT_DBG(lport
, "Entered SCR state from %s state\n",
1210 fc_lport_state(lport
));
1212 fc_lport_state_enter(lport
, LPORT_ST_SCR
);
1214 fp
= fc_frame_alloc(lport
, sizeof(struct fc_els_scr
));
1216 fc_lport_error(lport
, fp
);
1220 if (!lport
->tt
.elsct_send(lport
, NULL
, fp
, ELS_SCR
,
1221 fc_lport_scr_resp
, lport
, lport
->e_d_tov
))
1222 fc_lport_error(lport
, fp
);
1226 * fc_lport_enter_rft_id() - Register FC4-types with the name server
1227 * @lport: Fibre Channel local port to register
1229 * Locking Note: The lport lock is expected to be held before calling
1232 static void fc_lport_enter_rft_id(struct fc_lport
*lport
)
1234 struct fc_frame
*fp
;
1235 struct fc_ns_fts
*lps
;
1238 FC_LPORT_DBG(lport
, "Entered RFT_ID state from %s state\n",
1239 fc_lport_state(lport
));
1241 fc_lport_state_enter(lport
, LPORT_ST_RFT_ID
);
1244 i
= sizeof(lps
->ff_type_map
) / sizeof(lps
->ff_type_map
[0]);
1246 if (ntohl(lps
->ff_type_map
[i
]) != 0)
1249 /* nothing to register, move on to SCR */
1250 fc_lport_enter_scr(lport
);
1254 fp
= fc_frame_alloc(lport
, sizeof(struct fc_ct_hdr
) +
1255 sizeof(struct fc_ns_rft
));
1257 fc_lport_error(lport
, fp
);
1261 if (!lport
->tt
.elsct_send(lport
, NULL
, fp
, FC_NS_RFT_ID
,
1262 fc_lport_rft_id_resp
,
1263 lport
, lport
->e_d_tov
))
1264 fc_lport_error(lport
, fp
);
1268 * fc_rport_enter_rft_id() - Register port name with the name server
1269 * @lport: Fibre Channel local port to register
1271 * Locking Note: The lport lock is expected to be held before calling
1274 static void fc_lport_enter_rpn_id(struct fc_lport
*lport
)
1276 struct fc_frame
*fp
;
1278 FC_LPORT_DBG(lport
, "Entered RPN_ID state from %s state\n",
1279 fc_lport_state(lport
));
1281 fc_lport_state_enter(lport
, LPORT_ST_RPN_ID
);
1283 fp
= fc_frame_alloc(lport
, sizeof(struct fc_ct_hdr
) +
1284 sizeof(struct fc_ns_rn_id
));
1286 fc_lport_error(lport
, fp
);
1290 if (!lport
->tt
.elsct_send(lport
, NULL
, fp
, FC_NS_RPN_ID
,
1291 fc_lport_rpn_id_resp
,
1292 lport
, lport
->e_d_tov
))
1293 fc_lport_error(lport
, fp
);
1296 static struct fc_rport_operations fc_lport_rport_ops
= {
1297 .event_callback
= fc_lport_rport_callback
,
1301 * fc_rport_enter_dns() - Create a rport to the name server
1302 * @lport: Fibre Channel local port requesting a rport for the name server
1304 * Locking Note: The lport lock is expected to be held before calling
1307 static void fc_lport_enter_dns(struct fc_lport
*lport
)
1309 struct fc_rport_priv
*rdata
;
1310 struct fc_rport_identifiers ids
;
1312 ids
.port_id
= FC_FID_DIR_SERV
;
1315 ids
.roles
= FC_RPORT_ROLE_UNKNOWN
;
1317 FC_LPORT_DBG(lport
, "Entered DNS state from %s state\n",
1318 fc_lport_state(lport
));
1320 fc_lport_state_enter(lport
, LPORT_ST_DNS
);
1322 rdata
= lport
->tt
.rport_create(lport
, &ids
);
1326 rdata
->ops
= &fc_lport_rport_ops
;
1327 lport
->tt
.rport_login(rdata
);
1331 fc_lport_error(lport
, NULL
);
1335 * fc_lport_timeout() - Handler for the retry_work timer.
1336 * @work: The work struct of the fc_lport
1338 static void fc_lport_timeout(struct work_struct
*work
)
1340 struct fc_lport
*lport
=
1341 container_of(work
, struct fc_lport
,
1344 mutex_lock(&lport
->lp_mutex
);
1346 switch (lport
->state
) {
1347 case LPORT_ST_DISABLED
:
1348 case LPORT_ST_READY
:
1349 case LPORT_ST_RESET
:
1352 case LPORT_ST_FLOGI
:
1353 fc_lport_enter_flogi(lport
);
1356 fc_lport_enter_dns(lport
);
1358 case LPORT_ST_RPN_ID
:
1359 fc_lport_enter_rpn_id(lport
);
1361 case LPORT_ST_RFT_ID
:
1362 fc_lport_enter_rft_id(lport
);
1365 fc_lport_enter_scr(lport
);
1368 fc_lport_enter_logo(lport
);
1372 mutex_unlock(&lport
->lp_mutex
);
1376 * fc_lport_logo_resp() - Handle response to LOGO request
1377 * @sp: current sequence in LOGO exchange
1378 * @fp: response frame
1379 * @lp_arg: Fibre Channel lport port instance that sent the LOGO request
1381 * Locking Note: This function will be called without the lport lock
1382 * held, but it will lock, call an _enter_* function or fc_lport_error
1383 * and then unlock the lport.
1385 static void fc_lport_logo_resp(struct fc_seq
*sp
, struct fc_frame
*fp
,
1388 struct fc_lport
*lport
= lp_arg
;
1391 if (fp
== ERR_PTR(-FC_EX_CLOSED
))
1394 mutex_lock(&lport
->lp_mutex
);
1396 FC_LPORT_DBG(lport
, "Received a LOGO response\n");
1398 if (lport
->state
!= LPORT_ST_LOGO
) {
1399 FC_LPORT_DBG(lport
, "Received a LOGO response, but in state "
1400 "%s\n", fc_lport_state(lport
));
1407 fc_lport_error(lport
, fp
);
1411 op
= fc_frame_payload_op(fp
);
1412 if (op
== ELS_LS_ACC
)
1413 fc_lport_enter_disabled(lport
);
1415 fc_lport_error(lport
, fp
);
1420 mutex_unlock(&lport
->lp_mutex
);
1424 * fc_rport_enter_logo() - Logout of the fabric
1425 * @lport: Fibre Channel local port to be logged out
1427 * Locking Note: The lport lock is expected to be held before calling
1430 static void fc_lport_enter_logo(struct fc_lport
*lport
)
1432 struct fc_frame
*fp
;
1433 struct fc_els_logo
*logo
;
1435 FC_LPORT_DBG(lport
, "Entered LOGO state from %s state\n",
1436 fc_lport_state(lport
));
1438 fc_lport_state_enter(lport
, LPORT_ST_LOGO
);
1440 fp
= fc_frame_alloc(lport
, sizeof(*logo
));
1442 fc_lport_error(lport
, fp
);
1446 if (!lport
->tt
.elsct_send(lport
, NULL
, fp
, ELS_LOGO
, fc_lport_logo_resp
,
1447 lport
, lport
->e_d_tov
))
1448 fc_lport_error(lport
, fp
);
1452 * fc_lport_flogi_resp() - Handle response to FLOGI request
1453 * @sp: current sequence in FLOGI exchange
1454 * @fp: response frame
1455 * @lp_arg: Fibre Channel lport port instance that sent the FLOGI request
1457 * Locking Note: This function will be called without the lport lock
1458 * held, but it will lock, call an _enter_* function or fc_lport_error
1459 * and then unlock the lport.
1461 static void fc_lport_flogi_resp(struct fc_seq
*sp
, struct fc_frame
*fp
,
1464 struct fc_lport
*lport
= lp_arg
;
1465 struct fc_frame_header
*fh
;
1466 struct fc_els_flogi
*flp
;
1469 unsigned int r_a_tov
;
1470 unsigned int e_d_tov
;
1473 if (fp
== ERR_PTR(-FC_EX_CLOSED
))
1476 mutex_lock(&lport
->lp_mutex
);
1478 FC_LPORT_DBG(lport
, "Received a FLOGI response\n");
1480 if (lport
->state
!= LPORT_ST_FLOGI
) {
1481 FC_LPORT_DBG(lport
, "Received a FLOGI response, but in state "
1482 "%s\n", fc_lport_state(lport
));
1489 fc_lport_error(lport
, fp
);
1493 fh
= fc_frame_header_get(fp
);
1494 did
= ntoh24(fh
->fh_d_id
);
1495 if (fc_frame_payload_op(fp
) == ELS_LS_ACC
&& did
!= 0) {
1497 printk(KERN_INFO
"libfc: Assigned FID (%6x) in FLOGI response\n",
1499 fc_host_port_id(lport
->host
) = did
;
1501 flp
= fc_frame_payload_get(fp
, sizeof(*flp
));
1503 mfs
= ntohs(flp
->fl_csp
.sp_bb_data
) &
1505 if (mfs
>= FC_SP_MIN_MAX_PAYLOAD
&&
1508 csp_flags
= ntohs(flp
->fl_csp
.sp_features
);
1509 r_a_tov
= ntohl(flp
->fl_csp
.sp_r_a_tov
);
1510 e_d_tov
= ntohl(flp
->fl_csp
.sp_e_d_tov
);
1511 if (csp_flags
& FC_SP_FT_EDTR
)
1513 if ((csp_flags
& FC_SP_FT_FPORT
) == 0) {
1514 if (e_d_tov
> lport
->e_d_tov
)
1515 lport
->e_d_tov
= e_d_tov
;
1516 lport
->r_a_tov
= 2 * e_d_tov
;
1517 printk(KERN_INFO
"libfc: Port (%6x) entered "
1518 "point to point mode\n", did
);
1519 fc_lport_ptp_setup(lport
, ntoh24(fh
->fh_s_id
),
1525 lport
->e_d_tov
= e_d_tov
;
1526 lport
->r_a_tov
= r_a_tov
;
1527 fc_host_fabric_name(lport
->host
) =
1528 get_unaligned_be64(&flp
->fl_wwnn
);
1529 fc_lport_enter_dns(lport
);
1534 csp_flags
= ntohs(flp
->fl_csp
.sp_features
);
1535 if ((csp_flags
& FC_SP_FT_FPORT
) == 0) {
1536 lport
->tt
.disc_start(fc_lport_disc_callback
,
1541 FC_LPORT_DBG(lport
, "Bad FLOGI response\n");
1547 mutex_unlock(&lport
->lp_mutex
);
1551 * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager
1552 * @lport: Fibre Channel local port to be logged in to the fabric
1554 * Locking Note: The lport lock is expected to be held before calling
1557 void fc_lport_enter_flogi(struct fc_lport
*lport
)
1559 struct fc_frame
*fp
;
1561 FC_LPORT_DBG(lport
, "Entered FLOGI state from %s state\n",
1562 fc_lport_state(lport
));
1564 fc_lport_state_enter(lport
, LPORT_ST_FLOGI
);
1566 fp
= fc_frame_alloc(lport
, sizeof(struct fc_els_flogi
));
1568 return fc_lport_error(lport
, fp
);
1570 if (!lport
->tt
.elsct_send(lport
, NULL
, fp
, ELS_FLOGI
,
1571 fc_lport_flogi_resp
, lport
, lport
->e_d_tov
))
1572 fc_lport_error(lport
, fp
);
1575 /* Configure a fc_lport */
1576 int fc_lport_config(struct fc_lport
*lport
)
1578 INIT_DELAYED_WORK(&lport
->retry_work
, fc_lport_timeout
);
1579 mutex_init(&lport
->lp_mutex
);
1581 fc_lport_state_enter(lport
, LPORT_ST_DISABLED
);
1583 fc_lport_add_fc4_type(lport
, FC_TYPE_FCP
);
1584 fc_lport_add_fc4_type(lport
, FC_TYPE_CT
);
1588 EXPORT_SYMBOL(fc_lport_config
);
1590 int fc_lport_init(struct fc_lport
*lport
)
1592 if (!lport
->tt
.lport_recv
)
1593 lport
->tt
.lport_recv
= fc_lport_recv_req
;
1595 if (!lport
->tt
.lport_reset
)
1596 lport
->tt
.lport_reset
= fc_lport_reset
;
1598 fc_host_port_type(lport
->host
) = FC_PORTTYPE_NPORT
;
1599 fc_host_node_name(lport
->host
) = lport
->wwnn
;
1600 fc_host_port_name(lport
->host
) = lport
->wwpn
;
1601 fc_host_supported_classes(lport
->host
) = FC_COS_CLASS3
;
1602 memset(fc_host_supported_fc4s(lport
->host
), 0,
1603 sizeof(fc_host_supported_fc4s(lport
->host
)));
1604 fc_host_supported_fc4s(lport
->host
)[2] = 1;
1605 fc_host_supported_fc4s(lport
->host
)[7] = 1;
1607 /* This value is also unchanging */
1608 memset(fc_host_active_fc4s(lport
->host
), 0,
1609 sizeof(fc_host_active_fc4s(lport
->host
)));
1610 fc_host_active_fc4s(lport
->host
)[2] = 1;
1611 fc_host_active_fc4s(lport
->host
)[7] = 1;
1612 fc_host_maxframe_size(lport
->host
) = lport
->mfs
;
1613 fc_host_supported_speeds(lport
->host
) = 0;
1614 if (lport
->link_supported_speeds
& FC_PORTSPEED_1GBIT
)
1615 fc_host_supported_speeds(lport
->host
) |= FC_PORTSPEED_1GBIT
;
1616 if (lport
->link_supported_speeds
& FC_PORTSPEED_10GBIT
)
1617 fc_host_supported_speeds(lport
->host
) |= FC_PORTSPEED_10GBIT
;
1619 INIT_LIST_HEAD(&lport
->ema_list
);
1622 EXPORT_SYMBOL(fc_lport_init
);