Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a018d8ff authored by Hiral Patel's avatar Hiral Patel Committed by Christoph Hellwig
Browse files

qla2xxx: Check the QLA8044_CRB_DRV_ACTIVE_INDEX register when we are not the owner of the reset.

parent 1a5c69bf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@
 * | Virtual Port                 |       0xa007       |		|
 * | ISP82XX Specific             |       0xb157       | 0xb002,0xb024  |
 * |                              |                    | 0xb09e,0xb0ae  |
 * |				  |		       | 0xb0c3,0xb0c6  |
 * |                              |                    | 0xb0e0-0xb0ef  |
 * |                              |                    | 0xb085,0xb0dc  |
 * |                              |                    | 0xb107,0xb108  |
+57 −63
Original line number Diff line number Diff line
@@ -1633,7 +1633,7 @@ static void
qla8044_need_reset_handler(struct scsi_qla_host *vha)
{
	uint32_t dev_state = 0, drv_state, drv_active;
	unsigned long reset_timeout, dev_init_timeout;
	unsigned long reset_timeout;
	struct qla_hw_data *ha = vha->hw;

	ql_log(ql_log_fatal, vha, 0xb0c2,
@@ -1647,31 +1647,27 @@ qla8044_need_reset_handler(struct scsi_qla_host *vha)
		qla8044_idc_lock(ha);
	}

	dev_state = qla8044_rd_direct(vha,
	    QLA8044_CRB_DEV_STATE_INDEX);
	drv_state = qla8044_rd_direct(vha,
	    QLA8044_CRB_DRV_STATE_INDEX);
	drv_active = qla8044_rd_direct(vha,
	    QLA8044_CRB_DRV_ACTIVE_INDEX);

	ql_log(ql_log_info, vha, 0xb0c5,
	    "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
	    __func__, vha->host_no, drv_state, drv_active);
	    "%s(%ld): drv_state = 0x%x, drv_active = 0x%x dev_state = 0x%x\n",
	    __func__, vha->host_no, drv_state, drv_active, dev_state);

	if (!ha->flags.nic_core_reset_owner) {
		ql_dbg(ql_dbg_p3p, vha, 0xb0c3,
		    "%s(%ld): reset acknowledged\n",
		    __func__, vha->host_no);
	qla8044_set_rst_ready(vha);

		/* Non-reset owners ACK Reset and wait for device INIT state
		 * as part of Reset Recovery by Reset Owner
		 */
		dev_init_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
	/* wait for 10 seconds for reset ack from all functions */
	reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);

	do {
			if (time_after_eq(jiffies, dev_init_timeout)) {
		if (time_after_eq(jiffies, reset_timeout)) {
			ql_log(ql_log_info, vha, 0xb0c4,
				    "%s: Non Reset owner: Reset Ack Timeout!\n",
				    __func__);
			    "%s: Function %d: Reset Ack Timeout!, drv_state: 0x%08x, drv_active: 0x%08x\n",
			    __func__, ha->portnum, drv_state, drv_active);
			break;
		}

@@ -1681,50 +1677,48 @@ qla8044_need_reset_handler(struct scsi_qla_host *vha)

		dev_state = qla8044_rd_direct(vha,
		    QLA8044_CRB_DEV_STATE_INDEX);
		} while (((drv_state & drv_active) != drv_active) &&
		    (dev_state == QLA8XXX_DEV_NEED_RESET));
	} else {
		qla8044_set_rst_ready(vha);

		/* wait for 10 seconds for reset ack from all functions */
		reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);

		while ((drv_state & drv_active) != drv_active) {
			if (time_after_eq(jiffies, reset_timeout)) {
				ql_log(ql_log_info, vha, 0xb0c6,
				    "%s: RESET TIMEOUT!"
				    "drv_state: 0x%08x, drv_active: 0x%08x\n",
				    QLA2XXX_DRIVER_NAME, drv_state, drv_active);
				break;
			}

			qla8044_idc_unlock(ha);
			msleep(1000);
			qla8044_idc_lock(ha);

		drv_state = qla8044_rd_direct(vha,
		    QLA8044_CRB_DRV_STATE_INDEX);
		drv_active = qla8044_rd_direct(vha,
		    QLA8044_CRB_DRV_ACTIVE_INDEX);
		}
	} while (((drv_state & drv_active) != drv_active) &&
	    (dev_state == QLA8XXX_DEV_NEED_RESET));

	/* Remove IDC participation of functions not acknowledging */
	if (drv_state != drv_active) {
		ql_log(ql_log_info, vha, 0xb0c7,
			    "%s(%ld): Reset_owner turning off drv_active "
			    "of non-acking function 0x%x\n", __func__,
			    vha->host_no, (drv_active ^ drv_state));
		    "%s(%ld): Function %d turning off drv_active of non-acking function 0x%x\n",
		    __func__, vha->host_no, ha->portnum,
		    (drv_active ^ drv_state));
		drv_active = drv_active & drv_state;
		qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX,
		    drv_active);
	} else {
		/*
		 * Reset owner should execute reset recovery,
		 * if all functions acknowledged
		 */
		if ((ha->flags.nic_core_reset_owner) &&
		    (dev_state == QLA8XXX_DEV_NEED_RESET)) {
			ha->flags.nic_core_reset_owner = 0;
			qla8044_device_bootstrap(vha);
			return;
		}
	}

	/* Exit if non active function */
	if (!(drv_active & (1 << ha->portnum))) {
		ha->flags.nic_core_reset_owner = 0;
		return;
	}

	/*
		* Clear RESET OWNER, will be set at next reset
		* by next RST_OWNER
	 * Execute Reset Recovery if Reset Owner or Function 7
	 * is the only active function
	 */
	if (ha->flags.nic_core_reset_owner ||
	    ((drv_state & drv_active) == QLA8044_FUN7_ACTIVE_INDEX)) {
		ha->flags.nic_core_reset_owner = 0;

		/* Start Reset Recovery */
		qla8044_device_bootstrap(vha);
	}
}
+1 −0
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@
#define QLA8044_LINK_SPEED(f)		(0x36E0+(((f) >> 2) * 4))
#define QLA8044_MAX_LINK_SPEED(f)       (0x36F0+(((f) / 4) * 4))
#define QLA8044_LINK_SPEED_FACTOR	10
#define QLA8044_FUN7_ACTIVE_INDEX	0x80

/* FLASH API Defines */
#define QLA8044_FLASH_MAX_WAIT_USEC	100