/*
 * QLogic Fibre Channel HBA Driver
 * Copyright (c)  2003-2005 QLogic Corporation
 *
 * See LICENSE.qla2xxx for copyright and licensing 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);
	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);
	}
}
