diff options
author | Joe Eykholt <jeykholt@cisco.com> | 2009-08-25 17:00:50 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-10 13:07:41 -0400 |
commit | 9fb9d32831fd687e427ec5b147bb690f468b99a0 (patch) | |
tree | c3b6c29cb94040718ea2fe00daac05abf10db714 /drivers/scsi/libfc/fc_disc.c | |
parent | 922aa210bcad4b34a7bb98ec9d318b7e59e7a5ca (diff) |
[SCSI] libfc: make fc_rport_priv the primary rport interface.
The rport and discovery modules deal with remote ports
before fc_remote_port_add() can be done, because the
full set of rport identifiers is not known at early stages.
In preparation for splitting the fc_rport/fc_rport_priv allocation,
make fc_rport_priv the primary interface for the remote port and
discovery engines.
The FCP / SCSI layers still deal with fc_rport and
fc_rport_libfc_priv, however.
Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/libfc/fc_disc.c')
-rw-r--r-- | drivers/scsi/libfc/fc_disc.c | 95 |
1 files changed, 34 insertions, 61 deletions
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index ecc625c20520..448ffc388656 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c | |||
@@ -49,7 +49,6 @@ static void fc_disc_gpn_ft_req(struct fc_disc *); | |||
49 | static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *); | 49 | static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *); |
50 | static int fc_disc_new_target(struct fc_disc *, struct fc_rport *, | 50 | static int fc_disc_new_target(struct fc_disc *, struct fc_rport *, |
51 | struct fc_rport_identifiers *); | 51 | struct fc_rport_identifiers *); |
52 | static void fc_disc_del_target(struct fc_disc *, struct fc_rport *); | ||
53 | static void fc_disc_done(struct fc_disc *); | 52 | static void fc_disc_done(struct fc_disc *); |
54 | static void fc_disc_timeout(struct work_struct *); | 53 | static void fc_disc_timeout(struct work_struct *); |
55 | static void fc_disc_single(struct fc_disc *, struct fc_disc_port *); | 54 | static void fc_disc_single(struct fc_disc *, struct fc_disc_port *); |
@@ -60,27 +59,19 @@ static void fc_disc_restart(struct fc_disc *); | |||
60 | * @lport: Fibre Channel host port instance | 59 | * @lport: Fibre Channel host port instance |
61 | * @port_id: remote port port_id to match | 60 | * @port_id: remote port port_id to match |
62 | */ | 61 | */ |
63 | struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport, | 62 | struct fc_rport_priv *fc_disc_lookup_rport(const struct fc_lport *lport, |
64 | u32 port_id) | 63 | u32 port_id) |
65 | { | 64 | { |
66 | const struct fc_disc *disc = &lport->disc; | 65 | const struct fc_disc *disc = &lport->disc; |
67 | struct fc_rport *rport, *found = NULL; | 66 | struct fc_rport *rport; |
68 | struct fc_rport_priv *rdata; | 67 | struct fc_rport_priv *rdata; |
69 | int disc_found = 0; | ||
70 | 68 | ||
71 | list_for_each_entry(rdata, &disc->rports, peers) { | 69 | list_for_each_entry(rdata, &disc->rports, peers) { |
72 | rport = PRIV_TO_RPORT(rdata); | 70 | rport = PRIV_TO_RPORT(rdata); |
73 | if (rport->port_id == port_id) { | 71 | if (rport->port_id == port_id) |
74 | disc_found = 1; | 72 | return rdata; |
75 | found = rport; | ||
76 | break; | ||
77 | } | ||
78 | } | 73 | } |
79 | 74 | return NULL; | |
80 | if (!disc_found) | ||
81 | found = NULL; | ||
82 | |||
83 | return found; | ||
84 | } | 75 | } |
85 | 76 | ||
86 | /** | 77 | /** |
@@ -93,21 +84,18 @@ struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport, | |||
93 | void fc_disc_stop_rports(struct fc_disc *disc) | 84 | void fc_disc_stop_rports(struct fc_disc *disc) |
94 | { | 85 | { |
95 | struct fc_lport *lport; | 86 | struct fc_lport *lport; |
96 | struct fc_rport *rport; | ||
97 | struct fc_rport_priv *rdata, *next; | 87 | struct fc_rport_priv *rdata, *next; |
98 | 88 | ||
99 | lport = disc->lport; | 89 | lport = disc->lport; |
100 | 90 | ||
101 | mutex_lock(&disc->disc_mutex); | 91 | mutex_lock(&disc->disc_mutex); |
102 | list_for_each_entry_safe(rdata, next, &disc->rports, peers) { | 92 | list_for_each_entry_safe(rdata, next, &disc->rports, peers) { |
103 | rport = PRIV_TO_RPORT(rdata); | ||
104 | list_del(&rdata->peers); | 93 | list_del(&rdata->peers); |
105 | lport->tt.rport_logoff(rport); | 94 | lport->tt.rport_logoff(rdata); |
106 | } | 95 | } |
107 | 96 | ||
108 | list_for_each_entry_safe(rdata, next, &disc->rogue_rports, peers) { | 97 | list_for_each_entry_safe(rdata, next, &disc->rogue_rports, peers) { |
109 | rport = PRIV_TO_RPORT(rdata); | 98 | lport->tt.rport_logoff(rdata); |
110 | lport->tt.rport_logoff(rport); | ||
111 | } | 99 | } |
112 | 100 | ||
113 | mutex_unlock(&disc->disc_mutex); | 101 | mutex_unlock(&disc->disc_mutex); |
@@ -116,18 +104,18 @@ void fc_disc_stop_rports(struct fc_disc *disc) | |||
116 | /** | 104 | /** |
117 | * fc_disc_rport_callback() - Event handler for rport events | 105 | * fc_disc_rport_callback() - Event handler for rport events |
118 | * @lport: The lport which is receiving the event | 106 | * @lport: The lport which is receiving the event |
119 | * @rport: The rport which the event has occured on | 107 | * @rdata: private remote port data |
120 | * @event: The event that occured | 108 | * @event: The event that occured |
121 | * | 109 | * |
122 | * Locking Note: The rport lock should not be held when calling | 110 | * Locking Note: The rport lock should not be held when calling |
123 | * this function. | 111 | * this function. |
124 | */ | 112 | */ |
125 | static void fc_disc_rport_callback(struct fc_lport *lport, | 113 | static void fc_disc_rport_callback(struct fc_lport *lport, |
126 | struct fc_rport *rport, | 114 | struct fc_rport_priv *rdata, |
127 | enum fc_rport_event event) | 115 | enum fc_rport_event event) |
128 | { | 116 | { |
129 | struct fc_rport_priv *rdata = rport->dd_data; | ||
130 | struct fc_disc *disc = &lport->disc; | 117 | struct fc_disc *disc = &lport->disc; |
118 | struct fc_rport *rport = PRIV_TO_RPORT(rdata); | ||
131 | 119 | ||
132 | FC_DISC_DBG(disc, "Received a %d event for port (%6x)\n", event, | 120 | FC_DISC_DBG(disc, "Received a %d event for port (%6x)\n", event, |
133 | rport->port_id); | 121 | rport->port_id); |
@@ -169,7 +157,6 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, | |||
169 | struct fc_disc *disc) | 157 | struct fc_disc *disc) |
170 | { | 158 | { |
171 | struct fc_lport *lport; | 159 | struct fc_lport *lport; |
172 | struct fc_rport *rport; | ||
173 | struct fc_rport_priv *rdata; | 160 | struct fc_rport_priv *rdata; |
174 | struct fc_els_rscn *rp; | 161 | struct fc_els_rscn *rp; |
175 | struct fc_els_rscn_page *pp; | 162 | struct fc_els_rscn_page *pp; |
@@ -249,11 +236,10 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, | |||
249 | redisc, lport->state, disc->pending); | 236 | redisc, lport->state, disc->pending); |
250 | list_for_each_entry_safe(dp, next, &disc_ports, peers) { | 237 | list_for_each_entry_safe(dp, next, &disc_ports, peers) { |
251 | list_del(&dp->peers); | 238 | list_del(&dp->peers); |
252 | rport = lport->tt.rport_lookup(lport, dp->ids.port_id); | 239 | rdata = lport->tt.rport_lookup(lport, dp->ids.port_id); |
253 | if (rport) { | 240 | if (rdata) { |
254 | rdata = rport->dd_data; | ||
255 | list_del(&rdata->peers); | 241 | list_del(&rdata->peers); |
256 | lport->tt.rport_logoff(rport); | 242 | lport->tt.rport_logoff(rdata); |
257 | } | 243 | } |
258 | fc_disc_single(disc, dp); | 244 | fc_disc_single(disc, dp); |
259 | } | 245 | } |
@@ -308,16 +294,14 @@ static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp, | |||
308 | */ | 294 | */ |
309 | static void fc_disc_restart(struct fc_disc *disc) | 295 | static void fc_disc_restart(struct fc_disc *disc) |
310 | { | 296 | { |
311 | struct fc_rport *rport; | ||
312 | struct fc_rport_priv *rdata, *next; | 297 | struct fc_rport_priv *rdata, *next; |
313 | struct fc_lport *lport = disc->lport; | 298 | struct fc_lport *lport = disc->lport; |
314 | 299 | ||
315 | FC_DISC_DBG(disc, "Restarting discovery\n"); | 300 | FC_DISC_DBG(disc, "Restarting discovery\n"); |
316 | 301 | ||
317 | list_for_each_entry_safe(rdata, next, &disc->rports, peers) { | 302 | list_for_each_entry_safe(rdata, next, &disc->rports, peers) { |
318 | rport = PRIV_TO_RPORT(rdata); | ||
319 | list_del(&rdata->peers); | 303 | list_del(&rdata->peers); |
320 | lport->tt.rport_logoff(rport); | 304 | lport->tt.rport_logoff(rdata); |
321 | } | 305 | } |
322 | 306 | ||
323 | disc->requested = 1; | 307 | disc->requested = 1; |
@@ -335,6 +319,7 @@ static void fc_disc_start(void (*disc_callback)(struct fc_lport *, | |||
335 | enum fc_disc_event), | 319 | enum fc_disc_event), |
336 | struct fc_lport *lport) | 320 | struct fc_lport *lport) |
337 | { | 321 | { |
322 | struct fc_rport_priv *rdata; | ||
338 | struct fc_rport *rport; | 323 | struct fc_rport *rport; |
339 | struct fc_rport_identifiers ids; | 324 | struct fc_rport_identifiers ids; |
340 | struct fc_disc *disc = &lport->disc; | 325 | struct fc_disc *disc = &lport->disc; |
@@ -362,8 +347,9 @@ static void fc_disc_start(void (*disc_callback)(struct fc_lport *, | |||
362 | * Handle point-to-point mode as a simple discovery | 347 | * Handle point-to-point mode as a simple discovery |
363 | * of the remote port. Yucky, yucky, yuck, yuck! | 348 | * of the remote port. Yucky, yucky, yuck, yuck! |
364 | */ | 349 | */ |
365 | rport = disc->lport->ptp_rp; | 350 | rdata = disc->lport->ptp_rp; |
366 | if (rport) { | 351 | if (rdata) { |
352 | rport = PRIV_TO_RPORT(rdata); | ||
367 | ids.port_id = rport->port_id; | 353 | ids.port_id = rport->port_id; |
368 | ids.port_name = rport->port_name; | 354 | ids.port_name = rport->port_name; |
369 | ids.node_name = rport->node_name; | 355 | ids.node_name = rport->node_name; |
@@ -418,7 +404,9 @@ static int fc_disc_new_target(struct fc_disc *disc, | |||
418 | * assigned the same FCID. This should be rare. | 404 | * assigned the same FCID. This should be rare. |
419 | * Delete the old one and fall thru to re-create. | 405 | * Delete the old one and fall thru to re-create. |
420 | */ | 406 | */ |
421 | fc_disc_del_target(disc, rport); | 407 | rdata = rport->dd_data; |
408 | list_del(&rdata->peers); | ||
409 | lport->tt.rport_logoff(rdata); | ||
422 | rport = NULL; | 410 | rport = NULL; |
423 | } | 411 | } |
424 | } | 412 | } |
@@ -426,38 +414,27 @@ static int fc_disc_new_target(struct fc_disc *disc, | |||
426 | ids->port_id != fc_host_port_id(lport->host) && | 414 | ids->port_id != fc_host_port_id(lport->host) && |
427 | ids->port_name != lport->wwpn) { | 415 | ids->port_name != lport->wwpn) { |
428 | if (!rport) { | 416 | if (!rport) { |
429 | rport = lport->tt.rport_lookup(lport, ids->port_id); | 417 | rdata = lport->tt.rport_lookup(lport, ids->port_id); |
430 | if (!rport) { | 418 | if (!rport) { |
431 | rport = lport->tt.rport_create(lport, ids); | 419 | rdata = lport->tt.rport_create(lport, ids); |
432 | } | 420 | } |
433 | if (!rport) | 421 | if (!rdata) |
434 | error = -ENOMEM; | 422 | error = -ENOMEM; |
423 | else | ||
424 | rport = PRIV_TO_RPORT(rdata); | ||
435 | } | 425 | } |
436 | if (rport) { | 426 | if (rport) { |
437 | rdata = rport->dd_data; | 427 | rdata = rport->dd_data; |
438 | rdata->ops = &fc_disc_rport_ops; | 428 | rdata->ops = &fc_disc_rport_ops; |
439 | rdata->rp_state = RPORT_ST_INIT; | 429 | rdata->rp_state = RPORT_ST_INIT; |
440 | list_add_tail(&rdata->peers, &disc->rogue_rports); | 430 | list_add_tail(&rdata->peers, &disc->rogue_rports); |
441 | lport->tt.rport_login(rport); | 431 | lport->tt.rport_login(rdata); |
442 | } | 432 | } |
443 | } | 433 | } |
444 | return error; | 434 | return error; |
445 | } | 435 | } |
446 | 436 | ||
447 | /** | 437 | /** |
448 | * fc_disc_del_target() - Delete a target | ||
449 | * @disc: FC discovery context | ||
450 | * @rport: The remote port to be removed | ||
451 | */ | ||
452 | static void fc_disc_del_target(struct fc_disc *disc, struct fc_rport *rport) | ||
453 | { | ||
454 | struct fc_lport *lport = disc->lport; | ||
455 | struct fc_rport_priv *rdata = rport->dd_data; | ||
456 | list_del(&rdata->peers); | ||
457 | lport->tt.rport_logoff(rport); | ||
458 | } | ||
459 | |||
460 | /** | ||
461 | * fc_disc_done() - Discovery has been completed | 438 | * fc_disc_done() - Discovery has been completed |
462 | * @disc: FC discovery context | 439 | * @disc: FC discovery context |
463 | * Locking Note: This function expects that the disc mutex is locked before | 440 | * Locking Note: This function expects that the disc mutex is locked before |
@@ -573,7 +550,6 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) | |||
573 | size_t tlen; | 550 | size_t tlen; |
574 | int error = 0; | 551 | int error = 0; |
575 | struct fc_rport_identifiers ids; | 552 | struct fc_rport_identifiers ids; |
576 | struct fc_rport *rport; | ||
577 | struct fc_rport_priv *rdata; | 553 | struct fc_rport_priv *rdata; |
578 | 554 | ||
579 | lport = disc->lport; | 555 | lport = disc->lport; |
@@ -622,14 +598,13 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) | |||
622 | 598 | ||
623 | if (ids.port_id != fc_host_port_id(lport->host) && | 599 | if (ids.port_id != fc_host_port_id(lport->host) && |
624 | ids.port_name != lport->wwpn) { | 600 | ids.port_name != lport->wwpn) { |
625 | rport = lport->tt.rport_create(lport, &ids); | 601 | rdata = lport->tt.rport_create(lport, &ids); |
626 | if (rport) { | 602 | if (rdata) { |
627 | rdata = rport->dd_data; | ||
628 | rdata->ops = &fc_disc_rport_ops; | 603 | rdata->ops = &fc_disc_rport_ops; |
629 | rdata->local_port = lport; | 604 | rdata->local_port = lport; |
630 | list_add_tail(&rdata->peers, | 605 | list_add_tail(&rdata->peers, |
631 | &disc->rogue_rports); | 606 | &disc->rogue_rports); |
632 | lport->tt.rport_login(rport); | 607 | lport->tt.rport_login(rdata); |
633 | } else | 608 | } else |
634 | printk(KERN_WARNING "libfc: Failed to allocate " | 609 | printk(KERN_WARNING "libfc: Failed to allocate " |
635 | "memory for the newly discovered port " | 610 | "memory for the newly discovered port " |
@@ -766,7 +741,6 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
766 | static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp) | 741 | static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp) |
767 | { | 742 | { |
768 | struct fc_lport *lport; | 743 | struct fc_lport *lport; |
769 | struct fc_rport *new_rport; | ||
770 | struct fc_rport_priv *rdata; | 744 | struct fc_rport_priv *rdata; |
771 | 745 | ||
772 | lport = disc->lport; | 746 | lport = disc->lport; |
@@ -774,13 +748,12 @@ static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp) | |||
774 | if (dp->ids.port_id == fc_host_port_id(lport->host)) | 748 | if (dp->ids.port_id == fc_host_port_id(lport->host)) |
775 | goto out; | 749 | goto out; |
776 | 750 | ||
777 | new_rport = lport->tt.rport_create(lport, &dp->ids); | 751 | rdata = lport->tt.rport_create(lport, &dp->ids); |
778 | if (new_rport) { | 752 | if (rdata) { |
779 | rdata = new_rport->dd_data; | ||
780 | rdata->ops = &fc_disc_rport_ops; | 753 | rdata->ops = &fc_disc_rport_ops; |
781 | kfree(dp); | 754 | kfree(dp); |
782 | list_add_tail(&rdata->peers, &disc->rogue_rports); | 755 | list_add_tail(&rdata->peers, &disc->rogue_rports); |
783 | lport->tt.rport_login(new_rport); | 756 | lport->tt.rport_login(rdata); |
784 | } | 757 | } |
785 | return; | 758 | return; |
786 | out: | 759 | out: |