/*
 * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Maintained at www.Open-FCoE.org
 */

/*
 * Target Discovery
 *
 * This block discovers all FC-4 remote ports, including FCP initiators. It
 * also handles RSCN events and re-discovery if necessary.
 */

/*
 * DISC LOCKING
 *
 * The disc mutex is can be locked when acquiring rport locks, but may not
 * be held when acquiring the lport lock. Refer to fc_lport.c for more
 * details.
 */

#include <linux/timer.h>
#include <linux/err.h>
#include <asm/unaligned.h>

#include <scsi/fc/fc_gs.h>

#include <scsi/libfc.h>

#define FC_DISC_RETRY_LIMIT	3	/* max retries */
#define FC_DISC_RETRY_DELAY	500UL	/* (msecs) delay */

#define	FC_DISC_DELAY		3

static void fc_disc_gpn_ft_req(struct fc_disc *);
static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *);
static int fc_disc_new_target(struct fc_disc *, struct fc_rport *,
			      struct fc_rport_identifiers *);
static void fc_disc_del_target(struct fc_disc *, struct fc_rport *);
static void fc_disc_done(struct fc_disc *);
static void fc_disc_timeout(struct work_struct *);
static void fc_disc_single(struct fc_disc *, struct fc_disc_port *);
static void fc_disc_restart(struct fc_disc *);

/**
 * fc_disc_lookup_rport() - lookup a remote port by port_id
 * @lport: Fibre Channel host port instance
 * @port_id: remote port port_id to match
 */
struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport,
				      u32 port_id)
{
	const struct fc_disc *disc = &lport->disc;
	struct fc_rport *rport, *found = NULL;
	struct fc_rport_libfc_priv *rdata;
	int disc_found = 0;

	list_for_each_entry(rdata, &disc->rports, peers) {
		rport = PRIV_TO_RPORT(rdata);
		if (rport->port_id == port_id) {
			disc_found = 1;
			found = rport;
			break;
		}
	}

	if (!disc_found)
		found = NULL;

	return found;
}

/**
 * fc_disc_stop_rports() - delete all the remote ports associated with the lport
 * @disc: The discovery job to stop rports on
 *
 * Locking Note: This function expects that the lport mutex is locked before
 * calling it.
 */
void fc_disc_stop_rports(struct fc_disc *disc)
{
	struct fc_lport *lport;
	struct fc_rport *rport;
	struct fc_rport_libfc_priv *rdata, *next;

	lport = disc->lport;

	mutex_lock(&disc->disc_mutex);
	list_for_each_entry_safe(rdata, next, &disc->rports, peers) {
		rport = PRIV_TO_RPORT(rdata);
		list_del(&rdata->peers);
		lport->tt.rport_logoff(rport);
	}

	list_for_each_entry_safe(rdata, next, &disc->rogue_rports, peers) {
		rport = PRIV_TO_RPORT(rdata);
		lport->tt.rport_logoff(rport);
	}

	mutex_unlock(&disc->disc_mutex);
}

/**
 * fc_disc_rport_callback() - Event handler for rport events
 * @lport: The lport which is receiving the event
 * @rport: The rport which the event has occured on
 * @event: The event that occured
 *
 * Locking Note: The rport lock should not be held when calling
 *		 this function.
 */
static void fc_disc_rport_callback(struct fc_lport *lport,
				   struct fc_rport *rport,
				   enum fc_rport_event event)
{
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	struct fc_disc *disc = &lport->disc;

	FC_DISC_DBG(disc, "Received a %d event for port (%6x)\n", event,
		    rport->port_id);

	switch (event) {
	case RPORT_EV_CREATED:
		if (disc) {
			mutex_lock(&disc->disc_mutex);
			list_add_tail(&rdata->peers, &disc->rports);
			mutex_unlock(&disc->disc_mutex);
		}
		break;
	case RPORT_EV_LOGO:
	case RPORT_EV_FAILED:
	case RPORT_EV_STOP:
		mutex_lock(&disc->disc_mutex);
		mutex_lock(&rdata->rp_mutex);
		if (rdata->trans_state == FC_PORTSTATE_ROGUE)
			list_del(&rdata->peers);
		mutex_unlock(&rdata->rp_mutex);
		mutex_unlock(&disc->disc_mutex);
		break;
	default:
		break;
	}

}

/**
 * fc_disc_recv_rscn_req() - Handle Registered State Change Notification (RSCN)
 * @sp: Current sequence of the RSCN exchange
 * @fp: RSCN Frame
 * @lport: Fibre Channel host port instance
 *
 * Locking Note: This function expects that the disc_mutex is locked
 *		 before it is called.
 */
static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
				  struct fc_disc *disc)
{
	struct fc_lport *lport;
	struct fc_rport *rport;
	struct fc_rport_libfc_priv *rdata;
	struct fc_els_rscn *rp;
	struct fc_els_rscn_page *pp;
	struct fc_seq_els_data rjt_data;
	unsigned int len;
	int redisc = 0;
	enum fc_els_rscn_ev_qual ev_qual;
	enum fc_els_rscn_addr_fmt fmt;
	LIST_HEAD(disc_ports);
	struct fc_disc_port *dp, *next;

	lport = disc->lport;

	FC_DISC_DBG(disc, "Received an RSCN event\n");

	/* make sure the frame contains an RSCN message */
	rp = fc_frame_payload_get(fp, sizeof(*rp));
	if (!rp)
		goto reject;
	/* make sure the page length is as expected (4 bytes) */
	if (rp->rscn_page_len != sizeof(*pp))
		goto reject;
	/* get the RSCN payload length */
	len = ntohs(rp->rscn_plen);
	if (len < sizeof(*rp))
		goto reject;
	/* make sure the frame contains the expected payload */
	rp = fc_frame_payload_get(fp, len);
	if (!rp)
		goto reject;
	/* payload must be a multiple of the RSCN page size */
	len -= sizeof(*rp);
	if (len % sizeof(*pp))
		goto reject;

	for (pp = (void *)(rp + 1); len > 0; len -= sizeof(*pp), pp++) {
		ev_qual = pp->rscn_page_flags >> ELS_RSCN_EV_QUAL_BIT;
		ev_qual &= ELS_RSCN_EV_QUAL_MASK;
		fmt = pp->rscn_page_flags >> ELS_RSCN_ADDR_FMT_BIT;
		fmt &= ELS_RSCN_ADDR_FMT_MASK;
		/*
		 * if we get an address format other than port
		 * (area, domain, fabric), then do a full discovery
		 */
		switch (fmt) {
		case ELS_ADDR_FMT_PORT:
			FC_DISC_DBG(disc, "Port address format for port "
				    "(%6x)\n", ntoh24(pp->rscn_fid));
			dp = kzalloc(sizeof(*dp), GFP_KERNEL);
			if (!dp) {
				redisc = 1;
				break;
			}
			dp->lp = lport;
			dp->ids.port_id = ntoh24(pp->rscn_fid);
			dp->ids.port_name = -1;
			dp->ids.node_name = -1;
			dp->ids.roles = FC_RPORT_ROLE_UNKNOWN;
			list_add_tail(&dp->peers, &disc_ports);
			break;
		case ELS_ADDR_FMT_AREA:
		case ELS_ADDR_FMT_DOM:
		case ELS_ADDR_FMT_FAB:
		default:
			FC_DISC_DBG(disc, "Address format is (%d)\n", fmt);
			redisc = 1;
			break;
		}
	}
	lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
	if (redisc) {
		FC_DISC_DBG(disc, "RSCN received: rediscovering\n");
		fc_disc_restart(disc);
	} else {
		FC_DISC_DBG(disc, "RSCN received: not rediscovering. "
			    "redisc %d state %d in_prog %d\n",
			    redisc, lport->state, disc->pending);
		list_for_each_entry_safe(dp, next, &disc_ports, peers) {
			list_del(&dp->peers);
			rport = lport->tt.rport_lookup(lport, dp->ids.port_id);
			if (rport) {
				rdata = rport->dd_data;
				list_del(&rdata->peers);
				lport->tt.rport_logoff(rport);
			}
			fc_disc_single(disc, dp);
		}
	}
	fc_frame_free(fp);
	return;
reject:
	FC_DISC_DBG(disc, "Received a bad RSCN frame\n");
	rjt_data.fp = NULL;
	rjt_data.reason = ELS_RJT_LOGIC;
	rjt_data.explan = ELS_EXPL_NONE;
	lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
	fc_frame_free(fp);
}

/**
 * fc_disc_recv_req() - Handle incoming requests
 * @sp: Current sequence of the request exchange
 * @fp: The frame
 * @lport: The FC local port
 *
 * Locking Note: This function is called from the EM and will lock
 *		 the disc_mutex before calling the handler for the
 *		 request.
 */
static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp,
			     struct fc_lport *lport)
{
	u8 op;
	struct fc_disc *disc = &lport->disc;

	op = fc_frame_payload_op(fp);
	switch (op) {
	case ELS_RSCN:
		mutex_lock(&disc->disc_mutex);
		fc_disc_recv_rscn_req(sp, fp, disc);
		mutex_unlock(&disc->disc_mutex);
		break;
	default:
		FC_DISC_DBG(disc, "Received an unsupported request, "
			    "the opcode is (%x)\n", op);
		break;
	}
}

/**
 * fc_disc_restart() - Restart discovery
 * @lport: FC discovery context
 *
 * Locking Note: This function expects that the disc mutex
 *		 is already locked.
 */
static void fc_disc_restart(struct fc_disc *disc)
{
	struct fc_rport *rport;
	struct fc_rport_libfc_priv *rdata, *next;
	struct fc_lport *lport = disc->lport;

	FC_DISC_DBG(disc, "Restarting discovery\n");

	list_for_each_entry_safe(rdata, next, &disc->rports, peers) {
		rport = PRIV_TO_RPORT(rdata);
		list_del(&rdata->peers);
		lport->tt.rport_logoff(rport);
	}

	disc->requested = 1;
	if (!disc->pending)
		fc_disc_gpn_ft_req(disc);
}

/**
 * fc_disc_start() - Fibre Channel Target discovery
 * @lport: FC local port
 *
 * Returns non-zero if discovery cannot be started.
 */
static void fc_disc_start(void (*disc_callback)(struct fc_lport *,
						enum fc_disc_event),
			  struct fc_lport *lport)
{
	struct fc_rport *rport;
	struct fc_rport_identifiers ids;
	struct fc_disc *disc = &lport->disc;

	/*
	 * At this point we may have a new disc job or an existing
	 * one. Either way, let's lock when we make changes to it
	 * and send the GPN_FT request.
	 */
	mutex_lock(&disc->disc_mutex);

	disc->disc_callback = disc_callback;

	/*
	 * If not ready, or already running discovery, just set request flag.
	 */
	disc->requested = 1;

	if (disc->pending) {
		mutex_unlock(&disc->disc_mutex);
		return;
	}

	/*
	 * Handle point-to-point mode as a simple discovery
	 * of the remote port. Yucky, yucky, yuck, yuck!
	 */
	rport = disc->lport->ptp_rp;
	if (rport) {
		ids.port_id = rport->port_id;
		ids.port_name = rport->port_name;
		ids.node_name = rport->node_name;
		ids.roles = FC_RPORT_ROLE_UNKNOWN;
		get_device(&rport->dev);

		if (!fc_disc_new_target(disc, rport, &ids)) {
			disc->event = DISC_EV_SUCCESS;
			fc_disc_done(disc);
		}
		put_device(&rport->dev);
	} else {
		fc_disc_gpn_ft_req(disc);	/* get ports by FC-4 type */
	}

	mutex_unlock(&disc->disc_mutex);
}

static struct fc_rport_operations fc_disc_rport_ops = {
	.event_callback = fc_disc_rport_callback,
};

/**
 * fc_disc_new_target() - Handle new target found by discovery
 * @lport: FC local port
 * @rport: The previous FC remote port (NULL if new remote port)
 * @ids: Identifiers for the new FC remote port
 *
 * Locking Note: This function expects that the disc_mutex is locked
 *		 before it is called.
 */
static int fc_disc_new_target(struct fc_disc *disc,
			      struct fc_rport *rport,
			      struct fc_rport_identifiers *ids)
{
	struct fc_lport *lport = disc->lport;
	struct fc_rport_libfc_priv *rdata;
	int error = 0;

	if (rport && ids->port_name) {
		if (rport->port_name == -1) {
			/*
			 * Set WWN and fall through to notify of create.
			 */
			fc_rport_set_name(rport, ids->port_name,
					  rport->node_name);
		} else if (rport->port_name != ids->port_name) {
			/*
			 * This is a new port with the same FCID as
			 * a previously-discovered port.  Presumably the old
			 * port logged out and a new port logged in and was
			 * assigned the same FCID.  This should be rare.
			 * Delete the old one and fall thru to re-create.
			 */
			fc_disc_del_target(disc, rport);
			rport = NULL;
		}
	}
	if (((ids->port_name != -1) || (ids->port_id != -1)) &&
	    ids->port_id != fc_host_port_id(lport->host) &&
	    ids->port_name != lport->wwpn) {
		if (!rport) {
			rport = lport->tt.rport_lookup(lport, ids->port_id);
			if (!rport) {
				struct fc_disc_port dp;
				dp.lp = lport;
				dp.ids.port_id = ids->port_id;
				dp.ids.port_name = ids->port_name;
				dp.ids.node_name = ids->node_name;
				dp.ids.roles = ids->roles;
				rport = lport->tt.rport_create(&dp);
			}
			if (!rport)
				error = -ENOMEM;
		}
		if (rport) {
			rdata = rport->dd_data;
			rdata->ops = &fc_disc_rport_ops;
			rdata->rp_state = RPORT_ST_INIT;
			list_add_tail(&rdata->peers, &disc->rogue_rports);
			lport->tt.rport_login(rport);
		}
	}
	return error;
}

/**
 * fc_disc_del_target() - Delete a target
 * @disc: FC discovery context
 * @rport: The remote port to be removed
 */
static void fc_disc_del_target(struct fc_disc *disc, struct fc_rport *rport)
{
	struct fc_lport *lport = disc->lport;
	struct fc_rport_libfc_priv *rdata = rport->dd_data;
	list_del(&rdata->peers);
	lport->tt.rport_logoff(rport);
}

/**
 * fc_disc_done() - Discovery has been completed
 * @disc: FC discovery context
 * Locking Note: This function expects that the disc mutex is locked before
 * it is called. The discovery callback is then made with the lock released,
 * and the lock is re-taken before returning from this function
 */
static void fc_disc_done(struct fc_disc *disc)
{
	struct fc_lport *lport = disc->lport;
	enum fc_disc_event event;

	FC_DISC_DBG(disc, "Discovery complete\n");

	event = disc->event;
	disc->event = DISC_EV_NONE;

	if (disc->requested)
		fc_disc_gpn_ft_req(disc);
	else
		disc->pending = 0;

	mutex_unlock(&disc->disc_mutex);
	disc->disc_callback(lport, event);
	mutex_lock(&disc->disc_mutex);
}

/**
 * fc_disc_error() - Handle error on dNS request
 * @disc: FC discovery context
 * @fp: The frame pointer
 */
static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp)
{
	struct fc_lport *lport = disc->lport;
	unsigned long delay = 0;

	FC_DISC_DBG(disc, "Error %ld, retries %d/%d\n",
		    PTR_ERR(fp), disc->retry_count,
		    FC_DISC_RETRY_LIMIT);

	if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) {
		/*
		 * Memory allocation failure, or the exchange timed out,
		 * retry after delay.
		 */
		if (disc->retry_count < FC_DISC_RETRY_LIMIT) {
			/* go ahead and retry */
			if (!fp)
				delay = msecs_to_jiffies(FC_DISC_RETRY_DELAY);
			else {
				delay = msecs_to_jiffies(lport->e_d_tov);

				/* timeout faster first time */
				if (!disc->retry_count)
					delay /= 4;
			}
			disc->retry_count++;
			schedule_delayed_work(&disc->disc_work, delay);
		} else {
			/* exceeded retries */
			disc->event = DISC_EV_FAILED;
			fc_disc_done(disc);
		}
	}
}

/**
 * fc_disc_gpn_ft_req() - Send Get Port Names by FC-4 type (GPN_FT) request
 * @lport: FC discovery context
 *
 * Locking Note: This function expects that the disc_mutex is locked
 *		 before it is called.
 */
static void fc_disc_gpn_ft_req(struct fc_disc *disc)
{
	struct fc_frame *fp;
	struct fc_lport *lport = disc->lport;

	WARN_ON(!fc_lport_test_ready(lport));

	disc->pending = 1;
	disc->requested = 0;

	disc->buf_len = 0;
	disc->seq_count = 0;
	fp = fc_frame_alloc(lport,
			    sizeof(struct fc_ct_hdr) +
			    sizeof(struct fc_ns_gid_ft));
	if (!fp)
		goto err;

	if (lport->tt.elsct_send(lport, NULL, fp,
				 FC_NS_GPN_FT,
				 fc_disc_gpn_ft_resp,
				 disc, lport->e_d_tov))
		return;
err:
	fc_disc_error(disc, fp);
}

/**
 * fc_disc_gpn_ft_parse() - Parse the list of IDs and names resulting from a request
 * @lport: Fibre Channel host port instance
 * @buf: GPN_FT response buffer
 * @len: size of response buffer
 */
static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
{
	struct fc_lport *lport;
	struct fc_gpn_ft_resp *np;
	char *bp;
	size_t plen;
	size_t tlen;
	int error = 0;
	struct fc_disc_port dp;
	struct fc_rport *rport;
	struct fc_rport_libfc_priv *rdata;

	lport = disc->lport;

	/*
	 * Handle partial name record left over from previous call.
	 */
	bp = buf;
	plen = len;
	np = (struct fc_gpn_ft_resp *)bp;
	tlen = disc->buf_len;
	if (tlen) {
		WARN_ON(tlen >= sizeof(*np));
		plen = sizeof(*np) - tlen;
		WARN_ON(plen <= 0);
		WARN_ON(plen >= sizeof(*np));
		if (plen > len)
			plen = len;
		np = &disc->partial_buf;
		memcpy((char *)np + tlen, bp, plen);

		/*
		 * Set bp so that the loop below will advance it to the
		 * first valid full name element.
		 */
		bp -= tlen;
		len += tlen;
		plen += tlen;
		disc->buf_len = (unsigned char) plen;
		if (plen == sizeof(*np))
			disc->buf_len = 0;
	}

	/*
	 * Handle full name records, including the one filled from above.
	 * Normally, np == bp and plen == len, but from the partial case above,
	 * bp, len describe the overall buffer, and np, plen describe the
	 * partial buffer, which if would usually be full now.
	 * After the first time through the loop, things return to "normal".
	 */
	while (plen >= sizeof(*np)) {
		dp.lp = lport;
		dp.ids.port_id = ntoh24(np->fp_fid);
		dp.ids.port_name = ntohll(np->fp_wwpn);
		dp.ids.node_name = -1;
		dp.ids.roles = FC_RPORT_ROLE_UNKNOWN;

		if ((dp.ids.port_id != fc_host_port_id(lport->host)) &&
		    (dp.ids.port_name != lport->wwpn)) {
			rport = lport->tt.rport_create(&dp);
			if (rport) {
				rdata = rport->dd_data;
				rdata->ops = &fc_disc_rport_ops;
				rdata->local_port = lport;
				list_add_tail(&rdata->peers,
					      &disc->rogue_rports);
				lport->tt.rport_login(rport);
			} else
				printk(KERN_WARNING "libfc: Failed to allocate "
				       "memory for the newly discovered port "
				       "(%6x)\n", dp.ids.port_id);
		}

		if (np->fp_flags & FC_NS_FID_LAST) {
			disc->event = DISC_EV_SUCCESS;
			fc_disc_done(disc);
			len = 0;
			break;
		}
		len -= sizeof(*np);
		bp += sizeof(*np);
		np = (struct fc_gpn_ft_resp *)bp;
		plen = len;
	}

	/*
	 * Save any partial record at the end of the buffer for next time.
	 */
	if (error == 0 && len > 0 && len < sizeof(*np)) {
		if (np != &disc->partial_buf) {
			FC_DISC_DBG(disc, "Partial buffer remains "
				    "for discovery\n");
			memcpy(&disc->partial_buf, np, len);
		}
		disc->buf_len = (unsigned char) len;
	} else {
		disc->buf_len = 0;
	}
	return error;
}

/**
 * fc_disc_timeout() - Retry handler for the disc component
 * @work: Structure holding disc obj that needs retry discovery
 *
 * Handle retry of memory allocation for remote ports.
 */
static void fc_disc_timeout(struct work_struct *work)
{
	struct fc_disc *disc = container_of(work,
					    struct fc_disc,
					    disc_work.work);
	mutex_lock(&disc->disc_mutex);
	if (disc->requested && !disc->pending)
		fc_disc_gpn_ft_req(disc);
	mutex_unlock(&disc->disc_mutex);
}

/**
 * fc_disc_gpn_ft_resp() - Handle a response frame from Get Port Names (GPN_FT)
 * @sp: Current sequence of GPN_FT exchange
 * @fp: response frame
 * @lp_arg: Fibre Channel host port instance
 *
 * Locking Note: This function is called without disc mutex held, and
 *		 should do all its processing with the mutex held
 */
static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
				void *disc_arg)
{
	struct fc_disc *disc = disc_arg;
	struct fc_ct_hdr *cp;
	struct fc_frame_header *fh;
	unsigned int seq_cnt;
	void *buf = NULL;
	unsigned int len;
	int error;

	mutex_lock(&disc->disc_mutex);
	FC_DISC_DBG(disc, "Received a GPN_FT response\n");

	if (IS_ERR(fp)) {
		fc_disc_error(disc, fp);
		mutex_unlock(&disc->disc_mutex);
		return;
	}

	WARN_ON(!fc_frame_is_linear(fp));	/* buffer must be contiguous */
	fh = fc_frame_header_get(fp);
	len = fr_len(fp) - sizeof(*fh);
	seq_cnt = ntohs(fh->fh_seq_cnt);
	if (fr_sof(fp) == FC_SOF_I3 && seq_cnt == 0 &&
	    disc->seq_count == 0) {
		cp = fc_frame_payload_get(fp, sizeof(*cp));
		if (!cp) {
			FC_DISC_DBG(disc, "GPN_FT response too short, len %d\n",
				    fr_len(fp));
		} else if (ntohs(cp->ct_cmd) == FC_FS_ACC) {

			/* Accepted, parse the response. */
			buf = cp + 1;
			len -= sizeof(*cp);
		} else if (ntohs(cp->ct_cmd) == FC_FS_RJT) {
			FC_DISC_DBG(disc, "GPN_FT rejected reason %x exp %x "
				    "(check zoning)\n", cp->ct_reason,
				    cp->ct_explan);
			disc->event = DISC_EV_FAILED;
			fc_disc_done(disc);
		} else {
			FC_DISC_DBG(disc, "GPN_FT unexpected response code "
				    "%x\n", ntohs(cp->ct_cmd));
		}
	} else if (fr_sof(fp) == FC_SOF_N3 &&
		   seq_cnt == disc->seq_count) {
		buf = fh + 1;
	} else {
		FC_DISC_DBG(disc, "GPN_FT unexpected frame - out of sequence? "
			    "seq_cnt %x expected %x sof %x eof %x\n",
			    seq_cnt, disc->seq_count, fr_sof(fp), fr_eof(fp));
	}
	if (buf) {
		error = fc_disc_gpn_ft_parse(disc, buf, len);
		if (error)
			fc_disc_error(disc, fp);
		else
			disc->seq_count++;
	}
	fc_frame_free(fp);

	mutex_unlock(&disc->disc_mutex);
}

/**
 * fc_disc_single() - Discover the directory information for a single target
 * @lport: FC local port
 * @dp: The port to rediscover
 *
 * Locking Note: This function expects that the disc_mutex is locked
 *		 before it is called.
 */
static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp)
{
	struct fc_lport *lport;
	struct fc_rport *new_rport;
	struct fc_rport_libfc_priv *rdata;

	lport = disc->lport;

	if (dp->ids.port_id == fc_host_port_id(lport->host))
		goto out;

	new_rport = lport->tt.rport_create(dp);
	if (new_rport) {
		rdata = new_rport->dd_data;
		rdata->ops = &fc_disc_rport_ops;
		kfree(dp);
		list_add_tail(&rdata->peers, &disc->rogue_rports);
		lport->tt.rport_login(new_rport);
	}
	return;
out:
	kfree(dp);
}

/**
 * fc_disc_stop() - Stop discovery for a given lport
 * @lport: The lport that discovery should stop for
 */
void fc_disc_stop(struct fc_lport *lport)
{
	struct fc_disc *disc = &lport->disc;

	if (disc) {
		cancel_delayed_work_sync(&disc->disc_work);
		fc_disc_stop_rports(disc);
	}
}

/**
 * fc_disc_stop_final() - Stop discovery for a given lport
 * @lport: The lport that discovery should stop for
 *
 * This function will block until discovery has been
 * completely stopped and all rports have been deleted.
 */
void fc_disc_stop_final(struct fc_lport *lport)
{
	fc_disc_stop(lport);
	lport->tt.rport_flush_queue();
}

/**
 * fc_disc_init() - Initialize the discovery block
 * @lport: FC local port
 */
int fc_disc_init(struct fc_lport *lport)
{
	struct fc_disc *disc;

	if (!lport->tt.disc_start)
		lport->tt.disc_start = fc_disc_start;

	if (!lport->tt.disc_stop)
		lport->tt.disc_stop = fc_disc_stop;

	if (!lport->tt.disc_stop_final)
		lport->tt.disc_stop_final = fc_disc_stop_final;

	if (!lport->tt.disc_recv_req)
		lport->tt.disc_recv_req = fc_disc_recv_req;

	if (!lport->tt.rport_lookup)
		lport->tt.rport_lookup = fc_disc_lookup_rport;

	disc = &lport->disc;
	INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout);
	mutex_init(&disc->disc_mutex);
	INIT_LIST_HEAD(&disc->rports);
	INIT_LIST_HEAD(&disc->rogue_rports);

	disc->lport = lport;
	disc->delay = FC_DISC_DELAY;
	disc->event = DISC_EV_NONE;

	return 0;
}
EXPORT_SYMBOL(fc_disc_init);
