1 /* 2 * Copyright(c) 2007 Intel Corporation. All rights reserved. 3 * 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. 7 * 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 11 * more details. 12 * 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. 16 * 17 * Maintained at www.Open-FCoE.org 18 */ 19 20 /* 21 * PORT LOCKING NOTES 22 * 23 * These comments only apply to the 'port code' which consists of the lport, 24 * disc and rport blocks. 25 * 26 * MOTIVATION 27 * 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. 34 * 35 * HEIRARCHY 36 * 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- 40 * 41 * lport > disc, lport > rport, disc > rport 42 * 43 * CALLBACKS 44 * 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 47 * (to the lport). 48 * 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 56 * at the same time. 57 * 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. 62 */ 63 64 /* 65 * LPORT LOCKING 66 * 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 70 * performance. 71 * 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. 79 * 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. 84 * 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). 88 */ 89 90 #include <linux/timer.h> 91 #include <asm/unaligned.h> 92 93 #include <scsi/fc/fc_gs.h> 94 95 #include <scsi/libfc.h> 96 #include <scsi/fc_encode.h> 97 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 101 102 #define DNS_DELAY 3 /* Discovery delay after RSCN (in seconds)*/ 103 104 static void fc_lport_error(struct fc_lport *, struct fc_frame *); 105 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 *); 114 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", 125 }; 126 127 static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp) 128 { 129 fc_frame_free(fp); 130 return 0; 131 } 132 133 /** 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 138 * 139 * Locking Note: The rport lock should not be held when calling 140 * this function. 141 */ 142 static void fc_lport_rport_callback(struct fc_lport *lport, 143 struct fc_rport_priv *rdata, 144 enum fc_rport_event event) 145 { 146 FC_LPORT_DBG(lport, "Received a %d event for port (%6x)\n", event, 147 rdata->ids.port_id); 148 149 switch (event) { 150 case RPORT_EV_READY: 151 if (rdata->ids.port_id == FC_FID_DIR_SERV) { 152 mutex_lock(&lport->lp_mutex); 153 if (lport->state == LPORT_ST_DNS) { 154 lport->dns_rp = rdata; 155 fc_lport_enter_rpn_id(lport); 156 } else { 157 FC_LPORT_DBG(lport, "Received an READY event " 158 "on port (%6x) for the directory " 159 "server, but the lport is not " 160 "in the DNS state, it's in the " 161 "%d state", rdata->ids.port_id, 162 lport->state); 163 lport->tt.rport_logoff(rdata); 164 } 165 mutex_unlock(&lport->lp_mutex); 166 } else 167 FC_LPORT_DBG(lport, "Received an event for port (%6x) " 168 "which is not the directory server\n", 169 rdata->ids.port_id); 170 break; 171 case RPORT_EV_LOGO: 172 case RPORT_EV_FAILED: 173 case RPORT_EV_STOP: 174 if (rdata->ids.port_id == FC_FID_DIR_SERV) { 175 mutex_lock(&lport->lp_mutex); 176 lport->dns_rp = NULL; 177 mutex_unlock(&lport->lp_mutex); 178 179 } else 180 FC_LPORT_DBG(lport, "Received an event for port (%6x) " 181 "which is not the directory server\n", 182 rdata->ids.port_id); 183 break; 184 case RPORT_EV_NONE: 185 break; 186 } 187 } 188 189 /** 190 * fc_lport_state() - Return a string which represents the lport's state 191 * @lport: The lport whose state is to converted to a string 192 */ 193 static const char *fc_lport_state(struct fc_lport *lport) 194 { 195 const char *cp; 196 197 cp = fc_lport_state_names[lport->state]; 198 if (!cp) 199 cp = "unknown"; 200 return cp; 201 } 202 203 /** 204 * fc_lport_ptp_setup() - Create an rport for point-to-point mode 205 * @lport: The lport to attach the ptp rport to 206 * @fid: The FID of the ptp rport 207 * @remote_wwpn: The WWPN of the ptp rport 208 * @remote_wwnn: The WWNN of the ptp rport 209 */ 210 static void fc_lport_ptp_setup(struct fc_lport *lport, 211 u32 remote_fid, u64 remote_wwpn, 212 u64 remote_wwnn) 213 { 214 struct fc_rport_identifiers ids; 215 216 ids.port_id = remote_fid; 217 ids.port_name = remote_wwpn; 218 ids.node_name = remote_wwnn; 219 ids.roles = FC_RPORT_ROLE_UNKNOWN; 220 221 if (lport->ptp_rp) { 222 lport->tt.rport_logoff(lport->ptp_rp); 223 lport->ptp_rp = NULL; 224 } 225 226 lport->ptp_rp = lport->tt.rport_create(lport, &ids); 227 228 lport->tt.rport_login(lport->ptp_rp); 229 230 fc_lport_enter_ready(lport); 231 } 232 233 void fc_get_host_port_type(struct Scsi_Host *shost) 234 { 235 /* TODO - currently just NPORT */ 236 fc_host_port_type(shost) = FC_PORTTYPE_NPORT; 237 } 238 EXPORT_SYMBOL(fc_get_host_port_type); 239 240 void fc_get_host_port_state(struct Scsi_Host *shost) 241 { 242 struct fc_lport *lp = shost_priv(shost); 243 244 if (lp->link_up) 245 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; 246 else 247 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; 248 } 249 EXPORT_SYMBOL(fc_get_host_port_state); 250 251 void fc_get_host_speed(struct Scsi_Host *shost) 252 { 253 struct fc_lport *lport = shost_priv(shost); 254 255 fc_host_speed(shost) = lport->link_speed; 256 } 257 EXPORT_SYMBOL(fc_get_host_speed); 258 259 struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost) 260 { 261 struct fc_host_statistics *fcoe_stats; 262 struct fc_lport *lp = shost_priv(shost); 263 struct timespec v0, v1; 264 unsigned int cpu; 265 266 fcoe_stats = &lp->host_stats; 267 memset(fcoe_stats, 0, sizeof(struct fc_host_statistics)); 268 269 jiffies_to_timespec(jiffies, &v0); 270 jiffies_to_timespec(lp->boot_time, &v1); 271 fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec); 272 273 for_each_possible_cpu(cpu) { 274 struct fcoe_dev_stats *stats; 275 276 stats = per_cpu_ptr(lp->dev_stats, cpu); 277 278 fcoe_stats->tx_frames += stats->TxFrames; 279 fcoe_stats->tx_words += stats->TxWords; 280 fcoe_stats->rx_frames += stats->RxFrames; 281 fcoe_stats->rx_words += stats->RxWords; 282 fcoe_stats->error_frames += stats->ErrorFrames; 283 fcoe_stats->invalid_crc_count += stats->InvalidCRCCount; 284 fcoe_stats->fcp_input_requests += stats->InputRequests; 285 fcoe_stats->fcp_output_requests += stats->OutputRequests; 286 fcoe_stats->fcp_control_requests += stats->ControlRequests; 287 fcoe_stats->fcp_input_megabytes += stats->InputMegabytes; 288 fcoe_stats->fcp_output_megabytes += stats->OutputMegabytes; 289 fcoe_stats->link_failure_count += stats->LinkFailureCount; 290 } 291 fcoe_stats->lip_count = -1; 292 fcoe_stats->nos_count = -1; 293 fcoe_stats->loss_of_sync_count = -1; 294 fcoe_stats->loss_of_signal_count = -1; 295 fcoe_stats->prim_seq_protocol_err_count = -1; 296 fcoe_stats->dumped_frames = -1; 297 return fcoe_stats; 298 } 299 EXPORT_SYMBOL(fc_get_host_stats); 300 301 /* 302 * Fill in FLOGI command for request. 303 */ 304 static void 305 fc_lport_flogi_fill(struct fc_lport *lport, struct fc_els_flogi *flogi, 306 unsigned int op) 307 { 308 struct fc_els_csp *sp; 309 struct fc_els_cssp *cp; 310 311 memset(flogi, 0, sizeof(*flogi)); 312 flogi->fl_cmd = (u8) op; 313 put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn); 314 put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn); 315 sp = &flogi->fl_csp; 316 sp->sp_hi_ver = 0x20; 317 sp->sp_lo_ver = 0x20; 318 sp->sp_bb_cred = htons(10); /* this gets set by gateway */ 319 sp->sp_bb_data = htons((u16) lport->mfs); 320 cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ 321 cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); 322 if (op != ELS_FLOGI) { 323 sp->sp_features = htons(FC_SP_FT_CIRO); 324 sp->sp_tot_seq = htons(255); /* seq. we accept */ 325 sp->sp_rel_off = htons(0x1f); 326 sp->sp_e_d_tov = htonl(lport->e_d_tov); 327 328 cp->cp_rdfs = htons((u16) lport->mfs); 329 cp->cp_con_seq = htons(255); 330 cp->cp_open_seq = 1; 331 } 332 } 333 334 /* 335 * Add a supported FC-4 type. 336 */ 337 static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type) 338 { 339 __be32 *mp; 340 341 mp = &lport->fcts.ff_type_map[type / FC_NS_BPW]; 342 *mp = htonl(ntohl(*mp) | 1UL << (type % FC_NS_BPW)); 343 } 344 345 /** 346 * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report. 347 * @lport: Fibre Channel local port recieving the RLIR 348 * @sp: current sequence in the RLIR exchange 349 * @fp: RLIR request frame 350 * 351 * Locking Note: The lport lock is exected to be held before calling 352 * this function. 353 */ 354 static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp, 355 struct fc_lport *lport) 356 { 357 FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n", 358 fc_lport_state(lport)); 359 360 lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); 361 fc_frame_free(fp); 362 } 363 364 /** 365 * fc_lport_recv_echo_req() - Handle received ECHO request 366 * @lport: Fibre Channel local port recieving the ECHO 367 * @sp: current sequence in the ECHO exchange 368 * @fp: ECHO request frame 369 * 370 * Locking Note: The lport lock is exected to be held before calling 371 * this function. 372 */ 373 static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp, 374 struct fc_lport *lport) 375 { 376 struct fc_frame *fp; 377 struct fc_exch *ep = fc_seq_exch(sp); 378 unsigned int len; 379 void *pp; 380 void *dp; 381 u32 f_ctl; 382 383 FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n", 384 fc_lport_state(lport)); 385 386 len = fr_len(in_fp) - sizeof(struct fc_frame_header); 387 pp = fc_frame_payload_get(in_fp, len); 388 389 if (len < sizeof(__be32)) 390 len = sizeof(__be32); 391 392 fp = fc_frame_alloc(lport, len); 393 if (fp) { 394 dp = fc_frame_payload_get(fp, len); 395 memcpy(dp, pp, len); 396 *((u32 *)dp) = htonl(ELS_LS_ACC << 24); 397 sp = lport->tt.seq_start_next(sp); 398 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 399 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 400 FC_TYPE_ELS, f_ctl, 0); 401 lport->tt.seq_send(lport, sp, fp); 402 } 403 fc_frame_free(in_fp); 404 } 405 406 /** 407 * fc_lport_recv_echo_req() - Handle received Request Node ID data request 408 * @lport: Fibre Channel local port recieving the RNID 409 * @sp: current sequence in the RNID exchange 410 * @fp: RNID request frame 411 * 412 * Locking Note: The lport lock is exected to be held before calling 413 * this function. 414 */ 415 static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp, 416 struct fc_lport *lport) 417 { 418 struct fc_frame *fp; 419 struct fc_exch *ep = fc_seq_exch(sp); 420 struct fc_els_rnid *req; 421 struct { 422 struct fc_els_rnid_resp rnid; 423 struct fc_els_rnid_cid cid; 424 struct fc_els_rnid_gen gen; 425 } *rp; 426 struct fc_seq_els_data rjt_data; 427 u8 fmt; 428 size_t len; 429 u32 f_ctl; 430 431 FC_LPORT_DBG(lport, "Received RNID request while in state %s\n", 432 fc_lport_state(lport)); 433 434 req = fc_frame_payload_get(in_fp, sizeof(*req)); 435 if (!req) { 436 rjt_data.fp = NULL; 437 rjt_data.reason = ELS_RJT_LOGIC; 438 rjt_data.explan = ELS_EXPL_NONE; 439 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 440 } else { 441 fmt = req->rnid_fmt; 442 len = sizeof(*rp); 443 if (fmt != ELS_RNIDF_GEN || 444 ntohl(lport->rnid_gen.rnid_atype) == 0) { 445 fmt = ELS_RNIDF_NONE; /* nothing to provide */ 446 len -= sizeof(rp->gen); 447 } 448 fp = fc_frame_alloc(lport, len); 449 if (fp) { 450 rp = fc_frame_payload_get(fp, len); 451 memset(rp, 0, len); 452 rp->rnid.rnid_cmd = ELS_LS_ACC; 453 rp->rnid.rnid_fmt = fmt; 454 rp->rnid.rnid_cid_len = sizeof(rp->cid); 455 rp->cid.rnid_wwpn = htonll(lport->wwpn); 456 rp->cid.rnid_wwnn = htonll(lport->wwnn); 457 if (fmt == ELS_RNIDF_GEN) { 458 rp->rnid.rnid_sid_len = sizeof(rp->gen); 459 memcpy(&rp->gen, &lport->rnid_gen, 460 sizeof(rp->gen)); 461 } 462 sp = lport->tt.seq_start_next(sp); 463 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 464 f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 465 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 466 FC_TYPE_ELS, f_ctl, 0); 467 lport->tt.seq_send(lport, sp, fp); 468 } 469 } 470 fc_frame_free(in_fp); 471 } 472 473 /** 474 * fc_lport_recv_adisc_req() - Handle received Address Discovery Request 475 * @lport: Fibre Channel local port recieving the ADISC 476 * @sp: current sequence in the ADISC exchange 477 * @fp: ADISC request frame 478 * 479 * Locking Note: The lport lock is expected to be held before calling 480 * this function. 481 */ 482 static void fc_lport_recv_adisc_req(struct fc_seq *sp, struct fc_frame *in_fp, 483 struct fc_lport *lport) 484 { 485 struct fc_frame *fp; 486 struct fc_exch *ep = fc_seq_exch(sp); 487 struct fc_els_adisc *req, *rp; 488 struct fc_seq_els_data rjt_data; 489 size_t len; 490 u32 f_ctl; 491 492 FC_LPORT_DBG(lport, "Received ADISC request while in state %s\n", 493 fc_lport_state(lport)); 494 495 req = fc_frame_payload_get(in_fp, sizeof(*req)); 496 if (!req) { 497 rjt_data.fp = NULL; 498 rjt_data.reason = ELS_RJT_LOGIC; 499 rjt_data.explan = ELS_EXPL_NONE; 500 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 501 } else { 502 len = sizeof(*rp); 503 fp = fc_frame_alloc(lport, len); 504 if (fp) { 505 rp = fc_frame_payload_get(fp, len); 506 memset(rp, 0, len); 507 rp->adisc_cmd = ELS_LS_ACC; 508 rp->adisc_wwpn = htonll(lport->wwpn); 509 rp->adisc_wwnn = htonll(lport->wwnn); 510 hton24(rp->adisc_port_id, 511 fc_host_port_id(lport->host)); 512 sp = lport->tt.seq_start_next(sp); 513 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 514 f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 515 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 516 FC_TYPE_ELS, f_ctl, 0); 517 lport->tt.seq_send(lport, sp, fp); 518 } 519 } 520 fc_frame_free(in_fp); 521 } 522 523 /** 524 * fc_lport_recv_logo_req() - Handle received fabric LOGO request 525 * @lport: Fibre Channel local port recieving the LOGO 526 * @sp: current sequence in the LOGO exchange 527 * @fp: LOGO request frame 528 * 529 * Locking Note: The lport lock is exected to be held before calling 530 * this function. 531 */ 532 static void fc_lport_recv_logo_req(struct fc_seq *sp, struct fc_frame *fp, 533 struct fc_lport *lport) 534 { 535 lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); 536 fc_lport_enter_reset(lport); 537 fc_frame_free(fp); 538 } 539 540 /** 541 * fc_fabric_login() - Start the lport state machine 542 * @lport: The lport that should log into the fabric 543 * 544 * Locking Note: This function should not be called 545 * with the lport lock held. 546 */ 547 int fc_fabric_login(struct fc_lport *lport) 548 { 549 int rc = -1; 550 551 mutex_lock(&lport->lp_mutex); 552 if (lport->state == LPORT_ST_DISABLED) { 553 fc_lport_enter_reset(lport); 554 rc = 0; 555 } 556 mutex_unlock(&lport->lp_mutex); 557 558 return rc; 559 } 560 EXPORT_SYMBOL(fc_fabric_login); 561 562 /** 563 * fc_linkup() - Handler for transport linkup events 564 * @lport: The lport whose link is up 565 */ 566 void fc_linkup(struct fc_lport *lport) 567 { 568 printk(KERN_INFO "libfc: Link up on port (%6x)\n", 569 fc_host_port_id(lport->host)); 570 571 mutex_lock(&lport->lp_mutex); 572 if (!lport->link_up) { 573 lport->link_up = 1; 574 575 if (lport->state == LPORT_ST_RESET) 576 fc_lport_enter_flogi(lport); 577 } 578 mutex_unlock(&lport->lp_mutex); 579 } 580 EXPORT_SYMBOL(fc_linkup); 581 582 /** 583 * fc_linkdown() - Handler for transport linkdown events 584 * @lport: The lport whose link is down 585 */ 586 void fc_linkdown(struct fc_lport *lport) 587 { 588 mutex_lock(&lport->lp_mutex); 589 printk(KERN_INFO "libfc: Link down on port (%6x)\n", 590 fc_host_port_id(lport->host)); 591 592 if (lport->link_up) { 593 lport->link_up = 0; 594 fc_lport_enter_reset(lport); 595 lport->tt.fcp_cleanup(lport); 596 } 597 mutex_unlock(&lport->lp_mutex); 598 } 599 EXPORT_SYMBOL(fc_linkdown); 600 601 /** 602 * fc_fabric_logoff() - Logout of the fabric 603 * @lport: fc_lport pointer to logoff the fabric 604 * 605 * Return value: 606 * 0 for success, -1 for failure 607 */ 608 int fc_fabric_logoff(struct fc_lport *lport) 609 { 610 lport->tt.disc_stop_final(lport); 611 mutex_lock(&lport->lp_mutex); 612 if (lport->dns_rp) 613 lport->tt.rport_logoff(lport->dns_rp); 614 mutex_unlock(&lport->lp_mutex); 615 lport->tt.rport_flush_queue(); 616 mutex_lock(&lport->lp_mutex); 617 fc_lport_enter_logo(lport); 618 mutex_unlock(&lport->lp_mutex); 619 cancel_delayed_work_sync(&lport->retry_work); 620 return 0; 621 } 622 EXPORT_SYMBOL(fc_fabric_logoff); 623 624 /** 625 * fc_lport_destroy() - unregister a fc_lport 626 * @lport: fc_lport pointer to unregister 627 * 628 * Return value: 629 * None 630 * Note: 631 * exit routine for fc_lport instance 632 * clean-up all the allocated memory 633 * and free up other system resources. 634 * 635 */ 636 int fc_lport_destroy(struct fc_lport *lport) 637 { 638 mutex_lock(&lport->lp_mutex); 639 lport->state = LPORT_ST_DISABLED; 640 lport->link_up = 0; 641 lport->tt.frame_send = fc_frame_drop; 642 mutex_unlock(&lport->lp_mutex); 643 644 lport->tt.fcp_abort_io(lport); 645 lport->tt.disc_stop_final(lport); 646 lport->tt.exch_mgr_reset(lport, 0, 0); 647 return 0; 648 } 649 EXPORT_SYMBOL(fc_lport_destroy); 650 651 /** 652 * fc_set_mfs() - sets up the mfs for the corresponding fc_lport 653 * @lport: fc_lport pointer to unregister 654 * @mfs: the new mfs for fc_lport 655 * 656 * Set mfs for the given fc_lport to the new mfs. 657 * 658 * Return: 0 for success 659 */ 660 int fc_set_mfs(struct fc_lport *lport, u32 mfs) 661 { 662 unsigned int old_mfs; 663 int rc = -EINVAL; 664 665 mutex_lock(&lport->lp_mutex); 666 667 old_mfs = lport->mfs; 668 669 if (mfs >= FC_MIN_MAX_FRAME) { 670 mfs &= ~3; 671 if (mfs > FC_MAX_FRAME) 672 mfs = FC_MAX_FRAME; 673 mfs -= sizeof(struct fc_frame_header); 674 lport->mfs = mfs; 675 rc = 0; 676 } 677 678 if (!rc && mfs < old_mfs) 679 fc_lport_enter_reset(lport); 680 681 mutex_unlock(&lport->lp_mutex); 682 683 return rc; 684 } 685 EXPORT_SYMBOL(fc_set_mfs); 686 687 /** 688 * fc_lport_disc_callback() - Callback for discovery events 689 * @lport: FC local port 690 * @event: The discovery event 691 */ 692 void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event) 693 { 694 switch (event) { 695 case DISC_EV_SUCCESS: 696 FC_LPORT_DBG(lport, "Discovery succeeded\n"); 697 break; 698 case DISC_EV_FAILED: 699 printk(KERN_ERR "libfc: Discovery failed for port (%6x)\n", 700 fc_host_port_id(lport->host)); 701 mutex_lock(&lport->lp_mutex); 702 fc_lport_enter_reset(lport); 703 mutex_unlock(&lport->lp_mutex); 704 break; 705 case DISC_EV_NONE: 706 WARN_ON(1); 707 break; 708 } 709 } 710 711 /** 712 * fc_rport_enter_ready() - Enter the ready state and start discovery 713 * @lport: Fibre Channel local port that is ready 714 * 715 * Locking Note: The lport lock is expected to be held before calling 716 * this routine. 717 */ 718 static void fc_lport_enter_ready(struct fc_lport *lport) 719 { 720 FC_LPORT_DBG(lport, "Entered READY from state %s\n", 721 fc_lport_state(lport)); 722 723 fc_lport_state_enter(lport, LPORT_ST_READY); 724 725 lport->tt.disc_start(fc_lport_disc_callback, lport); 726 } 727 728 /** 729 * fc_lport_recv_flogi_req() - Receive a FLOGI request 730 * @sp_in: The sequence the FLOGI is on 731 * @rx_fp: The frame the FLOGI is in 732 * @lport: The lport that recieved the request 733 * 734 * A received FLOGI request indicates a point-to-point connection. 735 * Accept it with the common service parameters indicating our N port. 736 * Set up to do a PLOGI if we have the higher-number WWPN. 737 * 738 * Locking Note: The lport lock is exected to be held before calling 739 * this function. 740 */ 741 static void fc_lport_recv_flogi_req(struct fc_seq *sp_in, 742 struct fc_frame *rx_fp, 743 struct fc_lport *lport) 744 { 745 struct fc_frame *fp; 746 struct fc_frame_header *fh; 747 struct fc_seq *sp; 748 struct fc_exch *ep; 749 struct fc_els_flogi *flp; 750 struct fc_els_flogi *new_flp; 751 u64 remote_wwpn; 752 u32 remote_fid; 753 u32 local_fid; 754 u32 f_ctl; 755 756 FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n", 757 fc_lport_state(lport)); 758 759 fh = fc_frame_header_get(rx_fp); 760 remote_fid = ntoh24(fh->fh_s_id); 761 flp = fc_frame_payload_get(rx_fp, sizeof(*flp)); 762 if (!flp) 763 goto out; 764 remote_wwpn = get_unaligned_be64(&flp->fl_wwpn); 765 if (remote_wwpn == lport->wwpn) { 766 printk(KERN_WARNING "libfc: Received FLOGI from port " 767 "with same WWPN %llx\n", remote_wwpn); 768 goto out; 769 } 770 FC_LPORT_DBG(lport, "FLOGI from port WWPN %llx\n", remote_wwpn); 771 772 /* 773 * XXX what is the right thing to do for FIDs? 774 * The originator might expect our S_ID to be 0xfffffe. 775 * But if so, both of us could end up with the same FID. 776 */ 777 local_fid = FC_LOCAL_PTP_FID_LO; 778 if (remote_wwpn < lport->wwpn) { 779 local_fid = FC_LOCAL_PTP_FID_HI; 780 if (!remote_fid || remote_fid == local_fid) 781 remote_fid = FC_LOCAL_PTP_FID_LO; 782 } else if (!remote_fid) { 783 remote_fid = FC_LOCAL_PTP_FID_HI; 784 } 785 786 fc_host_port_id(lport->host) = local_fid; 787 788 fp = fc_frame_alloc(lport, sizeof(*flp)); 789 if (fp) { 790 sp = lport->tt.seq_start_next(fr_seq(rx_fp)); 791 new_flp = fc_frame_payload_get(fp, sizeof(*flp)); 792 fc_lport_flogi_fill(lport, new_flp, ELS_FLOGI); 793 new_flp->fl_cmd = (u8) ELS_LS_ACC; 794 795 /* 796 * Send the response. If this fails, the originator should 797 * repeat the sequence. 798 */ 799 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; 800 ep = fc_seq_exch(sp); 801 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 802 FC_TYPE_ELS, f_ctl, 0); 803 lport->tt.seq_send(lport, sp, fp); 804 805 } else { 806 fc_lport_error(lport, fp); 807 } 808 fc_lport_ptp_setup(lport, remote_fid, remote_wwpn, 809 get_unaligned_be64(&flp->fl_wwnn)); 810 811 lport->tt.disc_start(fc_lport_disc_callback, lport); 812 813 out: 814 sp = fr_seq(rx_fp); 815 fc_frame_free(rx_fp); 816 } 817 818 /** 819 * fc_lport_recv_req() - The generic lport request handler 820 * @lport: The lport that received the request 821 * @sp: The sequence the request is on 822 * @fp: The frame the request is in 823 * 824 * This function will see if the lport handles the request or 825 * if an rport should handle the request. 826 * 827 * Locking Note: This function should not be called with the lport 828 * lock held becuase it will grab the lock. 829 */ 830 static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, 831 struct fc_frame *fp) 832 { 833 struct fc_frame_header *fh = fc_frame_header_get(fp); 834 void (*recv) (struct fc_seq *, struct fc_frame *, struct fc_lport *); 835 struct fc_rport_priv *rdata; 836 u32 s_id; 837 u32 d_id; 838 struct fc_seq_els_data rjt_data; 839 840 mutex_lock(&lport->lp_mutex); 841 842 /* 843 * Handle special ELS cases like FLOGI, LOGO, and 844 * RSCN here. These don't require a session. 845 * Even if we had a session, it might not be ready. 846 */ 847 if (!lport->link_up) 848 fc_frame_free(fp); 849 else if (fh->fh_type == FC_TYPE_ELS && 850 fh->fh_r_ctl == FC_RCTL_ELS_REQ) { 851 /* 852 * Check opcode. 853 */ 854 recv = NULL; 855 switch (fc_frame_payload_op(fp)) { 856 case ELS_FLOGI: 857 recv = fc_lport_recv_flogi_req; 858 break; 859 case ELS_LOGO: 860 fh = fc_frame_header_get(fp); 861 if (ntoh24(fh->fh_s_id) == FC_FID_FLOGI) 862 recv = fc_lport_recv_logo_req; 863 break; 864 case ELS_RSCN: 865 recv = lport->tt.disc_recv_req; 866 break; 867 case ELS_ECHO: 868 recv = fc_lport_recv_echo_req; 869 break; 870 case ELS_RLIR: 871 recv = fc_lport_recv_rlir_req; 872 break; 873 case ELS_RNID: 874 recv = fc_lport_recv_rnid_req; 875 break; 876 case ELS_ADISC: 877 recv = fc_lport_recv_adisc_req; 878 break; 879 } 880 881 if (recv) 882 recv(sp, fp, lport); 883 else { 884 /* 885 * Find session. 886 * If this is a new incoming PLOGI, we won't find it. 887 */ 888 s_id = ntoh24(fh->fh_s_id); 889 d_id = ntoh24(fh->fh_d_id); 890 891 rdata = lport->tt.rport_lookup(lport, s_id); 892 if (rdata) 893 lport->tt.rport_recv_req(sp, fp, rdata); 894 else { 895 rjt_data.fp = NULL; 896 rjt_data.reason = ELS_RJT_UNAB; 897 rjt_data.explan = ELS_EXPL_NONE; 898 lport->tt.seq_els_rsp_send(sp, 899 ELS_LS_RJT, 900 &rjt_data); 901 fc_frame_free(fp); 902 } 903 } 904 } else { 905 FC_LPORT_DBG(lport, "dropping invalid frame (eof %x)\n", 906 fr_eof(fp)); 907 fc_frame_free(fp); 908 } 909 mutex_unlock(&lport->lp_mutex); 910 911 /* 912 * The common exch_done for all request may not be good 913 * if any request requires longer hold on exhange. XXX 914 */ 915 lport->tt.exch_done(sp); 916 } 917 918 /** 919 * fc_lport_reset() - Reset an lport 920 * @lport: The lport which should be reset 921 * 922 * Locking Note: This functions should not be called with the 923 * lport lock held. 924 */ 925 int fc_lport_reset(struct fc_lport *lport) 926 { 927 cancel_delayed_work_sync(&lport->retry_work); 928 mutex_lock(&lport->lp_mutex); 929 fc_lport_enter_reset(lport); 930 mutex_unlock(&lport->lp_mutex); 931 return 0; 932 } 933 EXPORT_SYMBOL(fc_lport_reset); 934 935 /** 936 * fc_lport_reset_locked() - Reset the local port 937 * @lport: Fibre Channel local port to be reset 938 * 939 * Locking Note: The lport lock is expected to be held before calling 940 * this routine. 941 */ 942 static void fc_lport_reset_locked(struct fc_lport *lport) 943 { 944 if (lport->dns_rp) 945 lport->tt.rport_logoff(lport->dns_rp); 946 947 if (lport->ptp_rp) { 948 lport->tt.rport_logoff(lport->ptp_rp); 949 lport->ptp_rp = NULL; 950 } 951 952 lport->tt.disc_stop(lport); 953 954 lport->tt.exch_mgr_reset(lport, 0, 0); 955 fc_host_fabric_name(lport->host) = 0; 956 fc_host_port_id(lport->host) = 0; 957 } 958 959 /** 960 * fc_lport_enter_reset() - Reset the local port 961 * @lport: Fibre Channel local port to be reset 962 * 963 * Locking Note: The lport lock is expected to be held before calling 964 * this routine. 965 */ 966 static void fc_lport_enter_reset(struct fc_lport *lport) 967 { 968 FC_LPORT_DBG(lport, "Entered RESET state from %s state\n", 969 fc_lport_state(lport)); 970 971 fc_lport_state_enter(lport, LPORT_ST_RESET); 972 fc_lport_reset_locked(lport); 973 if (lport->link_up) 974 fc_lport_enter_flogi(lport); 975 } 976 977 /** 978 * fc_lport_enter_disabled() - disable the local port 979 * @lport: Fibre Channel local port to be reset 980 * 981 * Locking Note: The lport lock is expected to be held before calling 982 * this routine. 983 */ 984 static void fc_lport_enter_disabled(struct fc_lport *lport) 985 { 986 FC_LPORT_DBG(lport, "Entered disabled state from %s state\n", 987 fc_lport_state(lport)); 988 989 fc_lport_state_enter(lport, LPORT_ST_DISABLED); 990 fc_lport_reset_locked(lport); 991 } 992 993 /** 994 * fc_lport_error() - Handler for any errors 995 * @lport: The fc_lport object 996 * @fp: The frame pointer 997 * 998 * If the error was caused by a resource allocation failure 999 * then wait for half a second and retry, otherwise retry 1000 * after the e_d_tov time. 1001 */ 1002 static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp) 1003 { 1004 unsigned long delay = 0; 1005 FC_LPORT_DBG(lport, "Error %ld in state %s, retries %d\n", 1006 PTR_ERR(fp), fc_lport_state(lport), 1007 lport->retry_count); 1008 1009 if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) { 1010 /* 1011 * Memory allocation failure, or the exchange timed out. 1012 * Retry after delay 1013 */ 1014 if (lport->retry_count < lport->max_retry_count) { 1015 lport->retry_count++; 1016 if (!fp) 1017 delay = msecs_to_jiffies(500); 1018 else 1019 delay = msecs_to_jiffies(lport->e_d_tov); 1020 1021 schedule_delayed_work(&lport->retry_work, delay); 1022 } else { 1023 switch (lport->state) { 1024 case LPORT_ST_DISABLED: 1025 case LPORT_ST_READY: 1026 case LPORT_ST_RESET: 1027 case LPORT_ST_RPN_ID: 1028 case LPORT_ST_RFT_ID: 1029 case LPORT_ST_SCR: 1030 case LPORT_ST_DNS: 1031 case LPORT_ST_FLOGI: 1032 case LPORT_ST_LOGO: 1033 fc_lport_enter_reset(lport); 1034 break; 1035 } 1036 } 1037 } 1038 } 1039 1040 /** 1041 * fc_lport_rft_id_resp() - Handle response to Register Fibre 1042 * Channel Types by ID (RPN_ID) request 1043 * @sp: current sequence in RPN_ID exchange 1044 * @fp: response frame 1045 * @lp_arg: Fibre Channel host port instance 1046 * 1047 * Locking Note: This function will be called without the lport lock 1048 * held, but it will lock, call an _enter_* function or fc_lport_error 1049 * and then unlock the lport. 1050 */ 1051 static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp, 1052 void *lp_arg) 1053 { 1054 struct fc_lport *lport = lp_arg; 1055 struct fc_frame_header *fh; 1056 struct fc_ct_hdr *ct; 1057 1058 if (fp == ERR_PTR(-FC_EX_CLOSED)) 1059 return; 1060 1061 mutex_lock(&lport->lp_mutex); 1062 1063 FC_LPORT_DBG(lport, "Received a RFT_ID response\n"); 1064 1065 if (lport->state != LPORT_ST_RFT_ID) { 1066 FC_LPORT_DBG(lport, "Received a RFT_ID response, but in state " 1067 "%s\n", fc_lport_state(lport)); 1068 if (IS_ERR(fp)) 1069 goto err; 1070 goto out; 1071 } 1072 1073 if (IS_ERR(fp)) { 1074 fc_lport_error(lport, fp); 1075 goto err; 1076 } 1077 1078 fh = fc_frame_header_get(fp); 1079 ct = fc_frame_payload_get(fp, sizeof(*ct)); 1080 1081 if (fh && ct && fh->fh_type == FC_TYPE_CT && 1082 ct->ct_fs_type == FC_FST_DIR && 1083 ct->ct_fs_subtype == FC_NS_SUBTYPE && 1084 ntohs(ct->ct_cmd) == FC_FS_ACC) 1085 fc_lport_enter_scr(lport); 1086 else 1087 fc_lport_error(lport, fp); 1088 out: 1089 fc_frame_free(fp); 1090 err: 1091 mutex_unlock(&lport->lp_mutex); 1092 } 1093 1094 /** 1095 * fc_lport_rpn_id_resp() - Handle response to Register Port 1096 * Name by ID (RPN_ID) request 1097 * @sp: current sequence in RPN_ID exchange 1098 * @fp: response frame 1099 * @lp_arg: Fibre Channel host port instance 1100 * 1101 * Locking Note: This function will be called without the lport lock 1102 * held, but it will lock, call an _enter_* function or fc_lport_error 1103 * and then unlock the lport. 1104 */ 1105 static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, 1106 void *lp_arg) 1107 { 1108 struct fc_lport *lport = lp_arg; 1109 struct fc_frame_header *fh; 1110 struct fc_ct_hdr *ct; 1111 1112 if (fp == ERR_PTR(-FC_EX_CLOSED)) 1113 return; 1114 1115 mutex_lock(&lport->lp_mutex); 1116 1117 FC_LPORT_DBG(lport, "Received a RPN_ID response\n"); 1118 1119 if (lport->state != LPORT_ST_RPN_ID) { 1120 FC_LPORT_DBG(lport, "Received a RPN_ID response, but in state " 1121 "%s\n", fc_lport_state(lport)); 1122 if (IS_ERR(fp)) 1123 goto err; 1124 goto out; 1125 } 1126 1127 if (IS_ERR(fp)) { 1128 fc_lport_error(lport, fp); 1129 goto err; 1130 } 1131 1132 fh = fc_frame_header_get(fp); 1133 ct = fc_frame_payload_get(fp, sizeof(*ct)); 1134 if (fh && ct && fh->fh_type == FC_TYPE_CT && 1135 ct->ct_fs_type == FC_FST_DIR && 1136 ct->ct_fs_subtype == FC_NS_SUBTYPE && 1137 ntohs(ct->ct_cmd) == FC_FS_ACC) 1138 fc_lport_enter_rft_id(lport); 1139 else 1140 fc_lport_error(lport, fp); 1141 1142 out: 1143 fc_frame_free(fp); 1144 err: 1145 mutex_unlock(&lport->lp_mutex); 1146 } 1147 1148 /** 1149 * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request 1150 * @sp: current sequence in SCR exchange 1151 * @fp: response frame 1152 * @lp_arg: Fibre Channel lport port instance that sent the registration request 1153 * 1154 * Locking Note: This function will be called without the lport lock 1155 * held, but it will lock, call an _enter_* function or fc_lport_error 1156 * and then unlock the lport. 1157 */ 1158 static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp, 1159 void *lp_arg) 1160 { 1161 struct fc_lport *lport = lp_arg; 1162 u8 op; 1163 1164 if (fp == ERR_PTR(-FC_EX_CLOSED)) 1165 return; 1166 1167 mutex_lock(&lport->lp_mutex); 1168 1169 FC_LPORT_DBG(lport, "Received a SCR response\n"); 1170 1171 if (lport->state != LPORT_ST_SCR) { 1172 FC_LPORT_DBG(lport, "Received a SCR response, but in state " 1173 "%s\n", fc_lport_state(lport)); 1174 if (IS_ERR(fp)) 1175 goto err; 1176 goto out; 1177 } 1178 1179 if (IS_ERR(fp)) { 1180 fc_lport_error(lport, fp); 1181 goto err; 1182 } 1183 1184 op = fc_frame_payload_op(fp); 1185 if (op == ELS_LS_ACC) 1186 fc_lport_enter_ready(lport); 1187 else 1188 fc_lport_error(lport, fp); 1189 1190 out: 1191 fc_frame_free(fp); 1192 err: 1193 mutex_unlock(&lport->lp_mutex); 1194 } 1195 1196 /** 1197 * fc_lport_enter_scr() - Send a State Change Register (SCR) request 1198 * @lport: Fibre Channel local port to register for state changes 1199 * 1200 * Locking Note: The lport lock is expected to be held before calling 1201 * this routine. 1202 */ 1203 static void fc_lport_enter_scr(struct fc_lport *lport) 1204 { 1205 struct fc_frame *fp; 1206 1207 FC_LPORT_DBG(lport, "Entered SCR state from %s state\n", 1208 fc_lport_state(lport)); 1209 1210 fc_lport_state_enter(lport, LPORT_ST_SCR); 1211 1212 fp = fc_frame_alloc(lport, sizeof(struct fc_els_scr)); 1213 if (!fp) { 1214 fc_lport_error(lport, fp); 1215 return; 1216 } 1217 1218 if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR, 1219 fc_lport_scr_resp, lport, lport->e_d_tov)) 1220 fc_lport_error(lport, fp); 1221 } 1222 1223 /** 1224 * fc_lport_enter_rft_id() - Register FC4-types with the name server 1225 * @lport: Fibre Channel local port to register 1226 * 1227 * Locking Note: The lport lock is expected to be held before calling 1228 * this routine. 1229 */ 1230 static void fc_lport_enter_rft_id(struct fc_lport *lport) 1231 { 1232 struct fc_frame *fp; 1233 struct fc_ns_fts *lps; 1234 int i; 1235 1236 FC_LPORT_DBG(lport, "Entered RFT_ID state from %s state\n", 1237 fc_lport_state(lport)); 1238 1239 fc_lport_state_enter(lport, LPORT_ST_RFT_ID); 1240 1241 lps = &lport->fcts; 1242 i = sizeof(lps->ff_type_map) / sizeof(lps->ff_type_map[0]); 1243 while (--i >= 0) 1244 if (ntohl(lps->ff_type_map[i]) != 0) 1245 break; 1246 if (i < 0) { 1247 /* nothing to register, move on to SCR */ 1248 fc_lport_enter_scr(lport); 1249 return; 1250 } 1251 1252 fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) + 1253 sizeof(struct fc_ns_rft)); 1254 if (!fp) { 1255 fc_lport_error(lport, fp); 1256 return; 1257 } 1258 1259 if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RFT_ID, 1260 fc_lport_rft_id_resp, 1261 lport, lport->e_d_tov)) 1262 fc_lport_error(lport, fp); 1263 } 1264 1265 /** 1266 * fc_rport_enter_rft_id() - Register port name with the name server 1267 * @lport: Fibre Channel local port to register 1268 * 1269 * Locking Note: The lport lock is expected to be held before calling 1270 * this routine. 1271 */ 1272 static void fc_lport_enter_rpn_id(struct fc_lport *lport) 1273 { 1274 struct fc_frame *fp; 1275 1276 FC_LPORT_DBG(lport, "Entered RPN_ID state from %s state\n", 1277 fc_lport_state(lport)); 1278 1279 fc_lport_state_enter(lport, LPORT_ST_RPN_ID); 1280 1281 fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) + 1282 sizeof(struct fc_ns_rn_id)); 1283 if (!fp) { 1284 fc_lport_error(lport, fp); 1285 return; 1286 } 1287 1288 if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RPN_ID, 1289 fc_lport_rpn_id_resp, 1290 lport, lport->e_d_tov)) 1291 fc_lport_error(lport, fp); 1292 } 1293 1294 static struct fc_rport_operations fc_lport_rport_ops = { 1295 .event_callback = fc_lport_rport_callback, 1296 }; 1297 1298 /** 1299 * fc_rport_enter_dns() - Create a rport to the name server 1300 * @lport: Fibre Channel local port requesting a rport for the name server 1301 * 1302 * Locking Note: The lport lock is expected to be held before calling 1303 * this routine. 1304 */ 1305 static void fc_lport_enter_dns(struct fc_lport *lport) 1306 { 1307 struct fc_rport_priv *rdata; 1308 struct fc_rport_identifiers ids; 1309 1310 ids.port_id = FC_FID_DIR_SERV; 1311 ids.port_name = -1; 1312 ids.node_name = -1; 1313 ids.roles = FC_RPORT_ROLE_UNKNOWN; 1314 1315 FC_LPORT_DBG(lport, "Entered DNS state from %s state\n", 1316 fc_lport_state(lport)); 1317 1318 fc_lport_state_enter(lport, LPORT_ST_DNS); 1319 1320 rdata = lport->tt.rport_create(lport, &ids); 1321 if (!rdata) 1322 goto err; 1323 1324 rdata->ops = &fc_lport_rport_ops; 1325 lport->tt.rport_login(rdata); 1326 return; 1327 1328 err: 1329 fc_lport_error(lport, NULL); 1330 } 1331 1332 /** 1333 * fc_lport_timeout() - Handler for the retry_work timer. 1334 * @work: The work struct of the fc_lport 1335 */ 1336 static void fc_lport_timeout(struct work_struct *work) 1337 { 1338 struct fc_lport *lport = 1339 container_of(work, struct fc_lport, 1340 retry_work.work); 1341 1342 mutex_lock(&lport->lp_mutex); 1343 1344 switch (lport->state) { 1345 case LPORT_ST_DISABLED: 1346 case LPORT_ST_READY: 1347 case LPORT_ST_RESET: 1348 WARN_ON(1); 1349 break; 1350 case LPORT_ST_FLOGI: 1351 fc_lport_enter_flogi(lport); 1352 break; 1353 case LPORT_ST_DNS: 1354 fc_lport_enter_dns(lport); 1355 break; 1356 case LPORT_ST_RPN_ID: 1357 fc_lport_enter_rpn_id(lport); 1358 break; 1359 case LPORT_ST_RFT_ID: 1360 fc_lport_enter_rft_id(lport); 1361 break; 1362 case LPORT_ST_SCR: 1363 fc_lport_enter_scr(lport); 1364 break; 1365 case LPORT_ST_LOGO: 1366 fc_lport_enter_logo(lport); 1367 break; 1368 } 1369 1370 mutex_unlock(&lport->lp_mutex); 1371 } 1372 1373 /** 1374 * fc_lport_logo_resp() - Handle response to LOGO request 1375 * @sp: current sequence in LOGO exchange 1376 * @fp: response frame 1377 * @lp_arg: Fibre Channel lport port instance that sent the LOGO request 1378 * 1379 * Locking Note: This function will be called without the lport lock 1380 * held, but it will lock, call an _enter_* function or fc_lport_error 1381 * and then unlock the lport. 1382 */ 1383 static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, 1384 void *lp_arg) 1385 { 1386 struct fc_lport *lport = lp_arg; 1387 u8 op; 1388 1389 if (fp == ERR_PTR(-FC_EX_CLOSED)) 1390 return; 1391 1392 mutex_lock(&lport->lp_mutex); 1393 1394 FC_LPORT_DBG(lport, "Received a LOGO response\n"); 1395 1396 if (lport->state != LPORT_ST_LOGO) { 1397 FC_LPORT_DBG(lport, "Received a LOGO response, but in state " 1398 "%s\n", fc_lport_state(lport)); 1399 if (IS_ERR(fp)) 1400 goto err; 1401 goto out; 1402 } 1403 1404 if (IS_ERR(fp)) { 1405 fc_lport_error(lport, fp); 1406 goto err; 1407 } 1408 1409 op = fc_frame_payload_op(fp); 1410 if (op == ELS_LS_ACC) 1411 fc_lport_enter_disabled(lport); 1412 else 1413 fc_lport_error(lport, fp); 1414 1415 out: 1416 fc_frame_free(fp); 1417 err: 1418 mutex_unlock(&lport->lp_mutex); 1419 } 1420 1421 /** 1422 * fc_rport_enter_logo() - Logout of the fabric 1423 * @lport: Fibre Channel local port to be logged out 1424 * 1425 * Locking Note: The lport lock is expected to be held before calling 1426 * this routine. 1427 */ 1428 static void fc_lport_enter_logo(struct fc_lport *lport) 1429 { 1430 struct fc_frame *fp; 1431 struct fc_els_logo *logo; 1432 1433 FC_LPORT_DBG(lport, "Entered LOGO state from %s state\n", 1434 fc_lport_state(lport)); 1435 1436 fc_lport_state_enter(lport, LPORT_ST_LOGO); 1437 1438 fp = fc_frame_alloc(lport, sizeof(*logo)); 1439 if (!fp) { 1440 fc_lport_error(lport, fp); 1441 return; 1442 } 1443 1444 if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO, 1445 fc_lport_logo_resp, lport, lport->e_d_tov)) 1446 fc_lport_error(lport, fp); 1447 } 1448 1449 /** 1450 * fc_lport_flogi_resp() - Handle response to FLOGI request 1451 * @sp: current sequence in FLOGI exchange 1452 * @fp: response frame 1453 * @lp_arg: Fibre Channel lport port instance that sent the FLOGI request 1454 * 1455 * Locking Note: This function will be called without the lport lock 1456 * held, but it will lock, call an _enter_* function or fc_lport_error 1457 * and then unlock the lport. 1458 */ 1459 static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, 1460 void *lp_arg) 1461 { 1462 struct fc_lport *lport = lp_arg; 1463 struct fc_frame_header *fh; 1464 struct fc_els_flogi *flp; 1465 u32 did; 1466 u16 csp_flags; 1467 unsigned int r_a_tov; 1468 unsigned int e_d_tov; 1469 u16 mfs; 1470 1471 if (fp == ERR_PTR(-FC_EX_CLOSED)) 1472 return; 1473 1474 mutex_lock(&lport->lp_mutex); 1475 1476 FC_LPORT_DBG(lport, "Received a FLOGI response\n"); 1477 1478 if (lport->state != LPORT_ST_FLOGI) { 1479 FC_LPORT_DBG(lport, "Received a FLOGI response, but in state " 1480 "%s\n", fc_lport_state(lport)); 1481 if (IS_ERR(fp)) 1482 goto err; 1483 goto out; 1484 } 1485 1486 if (IS_ERR(fp)) { 1487 fc_lport_error(lport, fp); 1488 goto err; 1489 } 1490 1491 fh = fc_frame_header_get(fp); 1492 did = ntoh24(fh->fh_d_id); 1493 if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { 1494 1495 printk(KERN_INFO "libfc: Assigned FID (%6x) in FLOGI response\n", 1496 did); 1497 fc_host_port_id(lport->host) = did; 1498 1499 flp = fc_frame_payload_get(fp, sizeof(*flp)); 1500 if (flp) { 1501 mfs = ntohs(flp->fl_csp.sp_bb_data) & 1502 FC_SP_BB_DATA_MASK; 1503 if (mfs >= FC_SP_MIN_MAX_PAYLOAD && 1504 mfs < lport->mfs) 1505 lport->mfs = mfs; 1506 csp_flags = ntohs(flp->fl_csp.sp_features); 1507 r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov); 1508 e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); 1509 if (csp_flags & FC_SP_FT_EDTR) 1510 e_d_tov /= 1000000; 1511 if ((csp_flags & FC_SP_FT_FPORT) == 0) { 1512 if (e_d_tov > lport->e_d_tov) 1513 lport->e_d_tov = e_d_tov; 1514 lport->r_a_tov = 2 * e_d_tov; 1515 printk(KERN_INFO "libfc: Port (%6x) entered " 1516 "point to point mode\n", did); 1517 fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id), 1518 get_unaligned_be64( 1519 &flp->fl_wwpn), 1520 get_unaligned_be64( 1521 &flp->fl_wwnn)); 1522 } else { 1523 lport->e_d_tov = e_d_tov; 1524 lport->r_a_tov = r_a_tov; 1525 fc_host_fabric_name(lport->host) = 1526 get_unaligned_be64(&flp->fl_wwnn); 1527 fc_lport_enter_dns(lport); 1528 } 1529 } 1530 1531 if (flp) { 1532 csp_flags = ntohs(flp->fl_csp.sp_features); 1533 if ((csp_flags & FC_SP_FT_FPORT) == 0) { 1534 lport->tt.disc_start(fc_lport_disc_callback, 1535 lport); 1536 } 1537 } 1538 } else { 1539 FC_LPORT_DBG(lport, "Bad FLOGI response\n"); 1540 } 1541 1542 out: 1543 fc_frame_free(fp); 1544 err: 1545 mutex_unlock(&lport->lp_mutex); 1546 } 1547 1548 /** 1549 * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager 1550 * @lport: Fibre Channel local port to be logged in to the fabric 1551 * 1552 * Locking Note: The lport lock is expected to be held before calling 1553 * this routine. 1554 */ 1555 void fc_lport_enter_flogi(struct fc_lport *lport) 1556 { 1557 struct fc_frame *fp; 1558 1559 FC_LPORT_DBG(lport, "Entered FLOGI state from %s state\n", 1560 fc_lport_state(lport)); 1561 1562 fc_lport_state_enter(lport, LPORT_ST_FLOGI); 1563 1564 fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi)); 1565 if (!fp) 1566 return fc_lport_error(lport, fp); 1567 1568 if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_FLOGI, 1569 fc_lport_flogi_resp, lport, lport->e_d_tov)) 1570 fc_lport_error(lport, fp); 1571 } 1572 1573 /* Configure a fc_lport */ 1574 int fc_lport_config(struct fc_lport *lport) 1575 { 1576 INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout); 1577 mutex_init(&lport->lp_mutex); 1578 1579 fc_lport_state_enter(lport, LPORT_ST_DISABLED); 1580 1581 fc_lport_add_fc4_type(lport, FC_TYPE_FCP); 1582 fc_lport_add_fc4_type(lport, FC_TYPE_CT); 1583 1584 return 0; 1585 } 1586 EXPORT_SYMBOL(fc_lport_config); 1587 1588 int fc_lport_init(struct fc_lport *lport) 1589 { 1590 if (!lport->tt.lport_recv) 1591 lport->tt.lport_recv = fc_lport_recv_req; 1592 1593 if (!lport->tt.lport_reset) 1594 lport->tt.lport_reset = fc_lport_reset; 1595 1596 fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; 1597 fc_host_node_name(lport->host) = lport->wwnn; 1598 fc_host_port_name(lport->host) = lport->wwpn; 1599 fc_host_supported_classes(lport->host) = FC_COS_CLASS3; 1600 memset(fc_host_supported_fc4s(lport->host), 0, 1601 sizeof(fc_host_supported_fc4s(lport->host))); 1602 fc_host_supported_fc4s(lport->host)[2] = 1; 1603 fc_host_supported_fc4s(lport->host)[7] = 1; 1604 1605 /* This value is also unchanging */ 1606 memset(fc_host_active_fc4s(lport->host), 0, 1607 sizeof(fc_host_active_fc4s(lport->host))); 1608 fc_host_active_fc4s(lport->host)[2] = 1; 1609 fc_host_active_fc4s(lport->host)[7] = 1; 1610 fc_host_maxframe_size(lport->host) = lport->mfs; 1611 fc_host_supported_speeds(lport->host) = 0; 1612 if (lport->link_supported_speeds & FC_PORTSPEED_1GBIT) 1613 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_1GBIT; 1614 if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT) 1615 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT; 1616 1617 INIT_LIST_HEAD(&lport->ema_list); 1618 return 0; 1619 } 1620 EXPORT_SYMBOL(fc_lport_init); 1621