1 /* 2 * Copyright(c) 2007 - 2008 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 * RPORT GENERAL INFO 22 * 23 * This file contains all processing regarding fc_rports. It contains the 24 * rport state machine and does all rport interaction with the transport class. 25 * There should be no other places in libfc that interact directly with the 26 * transport class in regards to adding and deleting rports. 27 * 28 * fc_rport's represent N_Port's within the fabric. 29 */ 30 31 /* 32 * RPORT LOCKING 33 * 34 * The rport should never hold the rport mutex and then attempt to acquire 35 * either the lport or disc mutexes. The rport's mutex is considered lesser 36 * than both the lport's mutex and the disc mutex. Refer to fc_lport.c for 37 * more comments on the heirarchy. 38 * 39 * The locking strategy is similar to the lport's strategy. The lock protects 40 * the rport's states and is held and released by the entry points to the rport 41 * block. All _enter_* functions correspond to rport states and expect the rport 42 * mutex to be locked before calling them. This means that rports only handle 43 * one request or response at a time, since they're not critical for the I/O 44 * path this potential over-use of the mutex is acceptable. 45 */ 46 47 #include <linux/kernel.h> 48 #include <linux/spinlock.h> 49 #include <linux/interrupt.h> 50 #include <linux/rcupdate.h> 51 #include <linux/timer.h> 52 #include <linux/workqueue.h> 53 #include <asm/unaligned.h> 54 55 #include <scsi/libfc.h> 56 #include <scsi/fc_encode.h> 57 58 static int fc_rport_debug; 59 60 #define FC_DEBUG_RPORT(fmt...) \ 61 do { \ 62 if (fc_rport_debug) \ 63 FC_DBG(fmt); \ 64 } while (0) 65 66 struct workqueue_struct *rport_event_queue; 67 68 static void fc_rport_enter_plogi(struct fc_rport *); 69 static void fc_rport_enter_prli(struct fc_rport *); 70 static void fc_rport_enter_rtv(struct fc_rport *); 71 static void fc_rport_enter_ready(struct fc_rport *); 72 static void fc_rport_enter_logo(struct fc_rport *); 73 74 static void fc_rport_recv_plogi_req(struct fc_rport *, 75 struct fc_seq *, struct fc_frame *); 76 static void fc_rport_recv_prli_req(struct fc_rport *, 77 struct fc_seq *, struct fc_frame *); 78 static void fc_rport_recv_prlo_req(struct fc_rport *, 79 struct fc_seq *, struct fc_frame *); 80 static void fc_rport_recv_logo_req(struct fc_rport *, 81 struct fc_seq *, struct fc_frame *); 82 static void fc_rport_timeout(struct work_struct *); 83 static void fc_rport_error(struct fc_rport *, struct fc_frame *); 84 static void fc_rport_error_retry(struct fc_rport *, struct fc_frame *); 85 static void fc_rport_work(struct work_struct *); 86 87 static const char *fc_rport_state_names[] = { 88 [RPORT_ST_NONE] = "None", 89 [RPORT_ST_INIT] = "Init", 90 [RPORT_ST_PLOGI] = "PLOGI", 91 [RPORT_ST_PRLI] = "PRLI", 92 [RPORT_ST_RTV] = "RTV", 93 [RPORT_ST_READY] = "Ready", 94 [RPORT_ST_LOGO] = "LOGO", 95 }; 96 97 static void fc_rport_rogue_destroy(struct device *dev) 98 { 99 struct fc_rport *rport = dev_to_rport(dev); 100 FC_DEBUG_RPORT("Destroying rogue rport (%6x)\n", rport->port_id); 101 kfree(rport); 102 } 103 104 struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *dp) 105 { 106 struct fc_rport *rport; 107 struct fc_rport_libfc_priv *rdata; 108 rport = kzalloc(sizeof(*rport) + sizeof(*rdata), GFP_KERNEL); 109 110 if (!rport) 111 return NULL; 112 113 rdata = RPORT_TO_PRIV(rport); 114 115 rport->dd_data = rdata; 116 rport->port_id = dp->ids.port_id; 117 rport->port_name = dp->ids.port_name; 118 rport->node_name = dp->ids.node_name; 119 rport->roles = dp->ids.roles; 120 rport->maxframe_size = FC_MIN_MAX_PAYLOAD; 121 /* 122 * Note: all this libfc rogue rport code will be removed for 123 * upstream so it fine that this is really ugly and hacky right now. 124 */ 125 device_initialize(&rport->dev); 126 rport->dev.release = fc_rport_rogue_destroy; 127 128 mutex_init(&rdata->rp_mutex); 129 rdata->local_port = dp->lp; 130 rdata->trans_state = FC_PORTSTATE_ROGUE; 131 rdata->rp_state = RPORT_ST_INIT; 132 rdata->event = RPORT_EV_NONE; 133 rdata->flags = FC_RP_FLAGS_REC_SUPPORTED; 134 rdata->ops = NULL; 135 rdata->e_d_tov = dp->lp->e_d_tov; 136 rdata->r_a_tov = dp->lp->r_a_tov; 137 INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout); 138 INIT_WORK(&rdata->event_work, fc_rport_work); 139 /* 140 * For good measure, but not necessary as we should only 141 * add REAL rport to the lport list. 142 */ 143 INIT_LIST_HEAD(&rdata->peers); 144 145 return rport; 146 } 147 148 /** 149 * fc_rport_state() - return a string for the state the rport is in 150 * @rport: The rport whose state we want to get a string for 151 */ 152 static const char *fc_rport_state(struct fc_rport *rport) 153 { 154 const char *cp; 155 struct fc_rport_libfc_priv *rdata = rport->dd_data; 156 157 cp = fc_rport_state_names[rdata->rp_state]; 158 if (!cp) 159 cp = "Unknown"; 160 return cp; 161 } 162 163 /** 164 * fc_set_rport_loss_tmo() - Set the remote port loss timeout in seconds. 165 * @rport: Pointer to Fibre Channel remote port structure 166 * @timeout: timeout in seconds 167 */ 168 void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) 169 { 170 if (timeout) 171 rport->dev_loss_tmo = timeout + 5; 172 else 173 rport->dev_loss_tmo = 30; 174 } 175 EXPORT_SYMBOL(fc_set_rport_loss_tmo); 176 177 /** 178 * fc_plogi_get_maxframe() - Get max payload from the common service parameters 179 * @flp: FLOGI payload structure 180 * @maxval: upper limit, may be less than what is in the service parameters 181 */ 182 static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp, 183 unsigned int maxval) 184 { 185 unsigned int mfs; 186 187 /* 188 * Get max payload from the common service parameters and the 189 * class 3 receive data field size. 190 */ 191 mfs = ntohs(flp->fl_csp.sp_bb_data) & FC_SP_BB_DATA_MASK; 192 if (mfs >= FC_SP_MIN_MAX_PAYLOAD && mfs < maxval) 193 maxval = mfs; 194 mfs = ntohs(flp->fl_cssp[3 - 1].cp_rdfs); 195 if (mfs >= FC_SP_MIN_MAX_PAYLOAD && mfs < maxval) 196 maxval = mfs; 197 return maxval; 198 } 199 200 /** 201 * fc_rport_state_enter() - Change the rport's state 202 * @rport: The rport whose state should change 203 * @new: The new state of the rport 204 * 205 * Locking Note: Called with the rport lock held 206 */ 207 static void fc_rport_state_enter(struct fc_rport *rport, 208 enum fc_rport_state new) 209 { 210 struct fc_rport_libfc_priv *rdata = rport->dd_data; 211 if (rdata->rp_state != new) 212 rdata->retries = 0; 213 rdata->rp_state = new; 214 } 215 216 static void fc_rport_work(struct work_struct *work) 217 { 218 u32 port_id; 219 struct fc_rport_libfc_priv *rdata = 220 container_of(work, struct fc_rport_libfc_priv, event_work); 221 enum fc_rport_event event; 222 enum fc_rport_trans_state trans_state; 223 struct fc_lport *lport = rdata->local_port; 224 struct fc_rport_operations *rport_ops; 225 struct fc_rport *rport = PRIV_TO_RPORT(rdata); 226 227 mutex_lock(&rdata->rp_mutex); 228 event = rdata->event; 229 rport_ops = rdata->ops; 230 231 if (event == RPORT_EV_CREATED) { 232 struct fc_rport *new_rport; 233 struct fc_rport_libfc_priv *new_rdata; 234 struct fc_rport_identifiers ids; 235 236 ids.port_id = rport->port_id; 237 ids.roles = rport->roles; 238 ids.port_name = rport->port_name; 239 ids.node_name = rport->node_name; 240 241 mutex_unlock(&rdata->rp_mutex); 242 243 new_rport = fc_remote_port_add(lport->host, 0, &ids); 244 if (new_rport) { 245 /* 246 * Switch from the rogue rport to the rport 247 * returned by the FC class. 248 */ 249 new_rport->maxframe_size = rport->maxframe_size; 250 251 new_rdata = new_rport->dd_data; 252 new_rdata->e_d_tov = rdata->e_d_tov; 253 new_rdata->r_a_tov = rdata->r_a_tov; 254 new_rdata->ops = rdata->ops; 255 new_rdata->local_port = rdata->local_port; 256 new_rdata->flags = FC_RP_FLAGS_REC_SUPPORTED; 257 new_rdata->trans_state = FC_PORTSTATE_REAL; 258 mutex_init(&new_rdata->rp_mutex); 259 INIT_DELAYED_WORK(&new_rdata->retry_work, 260 fc_rport_timeout); 261 INIT_LIST_HEAD(&new_rdata->peers); 262 INIT_WORK(&new_rdata->event_work, fc_rport_work); 263 264 fc_rport_state_enter(new_rport, RPORT_ST_READY); 265 } else { 266 FC_DBG("Failed to create the rport for port " 267 "(%6x).\n", ids.port_id); 268 event = RPORT_EV_FAILED; 269 } 270 put_device(&rport->dev); 271 rport = new_rport; 272 rdata = new_rport->dd_data; 273 if (rport_ops->event_callback) 274 rport_ops->event_callback(lport, rport, event); 275 } else if ((event == RPORT_EV_FAILED) || 276 (event == RPORT_EV_LOGO) || 277 (event == RPORT_EV_STOP)) { 278 trans_state = rdata->trans_state; 279 mutex_unlock(&rdata->rp_mutex); 280 if (rport_ops->event_callback) 281 rport_ops->event_callback(lport, rport, event); 282 if (trans_state == FC_PORTSTATE_ROGUE) 283 put_device(&rport->dev); 284 else { 285 port_id = rport->port_id; 286 fc_remote_port_delete(rport); 287 lport->tt.exch_mgr_reset(lport, 0, port_id); 288 lport->tt.exch_mgr_reset(lport, port_id, 0); 289 } 290 } else 291 mutex_unlock(&rdata->rp_mutex); 292 } 293 294 /** 295 * fc_rport_login() - Start the remote port login state machine 296 * @rport: Fibre Channel remote port 297 * 298 * Locking Note: Called without the rport lock held. This 299 * function will hold the rport lock, call an _enter_* 300 * function and then unlock the rport. 301 */ 302 int fc_rport_login(struct fc_rport *rport) 303 { 304 struct fc_rport_libfc_priv *rdata = rport->dd_data; 305 306 mutex_lock(&rdata->rp_mutex); 307 308 FC_DEBUG_RPORT("Login to port (%6x)\n", rport->port_id); 309 310 fc_rport_enter_plogi(rport); 311 312 mutex_unlock(&rdata->rp_mutex); 313 314 return 0; 315 } 316 317 /** 318 * fc_rport_logoff() - Logoff and remove an rport 319 * @rport: Fibre Channel remote port to be removed 320 * 321 * Locking Note: Called without the rport lock held. This 322 * function will hold the rport lock, call an _enter_* 323 * function and then unlock the rport. 324 */ 325 int fc_rport_logoff(struct fc_rport *rport) 326 { 327 struct fc_rport_libfc_priv *rdata = rport->dd_data; 328 329 mutex_lock(&rdata->rp_mutex); 330 331 FC_DEBUG_RPORT("Remove port (%6x)\n", rport->port_id); 332 333 fc_rport_enter_logo(rport); 334 335 /* 336 * Change the state to NONE so that we discard 337 * the response. 338 */ 339 fc_rport_state_enter(rport, RPORT_ST_NONE); 340 341 mutex_unlock(&rdata->rp_mutex); 342 343 cancel_delayed_work_sync(&rdata->retry_work); 344 345 mutex_lock(&rdata->rp_mutex); 346 347 rdata->event = RPORT_EV_STOP; 348 queue_work(rport_event_queue, &rdata->event_work); 349 350 mutex_unlock(&rdata->rp_mutex); 351 352 return 0; 353 } 354 355 /** 356 * fc_rport_enter_ready() - The rport is ready 357 * @rport: Fibre Channel remote port that is ready 358 * 359 * Locking Note: The rport lock is expected to be held before calling 360 * this routine. 361 */ 362 static void fc_rport_enter_ready(struct fc_rport *rport) 363 { 364 struct fc_rport_libfc_priv *rdata = rport->dd_data; 365 366 fc_rport_state_enter(rport, RPORT_ST_READY); 367 368 FC_DEBUG_RPORT("Port (%6x) is Ready\n", rport->port_id); 369 370 rdata->event = RPORT_EV_CREATED; 371 queue_work(rport_event_queue, &rdata->event_work); 372 } 373 374 /** 375 * fc_rport_timeout() - Handler for the retry_work timer. 376 * @work: The work struct of the fc_rport_libfc_priv 377 * 378 * Locking Note: Called without the rport lock held. This 379 * function will hold the rport lock, call an _enter_* 380 * function and then unlock the rport. 381 */ 382 static void fc_rport_timeout(struct work_struct *work) 383 { 384 struct fc_rport_libfc_priv *rdata = 385 container_of(work, struct fc_rport_libfc_priv, retry_work.work); 386 struct fc_rport *rport = PRIV_TO_RPORT(rdata); 387 388 mutex_lock(&rdata->rp_mutex); 389 390 switch (rdata->rp_state) { 391 case RPORT_ST_PLOGI: 392 fc_rport_enter_plogi(rport); 393 break; 394 case RPORT_ST_PRLI: 395 fc_rport_enter_prli(rport); 396 break; 397 case RPORT_ST_RTV: 398 fc_rport_enter_rtv(rport); 399 break; 400 case RPORT_ST_LOGO: 401 fc_rport_enter_logo(rport); 402 break; 403 case RPORT_ST_READY: 404 case RPORT_ST_INIT: 405 case RPORT_ST_NONE: 406 break; 407 } 408 409 mutex_unlock(&rdata->rp_mutex); 410 put_device(&rport->dev); 411 } 412 413 /** 414 * fc_rport_error() - Error handler, called once retries have been exhausted 415 * @rport: The fc_rport object 416 * @fp: The frame pointer 417 * 418 * Locking Note: The rport lock is expected to be held before 419 * calling this routine 420 */ 421 static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp) 422 { 423 struct fc_rport_libfc_priv *rdata = rport->dd_data; 424 425 FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n", 426 PTR_ERR(fp), fc_rport_state(rport), rdata->retries); 427 428 switch (rdata->rp_state) { 429 case RPORT_ST_PLOGI: 430 case RPORT_ST_PRLI: 431 case RPORT_ST_LOGO: 432 rdata->event = RPORT_EV_FAILED; 433 queue_work(rport_event_queue, 434 &rdata->event_work); 435 break; 436 case RPORT_ST_RTV: 437 fc_rport_enter_ready(rport); 438 break; 439 case RPORT_ST_NONE: 440 case RPORT_ST_READY: 441 case RPORT_ST_INIT: 442 break; 443 } 444 } 445 446 /** 447 * fc_rport_error_retry() - Error handler when retries are desired 448 * @rport: The fc_rport object 449 * @fp: The frame pointer 450 * 451 * If the error was an exchange timeout retry immediately, 452 * otherwise wait for E_D_TOV. 453 * 454 * Locking Note: The rport lock is expected to be held before 455 * calling this routine 456 */ 457 static void fc_rport_error_retry(struct fc_rport *rport, struct fc_frame *fp) 458 { 459 struct fc_rport_libfc_priv *rdata = rport->dd_data; 460 unsigned long delay = FC_DEF_E_D_TOV; 461 462 /* make sure this isn't an FC_EX_CLOSED error, never retry those */ 463 if (PTR_ERR(fp) == -FC_EX_CLOSED) 464 return fc_rport_error(rport, fp); 465 466 if (rdata->retries < rdata->local_port->max_retry_count) { 467 FC_DEBUG_RPORT("Error %ld in state %s, retrying\n", 468 PTR_ERR(fp), fc_rport_state(rport)); 469 rdata->retries++; 470 /* no additional delay on exchange timeouts */ 471 if (PTR_ERR(fp) == -FC_EX_TIMEOUT) 472 delay = 0; 473 get_device(&rport->dev); 474 schedule_delayed_work(&rdata->retry_work, delay); 475 return; 476 } 477 478 return fc_rport_error(rport, fp); 479 } 480 481 /** 482 * fc_rport_plogi_recv_resp() - Handle incoming ELS PLOGI response 483 * @sp: current sequence in the PLOGI exchange 484 * @fp: response frame 485 * @rp_arg: Fibre Channel remote port 486 * 487 * Locking Note: This function will be called without the rport lock 488 * held, but it will lock, call an _enter_* function or fc_rport_error 489 * and then unlock the rport. 490 */ 491 static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, 492 void *rp_arg) 493 { 494 struct fc_rport *rport = rp_arg; 495 struct fc_rport_libfc_priv *rdata = rport->dd_data; 496 struct fc_lport *lport = rdata->local_port; 497 struct fc_els_flogi *plp; 498 unsigned int tov; 499 u16 csp_seq; 500 u16 cssp_seq; 501 u8 op; 502 503 mutex_lock(&rdata->rp_mutex); 504 505 FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n", 506 rport->port_id); 507 508 if (IS_ERR(fp)) { 509 fc_rport_error_retry(rport, fp); 510 goto err; 511 } 512 513 if (rdata->rp_state != RPORT_ST_PLOGI) { 514 FC_DBG("Received a PLOGI response, but in state %s\n", 515 fc_rport_state(rport)); 516 goto out; 517 } 518 519 op = fc_frame_payload_op(fp); 520 if (op == ELS_LS_ACC && 521 (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) { 522 rport->port_name = get_unaligned_be64(&plp->fl_wwpn); 523 rport->node_name = get_unaligned_be64(&plp->fl_wwnn); 524 525 tov = ntohl(plp->fl_csp.sp_e_d_tov); 526 if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR) 527 tov /= 1000; 528 if (tov > rdata->e_d_tov) 529 rdata->e_d_tov = tov; 530 csp_seq = ntohs(plp->fl_csp.sp_tot_seq); 531 cssp_seq = ntohs(plp->fl_cssp[3 - 1].cp_con_seq); 532 if (cssp_seq < csp_seq) 533 csp_seq = cssp_seq; 534 rdata->max_seq = csp_seq; 535 rport->maxframe_size = 536 fc_plogi_get_maxframe(plp, lport->mfs); 537 538 /* 539 * If the rport is one of the well known addresses 540 * we skip PRLI and RTV and go straight to READY. 541 */ 542 if (rport->port_id >= FC_FID_DOM_MGR) 543 fc_rport_enter_ready(rport); 544 else 545 fc_rport_enter_prli(rport); 546 } else 547 fc_rport_error_retry(rport, fp); 548 549 out: 550 fc_frame_free(fp); 551 err: 552 mutex_unlock(&rdata->rp_mutex); 553 put_device(&rport->dev); 554 } 555 556 /** 557 * fc_rport_enter_plogi() - Send Port Login (PLOGI) request to peer 558 * @rport: Fibre Channel remote port to send PLOGI to 559 * 560 * Locking Note: The rport lock is expected to be held before calling 561 * this routine. 562 */ 563 static void fc_rport_enter_plogi(struct fc_rport *rport) 564 { 565 struct fc_rport_libfc_priv *rdata = rport->dd_data; 566 struct fc_lport *lport = rdata->local_port; 567 struct fc_frame *fp; 568 569 FC_DEBUG_RPORT("Port (%6x) entered PLOGI state from %s state\n", 570 rport->port_id, fc_rport_state(rport)); 571 572 fc_rport_state_enter(rport, RPORT_ST_PLOGI); 573 574 rport->maxframe_size = FC_MIN_MAX_PAYLOAD; 575 fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi)); 576 if (!fp) { 577 fc_rport_error_retry(rport, fp); 578 return; 579 } 580 rdata->e_d_tov = lport->e_d_tov; 581 582 if (!lport->tt.elsct_send(lport, rport, fp, ELS_PLOGI, 583 fc_rport_plogi_resp, rport, lport->e_d_tov)) 584 fc_rport_error_retry(rport, fp); 585 else 586 get_device(&rport->dev); 587 } 588 589 /** 590 * fc_rport_prli_resp() - Process Login (PRLI) response handler 591 * @sp: current sequence in the PRLI exchange 592 * @fp: response frame 593 * @rp_arg: Fibre Channel remote port 594 * 595 * Locking Note: This function will be called without the rport lock 596 * held, but it will lock, call an _enter_* function or fc_rport_error 597 * and then unlock the rport. 598 */ 599 static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, 600 void *rp_arg) 601 { 602 struct fc_rport *rport = rp_arg; 603 struct fc_rport_libfc_priv *rdata = rport->dd_data; 604 struct { 605 struct fc_els_prli prli; 606 struct fc_els_spp spp; 607 } *pp; 608 u32 roles = FC_RPORT_ROLE_UNKNOWN; 609 u32 fcp_parm = 0; 610 u8 op; 611 612 mutex_lock(&rdata->rp_mutex); 613 614 FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n", 615 rport->port_id); 616 617 if (IS_ERR(fp)) { 618 fc_rport_error_retry(rport, fp); 619 goto err; 620 } 621 622 if (rdata->rp_state != RPORT_ST_PRLI) { 623 FC_DBG("Received a PRLI response, but in state %s\n", 624 fc_rport_state(rport)); 625 goto out; 626 } 627 628 op = fc_frame_payload_op(fp); 629 if (op == ELS_LS_ACC) { 630 pp = fc_frame_payload_get(fp, sizeof(*pp)); 631 if (pp && pp->prli.prli_spp_len >= sizeof(pp->spp)) { 632 fcp_parm = ntohl(pp->spp.spp_params); 633 if (fcp_parm & FCP_SPPF_RETRY) 634 rdata->flags |= FC_RP_FLAGS_RETRY; 635 } 636 637 rport->supported_classes = FC_COS_CLASS3; 638 if (fcp_parm & FCP_SPPF_INIT_FCN) 639 roles |= FC_RPORT_ROLE_FCP_INITIATOR; 640 if (fcp_parm & FCP_SPPF_TARG_FCN) 641 roles |= FC_RPORT_ROLE_FCP_TARGET; 642 643 rport->roles = roles; 644 fc_rport_enter_rtv(rport); 645 646 } else { 647 FC_DBG("Bad ELS response\n"); 648 rdata->event = RPORT_EV_FAILED; 649 queue_work(rport_event_queue, &rdata->event_work); 650 } 651 652 out: 653 fc_frame_free(fp); 654 err: 655 mutex_unlock(&rdata->rp_mutex); 656 put_device(&rport->dev); 657 } 658 659 /** 660 * fc_rport_logo_resp() - Logout (LOGO) response handler 661 * @sp: current sequence in the LOGO exchange 662 * @fp: response frame 663 * @rp_arg: Fibre Channel remote port 664 * 665 * Locking Note: This function will be called without the rport lock 666 * held, but it will lock, call an _enter_* function or fc_rport_error 667 * and then unlock the rport. 668 */ 669 static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, 670 void *rp_arg) 671 { 672 struct fc_rport *rport = rp_arg; 673 struct fc_rport_libfc_priv *rdata = rport->dd_data; 674 u8 op; 675 676 mutex_lock(&rdata->rp_mutex); 677 678 FC_DEBUG_RPORT("Received a LOGO response from port (%6x)\n", 679 rport->port_id); 680 681 if (IS_ERR(fp)) { 682 fc_rport_error_retry(rport, fp); 683 goto err; 684 } 685 686 if (rdata->rp_state != RPORT_ST_LOGO) { 687 FC_DEBUG_RPORT("Received a LOGO response, but in state %s\n", 688 fc_rport_state(rport)); 689 goto out; 690 } 691 692 op = fc_frame_payload_op(fp); 693 if (op == ELS_LS_ACC) { 694 fc_rport_enter_rtv(rport); 695 } else { 696 FC_DBG("Bad ELS response\n"); 697 rdata->event = RPORT_EV_LOGO; 698 queue_work(rport_event_queue, &rdata->event_work); 699 } 700 701 out: 702 fc_frame_free(fp); 703 err: 704 mutex_unlock(&rdata->rp_mutex); 705 put_device(&rport->dev); 706 } 707 708 /** 709 * fc_rport_enter_prli() - Send Process Login (PRLI) request to peer 710 * @rport: Fibre Channel remote port to send PRLI to 711 * 712 * Locking Note: The rport lock is expected to be held before calling 713 * this routine. 714 */ 715 static void fc_rport_enter_prli(struct fc_rport *rport) 716 { 717 struct fc_rport_libfc_priv *rdata = rport->dd_data; 718 struct fc_lport *lport = rdata->local_port; 719 struct { 720 struct fc_els_prli prli; 721 struct fc_els_spp spp; 722 } *pp; 723 struct fc_frame *fp; 724 725 FC_DEBUG_RPORT("Port (%6x) entered PRLI state from %s state\n", 726 rport->port_id, fc_rport_state(rport)); 727 728 fc_rport_state_enter(rport, RPORT_ST_PRLI); 729 730 fp = fc_frame_alloc(lport, sizeof(*pp)); 731 if (!fp) { 732 fc_rport_error_retry(rport, fp); 733 return; 734 } 735 736 if (!lport->tt.elsct_send(lport, rport, fp, ELS_PRLI, 737 fc_rport_prli_resp, rport, lport->e_d_tov)) 738 fc_rport_error_retry(rport, fp); 739 else 740 get_device(&rport->dev); 741 } 742 743 /** 744 * fc_rport_els_rtv_resp() - Request Timeout Value response handler 745 * @sp: current sequence in the RTV exchange 746 * @fp: response frame 747 * @rp_arg: Fibre Channel remote port 748 * 749 * Many targets don't seem to support this. 750 * 751 * Locking Note: This function will be called without the rport lock 752 * held, but it will lock, call an _enter_* function or fc_rport_error 753 * and then unlock the rport. 754 */ 755 static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp, 756 void *rp_arg) 757 { 758 struct fc_rport *rport = rp_arg; 759 struct fc_rport_libfc_priv *rdata = rport->dd_data; 760 u8 op; 761 762 mutex_lock(&rdata->rp_mutex); 763 764 FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n", 765 rport->port_id); 766 767 if (IS_ERR(fp)) { 768 fc_rport_error(rport, fp); 769 goto err; 770 } 771 772 if (rdata->rp_state != RPORT_ST_RTV) { 773 FC_DBG("Received a RTV response, but in state %s\n", 774 fc_rport_state(rport)); 775 goto out; 776 } 777 778 op = fc_frame_payload_op(fp); 779 if (op == ELS_LS_ACC) { 780 struct fc_els_rtv_acc *rtv; 781 u32 toq; 782 u32 tov; 783 784 rtv = fc_frame_payload_get(fp, sizeof(*rtv)); 785 if (rtv) { 786 toq = ntohl(rtv->rtv_toq); 787 tov = ntohl(rtv->rtv_r_a_tov); 788 if (tov == 0) 789 tov = 1; 790 rdata->r_a_tov = tov; 791 tov = ntohl(rtv->rtv_e_d_tov); 792 if (toq & FC_ELS_RTV_EDRES) 793 tov /= 1000000; 794 if (tov == 0) 795 tov = 1; 796 rdata->e_d_tov = tov; 797 } 798 } 799 800 fc_rport_enter_ready(rport); 801 802 out: 803 fc_frame_free(fp); 804 err: 805 mutex_unlock(&rdata->rp_mutex); 806 put_device(&rport->dev); 807 } 808 809 /** 810 * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request to peer 811 * @rport: Fibre Channel remote port to send RTV to 812 * 813 * Locking Note: The rport lock is expected to be held before calling 814 * this routine. 815 */ 816 static void fc_rport_enter_rtv(struct fc_rport *rport) 817 { 818 struct fc_frame *fp; 819 struct fc_rport_libfc_priv *rdata = rport->dd_data; 820 struct fc_lport *lport = rdata->local_port; 821 822 FC_DEBUG_RPORT("Port (%6x) entered RTV state from %s state\n", 823 rport->port_id, fc_rport_state(rport)); 824 825 fc_rport_state_enter(rport, RPORT_ST_RTV); 826 827 fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv)); 828 if (!fp) { 829 fc_rport_error_retry(rport, fp); 830 return; 831 } 832 833 if (!lport->tt.elsct_send(lport, rport, fp, ELS_RTV, 834 fc_rport_rtv_resp, rport, lport->e_d_tov)) 835 fc_rport_error_retry(rport, fp); 836 else 837 get_device(&rport->dev); 838 } 839 840 /** 841 * fc_rport_enter_logo() - Send Logout (LOGO) request to peer 842 * @rport: Fibre Channel remote port to send LOGO to 843 * 844 * Locking Note: The rport lock is expected to be held before calling 845 * this routine. 846 */ 847 static void fc_rport_enter_logo(struct fc_rport *rport) 848 { 849 struct fc_rport_libfc_priv *rdata = rport->dd_data; 850 struct fc_lport *lport = rdata->local_port; 851 struct fc_frame *fp; 852 853 FC_DEBUG_RPORT("Port (%6x) entered LOGO state from %s state\n", 854 rport->port_id, fc_rport_state(rport)); 855 856 fc_rport_state_enter(rport, RPORT_ST_LOGO); 857 858 fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo)); 859 if (!fp) { 860 fc_rport_error_retry(rport, fp); 861 return; 862 } 863 864 if (!lport->tt.elsct_send(lport, rport, fp, ELS_LOGO, 865 fc_rport_logo_resp, rport, lport->e_d_tov)) 866 fc_rport_error_retry(rport, fp); 867 else 868 get_device(&rport->dev); 869 } 870 871 872 /** 873 * fc_rport_recv_req() - Receive a request from a rport 874 * @sp: current sequence in the PLOGI exchange 875 * @fp: response frame 876 * @rp_arg: Fibre Channel remote port 877 * 878 * Locking Note: Called without the rport lock held. This 879 * function will hold the rport lock, call an _enter_* 880 * function and then unlock the rport. 881 */ 882 void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp, 883 struct fc_rport *rport) 884 { 885 struct fc_rport_libfc_priv *rdata = rport->dd_data; 886 struct fc_lport *lport = rdata->local_port; 887 888 struct fc_frame_header *fh; 889 struct fc_seq_els_data els_data; 890 u8 op; 891 892 mutex_lock(&rdata->rp_mutex); 893 894 els_data.fp = NULL; 895 els_data.explan = ELS_EXPL_NONE; 896 els_data.reason = ELS_RJT_NONE; 897 898 fh = fc_frame_header_get(fp); 899 900 if (fh->fh_r_ctl == FC_RCTL_ELS_REQ && fh->fh_type == FC_TYPE_ELS) { 901 op = fc_frame_payload_op(fp); 902 switch (op) { 903 case ELS_PLOGI: 904 fc_rport_recv_plogi_req(rport, sp, fp); 905 break; 906 case ELS_PRLI: 907 fc_rport_recv_prli_req(rport, sp, fp); 908 break; 909 case ELS_PRLO: 910 fc_rport_recv_prlo_req(rport, sp, fp); 911 break; 912 case ELS_LOGO: 913 fc_rport_recv_logo_req(rport, sp, fp); 914 break; 915 case ELS_RRQ: 916 els_data.fp = fp; 917 lport->tt.seq_els_rsp_send(sp, ELS_RRQ, &els_data); 918 break; 919 case ELS_REC: 920 els_data.fp = fp; 921 lport->tt.seq_els_rsp_send(sp, ELS_REC, &els_data); 922 break; 923 default: 924 els_data.reason = ELS_RJT_UNSUP; 925 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &els_data); 926 break; 927 } 928 } 929 930 mutex_unlock(&rdata->rp_mutex); 931 } 932 933 /** 934 * fc_rport_recv_plogi_req() - Handle incoming Port Login (PLOGI) request 935 * @rport: Fibre Channel remote port that initiated PLOGI 936 * @sp: current sequence in the PLOGI exchange 937 * @fp: PLOGI request frame 938 * 939 * Locking Note: The rport lock is exected to be held before calling 940 * this function. 941 */ 942 static void fc_rport_recv_plogi_req(struct fc_rport *rport, 943 struct fc_seq *sp, struct fc_frame *rx_fp) 944 { 945 struct fc_rport_libfc_priv *rdata = rport->dd_data; 946 struct fc_lport *lport = rdata->local_port; 947 struct fc_frame *fp = rx_fp; 948 struct fc_exch *ep; 949 struct fc_frame_header *fh; 950 struct fc_els_flogi *pl; 951 struct fc_seq_els_data rjt_data; 952 u32 sid; 953 u64 wwpn; 954 u64 wwnn; 955 enum fc_els_rjt_reason reject = 0; 956 u32 f_ctl; 957 rjt_data.fp = NULL; 958 959 fh = fc_frame_header_get(fp); 960 961 FC_DEBUG_RPORT("Received PLOGI request from port (%6x) " 962 "while in state %s\n", ntoh24(fh->fh_s_id), 963 fc_rport_state(rport)); 964 965 sid = ntoh24(fh->fh_s_id); 966 pl = fc_frame_payload_get(fp, sizeof(*pl)); 967 if (!pl) { 968 FC_DBG("incoming PLOGI from %x too short\n", sid); 969 WARN_ON(1); 970 /* XXX TBD: send reject? */ 971 fc_frame_free(fp); 972 return; 973 } 974 wwpn = get_unaligned_be64(&pl->fl_wwpn); 975 wwnn = get_unaligned_be64(&pl->fl_wwnn); 976 977 /* 978 * If the session was just created, possibly due to the incoming PLOGI, 979 * set the state appropriately and accept the PLOGI. 980 * 981 * If we had also sent a PLOGI, and if the received PLOGI is from a 982 * higher WWPN, we accept it, otherwise an LS_RJT is sent with reason 983 * "command already in progress". 984 * 985 * XXX TBD: If the session was ready before, the PLOGI should result in 986 * all outstanding exchanges being reset. 987 */ 988 switch (rdata->rp_state) { 989 case RPORT_ST_INIT: 990 FC_DEBUG_RPORT("incoming PLOGI from %6x wwpn %llx state INIT " 991 "- reject\n", sid, (unsigned long long)wwpn); 992 reject = ELS_RJT_UNSUP; 993 break; 994 case RPORT_ST_PLOGI: 995 FC_DEBUG_RPORT("incoming PLOGI from %x in PLOGI state %d\n", 996 sid, rdata->rp_state); 997 if (wwpn < lport->wwpn) 998 reject = ELS_RJT_INPROG; 999 break; 1000 case RPORT_ST_PRLI: 1001 case RPORT_ST_READY: 1002 FC_DEBUG_RPORT("incoming PLOGI from %x in logged-in state %d " 1003 "- ignored for now\n", sid, rdata->rp_state); 1004 /* XXX TBD - should reset */ 1005 break; 1006 case RPORT_ST_NONE: 1007 default: 1008 FC_DEBUG_RPORT("incoming PLOGI from %x in unexpected " 1009 "state %d\n", sid, rdata->rp_state); 1010 break; 1011 } 1012 1013 if (reject) { 1014 rjt_data.reason = reject; 1015 rjt_data.explan = ELS_EXPL_NONE; 1016 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 1017 fc_frame_free(fp); 1018 } else { 1019 fp = fc_frame_alloc(lport, sizeof(*pl)); 1020 if (fp == NULL) { 1021 fp = rx_fp; 1022 rjt_data.reason = ELS_RJT_UNAB; 1023 rjt_data.explan = ELS_EXPL_NONE; 1024 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 1025 fc_frame_free(fp); 1026 } else { 1027 sp = lport->tt.seq_start_next(sp); 1028 WARN_ON(!sp); 1029 fc_rport_set_name(rport, wwpn, wwnn); 1030 1031 /* 1032 * Get session payload size from incoming PLOGI. 1033 */ 1034 rport->maxframe_size = 1035 fc_plogi_get_maxframe(pl, lport->mfs); 1036 fc_frame_free(rx_fp); 1037 fc_plogi_fill(lport, fp, ELS_LS_ACC); 1038 1039 /* 1040 * Send LS_ACC. If this fails, 1041 * the originator should retry. 1042 */ 1043 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 1044 f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 1045 ep = fc_seq_exch(sp); 1046 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 1047 FC_TYPE_ELS, f_ctl, 0); 1048 lport->tt.seq_send(lport, sp, fp); 1049 if (rdata->rp_state == RPORT_ST_PLOGI) 1050 fc_rport_enter_prli(rport); 1051 } 1052 } 1053 } 1054 1055 /** 1056 * fc_rport_recv_prli_req() - Handle incoming Process Login (PRLI) request 1057 * @rport: Fibre Channel remote port that initiated PRLI 1058 * @sp: current sequence in the PRLI exchange 1059 * @fp: PRLI request frame 1060 * 1061 * Locking Note: The rport lock is exected to be held before calling 1062 * this function. 1063 */ 1064 static void fc_rport_recv_prli_req(struct fc_rport *rport, 1065 struct fc_seq *sp, struct fc_frame *rx_fp) 1066 { 1067 struct fc_rport_libfc_priv *rdata = rport->dd_data; 1068 struct fc_lport *lport = rdata->local_port; 1069 struct fc_exch *ep; 1070 struct fc_frame *fp; 1071 struct fc_frame_header *fh; 1072 struct { 1073 struct fc_els_prli prli; 1074 struct fc_els_spp spp; 1075 } *pp; 1076 struct fc_els_spp *rspp; /* request service param page */ 1077 struct fc_els_spp *spp; /* response spp */ 1078 unsigned int len; 1079 unsigned int plen; 1080 enum fc_els_rjt_reason reason = ELS_RJT_UNAB; 1081 enum fc_els_rjt_explan explan = ELS_EXPL_NONE; 1082 enum fc_els_spp_resp resp; 1083 struct fc_seq_els_data rjt_data; 1084 u32 f_ctl; 1085 u32 fcp_parm; 1086 u32 roles = FC_RPORT_ROLE_UNKNOWN; 1087 rjt_data.fp = NULL; 1088 1089 fh = fc_frame_header_get(rx_fp); 1090 1091 FC_DEBUG_RPORT("Received PRLI request from port (%6x) " 1092 "while in state %s\n", ntoh24(fh->fh_s_id), 1093 fc_rport_state(rport)); 1094 1095 switch (rdata->rp_state) { 1096 case RPORT_ST_PRLI: 1097 case RPORT_ST_READY: 1098 reason = ELS_RJT_NONE; 1099 break; 1100 default: 1101 break; 1102 } 1103 len = fr_len(rx_fp) - sizeof(*fh); 1104 pp = fc_frame_payload_get(rx_fp, sizeof(*pp)); 1105 if (pp == NULL) { 1106 reason = ELS_RJT_PROT; 1107 explan = ELS_EXPL_INV_LEN; 1108 } else { 1109 plen = ntohs(pp->prli.prli_len); 1110 if ((plen % 4) != 0 || plen > len) { 1111 reason = ELS_RJT_PROT; 1112 explan = ELS_EXPL_INV_LEN; 1113 } else if (plen < len) { 1114 len = plen; 1115 } 1116 plen = pp->prli.prli_spp_len; 1117 if ((plen % 4) != 0 || plen < sizeof(*spp) || 1118 plen > len || len < sizeof(*pp)) { 1119 reason = ELS_RJT_PROT; 1120 explan = ELS_EXPL_INV_LEN; 1121 } 1122 rspp = &pp->spp; 1123 } 1124 if (reason != ELS_RJT_NONE || 1125 (fp = fc_frame_alloc(lport, len)) == NULL) { 1126 rjt_data.reason = reason; 1127 rjt_data.explan = explan; 1128 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 1129 } else { 1130 sp = lport->tt.seq_start_next(sp); 1131 WARN_ON(!sp); 1132 pp = fc_frame_payload_get(fp, len); 1133 WARN_ON(!pp); 1134 memset(pp, 0, len); 1135 pp->prli.prli_cmd = ELS_LS_ACC; 1136 pp->prli.prli_spp_len = plen; 1137 pp->prli.prli_len = htons(len); 1138 len -= sizeof(struct fc_els_prli); 1139 1140 /* 1141 * Go through all the service parameter pages and build 1142 * response. If plen indicates longer SPP than standard, 1143 * use that. The entire response has been pre-cleared above. 1144 */ 1145 spp = &pp->spp; 1146 while (len >= plen) { 1147 spp->spp_type = rspp->spp_type; 1148 spp->spp_type_ext = rspp->spp_type_ext; 1149 spp->spp_flags = rspp->spp_flags & FC_SPP_EST_IMG_PAIR; 1150 resp = FC_SPP_RESP_ACK; 1151 if (rspp->spp_flags & FC_SPP_RPA_VAL) 1152 resp = FC_SPP_RESP_NO_PA; 1153 switch (rspp->spp_type) { 1154 case 0: /* common to all FC-4 types */ 1155 break; 1156 case FC_TYPE_FCP: 1157 fcp_parm = ntohl(rspp->spp_params); 1158 if (fcp_parm * FCP_SPPF_RETRY) 1159 rdata->flags |= FC_RP_FLAGS_RETRY; 1160 rport->supported_classes = FC_COS_CLASS3; 1161 if (fcp_parm & FCP_SPPF_INIT_FCN) 1162 roles |= FC_RPORT_ROLE_FCP_INITIATOR; 1163 if (fcp_parm & FCP_SPPF_TARG_FCN) 1164 roles |= FC_RPORT_ROLE_FCP_TARGET; 1165 rport->roles = roles; 1166 1167 spp->spp_params = 1168 htonl(lport->service_params); 1169 break; 1170 default: 1171 resp = FC_SPP_RESP_INVL; 1172 break; 1173 } 1174 spp->spp_flags |= resp; 1175 len -= plen; 1176 rspp = (struct fc_els_spp *)((char *)rspp + plen); 1177 spp = (struct fc_els_spp *)((char *)spp + plen); 1178 } 1179 1180 /* 1181 * Send LS_ACC. If this fails, the originator should retry. 1182 */ 1183 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ; 1184 f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT; 1185 ep = fc_seq_exch(sp); 1186 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, 1187 FC_TYPE_ELS, f_ctl, 0); 1188 lport->tt.seq_send(lport, sp, fp); 1189 1190 /* 1191 * Get lock and re-check state. 1192 */ 1193 switch (rdata->rp_state) { 1194 case RPORT_ST_PRLI: 1195 fc_rport_enter_ready(rport); 1196 break; 1197 case RPORT_ST_READY: 1198 break; 1199 default: 1200 break; 1201 } 1202 } 1203 fc_frame_free(rx_fp); 1204 } 1205 1206 /** 1207 * fc_rport_recv_prlo_req() - Handle incoming Process Logout (PRLO) request 1208 * @rport: Fibre Channel remote port that initiated PRLO 1209 * @sp: current sequence in the PRLO exchange 1210 * @fp: PRLO request frame 1211 * 1212 * Locking Note: The rport lock is exected to be held before calling 1213 * this function. 1214 */ 1215 static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp, 1216 struct fc_frame *fp) 1217 { 1218 struct fc_rport_libfc_priv *rdata = rport->dd_data; 1219 struct fc_lport *lport = rdata->local_port; 1220 1221 struct fc_frame_header *fh; 1222 struct fc_seq_els_data rjt_data; 1223 1224 fh = fc_frame_header_get(fp); 1225 1226 FC_DEBUG_RPORT("Received PRLO request from port (%6x) " 1227 "while in state %s\n", ntoh24(fh->fh_s_id), 1228 fc_rport_state(rport)); 1229 1230 rjt_data.fp = NULL; 1231 rjt_data.reason = ELS_RJT_UNAB; 1232 rjt_data.explan = ELS_EXPL_NONE; 1233 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data); 1234 fc_frame_free(fp); 1235 } 1236 1237 /** 1238 * fc_rport_recv_logo_req() - Handle incoming Logout (LOGO) request 1239 * @rport: Fibre Channel remote port that initiated LOGO 1240 * @sp: current sequence in the LOGO exchange 1241 * @fp: LOGO request frame 1242 * 1243 * Locking Note: The rport lock is exected to be held before calling 1244 * this function. 1245 */ 1246 static void fc_rport_recv_logo_req(struct fc_rport *rport, struct fc_seq *sp, 1247 struct fc_frame *fp) 1248 { 1249 struct fc_frame_header *fh; 1250 struct fc_rport_libfc_priv *rdata = rport->dd_data; 1251 struct fc_lport *lport = rdata->local_port; 1252 1253 fh = fc_frame_header_get(fp); 1254 1255 FC_DEBUG_RPORT("Received LOGO request from port (%6x) " 1256 "while in state %s\n", ntoh24(fh->fh_s_id), 1257 fc_rport_state(rport)); 1258 1259 rdata->event = RPORT_EV_LOGO; 1260 queue_work(rport_event_queue, &rdata->event_work); 1261 1262 lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); 1263 fc_frame_free(fp); 1264 } 1265 1266 static void fc_rport_flush_queue(void) 1267 { 1268 flush_workqueue(rport_event_queue); 1269 } 1270 1271 1272 int fc_rport_init(struct fc_lport *lport) 1273 { 1274 if (!lport->tt.rport_create) 1275 lport->tt.rport_create = fc_rport_rogue_create; 1276 1277 if (!lport->tt.rport_login) 1278 lport->tt.rport_login = fc_rport_login; 1279 1280 if (!lport->tt.rport_logoff) 1281 lport->tt.rport_logoff = fc_rport_logoff; 1282 1283 if (!lport->tt.rport_recv_req) 1284 lport->tt.rport_recv_req = fc_rport_recv_req; 1285 1286 if (!lport->tt.rport_flush_queue) 1287 lport->tt.rport_flush_queue = fc_rport_flush_queue; 1288 1289 return 0; 1290 } 1291 EXPORT_SYMBOL(fc_rport_init); 1292 1293 int fc_setup_rport() 1294 { 1295 rport_event_queue = create_singlethread_workqueue("fc_rport_eq"); 1296 if (!rport_event_queue) 1297 return -ENOMEM; 1298 return 0; 1299 } 1300 EXPORT_SYMBOL(fc_setup_rport); 1301 1302 void fc_destroy_rport() 1303 { 1304 destroy_workqueue(rport_event_queue); 1305 } 1306 EXPORT_SYMBOL(fc_destroy_rport); 1307 1308 void fc_rport_terminate_io(struct fc_rport *rport) 1309 { 1310 struct fc_rport_libfc_priv *rdata = rport->dd_data; 1311 struct fc_lport *lport = rdata->local_port; 1312 1313 lport->tt.exch_mgr_reset(lport, 0, rport->port_id); 1314 lport->tt.exch_mgr_reset(lport, rport->port_id, 0); 1315 } 1316 EXPORT_SYMBOL(fc_rport_terminate_io); 1317