diff options
author | Robert Love <robert.w.love@intel.com> | 2009-08-25 17:02:59 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-10 13:07:57 -0400 |
commit | 9737e6a7b5b8af48f983cd565df93493597c565b (patch) | |
tree | 2bb3e50171af1fbc18d0f739d760b6218031fb31 /drivers/scsi | |
parent | 935d0fce44b906268b8a29de4e72ebb57a3a06d8 (diff) |
[SCSI] libfc: Initialize fc_rport_identifiers inside fc_rport_create
Currently these values are initialized by the callers. This was exposed
by a later patch that adds PLOGI request support. The patch failed to
initialize the new remote port's roles and it caused problems. This patch
has the rport_create routine initialize the identifiers and then the
callers can override them with real values.
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/libfc/fc_disc.c | 20 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 19 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 18 |
3 files changed, 23 insertions, 34 deletions
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 1a699f484c85..4242894cce7c 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c | |||
@@ -137,10 +137,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, | |||
137 | break; | 137 | break; |
138 | } | 138 | } |
139 | dp->lp = lport; | 139 | dp->lp = lport; |
140 | dp->ids.port_id = ntoh24(pp->rscn_fid); | 140 | dp->port_id = ntoh24(pp->rscn_fid); |
141 | dp->ids.port_name = -1; | ||
142 | dp->ids.node_name = -1; | ||
143 | dp->ids.roles = FC_RPORT_ROLE_UNKNOWN; | ||
144 | list_add_tail(&dp->peers, &disc_ports); | 141 | list_add_tail(&dp->peers, &disc_ports); |
145 | break; | 142 | break; |
146 | case ELS_ADDR_FMT_AREA: | 143 | case ELS_ADDR_FMT_AREA: |
@@ -162,7 +159,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, | |||
162 | redisc, lport->state, disc->pending); | 159 | redisc, lport->state, disc->pending); |
163 | list_for_each_entry_safe(dp, next, &disc_ports, peers) { | 160 | list_for_each_entry_safe(dp, next, &disc_ports, peers) { |
164 | list_del(&dp->peers); | 161 | list_del(&dp->peers); |
165 | rdata = lport->tt.rport_lookup(lport, dp->ids.port_id); | 162 | rdata = lport->tt.rport_lookup(lport, dp->port_id); |
166 | if (rdata) { | 163 | if (rdata) { |
167 | lport->tt.rport_logoff(rdata); | 164 | lport->tt.rport_logoff(rdata); |
168 | } | 165 | } |
@@ -435,15 +432,14 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) | |||
435 | while (plen >= sizeof(*np)) { | 432 | while (plen >= sizeof(*np)) { |
436 | ids.port_id = ntoh24(np->fp_fid); | 433 | ids.port_id = ntoh24(np->fp_fid); |
437 | ids.port_name = ntohll(np->fp_wwpn); | 434 | ids.port_name = ntohll(np->fp_wwpn); |
438 | ids.node_name = -1; | ||
439 | ids.roles = FC_RPORT_ROLE_UNKNOWN; | ||
440 | 435 | ||
441 | if (ids.port_id != fc_host_port_id(lport->host) && | 436 | if (ids.port_id != fc_host_port_id(lport->host) && |
442 | ids.port_name != lport->wwpn) { | 437 | ids.port_name != lport->wwpn) { |
443 | rdata = lport->tt.rport_create(lport, &ids); | 438 | rdata = lport->tt.rport_create(lport, ids.port_id); |
444 | if (rdata) | 439 | if (rdata) { |
440 | rdata->ids.port_name = ids.port_name; | ||
445 | rdata->disc_id = disc->disc_id; | 441 | rdata->disc_id = disc->disc_id; |
446 | else { | 442 | } else { |
447 | printk(KERN_WARNING "libfc: Failed to allocate " | 443 | printk(KERN_WARNING "libfc: Failed to allocate " |
448 | "memory for the newly discovered port " | 444 | "memory for the newly discovered port " |
449 | "(%6x)\n", ids.port_id); | 445 | "(%6x)\n", ids.port_id); |
@@ -580,10 +576,10 @@ static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp) | |||
580 | 576 | ||
581 | lport = disc->lport; | 577 | lport = disc->lport; |
582 | 578 | ||
583 | if (dp->ids.port_id == fc_host_port_id(lport->host)) | 579 | if (dp->port_id == fc_host_port_id(lport->host)) |
584 | goto out; | 580 | goto out; |
585 | 581 | ||
586 | rdata = lport->tt.rport_create(lport, &dp->ids); | 582 | rdata = lport->tt.rport_create(lport, dp->port_id); |
587 | if (rdata) { | 583 | if (rdata) { |
588 | rdata->disc_id = disc->disc_id; | 584 | rdata->disc_id = disc->disc_id; |
589 | kfree(dp); | 585 | kfree(dp); |
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 7000df573691..caf68240bddf 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c | |||
@@ -198,17 +198,12 @@ static void fc_lport_ptp_setup(struct fc_lport *lport, | |||
198 | u32 remote_fid, u64 remote_wwpn, | 198 | u32 remote_fid, u64 remote_wwpn, |
199 | u64 remote_wwnn) | 199 | u64 remote_wwnn) |
200 | { | 200 | { |
201 | struct fc_rport_identifiers ids; | ||
202 | |||
203 | ids.port_id = remote_fid; | ||
204 | ids.port_name = remote_wwpn; | ||
205 | ids.node_name = remote_wwnn; | ||
206 | ids.roles = FC_RPORT_ROLE_UNKNOWN; | ||
207 | |||
208 | mutex_lock(&lport->disc.disc_mutex); | 201 | mutex_lock(&lport->disc.disc_mutex); |
209 | if (lport->ptp_rp) | 202 | if (lport->ptp_rp) |
210 | lport->tt.rport_logoff(lport->ptp_rp); | 203 | lport->tt.rport_logoff(lport->ptp_rp); |
211 | lport->ptp_rp = lport->tt.rport_create(lport, &ids); | 204 | lport->ptp_rp = lport->tt.rport_create(lport, remote_fid); |
205 | lport->ptp_rp->ids.port_name = remote_wwpn; | ||
206 | lport->ptp_rp->ids.node_name = remote_wwnn; | ||
212 | mutex_unlock(&lport->disc.disc_mutex); | 207 | mutex_unlock(&lport->disc.disc_mutex); |
213 | 208 | ||
214 | lport->tt.rport_login(lport->ptp_rp); | 209 | lport->tt.rport_login(lport->ptp_rp); |
@@ -1287,12 +1282,6 @@ static struct fc_rport_operations fc_lport_rport_ops = { | |||
1287 | static void fc_lport_enter_dns(struct fc_lport *lport) | 1282 | static void fc_lport_enter_dns(struct fc_lport *lport) |
1288 | { | 1283 | { |
1289 | struct fc_rport_priv *rdata; | 1284 | struct fc_rport_priv *rdata; |
1290 | struct fc_rport_identifiers ids; | ||
1291 | |||
1292 | ids.port_id = FC_FID_DIR_SERV; | ||
1293 | ids.port_name = -1; | ||
1294 | ids.node_name = -1; | ||
1295 | ids.roles = FC_RPORT_ROLE_UNKNOWN; | ||
1296 | 1285 | ||
1297 | FC_LPORT_DBG(lport, "Entered DNS state from %s state\n", | 1286 | FC_LPORT_DBG(lport, "Entered DNS state from %s state\n", |
1298 | fc_lport_state(lport)); | 1287 | fc_lport_state(lport)); |
@@ -1300,7 +1289,7 @@ static void fc_lport_enter_dns(struct fc_lport *lport) | |||
1300 | fc_lport_state_enter(lport, LPORT_ST_DNS); | 1289 | fc_lport_state_enter(lport, LPORT_ST_DNS); |
1301 | 1290 | ||
1302 | mutex_lock(&lport->disc.disc_mutex); | 1291 | mutex_lock(&lport->disc.disc_mutex); |
1303 | rdata = lport->tt.rport_create(lport, &ids); | 1292 | rdata = lport->tt.rport_create(lport, FC_FID_DIR_SERV); |
1304 | mutex_unlock(&lport->disc.disc_mutex); | 1293 | mutex_unlock(&lport->disc.disc_mutex); |
1305 | if (!rdata) | 1294 | if (!rdata) |
1306 | goto err; | 1295 | goto err; |
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 99ac056293f5..c667be879be6 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c | |||
@@ -104,18 +104,18 @@ static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport, | |||
104 | } | 104 | } |
105 | 105 | ||
106 | /** | 106 | /** |
107 | * fc_rport_create() - create remote port in INIT state. | 107 | * fc_rport_create() - Create a new remote port |
108 | * @lport: local port. | 108 | * @lport: The local port that the new remote port is for |
109 | * @ids: remote port identifiers. | 109 | * @port_id: The port ID for the new remote port |
110 | * | 110 | * |
111 | * Locking note: must be called with the disc_mutex held. | 111 | * Locking note: must be called with the disc_mutex held. |
112 | */ | 112 | */ |
113 | static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, | 113 | static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, |
114 | struct fc_rport_identifiers *ids) | 114 | u32 port_id) |
115 | { | 115 | { |
116 | struct fc_rport_priv *rdata; | 116 | struct fc_rport_priv *rdata; |
117 | 117 | ||
118 | rdata = lport->tt.rport_lookup(lport, ids->port_id); | 118 | rdata = lport->tt.rport_lookup(lport, port_id); |
119 | if (rdata) | 119 | if (rdata) |
120 | return rdata; | 120 | return rdata; |
121 | 121 | ||
@@ -123,7 +123,11 @@ static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, | |||
123 | if (!rdata) | 123 | if (!rdata) |
124 | return NULL; | 124 | return NULL; |
125 | 125 | ||
126 | rdata->ids = *ids; | 126 | rdata->ids.node_name = -1; |
127 | rdata->ids.port_name = -1; | ||
128 | rdata->ids.port_id = port_id; | ||
129 | rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN; | ||
130 | |||
127 | kref_init(&rdata->kref); | 131 | kref_init(&rdata->kref); |
128 | mutex_init(&rdata->rp_mutex); | 132 | mutex_init(&rdata->rp_mutex); |
129 | rdata->local_port = lport; | 133 | rdata->local_port = lport; |
@@ -135,7 +139,7 @@ static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, | |||
135 | rdata->maxframe_size = FC_MIN_MAX_PAYLOAD; | 139 | rdata->maxframe_size = FC_MIN_MAX_PAYLOAD; |
136 | INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout); | 140 | INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout); |
137 | INIT_WORK(&rdata->event_work, fc_rport_work); | 141 | INIT_WORK(&rdata->event_work, fc_rport_work); |
138 | if (ids->port_id != FC_FID_DIR_SERV) | 142 | if (port_id != FC_FID_DIR_SERV) |
139 | list_add(&rdata->peers, &lport->disc.rports); | 143 | list_add(&rdata->peers, &lport->disc.rports); |
140 | return rdata; | 144 | return rdata; |
141 | } | 145 | } |