/*
 * QLogic Fibre Channel HBA Driver
 * Copyright (c)  2003-2005 QLogic Corporation
 *
 * See LICENSE.qla2xxx for copyright and licensing details.
 */
#include "qla_def.h"

#include <scsi/scsi_transport_fc.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);
	schedule_work(&fcport->rport_add_work);
}


/**
 * 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, gfp_t 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);
	}
}
