Commit 6cbcc7ab authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull more SCSI updates from James Bottomley:
 "This series is all the stragglers that didn't quite make the first
  merge window pull. It's mostly minor updates and bug fixes of merge
  window code but it also has two driver updates: ufs and qla2xxx"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (46 commits)
  scsi: scsi_debug: Don't call kcalloc() if size arg is zero
  scsi: core: Remove command size deduction from scsi_setup_scsi_cmnd()
  scsi: scsi_ioctl: Validate command size
  scsi: ufs: ufshpb: Properly handle max-single-cmd
  scsi: core: Avoid leaving shost->last_reset with stale value if EH does not run
  scsi: bsg: Fix errno when scsi_bsg_register_queue() fails
  scsi: sr: Remove duplicate assignment
  scsi: ufs: ufs-exynos: Introduce ExynosAuto v9 virtual host
  scsi: ufs: ufs-exynos: Multi-host configuration for ExynosAuto v9
  scsi: ufs: ufs-exynos: Support ExynosAuto v9 UFS
  scsi: ufs: ufs-exynos: Add pre/post_hce_enable drv callbacks
  scsi: ufs: ufs-exynos: Factor out priv data init
  scsi: ufs: ufs-exynos: Add EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR option
  scsi: ufs: ufs-exynos: Support custom version of ufs_hba_variant_ops
  scsi: ufs: ufs-exynos: Add setup_clocks callback
  scsi: ufs: ufs-exynos: Add refclkout_stop control
  scsi: ufs: ufs-exynos: Simplify drv_data retrieval
  scsi: ufs: ufs-exynos: Change pclk available max value
  scsi: ufs: Add quirk to enable host controller without PH configuration
  scsi: ufs: Add quirk to handle broken UIC command
  ...
parents 030c28a0 3344b58b
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -4145,7 +4145,7 @@ static int
sli_get_read_config(struct sli4 *sli4)
{
	struct sli4_rsp_read_config *conf = sli4->bmbx.virt;
	u32 i, total, total_size;
	u32 i, total;
	u32 *base;

	if (sli_cmd_read_config(sli4, sli4->bmbx.virt)) {
@@ -4203,8 +4203,7 @@ sli_get_read_config(struct sli4 *sli4)

	for (i = 0; i < SLI4_RSRC_MAX; i++) {
		total = sli4->ext[i].number * sli4->ext[i].size;
		total_size = BITS_TO_LONGS(total) * sizeof(long);
		sli4->ext[i].use_map = kzalloc(total_size, GFP_KERNEL);
		sli4->ext[i].use_map = bitmap_zalloc(total, GFP_KERNEL);
		if (!sli4->ext[i].use_map) {
			efc_log_err(sli4, "bitmap memory allocation failed %d\n",
				    i);
@@ -4743,7 +4742,7 @@ sli_reset(struct sli4 *sli4)
	sli4->ext[0].base = NULL;

	for (i = 0; i < SLI4_RSRC_MAX; i++) {
		kfree(sli4->ext[i].use_map);
		bitmap_free(sli4->ext[i].use_map);
		sli4->ext[i].use_map = NULL;
		sli4->ext[i].base = NULL;
	}
@@ -4784,7 +4783,7 @@ sli_teardown(struct sli4 *sli4)
	for (i = 0; i < SLI4_RSRC_MAX; i++) {
		sli4->ext[i].base = NULL;

		kfree(sli4->ext[i].use_map);
		bitmap_free(sli4->ext[i].use_map);
		sli4->ext[i].use_map = NULL;
	}

+1 −0
Original line number Diff line number Diff line
@@ -388,6 +388,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
	shost->shost_state = SHOST_CREATED;
	INIT_LIST_HEAD(&shost->__devices);
	INIT_LIST_HEAD(&shost->__targets);
	INIT_LIST_HEAD(&shost->eh_abort_list);
	INIT_LIST_HEAD(&shost->eh_cmd_q);
	INIT_LIST_HEAD(&shost->starved_list);
	init_waitqueue_head(&shost->host_wait);
+6 −1
Original line number Diff line number Diff line
@@ -2762,7 +2762,12 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
			if (fcport->loop_id != FC_NO_LOOP_ID)
				fcport->logout_on_delete = 1;

			if (!EDIF_NEGOTIATION_PENDING(fcport)) {
				ql_dbg(ql_dbg_disc, fcport->vha, 0x911e,
				       "%s %d schedule session deletion\n", __func__,
				       __LINE__);
				qlt_schedule_sess_for_deletion(fcport);
			}
		} else {
			qla2x00_port_logout(fcport->vha, fcport);
		}
+2 −2
Original line number Diff line number Diff line
@@ -639,9 +639,9 @@ struct qla_els_pt_arg {
	u8 els_opcode;
	u8 vp_idx;
	__le16 nport_handle;
	u16 control_flags;
	u16 control_flags, ox_id;
	__le32 rx_xchg_address;
	port_id_t did;
	port_id_t did, sid;
	u32 tx_len, tx_byte_count, rx_len, rx_byte_count;
	dma_addr_t tx_addr, rx_addr;

+172 −156
Original line number Diff line number Diff line
@@ -218,7 +218,7 @@ fc_port_t *fcport)
		    "%s edif not enabled\n", __func__);
		goto done;
	}
	if (vha->e_dbell.db_flags != EDB_ACTIVE) {
	if (DBELL_INACTIVE(vha)) {
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "%s doorbell not enabled\n", __func__);
		goto done;
@@ -290,63 +290,6 @@ qla_edif_app_check(scsi_qla_host_t *vha, struct app_id appid)
	return false;
}

static void qla_edif_reset_auth_wait(struct fc_port *fcport, int state,
		int waitonly)
{
	int cnt, max_cnt = 200;
	bool traced = false;

	fcport->keep_nport_handle = 1;

	if (!waitonly) {
		qla2x00_set_fcport_disc_state(fcport, state);
		qlt_schedule_sess_for_deletion(fcport);
	} else {
		qla2x00_set_fcport_disc_state(fcport, state);
	}

	ql_dbg(ql_dbg_edif, fcport->vha, 0xf086,
		"%s: waiting for session, max_cnt=%u\n",
		__func__, max_cnt);

	cnt = 0;

	if (waitonly) {
		/* Marker wait min 10 msecs. */
		msleep(50);
		cnt += 50;
	}
	while (1) {
		if (!traced) {
			ql_dbg(ql_dbg_edif, fcport->vha, 0xf086,
			    "%s: session sleep.\n",
			    __func__);
			traced = true;
		}
		msleep(20);
		cnt++;
		if (waitonly && (fcport->disc_state == state ||
			fcport->disc_state == DSC_LOGIN_COMPLETE))
			break;
		if (fcport->disc_state == DSC_LOGIN_AUTH_PEND)
			break;
		if (cnt > max_cnt)
			break;
	}

	if (!waitonly) {
		ql_dbg(ql_dbg_edif, fcport->vha, 0xf086,
		    "%s: waited for session - %8phC, loopid=%x portid=%06x fcport=%p state=%u, cnt=%u\n",
		    __func__, fcport->port_name, fcport->loop_id,
		    fcport->d_id.b24, fcport, fcport->disc_state, cnt);
	} else {
		ql_dbg(ql_dbg_edif, fcport->vha, 0xf086,
		    "%s: waited ONLY for session - %8phC, loopid=%x portid=%06x fcport=%p state=%u, cnt=%u\n",
		    __func__, fcport->port_name, fcport->loop_id,
		    fcport->d_id.b24, fcport, fcport->disc_state, cnt);
	}
}

static void
qla_edif_free_sa_ctl(fc_port_t *fcport, struct edif_sa_ctl *sa_ctl,
	int index)
@@ -529,7 +472,8 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
	struct app_start_reply	appreply;
	struct fc_port  *fcport, *tf;

	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app start\n", __func__);
	ql_log(ql_log_info, vha, 0x1313,
	       "EDIF application registration with driver, FC device connections will be re-established.\n");

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &appstart,
@@ -538,9 +482,9 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app_vid=%x app_start_flags %x\n",
	     __func__, appstart.app_info.app_vid, appstart.app_start_flags);

	if (vha->e_dbell.db_flags != EDB_ACTIVE) {
	if (DBELL_INACTIVE(vha)) {
		/* mark doorbell as active since an app is now present */
		vha->e_dbell.db_flags = EDB_ACTIVE;
		vha->e_dbell.db_flags |= EDB_ACTIVE;
	} else {
		ql_dbg(ql_dbg_edif, vha, 0x911e, "%s doorbell already active\n",
		     __func__);
@@ -554,37 +498,36 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
		qla2xxx_wake_dpc(vha);
	} else {
		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
			ql_dbg(ql_dbg_edif, vha, 0x2058,
			       "FCSP - nn %8phN pn %8phN portid=%06x.\n",
			       fcport->node_name, fcport->port_name,
			       fcport->d_id.b24);
			ql_dbg(ql_dbg_edif, vha, 0xf084,
			       "%s: sess %p %8phC lid %#04x s_id %06x logout %d\n",
			       __func__, fcport, fcport->port_name,
			       fcport->loop_id, fcport->d_id.b24,
			       fcport->logout_on_delete);

			ql_dbg(ql_dbg_edif, vha, 0xf084,
			       "keep %d els_logo %d disc state %d auth state %d stop state %d\n",
			       fcport->keep_nport_handle,
			       fcport->send_els_logo, fcport->disc_state,
			       fcport->edif.auth_state, fcport->edif.app_stop);
			       "%s: se_sess %p / sess %p from port %8phC "
			       "loop_id %#04x s_id %06x logout %d "
			       "keep %d els_logo %d disc state %d auth state %d"
			       "stop state %d\n",
			       __func__, fcport->se_sess, fcport,
			       fcport->port_name, fcport->loop_id,
			       fcport->d_id.b24, fcport->logout_on_delete,
			       fcport->keep_nport_handle, fcport->send_els_logo,
			       fcport->disc_state, fcport->edif.auth_state,
			       fcport->edif.app_stop);

			if (atomic_read(&vha->loop_state) == LOOP_DOWN)
				break;
			if (!(fcport->flags & FCF_FCSP_DEVICE))
				continue;

			fcport->edif.app_started = 1;
			if (fcport->edif.app_stop ||
			    (fcport->disc_state != DSC_LOGIN_COMPLETE &&
			     fcport->disc_state != DSC_LOGIN_PEND &&
			     fcport->disc_state != DSC_DELETED)) {
			fcport->login_retry = vha->hw->login_retry_count;

			/* no activity */
			fcport->edif.app_stop = 0;

			ql_dbg(ql_dbg_edif, vha, 0x911e,
			       "%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
			       __func__, fcport->port_name);
				fcport->edif.app_sess_online = 1;
				qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0);
			}
			fcport->edif.app_sess_online = 0;
			qlt_schedule_sess_for_deletion(fcport);
			qla_edif_sa_ctl_init(vha, fcport);
		}
	}
@@ -601,13 +544,13 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
	appreply.edif_enode_active = vha->pur_cinfo.enode_flags;
	appreply.edif_edb_active = vha->e_dbell.db_flags;

	bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
	    sizeof(struct app_start_reply);
	bsg_job->reply_len = sizeof(struct fc_bsg_reply);

	SET_DID_STATUS(bsg_reply->result, DID_OK);

	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
	    bsg_job->reply_payload.sg_cnt, &appreply,
	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
							       bsg_job->reply_payload.sg_cnt,
							       &appreply,
							       sizeof(struct app_start_reply));

	ql_dbg(ql_dbg_edif, vha, 0x911d,
@@ -800,14 +743,14 @@ qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
		ql_dbg(ql_dbg_edif, vha, 0x911e,
		    "%s AUTH complete - RESUME with prli for wwpn %8phC\n",
		    __func__, fcport->port_name);
		qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 1);
		qla24xx_post_prli_work(vha, fcport);
	}

errstate_exit:
	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
	    bsg_job->reply_payload.sg_cnt, &appplogireply,
	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
							       bsg_job->reply_payload.sg_cnt,
							       &appplogireply,
							       sizeof(struct app_plogi_reply));

	return rval;
@@ -873,7 +816,7 @@ qla_edif_app_authfail(scsi_qla_host_t *vha, struct bsg_job *bsg_job)

		if (qla_ini_mode_enabled(fcport->vha)) {
			fcport->send_els_logo = 1;
			qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0);
			qlt_schedule_sess_for_deletion(fcport);
		}
	}

@@ -891,7 +834,7 @@ static int
qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	int32_t			rval = 0;
	int32_t			num_cnt;
	int32_t			pcnt = 0;
	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
	struct app_pinfo_req	app_req;
	struct app_pinfo_reply	*app_reply;
@@ -903,16 +846,14 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
	    bsg_job->request_payload.sg_cnt, &app_req,
	    sizeof(struct app_pinfo_req));

	num_cnt = app_req.num_ports;	/* num of ports alloc'd by app */

	app_reply = kzalloc((sizeof(struct app_pinfo_reply) +
	    sizeof(struct app_pinfo) * num_cnt), GFP_KERNEL);
	    sizeof(struct app_pinfo) * app_req.num_ports), GFP_KERNEL);

	if (!app_reply) {
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		rval = -1;
	} else {
		struct fc_port	*fcport = NULL, *tf;
		uint32_t	pcnt = 0;

		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
			if (!(fcport->flags & FCF_FCSP_DEVICE))
@@ -981,9 +922,11 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
		SET_DID_STATUS(bsg_reply->result, DID_OK);
	}

	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
	    bsg_job->reply_payload.sg_cnt, app_reply,
	    sizeof(struct app_pinfo_reply) + sizeof(struct app_pinfo) * num_cnt);
	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
							       bsg_job->reply_payload.sg_cnt,
							       app_reply,
							       sizeof(struct app_pinfo_reply) + sizeof(struct app_pinfo) * pcnt);

	kfree(app_reply);

@@ -1000,10 +943,11 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	int32_t			rval = 0;
	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
	uint32_t ret_size, size;
	uint32_t size;

	struct app_sinfo_req	app_req;
	struct app_stats_reply	*app_reply;
	uint32_t pcnt = 0;

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &app_req,
@@ -1019,18 +963,12 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
	size = sizeof(struct app_stats_reply) +
	    (sizeof(struct app_sinfo) * app_req.num_ports);

	if (size > bsg_job->reply_payload.payload_len)
		ret_size = bsg_job->reply_payload.payload_len;
	else
		ret_size = size;

	app_reply = kzalloc(size, GFP_KERNEL);
	if (!app_reply) {
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		rval = -1;
	} else {
		struct fc_port	*fcport = NULL, *tf;
		uint32_t	pcnt = 0;

		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
			if (fcport->edif.enable) {
@@ -1054,9 +992,11 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
		SET_DID_STATUS(bsg_reply->result, DID_OK);
	}

	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	bsg_reply->reply_payload_rcv_len =
	    sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
	       bsg_job->reply_payload.sg_cnt, app_reply, ret_size);
	       bsg_job->reply_payload.sg_cnt, app_reply,
	       sizeof(struct app_stats_reply) + (sizeof(struct app_sinfo) * pcnt));

	kfree(app_reply);

@@ -1130,8 +1070,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
		    __func__,
		    bsg_request->rqst_data.h_vendor.vendor_cmd[1]);
		rval = EXT_STATUS_INVALID_PARAM;
		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		done = false;
		break;
	}

@@ -1330,7 +1269,7 @@ qla24xx_sadb_update(struct bsg_job *bsg_job)
		goto done;
	}

	if (vha->e_dbell.db_flags != EDB_ACTIVE) {
	if (DBELL_INACTIVE(vha)) {
		ql_log(ql_log_warn, vha, 0x70a1, "App not started\n");
		rval = -EIO;
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
@@ -1651,6 +1590,40 @@ qla_enode_stop(scsi_qla_host_t *vha)
	spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);
}

static void qla_enode_clear(scsi_qla_host_t *vha, port_id_t portid)
{
	unsigned    long flags;
	struct enode    *e, *tmp;
	struct purexevent   *purex;
	LIST_HEAD(enode_list);

	if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		       "%s enode not active\n", __func__);
		return;
	}
	spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags);
	list_for_each_entry_safe(e, tmp, &vha->pur_cinfo.head, list) {
		purex = &e->u.purexinfo;
		if (purex->pur_info.pur_sid.b24 == portid.b24) {
			ql_dbg(ql_dbg_edif, vha, 0x911d,
			    "%s free ELS sid=%06x. xchg %x, nb=%xh\n",
			    __func__, portid.b24,
			    purex->pur_info.pur_rx_xchg_address,
			    purex->pur_info.pur_bytes_rcvd);

			list_del_init(&e->list);
			list_add_tail(&e->list, &enode_list);
		}
	}
	spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);

	list_for_each_entry_safe(e, tmp, &enode_list, list) {
		list_del_init(&e->list);
		qla_enode_free(vha, e);
	}
}

/*
 *  allocate enode struct and populate buffer
 *  returns: enode pointer with buffers
@@ -1695,43 +1668,27 @@ static struct enode *
qla_enode_find(scsi_qla_host_t *vha, uint32_t ntype, uint32_t p1, uint32_t p2)
{
	struct enode		*node_rtn = NULL;
	struct enode		*list_node = NULL;
	struct enode		*list_node, *q;
	unsigned long		flags;
	struct list_head	*pos, *q;
	uint32_t		sid;
	uint32_t		rw_flag;
	struct purexevent	*purex;

	/* secure the list from moving under us */
	spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags);

	list_for_each_safe(pos, q, &vha->pur_cinfo.head) {
		list_node = list_entry(pos, struct enode, list);
	list_for_each_entry_safe(list_node, q, &vha->pur_cinfo.head, list) {

		/* node type determines what p1 and p2 are */
		purex = &list_node->u.purexinfo;
		sid = p1;
		rw_flag = p2;

		if (purex->pur_info.pur_sid.b24 == sid) {
			if (purex->pur_info.pur_pend == 1 &&
			    rw_flag == PUR_GET) {
				/*
				 * if the receive is in progress
				 * and its a read/get then can't
				 * transfer yet
				 */
				ql_dbg(ql_dbg_edif, vha, 0x9106,
				    "%s purex xfer in progress for sid=%x\n",
				    __func__, sid);
			} else {
			/* found it and its complete */
			node_rtn = list_node;
				list_del(pos);
			list_del(&list_node->list);
			break;
		}
	}
	}

	spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);

@@ -1802,7 +1759,8 @@ qla_els_reject_iocb(scsi_qla_host_t *vha, struct qla_qpair *qp,
	qla_els_pt_iocb(vha, els_iocb, a);

	ql_dbg(ql_dbg_edif, vha, 0x0183,
	    "Sending ELS reject...\n");
	    "Sending ELS reject ox_id %04x s:%06x -> d:%06x\n",
	    a->ox_id, a->sid.b24, a->did.b24);
	ql_dump_buffer(ql_dbg_edif + ql_dbg_verbose, vha, 0x0185,
	    vha->hw->elsrej.c, sizeof(*vha->hw->elsrej.c));
	/* flush iocb to mem before notifying hw doorbell */
@@ -1814,7 +1772,7 @@ qla_els_reject_iocb(scsi_qla_host_t *vha, struct qla_qpair *qp,
void
qla_edb_init(scsi_qla_host_t *vha)
{
	if (vha->e_dbell.db_flags == EDB_ACTIVE) {
	if (DBELL_ACTIVE(vha)) {
		/* list already init'd - error */
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "edif db already initialized, cannot reinit\n");
@@ -1850,6 +1808,57 @@ qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node)
	node->ntype = N_UNDEF;
}

static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid)
{
	unsigned long flags;
	struct edb_node *e, *tmp;
	port_id_t sid;
	LIST_HEAD(edb_list);

	if (DBELL_INACTIVE(vha)) {
		/* doorbell list not enabled */
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		       "%s doorbell not enabled\n", __func__);
		return;
	}

	/* grab lock so list doesn't move */
	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
	list_for_each_entry_safe(e, tmp, &vha->e_dbell.head, list) {
		switch (e->ntype) {
		case VND_CMD_AUTH_STATE_NEEDED:
		case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
			sid = e->u.plogi_did;
			break;
		case VND_CMD_AUTH_STATE_ELS_RCVD:
			sid = e->u.els_sid;
			break;
		case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
			/* app wants to see this  */
			continue;
		default:
			ql_log(ql_log_warn, vha, 0x09102,
			       "%s unknown node type: %x\n", __func__, e->ntype);
			sid.b24 = 0;
			break;
		}
		if (sid.b24 == portid.b24) {
			ql_dbg(ql_dbg_edif, vha, 0x910f,
			       "%s free doorbell event : node type = %x %p\n",
			       __func__, e->ntype, e);
			list_del_init(&e->list);
			list_add_tail(&e->list, &edb_list);
		}
	}
	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);

	list_for_each_entry_safe(e, tmp, &edb_list, list) {
		qla_edb_node_free(vha, e);
		list_del_init(&e->list);
		kfree(e);
	}
}

/* function called when app is stopping */

void
@@ -1858,7 +1867,7 @@ qla_edb_stop(scsi_qla_host_t *vha)
	unsigned long flags;
	struct edb_node *node, *q;

	if (vha->e_dbell.db_flags != EDB_ACTIVE) {
	if (DBELL_INACTIVE(vha)) {
		/* doorbell list not enabled */
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "%s doorbell not enabled\n", __func__);
@@ -1909,7 +1918,7 @@ qla_edb_node_add(scsi_qla_host_t *vha, struct edb_node *ptr)
{
	unsigned long		flags;

	if (vha->e_dbell.db_flags != EDB_ACTIVE) {
	if (DBELL_INACTIVE(vha)) {
		/* doorbell list not enabled */
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "%s doorbell not enabled\n", __func__);
@@ -1940,7 +1949,7 @@ qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype,
		return;
	}

	if (vha->e_dbell.db_flags != EDB_ACTIVE) {
	if (DBELL_INACTIVE(vha)) {
		if (fcport)
			fcport->edif.auth_state = dbtype;
		/* doorbell list not enabled */
@@ -2035,7 +2044,7 @@ qla_edif_timer(scsi_qla_host_t *vha)
	struct qla_hw_data *ha = vha->hw;

	if (!vha->vp_idx && N2N_TOPO(ha) && ha->flags.n2n_fw_acc_sec) {
		if (vha->e_dbell.db_flags != EDB_ACTIVE &&
		if (DBELL_INACTIVE(vha) &&
		    ha->edif_post_stop_cnt_down) {
			ha->edif_post_stop_cnt_down--;

@@ -2073,7 +2082,7 @@ edif_doorbell_show(struct device *dev, struct device_attribute *attr,
	sz = 256;

	/* stop new threads from waiting if we're not init'd */
	if (vha->e_dbell.db_flags != EDB_ACTIVE) {
	if (DBELL_INACTIVE(vha)) {
		ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x09122,
		    "%s error - edif db not enabled\n", __func__);
		return 0;
@@ -2346,6 +2355,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
	a.tx_addr = vha->hw->elsrej.cdma;
	a.vp_idx = vha->vp_idx;
	a.control_flags = EPD_ELS_RJT;
	a.ox_id = le16_to_cpu(p->ox_id);

	sid = p->s_id[0] | (p->s_id[1] << 8) | (p->s_id[2] << 16);

@@ -2357,7 +2367,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
		return;
	}

	if (totlen > MAX_PAYLOAD) {
	if (totlen > ELS_MAX_PAYLOAD) {
		ql_dbg(ql_dbg_edif, vha, 0x0910d,
		    "%s WARNING: verbose ELS frame received (totlen=%x)\n",
		    __func__, totlen);
@@ -2387,7 +2397,6 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)

	purex = &ptr->u.purexinfo;
	purex->pur_info.pur_sid = a.did;
	purex->pur_info.pur_pend = 0;
	purex->pur_info.pur_bytes_rcvd = totlen;
	purex->pur_info.pur_rx_xchg_address = le32_to_cpu(p->rx_xchg_addr);
	purex->pur_info.pur_nphdl = le16_to_cpu(p->nport_handle);
@@ -2396,6 +2405,8 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
	purex->pur_info.pur_did.b.al_pa =  p->d_id[0];
	purex->pur_info.vp_idx = p->vp_idx;

	a.sid = purex->pur_info.pur_did;

	rc = __qla_copy_purex_to_buffer(vha, pkt, rsp, purex->msgp,
		purex->msgp_len);
	if (rc) {
@@ -2419,7 +2430,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)

	fcport = qla2x00_find_fcport_by_pid(host, &purex->pur_info.pur_sid);

	if (host->e_dbell.db_flags != EDB_ACTIVE ||
	if (DBELL_INACTIVE(vha) ||
	    (fcport && EDIF_SESSION_DOWN(fcport))) {
		ql_dbg(ql_dbg_edif, host, 0x0910c, "%s e_dbell.db_flags =%x %06x\n",
		    __func__, host->e_dbell.db_flags,
@@ -2436,7 +2447,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
	ql_dbg(ql_dbg_edif, host, 0x0910c,
	    "%s COMPLETE purex->pur_info.pur_bytes_rcvd =%xh s:%06x -> d:%06x xchg=%xh\n",
	    __func__, purex->pur_info.pur_bytes_rcvd, purex->pur_info.pur_sid.b24,
	    purex->pur_info.pur_did.b24, p->rx_xchg_addr);
	    purex->pur_info.pur_did.b24, purex->pur_info.pur_rx_xchg_address);

	qla_edb_eventcreate(host, VND_CMD_AUTH_STATE_ELS_RCVD, sid, 0, NULL);
}
@@ -3139,18 +3150,14 @@ static uint16_t qla_edif_sadb_get_sa_index(fc_port_t *fcport,
/* release any sadb entries -- only done at teardown */
void qla_edif_sadb_release(struct qla_hw_data *ha)
{
	struct list_head *pos;
	struct list_head *tmp;
	struct edif_sa_index_entry *entry;
	struct edif_sa_index_entry *entry, *tmp;

	list_for_each_safe(pos, tmp, &ha->sadb_rx_index_list) {
		entry = list_entry(pos, struct edif_sa_index_entry, next);
	list_for_each_entry_safe(entry, tmp, &ha->sadb_rx_index_list, next) {
		list_del(&entry->next);
		kfree(entry);
	}

	list_for_each_safe(pos, tmp, &ha->sadb_tx_index_list) {
		entry = list_entry(pos, struct edif_sa_index_entry, next);
	list_for_each_entry_safe(entry, tmp, &ha->sadb_tx_index_list, next) {
		list_del(&entry->next);
		kfree(entry);
	}
@@ -3449,7 +3456,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)

void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
{
	if (sess->edif.app_sess_online && vha->e_dbell.db_flags & EDB_ACTIVE) {
	if (sess->edif.app_sess_online && DBELL_ACTIVE(vha)) {
		ql_dbg(ql_dbg_disc, vha, 0xf09c,
			"%s: sess %8phN send port_offline event\n",
			__func__, sess->port_name);
@@ -3459,3 +3466,12 @@ void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
		qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24);
	}
}

void qla_edif_clear_appdata(struct scsi_qla_host *vha, struct fc_port *fcport)
{
	if (!(fcport->flags & FCF_FCSP_DEVICE))
		return;

	qla_edb_clear(vha, fcport->d_id);
	qla_enode_clear(vha, fcport->d_id);
}
Loading