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

Commit 8fcd6b8b authored by Chad Dupuis's avatar Chad Dupuis Committed by James Bottomley
Browse files

[SCSI] qla2xxx: Changes for ISP83xx loopback support.



Minor changes to support loopback functionality with ISP83xx CNAs.

Signed-off-by: default avatarGiridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: default avatarChad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent f9322eec
Loading
Loading
Loading
Loading
+41 −38
Original line number Diff line number Diff line
@@ -530,13 +530,13 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
done:
	return rval;
}

/* Set the port configuration to enable the
 * internal loopback on ISP81XX
/*
 * Set the port configuration to enable the internal or external loopback
 * depending on the loopback mode.
 */
static inline int
qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
    uint16_t *new_config)
qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
	uint16_t *new_config, uint16_t mode)
{
	int ret = 0;
	int rval = 0;
@@ -545,7 +545,13 @@ qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
		goto done_set_internal;

	if (mode == INTERNAL_LOOPBACK)
		new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1);
	else if (mode == EXTERNAL_LOOPBACK)
		new_config[0] = config[0] | (ENABLE_EXTERNAL_LOOPBACK << 1);
	ql_dbg(ql_dbg_user, vha, 0x70be,
	     "new_config[0]=%02x\n", (new_config[0] & INTERNAL_LOOPBACK_MASK));

	memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3);

	ha->notify_dcbx_comp = 1;
@@ -572,11 +578,9 @@ qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
	return rval;
}

/* Set the port configuration to disable the
 * internal loopback on ISP81XX
 */
/* Disable loopback mode */
static inline int
qla81xx_reset_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
    int wait)
{
	int ret = 0;
@@ -589,8 +593,12 @@ qla81xx_reset_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,

	memset(new_config, 0 , sizeof(new_config));
	if ((config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
			ENABLE_INTERNAL_LOOPBACK) {
	    ENABLE_INTERNAL_LOOPBACK ||
	    (config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
	    ENABLE_EXTERNAL_LOOPBACK) {
		new_config[0] = config[0] & ~INTERNAL_LOOPBACK_MASK;
		ql_dbg(ql_dbg_user, vha, 0x70bf, "new_config[0]=%02x\n",
		    (new_config[0] & INTERNAL_LOOPBACK_MASK));
		memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;

		ha->notify_dcbx_comp = wait;
@@ -707,7 +715,8 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)

	elreq.options = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];

	if ((ha->current_topology == ISP_CFG_F ||
	if (atomic_read(&vha->loop_state) == LOOP_READY &&
	    (ha->current_topology == ISP_CFG_F ||
	    ((IS_QLA81XX(ha) || IS_QLA8031(ha)) &&
	    le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE
	    && req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
@@ -729,31 +738,25 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
				goto done_free_dma_req;
			}

			if (elreq.options != EXTERNAL_LOOPBACK) {
				ql_dbg(ql_dbg_user, vha, 0x7020,
				    "Internal: current port config = %x\n",
				    config[0]);
				if (qla81xx_set_internal_loopback(vha, config,
					new_config)) {
					ql_log(ql_log_warn, vha, 0x7024,
					    "Internal loopback failed.\n");
					bsg_job->reply->result =
						(DID_ERROR << 16);
					rval = -EPERM;
					goto done_free_dma_req;
				}
			} else {
				/* For external loopback to work
				 * ensure internal loopback is disabled
				 */
				if (qla81xx_reset_internal_loopback(vha,
					config, 1)) {
					bsg_job->reply->result =
						(DID_ERROR << 16);
			ql_dbg(ql_dbg_user, vha, 0x70c0,
			    "elreq.options=%04x\n", elreq.options);

			if (elreq.options == EXTERNAL_LOOPBACK)
				if (IS_QLA8031(ha))
					rval = qla81xx_set_loopback_mode(vha,
					    config, new_config, elreq.options);
				else
					rval = qla81xx_reset_loopback_mode(vha,
					    config, 1);
			else
				rval = qla81xx_set_loopback_mode(vha, config,
				    new_config, elreq.options);

			if (rval) {
				bsg_job->reply->result = (DID_ERROR << 16);
				rval = -EPERM;
				goto done_free_dma_req;
			}
			}

			type = "FC_BSG_HST_VENDOR_LOOPBACK";
			ql_dbg(ql_dbg_user, vha, 0x7028,
@@ -766,7 +769,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
				/* Revert back to original port config
				 * Also clear internal loopback
				 */
				qla81xx_reset_internal_loopback(vha,
				qla81xx_reset_loopback_mode(vha,
				    new_config, 0);
			}

+2 −0
Original line number Diff line number Diff line
@@ -50,8 +50,10 @@
#define INT_DEF_LB_ECHO_CMD             1

/* Loopback related definations */
#define INTERNAL_LOOPBACK		0xF1
#define EXTERNAL_LOOPBACK		0xF2
#define ENABLE_INTERNAL_LOOPBACK	0x02
#define ENABLE_EXTERNAL_LOOPBACK	0x04
#define INTERNAL_LOOPBACK_MASK		0x000E
#define MAX_ELS_FRAME_PAYLOAD		252
#define ELS_OPCODE_BYTE			0x10
+2 −3
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@
 * | Device Discovery             |       0x2087       | 0x2020-0x2022  |
 * | Queue Command and IO tracing |       0x3030       | 0x3006,0x3008  |
 * |                              |                    | 0x302d-0x302e  |
 * | DPC Thread                   |       0x401c       | 0x4002,0x4013  |
 * | DPC Thread                   |       0x401d       | 0x4002,0x4013  |
 * | Async Events                 |       0x5071       | 0x502b-0x502f  |
 * |                              |                    | 0x5047,0x5052  |
 * | Timer Routines               |       0x6011       |                |
@@ -29,12 +29,11 @@
 * |                              |                    | 0x70a5,0x70a6, |
 * |                              |                    | 0x70a8,0x70ab, |
 * |                              |                    | 0x70ad-0x70ae  |
 * |                              |                    | 0x70be-70c0    |
 * | Task Management              |       0x803c       | 0x8025-0x8026  |
 * |                              |                    | 0x800b,0x8039  |
 * | AER/EEH                      |       0x9011       |		|
 * | Virtual Port                 |       0xa007       |		|
 * | ISP82XX Specific             |       0xb084       | 0xb002         |
 * | ISP82XX Specific             |       0xb084       | 0xb002,0xb024  |
 * |                              |                    | 0xb082,0xb083  |
 * | MultiQ                       |       0xc00c       |		|
 * | Misc                         |       0xd010       |		|
+1 −0
Original line number Diff line number Diff line
@@ -799,6 +799,7 @@ typedef struct {
#define MBC_SEND_RNFT_ELS		0x5e	/* Send RNFT ELS request */
#define MBC_GET_LINK_PRIV_STATS		0x6d	/* Get link & private data. */
#define MBC_SET_VENDOR_ID		0x76	/* Set Vendor ID. */
#define MBC_PORT_RESET			0x120	/* Port Reset */
#define MBC_SET_PORT_CONFIG		0x122	/* Set port configuration */
#define MBC_GET_PORT_CONFIG		0x123	/* Get port configuration */

+1 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ extern void qla2x00_update_fcports(scsi_qla_host_t *);

extern int qla2x00_abort_isp(scsi_qla_host_t *);
extern void qla2x00_abort_isp_cleanup(scsi_qla_host_t *);
extern void qla82xx_quiescent_state_cleanup(scsi_qla_host_t *);
extern void qla2x00_quiesce_io(scsi_qla_host_t *);

extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);

Loading