/*
 *                  QLOGIC LINUX SOFTWARE
 *
 * QLogic ISP2x00 device driver for Linux 2.6.x
 * Copyright (C) 2003-2005 QLogic Corporation
 * (www.qlogic.com)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that 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.
 *
 */
#include "qla_def.h"

/**
 * IO descriptor handle definitions.
 *
 * Signature form:
 *
 *	|31------28|27-------------------12|11-------0|
 *	|   Type   |   Rolling Signature   |   Index  |
 *	|----------|-----------------------|----------|
 *
 **/

#define HDL_TYPE_SCSI		0
#define HDL_TYPE_ASYNC_IOCB	0x0A

#define HDL_INDEX_BITS	12
#define HDL_ITER_BITS	16
#define HDL_TYPE_BITS	4

#define HDL_INDEX_MASK	((1UL << HDL_INDEX_BITS) - 1)
#define HDL_ITER_MASK	((1UL << HDL_ITER_BITS) - 1)
#define HDL_TYPE_MASK	((1UL << HDL_TYPE_BITS) - 1)

#define HDL_INDEX_SHIFT	0
#define HDL_ITER_SHIFT	(HDL_INDEX_SHIFT + HDL_INDEX_BITS)
#define HDL_TYPE_SHIFT	(HDL_ITER_SHIFT + HDL_ITER_BITS)

/* Local Prototypes. */
static inline uint32_t qla2x00_to_handle(uint16_t, uint16_t, uint16_t);
static inline uint16_t qla2x00_handle_to_idx(uint32_t);
static inline uint32_t qla2x00_iodesc_to_handle(struct io_descriptor *);
static inline struct io_descriptor *qla2x00_handle_to_iodesc(scsi_qla_host_t *,
    uint32_t);

static inline struct io_descriptor *qla2x00_alloc_iodesc(scsi_qla_host_t *);
static inline void qla2x00_free_iodesc(struct io_descriptor *);
static inline void qla2x00_init_io_descriptors(scsi_qla_host_t *);

static void qla2x00_iodesc_timeout(unsigned long);
static inline void qla2x00_add_iodesc_timer(struct io_descriptor *);
static inline void qla2x00_remove_iodesc_timer(struct io_descriptor *);

static inline void qla2x00_update_login_fcport(scsi_qla_host_t *,
    struct mbx_entry *, fc_port_t *);

static int qla2x00_send_abort_iocb(scsi_qla_host_t *, struct io_descriptor *,
    uint32_t, int);
static int qla2x00_send_abort_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
    struct mbx_entry *);

static int qla2x00_send_adisc_iocb(scsi_qla_host_t *, struct io_descriptor *,
    int);
static int qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
    struct mbx_entry *);

static int qla2x00_send_logout_iocb(scsi_qla_host_t *, struct io_descriptor *,
    int);
static int qla2x00_send_logout_iocb_cb(scsi_qla_host_t *,
    struct io_descriptor *, struct mbx_entry *);

static int qla2x00_send_login_iocb(scsi_qla_host_t *, struct io_descriptor *,
    port_id_t *, int);
static int qla2x00_send_login_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
    struct mbx_entry *);

/**
 * Mailbox IOCB callback array.
 **/
static int (*iocb_function_cb_list[LAST_IOCB_CB])
	(scsi_qla_host_t *, struct io_descriptor *, struct mbx_entry *) = {

	qla2x00_send_abort_iocb_cb,
	qla2x00_send_adisc_iocb_cb,
	qla2x00_send_logout_iocb_cb,
	qla2x00_send_login_iocb_cb,
};


/**
 * Generic IO descriptor handle routines.
 **/

/**
 * qla2x00_to_handle() - Create a descriptor handle.
 * @type: descriptor type
 * @iter: descriptor rolling signature
 * @idx: index to the descriptor array
 *
 * Returns a composite handle based in the @type, @iter, and @idx.
 */
static inline uint32_t
qla2x00_to_handle(uint16_t type, uint16_t iter, uint16_t idx)
{
	return ((uint32_t)(((uint32_t)type << HDL_TYPE_SHIFT) |
	    ((uint32_t)iter << HDL_ITER_SHIFT) |
	    ((uint32_t)idx << HDL_INDEX_SHIFT)));
}

/**
 * qla2x00_handle_to_idx() - Retrive the index for a given handle.
 * @handle: descriptor handle
 *
 * Returns the index specified by the @handle.
 */
static inline uint16_t
qla2x00_handle_to_idx(uint32_t handle)
{
	return ((uint16_t)(((handle) >> HDL_INDEX_SHIFT) & HDL_INDEX_MASK));
}

/**
 * qla2x00_iodesc_to_handle() - Convert an IO descriptor to a unique handle.
 * @iodesc: io descriptor
 *
 * Returns a unique handle for @iodesc.
 */
static inline uint32_t
qla2x00_iodesc_to_handle(struct io_descriptor *iodesc)
{
	uint32_t handle;

	handle = qla2x00_to_handle(HDL_TYPE_ASYNC_IOCB,
	    ++iodesc->ha->iodesc_signature, iodesc->idx);
	iodesc->signature = handle;

	return (handle);
}

/**
 * qla2x00_handle_to_iodesc() - Retrieve an IO descriptor given a unique handle.
 * @ha: HA context
 * @handle: handle to io descriptor
 *
 * Returns a pointer to the io descriptor, or NULL, if the io descriptor does
 * not exist or the io descriptors signature does not @handle.
 */
static inline struct io_descriptor *
qla2x00_handle_to_iodesc(scsi_qla_host_t *ha, uint32_t handle)
{
	uint16_t idx;
	struct io_descriptor *iodesc;

	idx = qla2x00_handle_to_idx(handle);
	iodesc = &ha->io_descriptors[idx];
	if (iodesc)
		if (iodesc->signature != handle)
			iodesc = NULL;

	return (iodesc);
}


/**
 * IO descriptor allocation routines.
 **/

/**
 * qla2x00_alloc_iodesc() - Allocate an IO descriptor from the pool.
 * @ha: HA context
 *
 * Returns a pointer to the allocated io descriptor, or NULL, if none available.
 */
static inline struct io_descriptor *
qla2x00_alloc_iodesc(scsi_qla_host_t *ha)
{
	uint16_t iter;
	struct io_descriptor *iodesc;

	iodesc = NULL;
	for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) {
		if (ha->io_descriptors[iter].used)
			continue;

		iodesc = &ha->io_descriptors[iter];
		iodesc->used = 1;
		iodesc->idx = iter;
		init_timer(&iodesc->timer);
		iodesc->ha = ha;
		iodesc->signature = qla2x00_iodesc_to_handle(iodesc);
		break;
	}

	return (iodesc);
}

/**
 * qla2x00_free_iodesc() - Free an IO descriptor.
 * @iodesc: io descriptor
 *
 * NOTE: The io descriptors timer *must* be stopped before it can be free'd.
 */
static inline void
qla2x00_free_iodesc(struct io_descriptor *iodesc)
{
	iodesc->used = 0;
	iodesc->signature = 0;
}

/**
 * qla2x00_remove_iodesc_timer() - Remove an active timer from an IO descriptor.
 * @iodesc: io descriptor
 */
static inline void
qla2x00_remove_iodesc_timer(struct io_descriptor *iodesc)
{
	if (iodesc->timer.function != NULL) {
		del_timer_sync(&iodesc->timer);
		iodesc->timer.data = (unsigned long) NULL;
		iodesc->timer.function = NULL;
	}
}

/**
 * qla2x00_init_io_descriptors() - Initialize the pool of IO descriptors.
 * @ha: HA context
 */
static inline void
qla2x00_init_io_descriptors(scsi_qla_host_t *ha)
{
	uint16_t iter;

	for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) {
		if (!ha->io_descriptors[iter].used)
			continue;

		qla2x00_remove_iodesc_timer(&ha->io_descriptors[iter]);
		qla2x00_free_iodesc(&ha->io_descriptors[iter]);
	}
}


/**
 * IO descriptor timer routines.
 **/

/**
 * qla2x00_iodesc_timeout() - Timeout IO descriptor handler.
 * @data: io descriptor
 */
static void
qla2x00_iodesc_timeout(unsigned long data)
{
	struct io_descriptor *iodesc;

	iodesc = (struct io_descriptor *) data;

	DEBUG14(printk("scsi(%ld): IO descriptor timeout, index=%x "
	    "signature=%08x, scheduling ISP abort.\n", iodesc->ha->host_no,
	    iodesc->idx, iodesc->signature));

	qla2x00_free_iodesc(iodesc);

	qla_printk(KERN_WARNING, iodesc->ha,
	    "IO descriptor timeout. Scheduling ISP abort.\n");
	set_bit(ISP_ABORT_NEEDED, &iodesc->ha->dpc_flags);
}

/**
 * qla2x00_add_iodesc_timer() - Add and start a timer for an IO descriptor.
 * @iodesc: io descriptor
 *
 * NOTE:
 * The firmware shall timeout an outstanding mailbox IOCB in 2 * R_A_TOV (in
 * tenths of a second) after it hits the wire.  But, if there are any request
 * resource contraints (i.e. during heavy I/O), exchanges can be held off for
 * at most R_A_TOV.  Therefore, the driver will wait 4 * R_A_TOV before
 * scheduling a recovery (big hammer).
 */
static inline void
qla2x00_add_iodesc_timer(struct io_descriptor *iodesc)
{
	unsigned long timeout;

	timeout = (iodesc->ha->r_a_tov * 4) / 10;
	init_timer(&iodesc->timer);
	iodesc->timer.data = (unsigned long) iodesc;
	iodesc->timer.expires = jiffies + (timeout * HZ);
	iodesc->timer.function =
	    (void (*) (unsigned long)) qla2x00_iodesc_timeout;
	add_timer(&iodesc->timer);
}

/**
 * IO descriptor support routines.
 **/

/**
 * qla2x00_update_login_fcport() - Update fcport data after login processing.
 * @ha: HA context
 * @mbxstat: Mailbox command status IOCB
 * @fcport: port to update
 */
static inline void
qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat,
    fc_port_t *fcport)
{
	if (le16_to_cpu(mbxstat->mb1) & BIT_0) {
		fcport->port_type = FCT_INITIATOR;
	} else {
		fcport->port_type = FCT_TARGET;
		if (le16_to_cpu(mbxstat->mb1) & BIT_1) {
			fcport->flags |= FCF_TAPE_PRESENT;
		}
	}
	fcport->login_retry = 0;
	fcport->port_login_retry_count = ha->port_down_retry_count *
	    PORT_RETRY_TIME;
	atomic_set(&fcport->port_down_timer, ha->port_down_retry_count *
	    PORT_RETRY_TIME);
	fcport->flags |= FCF_FABRIC_DEVICE;
	fcport->flags &= ~FCF_FAILOVER_NEEDED;
	fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
	atomic_set(&fcport->state, FCS_ONLINE);
	if (fcport->rport)
		fc_remote_port_unblock(fcport->rport);
}


/**
 * Mailbox IOCB commands.
 **/

/**
 * qla2x00_get_mbx_iocb_entry() - Retrieve an IOCB from the request queue.
 * @ha: HA context
 * @handle: handle to io descriptor
 *
 * Returns a pointer to the reqest entry, or NULL, if none were available.
 */
static inline struct mbx_entry *
qla2x00_get_mbx_iocb_entry(scsi_qla_host_t *ha, uint32_t handle)
{
	uint16_t cnt;
	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
	struct mbx_entry *mbxentry;

	mbxentry = NULL;

	if (ha->req_q_cnt < 3) {
		cnt = qla2x00_debounce_register(ISP_REQ_Q_OUT(ha, reg));
		if  (ha->req_ring_index < cnt)
			ha->req_q_cnt = cnt - ha->req_ring_index;
		else
			ha->req_q_cnt = ha->request_q_length -
			    (ha->req_ring_index - cnt);
	}
	if (ha->req_q_cnt >= 3) {
		mbxentry = (struct mbx_entry *)ha->request_ring_ptr;

		memset(mbxentry, 0, sizeof(struct mbx_entry));
		mbxentry->entry_type = MBX_IOCB_TYPE;
		mbxentry->entry_count = 1;
		mbxentry->sys_define1 = SOURCE_ASYNC_IOCB;
		mbxentry->handle = handle;
	}
	return (mbxentry);
}

/**
 * qla2x00_send_abort_iocb() - Issue an abort IOCB to the firmware.
 * @ha: HA context
 * @iodesc: io descriptor
 * @handle_to_abort: firmware handle to abort
 * @ha_locked: is function called with the hardware lock
 *
 * Returns QLA_SUCCESS if the IOCB was issued.
 */
static int
qla2x00_send_abort_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
    uint32_t handle_to_abort, int ha_locked)
{
	unsigned long flags = 0;
	struct mbx_entry *mbxentry;

	/* Send marker if required. */
	if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
		return (QLA_FUNCTION_FAILED);

	if (!ha_locked)
		spin_lock_irqsave(&ha->hardware_lock, flags);

	/* Build abort mailbox IOCB. */
	mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
	if (mbxentry == NULL) {
		if (!ha_locked)
			spin_unlock_irqrestore(&ha->hardware_lock, flags);

		return (QLA_FUNCTION_FAILED);
	}
	mbxentry->mb0 = __constant_cpu_to_le16(MBC_ABORT_COMMAND);
	mbxentry->mb1 = mbxentry->loop_id.extended =
	    cpu_to_le16(iodesc->remote_fcport->loop_id);
	mbxentry->mb2 = LSW(handle_to_abort);
	mbxentry->mb3 = MSW(handle_to_abort);
	wmb();

	qla2x00_add_iodesc_timer(iodesc);

	/* Issue command to ISP. */
	qla2x00_isp_cmd(ha);

	if (!ha_locked)
		spin_unlock_irqrestore(&ha->hardware_lock, flags);

	DEBUG14(printk("scsi(%ld): Sending Abort IOCB (%08x) to [%x], aborting "
	    "%08x.\n", ha->host_no, iodesc->signature,
	    iodesc->remote_fcport->loop_id, handle_to_abort));

	return (QLA_SUCCESS);
}

/**
 * qla2x00_send_abort_iocb_cb() - Abort IOCB callback.
 * @ha: HA context
 * @iodesc: io descriptor
 * @mbxstat: mailbox status IOCB
 *
 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
 * will be used for a retry.
 */
static int
qla2x00_send_abort_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
    struct mbx_entry *mbxstat)
{
	DEBUG14(printk("scsi(%ld): Abort IOCB -- sent to [%x/%02x%02x%02x], "
	    "status=%x mb0=%x.\n", ha->host_no, iodesc->remote_fcport->loop_id,
	    iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa,
	    le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));

	return (QLA_SUCCESS);
}


/**
 * qla2x00_send_adisc_iocb() - Issue a Get Port Database IOCB to the firmware.
 * @ha: HA context
 * @iodesc: io descriptor
 * @ha_locked: is function called with the hardware lock
 *
 * Returns QLA_SUCCESS if the IOCB was issued.
 */
static int
qla2x00_send_adisc_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
    int ha_locked)
{
	unsigned long flags = 0;
	struct mbx_entry *mbxentry;

	/* Send marker if required. */
	if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
		return (QLA_FUNCTION_FAILED);

	if (!ha_locked)
		spin_lock_irqsave(&ha->hardware_lock, flags);

	/* Build Get Port Database IOCB. */
	mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
	if (mbxentry == NULL) {
		if (!ha_locked)
			spin_unlock_irqrestore(&ha->hardware_lock, flags);

		return (QLA_FUNCTION_FAILED);
	}
	mbxentry->mb0 = __constant_cpu_to_le16(MBC_GET_PORT_DATABASE);
	mbxentry->mb1 = mbxentry->loop_id.extended =
	    cpu_to_le16(iodesc->remote_fcport->loop_id);
	mbxentry->mb2 = cpu_to_le16(MSW(LSD(ha->iodesc_pd_dma)));
	mbxentry->mb3 = cpu_to_le16(LSW(LSD(ha->iodesc_pd_dma)));
	mbxentry->mb6 = cpu_to_le16(MSW(MSD(ha->iodesc_pd_dma)));
	mbxentry->mb7 = cpu_to_le16(LSW(MSD(ha->iodesc_pd_dma)));
	mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);
	wmb();

	qla2x00_add_iodesc_timer(iodesc);

	/* Issue command to ISP. */
	qla2x00_isp_cmd(ha);

	if (!ha_locked)
		spin_unlock_irqrestore(&ha->hardware_lock, flags);

	DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n",
	    ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));

	return (QLA_SUCCESS);
}

/**
 * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback.
 * @ha: HA context
 * @iodesc: io descriptor
 * @mbxstat: mailbox status IOCB
 *
 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
 * will be used for a retry.
 */
static int
qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
    struct mbx_entry *mbxstat)
{
	fc_port_t *remote_fcport;

	remote_fcport = iodesc->remote_fcport;

	/* Ensure the port IDs are consistent. */
	if (remote_fcport->d_id.b24 != iodesc->d_id.b24) {
		DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port "
		    "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n",
		    ha->host_no, remote_fcport->d_id.b.domain,
		    remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
		    iodesc->d_id.b.domain, iodesc->d_id.b.area,
		    iodesc->d_id.b.al_pa));

		return (QLA_SUCCESS);
	}

	/* Only process the last command. */
	if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
		DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to "
		    "[%02x%02x%02x], expected %x, received %x.\n", ha->host_no,
		    iodesc->d_id.b.domain, iodesc->d_id.b.area,
		    iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
		    iodesc->idx));

		return (QLA_SUCCESS);
	}

	if (le16_to_cpu(mbxstat->status) == CS_COMPLETE) {
		DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
		    "[%x/%02x%02x%02x] online.\n", ha->host_no,
		    remote_fcport->loop_id, remote_fcport->d_id.b.domain,
		    remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));

		atomic_set(&remote_fcport->state, FCS_ONLINE);
	} else {
		DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
		    "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha->host_no,
		    remote_fcport->loop_id, remote_fcport->d_id.b.domain,
		    remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
		    le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));

		if (atomic_read(&remote_fcport->state) != FCS_DEVICE_DEAD)
			atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
	}
	remote_fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;

	return (QLA_SUCCESS);
}


/**
 * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware.
 * @ha: HA context
 * @iodesc: io descriptor
 * @ha_locked: is function called with the hardware lock
 *
 * Returns QLA_SUCCESS if the IOCB was issued.
 */
static int
qla2x00_send_logout_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
    int ha_locked)
{
	unsigned long flags = 0;
	struct mbx_entry *mbxentry;

	/* Send marker if required. */
	if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
		return (QLA_FUNCTION_FAILED);

	if (!ha_locked)
		spin_lock_irqsave(&ha->hardware_lock, flags);

	/* Build fabric port logout mailbox IOCB. */
	mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
	if (mbxentry == NULL) {
		if (!ha_locked)
			spin_unlock_irqrestore(&ha->hardware_lock, flags);

		return (QLA_FUNCTION_FAILED);
	}
	mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);
	mbxentry->mb1 = mbxentry->loop_id.extended =
	    cpu_to_le16(iodesc->remote_fcport->loop_id);
	wmb();

	qla2x00_add_iodesc_timer(iodesc);

	/* Issue command to ISP. */
	qla2x00_isp_cmd(ha);

	if (!ha_locked)
		spin_unlock_irqrestore(&ha->hardware_lock, flags);

	DEBUG14(printk("scsi(%ld): Sending Logout IOCB (%08x) to [%x].\n",
	    ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));

	return (QLA_SUCCESS);
}

/**
 * qla2x00_send_logout_iocb_cb() - Fabric port logout IOCB callback.
 * @ha: HA context
 * @iodesc: io descriptor
 * @mbxstat: mailbox status IOCB
 *
 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
 * will be used for a retry.
 */
static int
qla2x00_send_logout_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
    struct mbx_entry *mbxstat)
{
	DEBUG14(printk("scsi(%ld): Logout IOCB -- sent to [%x/%02x%02x%02x], "
	    "status=%x mb0=%x mb1=%x.\n", ha->host_no,
	    iodesc->remote_fcport->loop_id,
	    iodesc->remote_fcport->d_id.b.domain,
	    iodesc->remote_fcport->d_id.b.area,
	    iodesc->remote_fcport->d_id.b.al_pa, le16_to_cpu(mbxstat->status),
	    le16_to_cpu(mbxstat->mb0), le16_to_cpu(mbxstat->mb1)));

	return (QLA_SUCCESS);
}


/**
 * qla2x00_send_login_iocb() - Issue a fabric port login IOCB to the firmware.
 * @ha: HA context
 * @iodesc: io descriptor
 * @d_id: port id for device
 * @ha_locked: is function called with the hardware lock
 *
 * Returns QLA_SUCCESS if the IOCB was issued.
 */
static int
qla2x00_send_login_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
    port_id_t *d_id, int ha_locked)
{
	unsigned long flags = 0;
	struct mbx_entry *mbxentry;

	/* Send marker if required. */
	if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
		return (QLA_FUNCTION_FAILED);

	if (!ha_locked)
		spin_lock_irqsave(&ha->hardware_lock, flags);

	/* Build fabric port login mailbox IOCB. */
	mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
	if (mbxentry == NULL) {
		if (!ha_locked)
			spin_unlock_irqrestore(&ha->hardware_lock, flags);

		return (QLA_FUNCTION_FAILED);
	}
	mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGIN_FABRIC_PORT);
	mbxentry->mb1 = mbxentry->loop_id.extended =
	    cpu_to_le16(iodesc->remote_fcport->loop_id);
	mbxentry->mb2 = cpu_to_le16(d_id->b.domain);
	mbxentry->mb3 = cpu_to_le16(d_id->b.area << 8 | d_id->b.al_pa);
	mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);
	wmb();

	qla2x00_add_iodesc_timer(iodesc);

	/* Issue command to ISP. */
	qla2x00_isp_cmd(ha);

	if (!ha_locked)
		spin_unlock_irqrestore(&ha->hardware_lock, flags);

	DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to "
	    "[%x/%02x%02x%02x].\n", ha->host_no, iodesc->signature,
	    iodesc->remote_fcport->loop_id, d_id->b.domain, d_id->b.area,
	    d_id->b.al_pa));

	return (QLA_SUCCESS);
}

/**
 * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback.
 * @ha: HA context
 * @iodesc: io descriptor
 * @mbxstat: mailbox status IOCB
 *
 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
 * will be used for a retry.
 */
static int
qla2x00_send_login_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
    struct mbx_entry *mbxstat)
{
	int rval;
	fc_port_t *fcport, *remote_fcport, *exist_fcport;
	struct io_descriptor *abort_iodesc, *login_iodesc;
	uint16_t status, mb[8];
	uint16_t reuse;
	uint16_t remote_loopid;
	port_id_t remote_did, inuse_did;

	remote_fcport = iodesc->remote_fcport;

	/* Only process the last command. */
	if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
		DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "
		    "[%02x%02x%02x], expected %x, received %x.\n",
		    ha->host_no, iodesc->d_id.b.domain, iodesc->d_id.b.area,
		    iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
		    iodesc->idx));

		/* Free RSCN fcport resources. */
		if (remote_fcport->port_type == FCT_RSCN) {
			DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN "
			    "fcport %p [%x/%02x%02x%02x] given ignored Login "
			    "IOCB.\n", ha->host_no, remote_fcport,
			    remote_fcport->loop_id,
			    remote_fcport->d_id.b.domain,
			    remote_fcport->d_id.b.area,
			    remote_fcport->d_id.b.al_pa));

			list_del(&remote_fcport->list);
			kfree(remote_fcport);
		}
		return (QLA_SUCCESS);
	}

	status = le16_to_cpu(mbxstat->status);
	mb[0] = le16_to_cpu(mbxstat->mb0);
	mb[1] = le16_to_cpu(mbxstat->mb1);
	mb[2] = le16_to_cpu(mbxstat->mb2);
	mb[6] = le16_to_cpu(mbxstat->mb6);
	mb[7] = le16_to_cpu(mbxstat->mb7);

	/* Good status? */
	if ((status == CS_COMPLETE || status == CS_COMPLETE_CHKCOND) &&
	    mb[0] == MBS_COMMAND_COMPLETE) {

		DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="
		    "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha->host_no, status,
		    mb[1], mbxstat->port_name[0], mbxstat->port_name[1],
		    mbxstat->port_name[2], mbxstat->port_name[3],
		    mbxstat->port_name[4], mbxstat->port_name[5],
		    mbxstat->port_name[6], mbxstat->port_name[7]));

		memcpy(remote_fcport->node_name, mbxstat->node_name, WWN_SIZE);
		memcpy(remote_fcport->port_name, mbxstat->port_name, WWN_SIZE);

		/* Is the device already in our fcports list? */
		if (remote_fcport->port_type != FCT_RSCN) {
			DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
			    "[%x/%02x%02x%02x] online.\n", ha->host_no,
			    remote_fcport->loop_id,
			    remote_fcport->d_id.b.domain,
			    remote_fcport->d_id.b.area,
			    remote_fcport->d_id.b.al_pa));

			qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);

			return (QLA_SUCCESS);
		}

		/* Does the RSCN portname already exist in our fcports list? */
		exist_fcport = NULL;
		list_for_each_entry(fcport, &ha->fcports, list) {
			if (memcmp(remote_fcport->port_name, fcport->port_name,
			    WWN_SIZE) == 0) {
				exist_fcport = fcport;
				break;
			}
		}
		if (exist_fcport != NULL) {
			DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN "
			    "fcport in fcports list [%p].\n", ha->host_no,
			    exist_fcport));

			/* Abort any ADISC that could have been sent. */
			if (exist_fcport->iodesc_idx_sent != iodesc->idx &&
			    exist_fcport->iodesc_idx_sent <
			    MAX_IO_DESCRIPTORS &&
			    ha->io_descriptors[exist_fcport->iodesc_idx_sent].
			    cb_idx == ADISC_PORT_IOCB_CB) {

				abort_iodesc = qla2x00_alloc_iodesc(ha);
				if (abort_iodesc) {
					DEBUG14(printk("scsi(%ld): Login IOCB "
					    "-- issuing abort to outstanding "
					    "Adisc [%x/%02x%02x%02x].\n",
					    ha->host_no, remote_fcport->loop_id,
					    exist_fcport->d_id.b.domain,
					    exist_fcport->d_id.b.area,
					    exist_fcport->d_id.b.al_pa));

					abort_iodesc->cb_idx = ABORT_IOCB_CB;
					abort_iodesc->d_id.b24 =
					    exist_fcport->d_id.b24;
					abort_iodesc->remote_fcport =
					    exist_fcport;
					exist_fcport->iodesc_idx_sent =
					    abort_iodesc->idx;
					qla2x00_send_abort_iocb(ha,
					    abort_iodesc, ha->io_descriptors[
					     exist_fcport->iodesc_idx_sent].
					      signature, 1);
				} else {
					DEBUG14(printk("scsi(%ld): Login IOCB "
					    "-- unable to abort outstanding "
					    "Adisc [%x/%02x%02x%02x].\n",
					    ha->host_no, remote_fcport->loop_id,
					    exist_fcport->d_id.b.domain,
					    exist_fcport->d_id.b.area,
					    exist_fcport->d_id.b.al_pa));
				}
			}

			/*
			 * If the existing fcport is waiting to send an ADISC
			 * or LOGIN, then reuse remote fcport (RSCN) to
			 * continue waiting.
			 */
			reuse = 0;
			remote_loopid = remote_fcport->loop_id;
			remote_did.b24 = remote_fcport->d_id.b24;
			if (exist_fcport->iodesc_idx_sent ==
			    IODESC_ADISC_NEEDED ||
			    exist_fcport->iodesc_idx_sent ==
			    IODESC_LOGIN_NEEDED) {
				DEBUG14(printk("scsi(%ld): Login IOCB -- "
				    "existing fcport [%x/%02x%02x%02x] "
				    "waiting for IO descriptor, reuse RSCN "
				    "fcport.\n", ha->host_no,
				    exist_fcport->loop_id,
				    exist_fcport->d_id.b.domain,
				    exist_fcport->d_id.b.area,
				    exist_fcport->d_id.b.al_pa));

				reuse++;
				remote_fcport->iodesc_idx_sent =
				    exist_fcport->iodesc_idx_sent;
				exist_fcport->iodesc_idx_sent =
				    IODESC_INVALID_INDEX;
				remote_fcport->loop_id = exist_fcport->loop_id;
				remote_fcport->d_id.b24 =
				    exist_fcport->d_id.b24;
			}

			/* Logout the old loopid. */
			if (!reuse &&
			    exist_fcport->loop_id != remote_fcport->loop_id &&
			    exist_fcport->loop_id != FC_NO_LOOP_ID) {
				login_iodesc = qla2x00_alloc_iodesc(ha);
				if (login_iodesc) {
					DEBUG14(printk("scsi(%ld): Login IOCB "
					    "-- issuing logout to free old "
					    "loop id [%x/%02x%02x%02x].\n",
					    ha->host_no, exist_fcport->loop_id,
					    exist_fcport->d_id.b.domain,
					    exist_fcport->d_id.b.area,
					    exist_fcport->d_id.b.al_pa));

					login_iodesc->cb_idx =
					    LOGOUT_PORT_IOCB_CB;
					login_iodesc->d_id.b24 =
					    exist_fcport->d_id.b24;
					login_iodesc->remote_fcport =
					    exist_fcport;
					exist_fcport->iodesc_idx_sent =
					    login_iodesc->idx;
					qla2x00_send_logout_iocb(ha,
					    login_iodesc, 1);
				} else {
					/* Ran out of IO descriptiors. */
					DEBUG14(printk("scsi(%ld): Login IOCB "
					    "-- unable to logout to free old "
					    "loop id [%x/%02x%02x%02x].\n",
					    ha->host_no, exist_fcport->loop_id,
					    exist_fcport->d_id.b.domain,
					    exist_fcport->d_id.b.area,
					    exist_fcport->d_id.b.al_pa));

					exist_fcport->iodesc_idx_sent =
					    IODESC_INVALID_INDEX;
				}

			}

			/* Update existing fcport with remote fcport info. */
			DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
			    "existing fcport [%x/%02x%02x%02x] online.\n",
			    ha->host_no, remote_loopid, remote_did.b.domain,
			    remote_did.b.area, remote_did.b.al_pa));

			memcpy(exist_fcport->node_name,
			    remote_fcport->node_name, WWN_SIZE);
			exist_fcport->loop_id = remote_loopid;
			exist_fcport->d_id.b24 = remote_did.b24;
			qla2x00_update_login_fcport(ha, mbxstat, exist_fcport);

			/* Finally, free the remote (RSCN) fcport. */
			if (!reuse) {
				DEBUG14(printk("scsi(%ld): Login IOCB -- "
				    "Freeing RSCN fcport %p "
				    "[%x/%02x%02x%02x].\n", ha->host_no,
				    remote_fcport, remote_fcport->loop_id,
				    remote_fcport->d_id.b.domain,
				    remote_fcport->d_id.b.area,
				    remote_fcport->d_id.b.al_pa));

				list_del(&remote_fcport->list);
				kfree(remote_fcport);
			}

			return (QLA_SUCCESS);
		}

		/*
		 * A new device has been added, move the RSCN fcport to our
		 * fcports list.
		 */
		DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport "
		    "[%x/%02x%02x%02x] to fcports list.\n", ha->host_no,
		    remote_fcport->loop_id, remote_fcport->d_id.b.domain,
		    remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));

		list_del(&remote_fcport->list);
		remote_fcport->flags = (FCF_RLC_SUPPORT | FCF_RESCAN_NEEDED);
		qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);
		list_add_tail(&remote_fcport->list, &ha->fcports);
		set_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags);
	} else {
		/* Handle login failure. */
		if (remote_fcport->login_retry != 0) {
			if (mb[0] == MBS_LOOP_ID_USED) {
				inuse_did.b.domain = LSB(mb[1]);
				inuse_did.b.area = MSB(mb[2]);
				inuse_did.b.al_pa = LSB(mb[2]);

				DEBUG14(printk("scsi(%ld): Login IOCB -- loop "
				    "id [%x] used by port id [%02x%02x%02x].\n",
				    ha->host_no, remote_fcport->loop_id,
				    inuse_did.b.domain, inuse_did.b.area,
				    inuse_did.b.al_pa));

				if (remote_fcport->d_id.b24 ==
				    INVALID_PORT_ID) {
					/*
					 * Invalid port id means we are trying
					 * to login to a remote port with just
					 * a loop id without knowing about the
					 * port id.  Copy the port id and try
					 * again.
					 */
					remote_fcport->d_id.b24 = inuse_did.b24;
					iodesc->d_id.b24 = inuse_did.b24;
				} else {
					remote_fcport->loop_id++;
					rval = qla2x00_find_new_loop_id(ha,
					    remote_fcport);
					if (rval == QLA_FUNCTION_FAILED) {
						/* No more loop ids. */
						return (QLA_SUCCESS);
					}
				}
			} else if (mb[0] == MBS_PORT_ID_USED) {
				/*
				 * Device has another loop ID.  The firmware
				 * group recommends the driver perform an
				 * implicit login with the specified ID.
				 */
				DEBUG14(printk("scsi(%ld): Login IOCB -- port "
				    "id [%02x%02x%02x] already assigned to "
				    "loop id [%x].\n", ha->host_no,
				    iodesc->d_id.b.domain, iodesc->d_id.b.area,
				    iodesc->d_id.b.al_pa, mb[1]));

				remote_fcport->loop_id = mb[1];

			} else {
				/* Unable to perform login, try again. */
				DEBUG14(printk("scsi(%ld): Login IOCB -- "
				    "failed login [%x/%02x%02x%02x], status=%x "
				    "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
				    ha->host_no, remote_fcport->loop_id,
				    iodesc->d_id.b.domain, iodesc->d_id.b.area,
				    iodesc->d_id.b.al_pa, status, mb[0], mb[1],
				    mb[2], mb[6], mb[7]));
			}

			/* Reissue Login with the same IO descriptor. */
			iodesc->signature =
			    qla2x00_iodesc_to_handle(iodesc);
			iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
			iodesc->d_id.b24 = remote_fcport->d_id.b24;
			remote_fcport->iodesc_idx_sent = iodesc->idx;
			remote_fcport->login_retry--;

			DEBUG14(printk("scsi(%ld): Login IOCB -- retrying "
			    "login to [%x/%02x%02x%02x] (%d).\n", ha->host_no,
			    remote_fcport->loop_id,
			    remote_fcport->d_id.b.domain,
			    remote_fcport->d_id.b.area,
			    remote_fcport->d_id.b.al_pa,
			    remote_fcport->login_retry));

			qla2x00_send_login_iocb(ha, iodesc,
			    &remote_fcport->d_id, 1);

			return (QLA_FUNCTION_FAILED);
		} else {
			/* No more logins, mark device dead. */
			DEBUG14(printk("scsi(%ld): Login IOCB -- failed "
			    "login [%x/%02x%02x%02x] after retries, status=%x "
			    "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
			    ha->host_no, remote_fcport->loop_id,
			    iodesc->d_id.b.domain, iodesc->d_id.b.area,
			    iodesc->d_id.b.al_pa, status, mb[0], mb[1],
			    mb[2], mb[6], mb[7]));

			atomic_set(&remote_fcport->state, FCS_DEVICE_DEAD);
			if (remote_fcport->port_type == FCT_RSCN) {
				DEBUG14(printk("scsi(%ld): Login IOCB -- "
				    "Freeing dead RSCN fcport %p "
				    "[%x/%02x%02x%02x].\n", ha->host_no,
				    remote_fcport, remote_fcport->loop_id,
				    remote_fcport->d_id.b.domain,
				    remote_fcport->d_id.b.area,
				    remote_fcport->d_id.b.al_pa));

				list_del(&remote_fcport->list);
				kfree(remote_fcport);
			}
		}
	}

	return (QLA_SUCCESS);
}


/**
 * IO descriptor processing routines.
 **/

/**
 * qla2x00_alloc_rscn_fcport() - Allocate an RSCN type fcport.
 * @ha: HA context
 * @flags: allocation flags
 *
 * Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
 */
fc_port_t *
qla2x00_alloc_rscn_fcport(scsi_qla_host_t *ha, int flags)
{
	fc_port_t *fcport;

	fcport = qla2x00_alloc_fcport(ha, flags);
	if (fcport == NULL)
		return (fcport);

	/* Setup RSCN fcport structure. */
	fcport->port_type = FCT_RSCN;

	return (fcport);
}

/**
 * qla2x00_handle_port_rscn() - Handle port RSCN.
 * @ha: HA context
 * @rscn_entry: RSCN entry
 * @fcport: fcport entry to updated
 *
 * Returns QLA_SUCCESS if the port RSCN was handled.
 */
int
qla2x00_handle_port_rscn(scsi_qla_host_t *ha, uint32_t rscn_entry,
    fc_port_t *known_fcport, int ha_locked)
{
	int	rval;
	port_id_t rscn_pid;
	fc_port_t *fcport, *remote_fcport, *rscn_fcport;
	struct io_descriptor *iodesc;

	remote_fcport = NULL;
	rscn_fcport = NULL;

	/* Prepare port id based on incoming entries. */
	if (known_fcport) {
		rscn_pid.b24 = known_fcport->d_id.b24;
		remote_fcport = known_fcport;

		DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
		    "fcport [%02x%02x%02x].\n", ha->host_no,
		    remote_fcport->d_id.b.domain, remote_fcport->d_id.b.area,
		    remote_fcport->d_id.b.al_pa));
	} else {
		rscn_pid.b.domain = LSB(MSW(rscn_entry));
		rscn_pid.b.area = MSB(LSW(rscn_entry));
		rscn_pid.b.al_pa = LSB(LSW(rscn_entry));

		DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
		    "port id [%02x%02x%02x].\n", ha->host_no,
		    rscn_pid.b.domain, rscn_pid.b.area, rscn_pid.b.al_pa));

		/*
		 * Search fcport lists for a known entry at the specified port
		 * ID.
		 */
		list_for_each_entry(fcport, &ha->fcports, list) {
		    if (rscn_pid.b24 == fcport->d_id.b24) {
			    remote_fcport = fcport;
			    break;
		    }
		}
		list_for_each_entry(fcport, &ha->rscn_fcports, list) {
		    if (rscn_pid.b24 == fcport->d_id.b24) {
			    rscn_fcport = fcport;
			    break;
		    }
		}
		if (remote_fcport == NULL)
		    remote_fcport = rscn_fcport;
	}

	/*
	 * If the port is already in our fcport list and online, send an ADISC
	 * to see if it's still alive.  Issue login if a new fcport or the known
	 * fcport is currently offline.
	 */
	if (remote_fcport) {
		/*
		 * No need to send request if the remote fcport is currently
		 * waiting for an available io descriptor.
		 */
		if (known_fcport == NULL &&
		    (remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
		    remote_fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED)) {
			/*
			 * If previous waiting io descriptor is an ADISC, then
			 * the new RSCN may come from a new remote fcport being
			 * plugged into the same location.
			 */
			if (remote_fcport->port_type == FCT_RSCN) {
			    remote_fcport->iodesc_idx_sent =
				IODESC_LOGIN_NEEDED;
			} else if (remote_fcport->iodesc_idx_sent ==
			    IODESC_ADISC_NEEDED) {
				fc_port_t *new_fcport;

				remote_fcport->iodesc_idx_sent =
				    IODESC_INVALID_INDEX;

				/* Create new fcport for later login. */
				new_fcport = qla2x00_alloc_rscn_fcport(ha,
				    ha_locked ? GFP_ATOMIC: GFP_KERNEL);
				if (new_fcport) {
					DEBUG14(printk("scsi(%ld): Handle RSCN "
					    "-- creating RSCN fcport %p for "
					    "future login.\n", ha->host_no,
					    new_fcport));

					new_fcport->d_id.b24 =
					    remote_fcport->d_id.b24;
					new_fcport->iodesc_idx_sent =
					    IODESC_LOGIN_NEEDED;

					list_add_tail(&new_fcport->list,
					    &ha->rscn_fcports);
					set_bit(IODESC_PROCESS_NEEDED,
					    &ha->dpc_flags);
				} else {
					DEBUG14(printk("scsi(%ld): Handle RSCN "
					    "-- unable to allocate RSCN fcport "
					    "for future login.\n",
					    ha->host_no));
				}
			}
			return (QLA_SUCCESS);
		}

		/* Send ADISC if the fcport is online */
		if (atomic_read(&remote_fcport->state) == FCS_ONLINE ||
		    remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED) {

			atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);

			iodesc = qla2x00_alloc_iodesc(ha);
			if (iodesc == NULL) {
				/* Mark fcport for later adisc processing */
				DEBUG14(printk("scsi(%ld): Handle RSCN -- not "
				    "enough IO descriptors for Adisc, flag "
				    "for later processing.\n", ha->host_no));

				remote_fcport->iodesc_idx_sent =
				    IODESC_ADISC_NEEDED;
				set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);

				return (QLA_SUCCESS);
			}

			iodesc->cb_idx = ADISC_PORT_IOCB_CB;
			iodesc->d_id.b24 = rscn_pid.b24;
			iodesc->remote_fcport = remote_fcport;
			remote_fcport->iodesc_idx_sent = iodesc->idx;
			qla2x00_send_adisc_iocb(ha, iodesc, ha_locked);

			return (QLA_SUCCESS);
		} else if (remote_fcport->iodesc_idx_sent <
		    MAX_IO_DESCRIPTORS &&
		    ha->io_descriptors[remote_fcport->iodesc_idx_sent].cb_idx ==
		    ADISC_PORT_IOCB_CB) {
			/*
			 * Receiving another RSCN while an ADISC is pending,
			 * abort the IOCB.  Use the same descriptor for the
			 * abort.
			 */
			uint32_t handle_to_abort;

			iodesc = &ha->io_descriptors[
				remote_fcport->iodesc_idx_sent];
			qla2x00_remove_iodesc_timer(iodesc);
			handle_to_abort = iodesc->signature;
			iodesc->signature = qla2x00_iodesc_to_handle(iodesc);
			iodesc->cb_idx = ABORT_IOCB_CB;
			iodesc->d_id.b24 = remote_fcport->d_id.b24;
			iodesc->remote_fcport = remote_fcport;
			remote_fcport->iodesc_idx_sent = iodesc->idx;

			DEBUG14(printk("scsi(%ld): Handle RSCN -- issuing "
			    "abort to outstanding Adisc [%x/%02x%02x%02x].\n",
			    ha->host_no, remote_fcport->loop_id,
			    iodesc->d_id.b.domain, iodesc->d_id.b.area,
			    iodesc->d_id.b.al_pa));

			qla2x00_send_abort_iocb(ha, iodesc, handle_to_abort,
			    ha_locked);
		}
	}

	/* We need to login to the remote port, find it. */
	if (known_fcport) {
		remote_fcport = known_fcport;
	} else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
	    rscn_fcport->iodesc_idx_sent < MAX_IO_DESCRIPTORS &&
	    ha->io_descriptors[rscn_fcport->iodesc_idx_sent].cb_idx ==
	    LOGIN_PORT_IOCB_CB) {
		/*
		 * Ignore duplicate RSCN on fcport which has already
		 * initiated a login IOCB.
		 */
		DEBUG14(printk("scsi(%ld): Handle RSCN -- ignoring, login "
		    "already sent to [%02x%02x%02x].\n", ha->host_no,
		    rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
		    rscn_fcport->d_id.b.al_pa));

		return (QLA_SUCCESS);
	} else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
	    rscn_fcport != remote_fcport) {
		/* Reuse same rscn fcport. */
		DEBUG14(printk("scsi(%ld): Handle RSCN -- reusing RSCN fcport "
		    "[%02x%02x%02x].\n", ha->host_no,
		    rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
		    rscn_fcport->d_id.b.al_pa));

		remote_fcport = rscn_fcport;
	} else {
		/* Create new fcport for later login. */
		remote_fcport = qla2x00_alloc_rscn_fcport(ha,
		    ha_locked ? GFP_ATOMIC: GFP_KERNEL);
		list_add_tail(&remote_fcport->list, &ha->rscn_fcports);
	}
	if (remote_fcport == NULL)
		return (QLA_SUCCESS);

	/* Prepare fcport for login. */
	atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
	remote_fcport->login_retry = 3; /* ha->login_retry_count; */
	remote_fcport->d_id.b24 = rscn_pid.b24;

	iodesc = qla2x00_alloc_iodesc(ha);
	if (iodesc == NULL) {
		/* Mark fcport for later adisc processing. */
		DEBUG14(printk("scsi(%ld): Handle RSCN -- not enough IO "
		    "descriptors for Login, flag for later processing.\n",
		    ha->host_no));

		remote_fcport->iodesc_idx_sent = IODESC_LOGIN_NEEDED;
		set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);

		return (QLA_SUCCESS);
	}

	if (known_fcport == NULL || rscn_pid.b24 != INVALID_PORT_ID) {
		remote_fcport->loop_id = ha->min_external_loopid;

		rval = qla2x00_find_new_loop_id(ha, remote_fcport);
		if (rval == QLA_FUNCTION_FAILED) {
			/* No more loop ids, failed. */
			DEBUG14(printk("scsi(%ld): Handle RSCN -- no available "
			    "loop id to perform Login, failed.\n",
			    ha->host_no));

			return (rval);
		}
	}

	iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
	iodesc->d_id.b24 = rscn_pid.b24;
	iodesc->remote_fcport = remote_fcport;
	remote_fcport->iodesc_idx_sent = iodesc->idx;

	DEBUG14(printk("scsi(%ld): Handle RSCN -- attempting login to "
	    "[%x/%02x%02x%02x].\n", ha->host_no, remote_fcport->loop_id,
	    iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa));

	qla2x00_send_login_iocb(ha, iodesc, &rscn_pid, ha_locked);

	return (QLA_SUCCESS);
}

/**
 * qla2x00_process_iodesc() - Complete IO descriptor processing.
 * @ha: HA context
 * @mbxstat: Mailbox IOCB status
 */
void
qla2x00_process_iodesc(scsi_qla_host_t *ha, struct mbx_entry *mbxstat)
{
	int rval;
	uint32_t signature;
	fc_port_t *fcport;
	struct io_descriptor *iodesc;

	signature = mbxstat->handle;

	DEBUG14(printk("scsi(%ld): Process IODesc -- processing %08x.\n",
	    ha->host_no, signature));

	/* Retrieve proper IO descriptor. */
	iodesc = qla2x00_handle_to_iodesc(ha, signature);
	if (iodesc == NULL) {
		DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
		    "incorrect signature %08x.\n", ha->host_no, signature));

		return;
	}

	/* Stop IO descriptor timer. */
	qla2x00_remove_iodesc_timer(iodesc);

	/* Verify signature match. */
	if (iodesc->signature != signature) {
		DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
		    "signature mismatch, sent %08x, received %08x.\n",
		    ha->host_no, iodesc->signature, signature));

		return;
	}

	/* Go with IOCB callback. */
	rval = iocb_function_cb_list[iodesc->cb_idx](ha, iodesc, mbxstat);
	if (rval != QLA_SUCCESS) {
		/* IO descriptor reused by callback. */
		return;
	}

	qla2x00_free_iodesc(iodesc);

	if (test_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags)) {
		/* Scan our fcports list for any RSCN requests. */
		list_for_each_entry(fcport, &ha->fcports, list) {
			if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
			    fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
				qla2x00_handle_port_rscn(ha, 0, fcport, 1);
				return;
			}
		}

		/* Scan our RSCN fcports list for any RSCN requests. */
		list_for_each_entry(fcport, &ha->rscn_fcports, list) {
			if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
			    fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
				qla2x00_handle_port_rscn(ha, 0, fcport, 1);
				return;
			}
		}
	}
	clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
}

/**
 * qla2x00_cancel_io_descriptors() - Cancel all outstanding io descriptors.
 * @ha: HA context
 *
 * This routine will also delete any RSCN entries related to the outstanding
 * IO descriptors.
 */
void
qla2x00_cancel_io_descriptors(scsi_qla_host_t *ha)
{
	fc_port_t *fcport, *fcptemp;

	clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);

	/* Abort all IO descriptors. */
	qla2x00_init_io_descriptors(ha);

	/* Reset all pending IO descriptors in fcports list. */
	list_for_each_entry(fcport, &ha->fcports, list) {
		fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
	}

	/* Reset all pending IO descriptors in rscn fcports list. */
	list_for_each_entry_safe(fcport, fcptemp, &ha->rscn_fcports, list) {
		DEBUG14(printk("scsi(%ld): Cancel IOs -- Freeing RSCN fcport "
		    "%p [%x/%02x%02x%02x].\n", ha->host_no, fcport,
		    fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
		    fcport->d_id.b.al_pa));

		list_del(&fcport->list);
		kfree(fcport);
	}
}
