diff options
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r-- | drivers/scsi/libfc/fc_disc.c | 63 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 32 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_fcp.c | 56 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 173 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 197 |
5 files changed, 255 insertions, 266 deletions
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index dd1564c9e04a..e57556ea5b48 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c | |||
@@ -64,7 +64,7 @@ static void fc_disc_single(struct fc_disc *, struct fc_disc_port *); | |||
64 | static void fc_disc_restart(struct fc_disc *); | 64 | static void fc_disc_restart(struct fc_disc *); |
65 | 65 | ||
66 | /** | 66 | /** |
67 | * fc_disc_lookup_rport - lookup a remote port by port_id | 67 | * fc_disc_lookup_rport() - lookup a remote port by port_id |
68 | * @lport: Fibre Channel host port instance | 68 | * @lport: Fibre Channel host port instance |
69 | * @port_id: remote port port_id to match | 69 | * @port_id: remote port port_id to match |
70 | */ | 70 | */ |
@@ -92,7 +92,7 @@ struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport, | |||
92 | } | 92 | } |
93 | 93 | ||
94 | /** | 94 | /** |
95 | * fc_disc_stop_rports - delete all the remote ports associated with the lport | 95 | * fc_disc_stop_rports() - delete all the remote ports associated with the lport |
96 | * @disc: The discovery job to stop rports on | 96 | * @disc: The discovery job to stop rports on |
97 | * | 97 | * |
98 | * Locking Note: This function expects that the lport mutex is locked before | 98 | * Locking Note: This function expects that the lport mutex is locked before |
@@ -117,7 +117,7 @@ void fc_disc_stop_rports(struct fc_disc *disc) | |||
117 | } | 117 | } |
118 | 118 | ||
119 | /** | 119 | /** |
120 | * fc_disc_rport_callback - Event handler for rport events | 120 | * fc_disc_rport_callback() - Event handler for rport events |
121 | * @lport: The lport which is receiving the event | 121 | * @lport: The lport which is receiving the event |
122 | * @rport: The rport which the event has occured on | 122 | * @rport: The rport which the event has occured on |
123 | * @event: The event that occured | 123 | * @event: The event that occured |
@@ -151,7 +151,7 @@ static void fc_disc_rport_callback(struct fc_lport *lport, | |||
151 | } | 151 | } |
152 | 152 | ||
153 | /** | 153 | /** |
154 | * fc_disc_recv_rscn_req - Handle Registered State Change Notification (RSCN) | 154 | * fc_disc_recv_rscn_req() - Handle Registered State Change Notification (RSCN) |
155 | * @sp: Current sequence of the RSCN exchange | 155 | * @sp: Current sequence of the RSCN exchange |
156 | * @fp: RSCN Frame | 156 | * @fp: RSCN Frame |
157 | * @lport: Fibre Channel host port instance | 157 | * @lport: Fibre Channel host port instance |
@@ -246,7 +246,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, | |||
246 | list_del(&dp->peers); | 246 | list_del(&dp->peers); |
247 | rport = lport->tt.rport_lookup(lport, dp->ids.port_id); | 247 | rport = lport->tt.rport_lookup(lport, dp->ids.port_id); |
248 | if (rport) { | 248 | if (rport) { |
249 | rdata = RPORT_TO_PRIV(rport); | 249 | rdata = rport->dd_data; |
250 | list_del(&rdata->peers); | 250 | list_del(&rdata->peers); |
251 | lport->tt.rport_logoff(rport); | 251 | lport->tt.rport_logoff(rport); |
252 | } | 252 | } |
@@ -265,7 +265,7 @@ reject: | |||
265 | } | 265 | } |
266 | 266 | ||
267 | /** | 267 | /** |
268 | * fc_disc_recv_req - Handle incoming requests | 268 | * fc_disc_recv_req() - Handle incoming requests |
269 | * @sp: Current sequence of the request exchange | 269 | * @sp: Current sequence of the request exchange |
270 | * @fp: The frame | 270 | * @fp: The frame |
271 | * @lport: The FC local port | 271 | * @lport: The FC local port |
@@ -294,7 +294,7 @@ static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp, | |||
294 | } | 294 | } |
295 | 295 | ||
296 | /** | 296 | /** |
297 | * fc_disc_restart - Restart discovery | 297 | * fc_disc_restart() - Restart discovery |
298 | * @lport: FC discovery context | 298 | * @lport: FC discovery context |
299 | * | 299 | * |
300 | * Locking Note: This function expects that the disc mutex | 300 | * Locking Note: This function expects that the disc mutex |
@@ -322,7 +322,7 @@ static void fc_disc_restart(struct fc_disc *disc) | |||
322 | } | 322 | } |
323 | 323 | ||
324 | /** | 324 | /** |
325 | * fc_disc_start - Fibre Channel Target discovery | 325 | * fc_disc_start() - Fibre Channel Target discovery |
326 | * @lport: FC local port | 326 | * @lport: FC local port |
327 | * | 327 | * |
328 | * Returns non-zero if discovery cannot be started. | 328 | * Returns non-zero if discovery cannot be started. |
@@ -383,7 +383,7 @@ static struct fc_rport_operations fc_disc_rport_ops = { | |||
383 | }; | 383 | }; |
384 | 384 | ||
385 | /** | 385 | /** |
386 | * fc_disc_new_target - Handle new target found by discovery | 386 | * fc_disc_new_target() - Handle new target found by discovery |
387 | * @lport: FC local port | 387 | * @lport: FC local port |
388 | * @rport: The previous FC remote port (NULL if new remote port) | 388 | * @rport: The previous FC remote port (NULL if new remote port) |
389 | * @ids: Identifiers for the new FC remote port | 389 | * @ids: Identifiers for the new FC remote port |
@@ -396,7 +396,7 @@ static int fc_disc_new_target(struct fc_disc *disc, | |||
396 | struct fc_rport_identifiers *ids) | 396 | struct fc_rport_identifiers *ids) |
397 | { | 397 | { |
398 | struct fc_lport *lport = disc->lport; | 398 | struct fc_lport *lport = disc->lport; |
399 | struct fc_rport_libfc_priv *rp; | 399 | struct fc_rport_libfc_priv *rdata; |
400 | int error = 0; | 400 | int error = 0; |
401 | 401 | ||
402 | if (rport && ids->port_name) { | 402 | if (rport && ids->port_name) { |
@@ -430,15 +430,15 @@ static int fc_disc_new_target(struct fc_disc *disc, | |||
430 | dp.ids.port_name = ids->port_name; | 430 | dp.ids.port_name = ids->port_name; |
431 | dp.ids.node_name = ids->node_name; | 431 | dp.ids.node_name = ids->node_name; |
432 | dp.ids.roles = ids->roles; | 432 | dp.ids.roles = ids->roles; |
433 | rport = fc_rport_rogue_create(&dp); | 433 | rport = lport->tt.rport_create(&dp); |
434 | } | 434 | } |
435 | if (!rport) | 435 | if (!rport) |
436 | error = -ENOMEM; | 436 | error = -ENOMEM; |
437 | } | 437 | } |
438 | if (rport) { | 438 | if (rport) { |
439 | rp = rport->dd_data; | 439 | rdata = rport->dd_data; |
440 | rp->ops = &fc_disc_rport_ops; | 440 | rdata->ops = &fc_disc_rport_ops; |
441 | rp->rp_state = RPORT_ST_INIT; | 441 | rdata->rp_state = RPORT_ST_INIT; |
442 | lport->tt.rport_login(rport); | 442 | lport->tt.rport_login(rport); |
443 | } | 443 | } |
444 | } | 444 | } |
@@ -446,20 +446,20 @@ static int fc_disc_new_target(struct fc_disc *disc, | |||
446 | } | 446 | } |
447 | 447 | ||
448 | /** | 448 | /** |
449 | * fc_disc_del_target - Delete a target | 449 | * fc_disc_del_target() - Delete a target |
450 | * @disc: FC discovery context | 450 | * @disc: FC discovery context |
451 | * @rport: The remote port to be removed | 451 | * @rport: The remote port to be removed |
452 | */ | 452 | */ |
453 | static void fc_disc_del_target(struct fc_disc *disc, struct fc_rport *rport) | 453 | static void fc_disc_del_target(struct fc_disc *disc, struct fc_rport *rport) |
454 | { | 454 | { |
455 | struct fc_lport *lport = disc->lport; | 455 | struct fc_lport *lport = disc->lport; |
456 | struct fc_rport_libfc_priv *rdata = RPORT_TO_PRIV(rport); | 456 | struct fc_rport_libfc_priv *rdata = rport->dd_data; |
457 | list_del(&rdata->peers); | 457 | list_del(&rdata->peers); |
458 | lport->tt.rport_logoff(rport); | 458 | lport->tt.rport_logoff(rport); |
459 | } | 459 | } |
460 | 460 | ||
461 | /** | 461 | /** |
462 | * fc_disc_done - Discovery has been completed | 462 | * fc_disc_done() - Discovery has been completed |
463 | * @disc: FC discovery context | 463 | * @disc: FC discovery context |
464 | */ | 464 | */ |
465 | static void fc_disc_done(struct fc_disc *disc) | 465 | static void fc_disc_done(struct fc_disc *disc) |
@@ -479,7 +479,7 @@ static void fc_disc_done(struct fc_disc *disc) | |||
479 | } | 479 | } |
480 | 480 | ||
481 | /** | 481 | /** |
482 | * fc_disc_error - Handle error on dNS request | 482 | * fc_disc_error() - Handle error on dNS request |
483 | * @disc: FC discovery context | 483 | * @disc: FC discovery context |
484 | * @fp: The frame pointer | 484 | * @fp: The frame pointer |
485 | */ | 485 | */ |
@@ -519,7 +519,7 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp) | |||
519 | } | 519 | } |
520 | 520 | ||
521 | /** | 521 | /** |
522 | * fc_disc_gpn_ft_req - Send Get Port Names by FC-4 type (GPN_FT) request | 522 | * fc_disc_gpn_ft_req() - Send Get Port Names by FC-4 type (GPN_FT) request |
523 | * @lport: FC discovery context | 523 | * @lport: FC discovery context |
524 | * | 524 | * |
525 | * Locking Note: This function expects that the disc_mutex is locked | 525 | * Locking Note: This function expects that the disc_mutex is locked |
@@ -553,7 +553,7 @@ err: | |||
553 | } | 553 | } |
554 | 554 | ||
555 | /** | 555 | /** |
556 | * fc_disc_gpn_ft_parse - Parse the list of IDs and names resulting from a request | 556 | * fc_disc_gpn_ft_parse() - Parse the list of IDs and names resulting from a request |
557 | * @lport: Fibre Channel host port instance | 557 | * @lport: Fibre Channel host port instance |
558 | * @buf: GPN_FT response buffer | 558 | * @buf: GPN_FT response buffer |
559 | * @len: size of response buffer | 559 | * @len: size of response buffer |
@@ -617,7 +617,7 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) | |||
617 | 617 | ||
618 | if ((dp.ids.port_id != fc_host_port_id(lport->host)) && | 618 | if ((dp.ids.port_id != fc_host_port_id(lport->host)) && |
619 | (dp.ids.port_name != lport->wwpn)) { | 619 | (dp.ids.port_name != lport->wwpn)) { |
620 | rport = fc_rport_rogue_create(&dp); | 620 | rport = lport->tt.rport_create(&dp); |
621 | if (rport) { | 621 | if (rport) { |
622 | rdata = rport->dd_data; | 622 | rdata = rport->dd_data; |
623 | rdata->ops = &fc_disc_rport_ops; | 623 | rdata->ops = &fc_disc_rport_ops; |
@@ -658,7 +658,10 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) | |||
658 | return error; | 658 | return error; |
659 | } | 659 | } |
660 | 660 | ||
661 | /* | 661 | /** |
662 | * fc_disc_timeout() - Retry handler for the disc component | ||
663 | * @work: Structure holding disc obj that needs retry discovery | ||
664 | * | ||
662 | * Handle retry of memory allocation for remote ports. | 665 | * Handle retry of memory allocation for remote ports. |
663 | */ | 666 | */ |
664 | static void fc_disc_timeout(struct work_struct *work) | 667 | static void fc_disc_timeout(struct work_struct *work) |
@@ -673,7 +676,7 @@ static void fc_disc_timeout(struct work_struct *work) | |||
673 | } | 676 | } |
674 | 677 | ||
675 | /** | 678 | /** |
676 | * fc_disc_gpn_ft_resp - Handle a response frame from Get Port Names (GPN_FT) | 679 | * fc_disc_gpn_ft_resp() - Handle a response frame from Get Port Names (GPN_FT) |
677 | * @sp: Current sequence of GPN_FT exchange | 680 | * @sp: Current sequence of GPN_FT exchange |
678 | * @fp: response frame | 681 | * @fp: response frame |
679 | * @lp_arg: Fibre Channel host port instance | 682 | * @lp_arg: Fibre Channel host port instance |
@@ -712,9 +715,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
712 | fr_len(fp)); | 715 | fr_len(fp)); |
713 | } else if (ntohs(cp->ct_cmd) == FC_FS_ACC) { | 716 | } else if (ntohs(cp->ct_cmd) == FC_FS_ACC) { |
714 | 717 | ||
715 | /* | 718 | /* Accepted, parse the response. */ |
716 | * Accepted. Parse response. | ||
717 | */ | ||
718 | buf = cp + 1; | 719 | buf = cp + 1; |
719 | len -= sizeof(*cp); | 720 | len -= sizeof(*cp); |
720 | } else if (ntohs(cp->ct_cmd) == FC_FS_RJT) { | 721 | } else if (ntohs(cp->ct_cmd) == FC_FS_RJT) { |
@@ -746,7 +747,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
746 | } | 747 | } |
747 | 748 | ||
748 | /** | 749 | /** |
749 | * fc_disc_single - Discover the directory information for a single target | 750 | * fc_disc_single() - Discover the directory information for a single target |
750 | * @lport: FC local port | 751 | * @lport: FC local port |
751 | * @dp: The port to rediscover | 752 | * @dp: The port to rediscover |
752 | * | 753 | * |
@@ -769,7 +770,7 @@ static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp) | |||
769 | if (rport) | 770 | if (rport) |
770 | fc_disc_del_target(disc, rport); | 771 | fc_disc_del_target(disc, rport); |
771 | 772 | ||
772 | new_rport = fc_rport_rogue_create(dp); | 773 | new_rport = lport->tt.rport_create(dp); |
773 | if (new_rport) { | 774 | if (new_rport) { |
774 | rdata = new_rport->dd_data; | 775 | rdata = new_rport->dd_data; |
775 | rdata->ops = &fc_disc_rport_ops; | 776 | rdata->ops = &fc_disc_rport_ops; |
@@ -782,7 +783,7 @@ out: | |||
782 | } | 783 | } |
783 | 784 | ||
784 | /** | 785 | /** |
785 | * fc_disc_stop - Stop discovery for a given lport | 786 | * fc_disc_stop() - Stop discovery for a given lport |
786 | * @lport: The lport that discovery should stop for | 787 | * @lport: The lport that discovery should stop for |
787 | */ | 788 | */ |
788 | void fc_disc_stop(struct fc_lport *lport) | 789 | void fc_disc_stop(struct fc_lport *lport) |
@@ -796,7 +797,7 @@ void fc_disc_stop(struct fc_lport *lport) | |||
796 | } | 797 | } |
797 | 798 | ||
798 | /** | 799 | /** |
799 | * fc_disc_stop_final - Stop discovery for a given lport | 800 | * fc_disc_stop_final() - Stop discovery for a given lport |
800 | * @lport: The lport that discovery should stop for | 801 | * @lport: The lport that discovery should stop for |
801 | * | 802 | * |
802 | * This function will block until discovery has been | 803 | * This function will block until discovery has been |
@@ -809,7 +810,7 @@ void fc_disc_stop_final(struct fc_lport *lport) | |||
809 | } | 810 | } |
810 | 811 | ||
811 | /** | 812 | /** |
812 | * fc_disc_init - Initialize the discovery block | 813 | * fc_disc_init() - Initialize the discovery block |
813 | * @lport: FC local port | 814 | * @lport: FC local port |
814 | */ | 815 | */ |
815 | int fc_disc_init(struct fc_lport *lport) | 816 | int fc_disc_init(struct fc_lport *lport) |
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 66db08a5f27f..505825b6124d 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include <scsi/libfc.h> | 32 | #include <scsi/libfc.h> |
33 | #include <scsi/fc_encode.h> | 33 | #include <scsi/fc_encode.h> |
34 | 34 | ||
35 | #define FC_DEF_R_A_TOV (10 * 1000) /* resource allocation timeout */ | ||
36 | |||
37 | /* | 35 | /* |
38 | * fc_exch_debug can be set in debugger or at compile time to get more logs. | 36 | * fc_exch_debug can be set in debugger or at compile time to get more logs. |
39 | */ | 37 | */ |
@@ -627,7 +625,6 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) | |||
627 | { | 625 | { |
628 | struct fc_exch *ep; | 626 | struct fc_exch *ep; |
629 | struct fc_frame_header *fh; | 627 | struct fc_frame_header *fh; |
630 | u16 rxid; | ||
631 | 628 | ||
632 | ep = mp->lp->tt.exch_get(mp->lp, fp); | 629 | ep = mp->lp->tt.exch_get(mp->lp, fp); |
633 | if (ep) { | 630 | if (ep) { |
@@ -654,18 +651,6 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) | |||
654 | if ((ntoh24(fh->fh_f_ctl) & FC_FC_SEQ_INIT) == 0) | 651 | if ((ntoh24(fh->fh_f_ctl) & FC_FC_SEQ_INIT) == 0) |
655 | ep->esb_stat &= ~ESB_ST_SEQ_INIT; | 652 | ep->esb_stat &= ~ESB_ST_SEQ_INIT; |
656 | 653 | ||
657 | /* | ||
658 | * Set the responder ID in the frame header. | ||
659 | * The old one should've been 0xffff. | ||
660 | * If it isn't, don't assign one. | ||
661 | * Incoming basic link service frames may specify | ||
662 | * a referenced RX_ID. | ||
663 | */ | ||
664 | if (fh->fh_type != FC_TYPE_BLS) { | ||
665 | rxid = ntohs(fh->fh_rx_id); | ||
666 | WARN_ON(rxid != FC_XID_UNKNOWN); | ||
667 | fh->fh_rx_id = htons(ep->rxid); | ||
668 | } | ||
669 | fc_exch_hold(ep); /* hold for caller */ | 654 | fc_exch_hold(ep); /* hold for caller */ |
670 | spin_unlock_bh(&ep->ex_lock); /* lock from exch_get */ | 655 | spin_unlock_bh(&ep->ex_lock); /* lock from exch_get */ |
671 | } | 656 | } |
@@ -677,8 +662,8 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) | |||
677 | * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold | 662 | * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold |
678 | * on the ep that should be released by the caller. | 663 | * on the ep that should be released by the caller. |
679 | */ | 664 | */ |
680 | static enum fc_pf_rjt_reason | 665 | static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_exch_mgr *mp, |
681 | fc_seq_lookup_recip(struct fc_exch_mgr *mp, struct fc_frame *fp) | 666 | struct fc_frame *fp) |
682 | { | 667 | { |
683 | struct fc_frame_header *fh = fc_frame_header_get(fp); | 668 | struct fc_frame_header *fh = fc_frame_header_get(fp); |
684 | struct fc_exch *ep = NULL; | 669 | struct fc_exch *ep = NULL; |
@@ -996,9 +981,9 @@ static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp) | |||
996 | * Send BLS Reject. | 981 | * Send BLS Reject. |
997 | * This is for rejecting BA_ABTS only. | 982 | * This is for rejecting BA_ABTS only. |
998 | */ | 983 | */ |
999 | static void | 984 | static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp, |
1000 | fc_exch_send_ba_rjt(struct fc_frame *rx_fp, enum fc_ba_rjt_reason reason, | 985 | enum fc_ba_rjt_reason reason, |
1001 | enum fc_ba_rjt_explan explan) | 986 | enum fc_ba_rjt_explan explan) |
1002 | { | 987 | { |
1003 | struct fc_frame *fp; | 988 | struct fc_frame *fp; |
1004 | struct fc_frame_header *rx_fh; | 989 | struct fc_frame_header *rx_fh; |
@@ -1096,7 +1081,7 @@ static void fc_exch_recv_abts(struct fc_exch *ep, struct fc_frame *rx_fp) | |||
1096 | ap->ba_high_seq_cnt = fh->fh_seq_cnt; | 1081 | ap->ba_high_seq_cnt = fh->fh_seq_cnt; |
1097 | ap->ba_low_seq_cnt = htons(sp->cnt); | 1082 | ap->ba_low_seq_cnt = htons(sp->cnt); |
1098 | } | 1083 | } |
1099 | sp = fc_seq_start_next(sp); | 1084 | sp = fc_seq_start_next_locked(sp); |
1100 | spin_unlock_bh(&ep->ex_lock); | 1085 | spin_unlock_bh(&ep->ex_lock); |
1101 | fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS); | 1086 | fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS); |
1102 | fc_frame_free(rx_fp); | 1087 | fc_frame_free(rx_fp); |
@@ -1480,10 +1465,11 @@ static void fc_exch_reset(struct fc_exch *ep) | |||
1480 | * If sid is non-zero, reset only exchanges we source from that FID. | 1465 | * If sid is non-zero, reset only exchanges we source from that FID. |
1481 | * If did is non-zero, reset only exchanges destined to that FID. | 1466 | * If did is non-zero, reset only exchanges destined to that FID. |
1482 | */ | 1467 | */ |
1483 | void fc_exch_mgr_reset(struct fc_exch_mgr *mp, u32 sid, u32 did) | 1468 | void fc_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did) |
1484 | { | 1469 | { |
1485 | struct fc_exch *ep; | 1470 | struct fc_exch *ep; |
1486 | struct fc_exch *next; | 1471 | struct fc_exch *next; |
1472 | struct fc_exch_mgr *mp = lp->emp; | ||
1487 | 1473 | ||
1488 | spin_lock_bh(&mp->em_lock); | 1474 | spin_lock_bh(&mp->em_lock); |
1489 | restart: | 1475 | restart: |
@@ -1607,7 +1593,7 @@ static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg) | |||
1607 | if (IS_ERR(fp)) { | 1593 | if (IS_ERR(fp)) { |
1608 | int err = PTR_ERR(fp); | 1594 | int err = PTR_ERR(fp); |
1609 | 1595 | ||
1610 | if (err == -FC_EX_CLOSED) | 1596 | if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT) |
1611 | goto cleanup; | 1597 | goto cleanup; |
1612 | FC_DBG("Cannot process RRQ, because of frame error %d\n", err); | 1598 | FC_DBG("Cannot process RRQ, because of frame error %d\n", err); |
1613 | return; | 1599 | return; |
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 404e63ff46b8..2a631d7dbcec 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c | |||
@@ -161,7 +161,7 @@ static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport *lp, gfp_t gfp) | |||
161 | } | 161 | } |
162 | 162 | ||
163 | /** | 163 | /** |
164 | * fc_fcp_pkt_release - release hold on scsi_pkt packet | 164 | * fc_fcp_pkt_release() - release hold on scsi_pkt packet |
165 | * @fsp: fcp packet struct | 165 | * @fsp: fcp packet struct |
166 | * | 166 | * |
167 | * This is used by upper layer scsi driver. | 167 | * This is used by upper layer scsi driver. |
@@ -183,8 +183,7 @@ static void fc_fcp_pkt_hold(struct fc_fcp_pkt *fsp) | |||
183 | } | 183 | } |
184 | 184 | ||
185 | /** | 185 | /** |
186 | * fc_fcp_pkt_destory - release hold on scsi_pkt packet | 186 | * fc_fcp_pkt_destory() - release hold on scsi_pkt packet |
187 | * | ||
188 | * @seq: exchange sequence | 187 | * @seq: exchange sequence |
189 | * @fsp: fcp packet struct | 188 | * @fsp: fcp packet struct |
190 | * | 189 | * |
@@ -199,7 +198,7 @@ static void fc_fcp_pkt_destroy(struct fc_seq *seq, void *fsp) | |||
199 | } | 198 | } |
200 | 199 | ||
201 | /** | 200 | /** |
202 | * fc_fcp_lock_pkt - lock a packet and get a ref to it. | 201 | * fc_fcp_lock_pkt() - lock a packet and get a ref to it. |
203 | * @fsp: fcp packet | 202 | * @fsp: fcp packet |
204 | * | 203 | * |
205 | * We should only return error if we return a command to scsi-ml before | 204 | * We should only return error if we return a command to scsi-ml before |
@@ -291,9 +290,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) | |||
291 | buf = fc_frame_payload_get(fp, 0); | 290 | buf = fc_frame_payload_get(fp, 0); |
292 | 291 | ||
293 | if (offset + len > fsp->data_len) { | 292 | if (offset + len > fsp->data_len) { |
294 | /* | 293 | /* this should never happen */ |
295 | * this should never happen | ||
296 | */ | ||
297 | if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && | 294 | if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && |
298 | fc_frame_crc_check(fp)) | 295 | fc_frame_crc_check(fp)) |
299 | goto crc_err; | 296 | goto crc_err; |
@@ -387,8 +384,8 @@ crc_err: | |||
387 | fc_fcp_complete_locked(fsp); | 384 | fc_fcp_complete_locked(fsp); |
388 | } | 385 | } |
389 | 386 | ||
390 | /* | 387 | /** |
391 | * fc_fcp_send_data - Send SCSI data to target. | 388 | * fc_fcp_send_data() - Send SCSI data to target. |
392 | * @fsp: ptr to fc_fcp_pkt | 389 | * @fsp: ptr to fc_fcp_pkt |
393 | * @sp: ptr to this sequence | 390 | * @sp: ptr to this sequence |
394 | * @offset: starting offset for this data request | 391 | * @offset: starting offset for this data request |
@@ -610,8 +607,8 @@ static void fc_fcp_abts_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) | |||
610 | } | 607 | } |
611 | } | 608 | } |
612 | 609 | ||
613 | /* | 610 | /** |
614 | * fc_fcp_reduce_can_queue - drop can_queue | 611 | * fc_fcp_reduce_can_queue() - drop can_queue |
615 | * @lp: lport to drop queueing for | 612 | * @lp: lport to drop queueing for |
616 | * | 613 | * |
617 | * If we are getting memory allocation failures, then we may | 614 | * If we are getting memory allocation failures, then we may |
@@ -642,9 +639,11 @@ done: | |||
642 | spin_unlock_irqrestore(lp->host->host_lock, flags); | 639 | spin_unlock_irqrestore(lp->host->host_lock, flags); |
643 | } | 640 | } |
644 | 641 | ||
645 | /* | 642 | /** |
646 | * exch mgr calls this routine to process scsi | 643 | * fc_fcp_recv() - Reveive FCP frames |
647 | * exchanges. | 644 | * @seq: The sequence the frame is on |
645 | * @fp: The FC frame | ||
646 | * @arg: The related FCP packet | ||
648 | * | 647 | * |
649 | * Return : None | 648 | * Return : None |
650 | * Context : called from Soft IRQ context | 649 | * Context : called from Soft IRQ context |
@@ -832,7 +831,7 @@ err: | |||
832 | } | 831 | } |
833 | 832 | ||
834 | /** | 833 | /** |
835 | * fc_fcp_complete_locked - complete processing of a fcp packet | 834 | * fc_fcp_complete_locked() - complete processing of a fcp packet |
836 | * @fsp: fcp packet | 835 | * @fsp: fcp packet |
837 | * | 836 | * |
838 | * This function may sleep if a timer is pending. The packet lock must be | 837 | * This function may sleep if a timer is pending. The packet lock must be |
@@ -900,7 +899,7 @@ static void fc_fcp_cleanup_cmd(struct fc_fcp_pkt *fsp, int error) | |||
900 | } | 899 | } |
901 | 900 | ||
902 | /** | 901 | /** |
903 | * fc_fcp_cleanup_each_cmd - run fn on each active command | 902 | * fc_fcp_cleanup_each_cmd() - Cleanup active commads |
904 | * @lp: logical port | 903 | * @lp: logical port |
905 | * @id: target id | 904 | * @id: target id |
906 | * @lun: lun | 905 | * @lun: lun |
@@ -952,7 +951,7 @@ static void fc_fcp_abort_io(struct fc_lport *lp) | |||
952 | } | 951 | } |
953 | 952 | ||
954 | /** | 953 | /** |
955 | * fc_fcp_pkt_send - send a fcp packet to the lower level. | 954 | * fc_fcp_pkt_send() - send a fcp packet to the lower level. |
956 | * @lp: fc lport | 955 | * @lp: fc lport |
957 | * @fsp: fc packet. | 956 | * @fsp: fc packet. |
958 | * | 957 | * |
@@ -1621,7 +1620,7 @@ out: | |||
1621 | static inline int fc_fcp_lport_queue_ready(struct fc_lport *lp) | 1620 | static inline int fc_fcp_lport_queue_ready(struct fc_lport *lp) |
1622 | { | 1621 | { |
1623 | /* lock ? */ | 1622 | /* lock ? */ |
1624 | return (lp->state == LPORT_ST_READY) && (lp->link_status & FC_LINK_UP); | 1623 | return (lp->state == LPORT_ST_READY) && lp->link_up && !lp->qfull; |
1625 | } | 1624 | } |
1626 | 1625 | ||
1627 | /** | 1626 | /** |
@@ -1727,7 +1726,7 @@ out: | |||
1727 | EXPORT_SYMBOL(fc_queuecommand); | 1726 | EXPORT_SYMBOL(fc_queuecommand); |
1728 | 1727 | ||
1729 | /** | 1728 | /** |
1730 | * fc_io_compl - Handle responses for completed commands | 1729 | * fc_io_compl() - Handle responses for completed commands |
1731 | * @fsp: scsi packet | 1730 | * @fsp: scsi packet |
1732 | * | 1731 | * |
1733 | * Translates a error to a Linux SCSI error. | 1732 | * Translates a error to a Linux SCSI error. |
@@ -1810,12 +1809,12 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) | |||
1810 | sc_cmd->result = DID_ERROR << 16; | 1809 | sc_cmd->result = DID_ERROR << 16; |
1811 | break; | 1810 | break; |
1812 | case FC_DATA_UNDRUN: | 1811 | case FC_DATA_UNDRUN: |
1813 | if (fsp->cdb_status == 0) { | 1812 | if ((fsp->cdb_status == 0) && !(fsp->req_flags & FC_SRB_READ)) { |
1814 | /* | 1813 | /* |
1815 | * scsi status is good but transport level | 1814 | * scsi status is good but transport level |
1816 | * underrun. for read it should be an error?? | 1815 | * underrun. |
1817 | */ | 1816 | */ |
1818 | sc_cmd->result = (DID_OK << 16) | fsp->cdb_status; | 1817 | sc_cmd->result = DID_OK << 16; |
1819 | } else { | 1818 | } else { |
1820 | /* | 1819 | /* |
1821 | * scsi got underrun, this is an error | 1820 | * scsi got underrun, this is an error |
@@ -1857,7 +1856,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) | |||
1857 | } | 1856 | } |
1858 | 1857 | ||
1859 | /** | 1858 | /** |
1860 | * fc_fcp_complete - complete processing of a fcp packet | 1859 | * fc_fcp_complete() - complete processing of a fcp packet |
1861 | * @fsp: fcp packet | 1860 | * @fsp: fcp packet |
1862 | * | 1861 | * |
1863 | * This function may sleep if a fsp timer is pending. | 1862 | * This function may sleep if a fsp timer is pending. |
@@ -1874,9 +1873,10 @@ void fc_fcp_complete(struct fc_fcp_pkt *fsp) | |||
1874 | EXPORT_SYMBOL(fc_fcp_complete); | 1873 | EXPORT_SYMBOL(fc_fcp_complete); |
1875 | 1874 | ||
1876 | /** | 1875 | /** |
1877 | * fc_eh_abort - Abort a command...from scsi host template | 1876 | * fc_eh_abort() - Abort a command |
1878 | * @sc_cmd: scsi command to abort | 1877 | * @sc_cmd: scsi command to abort |
1879 | * | 1878 | * |
1879 | * From scsi host template. | ||
1880 | * send ABTS to the target device and wait for the response | 1880 | * send ABTS to the target device and wait for the response |
1881 | * sc_cmd is the pointer to the command to be aborted. | 1881 | * sc_cmd is the pointer to the command to be aborted. |
1882 | */ | 1882 | */ |
@@ -1890,7 +1890,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd) | |||
1890 | lp = shost_priv(sc_cmd->device->host); | 1890 | lp = shost_priv(sc_cmd->device->host); |
1891 | if (lp->state != LPORT_ST_READY) | 1891 | if (lp->state != LPORT_ST_READY) |
1892 | return rc; | 1892 | return rc; |
1893 | else if (!(lp->link_status & FC_LINK_UP)) | 1893 | else if (!lp->link_up) |
1894 | return rc; | 1894 | return rc; |
1895 | 1895 | ||
1896 | spin_lock_irqsave(lp->host->host_lock, flags); | 1896 | spin_lock_irqsave(lp->host->host_lock, flags); |
@@ -1920,7 +1920,7 @@ release_pkt: | |||
1920 | EXPORT_SYMBOL(fc_eh_abort); | 1920 | EXPORT_SYMBOL(fc_eh_abort); |
1921 | 1921 | ||
1922 | /** | 1922 | /** |
1923 | * fc_eh_device_reset: Reset a single LUN | 1923 | * fc_eh_device_reset() Reset a single LUN |
1924 | * @sc_cmd: scsi command | 1924 | * @sc_cmd: scsi command |
1925 | * | 1925 | * |
1926 | * Set from scsi host template to send tm cmd to the target and wait for the | 1926 | * Set from scsi host template to send tm cmd to the target and wait for the |
@@ -1973,7 +1973,7 @@ out: | |||
1973 | EXPORT_SYMBOL(fc_eh_device_reset); | 1973 | EXPORT_SYMBOL(fc_eh_device_reset); |
1974 | 1974 | ||
1975 | /** | 1975 | /** |
1976 | * fc_eh_host_reset - The reset function will reset the ports on the host. | 1976 | * fc_eh_host_reset() - The reset function will reset the ports on the host. |
1977 | * @sc_cmd: scsi command | 1977 | * @sc_cmd: scsi command |
1978 | */ | 1978 | */ |
1979 | int fc_eh_host_reset(struct scsi_cmnd *sc_cmd) | 1979 | int fc_eh_host_reset(struct scsi_cmnd *sc_cmd) |
@@ -1999,7 +1999,7 @@ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd) | |||
1999 | EXPORT_SYMBOL(fc_eh_host_reset); | 1999 | EXPORT_SYMBOL(fc_eh_host_reset); |
2000 | 2000 | ||
2001 | /** | 2001 | /** |
2002 | * fc_slave_alloc - configure queue depth | 2002 | * fc_slave_alloc() - configure queue depth |
2003 | * @sdev: scsi device | 2003 | * @sdev: scsi device |
2004 | * | 2004 | * |
2005 | * Configures queue depth based on host's cmd_per_len. If not set | 2005 | * Configures queue depth based on host's cmd_per_len. If not set |
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 0b9bdb1fb807..2ae50a1188e6 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c | |||
@@ -139,7 +139,7 @@ static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp) | |||
139 | } | 139 | } |
140 | 140 | ||
141 | /** | 141 | /** |
142 | * fc_lport_rport_callback - Event handler for rport events | 142 | * fc_lport_rport_callback() - Event handler for rport events |
143 | * @lport: The lport which is receiving the event | 143 | * @lport: The lport which is receiving the event |
144 | * @rport: The rport which the event has occured on | 144 | * @rport: The rport which the event has occured on |
145 | * @event: The event that occured | 145 | * @event: The event that occured |
@@ -195,7 +195,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport, | |||
195 | } | 195 | } |
196 | 196 | ||
197 | /** | 197 | /** |
198 | * fc_lport_state - Return a string which represents the lport's state | 198 | * fc_lport_state() - Return a string which represents the lport's state |
199 | * @lport: The lport whose state is to converted to a string | 199 | * @lport: The lport whose state is to converted to a string |
200 | */ | 200 | */ |
201 | static const char *fc_lport_state(struct fc_lport *lport) | 201 | static const char *fc_lport_state(struct fc_lport *lport) |
@@ -209,7 +209,7 @@ static const char *fc_lport_state(struct fc_lport *lport) | |||
209 | } | 209 | } |
210 | 210 | ||
211 | /** | 211 | /** |
212 | * fc_lport_ptp_setup - Create an rport for point-to-point mode | 212 | * fc_lport_ptp_setup() - Create an rport for point-to-point mode |
213 | * @lport: The lport to attach the ptp rport to | 213 | * @lport: The lport to attach the ptp rport to |
214 | * @fid: The FID of the ptp rport | 214 | * @fid: The FID of the ptp rport |
215 | * @remote_wwpn: The WWPN of the ptp rport | 215 | * @remote_wwpn: The WWPN of the ptp rport |
@@ -232,7 +232,7 @@ static void fc_lport_ptp_setup(struct fc_lport *lport, | |||
232 | lport->ptp_rp = NULL; | 232 | lport->ptp_rp = NULL; |
233 | } | 233 | } |
234 | 234 | ||
235 | lport->ptp_rp = fc_rport_rogue_create(&dp); | 235 | lport->ptp_rp = lport->tt.rport_create(&dp); |
236 | 236 | ||
237 | lport->tt.rport_login(lport->ptp_rp); | 237 | lport->tt.rport_login(lport->ptp_rp); |
238 | 238 | ||
@@ -250,7 +250,7 @@ void fc_get_host_port_state(struct Scsi_Host *shost) | |||
250 | { | 250 | { |
251 | struct fc_lport *lp = shost_priv(shost); | 251 | struct fc_lport *lp = shost_priv(shost); |
252 | 252 | ||
253 | if ((lp->link_status & FC_LINK_UP) == FC_LINK_UP) | 253 | if (lp->link_up) |
254 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; | 254 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; |
255 | else | 255 | else |
256 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; | 256 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; |
@@ -351,7 +351,7 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type) | |||
351 | } | 351 | } |
352 | 352 | ||
353 | /** | 353 | /** |
354 | * fc_lport_recv_rlir_req - Handle received Registered Link Incident Report. | 354 | * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report. |
355 | * @lport: Fibre Channel local port recieving the RLIR | 355 | * @lport: Fibre Channel local port recieving the RLIR |
356 | * @sp: current sequence in the RLIR exchange | 356 | * @sp: current sequence in the RLIR exchange |
357 | * @fp: RLIR request frame | 357 | * @fp: RLIR request frame |
@@ -370,7 +370,7 @@ static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp, | |||
370 | } | 370 | } |
371 | 371 | ||
372 | /** | 372 | /** |
373 | * fc_lport_recv_echo_req - Handle received ECHO request | 373 | * fc_lport_recv_echo_req() - Handle received ECHO request |
374 | * @lport: Fibre Channel local port recieving the ECHO | 374 | * @lport: Fibre Channel local port recieving the ECHO |
375 | * @sp: current sequence in the ECHO exchange | 375 | * @sp: current sequence in the ECHO exchange |
376 | * @fp: ECHO request frame | 376 | * @fp: ECHO request frame |
@@ -412,7 +412,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp, | |||
412 | } | 412 | } |
413 | 413 | ||
414 | /** | 414 | /** |
415 | * fc_lport_recv_echo_req - Handle received Request Node ID data request | 415 | * fc_lport_recv_echo_req() - Handle received Request Node ID data request |
416 | * @lport: Fibre Channel local port recieving the RNID | 416 | * @lport: Fibre Channel local port recieving the RNID |
417 | * @sp: current sequence in the RNID exchange | 417 | * @sp: current sequence in the RNID exchange |
418 | * @fp: RNID request frame | 418 | * @fp: RNID request frame |
@@ -479,7 +479,7 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp, | |||
479 | } | 479 | } |
480 | 480 | ||
481 | /** | 481 | /** |
482 | * fc_lport_recv_adisc_req - Handle received Address Discovery Request | 482 | * fc_lport_recv_adisc_req() - Handle received Address Discovery Request |
483 | * @lport: Fibre Channel local port recieving the ADISC | 483 | * @lport: Fibre Channel local port recieving the ADISC |
484 | * @sp: current sequence in the ADISC exchange | 484 | * @sp: current sequence in the ADISC exchange |
485 | * @fp: ADISC request frame | 485 | * @fp: ADISC request frame |
@@ -529,7 +529,7 @@ static void fc_lport_recv_adisc_req(struct fc_seq *sp, struct fc_frame *in_fp, | |||
529 | } | 529 | } |
530 | 530 | ||
531 | /** | 531 | /** |
532 | * fc_lport_recv_logo_req - Handle received fabric LOGO request | 532 | * fc_lport_recv_logo_req() - Handle received fabric LOGO request |
533 | * @lport: Fibre Channel local port recieving the LOGO | 533 | * @lport: Fibre Channel local port recieving the LOGO |
534 | * @sp: current sequence in the LOGO exchange | 534 | * @sp: current sequence in the LOGO exchange |
535 | * @fp: LOGO request frame | 535 | * @fp: LOGO request frame |
@@ -546,7 +546,7 @@ static void fc_lport_recv_logo_req(struct fc_seq *sp, struct fc_frame *fp, | |||
546 | } | 546 | } |
547 | 547 | ||
548 | /** | 548 | /** |
549 | * fc_fabric_login - Start the lport state machine | 549 | * fc_fabric_login() - Start the lport state machine |
550 | * @lport: The lport that should log into the fabric | 550 | * @lport: The lport that should log into the fabric |
551 | * | 551 | * |
552 | * Locking Note: This function should not be called | 552 | * Locking Note: This function should not be called |
@@ -568,7 +568,7 @@ int fc_fabric_login(struct fc_lport *lport) | |||
568 | EXPORT_SYMBOL(fc_fabric_login); | 568 | EXPORT_SYMBOL(fc_fabric_login); |
569 | 569 | ||
570 | /** | 570 | /** |
571 | * fc_linkup - Handler for transport linkup events | 571 | * fc_linkup() - Handler for transport linkup events |
572 | * @lport: The lport whose link is up | 572 | * @lport: The lport whose link is up |
573 | */ | 573 | */ |
574 | void fc_linkup(struct fc_lport *lport) | 574 | void fc_linkup(struct fc_lport *lport) |
@@ -577,8 +577,8 @@ void fc_linkup(struct fc_lport *lport) | |||
577 | fc_host_port_id(lport->host)); | 577 | fc_host_port_id(lport->host)); |
578 | 578 | ||
579 | mutex_lock(&lport->lp_mutex); | 579 | mutex_lock(&lport->lp_mutex); |
580 | if ((lport->link_status & FC_LINK_UP) != FC_LINK_UP) { | 580 | if (!lport->link_up) { |
581 | lport->link_status |= FC_LINK_UP; | 581 | lport->link_up = 1; |
582 | 582 | ||
583 | if (lport->state == LPORT_ST_RESET) | 583 | if (lport->state == LPORT_ST_RESET) |
584 | fc_lport_enter_flogi(lport); | 584 | fc_lport_enter_flogi(lport); |
@@ -588,7 +588,7 @@ void fc_linkup(struct fc_lport *lport) | |||
588 | EXPORT_SYMBOL(fc_linkup); | 588 | EXPORT_SYMBOL(fc_linkup); |
589 | 589 | ||
590 | /** | 590 | /** |
591 | * fc_linkdown - Handler for transport linkdown events | 591 | * fc_linkdown() - Handler for transport linkdown events |
592 | * @lport: The lport whose link is down | 592 | * @lport: The lport whose link is down |
593 | */ | 593 | */ |
594 | void fc_linkdown(struct fc_lport *lport) | 594 | void fc_linkdown(struct fc_lport *lport) |
@@ -597,8 +597,8 @@ void fc_linkdown(struct fc_lport *lport) | |||
597 | FC_DEBUG_LPORT("Link is down for port (%6x)\n", | 597 | FC_DEBUG_LPORT("Link is down for port (%6x)\n", |
598 | fc_host_port_id(lport->host)); | 598 | fc_host_port_id(lport->host)); |
599 | 599 | ||
600 | if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP) { | 600 | if (lport->link_up) { |
601 | lport->link_status &= ~(FC_LINK_UP); | 601 | lport->link_up = 0; |
602 | fc_lport_enter_reset(lport); | 602 | fc_lport_enter_reset(lport); |
603 | lport->tt.fcp_cleanup(lport); | 603 | lport->tt.fcp_cleanup(lport); |
604 | } | 604 | } |
@@ -607,48 +607,25 @@ void fc_linkdown(struct fc_lport *lport) | |||
607 | EXPORT_SYMBOL(fc_linkdown); | 607 | EXPORT_SYMBOL(fc_linkdown); |
608 | 608 | ||
609 | /** | 609 | /** |
610 | * fc_pause - Pause the flow of frames | 610 | * fc_fabric_logoff() - Logout of the fabric |
611 | * @lport: The lport to be paused | ||
612 | */ | ||
613 | void fc_pause(struct fc_lport *lport) | ||
614 | { | ||
615 | mutex_lock(&lport->lp_mutex); | ||
616 | lport->link_status |= FC_PAUSE; | ||
617 | mutex_unlock(&lport->lp_mutex); | ||
618 | } | ||
619 | EXPORT_SYMBOL(fc_pause); | ||
620 | |||
621 | /** | ||
622 | * fc_unpause - Unpause the flow of frames | ||
623 | * @lport: The lport to be unpaused | ||
624 | */ | ||
625 | void fc_unpause(struct fc_lport *lport) | ||
626 | { | ||
627 | mutex_lock(&lport->lp_mutex); | ||
628 | lport->link_status &= ~(FC_PAUSE); | ||
629 | mutex_unlock(&lport->lp_mutex); | ||
630 | } | ||
631 | EXPORT_SYMBOL(fc_unpause); | ||
632 | |||
633 | /** | ||
634 | * fc_fabric_logoff - Logout of the fabric | ||
635 | * @lport: fc_lport pointer to logoff the fabric | 611 | * @lport: fc_lport pointer to logoff the fabric |
636 | * | 612 | * |
637 | * Return value: | 613 | * Return value: |
638 | * 0 for success, -1 for failure | 614 | * 0 for success, -1 for failure |
639 | **/ | 615 | */ |
640 | int fc_fabric_logoff(struct fc_lport *lport) | 616 | int fc_fabric_logoff(struct fc_lport *lport) |
641 | { | 617 | { |
642 | lport->tt.disc_stop_final(lport); | 618 | lport->tt.disc_stop_final(lport); |
643 | mutex_lock(&lport->lp_mutex); | 619 | mutex_lock(&lport->lp_mutex); |
644 | fc_lport_enter_logo(lport); | 620 | fc_lport_enter_logo(lport); |
645 | mutex_unlock(&lport->lp_mutex); | 621 | mutex_unlock(&lport->lp_mutex); |
622 | cancel_delayed_work_sync(&lport->retry_work); | ||
646 | return 0; | 623 | return 0; |
647 | } | 624 | } |
648 | EXPORT_SYMBOL(fc_fabric_logoff); | 625 | EXPORT_SYMBOL(fc_fabric_logoff); |
649 | 626 | ||
650 | /** | 627 | /** |
651 | * fc_lport_destroy - unregister a fc_lport | 628 | * fc_lport_destroy() - unregister a fc_lport |
652 | * @lport: fc_lport pointer to unregister | 629 | * @lport: fc_lport pointer to unregister |
653 | * | 630 | * |
654 | * Return value: | 631 | * Return value: |
@@ -658,26 +635,25 @@ EXPORT_SYMBOL(fc_fabric_logoff); | |||
658 | * clean-up all the allocated memory | 635 | * clean-up all the allocated memory |
659 | * and free up other system resources. | 636 | * and free up other system resources. |
660 | * | 637 | * |
661 | **/ | 638 | */ |
662 | int fc_lport_destroy(struct fc_lport *lport) | 639 | int fc_lport_destroy(struct fc_lport *lport) |
663 | { | 640 | { |
664 | lport->tt.frame_send = fc_frame_drop; | 641 | lport->tt.frame_send = fc_frame_drop; |
665 | lport->tt.fcp_abort_io(lport); | 642 | lport->tt.fcp_abort_io(lport); |
666 | lport->tt.exch_mgr_reset(lport->emp, 0, 0); | 643 | lport->tt.exch_mgr_reset(lport, 0, 0); |
667 | return 0; | 644 | return 0; |
668 | } | 645 | } |
669 | EXPORT_SYMBOL(fc_lport_destroy); | 646 | EXPORT_SYMBOL(fc_lport_destroy); |
670 | 647 | ||
671 | /** | 648 | /** |
672 | * fc_set_mfs - sets up the mfs for the corresponding fc_lport | 649 | * fc_set_mfs() - sets up the mfs for the corresponding fc_lport |
673 | * @lport: fc_lport pointer to unregister | 650 | * @lport: fc_lport pointer to unregister |
674 | * @mfs: the new mfs for fc_lport | 651 | * @mfs: the new mfs for fc_lport |
675 | * | 652 | * |
676 | * Set mfs for the given fc_lport to the new mfs. | 653 | * Set mfs for the given fc_lport to the new mfs. |
677 | * | 654 | * |
678 | * Return: 0 for success | 655 | * Return: 0 for success |
679 | * | 656 | */ |
680 | **/ | ||
681 | int fc_set_mfs(struct fc_lport *lport, u32 mfs) | 657 | int fc_set_mfs(struct fc_lport *lport, u32 mfs) |
682 | { | 658 | { |
683 | unsigned int old_mfs; | 659 | unsigned int old_mfs; |
@@ -706,7 +682,7 @@ int fc_set_mfs(struct fc_lport *lport, u32 mfs) | |||
706 | EXPORT_SYMBOL(fc_set_mfs); | 682 | EXPORT_SYMBOL(fc_set_mfs); |
707 | 683 | ||
708 | /** | 684 | /** |
709 | * fc_lport_disc_callback - Callback for discovery events | 685 | * fc_lport_disc_callback() - Callback for discovery events |
710 | * @lport: FC local port | 686 | * @lport: FC local port |
711 | * @event: The discovery event | 687 | * @event: The discovery event |
712 | */ | 688 | */ |
@@ -731,7 +707,7 @@ void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event) | |||
731 | } | 707 | } |
732 | 708 | ||
733 | /** | 709 | /** |
734 | * fc_rport_enter_ready - Enter the ready state and start discovery | 710 | * fc_rport_enter_ready() - Enter the ready state and start discovery |
735 | * @lport: Fibre Channel local port that is ready | 711 | * @lport: Fibre Channel local port that is ready |
736 | * | 712 | * |
737 | * Locking Note: The lport lock is expected to be held before calling | 713 | * Locking Note: The lport lock is expected to be held before calling |
@@ -748,7 +724,7 @@ static void fc_lport_enter_ready(struct fc_lport *lport) | |||
748 | } | 724 | } |
749 | 725 | ||
750 | /** | 726 | /** |
751 | * fc_lport_recv_flogi_req - Receive a FLOGI request | 727 | * fc_lport_recv_flogi_req() - Receive a FLOGI request |
752 | * @sp_in: The sequence the FLOGI is on | 728 | * @sp_in: The sequence the FLOGI is on |
753 | * @rx_fp: The frame the FLOGI is in | 729 | * @rx_fp: The frame the FLOGI is in |
754 | * @lport: The lport that recieved the request | 730 | * @lport: The lport that recieved the request |
@@ -838,7 +814,7 @@ out: | |||
838 | } | 814 | } |
839 | 815 | ||
840 | /** | 816 | /** |
841 | * fc_lport_recv_req - The generic lport request handler | 817 | * fc_lport_recv_req() - The generic lport request handler |
842 | * @lport: The lport that received the request | 818 | * @lport: The lport that received the request |
843 | * @sp: The sequence the request is on | 819 | * @sp: The sequence the request is on |
844 | * @fp: The frame the request is in | 820 | * @fp: The frame the request is in |
@@ -934,7 +910,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, | |||
934 | } | 910 | } |
935 | 911 | ||
936 | /** | 912 | /** |
937 | * fc_lport_reset - Reset an lport | 913 | * fc_lport_reset() - Reset an lport |
938 | * @lport: The lport which should be reset | 914 | * @lport: The lport which should be reset |
939 | * | 915 | * |
940 | * Locking Note: This functions should not be called with the | 916 | * Locking Note: This functions should not be called with the |
@@ -942,6 +918,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, | |||
942 | */ | 918 | */ |
943 | int fc_lport_reset(struct fc_lport *lport) | 919 | int fc_lport_reset(struct fc_lport *lport) |
944 | { | 920 | { |
921 | cancel_delayed_work_sync(&lport->retry_work); | ||
945 | mutex_lock(&lport->lp_mutex); | 922 | mutex_lock(&lport->lp_mutex); |
946 | fc_lport_enter_reset(lport); | 923 | fc_lport_enter_reset(lport); |
947 | mutex_unlock(&lport->lp_mutex); | 924 | mutex_unlock(&lport->lp_mutex); |
@@ -950,7 +927,7 @@ int fc_lport_reset(struct fc_lport *lport) | |||
950 | EXPORT_SYMBOL(fc_lport_reset); | 927 | EXPORT_SYMBOL(fc_lport_reset); |
951 | 928 | ||
952 | /** | 929 | /** |
953 | * fc_rport_enter_reset - Reset the local port | 930 | * fc_rport_enter_reset() - Reset the local port |
954 | * @lport: Fibre Channel local port to be reset | 931 | * @lport: Fibre Channel local port to be reset |
955 | * | 932 | * |
956 | * Locking Note: The lport lock is expected to be held before calling | 933 | * Locking Note: The lport lock is expected to be held before calling |
@@ -973,16 +950,16 @@ static void fc_lport_enter_reset(struct fc_lport *lport) | |||
973 | 950 | ||
974 | lport->tt.disc_stop(lport); | 951 | lport->tt.disc_stop(lport); |
975 | 952 | ||
976 | lport->tt.exch_mgr_reset(lport->emp, 0, 0); | 953 | lport->tt.exch_mgr_reset(lport, 0, 0); |
977 | fc_host_fabric_name(lport->host) = 0; | 954 | fc_host_fabric_name(lport->host) = 0; |
978 | fc_host_port_id(lport->host) = 0; | 955 | fc_host_port_id(lport->host) = 0; |
979 | 956 | ||
980 | if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP) | 957 | if (lport->link_up) |
981 | fc_lport_enter_flogi(lport); | 958 | fc_lport_enter_flogi(lport); |
982 | } | 959 | } |
983 | 960 | ||
984 | /** | 961 | /** |
985 | * fc_lport_error - Handler for any errors | 962 | * fc_lport_error() - Handler for any errors |
986 | * @lport: The fc_lport object | 963 | * @lport: The fc_lport object |
987 | * @fp: The frame pointer | 964 | * @fp: The frame pointer |
988 | * | 965 | * |
@@ -1029,8 +1006,8 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp) | |||
1029 | } | 1006 | } |
1030 | 1007 | ||
1031 | /** | 1008 | /** |
1032 | * fc_lport_rft_id_resp - Handle response to Register Fibre | 1009 | * fc_lport_rft_id_resp() - Handle response to Register Fibre |
1033 | * Channel Types by ID (RPN_ID) request | 1010 | * Channel Types by ID (RPN_ID) request |
1034 | * @sp: current sequence in RPN_ID exchange | 1011 | * @sp: current sequence in RPN_ID exchange |
1035 | * @fp: response frame | 1012 | * @fp: response frame |
1036 | * @lp_arg: Fibre Channel host port instance | 1013 | * @lp_arg: Fibre Channel host port instance |
@@ -1053,17 +1030,17 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
1053 | 1030 | ||
1054 | FC_DEBUG_LPORT("Received a RFT_ID response\n"); | 1031 | FC_DEBUG_LPORT("Received a RFT_ID response\n"); |
1055 | 1032 | ||
1033 | if (IS_ERR(fp)) { | ||
1034 | fc_lport_error(lport, fp); | ||
1035 | goto err; | ||
1036 | } | ||
1037 | |||
1056 | if (lport->state != LPORT_ST_RFT_ID) { | 1038 | if (lport->state != LPORT_ST_RFT_ID) { |
1057 | FC_DBG("Received a RFT_ID response, but in state %s\n", | 1039 | FC_DBG("Received a RFT_ID response, but in state %s\n", |
1058 | fc_lport_state(lport)); | 1040 | fc_lport_state(lport)); |
1059 | goto out; | 1041 | goto out; |
1060 | } | 1042 | } |
1061 | 1043 | ||
1062 | if (IS_ERR(fp)) { | ||
1063 | fc_lport_error(lport, fp); | ||
1064 | goto err; | ||
1065 | } | ||
1066 | |||
1067 | fh = fc_frame_header_get(fp); | 1044 | fh = fc_frame_header_get(fp); |
1068 | ct = fc_frame_payload_get(fp, sizeof(*ct)); | 1045 | ct = fc_frame_payload_get(fp, sizeof(*ct)); |
1069 | 1046 | ||
@@ -1081,8 +1058,8 @@ err: | |||
1081 | } | 1058 | } |
1082 | 1059 | ||
1083 | /** | 1060 | /** |
1084 | * fc_lport_rpn_id_resp - Handle response to Register Port | 1061 | * fc_lport_rpn_id_resp() - Handle response to Register Port |
1085 | * Name by ID (RPN_ID) request | 1062 | * Name by ID (RPN_ID) request |
1086 | * @sp: current sequence in RPN_ID exchange | 1063 | * @sp: current sequence in RPN_ID exchange |
1087 | * @fp: response frame | 1064 | * @fp: response frame |
1088 | * @lp_arg: Fibre Channel host port instance | 1065 | * @lp_arg: Fibre Channel host port instance |
@@ -1105,17 +1082,17 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
1105 | 1082 | ||
1106 | FC_DEBUG_LPORT("Received a RPN_ID response\n"); | 1083 | FC_DEBUG_LPORT("Received a RPN_ID response\n"); |
1107 | 1084 | ||
1085 | if (IS_ERR(fp)) { | ||
1086 | fc_lport_error(lport, fp); | ||
1087 | goto err; | ||
1088 | } | ||
1089 | |||
1108 | if (lport->state != LPORT_ST_RPN_ID) { | 1090 | if (lport->state != LPORT_ST_RPN_ID) { |
1109 | FC_DBG("Received a RPN_ID response, but in state %s\n", | 1091 | FC_DBG("Received a RPN_ID response, but in state %s\n", |
1110 | fc_lport_state(lport)); | 1092 | fc_lport_state(lport)); |
1111 | goto out; | 1093 | goto out; |
1112 | } | 1094 | } |
1113 | 1095 | ||
1114 | if (IS_ERR(fp)) { | ||
1115 | fc_lport_error(lport, fp); | ||
1116 | goto err; | ||
1117 | } | ||
1118 | |||
1119 | fh = fc_frame_header_get(fp); | 1096 | fh = fc_frame_header_get(fp); |
1120 | ct = fc_frame_payload_get(fp, sizeof(*ct)); | 1097 | ct = fc_frame_payload_get(fp, sizeof(*ct)); |
1121 | if (fh && ct && fh->fh_type == FC_TYPE_CT && | 1098 | if (fh && ct && fh->fh_type == FC_TYPE_CT && |
@@ -1133,7 +1110,7 @@ err: | |||
1133 | } | 1110 | } |
1134 | 1111 | ||
1135 | /** | 1112 | /** |
1136 | * fc_lport_scr_resp - Handle response to State Change Register (SCR) request | 1113 | * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request |
1137 | * @sp: current sequence in SCR exchange | 1114 | * @sp: current sequence in SCR exchange |
1138 | * @fp: response frame | 1115 | * @fp: response frame |
1139 | * @lp_arg: Fibre Channel lport port instance that sent the registration request | 1116 | * @lp_arg: Fibre Channel lport port instance that sent the registration request |
@@ -1155,17 +1132,17 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
1155 | 1132 | ||
1156 | FC_DEBUG_LPORT("Received a SCR response\n"); | 1133 | FC_DEBUG_LPORT("Received a SCR response\n"); |
1157 | 1134 | ||
1135 | if (IS_ERR(fp)) { | ||
1136 | fc_lport_error(lport, fp); | ||
1137 | goto err; | ||
1138 | } | ||
1139 | |||
1158 | if (lport->state != LPORT_ST_SCR) { | 1140 | if (lport->state != LPORT_ST_SCR) { |
1159 | FC_DBG("Received a SCR response, but in state %s\n", | 1141 | FC_DBG("Received a SCR response, but in state %s\n", |
1160 | fc_lport_state(lport)); | 1142 | fc_lport_state(lport)); |
1161 | goto out; | 1143 | goto out; |
1162 | } | 1144 | } |
1163 | 1145 | ||
1164 | if (IS_ERR(fp)) { | ||
1165 | fc_lport_error(lport, fp); | ||
1166 | goto err; | ||
1167 | } | ||
1168 | |||
1169 | op = fc_frame_payload_op(fp); | 1146 | op = fc_frame_payload_op(fp); |
1170 | if (op == ELS_LS_ACC) | 1147 | if (op == ELS_LS_ACC) |
1171 | fc_lport_enter_ready(lport); | 1148 | fc_lport_enter_ready(lport); |
@@ -1179,7 +1156,7 @@ err: | |||
1179 | } | 1156 | } |
1180 | 1157 | ||
1181 | /** | 1158 | /** |
1182 | * fc_lport_enter_scr - Send a State Change Register (SCR) request | 1159 | * fc_lport_enter_scr() - Send a State Change Register (SCR) request |
1183 | * @lport: Fibre Channel local port to register for state changes | 1160 | * @lport: Fibre Channel local port to register for state changes |
1184 | * | 1161 | * |
1185 | * Locking Note: The lport lock is expected to be held before calling | 1162 | * Locking Note: The lport lock is expected to be held before calling |
@@ -1206,7 +1183,7 @@ static void fc_lport_enter_scr(struct fc_lport *lport) | |||
1206 | } | 1183 | } |
1207 | 1184 | ||
1208 | /** | 1185 | /** |
1209 | * fc_lport_enter_rft_id - Register FC4-types with the name server | 1186 | * fc_lport_enter_rft_id() - Register FC4-types with the name server |
1210 | * @lport: Fibre Channel local port to register | 1187 | * @lport: Fibre Channel local port to register |
1211 | * | 1188 | * |
1212 | * Locking Note: The lport lock is expected to be held before calling | 1189 | * Locking Note: The lport lock is expected to be held before calling |
@@ -1248,7 +1225,7 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport) | |||
1248 | } | 1225 | } |
1249 | 1226 | ||
1250 | /** | 1227 | /** |
1251 | * fc_rport_enter_rft_id - Register port name with the name server | 1228 | * fc_rport_enter_rft_id() - Register port name with the name server |
1252 | * @lport: Fibre Channel local port to register | 1229 | * @lport: Fibre Channel local port to register |
1253 | * | 1230 | * |
1254 | * Locking Note: The lport lock is expected to be held before calling | 1231 | * Locking Note: The lport lock is expected to be held before calling |
@@ -1281,7 +1258,7 @@ static struct fc_rport_operations fc_lport_rport_ops = { | |||
1281 | }; | 1258 | }; |
1282 | 1259 | ||
1283 | /** | 1260 | /** |
1284 | * fc_rport_enter_dns - Create a rport to the name server | 1261 | * fc_rport_enter_dns() - Create a rport to the name server |
1285 | * @lport: Fibre Channel local port requesting a rport for the name server | 1262 | * @lport: Fibre Channel local port requesting a rport for the name server |
1286 | * | 1263 | * |
1287 | * Locking Note: The lport lock is expected to be held before calling | 1264 | * Locking Note: The lport lock is expected to be held before calling |
@@ -1304,7 +1281,7 @@ static void fc_lport_enter_dns(struct fc_lport *lport) | |||
1304 | 1281 | ||
1305 | fc_lport_state_enter(lport, LPORT_ST_DNS); | 1282 | fc_lport_state_enter(lport, LPORT_ST_DNS); |
1306 | 1283 | ||
1307 | rport = fc_rport_rogue_create(&dp); | 1284 | rport = lport->tt.rport_create(&dp); |
1308 | if (!rport) | 1285 | if (!rport) |
1309 | goto err; | 1286 | goto err; |
1310 | 1287 | ||
@@ -1318,7 +1295,7 @@ err: | |||
1318 | } | 1295 | } |
1319 | 1296 | ||
1320 | /** | 1297 | /** |
1321 | * fc_lport_timeout - Handler for the retry_work timer. | 1298 | * fc_lport_timeout() - Handler for the retry_work timer. |
1322 | * @work: The work struct of the fc_lport | 1299 | * @work: The work struct of the fc_lport |
1323 | */ | 1300 | */ |
1324 | static void fc_lport_timeout(struct work_struct *work) | 1301 | static void fc_lport_timeout(struct work_struct *work) |
@@ -1359,7 +1336,7 @@ static void fc_lport_timeout(struct work_struct *work) | |||
1359 | } | 1336 | } |
1360 | 1337 | ||
1361 | /** | 1338 | /** |
1362 | * fc_lport_logo_resp - Handle response to LOGO request | 1339 | * fc_lport_logo_resp() - Handle response to LOGO request |
1363 | * @sp: current sequence in LOGO exchange | 1340 | * @sp: current sequence in LOGO exchange |
1364 | * @fp: response frame | 1341 | * @fp: response frame |
1365 | * @lp_arg: Fibre Channel lport port instance that sent the LOGO request | 1342 | * @lp_arg: Fibre Channel lport port instance that sent the LOGO request |
@@ -1381,17 +1358,17 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
1381 | 1358 | ||
1382 | FC_DEBUG_LPORT("Received a LOGO response\n"); | 1359 | FC_DEBUG_LPORT("Received a LOGO response\n"); |
1383 | 1360 | ||
1361 | if (IS_ERR(fp)) { | ||
1362 | fc_lport_error(lport, fp); | ||
1363 | goto err; | ||
1364 | } | ||
1365 | |||
1384 | if (lport->state != LPORT_ST_LOGO) { | 1366 | if (lport->state != LPORT_ST_LOGO) { |
1385 | FC_DBG("Received a LOGO response, but in state %s\n", | 1367 | FC_DBG("Received a LOGO response, but in state %s\n", |
1386 | fc_lport_state(lport)); | 1368 | fc_lport_state(lport)); |
1387 | goto out; | 1369 | goto out; |
1388 | } | 1370 | } |
1389 | 1371 | ||
1390 | if (IS_ERR(fp)) { | ||
1391 | fc_lport_error(lport, fp); | ||
1392 | goto err; | ||
1393 | } | ||
1394 | |||
1395 | op = fc_frame_payload_op(fp); | 1372 | op = fc_frame_payload_op(fp); |
1396 | if (op == ELS_LS_ACC) | 1373 | if (op == ELS_LS_ACC) |
1397 | fc_lport_enter_reset(lport); | 1374 | fc_lport_enter_reset(lport); |
@@ -1405,7 +1382,7 @@ err: | |||
1405 | } | 1382 | } |
1406 | 1383 | ||
1407 | /** | 1384 | /** |
1408 | * fc_rport_enter_logo - Logout of the fabric | 1385 | * fc_rport_enter_logo() - Logout of the fabric |
1409 | * @lport: Fibre Channel local port to be logged out | 1386 | * @lport: Fibre Channel local port to be logged out |
1410 | * | 1387 | * |
1411 | * Locking Note: The lport lock is expected to be held before calling | 1388 | * Locking Note: The lport lock is expected to be held before calling |
@@ -1437,7 +1414,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport) | |||
1437 | } | 1414 | } |
1438 | 1415 | ||
1439 | /** | 1416 | /** |
1440 | * fc_lport_flogi_resp - Handle response to FLOGI request | 1417 | * fc_lport_flogi_resp() - Handle response to FLOGI request |
1441 | * @sp: current sequence in FLOGI exchange | 1418 | * @sp: current sequence in FLOGI exchange |
1442 | * @fp: response frame | 1419 | * @fp: response frame |
1443 | * @lp_arg: Fibre Channel lport port instance that sent the FLOGI request | 1420 | * @lp_arg: Fibre Channel lport port instance that sent the FLOGI request |
@@ -1465,17 +1442,17 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
1465 | 1442 | ||
1466 | FC_DEBUG_LPORT("Received a FLOGI response\n"); | 1443 | FC_DEBUG_LPORT("Received a FLOGI response\n"); |
1467 | 1444 | ||
1445 | if (IS_ERR(fp)) { | ||
1446 | fc_lport_error(lport, fp); | ||
1447 | goto err; | ||
1448 | } | ||
1449 | |||
1468 | if (lport->state != LPORT_ST_FLOGI) { | 1450 | if (lport->state != LPORT_ST_FLOGI) { |
1469 | FC_DBG("Received a FLOGI response, but in state %s\n", | 1451 | FC_DBG("Received a FLOGI response, but in state %s\n", |
1470 | fc_lport_state(lport)); | 1452 | fc_lport_state(lport)); |
1471 | goto out; | 1453 | goto out; |
1472 | } | 1454 | } |
1473 | 1455 | ||
1474 | if (IS_ERR(fp)) { | ||
1475 | fc_lport_error(lport, fp); | ||
1476 | goto err; | ||
1477 | } | ||
1478 | |||
1479 | fh = fc_frame_header_get(fp); | 1456 | fh = fc_frame_header_get(fp); |
1480 | did = ntoh24(fh->fh_d_id); | 1457 | did = ntoh24(fh->fh_d_id); |
1481 | if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { | 1458 | if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { |
@@ -1532,7 +1509,7 @@ err: | |||
1532 | } | 1509 | } |
1533 | 1510 | ||
1534 | /** | 1511 | /** |
1535 | * fc_rport_enter_flogi - Send a FLOGI request to the fabric manager | 1512 | * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager |
1536 | * @lport: Fibre Channel local port to be logged in to the fabric | 1513 | * @lport: Fibre Channel local port to be logged in to the fabric |
1537 | * | 1514 | * |
1538 | * Locking Note: The lport lock is expected to be held before calling | 1515 | * Locking Note: The lport lock is expected to be held before calling |
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); |