aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc/fc_disc.c
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2009-08-25 17:00:50 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-10 13:07:41 -0400
commit9fb9d32831fd687e427ec5b147bb690f468b99a0 (patch)
treec3b6c29cb94040718ea2fe00daac05abf10db714 /drivers/scsi/libfc/fc_disc.c
parent922aa210bcad4b34a7bb98ec9d318b7e59e7a5ca (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.c95
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 *);
49static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *); 49static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *);
50static int fc_disc_new_target(struct fc_disc *, struct fc_rport *, 50static int fc_disc_new_target(struct fc_disc *, struct fc_rport *,
51 struct fc_rport_identifiers *); 51 struct fc_rport_identifiers *);
52static void fc_disc_del_target(struct fc_disc *, struct fc_rport *);
53static void fc_disc_done(struct fc_disc *); 52static void fc_disc_done(struct fc_disc *);
54static void fc_disc_timeout(struct work_struct *); 53static void fc_disc_timeout(struct work_struct *);
55static void fc_disc_single(struct fc_disc *, struct fc_disc_port *); 54static 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 */
63struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport, 62struct 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,
93void fc_disc_stop_rports(struct fc_disc *disc) 84void 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 */
125static void fc_disc_rport_callback(struct fc_lport *lport, 113static 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 */
309static void fc_disc_restart(struct fc_disc *disc) 295static 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 */
452static 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,
766static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp) 741static 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;
786out: 759out: