diff options
Diffstat (limited to 'drivers/scsi/libfc/fc_rport.c')
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 197 |
1 files changed, 111 insertions, 86 deletions
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index e780d8caf70e..dae65133a833 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c | |||
@@ -81,6 +81,7 @@ static void fc_rport_recv_logo_req(struct fc_rport *, | |||
81 | struct fc_seq *, struct fc_frame *); | 81 | struct fc_seq *, struct fc_frame *); |
82 | static void fc_rport_timeout(struct work_struct *); | 82 | static void fc_rport_timeout(struct work_struct *); |
83 | static void fc_rport_error(struct fc_rport *, struct fc_frame *); | 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 *); | ||
84 | static void fc_rport_work(struct work_struct *); | 85 | static void fc_rport_work(struct work_struct *); |
85 | 86 | ||
86 | static const char *fc_rport_state_names[] = { | 87 | static const char *fc_rport_state_names[] = { |
@@ -145,7 +146,7 @@ struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *dp) | |||
145 | } | 146 | } |
146 | 147 | ||
147 | /** | 148 | /** |
148 | * fc_rport_state - return a string for the state the rport is in | 149 | * fc_rport_state() - return a string for the state the rport is in |
149 | * @rport: The rport whose state we want to get a string for | 150 | * @rport: The rport whose state we want to get a string for |
150 | */ | 151 | */ |
151 | static const char *fc_rport_state(struct fc_rport *rport) | 152 | static const char *fc_rport_state(struct fc_rport *rport) |
@@ -160,7 +161,7 @@ static const char *fc_rport_state(struct fc_rport *rport) | |||
160 | } | 161 | } |
161 | 162 | ||
162 | /** | 163 | /** |
163 | * fc_set_rport_loss_tmo - Set the remote port loss timeout in seconds. | 164 | * fc_set_rport_loss_tmo() - Set the remote port loss timeout in seconds. |
164 | * @rport: Pointer to Fibre Channel remote port structure | 165 | * @rport: Pointer to Fibre Channel remote port structure |
165 | * @timeout: timeout in seconds | 166 | * @timeout: timeout in seconds |
166 | */ | 167 | */ |
@@ -174,12 +175,12 @@ void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) | |||
174 | EXPORT_SYMBOL(fc_set_rport_loss_tmo); | 175 | EXPORT_SYMBOL(fc_set_rport_loss_tmo); |
175 | 176 | ||
176 | /** | 177 | /** |
177 | * fc_plogi_get_maxframe - Get max payload from the common service parameters | 178 | * fc_plogi_get_maxframe() - Get max payload from the common service parameters |
178 | * @flp: FLOGI payload structure | 179 | * @flp: FLOGI payload structure |
179 | * @maxval: upper limit, may be less than what is in the service parameters | 180 | * @maxval: upper limit, may be less than what is in the service parameters |
180 | */ | 181 | */ |
181 | static unsigned int | 182 | static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp, |
182 | fc_plogi_get_maxframe(struct fc_els_flogi *flp, unsigned int maxval) | 183 | unsigned int maxval) |
183 | { | 184 | { |
184 | unsigned int mfs; | 185 | unsigned int mfs; |
185 | 186 | ||
@@ -197,7 +198,7 @@ fc_plogi_get_maxframe(struct fc_els_flogi *flp, unsigned int maxval) | |||
197 | } | 198 | } |
198 | 199 | ||
199 | /** | 200 | /** |
200 | * fc_rport_state_enter - Change the rport's state | 201 | * fc_rport_state_enter() - Change the rport's state |
201 | * @rport: The rport whose state should change | 202 | * @rport: The rport whose state should change |
202 | * @new: The new state of the rport | 203 | * @new: The new state of the rport |
203 | * | 204 | * |
@@ -214,6 +215,7 @@ static void fc_rport_state_enter(struct fc_rport *rport, | |||
214 | 215 | ||
215 | static void fc_rport_work(struct work_struct *work) | 216 | static void fc_rport_work(struct work_struct *work) |
216 | { | 217 | { |
218 | u32 port_id; | ||
217 | struct fc_rport_libfc_priv *rdata = | 219 | struct fc_rport_libfc_priv *rdata = |
218 | container_of(work, struct fc_rport_libfc_priv, event_work); | 220 | container_of(work, struct fc_rport_libfc_priv, event_work); |
219 | enum fc_rport_event event; | 221 | enum fc_rport_event event; |
@@ -279,14 +281,18 @@ static void fc_rport_work(struct work_struct *work) | |||
279 | rport_ops->event_callback(lport, rport, event); | 281 | rport_ops->event_callback(lport, rport, event); |
280 | if (trans_state == FC_PORTSTATE_ROGUE) | 282 | if (trans_state == FC_PORTSTATE_ROGUE) |
281 | put_device(&rport->dev); | 283 | put_device(&rport->dev); |
282 | else | 284 | else { |
285 | port_id = rport->port_id; | ||
283 | fc_remote_port_delete(rport); | 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 | } | ||
284 | } else | 290 | } else |
285 | mutex_unlock(&rdata->rp_mutex); | 291 | mutex_unlock(&rdata->rp_mutex); |
286 | } | 292 | } |
287 | 293 | ||
288 | /** | 294 | /** |
289 | * fc_rport_login - Start the remote port login state machine | 295 | * fc_rport_login() - Start the remote port login state machine |
290 | * @rport: Fibre Channel remote port | 296 | * @rport: Fibre Channel remote port |
291 | * | 297 | * |
292 | * Locking Note: Called without the rport lock held. This | 298 | * Locking Note: Called without the rport lock held. This |
@@ -309,7 +315,7 @@ int fc_rport_login(struct fc_rport *rport) | |||
309 | } | 315 | } |
310 | 316 | ||
311 | /** | 317 | /** |
312 | * fc_rport_logoff - Logoff and remove an rport | 318 | * fc_rport_logoff() - Logoff and remove an rport |
313 | * @rport: Fibre Channel remote port to be removed | 319 | * @rport: Fibre Channel remote port to be removed |
314 | * | 320 | * |
315 | * Locking Note: Called without the rport lock held. This | 321 | * Locking Note: Called without the rport lock held. This |
@@ -347,7 +353,7 @@ int fc_rport_logoff(struct fc_rport *rport) | |||
347 | } | 353 | } |
348 | 354 | ||
349 | /** | 355 | /** |
350 | * fc_rport_enter_ready - The rport is ready | 356 | * fc_rport_enter_ready() - The rport is ready |
351 | * @rport: Fibre Channel remote port that is ready | 357 | * @rport: Fibre Channel remote port that is ready |
352 | * | 358 | * |
353 | * Locking Note: The rport lock is expected to be held before calling | 359 | * Locking Note: The rport lock is expected to be held before calling |
@@ -366,7 +372,7 @@ static void fc_rport_enter_ready(struct fc_rport *rport) | |||
366 | } | 372 | } |
367 | 373 | ||
368 | /** | 374 | /** |
369 | * fc_rport_timeout - Handler for the retry_work timer. | 375 | * fc_rport_timeout() - Handler for the retry_work timer. |
370 | * @work: The work struct of the fc_rport_libfc_priv | 376 | * @work: The work struct of the fc_rport_libfc_priv |
371 | * | 377 | * |
372 | * Locking Note: Called without the rport lock held. This | 378 | * Locking Note: Called without the rport lock held. This |
@@ -405,59 +411,75 @@ static void fc_rport_timeout(struct work_struct *work) | |||
405 | } | 411 | } |
406 | 412 | ||
407 | /** | 413 | /** |
408 | * fc_rport_error - Handler for any errors | 414 | * fc_rport_error() - Error handler, called once retries have been exhausted |
409 | * @rport: The fc_rport object | 415 | * @rport: The fc_rport object |
410 | * @fp: The frame pointer | 416 | * @fp: The frame pointer |
411 | * | 417 | * |
412 | * If the error was caused by a resource allocation failure | ||
413 | * then wait for half a second and retry, otherwise retry | ||
414 | * immediately. | ||
415 | * | ||
416 | * Locking Note: The rport lock is expected to be held before | 418 | * Locking Note: The rport lock is expected to be held before |
417 | * calling this routine | 419 | * calling this routine |
418 | */ | 420 | */ |
419 | static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp) | 421 | static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp) |
420 | { | 422 | { |
421 | struct fc_rport_libfc_priv *rdata = rport->dd_data; | 423 | struct fc_rport_libfc_priv *rdata = rport->dd_data; |
422 | unsigned long delay = 0; | ||
423 | 424 | ||
424 | FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n", | 425 | FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n", |
425 | PTR_ERR(fp), fc_rport_state(rport), rdata->retries); | 426 | PTR_ERR(fp), fc_rport_state(rport), rdata->retries); |
426 | 427 | ||
427 | if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) { | 428 | switch (rdata->rp_state) { |
428 | /* | 429 | case RPORT_ST_PLOGI: |
429 | * Memory allocation failure, or the exchange timed out. | 430 | case RPORT_ST_PRLI: |
430 | * Retry after delay | 431 | case RPORT_ST_LOGO: |
431 | */ | 432 | rdata->event = RPORT_EV_FAILED; |
432 | if (rdata->retries < rdata->local_port->max_retry_count) { | 433 | queue_work(rport_event_queue, |
433 | rdata->retries++; | 434 | &rdata->event_work); |
434 | if (!fp) | 435 | break; |
435 | delay = msecs_to_jiffies(500); | 436 | case RPORT_ST_RTV: |
436 | get_device(&rport->dev); | 437 | fc_rport_enter_ready(rport); |
437 | schedule_delayed_work(&rdata->retry_work, delay); | 438 | break; |
438 | } else { | 439 | case RPORT_ST_NONE: |
439 | switch (rdata->rp_state) { | 440 | case RPORT_ST_READY: |
440 | case RPORT_ST_PLOGI: | 441 | case RPORT_ST_INIT: |
441 | case RPORT_ST_PRLI: | 442 | break; |
442 | case RPORT_ST_LOGO: | ||
443 | rdata->event = RPORT_EV_FAILED; | ||
444 | queue_work(rport_event_queue, | ||
445 | &rdata->event_work); | ||
446 | break; | ||
447 | case RPORT_ST_RTV: | ||
448 | fc_rport_enter_ready(rport); | ||
449 | break; | ||
450 | case RPORT_ST_NONE: | ||
451 | case RPORT_ST_READY: | ||
452 | case RPORT_ST_INIT: | ||
453 | break; | ||
454 | } | ||
455 | } | ||
456 | } | 443 | } |
457 | } | 444 | } |
458 | 445 | ||
459 | /** | 446 | /** |
460 | * fc_rport_plogi_recv_resp - Handle incoming ELS PLOGI response | 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 | ||
461 | * @sp: current sequence in the PLOGI exchange | 483 | * @sp: current sequence in the PLOGI exchange |
462 | * @fp: response frame | 484 | * @fp: response frame |
463 | * @rp_arg: Fibre Channel remote port | 485 | * @rp_arg: Fibre Channel remote port |
@@ -483,17 +505,17 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
483 | FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n", | 505 | FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n", |
484 | rport->port_id); | 506 | rport->port_id); |
485 | 507 | ||
508 | if (IS_ERR(fp)) { | ||
509 | fc_rport_error_retry(rport, fp); | ||
510 | goto err; | ||
511 | } | ||
512 | |||
486 | if (rdata->rp_state != RPORT_ST_PLOGI) { | 513 | if (rdata->rp_state != RPORT_ST_PLOGI) { |
487 | FC_DBG("Received a PLOGI response, but in state %s\n", | 514 | FC_DBG("Received a PLOGI response, but in state %s\n", |
488 | fc_rport_state(rport)); | 515 | fc_rport_state(rport)); |
489 | goto out; | 516 | goto out; |
490 | } | 517 | } |
491 | 518 | ||
492 | if (IS_ERR(fp)) { | ||
493 | fc_rport_error(rport, fp); | ||
494 | goto err; | ||
495 | } | ||
496 | |||
497 | op = fc_frame_payload_op(fp); | 519 | op = fc_frame_payload_op(fp); |
498 | if (op == ELS_LS_ACC && | 520 | if (op == ELS_LS_ACC && |
499 | (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) { | 521 | (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) { |
@@ -522,7 +544,7 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
522 | else | 544 | else |
523 | fc_rport_enter_prli(rport); | 545 | fc_rport_enter_prli(rport); |
524 | } else | 546 | } else |
525 | fc_rport_error(rport, fp); | 547 | fc_rport_error_retry(rport, fp); |
526 | 548 | ||
527 | out: | 549 | out: |
528 | fc_frame_free(fp); | 550 | fc_frame_free(fp); |
@@ -532,7 +554,7 @@ err: | |||
532 | } | 554 | } |
533 | 555 | ||
534 | /** | 556 | /** |
535 | * fc_rport_enter_plogi - Send Port Login (PLOGI) request to peer | 557 | * fc_rport_enter_plogi() - Send Port Login (PLOGI) request to peer |
536 | * @rport: Fibre Channel remote port to send PLOGI to | 558 | * @rport: Fibre Channel remote port to send PLOGI to |
537 | * | 559 | * |
538 | * Locking Note: The rport lock is expected to be held before calling | 560 | * Locking Note: The rport lock is expected to be held before calling |
@@ -552,20 +574,20 @@ static void fc_rport_enter_plogi(struct fc_rport *rport) | |||
552 | rport->maxframe_size = FC_MIN_MAX_PAYLOAD; | 574 | rport->maxframe_size = FC_MIN_MAX_PAYLOAD; |
553 | fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi)); | 575 | fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi)); |
554 | if (!fp) { | 576 | if (!fp) { |
555 | fc_rport_error(rport, fp); | 577 | fc_rport_error_retry(rport, fp); |
556 | return; | 578 | return; |
557 | } | 579 | } |
558 | rdata->e_d_tov = lport->e_d_tov; | 580 | rdata->e_d_tov = lport->e_d_tov; |
559 | 581 | ||
560 | if (!lport->tt.elsct_send(lport, rport, fp, ELS_PLOGI, | 582 | if (!lport->tt.elsct_send(lport, rport, fp, ELS_PLOGI, |
561 | fc_rport_plogi_resp, rport, lport->e_d_tov)) | 583 | fc_rport_plogi_resp, rport, lport->e_d_tov)) |
562 | fc_rport_error(rport, fp); | 584 | fc_rport_error_retry(rport, fp); |
563 | else | 585 | else |
564 | get_device(&rport->dev); | 586 | get_device(&rport->dev); |
565 | } | 587 | } |
566 | 588 | ||
567 | /** | 589 | /** |
568 | * fc_rport_prli_resp - Process Login (PRLI) response handler | 590 | * fc_rport_prli_resp() - Process Login (PRLI) response handler |
569 | * @sp: current sequence in the PRLI exchange | 591 | * @sp: current sequence in the PRLI exchange |
570 | * @fp: response frame | 592 | * @fp: response frame |
571 | * @rp_arg: Fibre Channel remote port | 593 | * @rp_arg: Fibre Channel remote port |
@@ -592,17 +614,17 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
592 | FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n", | 614 | FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n", |
593 | rport->port_id); | 615 | rport->port_id); |
594 | 616 | ||
617 | if (IS_ERR(fp)) { | ||
618 | fc_rport_error_retry(rport, fp); | ||
619 | goto err; | ||
620 | } | ||
621 | |||
595 | if (rdata->rp_state != RPORT_ST_PRLI) { | 622 | if (rdata->rp_state != RPORT_ST_PRLI) { |
596 | FC_DBG("Received a PRLI response, but in state %s\n", | 623 | FC_DBG("Received a PRLI response, but in state %s\n", |
597 | fc_rport_state(rport)); | 624 | fc_rport_state(rport)); |
598 | goto out; | 625 | goto out; |
599 | } | 626 | } |
600 | 627 | ||
601 | if (IS_ERR(fp)) { | ||
602 | fc_rport_error(rport, fp); | ||
603 | goto err; | ||
604 | } | ||
605 | |||
606 | op = fc_frame_payload_op(fp); | 628 | op = fc_frame_payload_op(fp); |
607 | if (op == ELS_LS_ACC) { | 629 | if (op == ELS_LS_ACC) { |
608 | pp = fc_frame_payload_get(fp, sizeof(*pp)); | 630 | pp = fc_frame_payload_get(fp, sizeof(*pp)); |
@@ -635,7 +657,7 @@ err: | |||
635 | } | 657 | } |
636 | 658 | ||
637 | /** | 659 | /** |
638 | * fc_rport_logo_resp - Logout (LOGO) response handler | 660 | * fc_rport_logo_resp() - Logout (LOGO) response handler |
639 | * @sp: current sequence in the LOGO exchange | 661 | * @sp: current sequence in the LOGO exchange |
640 | * @fp: response frame | 662 | * @fp: response frame |
641 | * @rp_arg: Fibre Channel remote port | 663 | * @rp_arg: Fibre Channel remote port |
@@ -657,7 +679,7 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
657 | rport->port_id); | 679 | rport->port_id); |
658 | 680 | ||
659 | if (IS_ERR(fp)) { | 681 | if (IS_ERR(fp)) { |
660 | fc_rport_error(rport, fp); | 682 | fc_rport_error_retry(rport, fp); |
661 | goto err; | 683 | goto err; |
662 | } | 684 | } |
663 | 685 | ||
@@ -684,7 +706,7 @@ err: | |||
684 | } | 706 | } |
685 | 707 | ||
686 | /** | 708 | /** |
687 | * fc_rport_enter_prli - Send Process Login (PRLI) request to peer | 709 | * fc_rport_enter_prli() - Send Process Login (PRLI) request to peer |
688 | * @rport: Fibre Channel remote port to send PRLI to | 710 | * @rport: Fibre Channel remote port to send PRLI to |
689 | * | 711 | * |
690 | * Locking Note: The rport lock is expected to be held before calling | 712 | * Locking Note: The rport lock is expected to be held before calling |
@@ -707,19 +729,19 @@ static void fc_rport_enter_prli(struct fc_rport *rport) | |||
707 | 729 | ||
708 | fp = fc_frame_alloc(lport, sizeof(*pp)); | 730 | fp = fc_frame_alloc(lport, sizeof(*pp)); |
709 | if (!fp) { | 731 | if (!fp) { |
710 | fc_rport_error(rport, fp); | 732 | fc_rport_error_retry(rport, fp); |
711 | return; | 733 | return; |
712 | } | 734 | } |
713 | 735 | ||
714 | if (!lport->tt.elsct_send(lport, rport, fp, ELS_PRLI, | 736 | if (!lport->tt.elsct_send(lport, rport, fp, ELS_PRLI, |
715 | fc_rport_prli_resp, rport, lport->e_d_tov)) | 737 | fc_rport_prli_resp, rport, lport->e_d_tov)) |
716 | fc_rport_error(rport, fp); | 738 | fc_rport_error_retry(rport, fp); |
717 | else | 739 | else |
718 | get_device(&rport->dev); | 740 | get_device(&rport->dev); |
719 | } | 741 | } |
720 | 742 | ||
721 | /** | 743 | /** |
722 | * fc_rport_els_rtv_resp - Request Timeout Value response handler | 744 | * fc_rport_els_rtv_resp() - Request Timeout Value response handler |
723 | * @sp: current sequence in the RTV exchange | 745 | * @sp: current sequence in the RTV exchange |
724 | * @fp: response frame | 746 | * @fp: response frame |
725 | * @rp_arg: Fibre Channel remote port | 747 | * @rp_arg: Fibre Channel remote port |
@@ -742,17 +764,17 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
742 | FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n", | 764 | FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n", |
743 | rport->port_id); | 765 | rport->port_id); |
744 | 766 | ||
767 | if (IS_ERR(fp)) { | ||
768 | fc_rport_error(rport, fp); | ||
769 | goto err; | ||
770 | } | ||
771 | |||
745 | if (rdata->rp_state != RPORT_ST_RTV) { | 772 | if (rdata->rp_state != RPORT_ST_RTV) { |
746 | FC_DBG("Received a RTV response, but in state %s\n", | 773 | FC_DBG("Received a RTV response, but in state %s\n", |
747 | fc_rport_state(rport)); | 774 | fc_rport_state(rport)); |
748 | goto out; | 775 | goto out; |
749 | } | 776 | } |
750 | 777 | ||
751 | if (IS_ERR(fp)) { | ||
752 | fc_rport_error(rport, fp); | ||
753 | goto err; | ||
754 | } | ||
755 | |||
756 | op = fc_frame_payload_op(fp); | 778 | op = fc_frame_payload_op(fp); |
757 | if (op == ELS_LS_ACC) { | 779 | if (op == ELS_LS_ACC) { |
758 | struct fc_els_rtv_acc *rtv; | 780 | struct fc_els_rtv_acc *rtv; |
@@ -785,7 +807,7 @@ err: | |||
785 | } | 807 | } |
786 | 808 | ||
787 | /** | 809 | /** |
788 | * fc_rport_enter_rtv - Send Request Timeout Value (RTV) request to peer | 810 | * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request to peer |
789 | * @rport: Fibre Channel remote port to send RTV to | 811 | * @rport: Fibre Channel remote port to send RTV to |
790 | * | 812 | * |
791 | * Locking Note: The rport lock is expected to be held before calling | 813 | * Locking Note: The rport lock is expected to be held before calling |
@@ -804,19 +826,19 @@ static void fc_rport_enter_rtv(struct fc_rport *rport) | |||
804 | 826 | ||
805 | fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv)); | 827 | fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv)); |
806 | if (!fp) { | 828 | if (!fp) { |
807 | fc_rport_error(rport, fp); | 829 | fc_rport_error_retry(rport, fp); |
808 | return; | 830 | return; |
809 | } | 831 | } |
810 | 832 | ||
811 | if (!lport->tt.elsct_send(lport, rport, fp, ELS_RTV, | 833 | if (!lport->tt.elsct_send(lport, rport, fp, ELS_RTV, |
812 | fc_rport_rtv_resp, rport, lport->e_d_tov)) | 834 | fc_rport_rtv_resp, rport, lport->e_d_tov)) |
813 | fc_rport_error(rport, fp); | 835 | fc_rport_error_retry(rport, fp); |
814 | else | 836 | else |
815 | get_device(&rport->dev); | 837 | get_device(&rport->dev); |
816 | } | 838 | } |
817 | 839 | ||
818 | /** | 840 | /** |
819 | * fc_rport_enter_logo - Send Logout (LOGO) request to peer | 841 | * fc_rport_enter_logo() - Send Logout (LOGO) request to peer |
820 | * @rport: Fibre Channel remote port to send LOGO to | 842 | * @rport: Fibre Channel remote port to send LOGO to |
821 | * | 843 | * |
822 | * Locking Note: The rport lock is expected to be held before calling | 844 | * Locking Note: The rport lock is expected to be held before calling |
@@ -835,20 +857,20 @@ static void fc_rport_enter_logo(struct fc_rport *rport) | |||
835 | 857 | ||
836 | fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo)); | 858 | fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo)); |
837 | if (!fp) { | 859 | if (!fp) { |
838 | fc_rport_error(rport, fp); | 860 | fc_rport_error_retry(rport, fp); |
839 | return; | 861 | return; |
840 | } | 862 | } |
841 | 863 | ||
842 | if (!lport->tt.elsct_send(lport, rport, fp, ELS_LOGO, | 864 | if (!lport->tt.elsct_send(lport, rport, fp, ELS_LOGO, |
843 | fc_rport_logo_resp, rport, lport->e_d_tov)) | 865 | fc_rport_logo_resp, rport, lport->e_d_tov)) |
844 | fc_rport_error(rport, fp); | 866 | fc_rport_error_retry(rport, fp); |
845 | else | 867 | else |
846 | get_device(&rport->dev); | 868 | get_device(&rport->dev); |
847 | } | 869 | } |
848 | 870 | ||
849 | 871 | ||
850 | /** | 872 | /** |
851 | * fc_rport_recv_req - Receive a request from a rport | 873 | * fc_rport_recv_req() - Receive a request from a rport |
852 | * @sp: current sequence in the PLOGI exchange | 874 | * @sp: current sequence in the PLOGI exchange |
853 | * @fp: response frame | 875 | * @fp: response frame |
854 | * @rp_arg: Fibre Channel remote port | 876 | * @rp_arg: Fibre Channel remote port |
@@ -909,7 +931,7 @@ void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp, | |||
909 | } | 931 | } |
910 | 932 | ||
911 | /** | 933 | /** |
912 | * fc_rport_recv_plogi_req - Handle incoming Port Login (PLOGI) request | 934 | * fc_rport_recv_plogi_req() - Handle incoming Port Login (PLOGI) request |
913 | * @rport: Fibre Channel remote port that initiated PLOGI | 935 | * @rport: Fibre Channel remote port that initiated PLOGI |
914 | * @sp: current sequence in the PLOGI exchange | 936 | * @sp: current sequence in the PLOGI exchange |
915 | * @fp: PLOGI request frame | 937 | * @fp: PLOGI request frame |
@@ -1031,7 +1053,7 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport, | |||
1031 | } | 1053 | } |
1032 | 1054 | ||
1033 | /** | 1055 | /** |
1034 | * fc_rport_recv_prli_req - Handle incoming Process Login (PRLI) request | 1056 | * fc_rport_recv_prli_req() - Handle incoming Process Login (PRLI) request |
1035 | * @rport: Fibre Channel remote port that initiated PRLI | 1057 | * @rport: Fibre Channel remote port that initiated PRLI |
1036 | * @sp: current sequence in the PRLI exchange | 1058 | * @sp: current sequence in the PRLI exchange |
1037 | * @fp: PRLI request frame | 1059 | * @fp: PRLI request frame |
@@ -1182,7 +1204,7 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, | |||
1182 | } | 1204 | } |
1183 | 1205 | ||
1184 | /** | 1206 | /** |
1185 | * fc_rport_recv_prlo_req - Handle incoming Process Logout (PRLO) request | 1207 | * fc_rport_recv_prlo_req() - Handle incoming Process Logout (PRLO) request |
1186 | * @rport: Fibre Channel remote port that initiated PRLO | 1208 | * @rport: Fibre Channel remote port that initiated PRLO |
1187 | * @sp: current sequence in the PRLO exchange | 1209 | * @sp: current sequence in the PRLO exchange |
1188 | * @fp: PRLO request frame | 1210 | * @fp: PRLO request frame |
@@ -1213,7 +1235,7 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp, | |||
1213 | } | 1235 | } |
1214 | 1236 | ||
1215 | /** | 1237 | /** |
1216 | * fc_rport_recv_logo_req - Handle incoming Logout (LOGO) request | 1238 | * fc_rport_recv_logo_req() - Handle incoming Logout (LOGO) request |
1217 | * @rport: Fibre Channel remote port that initiated LOGO | 1239 | * @rport: Fibre Channel remote port that initiated LOGO |
1218 | * @sp: current sequence in the LOGO exchange | 1240 | * @sp: current sequence in the LOGO exchange |
1219 | * @fp: LOGO request frame | 1241 | * @fp: LOGO request frame |
@@ -1249,6 +1271,9 @@ static void fc_rport_flush_queue(void) | |||
1249 | 1271 | ||
1250 | int fc_rport_init(struct fc_lport *lport) | 1272 | int fc_rport_init(struct fc_lport *lport) |
1251 | { | 1273 | { |
1274 | if (!lport->tt.rport_create) | ||
1275 | lport->tt.rport_create = fc_rport_rogue_create; | ||
1276 | |||
1252 | if (!lport->tt.rport_login) | 1277 | if (!lport->tt.rport_login) |
1253 | lport->tt.rport_login = fc_rport_login; | 1278 | lport->tt.rport_login = fc_rport_login; |
1254 | 1279 | ||
@@ -1285,7 +1310,7 @@ void fc_rport_terminate_io(struct fc_rport *rport) | |||
1285 | struct fc_rport_libfc_priv *rdata = rport->dd_data; | 1310 | struct fc_rport_libfc_priv *rdata = rport->dd_data; |
1286 | struct fc_lport *lport = rdata->local_port; | 1311 | struct fc_lport *lport = rdata->local_port; |
1287 | 1312 | ||
1288 | lport->tt.exch_mgr_reset(lport->emp, 0, rport->port_id); | 1313 | lport->tt.exch_mgr_reset(lport, 0, rport->port_id); |
1289 | lport->tt.exch_mgr_reset(lport->emp, rport->port_id, 0); | 1314 | lport->tt.exch_mgr_reset(lport, rport->port_id, 0); |
1290 | } | 1315 | } |
1291 | EXPORT_SYMBOL(fc_rport_terminate_io); | 1316 | EXPORT_SYMBOL(fc_rport_terminate_io); |