From 48f00902ba40d3e4467782a42258b952437a89f9 Mon Sep 17 00:00:00 2001 From: Joe Eykholt Date: Tue, 25 Aug 2009 14:01:50 -0700 Subject: [SCSI] libfc: make rport module maintain the rport list The list of remote ports (struct fc_rport_priv) has been maintained by the discovery module. In preparation for having lport->tt.rport_create() do a lookup first, maintain the rports list in the rport module. It will still be protected by the disc_mutex. The DNS rport is an exception for until after further patches. For now, do not add it to the list. The point-to-point rport will be in the discovery list. So at shutdown, it doesn't need to be separately logged out. Signed-off-by: Joe Eykholt Signed-off-by: Robert Love Signed-off-by: James Bottomley --- drivers/scsi/libfc/fc_disc.c | 8 -------- drivers/scsi/libfc/fc_lport.c | 14 ++++++-------- drivers/scsi/libfc/fc_rport.c | 11 +++++++++-- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 8427396909e..e6b13bfecf7 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c @@ -115,9 +115,6 @@ static void fc_disc_rport_callback(struct fc_lport *lport, case RPORT_EV_LOGO: case RPORT_EV_FAILED: case RPORT_EV_STOP: - mutex_lock(&disc->disc_mutex); - list_del(&rdata->peers); - mutex_unlock(&disc->disc_mutex); break; default: break; @@ -385,9 +382,6 @@ static int fc_disc_new_target(struct fc_disc *disc, rdata = lport->tt.rport_create(lport, ids); if (!rdata) error = -ENOMEM; - else - list_add_tail(&rdata->peers, - &disc->rports); } } if (rdata) { @@ -562,7 +556,6 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) rdata = lport->tt.rport_create(lport, &ids); if (rdata) { rdata->ops = &fc_disc_rport_ops; - list_add_tail(&rdata->peers, &disc->rports); lport->tt.rport_login(rdata); } else printk(KERN_WARNING "libfc: Failed to allocate " @@ -709,7 +702,6 @@ static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp) if (rdata) { rdata->ops = &fc_disc_rport_ops; kfree(dp); - list_add_tail(&rdata->peers, &disc->rports); lport->tt.rport_login(rdata); } return; diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 22c0f7bc004..f33e5732e3f 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -205,12 +205,11 @@ static void fc_lport_ptp_setup(struct fc_lport *lport, ids.node_name = remote_wwnn; ids.roles = FC_RPORT_ROLE_UNKNOWN; - if (lport->ptp_rp) { + mutex_lock(&lport->disc.disc_mutex); + if (lport->ptp_rp) lport->tt.rport_logoff(lport->ptp_rp); - lport->ptp_rp = NULL; - } - lport->ptp_rp = lport->tt.rport_create(lport, &ids); + mutex_unlock(&lport->disc.disc_mutex); lport->tt.rport_login(lport->ptp_rp); @@ -931,10 +930,7 @@ static void fc_lport_reset_locked(struct fc_lport *lport) if (lport->dns_rp) lport->tt.rport_logoff(lport->dns_rp); - if (lport->ptp_rp) { - lport->tt.rport_logoff(lport->ptp_rp); - lport->ptp_rp = NULL; - } + lport->ptp_rp = NULL; lport->tt.disc_stop(lport); @@ -1304,7 +1300,9 @@ static void fc_lport_enter_dns(struct fc_lport *lport) fc_lport_state_enter(lport, LPORT_ST_DNS); + mutex_lock(&lport->disc.disc_mutex); rdata = lport->tt.rport_create(lport, &ids); + mutex_unlock(&lport->disc.disc_mutex); if (!rdata) goto err; diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 6ecf36d4708..a9087b31bce 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -91,8 +91,7 @@ static const char *fc_rport_state_names[] = { * @lport: local port. * @ids: remote port identifiers. * - * Locking note: this may be called without locks held, but - * is usually called from discovery with the disc_mutex held. + * Locking note: must be called with the disc_mutex held. */ static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, struct fc_rport_identifiers *ids) @@ -115,6 +114,8 @@ static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, rdata->maxframe_size = FC_MIN_MAX_PAYLOAD; INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout); INIT_WORK(&rdata->event_work, fc_rport_work); + if (ids->port_id != FC_FID_DIR_SERV) + list_add(&rdata->peers, &lport->disc.rports); return rdata; } @@ -258,6 +259,12 @@ static void fc_rport_work(struct work_struct *work) port_id = rdata->ids.port_id; mutex_unlock(&rdata->rp_mutex); + if (port_id != FC_FID_DIR_SERV) { + mutex_lock(&lport->disc.disc_mutex); + list_del(&rdata->peers); + mutex_unlock(&lport->disc.disc_mutex); + } + if (rport_ops->event_callback) { FC_RPORT_DBG(rdata, "callback ev %d\n", event); rport_ops->event_callback(lport, rdata, event); -- cgit v1.2.3