diff options
author | Joe Eykholt <jeykholt@cisco.com> | 2009-08-25 17:01:18 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-10 13:07:43 -0400 |
commit | 9e9d0452fe12115b1c1883c0d4d2ee509079791b (patch) | |
tree | 7cf8bb38e28e562274dcd7eeb2adfdf394876d14 /drivers/scsi/libfc/fc_disc.c | |
parent | 4c0f62b5679321b2e5572cf541ffb9f7b344d47c (diff) |
[SCSI] libfc: don't create dummy (rogue) remote ports
Don't create a "dummy" remote port to go with fc_rport_priv.
Make the rport truly optional by allocating fc_rport_priv separately
and not requiring a dummy rport to be there if we haven't yet done
fc_remote_port_add().
The fc_rport_libfc_priv remains as a structure attached to the
rport for I/O purposes.
Be sure to hold references on rdata when the lock is dropped in
fc_rport_work().
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 | 40 |
1 files changed, 10 insertions, 30 deletions
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index e5e5b260a572..bbea41e50a57 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c | |||
@@ -66,7 +66,8 @@ struct fc_rport_priv *fc_disc_lookup_rport(const struct fc_lport *lport, | |||
66 | struct fc_rport_priv *rdata; | 66 | struct fc_rport_priv *rdata; |
67 | 67 | ||
68 | list_for_each_entry(rdata, &disc->rports, peers) { | 68 | list_for_each_entry(rdata, &disc->rports, peers) { |
69 | if (rdata->ids.port_id == port_id) | 69 | if (rdata->ids.port_id == port_id && |
70 | rdata->rp_state != RPORT_ST_DELETE) | ||
70 | return rdata; | 71 | return rdata; |
71 | } | 72 | } |
72 | return NULL; | 73 | return NULL; |
@@ -87,15 +88,8 @@ void fc_disc_stop_rports(struct fc_disc *disc) | |||
87 | lport = disc->lport; | 88 | lport = disc->lport; |
88 | 89 | ||
89 | mutex_lock(&disc->disc_mutex); | 90 | mutex_lock(&disc->disc_mutex); |
90 | list_for_each_entry_safe(rdata, next, &disc->rports, peers) { | 91 | list_for_each_entry_safe(rdata, next, &disc->rports, peers) |
91 | list_del(&rdata->peers); | ||
92 | lport->tt.rport_logoff(rdata); | 92 | lport->tt.rport_logoff(rdata); |
93 | } | ||
94 | |||
95 | list_for_each_entry_safe(rdata, next, &disc->rogue_rports, peers) { | ||
96 | lport->tt.rport_logoff(rdata); | ||
97 | } | ||
98 | |||
99 | mutex_unlock(&disc->disc_mutex); | 93 | mutex_unlock(&disc->disc_mutex); |
100 | } | 94 | } |
101 | 95 | ||
@@ -119,20 +113,12 @@ static void fc_disc_rport_callback(struct fc_lport *lport, | |||
119 | 113 | ||
120 | switch (event) { | 114 | switch (event) { |
121 | case RPORT_EV_READY: | 115 | case RPORT_EV_READY: |
122 | if (disc) { | ||
123 | mutex_lock(&disc->disc_mutex); | ||
124 | list_add_tail(&rdata->peers, &disc->rports); | ||
125 | mutex_unlock(&disc->disc_mutex); | ||
126 | } | ||
127 | break; | 116 | break; |
128 | case RPORT_EV_LOGO: | 117 | case RPORT_EV_LOGO: |
129 | case RPORT_EV_FAILED: | 118 | case RPORT_EV_FAILED: |
130 | case RPORT_EV_STOP: | 119 | case RPORT_EV_STOP: |
131 | mutex_lock(&disc->disc_mutex); | 120 | mutex_lock(&disc->disc_mutex); |
132 | mutex_lock(&rdata->rp_mutex); | 121 | list_del(&rdata->peers); |
133 | if (rdata->trans_state == FC_PORTSTATE_ROGUE) | ||
134 | list_del(&rdata->peers); | ||
135 | mutex_unlock(&rdata->rp_mutex); | ||
136 | mutex_unlock(&disc->disc_mutex); | 122 | mutex_unlock(&disc->disc_mutex); |
137 | break; | 123 | break; |
138 | default: | 124 | default: |
@@ -235,7 +221,6 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, | |||
235 | list_del(&dp->peers); | 221 | list_del(&dp->peers); |
236 | rdata = lport->tt.rport_lookup(lport, dp->ids.port_id); | 222 | rdata = lport->tt.rport_lookup(lport, dp->ids.port_id); |
237 | if (rdata) { | 223 | if (rdata) { |
238 | list_del(&rdata->peers); | ||
239 | lport->tt.rport_logoff(rdata); | 224 | lport->tt.rport_logoff(rdata); |
240 | } | 225 | } |
241 | fc_disc_single(disc, dp); | 226 | fc_disc_single(disc, dp); |
@@ -296,10 +281,8 @@ static void fc_disc_restart(struct fc_disc *disc) | |||
296 | 281 | ||
297 | FC_DISC_DBG(disc, "Restarting discovery\n"); | 282 | FC_DISC_DBG(disc, "Restarting discovery\n"); |
298 | 283 | ||
299 | list_for_each_entry_safe(rdata, next, &disc->rports, peers) { | 284 | list_for_each_entry_safe(rdata, next, &disc->rports, peers) |
300 | list_del(&rdata->peers); | ||
301 | lport->tt.rport_logoff(rdata); | 285 | lport->tt.rport_logoff(rdata); |
302 | } | ||
303 | 286 | ||
304 | disc->requested = 1; | 287 | disc->requested = 1; |
305 | if (!disc->pending) | 288 | if (!disc->pending) |
@@ -392,7 +375,6 @@ static int fc_disc_new_target(struct fc_disc *disc, | |||
392 | * assigned the same FCID. This should be rare. | 375 | * assigned the same FCID. This should be rare. |
393 | * Delete the old one and fall thru to re-create. | 376 | * Delete the old one and fall thru to re-create. |
394 | */ | 377 | */ |
395 | list_del(&rdata->peers); | ||
396 | lport->tt.rport_logoff(rdata); | 378 | lport->tt.rport_logoff(rdata); |
397 | rdata = NULL; | 379 | rdata = NULL; |
398 | } | 380 | } |
@@ -406,12 +388,13 @@ static int fc_disc_new_target(struct fc_disc *disc, | |||
406 | rdata = lport->tt.rport_create(lport, ids); | 388 | rdata = lport->tt.rport_create(lport, ids); |
407 | if (!rdata) | 389 | if (!rdata) |
408 | error = -ENOMEM; | 390 | error = -ENOMEM; |
391 | else | ||
392 | list_add_tail(&rdata->peers, | ||
393 | &disc->rports); | ||
409 | } | 394 | } |
410 | } | 395 | } |
411 | if (rdata) { | 396 | if (rdata) { |
412 | rdata->ops = &fc_disc_rport_ops; | 397 | rdata->ops = &fc_disc_rport_ops; |
413 | rdata->rp_state = RPORT_ST_INIT; | ||
414 | list_add_tail(&rdata->peers, &disc->rogue_rports); | ||
415 | lport->tt.rport_login(rdata); | 398 | lport->tt.rport_login(rdata); |
416 | } | 399 | } |
417 | } | 400 | } |
@@ -585,9 +568,7 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) | |||
585 | rdata = lport->tt.rport_create(lport, &ids); | 568 | rdata = lport->tt.rport_create(lport, &ids); |
586 | if (rdata) { | 569 | if (rdata) { |
587 | rdata->ops = &fc_disc_rport_ops; | 570 | rdata->ops = &fc_disc_rport_ops; |
588 | rdata->local_port = lport; | 571 | list_add_tail(&rdata->peers, &disc->rports); |
589 | list_add_tail(&rdata->peers, | ||
590 | &disc->rogue_rports); | ||
591 | lport->tt.rport_login(rdata); | 572 | lport->tt.rport_login(rdata); |
592 | } else | 573 | } else |
593 | printk(KERN_WARNING "libfc: Failed to allocate " | 574 | printk(KERN_WARNING "libfc: Failed to allocate " |
@@ -736,7 +717,7 @@ static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp) | |||
736 | if (rdata) { | 717 | if (rdata) { |
737 | rdata->ops = &fc_disc_rport_ops; | 718 | rdata->ops = &fc_disc_rport_ops; |
738 | kfree(dp); | 719 | kfree(dp); |
739 | list_add_tail(&rdata->peers, &disc->rogue_rports); | 720 | list_add_tail(&rdata->peers, &disc->rports); |
740 | lport->tt.rport_login(rdata); | 721 | lport->tt.rport_login(rdata); |
741 | } | 722 | } |
742 | return; | 723 | return; |
@@ -798,7 +779,6 @@ int fc_disc_init(struct fc_lport *lport) | |||
798 | INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout); | 779 | INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout); |
799 | mutex_init(&disc->disc_mutex); | 780 | mutex_init(&disc->disc_mutex); |
800 | INIT_LIST_HEAD(&disc->rports); | 781 | INIT_LIST_HEAD(&disc->rports); |
801 | INIT_LIST_HEAD(&disc->rogue_rports); | ||
802 | 782 | ||
803 | disc->lport = lport; | 783 | disc->lport = lport; |
804 | disc->delay = FC_DISC_DELAY; | 784 | disc->delay = FC_DISC_DELAY; |