aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 *