0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078 #include <linux/timer.h>
0079 #include <linux/delay.h>
0080 #include <linux/module.h>
0081 #include <linux/slab.h>
0082 #include <asm/unaligned.h>
0083
0084 #include <scsi/fc/fc_gs.h>
0085
0086 #include <scsi/libfc.h>
0087 #include <linux/scatterlist.h>
0088
0089 #include "fc_encode.h"
0090 #include "fc_libfc.h"
0091
0092
0093 #define FC_LOCAL_PTP_FID_LO 0x010101
0094 #define FC_LOCAL_PTP_FID_HI 0x010102
0095
0096 #define DNS_DELAY 3
0097 #define MAX_CT_PAYLOAD 2048
0098 #define DISCOVERED_PORTS 4
0099 #define NUMBER_OF_PORTS 1
0100
0101 static void fc_lport_error(struct fc_lport *, struct fc_frame *);
0102
0103 static void fc_lport_enter_reset(struct fc_lport *);
0104 static void fc_lport_enter_flogi(struct fc_lport *);
0105 static void fc_lport_enter_dns(struct fc_lport *);
0106 static void fc_lport_enter_ns(struct fc_lport *, enum fc_lport_state);
0107 static void fc_lport_enter_scr(struct fc_lport *);
0108 static void fc_lport_enter_ready(struct fc_lport *);
0109 static void fc_lport_enter_logo(struct fc_lport *);
0110 static void fc_lport_enter_fdmi(struct fc_lport *lport);
0111 static void fc_lport_enter_ms(struct fc_lport *, enum fc_lport_state);
0112
0113 static const char *fc_lport_state_names[] = {
0114 [LPORT_ST_DISABLED] = "disabled",
0115 [LPORT_ST_FLOGI] = "FLOGI",
0116 [LPORT_ST_DNS] = "dNS",
0117 [LPORT_ST_RNN_ID] = "RNN_ID",
0118 [LPORT_ST_RSNN_NN] = "RSNN_NN",
0119 [LPORT_ST_RSPN_ID] = "RSPN_ID",
0120 [LPORT_ST_RFT_ID] = "RFT_ID",
0121 [LPORT_ST_RFF_ID] = "RFF_ID",
0122 [LPORT_ST_FDMI] = "FDMI",
0123 [LPORT_ST_RHBA] = "RHBA",
0124 [LPORT_ST_RPA] = "RPA",
0125 [LPORT_ST_DHBA] = "DHBA",
0126 [LPORT_ST_DPRT] = "DPRT",
0127 [LPORT_ST_SCR] = "SCR",
0128 [LPORT_ST_READY] = "Ready",
0129 [LPORT_ST_LOGO] = "LOGO",
0130 [LPORT_ST_RESET] = "reset",
0131 };
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 struct fc_bsg_info {
0143 struct bsg_job *job;
0144 struct fc_lport *lport;
0145 u16 rsp_code;
0146 struct scatterlist *sg;
0147 u32 nents;
0148 size_t offset;
0149 };
0150
0151
0152
0153
0154
0155
0156 static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp)
0157 {
0158 fc_frame_free(fp);
0159 return 0;
0160 }
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 static void fc_lport_rport_callback(struct fc_lport *lport,
0172 struct fc_rport_priv *rdata,
0173 enum fc_rport_event event)
0174 {
0175 FC_LPORT_DBG(lport, "Received a %d event for port (%6.6x)\n", event,
0176 rdata->ids.port_id);
0177
0178 mutex_lock(&lport->lp_mutex);
0179 switch (event) {
0180 case RPORT_EV_READY:
0181 if (lport->state == LPORT_ST_DNS) {
0182 lport->dns_rdata = rdata;
0183 fc_lport_enter_ns(lport, LPORT_ST_RNN_ID);
0184 } else if (lport->state == LPORT_ST_FDMI) {
0185 lport->ms_rdata = rdata;
0186 fc_lport_enter_ms(lport, LPORT_ST_DHBA);
0187 } else {
0188 FC_LPORT_DBG(lport, "Received an READY event "
0189 "on port (%6.6x) for the directory "
0190 "server, but the lport is not "
0191 "in the DNS or FDMI state, it's in the "
0192 "%d state", rdata->ids.port_id,
0193 lport->state);
0194 fc_rport_logoff(rdata);
0195 }
0196 break;
0197 case RPORT_EV_LOGO:
0198 case RPORT_EV_FAILED:
0199 case RPORT_EV_STOP:
0200 if (rdata->ids.port_id == FC_FID_DIR_SERV)
0201 lport->dns_rdata = NULL;
0202 else if (rdata->ids.port_id == FC_FID_MGMT_SERV)
0203 lport->ms_rdata = NULL;
0204 break;
0205 case RPORT_EV_NONE:
0206 break;
0207 }
0208 mutex_unlock(&lport->lp_mutex);
0209 }
0210
0211
0212
0213
0214
0215 static const char *fc_lport_state(struct fc_lport *lport)
0216 {
0217 const char *cp;
0218
0219 cp = fc_lport_state_names[lport->state];
0220 if (!cp)
0221 cp = "unknown";
0222 return cp;
0223 }
0224
0225
0226
0227
0228
0229
0230
0231
0232 static void fc_lport_ptp_setup(struct fc_lport *lport,
0233 u32 remote_fid, u64 remote_wwpn,
0234 u64 remote_wwnn)
0235 {
0236 lockdep_assert_held(&lport->lp_mutex);
0237
0238 if (lport->ptp_rdata) {
0239 fc_rport_logoff(lport->ptp_rdata);
0240 kref_put(&lport->ptp_rdata->kref, fc_rport_destroy);
0241 }
0242 mutex_lock(&lport->disc.disc_mutex);
0243 lport->ptp_rdata = fc_rport_create(lport, remote_fid);
0244 kref_get(&lport->ptp_rdata->kref);
0245 lport->ptp_rdata->ids.port_name = remote_wwpn;
0246 lport->ptp_rdata->ids.node_name = remote_wwnn;
0247 mutex_unlock(&lport->disc.disc_mutex);
0248
0249 fc_rport_login(lport->ptp_rdata);
0250
0251 fc_lport_enter_ready(lport);
0252 }
0253
0254
0255
0256
0257
0258 void fc_get_host_port_state(struct Scsi_Host *shost)
0259 {
0260 struct fc_lport *lport = shost_priv(shost);
0261
0262 mutex_lock(&lport->lp_mutex);
0263 if (!lport->link_up)
0264 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
0265 else
0266 switch (lport->state) {
0267 case LPORT_ST_READY:
0268 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
0269 break;
0270 default:
0271 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
0272 }
0273 mutex_unlock(&lport->lp_mutex);
0274 }
0275 EXPORT_SYMBOL(fc_get_host_port_state);
0276
0277
0278
0279
0280
0281 void fc_get_host_speed(struct Scsi_Host *shost)
0282 {
0283 struct fc_lport *lport = shost_priv(shost);
0284
0285 fc_host_speed(shost) = lport->link_speed;
0286 }
0287 EXPORT_SYMBOL(fc_get_host_speed);
0288
0289
0290
0291
0292
0293 struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
0294 {
0295 struct fc_host_statistics *fc_stats;
0296 struct fc_lport *lport = shost_priv(shost);
0297 unsigned int cpu;
0298 u64 fcp_in_bytes = 0;
0299 u64 fcp_out_bytes = 0;
0300
0301 fc_stats = &lport->host_stats;
0302 memset(fc_stats, 0, sizeof(struct fc_host_statistics));
0303
0304 fc_stats->seconds_since_last_reset = (jiffies - lport->boot_time) / HZ;
0305
0306 for_each_possible_cpu(cpu) {
0307 struct fc_stats *stats;
0308
0309 stats = per_cpu_ptr(lport->stats, cpu);
0310
0311 fc_stats->tx_frames += READ_ONCE(stats->TxFrames);
0312 fc_stats->tx_words += READ_ONCE(stats->TxWords);
0313 fc_stats->rx_frames += READ_ONCE(stats->RxFrames);
0314 fc_stats->rx_words += READ_ONCE(stats->RxWords);
0315 fc_stats->error_frames += READ_ONCE(stats->ErrorFrames);
0316 fc_stats->invalid_crc_count += READ_ONCE(stats->InvalidCRCCount);
0317 fc_stats->fcp_input_requests += READ_ONCE(stats->InputRequests);
0318 fc_stats->fcp_output_requests += READ_ONCE(stats->OutputRequests);
0319 fc_stats->fcp_control_requests += READ_ONCE(stats->ControlRequests);
0320 fcp_in_bytes += READ_ONCE(stats->InputBytes);
0321 fcp_out_bytes += READ_ONCE(stats->OutputBytes);
0322 fc_stats->fcp_packet_alloc_failures += READ_ONCE(stats->FcpPktAllocFails);
0323 fc_stats->fcp_packet_aborts += READ_ONCE(stats->FcpPktAborts);
0324 fc_stats->fcp_frame_alloc_failures += READ_ONCE(stats->FcpFrameAllocFails);
0325 fc_stats->link_failure_count += READ_ONCE(stats->LinkFailureCount);
0326 }
0327 fc_stats->fcp_input_megabytes = div_u64(fcp_in_bytes, 1000000);
0328 fc_stats->fcp_output_megabytes = div_u64(fcp_out_bytes, 1000000);
0329 fc_stats->lip_count = -1;
0330 fc_stats->nos_count = -1;
0331 fc_stats->loss_of_sync_count = -1;
0332 fc_stats->loss_of_signal_count = -1;
0333 fc_stats->prim_seq_protocol_err_count = -1;
0334 fc_stats->dumped_frames = -1;
0335
0336
0337 fc_exch_update_stats(lport);
0338
0339 return fc_stats;
0340 }
0341 EXPORT_SYMBOL(fc_get_host_stats);
0342
0343
0344
0345
0346
0347
0348
0349 static void fc_lport_flogi_fill(struct fc_lport *lport,
0350 struct fc_els_flogi *flogi,
0351 unsigned int op)
0352 {
0353 struct fc_els_csp *sp;
0354 struct fc_els_cssp *cp;
0355
0356 memset(flogi, 0, sizeof(*flogi));
0357 flogi->fl_cmd = (u8) op;
0358 put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn);
0359 put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn);
0360 sp = &flogi->fl_csp;
0361 sp->sp_hi_ver = 0x20;
0362 sp->sp_lo_ver = 0x20;
0363 sp->sp_bb_cred = htons(10);
0364 sp->sp_bb_data = htons((u16) lport->mfs);
0365 cp = &flogi->fl_cssp[3 - 1];
0366 cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
0367 if (op != ELS_FLOGI) {
0368 sp->sp_features = htons(FC_SP_FT_CIRO);
0369 sp->sp_tot_seq = htons(255);
0370 sp->sp_rel_off = htons(0x1f);
0371 sp->sp_e_d_tov = htonl(lport->e_d_tov);
0372
0373 cp->cp_rdfs = htons((u16) lport->mfs);
0374 cp->cp_con_seq = htons(255);
0375 cp->cp_open_seq = 1;
0376 }
0377 }
0378
0379
0380
0381
0382
0383
0384 static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
0385 {
0386 __be32 *mp;
0387
0388 mp = &lport->fcts.ff_type_map[type / FC_NS_BPW];
0389 *mp = htonl(ntohl(*mp) | 1UL << (type % FC_NS_BPW));
0390 }
0391
0392
0393
0394
0395
0396
0397 static void fc_lport_recv_rlir_req(struct fc_lport *lport, struct fc_frame *fp)
0398 {
0399 lockdep_assert_held(&lport->lp_mutex);
0400
0401 FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n",
0402 fc_lport_state(lport));
0403
0404 fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
0405 fc_frame_free(fp);
0406 }
0407
0408
0409
0410
0411
0412
0413 static void fc_lport_recv_echo_req(struct fc_lport *lport,
0414 struct fc_frame *in_fp)
0415 {
0416 struct fc_frame *fp;
0417 unsigned int len;
0418 void *pp;
0419 void *dp;
0420
0421 lockdep_assert_held(&lport->lp_mutex);
0422
0423 FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n",
0424 fc_lport_state(lport));
0425
0426 len = fr_len(in_fp) - sizeof(struct fc_frame_header);
0427 pp = fc_frame_payload_get(in_fp, len);
0428
0429 if (len < sizeof(__be32))
0430 len = sizeof(__be32);
0431
0432 fp = fc_frame_alloc(lport, len);
0433 if (fp) {
0434 dp = fc_frame_payload_get(fp, len);
0435 memcpy(dp, pp, len);
0436 *((__be32 *)dp) = htonl(ELS_LS_ACC << 24);
0437 fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
0438 lport->tt.frame_send(lport, fp);
0439 }
0440 fc_frame_free(in_fp);
0441 }
0442
0443
0444
0445
0446
0447
0448 static void fc_lport_recv_rnid_req(struct fc_lport *lport,
0449 struct fc_frame *in_fp)
0450 {
0451 struct fc_frame *fp;
0452 struct fc_els_rnid *req;
0453 struct {
0454 struct fc_els_rnid_resp rnid;
0455 struct fc_els_rnid_cid cid;
0456 struct fc_els_rnid_gen gen;
0457 } *rp;
0458 struct fc_seq_els_data rjt_data;
0459 u8 fmt;
0460 size_t len;
0461
0462 lockdep_assert_held(&lport->lp_mutex);
0463
0464 FC_LPORT_DBG(lport, "Received RNID request while in state %s\n",
0465 fc_lport_state(lport));
0466
0467 req = fc_frame_payload_get(in_fp, sizeof(*req));
0468 if (!req) {
0469 rjt_data.reason = ELS_RJT_LOGIC;
0470 rjt_data.explan = ELS_EXPL_NONE;
0471 fc_seq_els_rsp_send(in_fp, ELS_LS_RJT, &rjt_data);
0472 } else {
0473 fmt = req->rnid_fmt;
0474 len = sizeof(*rp);
0475 if (fmt != ELS_RNIDF_GEN ||
0476 ntohl(lport->rnid_gen.rnid_atype) == 0) {
0477 fmt = ELS_RNIDF_NONE;
0478 len -= sizeof(rp->gen);
0479 }
0480 fp = fc_frame_alloc(lport, len);
0481 if (fp) {
0482 rp = fc_frame_payload_get(fp, len);
0483 memset(rp, 0, len);
0484 rp->rnid.rnid_cmd = ELS_LS_ACC;
0485 rp->rnid.rnid_fmt = fmt;
0486 rp->rnid.rnid_cid_len = sizeof(rp->cid);
0487 rp->cid.rnid_wwpn = htonll(lport->wwpn);
0488 rp->cid.rnid_wwnn = htonll(lport->wwnn);
0489 if (fmt == ELS_RNIDF_GEN) {
0490 rp->rnid.rnid_sid_len = sizeof(rp->gen);
0491 memcpy(&rp->gen, &lport->rnid_gen,
0492 sizeof(rp->gen));
0493 }
0494 fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
0495 lport->tt.frame_send(lport, fp);
0496 }
0497 }
0498 fc_frame_free(in_fp);
0499 }
0500
0501
0502
0503
0504
0505
0506 static void fc_lport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp)
0507 {
0508 lockdep_assert_held(&lport->lp_mutex);
0509
0510 fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
0511 fc_lport_enter_reset(lport);
0512 fc_frame_free(fp);
0513 }
0514
0515
0516
0517
0518
0519
0520
0521
0522 int fc_fabric_login(struct fc_lport *lport)
0523 {
0524 int rc = -1;
0525
0526 mutex_lock(&lport->lp_mutex);
0527 if (lport->state == LPORT_ST_DISABLED ||
0528 lport->state == LPORT_ST_LOGO) {
0529 fc_lport_state_enter(lport, LPORT_ST_RESET);
0530 fc_lport_enter_reset(lport);
0531 rc = 0;
0532 }
0533 mutex_unlock(&lport->lp_mutex);
0534
0535 return rc;
0536 }
0537 EXPORT_SYMBOL(fc_fabric_login);
0538
0539
0540
0541
0542
0543 void __fc_linkup(struct fc_lport *lport)
0544 {
0545 lockdep_assert_held(&lport->lp_mutex);
0546
0547 if (!lport->link_up) {
0548 lport->link_up = 1;
0549
0550 if (lport->state == LPORT_ST_RESET)
0551 fc_lport_enter_flogi(lport);
0552 }
0553 }
0554
0555
0556
0557
0558
0559 void fc_linkup(struct fc_lport *lport)
0560 {
0561 printk(KERN_INFO "host%d: libfc: Link up on port (%6.6x)\n",
0562 lport->host->host_no, lport->port_id);
0563
0564 mutex_lock(&lport->lp_mutex);
0565 __fc_linkup(lport);
0566 mutex_unlock(&lport->lp_mutex);
0567 }
0568 EXPORT_SYMBOL(fc_linkup);
0569
0570
0571
0572
0573
0574 void __fc_linkdown(struct fc_lport *lport)
0575 {
0576 lockdep_assert_held(&lport->lp_mutex);
0577
0578 if (lport->link_up) {
0579 lport->link_up = 0;
0580 fc_lport_enter_reset(lport);
0581 lport->tt.fcp_cleanup(lport);
0582 }
0583 }
0584
0585
0586
0587
0588
0589 void fc_linkdown(struct fc_lport *lport)
0590 {
0591 printk(KERN_INFO "host%d: libfc: Link down on port (%6.6x)\n",
0592 lport->host->host_no, lport->port_id);
0593
0594 mutex_lock(&lport->lp_mutex);
0595 __fc_linkdown(lport);
0596 mutex_unlock(&lport->lp_mutex);
0597 }
0598 EXPORT_SYMBOL(fc_linkdown);
0599
0600
0601
0602
0603
0604
0605
0606
0607 int fc_fabric_logoff(struct fc_lport *lport)
0608 {
0609 lport->tt.disc_stop_final(lport);
0610 mutex_lock(&lport->lp_mutex);
0611 if (lport->dns_rdata)
0612 fc_rport_logoff(lport->dns_rdata);
0613 mutex_unlock(&lport->lp_mutex);
0614 fc_rport_flush_queue();
0615 mutex_lock(&lport->lp_mutex);
0616 fc_lport_enter_logo(lport);
0617 mutex_unlock(&lport->lp_mutex);
0618 cancel_delayed_work_sync(&lport->retry_work);
0619 return 0;
0620 }
0621 EXPORT_SYMBOL(fc_fabric_logoff);
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633 int fc_lport_destroy(struct fc_lport *lport)
0634 {
0635 mutex_lock(&lport->lp_mutex);
0636 lport->state = LPORT_ST_DISABLED;
0637 lport->link_up = 0;
0638 lport->tt.frame_send = fc_frame_drop;
0639 mutex_unlock(&lport->lp_mutex);
0640
0641 lport->tt.fcp_abort_io(lport);
0642 lport->tt.disc_stop_final(lport);
0643 lport->tt.exch_mgr_reset(lport, 0, 0);
0644 cancel_delayed_work_sync(&lport->retry_work);
0645 fc_fc4_del_lport(lport);
0646 return 0;
0647 }
0648 EXPORT_SYMBOL(fc_lport_destroy);
0649
0650
0651
0652
0653
0654
0655 int fc_set_mfs(struct fc_lport *lport, u32 mfs)
0656 {
0657 unsigned int old_mfs;
0658 int rc = -EINVAL;
0659
0660 mutex_lock(&lport->lp_mutex);
0661
0662 old_mfs = lport->mfs;
0663
0664 if (mfs >= FC_MIN_MAX_FRAME) {
0665 mfs &= ~3;
0666 if (mfs > FC_MAX_FRAME)
0667 mfs = FC_MAX_FRAME;
0668 mfs -= sizeof(struct fc_frame_header);
0669 lport->mfs = mfs;
0670 rc = 0;
0671 }
0672
0673 if (!rc && mfs < old_mfs)
0674 fc_lport_enter_reset(lport);
0675
0676 mutex_unlock(&lport->lp_mutex);
0677
0678 return rc;
0679 }
0680 EXPORT_SYMBOL(fc_set_mfs);
0681
0682
0683
0684
0685
0686
0687 static void fc_lport_disc_callback(struct fc_lport *lport,
0688 enum fc_disc_event event)
0689 {
0690 switch (event) {
0691 case DISC_EV_SUCCESS:
0692 FC_LPORT_DBG(lport, "Discovery succeeded\n");
0693 break;
0694 case DISC_EV_FAILED:
0695 printk(KERN_ERR "host%d: libfc: "
0696 "Discovery failed for port (%6.6x)\n",
0697 lport->host->host_no, lport->port_id);
0698 mutex_lock(&lport->lp_mutex);
0699 fc_lport_enter_reset(lport);
0700 mutex_unlock(&lport->lp_mutex);
0701 break;
0702 case DISC_EV_NONE:
0703 WARN_ON(1);
0704 break;
0705 }
0706 }
0707
0708
0709
0710
0711
0712 static void fc_lport_enter_ready(struct fc_lport *lport)
0713 {
0714 lockdep_assert_held(&lport->lp_mutex);
0715
0716 FC_LPORT_DBG(lport, "Entered READY from state %s\n",
0717 fc_lport_state(lport));
0718
0719 fc_lport_state_enter(lport, LPORT_ST_READY);
0720 if (lport->vport)
0721 fc_vport_set_state(lport->vport, FC_VPORT_ACTIVE);
0722 fc_vports_linkchange(lport);
0723
0724 if (!lport->ptp_rdata)
0725 lport->tt.disc_start(fc_lport_disc_callback, lport);
0726 }
0727
0728
0729
0730
0731
0732
0733
0734 static void fc_lport_set_port_id(struct fc_lport *lport, u32 port_id,
0735 struct fc_frame *fp)
0736 {
0737 lockdep_assert_held(&lport->lp_mutex);
0738
0739 if (port_id)
0740 printk(KERN_INFO "host%d: Assigned Port ID %6.6x\n",
0741 lport->host->host_no, port_id);
0742
0743 lport->port_id = port_id;
0744
0745
0746 fc_host_port_id(lport->host) = port_id;
0747
0748 if (lport->tt.lport_set_port_id)
0749 lport->tt.lport_set_port_id(lport, port_id, fp);
0750 }
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761 void fc_lport_set_local_id(struct fc_lport *lport, u32 port_id)
0762 {
0763 mutex_lock(&lport->lp_mutex);
0764
0765 fc_lport_set_port_id(lport, port_id, NULL);
0766
0767 switch (lport->state) {
0768 case LPORT_ST_RESET:
0769 case LPORT_ST_FLOGI:
0770 if (port_id)
0771 fc_lport_enter_ready(lport);
0772 break;
0773 default:
0774 break;
0775 }
0776 mutex_unlock(&lport->lp_mutex);
0777 }
0778 EXPORT_SYMBOL(fc_lport_set_local_id);
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789 static void fc_lport_recv_flogi_req(struct fc_lport *lport,
0790 struct fc_frame *rx_fp)
0791 {
0792 struct fc_frame *fp;
0793 struct fc_frame_header *fh;
0794 struct fc_els_flogi *flp;
0795 struct fc_els_flogi *new_flp;
0796 u64 remote_wwpn;
0797 u32 remote_fid;
0798 u32 local_fid;
0799
0800 lockdep_assert_held(&lport->lp_mutex);
0801
0802 FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n",
0803 fc_lport_state(lport));
0804
0805 remote_fid = fc_frame_sid(rx_fp);
0806 flp = fc_frame_payload_get(rx_fp, sizeof(*flp));
0807 if (!flp)
0808 goto out;
0809 remote_wwpn = get_unaligned_be64(&flp->fl_wwpn);
0810 if (remote_wwpn == lport->wwpn) {
0811 printk(KERN_WARNING "host%d: libfc: Received FLOGI from port "
0812 "with same WWPN %16.16llx\n",
0813 lport->host->host_no, remote_wwpn);
0814 goto out;
0815 }
0816 FC_LPORT_DBG(lport, "FLOGI from port WWPN %16.16llx\n", remote_wwpn);
0817
0818
0819
0820
0821
0822
0823 local_fid = FC_LOCAL_PTP_FID_LO;
0824 if (remote_wwpn < lport->wwpn) {
0825 local_fid = FC_LOCAL_PTP_FID_HI;
0826 if (!remote_fid || remote_fid == local_fid)
0827 remote_fid = FC_LOCAL_PTP_FID_LO;
0828 } else if (!remote_fid) {
0829 remote_fid = FC_LOCAL_PTP_FID_HI;
0830 }
0831
0832 fc_lport_set_port_id(lport, local_fid, rx_fp);
0833
0834 fp = fc_frame_alloc(lport, sizeof(*flp));
0835 if (fp) {
0836 new_flp = fc_frame_payload_get(fp, sizeof(*flp));
0837 fc_lport_flogi_fill(lport, new_flp, ELS_FLOGI);
0838 new_flp->fl_cmd = (u8) ELS_LS_ACC;
0839
0840
0841
0842
0843
0844 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
0845 fh = fc_frame_header_get(fp);
0846 hton24(fh->fh_s_id, local_fid);
0847 hton24(fh->fh_d_id, remote_fid);
0848 lport->tt.frame_send(lport, fp);
0849
0850 } else {
0851 fc_lport_error(lport, fp);
0852 }
0853 fc_lport_ptp_setup(lport, remote_fid, remote_wwpn,
0854 get_unaligned_be64(&flp->fl_wwnn));
0855 out:
0856 fc_frame_free(rx_fp);
0857 }
0858
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870 static void fc_lport_recv_els_req(struct fc_lport *lport,
0871 struct fc_frame *fp)
0872 {
0873 mutex_lock(&lport->lp_mutex);
0874
0875
0876
0877
0878
0879
0880 if (!lport->link_up)
0881 fc_frame_free(fp);
0882 else {
0883
0884
0885
0886 switch (fc_frame_payload_op(fp)) {
0887 case ELS_FLOGI:
0888 if (!lport->point_to_multipoint)
0889 fc_lport_recv_flogi_req(lport, fp);
0890 else
0891 fc_rport_recv_req(lport, fp);
0892 break;
0893 case ELS_LOGO:
0894 if (fc_frame_sid(fp) == FC_FID_FLOGI)
0895 fc_lport_recv_logo_req(lport, fp);
0896 else
0897 fc_rport_recv_req(lport, fp);
0898 break;
0899 case ELS_RSCN:
0900 lport->tt.disc_recv_req(lport, fp);
0901 break;
0902 case ELS_ECHO:
0903 fc_lport_recv_echo_req(lport, fp);
0904 break;
0905 case ELS_RLIR:
0906 fc_lport_recv_rlir_req(lport, fp);
0907 break;
0908 case ELS_RNID:
0909 fc_lport_recv_rnid_req(lport, fp);
0910 break;
0911 default:
0912 fc_rport_recv_req(lport, fp);
0913 break;
0914 }
0915 }
0916 mutex_unlock(&lport->lp_mutex);
0917 }
0918
0919 static int fc_lport_els_prli(struct fc_rport_priv *rdata, u32 spp_len,
0920 const struct fc_els_spp *spp_in,
0921 struct fc_els_spp *spp_out)
0922 {
0923 return FC_SPP_RESP_INVL;
0924 }
0925
0926 struct fc4_prov fc_lport_els_prov = {
0927 .prli = fc_lport_els_prli,
0928 .recv = fc_lport_recv_els_req,
0929 };
0930
0931
0932
0933
0934
0935
0936
0937
0938
0939 void fc_lport_recv(struct fc_lport *lport, struct fc_frame *fp)
0940 {
0941 struct fc_frame_header *fh = fc_frame_header_get(fp);
0942 struct fc_seq *sp = fr_seq(fp);
0943 struct fc4_prov *prov;
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953 rcu_read_lock();
0954 if (fh->fh_type >= FC_FC4_PROV_SIZE)
0955 goto drop;
0956 prov = rcu_dereference(fc_passive_prov[fh->fh_type]);
0957 if (!prov || !try_module_get(prov->module))
0958 goto drop;
0959 rcu_read_unlock();
0960 prov->recv(lport, fp);
0961 module_put(prov->module);
0962 return;
0963 drop:
0964 rcu_read_unlock();
0965 FC_LPORT_DBG(lport, "dropping unexpected frame type %x\n", fh->fh_type);
0966 fc_frame_free(fp);
0967 if (sp)
0968 fc_exch_done(sp);
0969 }
0970 EXPORT_SYMBOL(fc_lport_recv);
0971
0972
0973
0974
0975
0976
0977
0978
0979 int fc_lport_reset(struct fc_lport *lport)
0980 {
0981 cancel_delayed_work_sync(&lport->retry_work);
0982 mutex_lock(&lport->lp_mutex);
0983 fc_lport_enter_reset(lport);
0984 mutex_unlock(&lport->lp_mutex);
0985 return 0;
0986 }
0987 EXPORT_SYMBOL(fc_lport_reset);
0988
0989
0990
0991
0992
0993 static void fc_lport_reset_locked(struct fc_lport *lport)
0994 {
0995 lockdep_assert_held(&lport->lp_mutex);
0996
0997 if (lport->dns_rdata) {
0998 fc_rport_logoff(lport->dns_rdata);
0999 lport->dns_rdata = NULL;
1000 }
1001
1002 if (lport->ptp_rdata) {
1003 fc_rport_logoff(lport->ptp_rdata);
1004 kref_put(&lport->ptp_rdata->kref, fc_rport_destroy);
1005 lport->ptp_rdata = NULL;
1006 }
1007
1008 lport->tt.disc_stop(lport);
1009
1010 lport->tt.exch_mgr_reset(lport, 0, 0);
1011 fc_host_fabric_name(lport->host) = 0;
1012
1013 if (lport->port_id && (!lport->point_to_multipoint || !lport->link_up))
1014 fc_lport_set_port_id(lport, 0, NULL);
1015 }
1016
1017
1018
1019
1020
1021 static void fc_lport_enter_reset(struct fc_lport *lport)
1022 {
1023 lockdep_assert_held(&lport->lp_mutex);
1024
1025 FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
1026 fc_lport_state(lport));
1027
1028 if (lport->state == LPORT_ST_DISABLED || lport->state == LPORT_ST_LOGO)
1029 return;
1030
1031 if (lport->vport) {
1032 if (lport->link_up)
1033 fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING);
1034 else
1035 fc_vport_set_state(lport->vport, FC_VPORT_LINKDOWN);
1036 }
1037 fc_lport_state_enter(lport, LPORT_ST_RESET);
1038 fc_host_post_event(lport->host, fc_get_event_number(),
1039 FCH_EVT_LIPRESET, 0);
1040 fc_vports_linkchange(lport);
1041 fc_lport_reset_locked(lport);
1042 if (lport->link_up)
1043 fc_lport_enter_flogi(lport);
1044 }
1045
1046
1047
1048
1049
1050 static void fc_lport_enter_disabled(struct fc_lport *lport)
1051 {
1052 lockdep_assert_held(&lport->lp_mutex);
1053
1054 FC_LPORT_DBG(lport, "Entered disabled state from %s state\n",
1055 fc_lport_state(lport));
1056
1057 fc_lport_state_enter(lport, LPORT_ST_DISABLED);
1058 fc_vports_linkchange(lport);
1059 fc_lport_reset_locked(lport);
1060 }
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071 static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
1072 {
1073 unsigned long delay = 0;
1074 FC_LPORT_DBG(lport, "Error %ld in state %s, retries %d\n",
1075 IS_ERR(fp) ? -PTR_ERR(fp) : 0, fc_lport_state(lport),
1076 lport->retry_count);
1077
1078 if (PTR_ERR(fp) == -FC_EX_CLOSED)
1079 return;
1080
1081
1082
1083
1084
1085
1086 if (lport->retry_count < lport->max_retry_count) {
1087 lport->retry_count++;
1088 if (!fp)
1089 delay = msecs_to_jiffies(500);
1090 else
1091 delay = msecs_to_jiffies(lport->e_d_tov);
1092
1093 schedule_delayed_work(&lport->retry_work, delay);
1094 } else
1095 fc_lport_enter_reset(lport);
1096 }
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109 static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
1110 void *lp_arg)
1111 {
1112 struct fc_lport *lport = lp_arg;
1113 struct fc_frame_header *fh;
1114 struct fc_ct_hdr *ct;
1115
1116 FC_LPORT_DBG(lport, "Received a ns %s\n", fc_els_resp_type(fp));
1117
1118 if (fp == ERR_PTR(-FC_EX_CLOSED))
1119 return;
1120
1121 mutex_lock(&lport->lp_mutex);
1122
1123 if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFF_ID) {
1124 FC_LPORT_DBG(lport, "Received a name server response, "
1125 "but in state %s\n", fc_lport_state(lport));
1126 if (IS_ERR(fp))
1127 goto err;
1128 goto out;
1129 }
1130
1131 if (IS_ERR(fp)) {
1132 fc_lport_error(lport, fp);
1133 goto err;
1134 }
1135
1136 fh = fc_frame_header_get(fp);
1137 ct = fc_frame_payload_get(fp, sizeof(*ct));
1138
1139 if (fh && ct && fh->fh_type == FC_TYPE_CT &&
1140 ct->ct_fs_type == FC_FST_DIR &&
1141 ct->ct_fs_subtype == FC_NS_SUBTYPE &&
1142 ntohs(ct->ct_cmd) == FC_FS_ACC)
1143 switch (lport->state) {
1144 case LPORT_ST_RNN_ID:
1145 fc_lport_enter_ns(lport, LPORT_ST_RSNN_NN);
1146 break;
1147 case LPORT_ST_RSNN_NN:
1148 fc_lport_enter_ns(lport, LPORT_ST_RSPN_ID);
1149 break;
1150 case LPORT_ST_RSPN_ID:
1151 fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1152 break;
1153 case LPORT_ST_RFT_ID:
1154 fc_lport_enter_ns(lport, LPORT_ST_RFF_ID);
1155 break;
1156 case LPORT_ST_RFF_ID:
1157 if (lport->fdmi_enabled)
1158 fc_lport_enter_fdmi(lport);
1159 else
1160 fc_lport_enter_scr(lport);
1161 break;
1162 default:
1163
1164 break;
1165 }
1166 else
1167 fc_lport_error(lport, fp);
1168 out:
1169 fc_frame_free(fp);
1170 err:
1171 mutex_unlock(&lport->lp_mutex);
1172 }
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185 static void fc_lport_ms_resp(struct fc_seq *sp, struct fc_frame *fp,
1186 void *lp_arg)
1187 {
1188 struct fc_lport *lport = lp_arg;
1189 struct fc_frame_header *fh;
1190 struct fc_ct_hdr *ct;
1191 struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host);
1192 FC_LPORT_DBG(lport, "Received a ms %s\n", fc_els_resp_type(fp));
1193
1194 if (fp == ERR_PTR(-FC_EX_CLOSED))
1195 return;
1196
1197 mutex_lock(&lport->lp_mutex);
1198
1199 if (lport->state < LPORT_ST_RHBA || lport->state > LPORT_ST_DPRT) {
1200 FC_LPORT_DBG(lport, "Received a management server response, "
1201 "but in state %s\n", fc_lport_state(lport));
1202 if (IS_ERR(fp))
1203 goto err;
1204 goto out;
1205 }
1206
1207 if (IS_ERR(fp)) {
1208 fc_lport_error(lport, fp);
1209 goto err;
1210 }
1211
1212 fh = fc_frame_header_get(fp);
1213 ct = fc_frame_payload_get(fp, sizeof(*ct));
1214
1215 if (fh && ct && fh->fh_type == FC_TYPE_CT &&
1216 ct->ct_fs_type == FC_FST_MGMT &&
1217 ct->ct_fs_subtype == FC_FDMI_SUBTYPE) {
1218 FC_LPORT_DBG(lport, "Received a management server response, "
1219 "reason=%d explain=%d\n",
1220 ct->ct_reason,
1221 ct->ct_explan);
1222
1223 switch (lport->state) {
1224 case LPORT_ST_RHBA:
1225 if ((ntohs(ct->ct_cmd) == FC_FS_RJT) && fc_host->fdmi_version == FDMI_V2) {
1226 FC_LPORT_DBG(lport, "Error for FDMI-V2, fall back to FDMI-V1\n");
1227 fc_host->fdmi_version = FDMI_V1;
1228
1229 fc_lport_enter_ms(lport, LPORT_ST_RHBA);
1230
1231 } else if (ntohs(ct->ct_cmd) == FC_FS_ACC)
1232 fc_lport_enter_ms(lport, LPORT_ST_RPA);
1233 else
1234 fc_lport_enter_scr(lport);
1235 break;
1236 case LPORT_ST_RPA:
1237 fc_lport_enter_scr(lport);
1238 break;
1239 case LPORT_ST_DPRT:
1240 fc_lport_enter_ms(lport, LPORT_ST_RHBA);
1241 break;
1242 case LPORT_ST_DHBA:
1243 fc_lport_enter_ms(lport, LPORT_ST_DPRT);
1244 break;
1245 default:
1246
1247 break;
1248 }
1249 } else {
1250
1251 fc_lport_error(lport, fp);
1252 }
1253 out:
1254 fc_frame_free(fp);
1255 err:
1256 mutex_unlock(&lport->lp_mutex);
1257 }
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269 static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
1270 void *lp_arg)
1271 {
1272 struct fc_lport *lport = lp_arg;
1273 u8 op;
1274
1275 FC_LPORT_DBG(lport, "Received a SCR %s\n", fc_els_resp_type(fp));
1276
1277 if (fp == ERR_PTR(-FC_EX_CLOSED))
1278 return;
1279
1280 mutex_lock(&lport->lp_mutex);
1281
1282 if (lport->state != LPORT_ST_SCR) {
1283 FC_LPORT_DBG(lport, "Received a SCR response, but in state "
1284 "%s\n", fc_lport_state(lport));
1285 if (IS_ERR(fp))
1286 goto err;
1287 goto out;
1288 }
1289
1290 if (IS_ERR(fp)) {
1291 fc_lport_error(lport, fp);
1292 goto err;
1293 }
1294
1295 op = fc_frame_payload_op(fp);
1296 if (op == ELS_LS_ACC)
1297 fc_lport_enter_ready(lport);
1298 else
1299 fc_lport_error(lport, fp);
1300
1301 out:
1302 fc_frame_free(fp);
1303 err:
1304 mutex_unlock(&lport->lp_mutex);
1305 }
1306
1307
1308
1309
1310
1311 static void fc_lport_enter_scr(struct fc_lport *lport)
1312 {
1313 struct fc_frame *fp;
1314
1315 lockdep_assert_held(&lport->lp_mutex);
1316
1317 FC_LPORT_DBG(lport, "Entered SCR state from %s state\n",
1318 fc_lport_state(lport));
1319
1320 fc_lport_state_enter(lport, LPORT_ST_SCR);
1321
1322 fp = fc_frame_alloc(lport, sizeof(struct fc_els_scr));
1323 if (!fp) {
1324 fc_lport_error(lport, fp);
1325 return;
1326 }
1327
1328 if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR,
1329 fc_lport_scr_resp, lport,
1330 2 * lport->r_a_tov))
1331 fc_lport_error(lport, NULL);
1332 }
1333
1334
1335
1336
1337
1338
1339 static void fc_lport_enter_ns(struct fc_lport *lport, enum fc_lport_state state)
1340 {
1341 struct fc_frame *fp;
1342 enum fc_ns_req cmd;
1343 int size = sizeof(struct fc_ct_hdr);
1344 size_t len;
1345
1346 lockdep_assert_held(&lport->lp_mutex);
1347
1348 FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
1349 fc_lport_state_names[state],
1350 fc_lport_state(lport));
1351
1352 fc_lport_state_enter(lport, state);
1353
1354 switch (state) {
1355 case LPORT_ST_RNN_ID:
1356 cmd = FC_NS_RNN_ID;
1357 size += sizeof(struct fc_ns_rn_id);
1358 break;
1359 case LPORT_ST_RSNN_NN:
1360 len = strnlen(fc_host_symbolic_name(lport->host), 255);
1361
1362 if (!len)
1363 return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1364 cmd = FC_NS_RSNN_NN;
1365 size += sizeof(struct fc_ns_rsnn) + len;
1366 break;
1367 case LPORT_ST_RSPN_ID:
1368 len = strnlen(fc_host_symbolic_name(lport->host), 255);
1369
1370 if (!len)
1371 return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1372 cmd = FC_NS_RSPN_ID;
1373 size += sizeof(struct fc_ns_rspn) + len;
1374 break;
1375 case LPORT_ST_RFT_ID:
1376 cmd = FC_NS_RFT_ID;
1377 size += sizeof(struct fc_ns_rft);
1378 break;
1379 case LPORT_ST_RFF_ID:
1380 cmd = FC_NS_RFF_ID;
1381 size += sizeof(struct fc_ns_rff_id);
1382 break;
1383 default:
1384 fc_lport_error(lport, NULL);
1385 return;
1386 }
1387
1388 fp = fc_frame_alloc(lport, size);
1389 if (!fp) {
1390 fc_lport_error(lport, fp);
1391 return;
1392 }
1393
1394 if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, cmd,
1395 fc_lport_ns_resp,
1396 lport, 3 * lport->r_a_tov))
1397 fc_lport_error(lport, fp);
1398 }
1399
1400 static struct fc_rport_operations fc_lport_rport_ops = {
1401 .event_callback = fc_lport_rport_callback,
1402 };
1403
1404
1405
1406
1407
1408 static void fc_lport_enter_dns(struct fc_lport *lport)
1409 {
1410 struct fc_rport_priv *rdata;
1411
1412 lockdep_assert_held(&lport->lp_mutex);
1413
1414 FC_LPORT_DBG(lport, "Entered DNS state from %s state\n",
1415 fc_lport_state(lport));
1416
1417 fc_lport_state_enter(lport, LPORT_ST_DNS);
1418
1419 mutex_lock(&lport->disc.disc_mutex);
1420 rdata = fc_rport_create(lport, FC_FID_DIR_SERV);
1421 mutex_unlock(&lport->disc.disc_mutex);
1422 if (!rdata)
1423 goto err;
1424
1425 rdata->ops = &fc_lport_rport_ops;
1426 fc_rport_login(rdata);
1427 return;
1428
1429 err:
1430 fc_lport_error(lport, NULL);
1431 }
1432
1433
1434
1435
1436
1437
1438 static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state)
1439 {
1440 struct fc_frame *fp;
1441 enum fc_fdmi_req cmd;
1442 int size = sizeof(struct fc_ct_hdr);
1443 size_t len;
1444 int numattrs;
1445 struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host);
1446 lockdep_assert_held(&lport->lp_mutex);
1447
1448 FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
1449 fc_lport_state_names[state],
1450 fc_lport_state(lport));
1451
1452 fc_lport_state_enter(lport, state);
1453
1454 switch (state) {
1455 case LPORT_ST_RHBA:
1456 cmd = FC_FDMI_RHBA;
1457
1458 numattrs = 11;
1459 len = sizeof(struct fc_fdmi_rhba);
1460 len -= sizeof(struct fc_fdmi_attr_entry);
1461
1462 len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
1463 len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
1464 len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
1465 len += FC_FDMI_HBA_ATTR_MODEL_LEN;
1466 len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
1467 len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
1468 len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
1469 len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
1470 len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
1471 len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
1472 len += FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN;
1473
1474
1475 if (fc_host->fdmi_version == FDMI_V2) {
1476 numattrs += 7;
1477 len += FC_FDMI_HBA_ATTR_NODESYMBLNAME_LEN;
1478 len += FC_FDMI_HBA_ATTR_VENDORSPECIFICINFO_LEN;
1479 len += FC_FDMI_HBA_ATTR_NUMBEROFPORTS_LEN;
1480 len += FC_FDMI_HBA_ATTR_FABRICNAME_LEN;
1481 len += FC_FDMI_HBA_ATTR_BIOSVERSION_LEN;
1482 len += FC_FDMI_HBA_ATTR_BIOSSTATE_LEN;
1483 len += FC_FDMI_HBA_ATTR_VENDORIDENTIFIER_LEN;
1484 }
1485
1486 len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
1487
1488 size += len;
1489 break;
1490 case LPORT_ST_RPA:
1491 cmd = FC_FDMI_RPA;
1492
1493 numattrs = 6;
1494 len = sizeof(struct fc_fdmi_rpa);
1495 len -= sizeof(struct fc_fdmi_attr_entry);
1496 len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
1497 len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
1498 len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
1499 len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
1500 len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
1501 len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
1502
1503 if (fc_host->fdmi_version == FDMI_V2) {
1504 numattrs += 10;
1505 len += FC_FDMI_PORT_ATTR_NODENAME_LEN;
1506 len += FC_FDMI_PORT_ATTR_PORTNAME_LEN;
1507 len += FC_FDMI_PORT_ATTR_SYMBOLICNAME_LEN;
1508 len += FC_FDMI_PORT_ATTR_PORTTYPE_LEN;
1509 len += FC_FDMI_PORT_ATTR_SUPPORTEDCLASSSRVC_LEN;
1510 len += FC_FDMI_PORT_ATTR_FABRICNAME_LEN;
1511 len += FC_FDMI_PORT_ATTR_CURRENTFC4TYPE_LEN;
1512 len += FC_FDMI_PORT_ATTR_PORTSTATE_LEN;
1513 len += FC_FDMI_PORT_ATTR_DISCOVEREDPORTS_LEN;
1514 len += FC_FDMI_PORT_ATTR_PORTID_LEN;
1515 }
1516
1517 len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
1518
1519 size += len;
1520 break;
1521 case LPORT_ST_DPRT:
1522 cmd = FC_FDMI_DPRT;
1523 len = sizeof(struct fc_fdmi_dprt);
1524 size += len;
1525 break;
1526 case LPORT_ST_DHBA:
1527 cmd = FC_FDMI_DHBA;
1528 len = sizeof(struct fc_fdmi_dhba);
1529 size += len;
1530 break;
1531 default:
1532 fc_lport_error(lport, NULL);
1533 return;
1534 }
1535
1536 FC_LPORT_DBG(lport, "Cmd=0x%x Len %d size %d\n",
1537 cmd, (int)len, size);
1538 fp = fc_frame_alloc(lport, size);
1539 if (!fp) {
1540 fc_lport_error(lport, fp);
1541 return;
1542 }
1543
1544 if (!lport->tt.elsct_send(lport, FC_FID_MGMT_SERV, fp, cmd,
1545 fc_lport_ms_resp,
1546 lport, 3 * lport->r_a_tov))
1547 fc_lport_error(lport, fp);
1548 }
1549
1550
1551
1552
1553
1554 static void fc_lport_enter_fdmi(struct fc_lport *lport)
1555 {
1556 struct fc_rport_priv *rdata;
1557
1558 lockdep_assert_held(&lport->lp_mutex);
1559
1560 FC_LPORT_DBG(lport, "Entered FDMI state from %s state\n",
1561 fc_lport_state(lport));
1562
1563 fc_lport_state_enter(lport, LPORT_ST_FDMI);
1564
1565 mutex_lock(&lport->disc.disc_mutex);
1566 rdata = fc_rport_create(lport, FC_FID_MGMT_SERV);
1567 mutex_unlock(&lport->disc.disc_mutex);
1568 if (!rdata)
1569 goto err;
1570
1571 rdata->ops = &fc_lport_rport_ops;
1572 fc_rport_login(rdata);
1573 return;
1574
1575 err:
1576 fc_lport_error(lport, NULL);
1577 }
1578
1579
1580
1581
1582
1583 static void fc_lport_timeout(struct work_struct *work)
1584 {
1585 struct fc_lport *lport =
1586 container_of(work, struct fc_lport,
1587 retry_work.work);
1588 struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host);
1589
1590 mutex_lock(&lport->lp_mutex);
1591
1592 switch (lport->state) {
1593 case LPORT_ST_DISABLED:
1594 break;
1595 case LPORT_ST_READY:
1596 break;
1597 case LPORT_ST_RESET:
1598 break;
1599 case LPORT_ST_FLOGI:
1600 fc_lport_enter_flogi(lport);
1601 break;
1602 case LPORT_ST_DNS:
1603 fc_lport_enter_dns(lport);
1604 break;
1605 case LPORT_ST_RNN_ID:
1606 case LPORT_ST_RSNN_NN:
1607 case LPORT_ST_RSPN_ID:
1608 case LPORT_ST_RFT_ID:
1609 case LPORT_ST_RFF_ID:
1610 fc_lport_enter_ns(lport, lport->state);
1611 break;
1612 case LPORT_ST_FDMI:
1613 fc_lport_enter_fdmi(lport);
1614 break;
1615 case LPORT_ST_RHBA:
1616 if (fc_host->fdmi_version == FDMI_V2) {
1617 FC_LPORT_DBG(lport, "timeout for FDMI-V2 RHBA,fall back to FDMI-V1\n");
1618 fc_host->fdmi_version = FDMI_V1;
1619 fc_lport_enter_ms(lport, LPORT_ST_RHBA);
1620 break;
1621 }
1622 fallthrough;
1623 case LPORT_ST_RPA:
1624 case LPORT_ST_DHBA:
1625 case LPORT_ST_DPRT:
1626 FC_LPORT_DBG(lport, "Skipping lport state %s to SCR\n",
1627 fc_lport_state(lport));
1628 fallthrough;
1629 case LPORT_ST_SCR:
1630 fc_lport_enter_scr(lport);
1631 break;
1632 case LPORT_ST_LOGO:
1633 fc_lport_enter_logo(lport);
1634 break;
1635 }
1636
1637 mutex_unlock(&lport->lp_mutex);
1638 }
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650 void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
1651 void *lp_arg)
1652 {
1653 struct fc_lport *lport = lp_arg;
1654 u8 op;
1655
1656 FC_LPORT_DBG(lport, "Received a LOGO %s\n", fc_els_resp_type(fp));
1657
1658 if (fp == ERR_PTR(-FC_EX_CLOSED))
1659 return;
1660
1661 mutex_lock(&lport->lp_mutex);
1662
1663 if (lport->state != LPORT_ST_LOGO) {
1664 FC_LPORT_DBG(lport, "Received a LOGO response, but in state "
1665 "%s\n", fc_lport_state(lport));
1666 if (IS_ERR(fp))
1667 goto err;
1668 goto out;
1669 }
1670
1671 if (IS_ERR(fp)) {
1672 fc_lport_error(lport, fp);
1673 goto err;
1674 }
1675
1676 op = fc_frame_payload_op(fp);
1677 if (op == ELS_LS_ACC)
1678 fc_lport_enter_disabled(lport);
1679 else
1680 fc_lport_error(lport, fp);
1681
1682 out:
1683 fc_frame_free(fp);
1684 err:
1685 mutex_unlock(&lport->lp_mutex);
1686 }
1687 EXPORT_SYMBOL(fc_lport_logo_resp);
1688
1689
1690
1691
1692
1693 static void fc_lport_enter_logo(struct fc_lport *lport)
1694 {
1695 struct fc_frame *fp;
1696 struct fc_els_logo *logo;
1697
1698 lockdep_assert_held(&lport->lp_mutex);
1699
1700 FC_LPORT_DBG(lport, "Entered LOGO state from %s state\n",
1701 fc_lport_state(lport));
1702
1703 fc_lport_state_enter(lport, LPORT_ST_LOGO);
1704 fc_vports_linkchange(lport);
1705
1706 fp = fc_frame_alloc(lport, sizeof(*logo));
1707 if (!fp) {
1708 fc_lport_error(lport, fp);
1709 return;
1710 }
1711
1712 if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO,
1713 fc_lport_logo_resp, lport,
1714 2 * lport->r_a_tov))
1715 fc_lport_error(lport, NULL);
1716 }
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728 void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1729 void *lp_arg)
1730 {
1731 struct fc_lport *lport = lp_arg;
1732 struct fc_frame_header *fh;
1733 struct fc_els_flogi *flp;
1734 u32 did;
1735 u16 csp_flags;
1736 unsigned int r_a_tov;
1737 unsigned int e_d_tov;
1738 u16 mfs;
1739
1740 FC_LPORT_DBG(lport, "Received a FLOGI %s\n", fc_els_resp_type(fp));
1741
1742 if (fp == ERR_PTR(-FC_EX_CLOSED))
1743 return;
1744
1745 mutex_lock(&lport->lp_mutex);
1746
1747 if (lport->state != LPORT_ST_FLOGI) {
1748 FC_LPORT_DBG(lport, "Received a FLOGI response, but in state "
1749 "%s\n", fc_lport_state(lport));
1750 if (IS_ERR(fp))
1751 goto err;
1752 goto out;
1753 }
1754
1755 if (IS_ERR(fp)) {
1756 fc_lport_error(lport, fp);
1757 goto err;
1758 }
1759
1760 fh = fc_frame_header_get(fp);
1761 did = fc_frame_did(fp);
1762 if (fh->fh_r_ctl != FC_RCTL_ELS_REP || did == 0 ||
1763 fc_frame_payload_op(fp) != ELS_LS_ACC) {
1764 FC_LPORT_DBG(lport, "FLOGI not accepted or bad response\n");
1765 fc_lport_error(lport, fp);
1766 goto out;
1767 }
1768
1769 flp = fc_frame_payload_get(fp, sizeof(*flp));
1770 if (!flp) {
1771 FC_LPORT_DBG(lport, "FLOGI bad response\n");
1772 fc_lport_error(lport, fp);
1773 goto out;
1774 }
1775
1776 mfs = ntohs(flp->fl_csp.sp_bb_data) &
1777 FC_SP_BB_DATA_MASK;
1778
1779 if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) {
1780 FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, "
1781 "lport->mfs:%u\n", mfs, lport->mfs);
1782 fc_lport_error(lport, fp);
1783 goto out;
1784 }
1785
1786 if (mfs <= lport->mfs) {
1787 lport->mfs = mfs;
1788 fc_host_maxframe_size(lport->host) = mfs;
1789 }
1790
1791 csp_flags = ntohs(flp->fl_csp.sp_features);
1792 r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);
1793 e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
1794 if (csp_flags & FC_SP_FT_EDTR)
1795 e_d_tov /= 1000000;
1796
1797 lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
1798
1799 if ((csp_flags & FC_SP_FT_FPORT) == 0) {
1800 if (e_d_tov > lport->e_d_tov)
1801 lport->e_d_tov = e_d_tov;
1802 lport->r_a_tov = 2 * lport->e_d_tov;
1803 fc_lport_set_port_id(lport, did, fp);
1804 printk(KERN_INFO "host%d: libfc: "
1805 "Port (%6.6x) entered "
1806 "point-to-point mode\n",
1807 lport->host->host_no, did);
1808 fc_lport_ptp_setup(lport, fc_frame_sid(fp),
1809 get_unaligned_be64(
1810 &flp->fl_wwpn),
1811 get_unaligned_be64(
1812 &flp->fl_wwnn));
1813 } else {
1814 if (e_d_tov > lport->e_d_tov)
1815 lport->e_d_tov = e_d_tov;
1816 if (r_a_tov > lport->r_a_tov)
1817 lport->r_a_tov = r_a_tov;
1818 fc_host_fabric_name(lport->host) =
1819 get_unaligned_be64(&flp->fl_wwnn);
1820 fc_lport_set_port_id(lport, did, fp);
1821 fc_lport_enter_dns(lport);
1822 }
1823
1824 out:
1825 fc_frame_free(fp);
1826 err:
1827 mutex_unlock(&lport->lp_mutex);
1828 }
1829 EXPORT_SYMBOL(fc_lport_flogi_resp);
1830
1831
1832
1833
1834
1835 static void fc_lport_enter_flogi(struct fc_lport *lport)
1836 {
1837 struct fc_frame *fp;
1838
1839 lockdep_assert_held(&lport->lp_mutex);
1840
1841 FC_LPORT_DBG(lport, "Entered FLOGI state from %s state\n",
1842 fc_lport_state(lport));
1843
1844 fc_lport_state_enter(lport, LPORT_ST_FLOGI);
1845
1846 if (lport->point_to_multipoint) {
1847 if (lport->port_id)
1848 fc_lport_enter_ready(lport);
1849 return;
1850 }
1851
1852 fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
1853 if (!fp)
1854 return fc_lport_error(lport, fp);
1855
1856 if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp,
1857 lport->vport ? ELS_FDISC : ELS_FLOGI,
1858 fc_lport_flogi_resp, lport,
1859 lport->vport ? 2 * lport->r_a_tov :
1860 lport->e_d_tov))
1861 fc_lport_error(lport, NULL);
1862 }
1863
1864
1865
1866
1867
1868 int fc_lport_config(struct fc_lport *lport)
1869 {
1870 INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
1871 mutex_init(&lport->lp_mutex);
1872
1873 fc_lport_state_enter(lport, LPORT_ST_DISABLED);
1874
1875 fc_lport_add_fc4_type(lport, FC_TYPE_FCP);
1876 fc_lport_add_fc4_type(lport, FC_TYPE_CT);
1877 fc_fc4_conf_lport_params(lport, FC_TYPE_FCP);
1878
1879 return 0;
1880 }
1881 EXPORT_SYMBOL(fc_lport_config);
1882
1883
1884
1885
1886
1887 int fc_lport_init(struct fc_lport *lport)
1888 {
1889 struct fc_host_attrs *fc_host;
1890
1891 fc_host = shost_to_fc_host(lport->host);
1892
1893
1894 fc_host->fdmi_version = FDMI_V2;
1895
1896 fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
1897 fc_host_node_name(lport->host) = lport->wwnn;
1898 fc_host_port_name(lport->host) = lport->wwpn;
1899 fc_host_supported_classes(lport->host) = FC_COS_CLASS3;
1900 memset(fc_host_supported_fc4s(lport->host), 0,
1901 sizeof(fc_host_supported_fc4s(lport->host)));
1902 fc_host_supported_fc4s(lport->host)[2] = 1;
1903 fc_host_supported_fc4s(lport->host)[7] = 1;
1904 fc_host_num_discovered_ports(lport->host) = 4;
1905
1906
1907 memset(fc_host_active_fc4s(lport->host), 0,
1908 sizeof(fc_host_active_fc4s(lport->host)));
1909 fc_host_active_fc4s(lport->host)[2] = 1;
1910 fc_host_active_fc4s(lport->host)[7] = 1;
1911 fc_host_maxframe_size(lport->host) = lport->mfs;
1912 fc_host_supported_speeds(lport->host) = 0;
1913 if (lport->link_supported_speeds & FC_PORTSPEED_1GBIT)
1914 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_1GBIT;
1915 if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
1916 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
1917 if (lport->link_supported_speeds & FC_PORTSPEED_40GBIT)
1918 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_40GBIT;
1919 if (lport->link_supported_speeds & FC_PORTSPEED_100GBIT)
1920 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_100GBIT;
1921 if (lport->link_supported_speeds & FC_PORTSPEED_25GBIT)
1922 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_25GBIT;
1923 if (lport->link_supported_speeds & FC_PORTSPEED_50GBIT)
1924 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_50GBIT;
1925 if (lport->link_supported_speeds & FC_PORTSPEED_100GBIT)
1926 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_100GBIT;
1927
1928 fc_fc4_add_lport(lport);
1929
1930 fc_host_num_discovered_ports(lport->host) = DISCOVERED_PORTS;
1931 fc_host_port_state(lport->host) = FC_PORTSTATE_ONLINE;
1932 fc_host_max_ct_payload(lport->host) = MAX_CT_PAYLOAD;
1933 fc_host_num_ports(lport->host) = NUMBER_OF_PORTS;
1934 fc_host_bootbios_state(lport->host) = 0X00000000;
1935 snprintf(fc_host_bootbios_version(lport->host),
1936 FC_SYMBOLIC_NAME_SIZE, "%s", "Unknown");
1937
1938 return 0;
1939 }
1940 EXPORT_SYMBOL(fc_lport_init);
1941
1942
1943
1944
1945
1946
1947
1948 static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
1949 void *info_arg)
1950 {
1951 struct fc_bsg_info *info = info_arg;
1952 struct bsg_job *job = info->job;
1953 struct fc_bsg_reply *bsg_reply = job->reply;
1954 struct fc_lport *lport = info->lport;
1955 struct fc_frame_header *fh;
1956 size_t len;
1957 void *buf;
1958
1959 if (IS_ERR(fp)) {
1960 bsg_reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
1961 -ECONNABORTED : -ETIMEDOUT;
1962 job->reply_len = sizeof(uint32_t);
1963 bsg_job_done(job, bsg_reply->result,
1964 bsg_reply->reply_payload_rcv_len);
1965 kfree(info);
1966 return;
1967 }
1968
1969 mutex_lock(&lport->lp_mutex);
1970 fh = fc_frame_header_get(fp);
1971 len = fr_len(fp) - sizeof(*fh);
1972 buf = fc_frame_payload_get(fp, 0);
1973
1974 if (fr_sof(fp) == FC_SOF_I3 && !ntohs(fh->fh_seq_cnt)) {
1975
1976 unsigned short cmd = (info->rsp_code == FC_FS_ACC) ?
1977 ntohs(((struct fc_ct_hdr *)buf)->ct_cmd) :
1978 (unsigned short)fc_frame_payload_op(fp);
1979
1980
1981 bsg_reply->reply_data.ctels_reply.status =
1982 (cmd == info->rsp_code) ?
1983 FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT;
1984 }
1985
1986 bsg_reply->reply_payload_rcv_len +=
1987 fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
1988 &info->offset, NULL);
1989
1990 if (fr_eof(fp) == FC_EOF_T &&
1991 (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
1992 (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
1993 if (bsg_reply->reply_payload_rcv_len >
1994 job->reply_payload.payload_len)
1995 bsg_reply->reply_payload_rcv_len =
1996 job->reply_payload.payload_len;
1997 bsg_reply->result = 0;
1998 bsg_job_done(job, bsg_reply->result,
1999 bsg_reply->reply_payload_rcv_len);
2000 kfree(info);
2001 }
2002 fc_frame_free(fp);
2003 mutex_unlock(&lport->lp_mutex);
2004 }
2005
2006
2007
2008
2009
2010
2011
2012
2013 static int fc_lport_els_request(struct bsg_job *job,
2014 struct fc_lport *lport,
2015 u32 did, u32 tov)
2016 {
2017 struct fc_bsg_info *info;
2018 struct fc_frame *fp;
2019 struct fc_frame_header *fh;
2020 char *pp;
2021 int len;
2022
2023 lockdep_assert_held(&lport->lp_mutex);
2024
2025 fp = fc_frame_alloc(lport, job->request_payload.payload_len);
2026 if (!fp)
2027 return -ENOMEM;
2028
2029 len = job->request_payload.payload_len;
2030 pp = fc_frame_payload_get(fp, len);
2031
2032 sg_copy_to_buffer(job->request_payload.sg_list,
2033 job->request_payload.sg_cnt,
2034 pp, len);
2035
2036 fh = fc_frame_header_get(fp);
2037 fh->fh_r_ctl = FC_RCTL_ELS_REQ;
2038 hton24(fh->fh_d_id, did);
2039 hton24(fh->fh_s_id, lport->port_id);
2040 fh->fh_type = FC_TYPE_ELS;
2041 hton24(fh->fh_f_ctl, FC_FCTL_REQ);
2042 fh->fh_cs_ctl = 0;
2043 fh->fh_df_ctl = 0;
2044 fh->fh_parm_offset = 0;
2045
2046 info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
2047 if (!info) {
2048 fc_frame_free(fp);
2049 return -ENOMEM;
2050 }
2051
2052 info->job = job;
2053 info->lport = lport;
2054 info->rsp_code = ELS_LS_ACC;
2055 info->nents = job->reply_payload.sg_cnt;
2056 info->sg = job->reply_payload.sg_list;
2057
2058 if (!fc_exch_seq_send(lport, fp, fc_lport_bsg_resp,
2059 NULL, info, tov)) {
2060 kfree(info);
2061 return -ECOMM;
2062 }
2063 return 0;
2064 }
2065
2066
2067
2068
2069
2070
2071
2072
2073 static int fc_lport_ct_request(struct bsg_job *job,
2074 struct fc_lport *lport, u32 did, u32 tov)
2075 {
2076 struct fc_bsg_info *info;
2077 struct fc_frame *fp;
2078 struct fc_frame_header *fh;
2079 struct fc_ct_req *ct;
2080 size_t len;
2081
2082 lockdep_assert_held(&lport->lp_mutex);
2083
2084 fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
2085 job->request_payload.payload_len);
2086 if (!fp)
2087 return -ENOMEM;
2088
2089 len = job->request_payload.payload_len;
2090 ct = fc_frame_payload_get(fp, len);
2091
2092 sg_copy_to_buffer(job->request_payload.sg_list,
2093 job->request_payload.sg_cnt,
2094 ct, len);
2095
2096 fh = fc_frame_header_get(fp);
2097 fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL;
2098 hton24(fh->fh_d_id, did);
2099 hton24(fh->fh_s_id, lport->port_id);
2100 fh->fh_type = FC_TYPE_CT;
2101 hton24(fh->fh_f_ctl, FC_FCTL_REQ);
2102 fh->fh_cs_ctl = 0;
2103 fh->fh_df_ctl = 0;
2104 fh->fh_parm_offset = 0;
2105
2106 info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
2107 if (!info) {
2108 fc_frame_free(fp);
2109 return -ENOMEM;
2110 }
2111
2112 info->job = job;
2113 info->lport = lport;
2114 info->rsp_code = FC_FS_ACC;
2115 info->nents = job->reply_payload.sg_cnt;
2116 info->sg = job->reply_payload.sg_list;
2117
2118 if (!fc_exch_seq_send(lport, fp, fc_lport_bsg_resp,
2119 NULL, info, tov)) {
2120 kfree(info);
2121 return -ECOMM;
2122 }
2123 return 0;
2124 }
2125
2126
2127
2128
2129
2130
2131 int fc_lport_bsg_request(struct bsg_job *job)
2132 {
2133 struct fc_bsg_request *bsg_request = job->request;
2134 struct fc_bsg_reply *bsg_reply = job->reply;
2135 struct Scsi_Host *shost = fc_bsg_to_shost(job);
2136 struct fc_lport *lport = shost_priv(shost);
2137 struct fc_rport *rport;
2138 struct fc_rport_priv *rdata;
2139 int rc = -EINVAL;
2140 u32 did, tov;
2141
2142 bsg_reply->reply_payload_rcv_len = 0;
2143
2144 mutex_lock(&lport->lp_mutex);
2145
2146 switch (bsg_request->msgcode) {
2147 case FC_BSG_RPT_ELS:
2148 rport = fc_bsg_to_rport(job);
2149 if (!rport)
2150 break;
2151
2152 rdata = rport->dd_data;
2153 rc = fc_lport_els_request(job, lport, rport->port_id,
2154 rdata->e_d_tov);
2155 break;
2156
2157 case FC_BSG_RPT_CT:
2158 rport = fc_bsg_to_rport(job);
2159 if (!rport)
2160 break;
2161
2162 rdata = rport->dd_data;
2163 rc = fc_lport_ct_request(job, lport, rport->port_id,
2164 rdata->e_d_tov);
2165 break;
2166
2167 case FC_BSG_HST_CT:
2168 did = ntoh24(bsg_request->rqst_data.h_ct.port_id);
2169 if (did == FC_FID_DIR_SERV) {
2170 rdata = lport->dns_rdata;
2171 if (!rdata)
2172 break;
2173 tov = rdata->e_d_tov;
2174 } else {
2175 rdata = fc_rport_lookup(lport, did);
2176 if (!rdata)
2177 break;
2178 tov = rdata->e_d_tov;
2179 kref_put(&rdata->kref, fc_rport_destroy);
2180 }
2181
2182 rc = fc_lport_ct_request(job, lport, did, tov);
2183 break;
2184
2185 case FC_BSG_HST_ELS_NOLOGIN:
2186 did = ntoh24(bsg_request->rqst_data.h_els.port_id);
2187 rc = fc_lport_els_request(job, lport, did, lport->e_d_tov);
2188 break;
2189 }
2190
2191 mutex_unlock(&lport->lp_mutex);
2192 return rc;
2193 }
2194 EXPORT_SYMBOL(fc_lport_bsg_request);