/*
 *  linux/drivers/scsi/esas2r/esas2r_vda.c
 *      esas2r driver VDA firmware interface functions
 *
 *  Copyright (c) 2001-2013 ATTO Technology, Inc.
 *  (mailto:linuxdrivers@attotech.com)
 */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  NO WARRANTY
 *  THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
 *  CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
 *  LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
 *  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
 *  solely responsible for determining the appropriateness of using and
 *  distributing the Program and assumes all risks associated with its
 *  exercise of rights under this Agreement, including but not limited to
 *  the risks and costs of program errors, damage to or loss of data,
 *  programs or equipment, and unavailability or interruption of operations.
 *
 *  DISCLAIMER OF LIABILITY
 *  NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
 *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *  DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 *  USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
 *  HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

#include "esas2r.h"

static u8 esas2r_vdaioctl_versions[] = {
	ATTO_VDA_VER_UNSUPPORTED,
	ATTO_VDA_FLASH_VER,
	ATTO_VDA_VER_UNSUPPORTED,
	ATTO_VDA_VER_UNSUPPORTED,
	ATTO_VDA_CLI_VER,
	ATTO_VDA_VER_UNSUPPORTED,
	ATTO_VDA_CFG_VER,
	ATTO_VDA_MGT_VER,
	ATTO_VDA_GSV_VER
};

static void clear_vda_request(struct esas2r_request *rq);

static void esas2r_complete_vda_ioctl(struct esas2r_adapter *a,
				      struct esas2r_request *rq);

/* Prepare a VDA IOCTL request to be sent to the firmware. */
bool esas2r_process_vda_ioctl(struct esas2r_adapter *a,
			      struct atto_ioctl_vda *vi,
			      struct esas2r_request *rq,
			      struct esas2r_sg_context *sgc)
{
	u32 datalen = 0;
	struct atto_vda_sge *firstsg = NULL;
	u8 vercnt = (u8)ARRAY_SIZE(esas2r_vdaioctl_versions);

	vi->status = ATTO_STS_SUCCESS;
	vi->vda_status = RS_PENDING;

	if (vi->function >= vercnt) {
		vi->status = ATTO_STS_INV_FUNC;
		return false;
	}

	if (vi->version > esas2r_vdaioctl_versions[vi->function]) {
		vi->status = ATTO_STS_INV_VERSION;
		return false;
	}

	if (test_bit(AF_DEGRADED_MODE, &a->flags)) {
		vi->status = ATTO_STS_DEGRADED;
		return false;
	}

	if (vi->function != VDA_FUNC_SCSI)
		clear_vda_request(rq);

	rq->vrq->scsi.function = vi->function;
	rq->interrupt_cb = esas2r_complete_vda_ioctl;
	rq->interrupt_cx = vi;

	switch (vi->function) {
	case VDA_FUNC_FLASH:

		if (vi->cmd.flash.sub_func != VDA_FLASH_FREAD
		    && vi->cmd.flash.sub_func != VDA_FLASH_FWRITE
		    && vi->cmd.flash.sub_func != VDA_FLASH_FINFO) {
			vi->status = ATTO_STS_INV_FUNC;
			return false;
		}

		if (vi->cmd.flash.sub_func != VDA_FLASH_FINFO)
			datalen = vi->data_length;

		rq->vrq->flash.length = cpu_to_le32(datalen);
		rq->vrq->flash.sub_func = vi->cmd.flash.sub_func;

		memcpy(rq->vrq->flash.data.file.file_name,
		       vi->cmd.flash.data.file.file_name,
		       sizeof(vi->cmd.flash.data.file.file_name));

		firstsg = rq->vrq->flash.data.file.sge;
		break;

	case VDA_FUNC_CLI:

		datalen = vi->data_length;

		rq->vrq->cli.cmd_rsp_len =
			cpu_to_le32(vi->cmd.cli.cmd_rsp_len);
		rq->vrq->cli.length = cpu_to_le32(datalen);

		firstsg = rq->vrq->cli.sge;
		break;

	case VDA_FUNC_MGT:
	{
		u8 *cmdcurr_offset = sgc->cur_offset
				     - offsetof(struct atto_ioctl_vda, data)
				     + offsetof(struct atto_ioctl_vda, cmd)
				     + offsetof(struct atto_ioctl_vda_mgt_cmd,
						data);
		/*
		 * build the data payload SGL here first since
		 * esas2r_sgc_init() will modify the S/G list offset for the
		 * management SGL (which is built below where the data SGL is
		 * usually built).
		 */

		if (vi->data_length) {
			u32 payldlen = 0;

			if (vi->cmd.mgt.mgt_func == VDAMGT_DEV_HEALTH_REQ
			    || vi->cmd.mgt.mgt_func == VDAMGT_DEV_METRICS) {
				rq->vrq->mgt.payld_sglst_offset =
					(u8)offsetof(struct atto_vda_mgmt_req,
						     payld_sge);

				payldlen = vi->data_length;
				datalen = vi->cmd.mgt.data_length;
			} else if (vi->cmd.mgt.mgt_func == VDAMGT_DEV_INFO2
				   || vi->cmd.mgt.mgt_func ==
				   VDAMGT_DEV_INFO2_BYADDR) {
				datalen = vi->data_length;
				cmdcurr_offset = sgc->cur_offset;
			} else {
				vi->status = ATTO_STS_INV_PARAM;
				return false;
			}

			/* Setup the length so building the payload SGL works */
			rq->vrq->mgt.length = cpu_to_le32(datalen);

			if (payldlen) {
				rq->vrq->mgt.payld_length =
					cpu_to_le32(payldlen);

				esas2r_sgc_init(sgc, a, rq,
						rq->vrq->mgt.payld_sge);
				sgc->length = payldlen;

				if (!esas2r_build_sg_list(a, rq, sgc)) {
					vi->status = ATTO_STS_OUT_OF_RSRC;
					return false;
				}
			}
		} else {
			datalen = vi->cmd.mgt.data_length;

			rq->vrq->mgt.length = cpu_to_le32(datalen);
		}

		/*
		 * Now that the payload SGL is built, if any, setup to build
		 * the management SGL.
		 */
		firstsg = rq->vrq->mgt.sge;
		sgc->cur_offset = cmdcurr_offset;

		/* Finish initializing the management request. */
		rq->vrq->mgt.mgt_func = vi->cmd.mgt.mgt_func;
		rq->vrq->mgt.scan_generation = vi->cmd.mgt.scan_generation;
		rq->vrq->mgt.dev_index =
			cpu_to_le32(vi->cmd.mgt.dev_index);

		esas2r_nuxi_mgt_data(rq->vrq->mgt.mgt_func, &vi->cmd.mgt.data);
		break;
	}

	case VDA_FUNC_CFG:

		if (vi->data_length
		    || vi->cmd.cfg.data_length == 0) {
			vi->status = ATTO_STS_INV_PARAM;
			return false;
		}

		if (vi->cmd.cfg.cfg_func == VDA_CFG_INIT) {
			vi->status = ATTO_STS_INV_FUNC;
			return false;
		}

		rq->vrq->cfg.sub_func = vi->cmd.cfg.cfg_func;
		rq->vrq->cfg.length = cpu_to_le32(vi->cmd.cfg.data_length);

		if (vi->cmd.cfg.cfg_func == VDA_CFG_GET_INIT) {
			memcpy(&rq->vrq->cfg.data,
			       &vi->cmd.cfg.data,
			       vi->cmd.cfg.data_length);

			esas2r_nuxi_cfg_data(rq->vrq->cfg.sub_func,
					     &rq->vrq->cfg.data);
		} else {
			vi->status = ATTO_STS_INV_FUNC;

			return false;
		}

		break;

	case VDA_FUNC_GSV:

		vi->cmd.gsv.rsp_len = vercnt;

		memcpy(vi->cmd.gsv.version_info, esas2r_vdaioctl_versions,
		       vercnt);

		vi->vda_status = RS_SUCCESS;
		break;

	default:

		vi->status = ATTO_STS_INV_FUNC;
		return false;
	}

	if (datalen) {
		esas2r_sgc_init(sgc, a, rq, firstsg);
		sgc->length = datalen;

		if (!esas2r_build_sg_list(a, rq, sgc)) {
			vi->status = ATTO_STS_OUT_OF_RSRC;
			return false;
		}
	}

	esas2r_start_request(a, rq);

	return true;
}

static void esas2r_complete_vda_ioctl(struct esas2r_adapter *a,
				      struct esas2r_request *rq)
{
	struct atto_ioctl_vda *vi = (struct atto_ioctl_vda *)rq->interrupt_cx;

	vi->vda_status = rq->req_stat;

	switch (vi->function) {
	case VDA_FUNC_FLASH:

		if (vi->cmd.flash.sub_func == VDA_FLASH_FINFO
		    || vi->cmd.flash.sub_func == VDA_FLASH_FREAD)
			vi->cmd.flash.data.file.file_size =
				le32_to_cpu(rq->func_rsp.flash_rsp.file_size);

		break;

	case VDA_FUNC_MGT:

		vi->cmd.mgt.scan_generation =
			rq->func_rsp.mgt_rsp.scan_generation;
		vi->cmd.mgt.dev_index = le16_to_cpu(
			rq->func_rsp.mgt_rsp.dev_index);

		if (vi->data_length == 0)
			vi->cmd.mgt.data_length =
				le32_to_cpu(rq->func_rsp.mgt_rsp.length);

		esas2r_nuxi_mgt_data(rq->vrq->mgt.mgt_func, &vi->cmd.mgt.data);
		break;

	case VDA_FUNC_CFG:

		if (vi->cmd.cfg.cfg_func == VDA_CFG_GET_INIT) {
			struct atto_ioctl_vda_cfg_cmd *cfg = &vi->cmd.cfg;
			struct atto_vda_cfg_rsp *rsp = &rq->func_rsp.cfg_rsp;
			char buf[sizeof(cfg->data.init.fw_release) + 1];

			cfg->data_length =
				cpu_to_le32(sizeof(struct atto_vda_cfg_init));
			cfg->data.init.vda_version =
				le32_to_cpu(rsp->vda_version);
			cfg->data.init.fw_build = rsp->fw_build;

			snprintf(buf, sizeof(buf), "%1.1u.%2.2u",
				 (int)LOBYTE(le16_to_cpu(rsp->fw_release)),
				 (int)HIBYTE(le16_to_cpu(rsp->fw_release)));

			memcpy(&cfg->data.init.fw_release, buf,
			       sizeof(cfg->data.init.fw_release));

			if (LOWORD(LOBYTE(cfg->data.init.fw_build)) == 'A')
				cfg->data.init.fw_version =
					cfg->data.init.fw_build;
			else
				cfg->data.init.fw_version =
					cfg->data.init.fw_release;
		} else {
			esas2r_nuxi_cfg_data(rq->vrq->cfg.sub_func,
					     &vi->cmd.cfg.data);
		}

		break;

	case VDA_FUNC_CLI:

		vi->cmd.cli.cmd_rsp_len =
			le32_to_cpu(rq->func_rsp.cli_rsp.cmd_rsp_len);
		break;

	default:

		break;
	}
}

/* Build a flash VDA request. */
void esas2r_build_flash_req(struct esas2r_adapter *a,
			    struct esas2r_request *rq,
			    u8 sub_func,
			    u8 cksum,
			    u32 addr,
			    u32 length)
{
	struct atto_vda_flash_req *vrq = &rq->vrq->flash;

	clear_vda_request(rq);

	rq->vrq->scsi.function = VDA_FUNC_FLASH;

	if (sub_func == VDA_FLASH_BEGINW
	    || sub_func == VDA_FLASH_WRITE
	    || sub_func == VDA_FLASH_READ)
		vrq->sg_list_offset = (u8)offsetof(struct atto_vda_flash_req,
						   data.sge);

	vrq->length = cpu_to_le32(length);
	vrq->flash_addr = cpu_to_le32(addr);
	vrq->checksum = cksum;
	vrq->sub_func = sub_func;
}

/* Build a VDA management request. */
void esas2r_build_mgt_req(struct esas2r_adapter *a,
			  struct esas2r_request *rq,
			  u8 sub_func,
			  u8 scan_gen,
			  u16 dev_index,
			  u32 length,
			  void *data)
{
	struct atto_vda_mgmt_req *vrq = &rq->vrq->mgt;

	clear_vda_request(rq);

	rq->vrq->scsi.function = VDA_FUNC_MGT;

	vrq->mgt_func = sub_func;
	vrq->scan_generation = scan_gen;
	vrq->dev_index = cpu_to_le16(dev_index);
	vrq->length = cpu_to_le32(length);

	if (vrq->length) {
		if (test_bit(AF_LEGACY_SGE_MODE, &a->flags)) {
			vrq->sg_list_offset = (u8)offsetof(
				struct atto_vda_mgmt_req, sge);

			vrq->sge[0].length = cpu_to_le32(SGE_LAST | length);
			vrq->sge[0].address = cpu_to_le64(
				rq->vrq_md->phys_addr +
				sizeof(union atto_vda_req));
		} else {
			vrq->sg_list_offset = (u8)offsetof(
				struct atto_vda_mgmt_req, prde);

			vrq->prde[0].ctl_len = cpu_to_le32(length);
			vrq->prde[0].address = cpu_to_le64(
				rq->vrq_md->phys_addr +
				sizeof(union atto_vda_req));
		}
	}

	if (data) {
		esas2r_nuxi_mgt_data(sub_func, data);

		memcpy(&rq->vda_rsp_data->mgt_data.data.bytes[0], data,
		       length);
	}
}

/* Build a VDA asyncronous event (AE) request. */
void esas2r_build_ae_req(struct esas2r_adapter *a, struct esas2r_request *rq)
{
	struct atto_vda_ae_req *vrq = &rq->vrq->ae;

	clear_vda_request(rq);

	rq->vrq->scsi.function = VDA_FUNC_AE;

	vrq->length = cpu_to_le32(sizeof(struct atto_vda_ae_data));

	if (test_bit(AF_LEGACY_SGE_MODE, &a->flags)) {
		vrq->sg_list_offset =
			(u8)offsetof(struct atto_vda_ae_req, sge);
		vrq->sge[0].length = cpu_to_le32(SGE_LAST | vrq->length);
		vrq->sge[0].address = cpu_to_le64(
			rq->vrq_md->phys_addr +
			sizeof(union atto_vda_req));
	} else {
		vrq->sg_list_offset = (u8)offsetof(struct atto_vda_ae_req,
						   prde);
		vrq->prde[0].ctl_len = cpu_to_le32(vrq->length);
		vrq->prde[0].address = cpu_to_le64(
			rq->vrq_md->phys_addr +
			sizeof(union atto_vda_req));
	}
}

/* Build a VDA CLI request. */
void esas2r_build_cli_req(struct esas2r_adapter *a,
			  struct esas2r_request *rq,
			  u32 length,
			  u32 cmd_rsp_len)
{
	struct atto_vda_cli_req *vrq = &rq->vrq->cli;

	clear_vda_request(rq);

	rq->vrq->scsi.function = VDA_FUNC_CLI;

	vrq->length = cpu_to_le32(length);
	vrq->cmd_rsp_len = cpu_to_le32(cmd_rsp_len);
	vrq->sg_list_offset = (u8)offsetof(struct atto_vda_cli_req, sge);
}

/* Build a VDA IOCTL request. */
void esas2r_build_ioctl_req(struct esas2r_adapter *a,
			    struct esas2r_request *rq,
			    u32 length,
			    u8 sub_func)
{
	struct atto_vda_ioctl_req *vrq = &rq->vrq->ioctl;

	clear_vda_request(rq);

	rq->vrq->scsi.function = VDA_FUNC_IOCTL;

	vrq->length = cpu_to_le32(length);
	vrq->sub_func = sub_func;
	vrq->sg_list_offset = (u8)offsetof(struct atto_vda_ioctl_req, sge);
}

/* Build a VDA configuration request. */
void esas2r_build_cfg_req(struct esas2r_adapter *a,
			  struct esas2r_request *rq,
			  u8 sub_func,
			  u32 length,
			  void *data)
{
	struct atto_vda_cfg_req *vrq = &rq->vrq->cfg;

	clear_vda_request(rq);

	rq->vrq->scsi.function = VDA_FUNC_CFG;

	vrq->sub_func = sub_func;
	vrq->length = cpu_to_le32(length);

	if (data) {
		esas2r_nuxi_cfg_data(sub_func, data);

		memcpy(&vrq->data, data, length);
	}
}

static void clear_vda_request(struct esas2r_request *rq)
{
	u32 handle = rq->vrq->scsi.handle;

	memset(rq->vrq, 0, sizeof(*rq->vrq));

	rq->vrq->scsi.handle = handle;

	rq->req_stat = RS_PENDING;

	/* since the data buffer is separate clear that too */

	memset(rq->data_buf, 0, ESAS2R_DATA_BUF_LEN);

	/*
	 * Setup next and prev pointer in case the request is not going through
	 * esas2r_start_request().
	 */

	INIT_LIST_HEAD(&rq->req_list);
}
