Re: [PATCH v2 08/10] qla2xxx: Add doorbell notification for app

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 5/31/21 9:05 AM, Nilesh Javali wrote:
> From: Quinn Tran <qutran@xxxxxxxxxxx>
> 
> Latest FC adapter from Marvell has the ability to encrypt
> data in flight (EDIF) feature. This feature require an
> application (ex: ipsec, etc) to act as an authenticator.
> 
> During runtime, driver and authentication application needs
> to stay in sync in terms of: session being down|up, arrival of
> new authentication message(AUTH ELS) and SADB update completion.
> 
> These events are queued up as doorbell to the authentication
> application. Application would read this doorbell on regular
> basis to stay up to date. Each SCSI host would have a separate
> doorbell queue.
> 
> The doorbell interface can daisy chain a list of events for
> each read. Each event contains an event code + hint to help
> application steer the next course of action.
> 
> Signed-off-by: Larry Wisneski <Larry.Wisneski@xxxxxxxxxxx>
> Signed-off-by: Duane Grigsby <duane.grigsby@xxxxxxxxxxx>
> Signed-off-by: Rick Hicksted Jr <rhicksted@xxxxxxxxxxx>
> Signed-off-by: Quinn Tran <qutran@xxxxxxxxxxx>
> Signed-off-by: Nilesh Javali <njavali@xxxxxxxxxxx>
> ---
>  drivers/scsi/qla2xxx/qla_attr.c   |   4 +
>  drivers/scsi/qla2xxx/qla_bsg.c    |  24 ++-
>  drivers/scsi/qla2xxx/qla_edif.c   | 342 ++++++++++++++++++++++++++++++
>  drivers/scsi/qla2xxx/qla_gbl.h    |   4 +
>  drivers/scsi/qla2xxx/qla_init.c   |   3 +
>  drivers/scsi/qla2xxx/qla_os.c     |   4 +
>  drivers/scsi/qla2xxx/qla_target.c |   2 +
>  7 files changed, 379 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
> index d78db2949ef6..22191e9a04a0 100644
> --- a/drivers/scsi/qla2xxx/qla_attr.c
> +++ b/drivers/scsi/qla2xxx/qla_attr.c
> @@ -2435,6 +2435,7 @@ static DEVICE_ATTR(port_speed, 0644, qla2x00_port_speed_show,
>      qla2x00_port_speed_store);
>  static DEVICE_ATTR(port_no, 0444, qla2x00_port_no_show, NULL);
>  static DEVICE_ATTR(fw_attr, 0444, qla2x00_fw_attr_show, NULL);
> +static DEVICE_ATTR_RO(edif_doorbell);
>  
>  
>  struct device_attribute *qla2x00_host_attrs[] = {
> @@ -2480,6 +2481,7 @@ struct device_attribute *qla2x00_host_attrs[] = {
>  	&dev_attr_port_no,
>  	&dev_attr_fw_attr,
>  	&dev_attr_dport_diagnostics,
> +	&dev_attr_edif_doorbell,
>  	NULL, /* reserve for qlini_mode */
>  	NULL, /* reserve for ql2xiniexchg */
>  	NULL, /* reserve for ql2xexchoffld */
> @@ -3108,6 +3110,8 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
>  
>  	qla_nvme_delete(vha);
>  	qla_enode_stop(vha);
> +	qla_edb_stop(vha);
> +
>  	vha->flags.delete_progress = 1;
>  
>  	qlt_remove_target(ha, vha);
> diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
> index 2d43603e31ec..0739f8ad525a 100644
> --- a/drivers/scsi/qla2xxx/qla_bsg.c
> +++ b/drivers/scsi/qla2xxx/qla_bsg.c
> @@ -2784,10 +2784,13 @@ qla2x00_manage_host_port(struct bsg_job *bsg_job)
>  }
>  
>  static int
> -qla2x00_process_vendor_specific(struct bsg_job *bsg_job)
> +qla2x00_process_vendor_specific(struct scsi_qla_host *vha, struct bsg_job *bsg_job)
>  {
>  	struct fc_bsg_request *bsg_request = bsg_job->request;
>  
> +	ql_dbg(ql_dbg_edif, vha, 0x911b, "%s FC_BSG_HST_VENDOR cmd[0]=0x%x\n",
> +	    __func__, bsg_request->rqst_data.h_vendor.vendor_cmd[0]);
> +
>  	switch (bsg_request->rqst_data.h_vendor.vendor_cmd[0]) {
>  	case QL_VND_LOOPBACK:
>  		return qla2x00_process_loopback(bsg_job);
> @@ -2916,12 +2919,19 @@ qla24xx_bsg_request(struct bsg_job *bsg_job)
>  		ql_dbg(ql_dbg_user, vha, 0x709f,
>  		    "BSG: ISP abort active/needed -- cmd=%d.\n",
>  		    bsg_request->msgcode);
> +		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
>  		return -EBUSY;
>  	}
>  
> +	if (test_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags)) {
> +		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
> +		return -EIO;
> +	}
> +
>  skip_chip_chk:
> -	ql_dbg(ql_dbg_user, vha, 0x7000,
> -	    "Entered %s msgcode=0x%x.\n", __func__, bsg_request->msgcode);
> +	ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x7000,
> +	    "Entered %s msgcode=0x%x. bsg ptr %px\n",
> +	    __func__, bsg_request->msgcode, bsg_job);
>  
>  	switch (bsg_request->msgcode) {
>  	case FC_BSG_RPT_ELS:
> @@ -2932,7 +2942,7 @@ qla24xx_bsg_request(struct bsg_job *bsg_job)
>  		ret = qla2x00_process_ct(bsg_job);
>  		break;
>  	case FC_BSG_HST_VENDOR:
> -		ret = qla2x00_process_vendor_specific(bsg_job);
> +		ret = qla2x00_process_vendor_specific(vha, bsg_job);
>  		break;
>  	case FC_BSG_HST_ADD_RPORT:
>  	case FC_BSG_HST_DEL_RPORT:
> @@ -2941,6 +2951,10 @@ qla24xx_bsg_request(struct bsg_job *bsg_job)
>  		ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n");
>  		break;
>  	}
> +
> +	ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x7000,
> +	    "%s done with return %x\n", __func__, ret);
> +
>  	return ret;
>  }
>  
> @@ -2955,6 +2969,8 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_job)
>  	unsigned long flags;
>  	struct req_que *req;
>  
> +	ql_log(ql_log_info, vha, 0x708b, "%s CMD timeout. bsg ptr %p.\n",
> +	    __func__, bsg_job);
>  	/* find the bsg job from the active list of commands */
>  	spin_lock_irqsave(&ha->hardware_lock, flags);
>  	for (que = 0; que < ha->max_req_queues; que++) {
> diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
> index 0fa6a1420c30..721898afb064 100644
> --- a/drivers/scsi/qla2xxx/qla_edif.c
> +++ b/drivers/scsi/qla2xxx/qla_edif.c
> @@ -19,6 +19,18 @@ static int qla_edif_sadb_delete_sa_index(fc_port_t *fcport, uint16_t nport_handl
>  		uint16_t sa_index);
>  static int qla_pur_get_pending(scsi_qla_host_t *, fc_port_t *, struct bsg_job *);
>  
> +struct edb_node {
> +	struct  list_head	list;
> +	uint32_t		ntype;
> +	uint32_t		lstate;
> +	union {
> +		port_id_t	plogi_did;
> +		uint32_t	async;
> +		port_id_t	els_sid;
> +		struct edif_sa_update_aen	sa_aen;
> +	} u;
> +};
> +
>  static struct els_sub_cmd {
>  	uint16_t cmd;
>  	const char *str;
> @@ -455,6 +467,10 @@ static void __qla2x00_release_all_sadb(struct scsi_qla_host *vha,
>  					/* build and send the aen */
>  					fcport->edif.rx_sa_set = 1;
>  					fcport->edif.rx_sa_pending = 0;
> +					qla_edb_eventcreate(vha,
> +							VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
> +							QL_VND_SA_STAT_SUCCESS,
> +							QL_VND_RX_SA_KEY, fcport);
>  				}
>  				ql_dbg(ql_dbg_edif, vha, 0x5033,
>  	"%s: releasing edif_entry %p, update_sa_index: 0x%x, delete_sa_index: 0x%x\n",
> @@ -547,6 +563,12 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
>  			    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);
> +
>  			if (atomic_read(&vha->loop_state) == LOOP_DOWN)
>  				break;
>  
> @@ -1232,6 +1254,10 @@ qla24xx_check_sadb_avail_slot(struct bsg_job *bsg_job, fc_port_t *fcport,
>  		/* build and send the aen */
>  		fcport->edif.rx_sa_set = 1;
>  		fcport->edif.rx_sa_pending = 0;
> +		qla_edb_eventcreate(fcport->vha,
> +		    VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
> +		    QL_VND_SA_STAT_SUCCESS,
> +		    QL_VND_RX_SA_KEY, fcport);
>  
>  		/* force a return of good bsg status; */
>  		return RX_DELETE_NO_EDIF_SA_INDEX;
> @@ -1806,17 +1832,314 @@ qla_els_reject_iocb(scsi_qla_host_t *vha, struct qla_qpair *qp,
>  	qla2x00_start_iocbs(vha, qp->req);
>  	return 0;
>  }
> +
> +void
> +qla_edb_init(scsi_qla_host_t *vha)
> +{
> +	if (vha->e_dbell.db_flags == EDB_ACTIVE) {
> +		/* list already init'd - error */
> +		ql_dbg(ql_dbg_edif, vha, 0x09102,
> +		    "edif db already initialized, cannot reinit\n");
> +		return;
> +	}
> +
> +	/* initialize lock which protects doorbell & init list */
> +	spin_lock_init(&vha->e_dbell.db_lock);
> +	INIT_LIST_HEAD(&vha->e_dbell.head);
> +
> +	/* create and initialize doorbell */
> +	init_completion(&vha->e_dbell.dbell);
> +}
> +
> +static void
> +qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node)
> +{
> +	/*
> +	 * releases the space held by this edb node entry
> +	 * this function does _not_ free the edb node itself
> +	 * NB: the edb node entry passed should not be on any list
> +	 *
> +	 * currently for doorbell there's no additional cleanup
> +	 * needed, but here as a placeholder for furture use.
> +	 */
> +
> +	if (!node) {
> +		ql_dbg(ql_dbg_edif, vha, 0x09122,
> +		    "%s error - no valid node passed\n", __func__);
> +		return;
> +	}
> +
> +	node->lstate = LSTATE_DEST;
> +	node->ntype = N_UNDEF;
> +}
> +
>  /* function called when app is stopping */
>  
>  void
>  qla_edb_stop(scsi_qla_host_t *vha)
>  {
> +	unsigned long flags;
> +	struct edb_node *node, *q;
> +
>  	if (vha->e_dbell.db_flags != EDB_ACTIVE) {
>  		/* 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);
> +
> +	vha->e_dbell.db_flags &= ~EDB_ACTIVE; /* mark it not active */
> +	/* hopefully this is a null list at this point */
> +	list_for_each_entry_safe(node, q, &vha->e_dbell.head, list) {
> +		ql_dbg(ql_dbg_edif, vha, 0x910f,
> +		    "%s freeing edb_node type=%x\n",
> +		    __func__, node->ntype);
> +		qla_edb_node_free(vha, node);
> +		list_del(&node->list);
> +
> +		spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
> +		kfree(node);
> +		spin_lock_irqsave(&vha->e_dbell.db_lock, flags);

Unlock before kfree?
Why?

> +	}
> +	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
> +
> +	/* wake up doorbell waiters - they'll be dismissed with error code */
> +	complete_all(&vha->e_dbell.dbell);
> +}
> +
> +static struct edb_node *
> +qla_edb_node_alloc(scsi_qla_host_t *vha, uint32_t ntype)
> +{
> +	struct edb_node	*node;
> +
> +	node = kzalloc(sizeof(*node), GFP_ATOMIC);
> +	if (!node) {
> +		/* couldn't get space */
> +		ql_dbg(ql_dbg_edif, vha, 0x9100,
> +		    "edb node unable to be allocated\n");
> +		return NULL;
> +	}
> +
> +	node->lstate = LSTATE_OFF;
> +	node->ntype = ntype;
> +	INIT_LIST_HEAD(&node->list);
> +	return node;
> +}
> +
> +/* adds a already alllocated enode to the linked list */
> +static bool
> +qla_edb_node_add(scsi_qla_host_t *vha, struct edb_node *ptr)
> +{
> +	unsigned long		flags;
> +
> +	if (ptr->lstate != LSTATE_OFF) {
> +		ql_dbg(ql_dbg_edif, vha, 0x911a,
> +		    "%s error edb node(%p) state=%x\n",
> +		    __func__, ptr, ptr->lstate);
> +		return false;
> +	}
> +
> +	if (vha->e_dbell.db_flags != EDB_ACTIVE) {
> +		/* doorbell list not enabled */
> +		ql_dbg(ql_dbg_edif, vha, 0x09102,
> +		    "%s doorbell not enabled\n", __func__);
> +		return false;
> +	}
> +
> +	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
> +	ptr->lstate = LSTATE_ON;

LSTATE_ON can be replaced by a check for list_empty()

> +	list_add_tail(&ptr->list, &vha->e_dbell.head);
> +	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
> +
> +	/* ring doorbell for waiters */
> +	complete(&vha->e_dbell.dbell);
> +
> +	return true;
> +}
> +
> +/* adds event to doorbell list */
> +void
> +qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype,
> +	uint32_t data, uint32_t data2, fc_port_t	*sfcport)
> +{
> +	struct edb_node	*edbnode;
> +	fc_port_t *fcport = sfcport;
> +	port_id_t id;
> +
> +	if (!vha->hw->flags.edif_enabled) {
> +		/* edif not enabled */
> +		return;
> +	}
> +
> +	if (vha->e_dbell.db_flags != EDB_ACTIVE) {
> +		if (fcport)
> +			fcport->edif.auth_state = dbtype;
> +		/* doorbell list not enabled */
> +		ql_dbg(ql_dbg_edif, vha, 0x09102,
> +		    "%s doorbell not enabled (type=%d\n", __func__, dbtype);
> +		return;
> +	}
> +
> +	edbnode = qla_edb_node_alloc(vha, dbtype);
> +	if (!edbnode) {
> +		ql_dbg(ql_dbg_edif, vha, 0x09102,
> +		    "%s unable to alloc db node\n", __func__);
> +		return;
> +	}
> +
> +	if (!fcport) {
> +		id.b.domain = (data >> 16) & 0xff;
> +		id.b.area = (data >> 8) & 0xff;
> +		id.b.al_pa = data & 0xff;
> +		ql_dbg(ql_dbg_edif, vha, 0x09222,
> +		    "%s: Arrived s_id: %06x\n", __func__,
> +		    id.b24);
> +		fcport = qla2x00_find_fcport_by_pid(vha, &id);
> +		if (!fcport) {
> +			ql_dbg(ql_dbg_edif, vha, 0x09102,
> +			    "%s can't find fcport for sid= 0x%x - ignoring\n",
> +			__func__, id.b24);
> +			kfree(edbnode);
> +			return;
> +		}
> +	}
> +
> +	/* populate the edb node */
> +	switch (dbtype) {
> +	case VND_CMD_AUTH_STATE_NEEDED:
> +	case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
> +		edbnode->u.plogi_did.b24 = fcport->d_id.b24;
> +		break;
> +	case VND_CMD_AUTH_STATE_ELS_RCVD:
> +		edbnode->u.els_sid.b24 = fcport->d_id.b24;
> +		break;
> +	case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
> +		edbnode->u.sa_aen.port_id = fcport->d_id;
> +		edbnode->u.sa_aen.status =  data;
> +		edbnode->u.sa_aen.key_type =  data2;
> +		break;
> +	default:
> +		ql_dbg(ql_dbg_edif, vha, 0x09102,
> +			"%s unknown type: %x\n", __func__, dbtype);
> +		qla_edb_node_free(vha, edbnode);
> +		kfree(edbnode);
> +		edbnode = NULL;
> +		break;
> +	}
> +
> +	if (edbnode && (!qla_edb_node_add(vha, edbnode))) {
> +		ql_dbg(ql_dbg_edif, vha, 0x09102,
> +		    "%s unable to add dbnode\n", __func__);
> +		qla_edb_node_free(vha, edbnode);
> +		kfree(edbnode);
> +		return;
> +	}
> +	if (edbnode && fcport)
> +		fcport->edif.auth_state = dbtype;
> +	ql_dbg(ql_dbg_edif, vha, 0x09102,
> +	    "%s Doorbell produced : type=%d %p\n", __func__, dbtype, edbnode);
> +}
> +
> +static struct edb_node *
> +qla_edb_getnext(scsi_qla_host_t *vha)
> +{
> +	unsigned long	flags;
> +	struct edb_node	*edbnode = NULL;
> +
> +	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
> +
> +	/* db nodes are fifo - no qualifications done */
> +	if (!list_empty(&vha->e_dbell.head)) {
> +		edbnode = list_first_entry(&vha->e_dbell.head,
> +		    struct edb_node, list);
> +		list_del(&edbnode->list);
> +		edbnode->lstate = LSTATE_OFF;
> +	}
> +
> +	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
> +
> +	return edbnode;
> +}
> +
> +/*
> + * app uses separate thread to read this. It'll wait until the doorbell
> + * is rung by the driver or the max wait time has expired
> + */
> +ssize_t
> +edif_doorbell_show(struct device *dev, struct device_attribute *attr,
> +		char *buf)
> +{
> +	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
> +	struct edb_node	*dbnode = NULL;
> +	struct edif_app_dbell *ap = (struct edif_app_dbell *)buf;
> +	uint32_t dat_siz, buf_size, sz;
> +
> +	sz = 256; /* app currently hardcode to 256. */

Shouldn't that be 'sizeof(struct edif_app_dbell)'?
And shouldn't that rather be a compile-time warning, then?

> +
> +	/* stop new threads from waiting if we're not init'd */
> +	if (vha->e_dbell.db_flags != EDB_ACTIVE) {
> +		ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x09122,
> +		    "%s error - edif db not enabled\n", __func__);
> +		return 0;
> +	}
> +
> +	if (!vha->hw->flags.edif_enabled) {
> +		/* edif not enabled */
> +		ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x09122,
> +		    "%s error - edif not enabled\n", __func__);
> +		return -1;
> +	}
> +
> +	buf_size = 0;
> +	while ((sz - buf_size) >= sizeof(struct edb_node)) {
> +		/* remove the next item from the doorbell list */
> +		dat_siz = 0;
> +		dbnode = qla_edb_getnext(vha);
> +		if (dbnode) {
> +			ap->event_code = dbnode->ntype;
> +			switch (dbnode->ntype) {
> +			case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
> +			case VND_CMD_AUTH_STATE_NEEDED:
> +				ap->port_id = dbnode->u.plogi_did;
> +				dat_siz += sizeof(ap->port_id);
> +				break;
> +			case VND_CMD_AUTH_STATE_ELS_RCVD:
> +				ap->port_id = dbnode->u.els_sid;
> +				dat_siz += sizeof(ap->port_id);
> +				break;
> +			case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
> +				ap->port_id = dbnode->u.sa_aen.port_id;
> +				memcpy(ap->event_data, &dbnode->u,
> +						sizeof(struct edif_sa_update_aen));
> +				dat_siz += sizeof(struct edif_sa_update_aen);
> +				break;
> +			default:
> +				/* unknown node type, rtn unknown ntype */
> +				ap->event_code = VND_CMD_AUTH_STATE_UNDEF;
> +				memcpy(ap->event_data, &dbnode->ntype, 4);
> +				dat_siz += 4;
> +				break;
> +			}
> +
> +			ql_dbg(ql_dbg_edif, vha, 0x09102,
> +				"%s Doorbell consumed : type=%d %p\n",
> +				__func__, dbnode->ntype, dbnode);
> +			/* we're done with the db node, so free it up */
> +			qla_edb_node_free(vha, dbnode);
> +			kfree(dbnode);
> +		} else {
> +			break;
> +		}
> +
> +		ap->event_data_size = dat_siz;
> +		/* 8bytes = ap->event_code + ap->event_data_size */
> +		buf_size += dat_siz + 8;
> +		ap = (struct edif_app_dbell *)(buf + buf_size);
> +	}
> +	return buf_size;
>  }
>  
>  static void qla_noop_sp_done(srb_t *sp, int res)
> @@ -2138,6 +2461,8 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
>  	    __func__, purex->pur_info.pur_bytes_rcvd,
>  	    purex->pur_info.pur_sid.b24,
>  	    purex->pur_info.pur_did.b24, p->rx_xchg_addr);
> +
> +	qla_edb_eventcreate(host, VND_CMD_AUTH_STATE_ELS_RCVD, sid, 0, NULL);
>  }
>  
>  static uint16_t  qla_edif_get_sa_index_from_freepool(fc_port_t *fcport, int dir)
> @@ -2356,9 +2681,15 @@ qla28xx_sa_update_iocb_entry(scsi_qla_host_t *v, struct req_que *req,
>  		if (pkt->flags & SA_FLAG_TX) {
>  			sp->fcport->edif.tx_sa_set = 1;
>  			sp->fcport->edif.tx_sa_pending = 0;
> +			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
> +				QL_VND_SA_STAT_SUCCESS,
> +				QL_VND_TX_SA_KEY, sp->fcport);
>  		} else {
>  			sp->fcport->edif.rx_sa_set = 1;
>  			sp->fcport->edif.rx_sa_pending = 0;
> +			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
> +				QL_VND_SA_STAT_SUCCESS,
> +				QL_VND_RX_SA_KEY, sp->fcport);
>  		}
>  	} else {
>  		ql_dbg(ql_dbg_edif, vha, 0x3063,
> @@ -2366,6 +2697,15 @@ qla28xx_sa_update_iocb_entry(scsi_qla_host_t *v, struct req_que *req,
>  		    __func__, sp->fcport->port_name,
>  		    pkt->sa_index, pkt->new_sa_info, pkt->port_id[2],
>  		    pkt->port_id[1], pkt->port_id[0]);
> +
> +		if (pkt->flags & SA_FLAG_TX)
> +			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
> +				(le16_to_cpu(pkt->u.comp_sts) << 16) | QL_VND_SA_STAT_FAILED,
> +				QL_VND_TX_SA_KEY, sp->fcport);
> +		else
> +			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
> +				(le16_to_cpu(pkt->u.comp_sts) << 16) | QL_VND_SA_STAT_FAILED,
> +				QL_VND_RX_SA_KEY, sp->fcport);
>  	}
>  
>  	/* for delete, release sa_ctl, sa_index */
> @@ -2872,6 +3212,8 @@ void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
>  			"%s: sess %8phN send port_offline event\n",
>  			__func__, sess->port_name);
>  		sess->edif.app_sess_online = 0;
> +		qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SESSION_SHUTDOWN,
> +		    sess->d_id.b24, 0, sess);
>  		qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24);
>  	}
>  }
> diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
> index c695f5a58d4d..cc78339b47ac 100644
> --- a/drivers/scsi/qla2xxx/qla_gbl.h
> +++ b/drivers/scsi/qla2xxx/qla_gbl.h
> @@ -981,11 +981,15 @@ void qla_nvme_unregister_remote_port(struct fc_port *fcport);
>  
>  /* qla_edif.c */
>  fc_port_t *qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id);
> +void qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype, uint32_t data, uint32_t data2,
> +		fc_port_t *fcport);
>  void qla_edb_stop(scsi_qla_host_t *vha);
> +ssize_t edif_doorbell_show(struct device *dev, struct device_attribute *attr, char *buf);
>  int32_t qla_edif_app_mgmt(struct bsg_job *bsg_job);
>  void qla_enode_init(scsi_qla_host_t *vha);
>  void qla_enode_stop(scsi_qla_host_t *vha);
>  void qla_edif_flush_sa_ctl_lists(fc_port_t *fcport);
> +void qla_edb_init(scsi_qla_host_t *vha);
>  void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb);
>  void qla24xx_sa_replace_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb);
>  void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp);
> diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
> index 7a20b1ddc63f..bef9bf59bc50 100644
> --- a/drivers/scsi/qla2xxx/qla_init.c
> +++ b/drivers/scsi/qla2xxx/qla_init.c
> @@ -1474,6 +1474,9 @@ static int	qla_chk_secure_login(scsi_qla_host_t	*vha, fc_port_t *fcport,
>  				    __func__, __LINE__, fcport->port_name);
>  				fcport->edif.app_started = 1;
>  				fcport->edif.app_sess_online = 1;
> +
> +				qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED,
> +				    fcport->d_id.b24, 0, fcport);
>  			}
>  
>  			rc = 1;
> diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
> index 0b379ac179fa..efc21ef80142 100644
> --- a/drivers/scsi/qla2xxx/qla_os.c
> +++ b/drivers/scsi/qla2xxx/qla_os.c
> @@ -3490,6 +3490,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
>  
>  probe_failed:
>  	qla_enode_stop(base_vha);
> +	qla_edb_stop(base_vha);
>  	if (base_vha->gnl.l) {
>  		dma_free_coherent(&ha->pdev->dev, base_vha->gnl.size,
>  				base_vha->gnl.l, base_vha->gnl.ldma);
> @@ -3793,6 +3794,7 @@ qla2x00_remove_one(struct pci_dev *pdev)
>  
>  	base_vha->gnl.l = NULL;
>  	qla_enode_stop(base_vha);
> +	qla_edb_stop(base_vha);
>  
>  	vfree(base_vha->scan.l);
>  
> @@ -4919,6 +4921,8 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
>  	init_waitqueue_head(&vha->fcport_waitQ);
>  	init_waitqueue_head(&vha->vref_waitq);
>  	qla_enode_init(vha);
> +	qla_edb_init(vha);
> +
>  
>  	vha->gnl.size = sizeof(struct get_name_list_extended) *
>  			(ha->max_loop_id + 1);
> diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
> index faf446f0fe8c..5d9fafa0c5d9 100644
> --- a/drivers/scsi/qla2xxx/qla_target.c
> +++ b/drivers/scsi/qla2xxx/qla_target.c
> @@ -585,6 +585,8 @@ static void qla2x00_async_nack_sp_done(srb_t *sp, int res)
>  			    DSC_LOGIN_AUTH_PEND);
>  			qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE,
>  			    sp->fcport->d_id.b24);
> +			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED, sp->fcport->d_id.b24,
> +			    0, sp->fcport);
>  		}
>  		break;
>  
> 
Cheers,

Hannes
-- 
Dr. Hannes Reinecke		        Kernel Storage Architect
hare@xxxxxxx			               +49 911 74053 688
SUSE Software Solutions Germany GmbH, 90409 Nürnberg
GF: F. Imendörffer, HRB 36809 (AG Nürnberg)



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux