/**
 * Copyright (C) 2005 - 2009 ServerEngines
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.  The full GNU General
 * Public License is included in this distribution in the file called COPYING.
 *
 * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
 *
 * Contact Information:
 * linux-drivers@serverengines.com
 *
 * ServerEngines
 * 209 N. Fair Oaks Ave
 * Sunnyvale, CA 94085
 *
 */

#include <scsi/libiscsi.h>
#include <scsi/scsi_transport_iscsi.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi.h>

#include "be_iscsi.h"

extern struct iscsi_transport beiscsi_iscsi_transport;

/**
 * beiscsi_session_create - creates a new iscsi session
 * @cmds_max: max commands supported
 * @qdepth: max queue depth supported
 * @initial_cmdsn: initial iscsi CMDSN
 */
struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
						 u16 cmds_max,
						 u16 qdepth,
						 u32 initial_cmdsn)
{
	struct Scsi_Host *shost;
	struct beiscsi_endpoint *beiscsi_ep;
	struct iscsi_cls_session *cls_session;
	struct beiscsi_hba *phba;
	struct iscsi_session *sess;
	struct beiscsi_session *beiscsi_sess;
	struct beiscsi_io_task *io_task;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_session_create\n");

	if (!ep) {
		SE_DEBUG(DBG_LVL_1, "beiscsi_session_create: invalid ep \n");
		return NULL;
	}
	beiscsi_ep = ep->dd_data;
	phba = beiscsi_ep->phba;
	shost = phba->shost;
	if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) {
		shost_printk(KERN_ERR, shost, "Cannot handle %d cmds."
			     "Max cmds per session supported is %d. Using %d. "
			     "\n", cmds_max,
			      beiscsi_ep->phba->params.wrbs_per_cxn,
			      beiscsi_ep->phba->params.wrbs_per_cxn);
		cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
	}

	cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
					  shost, cmds_max,
					  sizeof(*beiscsi_sess),
					  sizeof(*io_task),
					  initial_cmdsn, ISCSI_MAX_TARGET);
	if (!cls_session)
		return NULL;
	sess = cls_session->dd_data;
	beiscsi_sess = sess->dd_data;
	beiscsi_sess->bhs_pool =  pci_pool_create("beiscsi_bhs_pool",
						   phba->pcidev,
						   sizeof(struct be_cmd_bhs),
						   64, 0);
	if (!beiscsi_sess->bhs_pool)
		goto destroy_sess;

	return cls_session;
destroy_sess:
	iscsi_session_teardown(cls_session);
	return NULL;
}

/**
 * beiscsi_session_destroy - destroys iscsi session
 * @cls_session:	pointer to iscsi cls session
 *
 * Destroys iSCSI session instance and releases
 * resources allocated for it.
 */
void beiscsi_session_destroy(struct iscsi_cls_session *cls_session)
{
	struct iscsi_session *sess = cls_session->dd_data;
	struct beiscsi_session *beiscsi_sess = sess->dd_data;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_session_destroy\n");
	pci_pool_destroy(beiscsi_sess->bhs_pool);
	iscsi_session_teardown(cls_session);
}

/**
 * beiscsi_conn_create - create an instance of iscsi connection
 * @cls_session: ptr to iscsi_cls_session
 * @cid: iscsi cid
 */
struct iscsi_cls_conn *
beiscsi_conn_create(struct iscsi_cls_session *cls_session, u32 cid)
{
	struct beiscsi_hba *phba;
	struct Scsi_Host *shost;
	struct iscsi_cls_conn *cls_conn;
	struct beiscsi_conn *beiscsi_conn;
	struct iscsi_conn *conn;
	struct iscsi_session *sess;
	struct beiscsi_session *beiscsi_sess;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_create ,cid"
		 "from iscsi layer=%d\n", cid);
	shost = iscsi_session_to_shost(cls_session);
	phba = iscsi_host_priv(shost);

	cls_conn = iscsi_conn_setup(cls_session, sizeof(*beiscsi_conn), cid);
	if (!cls_conn)
		return NULL;

	conn = cls_conn->dd_data;
	beiscsi_conn = conn->dd_data;
	beiscsi_conn->ep = NULL;
	beiscsi_conn->phba = phba;
	beiscsi_conn->conn = conn;
	sess = cls_session->dd_data;
	beiscsi_sess = sess->dd_data;
	beiscsi_conn->beiscsi_sess = beiscsi_sess;
	return cls_conn;
}

/**
 * beiscsi_bindconn_cid - Bind the beiscsi_conn with phba connection table
 * @beiscsi_conn: The pointer to  beiscsi_conn structure
 * @phba: The phba instance
 * @cid: The cid to free
 */
static int beiscsi_bindconn_cid(struct beiscsi_hba *phba,
				struct beiscsi_conn *beiscsi_conn,
				unsigned int cid)
{
	if (phba->conn_table[cid]) {
		SE_DEBUG(DBG_LVL_1,
			 "Connection table already occupied. Detected clash\n");
		return -EINVAL;
	} else {
		SE_DEBUG(DBG_LVL_8, "phba->conn_table[%d]=%p(beiscsi_conn) \n",
			 cid, beiscsi_conn);
		phba->conn_table[cid] = beiscsi_conn;
	}
	return 0;
}

/**
 * beiscsi_conn_bind - Binds iscsi session/connection with TCP connection
 * @cls_session: pointer to iscsi cls session
 * @cls_conn: pointer to iscsi cls conn
 * @transport_fd: EP handle(64 bit)
 *
 * This function binds the TCP Conn with iSCSI Connection and Session.
 */
int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
		      struct iscsi_cls_conn *cls_conn,
		      u64 transport_fd, int is_leading)
{
	struct iscsi_conn *conn = cls_conn->dd_data;
	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
	struct Scsi_Host *shost =
		(struct Scsi_Host *)iscsi_session_to_shost(cls_session);
	struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost);
	struct beiscsi_endpoint *beiscsi_ep;
	struct iscsi_endpoint *ep;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_bind\n");
	ep = iscsi_lookup_endpoint(transport_fd);
	if (!ep)
		return -EINVAL;

	beiscsi_ep = ep->dd_data;

	if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
		return -EINVAL;

	if (beiscsi_ep->phba != phba) {
		SE_DEBUG(DBG_LVL_8,
			 "beiscsi_ep->hba=%p not equal to phba=%p \n",
			 beiscsi_ep->phba, phba);
		return -EEXIST;
	}

	beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid;
	beiscsi_conn->ep = beiscsi_ep;
	beiscsi_ep->conn = beiscsi_conn;
	SE_DEBUG(DBG_LVL_8, "beiscsi_conn=%p conn=%p ep_cid=%d \n",
		 beiscsi_conn, conn, beiscsi_ep->ep_cid);
	return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid);
}

/**
 * beiscsi_conn_get_param - get the iscsi parameter
 * @cls_conn: pointer to iscsi cls conn
 * @param: parameter type identifier
 * @buf: buffer pointer
 *
 * returns iscsi parameter
 */
int beiscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
			   enum iscsi_param param, char *buf)
{
	struct beiscsi_endpoint *beiscsi_ep;
	struct iscsi_conn *conn = cls_conn->dd_data;
	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
	int len = 0;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_get_param, param= %d\n", param);
	beiscsi_ep = beiscsi_conn->ep;
	if (!beiscsi_ep) {
		SE_DEBUG(DBG_LVL_1,
			 "In beiscsi_conn_get_param , no beiscsi_ep\n");
		return -1;
	}

	switch (param) {
	case ISCSI_PARAM_CONN_PORT:
		len = sprintf(buf, "%hu\n", beiscsi_ep->dst_tcpport);
		break;
	case ISCSI_PARAM_CONN_ADDRESS:
		if (beiscsi_ep->ip_type == BE2_IPV4)
			len = sprintf(buf, "%pI4\n", &beiscsi_ep->dst_addr);
		else
			len = sprintf(buf, "%pI6\n", &beiscsi_ep->dst6_addr);
		break;
	default:
		return iscsi_conn_get_param(cls_conn, param, buf);
	}
	return len;
}

int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
		      enum iscsi_param param, char *buf, int buflen)
{
	struct iscsi_conn *conn = cls_conn->dd_data;
	struct iscsi_session *session = conn->session;
	int ret;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_set_param, param= %d\n", param);
	ret = iscsi_set_param(cls_conn, param, buf, buflen);
	if (ret)
		return ret;
	/*
	 * If userspace tried to set the value to higher than we can
	 * support override here.
	 */
	switch (param) {
	case ISCSI_PARAM_FIRST_BURST:
		if (session->first_burst > 8192)
			session->first_burst = 8192;
		break;
	case ISCSI_PARAM_MAX_RECV_DLENGTH:
		if (conn->max_recv_dlength > 65536)
			conn->max_recv_dlength = 65536;
		break;
	case ISCSI_PARAM_MAX_BURST:
		if (session->first_burst > 262144)
			session->first_burst = 262144;
		break;
	default:
		return 0;
	}

	return 0;
}

/**
 * beiscsi_get_host_param - get the iscsi parameter
 * @shost: pointer to scsi_host structure
 * @param: parameter type identifier
 * @buf: buffer pointer
 *
 * returns host parameter
 */
int beiscsi_get_host_param(struct Scsi_Host *shost,
			   enum iscsi_host_param param, char *buf)
{
	struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost);
	struct be_cmd_resp_get_mac_addr *resp;
	struct be_mcc_wrb *wrb;
	unsigned int tag, wrb_num;
	int len = 0;
	unsigned short status, extd_status;
	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param);
	switch (param) {
	case ISCSI_HOST_PARAM_HWADDRESS:
		tag = be_cmd_get_mac_addr(phba);
		if (!tag) {
			SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed \n");
			return -1;
		} else
			wait_event_interruptible(phba->ctrl.mcc_wait[tag],
						 phba->ctrl.mcc_numtag[tag]);

		wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
		extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
		status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
		if (status || extd_status) {
			SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed"
					    " status = %d extd_status = %d \n",
					    status, extd_status);
			free_mcc_tag(&phba->ctrl, tag);
			return -1;
		} else {
			wrb = queue_get_wrb(mccq, wrb_num);
			free_mcc_tag(&phba->ctrl, tag);
			resp = embedded_payload(wrb);
			memcpy(phba->mac_address, resp->mac_address, ETH_ALEN);
			len = sysfs_format_mac(buf, phba->mac_address,
					       ETH_ALEN);
		}
		break;
	default:
		return iscsi_host_get_param(shost, param, buf);
	}
	return len;
}

/**
 * beiscsi_conn_get_stats - get the iscsi stats
 * @cls_conn: pointer to iscsi cls conn
 * @stats: pointer to iscsi_stats structure
 *
 * returns iscsi stats
 */
void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn,
			    struct iscsi_stats *stats)
{
	struct iscsi_conn *conn = cls_conn->dd_data;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_get_stats\n");
	stats->txdata_octets = conn->txdata_octets;
	stats->rxdata_octets = conn->rxdata_octets;
	stats->dataout_pdus = conn->dataout_pdus_cnt;
	stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;
	stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;
	stats->datain_pdus = conn->datain_pdus_cnt;
	stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
	stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
	stats->r2t_pdus = conn->r2t_pdus_cnt;
	stats->digest_err = 0;
	stats->timeout_err = 0;
	stats->custom_length = 0;
	strcpy(stats->custom[0].desc, "eh_abort_cnt");
	stats->custom[0].value = conn->eh_abort_cnt;
}

/**
 * beiscsi_set_params_for_offld - get the parameters for offload
 * @beiscsi_conn: pointer to beiscsi_conn
 * @params: pointer to offload_params structure
 */
static void  beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn,
					  struct beiscsi_offload_params *params)
{
	struct iscsi_conn *conn = beiscsi_conn->conn;
	struct iscsi_session *session = conn->session;

	AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_burst_length,
		      params, session->max_burst);
	AMAP_SET_BITS(struct amap_beiscsi_offload_params,
		      max_send_data_segment_length, params,
		      conn->max_xmit_dlength);
	AMAP_SET_BITS(struct amap_beiscsi_offload_params, first_burst_length,
		      params, session->first_burst);
	AMAP_SET_BITS(struct amap_beiscsi_offload_params, erl, params,
		      session->erl);
	AMAP_SET_BITS(struct amap_beiscsi_offload_params, dde, params,
		      conn->datadgst_en);
	AMAP_SET_BITS(struct amap_beiscsi_offload_params, hde, params,
		      conn->hdrdgst_en);
	AMAP_SET_BITS(struct amap_beiscsi_offload_params, ir2t, params,
		      session->initial_r2t_en);
	AMAP_SET_BITS(struct amap_beiscsi_offload_params, imd, params,
		      session->imm_data_en);
	AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params,
		      (conn->exp_statsn - 1));
}

/**
 * beiscsi_conn_start - offload of session to chip
 * @cls_conn: pointer to beiscsi_conn
 */
int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
{
	struct iscsi_conn *conn = cls_conn->dd_data;
	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
	struct beiscsi_endpoint *beiscsi_ep;
	struct beiscsi_offload_params params;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_start\n");
	memset(&params, 0, sizeof(struct beiscsi_offload_params));
	beiscsi_ep = beiscsi_conn->ep;
	if (!beiscsi_ep)
		SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n");

	beiscsi_conn->login_in_progress = 0;
	beiscsi_set_params_for_offld(beiscsi_conn, &params);
	beiscsi_offload_connection(beiscsi_conn, &params);
	iscsi_conn_start(cls_conn);
	return 0;
}

/**
 * beiscsi_get_cid - Allocate a cid
 * @phba: The phba instance
 */
static int beiscsi_get_cid(struct beiscsi_hba *phba)
{
	unsigned short cid = 0xFFFF;

	if (!phba->avlbl_cids)
		return cid;

	cid = phba->cid_array[phba->cid_alloc++];
	if (phba->cid_alloc == phba->params.cxns_per_ctrl)
		phba->cid_alloc = 0;
	phba->avlbl_cids--;
	return cid;
}

/**
 * beiscsi_open_conn - Ask FW to open a TCP connection
 * @ep:	endpoint to be used
 * @src_addr: The source IP address
 * @dst_addr: The Destination  IP address
 *
 * Asks the FW to open a TCP connection
 */
static int beiscsi_open_conn(struct iscsi_endpoint *ep,
			     struct sockaddr *src_addr,
			     struct sockaddr *dst_addr, int non_blocking)
{
	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
	struct beiscsi_hba *phba = beiscsi_ep->phba;
	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
	struct be_mcc_wrb *wrb;
	struct tcp_connect_and_offload_out *ptcpcnct_out;
	unsigned short status, extd_status;
	unsigned int tag, wrb_num;
	int ret = -1;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n");
	beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
	if (beiscsi_ep->ep_cid == 0xFFFF) {
		SE_DEBUG(DBG_LVL_1, "No free cid available\n");
		return ret;
	}
	SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d ",
		 beiscsi_ep->ep_cid);
	phba->ep_array[beiscsi_ep->ep_cid -
		       phba->fw_config.iscsi_cid_start] = ep;
	if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start +
				  phba->params.cxns_per_ctrl * 2)) {
		SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
		return ret;
	}

	beiscsi_ep->cid_vld = 0;
	tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep);
	if (!tag) {
		SE_DEBUG(DBG_LVL_1,
			 "mgmt_invalidate_connection Failed for cid=%d \n",
			 beiscsi_ep->ep_cid);
	} else {
		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
					 phba->ctrl.mcc_numtag[tag]);
	}
	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
	if (status || extd_status) {
		SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed"
				    " status = %d extd_status = %d \n",
				    status, extd_status);
		free_mcc_tag(&phba->ctrl, tag);
		return -1;
	} else {
		wrb = queue_get_wrb(mccq, wrb_num);
		free_mcc_tag(&phba->ctrl, tag);

		ptcpcnct_out = 	embedded_payload(wrb);
		beiscsi_ep = ep->dd_data;
		beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
		beiscsi_ep->cid_vld = 1;
		SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
	}
	return 0;
}

/**
 * beiscsi_put_cid - Free the cid
 * @phba: The phba for which the cid is being freed
 * @cid: The cid to free
 */
static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
{
	phba->avlbl_cids++;
	phba->cid_array[phba->cid_free++] = cid;
	if (phba->cid_free == phba->params.cxns_per_ctrl)
		phba->cid_free = 0;
}

/**
 * beiscsi_free_ep - free endpoint
 * @ep:	pointer to iscsi endpoint structure
 */
static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
{
	struct beiscsi_hba *phba = beiscsi_ep->phba;

	beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
	beiscsi_ep->phba = NULL;
}

/**
 * beiscsi_ep_connect - Ask chip to create TCP Conn
 * @scsi_host: Pointer to scsi_host structure
 * @dst_addr: The IP address of Target
 * @non_blocking: blocking or non-blocking call
 *
 * This routines first asks chip to create a connection and then allocates an EP
 */
struct iscsi_endpoint *
beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
		   int non_blocking)
{
	struct beiscsi_hba *phba;
	struct beiscsi_endpoint *beiscsi_ep;
	struct iscsi_endpoint *ep;
	int ret;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_connect \n");
	if (shost)
		phba = iscsi_host_priv(shost);
	else {
		ret = -ENXIO;
		SE_DEBUG(DBG_LVL_1, "shost is NULL \n");
		return ERR_PTR(ret);
	}

	if (phba->state) {
		ret = -EBUSY;
		SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP \n");
		return ERR_PTR(ret);
	}

	ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint));
	if (!ep) {
		ret = -ENOMEM;
		return ERR_PTR(ret);
	}

	beiscsi_ep = ep->dd_data;
	beiscsi_ep->phba = phba;
	beiscsi_ep->openiscsi_ep = ep;
	if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) {
		SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n");
		ret = -ENOMEM;
		goto free_ep;
	}

	return ep;

free_ep:
	beiscsi_free_ep(beiscsi_ep);
	return ERR_PTR(ret);
}

/**
 * beiscsi_ep_poll - Poll to see if connection is established
 * @ep:	endpoint to be used
 * @timeout_ms: timeout specified in millisecs
 *
 * Poll to see if TCP connection established
 */
int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
{
	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;

	SE_DEBUG(DBG_LVL_8, "In  beiscsi_ep_poll\n");
	if (beiscsi_ep->cid_vld == 1)
		return 1;
	else
		return 0;
}

/**
 * beiscsi_close_conn - Upload the  connection
 * @ep: The iscsi endpoint
 * @flag: The type of connection closure
 */
static int beiscsi_close_conn(struct  beiscsi_endpoint *beiscsi_ep, int flag)
{
	int ret = 0;
	unsigned int tag;
	struct beiscsi_hba *phba = beiscsi_ep->phba;

	tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag);
	if (!tag) {
		SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x",
			 beiscsi_ep->ep_cid);
		ret = -1;
	} else {
		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
					 phba->ctrl.mcc_numtag[tag]);
		free_mcc_tag(&phba->ctrl, tag);
	}
	return ret;
}

/**
 * beiscsi_ep_disconnect - Tears down the TCP connection
 * @ep:	endpoint to be used
 *
 * Tears down the TCP connection
 */
void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
{
	struct beiscsi_conn *beiscsi_conn;
	struct beiscsi_endpoint *beiscsi_ep;
	struct beiscsi_hba *phba;

	beiscsi_ep = ep->dd_data;
	phba = beiscsi_ep->phba;
	SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n",
			     beiscsi_ep->ep_cid);

	if (beiscsi_ep->conn) {
		beiscsi_conn = beiscsi_ep->conn;
		iscsi_suspend_queue(beiscsi_conn->conn);
	}

}

/**
 * beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table
 * @phba: The phba instance
 * @cid: The cid to free
 */
static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba,
				      unsigned int cid)
{
	if (phba->conn_table[cid])
		phba->conn_table[cid] = NULL;
	else {
		SE_DEBUG(DBG_LVL_8, "Connection table Not occupied. \n");
		return -EINVAL;
	}
	return 0;
}

/**
 * beiscsi_conn_stop - Invalidate and stop the connection
 * @cls_conn: pointer to get iscsi_conn
 * @flag: The type of connection closure
 */
void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
{
	struct iscsi_conn *conn = cls_conn->dd_data;
	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
	struct beiscsi_endpoint *beiscsi_ep;
	struct iscsi_session *session = conn->session;
	struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
	struct beiscsi_hba *phba = iscsi_host_priv(shost);
	unsigned int tag;
	unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH;

	beiscsi_ep = beiscsi_conn->ep;
	if (!beiscsi_ep) {
		SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop , no beiscsi_ep\n");
		return;
	}
	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop  ep_cid = %d\n",
			     beiscsi_ep->ep_cid);
	tag = mgmt_invalidate_connection(phba, beiscsi_ep,
					    beiscsi_ep->ep_cid, 1,
					    savecfg_flag);
	if (!tag) {
		SE_DEBUG(DBG_LVL_1,
			 "mgmt_invalidate_connection Failed for cid=%d \n",
			 beiscsi_ep->ep_cid);
	} else {
		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
					 phba->ctrl.mcc_numtag[tag]);
		free_mcc_tag(&phba->ctrl, tag);
	}
	beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL);
	beiscsi_free_ep(beiscsi_ep);
	iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
	beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
	iscsi_conn_stop(cls_conn, flag);
}
