aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2009-08-25 17:01:01 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-10 13:07:42 -0400
commitf211fa514a07326c0f9364c0e6ed17e38860172f (patch)
tree9c2c54fee556816f36211185b6d6df0812b9acec
parenta46f327aa5caf2cce138e98ddd863b6cca0e71e2 (diff)
[SCSI] libfc: make rport structure optional
Allow a struct fc_rport_priv to have no fc_rport associated with it. This sets up to remove the need for "rogue" rports. Add a few fields to fc_rport_priv that are needed before the fc_rport is created. These are the ids, maxframe_size, classes, and rport pointer. Remove the macro PRIV_TO_RPORT(). Just use rdata->rport where appropriate. To take the place of the get_device()/put_device ops that were used to hold both the rport and rdata, add a reference count to rdata structures using kref. When kref_get decrements the refcount to zero, a new template function releasing the rdata should be called. This will take care of freeing the rdata and releasing the hold on the rport (for now). After subsequent patches make the rport truly optional, this release function will simply free the rdata. Remove the simple inline function fc_rport_set_name(), which becomes semanticly ambiguous otherwise. The caller will set the port_name and node_name in the rdata->Ids, which will later be copied to the rport when it its created. 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>
-rw-r--r--drivers/scsi/libfc/fc_disc.c54
-rw-r--r--drivers/scsi/libfc/fc_lport.c14
-rw-r--r--drivers/scsi/libfc/fc_rport.c102
-rw-r--r--include/scsi/libfc.h29
4 files changed, 98 insertions, 101 deletions
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index 4b1f9faf639a..5f839b625e50 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -47,7 +47,7 @@
47 47
48static void fc_disc_gpn_ft_req(struct fc_disc *); 48static 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_priv *,
51 struct fc_rport_identifiers *); 51 struct fc_rport_identifiers *);
52static void fc_disc_done(struct fc_disc *); 52static void fc_disc_done(struct fc_disc *);
53static void fc_disc_timeout(struct work_struct *); 53static void fc_disc_timeout(struct work_struct *);
@@ -63,12 +63,10 @@ struct fc_rport_priv *fc_disc_lookup_rport(const struct fc_lport *lport,
63 u32 port_id) 63 u32 port_id)
64{ 64{
65 const struct fc_disc *disc = &lport->disc; 65 const struct fc_disc *disc = &lport->disc;
66 struct fc_rport *rport;
67 struct fc_rport_priv *rdata; 66 struct fc_rport_priv *rdata;
68 67
69 list_for_each_entry(rdata, &disc->rports, peers) { 68 list_for_each_entry(rdata, &disc->rports, peers) {
70 rport = PRIV_TO_RPORT(rdata); 69 if (rdata->ids.port_id == port_id)
71 if (rport->port_id == port_id)
72 return rdata; 70 return rdata;
73 } 71 }
74 return NULL; 72 return NULL;
@@ -115,10 +113,9 @@ static void fc_disc_rport_callback(struct fc_lport *lport,
115 enum fc_rport_event event) 113 enum fc_rport_event event)
116{ 114{
117 struct fc_disc *disc = &lport->disc; 115 struct fc_disc *disc = &lport->disc;
118 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
119 116
120 FC_DISC_DBG(disc, "Received a %d event for port (%6x)\n", event, 117 FC_DISC_DBG(disc, "Received a %d event for port (%6x)\n", event,
121 rport->port_id); 118 rdata->ids.port_id);
122 119
123 switch (event) { 120 switch (event) {
124 case RPORT_EV_CREATED: 121 case RPORT_EV_CREATED:
@@ -320,8 +317,6 @@ static void fc_disc_start(void (*disc_callback)(struct fc_lport *,
320 struct fc_lport *lport) 317 struct fc_lport *lport)
321{ 318{
322 struct fc_rport_priv *rdata; 319 struct fc_rport_priv *rdata;
323 struct fc_rport *rport;
324 struct fc_rport_identifiers ids;
325 struct fc_disc *disc = &lport->disc; 320 struct fc_disc *disc = &lport->disc;
326 321
327 /* 322 /*
@@ -349,18 +344,12 @@ static void fc_disc_start(void (*disc_callback)(struct fc_lport *,
349 */ 344 */
350 rdata = disc->lport->ptp_rp; 345 rdata = disc->lport->ptp_rp;
351 if (rdata) { 346 if (rdata) {
352 rport = PRIV_TO_RPORT(rdata); 347 kref_get(&rdata->kref);
353 ids.port_id = rport->port_id; 348 if (!fc_disc_new_target(disc, rdata, &rdata->ids)) {
354 ids.port_name = rport->port_name;
355 ids.node_name = rport->node_name;
356 ids.roles = FC_RPORT_ROLE_UNKNOWN;
357 get_device(&rport->dev);
358
359 if (!fc_disc_new_target(disc, rport, &ids)) {
360 disc->event = DISC_EV_SUCCESS; 349 disc->event = DISC_EV_SUCCESS;
361 fc_disc_done(disc); 350 fc_disc_done(disc);
362 } 351 }
363 put_device(&rport->dev); 352 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
364 } else { 353 } else {
365 fc_disc_gpn_ft_req(disc); /* get ports by FC-4 type */ 354 fc_disc_gpn_ft_req(disc); /* get ports by FC-4 type */
366 } 355 }
@@ -375,28 +364,27 @@ static struct fc_rport_operations fc_disc_rport_ops = {
375/** 364/**
376 * fc_disc_new_target() - Handle new target found by discovery 365 * fc_disc_new_target() - Handle new target found by discovery
377 * @lport: FC local port 366 * @lport: FC local port
378 * @rport: The previous FC remote port (NULL if new remote port) 367 * @rdata: The previous FC remote port priv (NULL if new remote port)
379 * @ids: Identifiers for the new FC remote port 368 * @ids: Identifiers for the new FC remote port
380 * 369 *
381 * Locking Note: This function expects that the disc_mutex is locked 370 * Locking Note: This function expects that the disc_mutex is locked
382 * before it is called. 371 * before it is called.
383 */ 372 */
384static int fc_disc_new_target(struct fc_disc *disc, 373static int fc_disc_new_target(struct fc_disc *disc,
385 struct fc_rport *rport, 374 struct fc_rport_priv *rdata,
386 struct fc_rport_identifiers *ids) 375 struct fc_rport_identifiers *ids)
387{ 376{
388 struct fc_lport *lport = disc->lport; 377 struct fc_lport *lport = disc->lport;
389 struct fc_rport_priv *rdata;
390 int error = 0; 378 int error = 0;
391 379
392 if (rport && ids->port_name) { 380 if (rdata && ids->port_name) {
393 if (rport->port_name == -1) { 381 if (rdata->ids.port_name == -1) {
394 /* 382 /*
395 * Set WWN and fall through to notify of create. 383 * Set WWN and fall through to notify of create.
396 */ 384 */
397 fc_rport_set_name(rport, ids->port_name, 385 rdata->ids.port_name = ids->port_name;
398 rport->node_name); 386 rdata->ids.node_name = ids->node_name;
399 } else if (rport->port_name != ids->port_name) { 387 } else if (rdata->ids.port_name != ids->port_name) {
400 /* 388 /*
401 * This is a new port with the same FCID as 389 * This is a new port with the same FCID as
402 * a previously-discovered port. Presumably the old 390 * a previously-discovered port. Presumably the old
@@ -404,27 +392,23 @@ static int fc_disc_new_target(struct fc_disc *disc,
404 * assigned the same FCID. This should be rare. 392 * assigned the same FCID. This should be rare.
405 * Delete the old one and fall thru to re-create. 393 * Delete the old one and fall thru to re-create.
406 */ 394 */
407 rdata = rport->dd_data;
408 list_del(&rdata->peers); 395 list_del(&rdata->peers);
409 lport->tt.rport_logoff(rdata); 396 lport->tt.rport_logoff(rdata);
410 rport = NULL; 397 rdata = NULL;
411 } 398 }
412 } 399 }
413 if (((ids->port_name != -1) || (ids->port_id != -1)) && 400 if (((ids->port_name != -1) || (ids->port_id != -1)) &&
414 ids->port_id != fc_host_port_id(lport->host) && 401 ids->port_id != fc_host_port_id(lport->host) &&
415 ids->port_name != lport->wwpn) { 402 ids->port_name != lport->wwpn) {
416 if (!rport) { 403 if (!rdata) {
417 rdata = lport->tt.rport_lookup(lport, ids->port_id); 404 rdata = lport->tt.rport_lookup(lport, ids->port_id);
418 if (!rport) { 405 if (!rdata) {
419 rdata = lport->tt.rport_create(lport, ids); 406 rdata = lport->tt.rport_create(lport, ids);
407 if (!rdata)
408 error = -ENOMEM;
420 } 409 }
421 if (!rdata)
422 error = -ENOMEM;
423 else
424 rport = PRIV_TO_RPORT(rdata);
425 } 410 }
426 if (rport) { 411 if (rdata) {
427 rdata = rport->dd_data;
428 rdata->ops = &fc_disc_rport_ops; 412 rdata->ops = &fc_disc_rport_ops;
429 rdata->rp_state = RPORT_ST_INIT; 413 rdata->rp_state = RPORT_ST_INIT;
430 list_add_tail(&rdata->peers, &disc->rogue_rports); 414 list_add_tail(&rdata->peers, &disc->rogue_rports);
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index aa605d2012e0..a7fe6b8d38b8 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -143,14 +143,12 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
143 struct fc_rport_priv *rdata, 143 struct fc_rport_priv *rdata,
144 enum fc_rport_event event) 144 enum fc_rport_event event)
145{ 145{
146 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
147
148 FC_LPORT_DBG(lport, "Received a %d event for port (%6x)\n", event, 146 FC_LPORT_DBG(lport, "Received a %d event for port (%6x)\n", event,
149 rport->port_id); 147 rdata->ids.port_id);
150 148
151 switch (event) { 149 switch (event) {
152 case RPORT_EV_CREATED: 150 case RPORT_EV_CREATED:
153 if (rport->port_id == FC_FID_DIR_SERV) { 151 if (rdata->ids.port_id == FC_FID_DIR_SERV) {
154 mutex_lock(&lport->lp_mutex); 152 mutex_lock(&lport->lp_mutex);
155 if (lport->state == LPORT_ST_DNS) { 153 if (lport->state == LPORT_ST_DNS) {
156 lport->dns_rp = rdata; 154 lport->dns_rp = rdata;
@@ -160,7 +158,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
160 "on port (%6x) for the directory " 158 "on port (%6x) for the directory "
161 "server, but the lport is not " 159 "server, but the lport is not "
162 "in the DNS state, it's in the " 160 "in the DNS state, it's in the "
163 "%d state", rport->port_id, 161 "%d state", rdata->ids.port_id,
164 lport->state); 162 lport->state);
165 lport->tt.rport_logoff(rdata); 163 lport->tt.rport_logoff(rdata);
166 } 164 }
@@ -168,12 +166,12 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
168 } else 166 } else
169 FC_LPORT_DBG(lport, "Received an event for port (%6x) " 167 FC_LPORT_DBG(lport, "Received an event for port (%6x) "
170 "which is not the directory server\n", 168 "which is not the directory server\n",
171 rport->port_id); 169 rdata->ids.port_id);
172 break; 170 break;
173 case RPORT_EV_LOGO: 171 case RPORT_EV_LOGO:
174 case RPORT_EV_FAILED: 172 case RPORT_EV_FAILED:
175 case RPORT_EV_STOP: 173 case RPORT_EV_STOP:
176 if (rport->port_id == FC_FID_DIR_SERV) { 174 if (rdata->ids.port_id == FC_FID_DIR_SERV) {
177 mutex_lock(&lport->lp_mutex); 175 mutex_lock(&lport->lp_mutex);
178 lport->dns_rp = NULL; 176 lport->dns_rp = NULL;
179 mutex_unlock(&lport->lp_mutex); 177 mutex_unlock(&lport->lp_mutex);
@@ -181,7 +179,7 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
181 } else 179 } else
182 FC_LPORT_DBG(lport, "Received an event for port (%6x) " 180 FC_LPORT_DBG(lport, "Received an event for port (%6x) "
183 "which is not the directory server\n", 181 "which is not the directory server\n",
184 rport->port_id); 182 rdata->ids.port_id);
185 break; 183 break;
186 case RPORT_EV_NONE: 184 case RPORT_EV_NONE:
187 break; 185 break;
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 20371b445bb1..69f6e588d37b 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -120,7 +120,10 @@ struct fc_rport_priv *fc_rport_rogue_create(struct fc_lport *lport,
120 device_initialize(&rport->dev); 120 device_initialize(&rport->dev);
121 rport->dev.release = fc_rport_rogue_destroy; 121 rport->dev.release = fc_rport_rogue_destroy;
122 122
123 rdata->ids = *ids;
124 kref_init(&rdata->kref);
123 mutex_init(&rdata->rp_mutex); 125 mutex_init(&rdata->rp_mutex);
126 rdata->rport = rport;
124 rdata->local_port = lport; 127 rdata->local_port = lport;
125 rdata->trans_state = FC_PORTSTATE_ROGUE; 128 rdata->trans_state = FC_PORTSTATE_ROGUE;
126 rdata->rp_state = RPORT_ST_INIT; 129 rdata->rp_state = RPORT_ST_INIT;
@@ -129,6 +132,7 @@ struct fc_rport_priv *fc_rport_rogue_create(struct fc_lport *lport,
129 rdata->ops = NULL; 132 rdata->ops = NULL;
130 rdata->e_d_tov = lport->e_d_tov; 133 rdata->e_d_tov = lport->e_d_tov;
131 rdata->r_a_tov = lport->r_a_tov; 134 rdata->r_a_tov = lport->r_a_tov;
135 rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;
132 INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout); 136 INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);
133 INIT_WORK(&rdata->event_work, fc_rport_work); 137 INIT_WORK(&rdata->event_work, fc_rport_work);
134 /* 138 /*
@@ -141,6 +145,20 @@ struct fc_rport_priv *fc_rport_rogue_create(struct fc_lport *lport,
141} 145}
142 146
143/** 147/**
148 * fc_rport_destroy() - free a remote port after last reference is released.
149 * @kref: pointer to kref inside struct fc_rport_priv
150 */
151static void fc_rport_destroy(struct kref *kref)
152{
153 struct fc_rport_priv *rdata;
154 struct fc_rport *rport;
155
156 rdata = container_of(kref, struct fc_rport_priv, kref);
157 rport = rdata->rport;
158 put_device(&rport->dev);
159}
160
161/**
144 * fc_rport_state() - return a string for the state the rport is in 162 * fc_rport_state() - return a string for the state the rport is in
145 * @rdata: remote port private data 163 * @rdata: remote port private data
146 */ 164 */
@@ -215,22 +233,19 @@ static void fc_rport_work(struct work_struct *work)
215 enum fc_rport_trans_state trans_state; 233 enum fc_rport_trans_state trans_state;
216 struct fc_lport *lport = rdata->local_port; 234 struct fc_lport *lport = rdata->local_port;
217 struct fc_rport_operations *rport_ops; 235 struct fc_rport_operations *rport_ops;
218 struct fc_rport *rport = PRIV_TO_RPORT(rdata); 236 struct fc_rport *rport;
219 237
220 mutex_lock(&rdata->rp_mutex); 238 mutex_lock(&rdata->rp_mutex);
221 event = rdata->event; 239 event = rdata->event;
222 rport_ops = rdata->ops; 240 rport_ops = rdata->ops;
241 rport = rdata->rport;
223 242
224 if (event == RPORT_EV_CREATED) { 243 if (event == RPORT_EV_CREATED) {
225 struct fc_rport *new_rport; 244 struct fc_rport *new_rport;
226 struct fc_rport_priv *new_rdata; 245 struct fc_rport_priv *new_rdata;
227 struct fc_rport_identifiers ids; 246 struct fc_rport_identifiers ids;
228 247
229 ids.port_id = rport->port_id; 248 ids = rdata->ids;
230 ids.roles = rport->roles;
231 ids.port_name = rport->port_name;
232 ids.node_name = rport->node_name;
233
234 rdata->event = RPORT_EV_NONE; 249 rdata->event = RPORT_EV_NONE;
235 mutex_unlock(&rdata->rp_mutex); 250 mutex_unlock(&rdata->rp_mutex);
236 251
@@ -240,15 +255,20 @@ static void fc_rport_work(struct work_struct *work)
240 * Switch from the rogue rport to the rport 255 * Switch from the rogue rport to the rport
241 * returned by the FC class. 256 * returned by the FC class.
242 */ 257 */
243 new_rport->maxframe_size = rport->maxframe_size; 258 new_rport->maxframe_size = rdata->maxframe_size;
244 259
245 new_rdata = new_rport->dd_data; 260 new_rdata = new_rport->dd_data;
261 new_rdata->rport = new_rport;
262 new_rdata->ids = ids;
246 new_rdata->e_d_tov = rdata->e_d_tov; 263 new_rdata->e_d_tov = rdata->e_d_tov;
247 new_rdata->r_a_tov = rdata->r_a_tov; 264 new_rdata->r_a_tov = rdata->r_a_tov;
248 new_rdata->ops = rdata->ops; 265 new_rdata->ops = rdata->ops;
249 new_rdata->local_port = rdata->local_port; 266 new_rdata->local_port = rdata->local_port;
250 new_rdata->flags = FC_RP_FLAGS_REC_SUPPORTED; 267 new_rdata->flags = FC_RP_FLAGS_REC_SUPPORTED;
251 new_rdata->trans_state = FC_PORTSTATE_REAL; 268 new_rdata->trans_state = FC_PORTSTATE_REAL;
269 new_rdata->maxframe_size = rdata->maxframe_size;
270 new_rdata->supported_classes = rdata->supported_classes;
271 kref_init(&new_rdata->kref);
252 mutex_init(&new_rdata->rp_mutex); 272 mutex_init(&new_rdata->rp_mutex);
253 INIT_DELAYED_WORK(&new_rdata->retry_work, 273 INIT_DELAYED_WORK(&new_rdata->retry_work,
254 fc_rport_timeout); 274 fc_rport_timeout);
@@ -261,12 +281,11 @@ static void fc_rport_work(struct work_struct *work)
261 " memory for rport (%6x)\n", ids.port_id); 281 " memory for rport (%6x)\n", ids.port_id);
262 event = RPORT_EV_FAILED; 282 event = RPORT_EV_FAILED;
263 } 283 }
264 if (rport->port_id != FC_FID_DIR_SERV) 284 if (rdata->ids.port_id != FC_FID_DIR_SERV)
265 if (rport_ops->event_callback) 285 if (rport_ops->event_callback)
266 rport_ops->event_callback(lport, rdata, 286 rport_ops->event_callback(lport, rdata,
267 RPORT_EV_FAILED); 287 RPORT_EV_FAILED);
268 put_device(&rport->dev); 288 kref_put(&rdata->kref, lport->tt.rport_destroy);
269 rport = new_rport;
270 rdata = new_rport->dd_data; 289 rdata = new_rport->dd_data;
271 if (rport_ops->event_callback) 290 if (rport_ops->event_callback)
272 rport_ops->event_callback(lport, rdata, event); 291 rport_ops->event_callback(lport, rdata, event);
@@ -279,7 +298,7 @@ static void fc_rport_work(struct work_struct *work)
279 rport_ops->event_callback(lport, rdata, event); 298 rport_ops->event_callback(lport, rdata, event);
280 cancel_delayed_work_sync(&rdata->retry_work); 299 cancel_delayed_work_sync(&rdata->retry_work);
281 if (trans_state == FC_PORTSTATE_ROGUE) 300 if (trans_state == FC_PORTSTATE_ROGUE)
282 put_device(&rport->dev); 301 kref_put(&rdata->kref, lport->tt.rport_destroy);
283 else { 302 else {
284 port_id = rport->port_id; 303 port_id = rport->port_id;
285 fc_remote_port_delete(rport); 304 fc_remote_port_delete(rport);
@@ -505,7 +524,6 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
505 void *rdata_arg) 524 void *rdata_arg)
506{ 525{
507 struct fc_rport_priv *rdata = rdata_arg; 526 struct fc_rport_priv *rdata = rdata_arg;
508 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
509 struct fc_lport *lport = rdata->local_port; 527 struct fc_lport *lport = rdata->local_port;
510 struct fc_els_flogi *plp = NULL; 528 struct fc_els_flogi *plp = NULL;
511 unsigned int tov; 529 unsigned int tov;
@@ -533,8 +551,8 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
533 op = fc_frame_payload_op(fp); 551 op = fc_frame_payload_op(fp);
534 if (op == ELS_LS_ACC && 552 if (op == ELS_LS_ACC &&
535 (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) { 553 (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) {
536 rport->port_name = get_unaligned_be64(&plp->fl_wwpn); 554 rdata->ids.port_name = get_unaligned_be64(&plp->fl_wwpn);
537 rport->node_name = get_unaligned_be64(&plp->fl_wwnn); 555 rdata->ids.node_name = get_unaligned_be64(&plp->fl_wwnn);
538 556
539 tov = ntohl(plp->fl_csp.sp_e_d_tov); 557 tov = ntohl(plp->fl_csp.sp_e_d_tov);
540 if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR) 558 if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR)
@@ -546,14 +564,13 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
546 if (cssp_seq < csp_seq) 564 if (cssp_seq < csp_seq)
547 csp_seq = cssp_seq; 565 csp_seq = cssp_seq;
548 rdata->max_seq = csp_seq; 566 rdata->max_seq = csp_seq;
549 rport->maxframe_size = 567 rdata->maxframe_size = fc_plogi_get_maxframe(plp, lport->mfs);
550 fc_plogi_get_maxframe(plp, lport->mfs);
551 568
552 /* 569 /*
553 * If the rport is one of the well known addresses 570 * If the rport is one of the well known addresses
554 * we skip PRLI and RTV and go straight to READY. 571 * we skip PRLI and RTV and go straight to READY.
555 */ 572 */
556 if (rport->port_id >= FC_FID_DOM_MGR) 573 if (rdata->ids.port_id >= FC_FID_DOM_MGR)
557 fc_rport_enter_ready(rdata); 574 fc_rport_enter_ready(rdata);
558 else 575 else
559 fc_rport_enter_prli(rdata); 576 fc_rport_enter_prli(rdata);
@@ -564,7 +581,7 @@ out:
564 fc_frame_free(fp); 581 fc_frame_free(fp);
565err: 582err:
566 mutex_unlock(&rdata->rp_mutex); 583 mutex_unlock(&rdata->rp_mutex);
567 put_device(&rport->dev); 584 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
568} 585}
569 586
570/** 587/**
@@ -577,7 +594,6 @@ err:
577static void fc_rport_enter_plogi(struct fc_rport_priv *rdata) 594static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
578{ 595{
579 struct fc_lport *lport = rdata->local_port; 596 struct fc_lport *lport = rdata->local_port;
580 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
581 struct fc_frame *fp; 597 struct fc_frame *fp;
582 598
583 FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n", 599 FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n",
@@ -585,7 +601,7 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
585 601
586 fc_rport_state_enter(rdata, RPORT_ST_PLOGI); 602 fc_rport_state_enter(rdata, RPORT_ST_PLOGI);
587 603
588 rport->maxframe_size = FC_MIN_MAX_PAYLOAD; 604 rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;
589 fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi)); 605 fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
590 if (!fp) { 606 if (!fp) {
591 fc_rport_error_retry(rdata, fp); 607 fc_rport_error_retry(rdata, fp);
@@ -593,11 +609,11 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
593 } 609 }
594 rdata->e_d_tov = lport->e_d_tov; 610 rdata->e_d_tov = lport->e_d_tov;
595 611
596 if (!lport->tt.elsct_send(lport, rport->port_id, fp, ELS_PLOGI, 612 if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PLOGI,
597 fc_rport_plogi_resp, rdata, lport->e_d_tov)) 613 fc_rport_plogi_resp, rdata, lport->e_d_tov))
598 fc_rport_error_retry(rdata, fp); 614 fc_rport_error_retry(rdata, fp);
599 else 615 else
600 get_device(&rport->dev); 616 kref_get(&rdata->kref);
601} 617}
602 618
603/** 619/**
@@ -614,7 +630,6 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
614 void *rdata_arg) 630 void *rdata_arg)
615{ 631{
616 struct fc_rport_priv *rdata = rdata_arg; 632 struct fc_rport_priv *rdata = rdata_arg;
617 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
618 struct { 633 struct {
619 struct fc_els_prli prli; 634 struct fc_els_prli prli;
620 struct fc_els_spp spp; 635 struct fc_els_spp spp;
@@ -649,13 +664,13 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
649 rdata->flags |= FC_RP_FLAGS_RETRY; 664 rdata->flags |= FC_RP_FLAGS_RETRY;
650 } 665 }
651 666
652 rport->supported_classes = FC_COS_CLASS3; 667 rdata->supported_classes = FC_COS_CLASS3;
653 if (fcp_parm & FCP_SPPF_INIT_FCN) 668 if (fcp_parm & FCP_SPPF_INIT_FCN)
654 roles |= FC_RPORT_ROLE_FCP_INITIATOR; 669 roles |= FC_RPORT_ROLE_FCP_INITIATOR;
655 if (fcp_parm & FCP_SPPF_TARG_FCN) 670 if (fcp_parm & FCP_SPPF_TARG_FCN)
656 roles |= FC_RPORT_ROLE_FCP_TARGET; 671 roles |= FC_RPORT_ROLE_FCP_TARGET;
657 672
658 rport->roles = roles; 673 rdata->ids.roles = roles;
659 fc_rport_enter_rtv(rdata); 674 fc_rport_enter_rtv(rdata);
660 675
661 } else { 676 } else {
@@ -667,7 +682,7 @@ out:
667 fc_frame_free(fp); 682 fc_frame_free(fp);
668err: 683err:
669 mutex_unlock(&rdata->rp_mutex); 684 mutex_unlock(&rdata->rp_mutex);
670 put_device(&rport->dev); 685 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
671} 686}
672 687
673/** 688/**
@@ -684,7 +699,6 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
684 void *rdata_arg) 699 void *rdata_arg)
685{ 700{
686 struct fc_rport_priv *rdata = rdata_arg; 701 struct fc_rport_priv *rdata = rdata_arg;
687 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
688 u8 op; 702 u8 op;
689 703
690 mutex_lock(&rdata->rp_mutex); 704 mutex_lock(&rdata->rp_mutex);
@@ -716,7 +730,7 @@ out:
716 fc_frame_free(fp); 730 fc_frame_free(fp);
717err: 731err:
718 mutex_unlock(&rdata->rp_mutex); 732 mutex_unlock(&rdata->rp_mutex);
719 put_device(&rport->dev); 733 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
720} 734}
721 735
722/** 736/**
@@ -728,7 +742,6 @@ err:
728 */ 742 */
729static void fc_rport_enter_prli(struct fc_rport_priv *rdata) 743static void fc_rport_enter_prli(struct fc_rport_priv *rdata)
730{ 744{
731 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
732 struct fc_lport *lport = rdata->local_port; 745 struct fc_lport *lport = rdata->local_port;
733 struct { 746 struct {
734 struct fc_els_prli prli; 747 struct fc_els_prli prli;
@@ -747,11 +760,11 @@ static void fc_rport_enter_prli(struct fc_rport_priv *rdata)
747 return; 760 return;
748 } 761 }
749 762
750 if (!lport->tt.elsct_send(lport, rport->port_id, fp, ELS_PRLI, 763 if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PRLI,
751 fc_rport_prli_resp, rdata, lport->e_d_tov)) 764 fc_rport_prli_resp, rdata, lport->e_d_tov))
752 fc_rport_error_retry(rdata, fp); 765 fc_rport_error_retry(rdata, fp);
753 else 766 else
754 get_device(&rport->dev); 767 kref_get(&rdata->kref);
755} 768}
756 769
757/** 770/**
@@ -770,7 +783,6 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
770 void *rdata_arg) 783 void *rdata_arg)
771{ 784{
772 struct fc_rport_priv *rdata = rdata_arg; 785 struct fc_rport_priv *rdata = rdata_arg;
773 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
774 u8 op; 786 u8 op;
775 787
776 mutex_lock(&rdata->rp_mutex); 788 mutex_lock(&rdata->rp_mutex);
@@ -818,7 +830,7 @@ out:
818 fc_frame_free(fp); 830 fc_frame_free(fp);
819err: 831err:
820 mutex_unlock(&rdata->rp_mutex); 832 mutex_unlock(&rdata->rp_mutex);
821 put_device(&rport->dev); 833 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
822} 834}
823 835
824/** 836/**
@@ -832,7 +844,6 @@ static void fc_rport_enter_rtv(struct fc_rport_priv *rdata)
832{ 844{
833 struct fc_frame *fp; 845 struct fc_frame *fp;
834 struct fc_lport *lport = rdata->local_port; 846 struct fc_lport *lport = rdata->local_port;
835 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
836 847
837 FC_RPORT_DBG(rdata, "Port entered RTV state from %s state\n", 848 FC_RPORT_DBG(rdata, "Port entered RTV state from %s state\n",
838 fc_rport_state(rdata)); 849 fc_rport_state(rdata));
@@ -845,11 +856,11 @@ static void fc_rport_enter_rtv(struct fc_rport_priv *rdata)
845 return; 856 return;
846 } 857 }
847 858
848 if (!lport->tt.elsct_send(lport, rport->port_id, fp, ELS_RTV, 859 if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_RTV,
849 fc_rport_rtv_resp, rdata, lport->e_d_tov)) 860 fc_rport_rtv_resp, rdata, lport->e_d_tov))
850 fc_rport_error_retry(rdata, fp); 861 fc_rport_error_retry(rdata, fp);
851 else 862 else
852 get_device(&rport->dev); 863 kref_get(&rdata->kref);
853} 864}
854 865
855/** 866/**
@@ -862,7 +873,6 @@ static void fc_rport_enter_rtv(struct fc_rport_priv *rdata)
862static void fc_rport_enter_logo(struct fc_rport_priv *rdata) 873static void fc_rport_enter_logo(struct fc_rport_priv *rdata)
863{ 874{
864 struct fc_lport *lport = rdata->local_port; 875 struct fc_lport *lport = rdata->local_port;
865 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
866 struct fc_frame *fp; 876 struct fc_frame *fp;
867 877
868 FC_RPORT_DBG(rdata, "Port entered LOGO state from %s state\n", 878 FC_RPORT_DBG(rdata, "Port entered LOGO state from %s state\n",
@@ -876,11 +886,11 @@ static void fc_rport_enter_logo(struct fc_rport_priv *rdata)
876 return; 886 return;
877 } 887 }
878 888
879 if (!lport->tt.elsct_send(lport, rport->port_id, fp, ELS_LOGO, 889 if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_LOGO,
880 fc_rport_logo_resp, rdata, lport->e_d_tov)) 890 fc_rport_logo_resp, rdata, lport->e_d_tov))
881 fc_rport_error_retry(rdata, fp); 891 fc_rport_error_retry(rdata, fp);
882 else 892 else
883 get_device(&rport->dev); 893 kref_get(&rdata->kref);
884} 894}
885 895
886 896
@@ -956,7 +966,6 @@ void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp,
956static void fc_rport_recv_plogi_req(struct fc_rport_priv *rdata, 966static void fc_rport_recv_plogi_req(struct fc_rport_priv *rdata,
957 struct fc_seq *sp, struct fc_frame *rx_fp) 967 struct fc_seq *sp, struct fc_frame *rx_fp)
958{ 968{
959 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
960 struct fc_lport *lport = rdata->local_port; 969 struct fc_lport *lport = rdata->local_port;
961 struct fc_frame *fp = rx_fp; 970 struct fc_frame *fp = rx_fp;
962 struct fc_exch *ep; 971 struct fc_exch *ep;
@@ -1041,12 +1050,13 @@ static void fc_rport_recv_plogi_req(struct fc_rport_priv *rdata,
1041 } else { 1050 } else {
1042 sp = lport->tt.seq_start_next(sp); 1051 sp = lport->tt.seq_start_next(sp);
1043 WARN_ON(!sp); 1052 WARN_ON(!sp);
1044 fc_rport_set_name(rport, wwpn, wwnn); 1053 rdata->ids.port_name = wwpn;
1054 rdata->ids.node_name = wwnn;
1045 1055
1046 /* 1056 /*
1047 * Get session payload size from incoming PLOGI. 1057 * Get session payload size from incoming PLOGI.
1048 */ 1058 */
1049 rport->maxframe_size = 1059 rdata->maxframe_size =
1050 fc_plogi_get_maxframe(pl, lport->mfs); 1060 fc_plogi_get_maxframe(pl, lport->mfs);
1051 fc_frame_free(rx_fp); 1061 fc_frame_free(rx_fp);
1052 fc_plogi_fill(lport, fp, ELS_LS_ACC); 1062 fc_plogi_fill(lport, fp, ELS_LS_ACC);
@@ -1079,7 +1089,6 @@ static void fc_rport_recv_plogi_req(struct fc_rport_priv *rdata,
1079static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata, 1089static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
1080 struct fc_seq *sp, struct fc_frame *rx_fp) 1090 struct fc_seq *sp, struct fc_frame *rx_fp)
1081{ 1091{
1082 struct fc_rport *rport = PRIV_TO_RPORT(rdata);
1083 struct fc_lport *lport = rdata->local_port; 1092 struct fc_lport *lport = rdata->local_port;
1084 struct fc_exch *ep; 1093 struct fc_exch *ep;
1085 struct fc_frame *fp; 1094 struct fc_frame *fp;
@@ -1173,12 +1182,12 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
1173 fcp_parm = ntohl(rspp->spp_params); 1182 fcp_parm = ntohl(rspp->spp_params);
1174 if (fcp_parm * FCP_SPPF_RETRY) 1183 if (fcp_parm * FCP_SPPF_RETRY)
1175 rdata->flags |= FC_RP_FLAGS_RETRY; 1184 rdata->flags |= FC_RP_FLAGS_RETRY;
1176 rport->supported_classes = FC_COS_CLASS3; 1185 rdata->supported_classes = FC_COS_CLASS3;
1177 if (fcp_parm & FCP_SPPF_INIT_FCN) 1186 if (fcp_parm & FCP_SPPF_INIT_FCN)
1178 roles |= FC_RPORT_ROLE_FCP_INITIATOR; 1187 roles |= FC_RPORT_ROLE_FCP_INITIATOR;
1179 if (fcp_parm & FCP_SPPF_TARG_FCN) 1188 if (fcp_parm & FCP_SPPF_TARG_FCN)
1180 roles |= FC_RPORT_ROLE_FCP_TARGET; 1189 roles |= FC_RPORT_ROLE_FCP_TARGET;
1181 rport->roles = roles; 1190 rdata->ids.roles = roles;
1182 1191
1183 spp->spp_params = 1192 spp->spp_params =
1184 htonl(lport->service_params); 1193 htonl(lport->service_params);
@@ -1310,6 +1319,9 @@ int fc_rport_init(struct fc_lport *lport)
1310 if (!lport->tt.rport_flush_queue) 1319 if (!lport->tt.rport_flush_queue)
1311 lport->tt.rport_flush_queue = fc_rport_flush_queue; 1320 lport->tt.rport_flush_queue = fc_rport_flush_queue;
1312 1321
1322 if (!lport->tt.rport_destroy)
1323 lport->tt.rport_destroy = fc_rport_destroy;
1324
1313 return 0; 1325 return 0;
1314} 1326}
1315EXPORT_SYMBOL(fc_rport_init); 1327EXPORT_SYMBOL(fc_rport_init);
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 2473167464c2..a94d216d2207 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -76,11 +76,7 @@ do { \
76 (port_id), ##args)) 76 (port_id), ##args))
77 77
78#define FC_RPORT_DBG(rdata, fmt, args...) \ 78#define FC_RPORT_DBG(rdata, fmt, args...) \
79do { \ 79 FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args)
80 struct fc_lport *lport = rdata->local_port; \
81 struct fc_rport *rport = PRIV_TO_RPORT(rdata); \
82 FC_RPORT_ID_DBG(lport, rport->port_id, fmt, ##args); \
83} while (0)
84 80
85#define FC_FCP_DBG(pkt, fmt, args...) \ 81#define FC_FCP_DBG(pkt, fmt, args...) \
86 FC_CHECK_LOGGING(FC_FCP_LOGGING, \ 82 FC_CHECK_LOGGING(FC_FCP_LOGGING, \
@@ -195,9 +191,13 @@ struct fc_rport_operations {
195/** 191/**
196 * struct fc_rport_libfc_priv - libfc internal information about a remote port 192 * struct fc_rport_libfc_priv - libfc internal information about a remote port
197 * @local_port: Fibre Channel host port instance 193 * @local_port: Fibre Channel host port instance
194 * @rport: transport remote port
195 * @kref: reference counter
198 * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges 196 * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges
197 * @ids: remote port identifiers and roles
199 * @flags: REC and RETRY supported flags 198 * @flags: REC and RETRY supported flags
200 * @max_seq: maximum number of concurrent sequences 199 * @max_seq: maximum number of concurrent sequences
200 * @maxframe_size: maximum frame size
201 * @retries: retry count in current state 201 * @retries: retry count in current state
202 * @e_d_tov: error detect timeout value (in msec) 202 * @e_d_tov: error detect timeout value (in msec)
203 * @r_a_tov: resource allocation timeout value (in msec) 203 * @r_a_tov: resource allocation timeout value (in msec)
@@ -207,11 +207,15 @@ struct fc_rport_operations {
207 */ 207 */
208struct fc_rport_libfc_priv { 208struct fc_rport_libfc_priv {
209 struct fc_lport *local_port; 209 struct fc_lport *local_port;
210 struct fc_rport *rport;
211 struct kref kref;
210 enum fc_rport_state rp_state; 212 enum fc_rport_state rp_state;
213 struct fc_rport_identifiers ids;
211 u16 flags; 214 u16 flags;
212 #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0) 215 #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0)
213 #define FC_RP_FLAGS_RETRY (1 << 1) 216 #define FC_RP_FLAGS_RETRY (1 << 1)
214 u16 max_seq; 217 u16 max_seq;
218 u16 maxframe_size;
215 unsigned int retries; 219 unsigned int retries;
216 unsigned int e_d_tov; 220 unsigned int e_d_tov;
217 unsigned int r_a_tov; 221 unsigned int r_a_tov;
@@ -222,19 +226,12 @@ struct fc_rport_libfc_priv {
222 struct fc_rport_operations *ops; 226 struct fc_rport_operations *ops;
223 struct list_head peers; 227 struct list_head peers;
224 struct work_struct event_work; 228 struct work_struct event_work;
229 u32 supported_classes;
225}; 230};
226 231
227#define PRIV_TO_RPORT(x) \
228 ((struct fc_rport *)((void *)(x) - sizeof(struct fc_rport)))
229#define RPORT_TO_PRIV(x) \ 232#define RPORT_TO_PRIV(x) \
230 ((struct fc_rport_libfc_priv *)((void *)(x) + sizeof(struct fc_rport))) 233 ((struct fc_rport_libfc_priv *)((void *)(x) + sizeof(struct fc_rport)))
231 234
232static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn)
233{
234 rport->node_name = wwnn;
235 rport->port_name = wwpn;
236}
237
238/* 235/*
239 * fcoe stats structure 236 * fcoe stats structure
240 */ 237 */
@@ -609,6 +606,12 @@ struct libfc_function_template {
609 struct fc_rport_priv *(*rport_lookup)(const struct fc_lport *, u32); 606 struct fc_rport_priv *(*rport_lookup)(const struct fc_lport *, u32);
610 607
611 /* 608 /*
609 * Destroy an rport after final kref_put().
610 * The argument is a pointer to the kref inside the fc_rport_priv.
611 */
612 void (*rport_destroy)(struct kref *);
613
614 /*
612 * Send a fcp cmd from fsp pkt. 615 * Send a fcp cmd from fsp pkt.
613 * Called with the SCSI host lock unlocked and irqs disabled. 616 * Called with the SCSI host lock unlocked and irqs disabled.
614 * 617 *