/*
 *  linux/drivers/scsi/esas2r/esas2r_ioctl.c
 *      For use with ATTO ExpressSAS R6xx SAS/SATA RAID controllers
 *
 *  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; either version 2
 * of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
 * USA.
 */

#include "esas2r.h"

/*
 * Buffered ioctl handlers.  A buffered ioctl is one which requires that we
 * allocate a DMA-able memory area to communicate with the firmware.  In
 * order to prevent continually allocating and freeing consistent memory,
 * we will allocate a global buffer the first time we need it and re-use
 * it for subsequent ioctl calls that require it.
 */

u8 *esas2r_buffered_ioctl;
dma_addr_t esas2r_buffered_ioctl_addr;
u32 esas2r_buffered_ioctl_size;
struct pci_dev *esas2r_buffered_ioctl_pcid;

static DEFINE_SEMAPHORE(buffered_ioctl_semaphore);
typedef int (*BUFFERED_IOCTL_CALLBACK)(struct esas2r_adapter *,
				       struct esas2r_request *,
				       struct esas2r_sg_context *,
				       void *);
typedef void (*BUFFERED_IOCTL_DONE_CALLBACK)(struct esas2r_adapter *,
					     struct esas2r_request *, void *);

struct esas2r_buffered_ioctl {
	struct esas2r_adapter *a;
	void *ioctl;
	u32 length;
	u32 control_code;
	u32 offset;
	BUFFERED_IOCTL_CALLBACK
		callback;
	void *context;
	BUFFERED_IOCTL_DONE_CALLBACK
		done_callback;
	void *done_context;

};

static void complete_fm_api_req(struct esas2r_adapter *a,
				struct esas2r_request *rq)
{
	a->fm_api_command_done = 1;
	wake_up_interruptible(&a->fm_api_waiter);
}

/* Callbacks for building scatter/gather lists for FM API requests */
static u32 get_physaddr_fm_api(struct esas2r_sg_context *sgc, u64 *addr)
{
	struct esas2r_adapter *a = (struct esas2r_adapter *)sgc->adapter;
	int offset = sgc->cur_offset - a->save_offset;

	(*addr) = a->firmware.phys + offset;
	return a->firmware.orig_len - offset;
}

static u32 get_physaddr_fm_api_header(struct esas2r_sg_context *sgc, u64 *addr)
{
	struct esas2r_adapter *a = (struct esas2r_adapter *)sgc->adapter;
	int offset = sgc->cur_offset - a->save_offset;

	(*addr) = a->firmware.header_buff_phys + offset;
	return sizeof(struct esas2r_flash_img) - offset;
}

/* Handle EXPRESS_IOCTL_RW_FIRMWARE ioctl with img_type = FW_IMG_FM_API. */
static void do_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi)
{
	struct esas2r_request *rq;

	if (down_interruptible(&a->fm_api_semaphore)) {
		fi->status = FI_STAT_BUSY;
		return;
	}

	rq = esas2r_alloc_request(a);
	if (rq == NULL) {
		up(&a->fm_api_semaphore);
		fi->status = FI_STAT_BUSY;
		return;
	}

	if (fi == &a->firmware.header) {
		a->firmware.header_buff = dma_alloc_coherent(&a->pcid->dev,
							     (size_t)sizeof(
								     struct
								     esas2r_flash_img),
							     (dma_addr_t *)&a->
							     firmware.
							     header_buff_phys,
							     GFP_KERNEL);

		if (a->firmware.header_buff == NULL) {
			esas2r_debug("failed to allocate header buffer!");
			fi->status = FI_STAT_BUSY;
			return;
		}

		memcpy(a->firmware.header_buff, fi,
		       sizeof(struct esas2r_flash_img));
		a->save_offset = a->firmware.header_buff;
		a->fm_api_sgc.get_phys_addr =
			(PGETPHYSADDR)get_physaddr_fm_api_header;
	} else {
		a->save_offset = (u8 *)fi;
		a->fm_api_sgc.get_phys_addr =
			(PGETPHYSADDR)get_physaddr_fm_api;
	}

	rq->comp_cb = complete_fm_api_req;
	a->fm_api_command_done = 0;
	a->fm_api_sgc.cur_offset = a->save_offset;

	if (!esas2r_fm_api(a, (struct esas2r_flash_img *)a->save_offset, rq,
			   &a->fm_api_sgc))
		goto all_done;

	/* Now wait around for it to complete. */
	while (!a->fm_api_command_done)
		wait_event_interruptible(a->fm_api_waiter,
					 a->fm_api_command_done);
all_done:
	if (fi == &a->firmware.header) {
		memcpy(fi, a->firmware.header_buff,
		       sizeof(struct esas2r_flash_img));

		dma_free_coherent(&a->pcid->dev,
				  (size_t)sizeof(struct esas2r_flash_img),
				  a->firmware.header_buff,
				  (dma_addr_t)a->firmware.header_buff_phys);
	}

	up(&a->fm_api_semaphore);
	esas2r_free_request(a, (struct esas2r_request *)rq);
	return;

}

static void complete_nvr_req(struct esas2r_adapter *a,
			     struct esas2r_request *rq)
{
	a->nvram_command_done = 1;
	wake_up_interruptible(&a->nvram_waiter);
}

/* Callback for building scatter/gather lists for buffered ioctls */
static u32 get_physaddr_buffered_ioctl(struct esas2r_sg_context *sgc,
				       u64 *addr)
{
	int offset = (u8 *)sgc->cur_offset - esas2r_buffered_ioctl;

	(*addr) = esas2r_buffered_ioctl_addr + offset;
	return esas2r_buffered_ioctl_size - offset;
}

static void complete_buffered_ioctl_req(struct esas2r_adapter *a,
					struct esas2r_request *rq)
{
	a->buffered_ioctl_done = 1;
	wake_up_interruptible(&a->buffered_ioctl_waiter);
}

static u8 handle_buffered_ioctl(struct esas2r_buffered_ioctl *bi)
{
	struct esas2r_adapter *a = bi->a;
	struct esas2r_request *rq;
	struct esas2r_sg_context sgc;
	u8 result = IOCTL_SUCCESS;

	if (down_interruptible(&buffered_ioctl_semaphore))
		return IOCTL_OUT_OF_RESOURCES;

	/* allocate a buffer or use the existing buffer. */
	if (esas2r_buffered_ioctl) {
		if (esas2r_buffered_ioctl_size < bi->length) {
			/* free the too-small buffer and get a new one */
			dma_free_coherent(&a->pcid->dev,
					  (size_t)esas2r_buffered_ioctl_size,
					  esas2r_buffered_ioctl,
					  esas2r_buffered_ioctl_addr);

			goto allocate_buffer;
		}
	} else {
allocate_buffer:
		esas2r_buffered_ioctl_size = bi->length;
		esas2r_buffered_ioctl_pcid = a->pcid;
		esas2r_buffered_ioctl = dma_alloc_coherent(&a->pcid->dev,
							   (size_t)
							   esas2r_buffered_ioctl_size,
							   &
							   esas2r_buffered_ioctl_addr,
							   GFP_KERNEL);
	}

	if (!esas2r_buffered_ioctl) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "could not allocate %d bytes of consistent memory "
			   "for a buffered ioctl!",
			   bi->length);

		esas2r_debug("buffered ioctl alloc failure");
		result = IOCTL_OUT_OF_RESOURCES;
		goto exit_cleanly;
	}

	memcpy(esas2r_buffered_ioctl, bi->ioctl, bi->length);

	rq = esas2r_alloc_request(a);
	if (rq == NULL) {
		esas2r_log(ESAS2R_LOG_CRIT,
			   "could not allocate an internal request");

		result = IOCTL_OUT_OF_RESOURCES;
		esas2r_debug("buffered ioctl - no requests");
		goto exit_cleanly;
	}

	a->buffered_ioctl_done = 0;
	rq->comp_cb = complete_buffered_ioctl_req;
	sgc.cur_offset = esas2r_buffered_ioctl + bi->offset;
	sgc.get_phys_addr = (PGETPHYSADDR)get_physaddr_buffered_ioctl;
	sgc.length = esas2r_buffered_ioctl_size;

	if (!(*bi->callback)(a, rq, &sgc, bi->context)) {
		/* completed immediately, no need to wait */
		a->buffered_ioctl_done = 0;
		goto free_andexit_cleanly;
	}

	/* now wait around for it to complete. */
	while (!a->buffered_ioctl_done)
		wait_event_interruptible(a->buffered_ioctl_waiter,
					 a->buffered_ioctl_done);

free_andexit_cleanly:
	if (result == IOCTL_SUCCESS && bi->done_callback)
		(*bi->done_callback)(a, rq, bi->done_context);

	esas2r_free_request(a, rq);

exit_cleanly:
	if (result == IOCTL_SUCCESS)
		memcpy(bi->ioctl, esas2r_buffered_ioctl, bi->length);

	up(&buffered_ioctl_semaphore);
	return result;
}

/* SMP ioctl support */
static int smp_ioctl_callback(struct esas2r_adapter *a,
			      struct esas2r_request *rq,
			      struct esas2r_sg_context *sgc, void *context)
{
	struct atto_ioctl_smp *si =
		(struct atto_ioctl_smp *)esas2r_buffered_ioctl;

	esas2r_sgc_init(sgc, a, rq, rq->vrq->ioctl.sge);
	esas2r_build_ioctl_req(a, rq, sgc->length, VDA_IOCTL_SMP);

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

	esas2r_start_request(a, rq);
	return true;
}

static u8 handle_smp_ioctl(struct esas2r_adapter *a, struct atto_ioctl_smp *si)
{
	struct esas2r_buffered_ioctl bi;

	memset(&bi, 0, sizeof(bi));

	bi.a = a;
	bi.ioctl = si;
	bi.length = sizeof(struct atto_ioctl_smp)
		    + le32_to_cpu(si->req_length)
		    + le32_to_cpu(si->rsp_length);
	bi.offset = 0;
	bi.callback = smp_ioctl_callback;
	return handle_buffered_ioctl(&bi);
}


/* CSMI ioctl support */
static void esas2r_csmi_ioctl_tunnel_comp_cb(struct esas2r_adapter *a,
					     struct esas2r_request *rq)
{
	rq->target_id = le16_to_cpu(rq->func_rsp.ioctl_rsp.csmi.target_id);
	rq->vrq->scsi.flags |= cpu_to_le32(rq->func_rsp.ioctl_rsp.csmi.lun);

	/* Now call the original completion callback. */
	(*rq->aux_req_cb)(a, rq);
}

/* Tunnel a CSMI IOCTL to the back end driver for processing. */
static bool csmi_ioctl_tunnel(struct esas2r_adapter *a,
			      union atto_ioctl_csmi *ci,
			      struct esas2r_request *rq,
			      struct esas2r_sg_context *sgc,
			      u32 ctrl_code,
			      u16 target_id)
{
	struct atto_vda_ioctl_req *ioctl = &rq->vrq->ioctl;

	if (a->flags & AF_DEGRADED_MODE)
		return false;

	esas2r_sgc_init(sgc, a, rq, rq->vrq->ioctl.sge);
	esas2r_build_ioctl_req(a, rq, sgc->length, VDA_IOCTL_CSMI);
	ioctl->csmi.ctrl_code = cpu_to_le32(ctrl_code);
	ioctl->csmi.target_id = cpu_to_le16(target_id);
	ioctl->csmi.lun = (u8)le32_to_cpu(rq->vrq->scsi.flags);

	/*
	 * Always usurp the completion callback since the interrupt callback
	 * mechanism may be used.
	 */
	rq->aux_req_cx = ci;
	rq->aux_req_cb = rq->comp_cb;
	rq->comp_cb = esas2r_csmi_ioctl_tunnel_comp_cb;

	if (!esas2r_build_sg_list(a, rq, sgc))
		return false;

	esas2r_start_request(a, rq);
	return true;
}

static bool check_lun(struct scsi_lun lun)
{
	bool result;

	result = ((lun.scsi_lun[7] == 0) &&
		  (lun.scsi_lun[6] == 0) &&
		  (lun.scsi_lun[5] == 0) &&
		  (lun.scsi_lun[4] == 0) &&
		  (lun.scsi_lun[3] == 0) &&
		  (lun.scsi_lun[2] == 0) &&
/* Byte 1 is intentionally skipped */
		  (lun.scsi_lun[0] == 0));

	return result;
}

static int csmi_ioctl_callback(struct esas2r_adapter *a,
			       struct esas2r_request *rq,
			       struct esas2r_sg_context *sgc, void *context)
{
	struct atto_csmi *ci = (struct atto_csmi *)context;
	union atto_ioctl_csmi *ioctl_csmi =
		(union atto_ioctl_csmi *)esas2r_buffered_ioctl;
	u8 path = 0;
	u8 tid = 0;
	u8 lun = 0;
	u32 sts = CSMI_STS_SUCCESS;
	struct esas2r_target *t;
	unsigned long flags;

	if (ci->control_code == CSMI_CC_GET_DEV_ADDR) {
		struct atto_csmi_get_dev_addr *gda = &ci->data.dev_addr;

		path = gda->path_id;
		tid = gda->target_id;
		lun = gda->lun;
	} else if (ci->control_code == CSMI_CC_TASK_MGT) {
		struct atto_csmi_task_mgmt *tm = &ci->data.tsk_mgt;

		path = tm->path_id;
		tid = tm->target_id;
		lun = tm->lun;
	}

	if (path > 0) {
		rq->func_rsp.ioctl_rsp.csmi.csmi_status = cpu_to_le32(
			CSMI_STS_INV_PARAM);
		return false;
	}

	rq->target_id = tid;
	rq->vrq->scsi.flags |= cpu_to_le32(lun);

	switch (ci->control_code) {
	case CSMI_CC_GET_DRVR_INFO:
	{
		struct atto_csmi_get_driver_info *gdi = &ioctl_csmi->drvr_info;

		strcpy(gdi->description, esas2r_get_model_name(a));
		gdi->csmi_major_rev = CSMI_MAJOR_REV;
		gdi->csmi_minor_rev = CSMI_MINOR_REV;
		break;
	}

	case CSMI_CC_GET_CNTLR_CFG:
	{
		struct atto_csmi_get_cntlr_cfg *gcc = &ioctl_csmi->cntlr_cfg;

		gcc->base_io_addr = 0;
		pci_read_config_dword(a->pcid, PCI_BASE_ADDRESS_2,
				      &gcc->base_memaddr_lo);
		pci_read_config_dword(a->pcid, PCI_BASE_ADDRESS_3,
				      &gcc->base_memaddr_hi);
		gcc->board_id = MAKEDWORD(a->pcid->subsystem_device,
					  a->pcid->subsystem_vendor);
		gcc->slot_num = CSMI_SLOT_NUM_UNKNOWN;
		gcc->cntlr_class = CSMI_CNTLR_CLASS_HBA;
		gcc->io_bus_type = CSMI_BUS_TYPE_PCI;
		gcc->pci_addr.bus_num = a->pcid->bus->number;
		gcc->pci_addr.device_num = PCI_SLOT(a->pcid->devfn);
		gcc->pci_addr.function_num = PCI_FUNC(a->pcid->devfn);

		memset(gcc->serial_num, 0, sizeof(gcc->serial_num));

		gcc->major_rev = LOBYTE(LOWORD(a->fw_version));
		gcc->minor_rev = HIBYTE(LOWORD(a->fw_version));
		gcc->build_rev = LOBYTE(HIWORD(a->fw_version));
		gcc->release_rev = HIBYTE(HIWORD(a->fw_version));
		gcc->bios_major_rev = HIBYTE(HIWORD(a->flash_ver));
		gcc->bios_minor_rev = LOBYTE(HIWORD(a->flash_ver));
		gcc->bios_build_rev = LOWORD(a->flash_ver);

		if (a->flags2 & AF2_THUNDERLINK)
			gcc->cntlr_flags = CSMI_CNTLRF_SAS_HBA
					   | CSMI_CNTLRF_SATA_HBA;
		else
			gcc->cntlr_flags = CSMI_CNTLRF_SAS_RAID
					   | CSMI_CNTLRF_SATA_RAID;

		gcc->rrom_major_rev = 0;
		gcc->rrom_minor_rev = 0;
		gcc->rrom_build_rev = 0;
		gcc->rrom_release_rev = 0;
		gcc->rrom_biosmajor_rev = 0;
		gcc->rrom_biosminor_rev = 0;
		gcc->rrom_biosbuild_rev = 0;
		gcc->rrom_biosrelease_rev = 0;
		break;
	}

	case CSMI_CC_GET_CNTLR_STS:
	{
		struct atto_csmi_get_cntlr_sts *gcs = &ioctl_csmi->cntlr_sts;

		if (a->flags & AF_DEGRADED_MODE)
			gcs->status = CSMI_CNTLR_STS_FAILED;
		else
			gcs->status = CSMI_CNTLR_STS_GOOD;

		gcs->offline_reason = CSMI_OFFLINE_NO_REASON;
		break;
	}

	case CSMI_CC_FW_DOWNLOAD:
	case CSMI_CC_GET_RAID_INFO:
	case CSMI_CC_GET_RAID_CFG:

		sts = CSMI_STS_BAD_CTRL_CODE;
		break;

	case CSMI_CC_SMP_PASSTHRU:
	case CSMI_CC_SSP_PASSTHRU:
	case CSMI_CC_STP_PASSTHRU:
	case CSMI_CC_GET_PHY_INFO:
	case CSMI_CC_SET_PHY_INFO:
	case CSMI_CC_GET_LINK_ERRORS:
	case CSMI_CC_GET_SATA_SIG:
	case CSMI_CC_GET_CONN_INFO:
	case CSMI_CC_PHY_CTRL:

		if (!csmi_ioctl_tunnel(a, ioctl_csmi, rq, sgc,
				       ci->control_code,
				       ESAS2R_TARG_ID_INV)) {
			sts = CSMI_STS_FAILED;
			break;
		}

		return true;

	case CSMI_CC_GET_SCSI_ADDR:
	{
		struct atto_csmi_get_scsi_addr *gsa = &ioctl_csmi->scsi_addr;

		struct scsi_lun lun;

		memcpy(&lun, gsa->sas_lun, sizeof(struct scsi_lun));

		if (!check_lun(lun)) {
			sts = CSMI_STS_NO_SCSI_ADDR;
			break;
		}

		/* make sure the device is present */
		spin_lock_irqsave(&a->mem_lock, flags);
		t = esas2r_targ_db_find_by_sas_addr(a, (u64 *)gsa->sas_addr);
		spin_unlock_irqrestore(&a->mem_lock, flags);

		if (t == NULL) {
			sts = CSMI_STS_NO_SCSI_ADDR;
			break;
		}

		gsa->host_index = 0xFF;
		gsa->lun = gsa->sas_lun[1];
		rq->target_id = esas2r_targ_get_id(t, a);
		break;
	}

	case CSMI_CC_GET_DEV_ADDR:
	{
		struct atto_csmi_get_dev_addr *gda = &ioctl_csmi->dev_addr;

		/* make sure the target is present */
		t = a->targetdb + rq->target_id;

		if (t >= a->targetdb_end
		    || t->target_state != TS_PRESENT
		    || t->sas_addr == 0) {
			sts = CSMI_STS_NO_DEV_ADDR;
			break;
		}

		/* fill in the result */
		*(u64 *)gda->sas_addr = t->sas_addr;
		memset(gda->sas_lun, 0, sizeof(gda->sas_lun));
		gda->sas_lun[1] = (u8)le32_to_cpu(rq->vrq->scsi.flags);
		break;
	}

	case CSMI_CC_TASK_MGT:

		/* make sure the target is present */
		t = a->targetdb + rq->target_id;

		if (t >= a->targetdb_end
		    || t->target_state != TS_PRESENT
		    || !(t->flags & TF_PASS_THRU)) {
			sts = CSMI_STS_NO_DEV_ADDR;
			break;
		}

		if (!csmi_ioctl_tunnel(a, ioctl_csmi, rq, sgc,
				       ci->control_code,
				       t->phys_targ_id)) {
			sts = CSMI_STS_FAILED;
			break;
		}

		return true;

	default:

		sts = CSMI_STS_BAD_CTRL_CODE;
		break;
	}

	rq->func_rsp.ioctl_rsp.csmi.csmi_status = cpu_to_le32(sts);

	return false;
}


static void csmi_ioctl_done_callback(struct esas2r_adapter *a,
				     struct esas2r_request *rq, void *context)
{
	struct atto_csmi *ci = (struct atto_csmi *)context;
	union atto_ioctl_csmi *ioctl_csmi =
		(union atto_ioctl_csmi *)esas2r_buffered_ioctl;

	switch (ci->control_code) {
	case CSMI_CC_GET_DRVR_INFO:
	{
		struct atto_csmi_get_driver_info *gdi =
			&ioctl_csmi->drvr_info;

		strcpy(gdi->name, ESAS2R_VERSION_STR);

		gdi->major_rev = ESAS2R_MAJOR_REV;
		gdi->minor_rev = ESAS2R_MINOR_REV;
		gdi->build_rev = 0;
		gdi->release_rev = 0;
		break;
	}

	case CSMI_CC_GET_SCSI_ADDR:
	{
		struct atto_csmi_get_scsi_addr *gsa = &ioctl_csmi->scsi_addr;

		if (le32_to_cpu(rq->func_rsp.ioctl_rsp.csmi.csmi_status) ==
		    CSMI_STS_SUCCESS) {
			gsa->target_id = rq->target_id;
			gsa->path_id = 0;
		}

		break;
	}
	}

	ci->status = le32_to_cpu(rq->func_rsp.ioctl_rsp.csmi.csmi_status);
}


static u8 handle_csmi_ioctl(struct esas2r_adapter *a, struct atto_csmi *ci)
{
	struct esas2r_buffered_ioctl bi;

	memset(&bi, 0, sizeof(bi));

	bi.a = a;
	bi.ioctl = &ci->data;
	bi.length = sizeof(union atto_ioctl_csmi);
	bi.offset = 0;
	bi.callback = csmi_ioctl_callback;
	bi.context = ci;
	bi.done_callback = csmi_ioctl_done_callback;
	bi.done_context = ci;

	return handle_buffered_ioctl(&bi);
}

/* ATTO HBA ioctl support */

/* Tunnel an ATTO HBA IOCTL to the back end driver for processing. */
static bool hba_ioctl_tunnel(struct esas2r_adapter *a,
			     struct atto_ioctl *hi,
			     struct esas2r_request *rq,
			     struct esas2r_sg_context *sgc)
{
	esas2r_sgc_init(sgc, a, rq, rq->vrq->ioctl.sge);

	esas2r_build_ioctl_req(a, rq, sgc->length, VDA_IOCTL_HBA);

	if (!esas2r_build_sg_list(a, rq, sgc)) {
		hi->status = ATTO_STS_OUT_OF_RSRC;

		return false;
	}

	esas2r_start_request(a, rq);

	return true;
}

static void scsi_passthru_comp_cb(struct esas2r_adapter *a,
				  struct esas2r_request *rq)
{
	struct atto_ioctl *hi = (struct atto_ioctl *)rq->aux_req_cx;
	struct atto_hba_scsi_pass_thru *spt = &hi->data.scsi_pass_thru;
	u8 sts = ATTO_SPT_RS_FAILED;

	spt->scsi_status = rq->func_rsp.scsi_rsp.scsi_stat;
	spt->sense_length = rq->sense_len;
	spt->residual_length =
		le32_to_cpu(rq->func_rsp.scsi_rsp.residual_length);

	switch (rq->req_stat) {
	case RS_SUCCESS:
	case RS_SCSI_ERROR:
		sts = ATTO_SPT_RS_SUCCESS;
		break;
	case RS_UNDERRUN:
		sts = ATTO_SPT_RS_UNDERRUN;
		break;
	case RS_OVERRUN:
		sts = ATTO_SPT_RS_OVERRUN;
		break;
	case RS_SEL:
	case RS_SEL2:
		sts = ATTO_SPT_RS_NO_DEVICE;
		break;
	case RS_NO_LUN:
		sts = ATTO_SPT_RS_NO_LUN;
		break;
	case RS_TIMEOUT:
		sts = ATTO_SPT_RS_TIMEOUT;
		break;
	case RS_DEGRADED:
		sts = ATTO_SPT_RS_DEGRADED;
		break;
	case RS_BUSY:
		sts = ATTO_SPT_RS_BUSY;
		break;
	case RS_ABORTED:
		sts = ATTO_SPT_RS_ABORTED;
		break;
	case RS_RESET:
		sts = ATTO_SPT_RS_BUS_RESET;
		break;
	}

	spt->req_status = sts;

	/* Update the target ID to the next one present. */
	spt->target_id =
		esas2r_targ_db_find_next_present(a, (u16)spt->target_id);

	/* Done, call the completion callback. */
	(*rq->aux_req_cb)(a, rq);
}

static int hba_ioctl_callback(struct esas2r_adapter *a,
			      struct esas2r_request *rq,
			      struct esas2r_sg_context *sgc,
			      void *context)
{
	struct atto_ioctl *hi = (struct atto_ioctl *)esas2r_buffered_ioctl;

	hi->status = ATTO_STS_SUCCESS;

	switch (hi->function) {
	case ATTO_FUNC_GET_ADAP_INFO:
	{
		u8 *class_code = (u8 *)&a->pcid->class;

		struct atto_hba_get_adapter_info *gai =
			&hi->data.get_adap_info;
		int pcie_cap_reg;

		if (hi->flags & HBAF_TUNNEL) {
			hi->status = ATTO_STS_UNSUPPORTED;
			break;
		}

		if (hi->version > ATTO_VER_GET_ADAP_INFO0) {
			hi->status = ATTO_STS_INV_VERSION;
			hi->version = ATTO_VER_GET_ADAP_INFO0;
			break;
		}

		memset(gai, 0, sizeof(*gai));

		gai->pci.vendor_id = a->pcid->vendor;
		gai->pci.device_id = a->pcid->device;
		gai->pci.ss_vendor_id = a->pcid->subsystem_vendor;
		gai->pci.ss_device_id = a->pcid->subsystem_device;
		gai->pci.class_code[0] = class_code[0];
		gai->pci.class_code[1] = class_code[1];
		gai->pci.class_code[2] = class_code[2];
		gai->pci.rev_id = a->pcid->revision;
		gai->pci.bus_num = a->pcid->bus->number;
		gai->pci.dev_num = PCI_SLOT(a->pcid->devfn);
		gai->pci.func_num = PCI_FUNC(a->pcid->devfn);

		pcie_cap_reg = pci_find_capability(a->pcid, PCI_CAP_ID_EXP);
		if (pcie_cap_reg) {
			u16 stat;
			u32 caps;

			pci_read_config_word(a->pcid,
					     pcie_cap_reg + PCI_EXP_LNKSTA,
					     &stat);
			pci_read_config_dword(a->pcid,
					      pcie_cap_reg + PCI_EXP_LNKCAP,
					      &caps);

			gai->pci.link_speed_curr =
				(u8)(stat & PCI_EXP_LNKSTA_CLS);
			gai->pci.link_speed_max =
				(u8)(caps & PCI_EXP_LNKCAP_SLS);
			gai->pci.link_width_curr =
				(u8)((stat & PCI_EXP_LNKSTA_NLW)
				     >> PCI_EXP_LNKSTA_NLW_SHIFT);
			gai->pci.link_width_max =
				(u8)((caps & PCI_EXP_LNKCAP_MLW)
				     >> 4);
		}

		gai->pci.msi_vector_cnt = 1;

		if (a->pcid->msix_enabled)
			gai->pci.interrupt_mode = ATTO_GAI_PCIIM_MSIX;
		else if (a->pcid->msi_enabled)
			gai->pci.interrupt_mode = ATTO_GAI_PCIIM_MSI;
		else
			gai->pci.interrupt_mode = ATTO_GAI_PCIIM_LEGACY;

		gai->adap_type = ATTO_GAI_AT_ESASRAID2;

		if (a->flags2 & AF2_THUNDERLINK)
			gai->adap_type = ATTO_GAI_AT_TLSASHBA;

		if (a->flags & AF_DEGRADED_MODE)
			gai->adap_flags |= ATTO_GAI_AF_DEGRADED;

		gai->adap_flags |= ATTO_GAI_AF_SPT_SUPP |
				   ATTO_GAI_AF_DEVADDR_SUPP;

		if (a->pcid->subsystem_device == ATTO_ESAS_R60F
		    || a->pcid->subsystem_device == ATTO_ESAS_R608
		    || a->pcid->subsystem_device == ATTO_ESAS_R644
		    || a->pcid->subsystem_device == ATTO_TSSC_3808E)
			gai->adap_flags |= ATTO_GAI_AF_VIRT_SES;

		gai->num_ports = ESAS2R_NUM_PHYS;
		gai->num_phys = ESAS2R_NUM_PHYS;

		strcpy(gai->firmware_rev, a->fw_rev);
		strcpy(gai->flash_rev, a->flash_rev);
		strcpy(gai->model_name_short, esas2r_get_model_name_short(a));
		strcpy(gai->model_name, esas2r_get_model_name(a));

		gai->num_targets = ESAS2R_MAX_TARGETS;

		gai->num_busses = 1;
		gai->num_targsper_bus = gai->num_targets;
		gai->num_lunsper_targ = 256;

		if (a->pcid->subsystem_device == ATTO_ESAS_R6F0
		    || a->pcid->subsystem_device == ATTO_ESAS_R60F)
			gai->num_connectors = 4;
		else
			gai->num_connectors = 2;

		gai->adap_flags2 |= ATTO_GAI_AF2_ADAP_CTRL_SUPP;

		gai->num_targets_backend = a->num_targets_backend;

		gai->tunnel_flags = a->ioctl_tunnel
				    & (ATTO_GAI_TF_MEM_RW
				       | ATTO_GAI_TF_TRACE
				       | ATTO_GAI_TF_SCSI_PASS_THRU
				       | ATTO_GAI_TF_GET_DEV_ADDR
				       | ATTO_GAI_TF_PHY_CTRL
				       | ATTO_GAI_TF_CONN_CTRL
				       | ATTO_GAI_TF_GET_DEV_INFO);
		break;
	}

	case ATTO_FUNC_GET_ADAP_ADDR:
	{
		struct atto_hba_get_adapter_address *gaa =
			&hi->data.get_adap_addr;

		if (hi->flags & HBAF_TUNNEL) {
			hi->status = ATTO_STS_UNSUPPORTED;
			break;
		}

		if (hi->version > ATTO_VER_GET_ADAP_ADDR0) {
			hi->status = ATTO_STS_INV_VERSION;
			hi->version = ATTO_VER_GET_ADAP_ADDR0;
		} else if (gaa->addr_type == ATTO_GAA_AT_PORT
			   || gaa->addr_type == ATTO_GAA_AT_NODE) {
			if (gaa->addr_type == ATTO_GAA_AT_PORT
			    && gaa->port_id >= ESAS2R_NUM_PHYS) {
				hi->status = ATTO_STS_NOT_APPL;
			} else {
				memcpy((u64 *)gaa->address,
				       &a->nvram->sas_addr[0], sizeof(u64));
				gaa->addr_len = sizeof(u64);
			}
		} else {
			hi->status = ATTO_STS_INV_PARAM;
		}

		break;
	}

	case ATTO_FUNC_MEM_RW:
	{
		if (hi->flags & HBAF_TUNNEL) {
			if (hba_ioctl_tunnel(a, hi, rq, sgc))
				return true;

			break;
		}

		hi->status = ATTO_STS_UNSUPPORTED;

		break;
	}

	case ATTO_FUNC_TRACE:
	{
		struct atto_hba_trace *trc = &hi->data.trace;

		if (hi->flags & HBAF_TUNNEL) {
			if (hba_ioctl_tunnel(a, hi, rq, sgc))
				return true;

			break;
		}

		if (hi->version > ATTO_VER_TRACE1) {
			hi->status = ATTO_STS_INV_VERSION;
			hi->version = ATTO_VER_TRACE1;
			break;
		}

		if (trc->trace_type == ATTO_TRC_TT_FWCOREDUMP
		    && hi->version >= ATTO_VER_TRACE1) {
			if (trc->trace_func == ATTO_TRC_TF_UPLOAD) {
				u32 len = hi->data_length;
				u32 offset = trc->current_offset;
				u32 total_len = ESAS2R_FWCOREDUMP_SZ;

				/* Size is zero if a core dump isn't present */
				if (!(a->flags2 & AF2_COREDUMP_SAVED))
					total_len = 0;

				if (len > total_len)
					len = total_len;

				if (offset >= total_len
				    || offset + len > total_len
				    || len == 0) {
					hi->status = ATTO_STS_INV_PARAM;
					break;
				}

				memcpy(trc + 1,
				       a->fw_coredump_buff + offset,
				       len);

				hi->data_length = len;
			} else if (trc->trace_func == ATTO_TRC_TF_RESET) {
				memset(a->fw_coredump_buff, 0,
				       ESAS2R_FWCOREDUMP_SZ);

				esas2r_lock_clear_flags(&a->flags2,
							AF2_COREDUMP_SAVED);
			} else if (trc->trace_func != ATTO_TRC_TF_GET_INFO) {
				hi->status = ATTO_STS_UNSUPPORTED;
				break;
			}

			/* Always return all the info we can. */
			trc->trace_mask = 0;
			trc->current_offset = 0;
			trc->total_length = ESAS2R_FWCOREDUMP_SZ;

			/* Return zero length buffer if core dump not present */
			if (!(a->flags2 & AF2_COREDUMP_SAVED))
				trc->total_length = 0;
		} else {
			hi->status = ATTO_STS_UNSUPPORTED;
		}

		break;
	}

	case ATTO_FUNC_SCSI_PASS_THRU:
	{
		struct atto_hba_scsi_pass_thru *spt = &hi->data.scsi_pass_thru;
		struct scsi_lun lun;

		memcpy(&lun, spt->lun, sizeof(struct scsi_lun));

		if (hi->flags & HBAF_TUNNEL) {
			if (hba_ioctl_tunnel(a, hi, rq, sgc))
				return true;

			break;
		}

		if (hi->version > ATTO_VER_SCSI_PASS_THRU0) {
			hi->status = ATTO_STS_INV_VERSION;
			hi->version = ATTO_VER_SCSI_PASS_THRU0;
			break;
		}

		if (spt->target_id >= ESAS2R_MAX_TARGETS || !check_lun(lun)) {
			hi->status = ATTO_STS_INV_PARAM;
			break;
		}

		esas2r_sgc_init(sgc, a, rq, NULL);

		sgc->length = hi->data_length;
		sgc->cur_offset += offsetof(struct atto_ioctl, data.byte)
				   + sizeof(struct atto_hba_scsi_pass_thru);

		/* Finish request initialization */
		rq->target_id = (u16)spt->target_id;
		rq->vrq->scsi.flags |= cpu_to_le32(spt->lun[1]);
		memcpy(rq->vrq->scsi.cdb, spt->cdb, 16);
		rq->vrq->scsi.length = cpu_to_le32(hi->data_length);
		rq->sense_len = spt->sense_length;
		rq->sense_buf = (u8 *)spt->sense_data;
		/* NOTE: we ignore spt->timeout */

		/*
		 * always usurp the completion callback since the interrupt
		 * callback mechanism may be used.
		 */

		rq->aux_req_cx = hi;
		rq->aux_req_cb = rq->comp_cb;
		rq->comp_cb = scsi_passthru_comp_cb;

		if (spt->flags & ATTO_SPTF_DATA_IN) {
			rq->vrq->scsi.flags |= cpu_to_le32(FCP_CMND_RDD);
		} else if (spt->flags & ATTO_SPTF_DATA_OUT) {
			rq->vrq->scsi.flags |= cpu_to_le32(FCP_CMND_WRD);
		} else {
			if (sgc->length) {
				hi->status = ATTO_STS_INV_PARAM;
				break;
			}
		}

		if (spt->flags & ATTO_SPTF_ORDERED_Q)
			rq->vrq->scsi.flags |=
				cpu_to_le32(FCP_CMND_TA_ORDRD_Q);
		else if (spt->flags & ATTO_SPTF_HEAD_OF_Q)
			rq->vrq->scsi.flags |= cpu_to_le32(FCP_CMND_TA_HEAD_Q);

		if (!esas2r_build_sg_list(a, rq, sgc)) {
			hi->status = ATTO_STS_OUT_OF_RSRC;
			break;
		}

		esas2r_start_request(a, rq);

		return true;
	}

	case ATTO_FUNC_GET_DEV_ADDR:
	{
		struct atto_hba_get_device_address *gda =
			&hi->data.get_dev_addr;
		struct esas2r_target *t;

		if (hi->flags & HBAF_TUNNEL) {
			if (hba_ioctl_tunnel(a, hi, rq, sgc))
				return true;

			break;
		}

		if (hi->version > ATTO_VER_GET_DEV_ADDR0) {
			hi->status = ATTO_STS_INV_VERSION;
			hi->version = ATTO_VER_GET_DEV_ADDR0;
			break;
		}

		if (gda->target_id >= ESAS2R_MAX_TARGETS) {
			hi->status = ATTO_STS_INV_PARAM;
			break;
		}

		t = a->targetdb + (u16)gda->target_id;

		if (t->target_state != TS_PRESENT) {
			hi->status = ATTO_STS_FAILED;
		} else if (gda->addr_type == ATTO_GDA_AT_PORT) {
			if (t->sas_addr == 0) {
				hi->status = ATTO_STS_UNSUPPORTED;
			} else {
				*(u64 *)gda->address = t->sas_addr;

				gda->addr_len = sizeof(u64);
			}
		} else if (gda->addr_type == ATTO_GDA_AT_NODE) {
			hi->status = ATTO_STS_NOT_APPL;
		} else {
			hi->status = ATTO_STS_INV_PARAM;
		}

		/* update the target ID to the next one present. */

		gda->target_id =
			esas2r_targ_db_find_next_present(a,
							 (u16)gda->target_id);
		break;
	}

	case ATTO_FUNC_PHY_CTRL:
	case ATTO_FUNC_CONN_CTRL:
	{
		if (hba_ioctl_tunnel(a, hi, rq, sgc))
			return true;

		break;
	}

	case ATTO_FUNC_ADAP_CTRL:
	{
		struct atto_hba_adap_ctrl *ac = &hi->data.adap_ctrl;

		if (hi->flags & HBAF_TUNNEL) {
			hi->status = ATTO_STS_UNSUPPORTED;
			break;
		}

		if (hi->version > ATTO_VER_ADAP_CTRL0) {
			hi->status = ATTO_STS_INV_VERSION;
			hi->version = ATTO_VER_ADAP_CTRL0;
			break;
		}

		if (ac->adap_func == ATTO_AC_AF_HARD_RST) {
			esas2r_reset_adapter(a);
		} else if (ac->adap_func != ATTO_AC_AF_GET_STATE) {
			hi->status = ATTO_STS_UNSUPPORTED;
			break;
		}

		if (a->flags & AF_CHPRST_NEEDED)
			ac->adap_state = ATTO_AC_AS_RST_SCHED;
		else if (a->flags & AF_CHPRST_PENDING)
			ac->adap_state = ATTO_AC_AS_RST_IN_PROG;
		else if (a->flags & AF_DISC_PENDING)
			ac->adap_state = ATTO_AC_AS_RST_DISC;
		else if (a->flags & AF_DISABLED)
			ac->adap_state = ATTO_AC_AS_DISABLED;
		else if (a->flags & AF_DEGRADED_MODE)
			ac->adap_state = ATTO_AC_AS_DEGRADED;
		else
			ac->adap_state = ATTO_AC_AS_OK;

		break;
	}

	case ATTO_FUNC_GET_DEV_INFO:
	{
		struct atto_hba_get_device_info *gdi = &hi->data.get_dev_info;
		struct esas2r_target *t;

		if (hi->flags & HBAF_TUNNEL) {
			if (hba_ioctl_tunnel(a, hi, rq, sgc))
				return true;

			break;
		}

		if (hi->version > ATTO_VER_GET_DEV_INFO0) {
			hi->status = ATTO_STS_INV_VERSION;
			hi->version = ATTO_VER_GET_DEV_INFO0;
			break;
		}

		if (gdi->target_id >= ESAS2R_MAX_TARGETS) {
			hi->status = ATTO_STS_INV_PARAM;
			break;
		}

		t = a->targetdb + (u16)gdi->target_id;

		/* update the target ID to the next one present. */

		gdi->target_id =
			esas2r_targ_db_find_next_present(a,
							 (u16)gdi->target_id);

		if (t->target_state != TS_PRESENT) {
			hi->status = ATTO_STS_FAILED;
			break;
		}

		hi->status = ATTO_STS_UNSUPPORTED;
		break;
	}

	default:

		hi->status = ATTO_STS_INV_FUNC;
		break;
	}

	return false;
}

static void hba_ioctl_done_callback(struct esas2r_adapter *a,
				    struct esas2r_request *rq, void *context)
{
	struct atto_ioctl *ioctl_hba =
		(struct atto_ioctl *)esas2r_buffered_ioctl;

	esas2r_debug("hba_ioctl_done_callback %d", a->index);

	if (ioctl_hba->function == ATTO_FUNC_GET_ADAP_INFO) {
		struct atto_hba_get_adapter_info *gai =
			&ioctl_hba->data.get_adap_info;

		esas2r_debug("ATTO_FUNC_GET_ADAP_INFO");

		gai->drvr_rev_major = ESAS2R_MAJOR_REV;
		gai->drvr_rev_minor = ESAS2R_MINOR_REV;

		strcpy(gai->drvr_rev_ascii, ESAS2R_VERSION_STR);
		strcpy(gai->drvr_name, ESAS2R_DRVR_NAME);

		gai->num_busses = 1;
		gai->num_targsper_bus = ESAS2R_MAX_ID + 1;
		gai->num_lunsper_targ = 1;
	}
}

u8 handle_hba_ioctl(struct esas2r_adapter *a,
		    struct atto_ioctl *ioctl_hba)
{
	struct esas2r_buffered_ioctl bi;

	memset(&bi, 0, sizeof(bi));

	bi.a = a;
	bi.ioctl = ioctl_hba;
	bi.length = sizeof(struct atto_ioctl) + ioctl_hba->data_length;
	bi.callback = hba_ioctl_callback;
	bi.context = NULL;
	bi.done_callback = hba_ioctl_done_callback;
	bi.done_context = NULL;
	bi.offset = 0;

	return handle_buffered_ioctl(&bi);
}


int esas2r_write_params(struct esas2r_adapter *a, struct esas2r_request *rq,
			struct esas2r_sas_nvram *data)
{
	int result = 0;

	a->nvram_command_done = 0;
	rq->comp_cb = complete_nvr_req;

	if (esas2r_nvram_write(a, rq, data)) {
		/* now wait around for it to complete. */
		while (!a->nvram_command_done)
			wait_event_interruptible(a->nvram_waiter,
						 a->nvram_command_done);
		;

		/* done, check the status. */
		if (rq->req_stat == RS_SUCCESS)
			result = 1;
	}
	return result;
}


/* This function only cares about ATTO-specific ioctls (atto_express_ioctl) */
int esas2r_ioctl_handler(void *hostdata, int cmd, void __user *arg)
{
	struct atto_express_ioctl *ioctl = NULL;
	struct esas2r_adapter *a;
	struct esas2r_request *rq;
	u16 code;
	int err;

	esas2r_log(ESAS2R_LOG_DEBG, "ioctl (%p, %x, %p)", hostdata, cmd, arg);

	if ((arg == NULL)
	    || (cmd < EXPRESS_IOCTL_MIN)
	    || (cmd > EXPRESS_IOCTL_MAX))
		return -ENOTSUPP;

	if (!access_ok(VERIFY_WRITE, arg, sizeof(struct atto_express_ioctl))) {
		esas2r_log(ESAS2R_LOG_WARN,
			   "ioctl_handler access_ok failed for cmd %d, "
			   "address %p", cmd,
			   arg);
		return -EFAULT;
	}

	/* allocate a kernel memory buffer for the IOCTL data */
	ioctl = kzalloc(sizeof(struct atto_express_ioctl), GFP_KERNEL);
	if (ioctl == NULL) {
		esas2r_log(ESAS2R_LOG_WARN,
			   "ioctl_handler kzalloc failed for %d bytes",
			   sizeof(struct atto_express_ioctl));
		return -ENOMEM;
	}

	err = __copy_from_user(ioctl, arg, sizeof(struct atto_express_ioctl));
	if (err != 0) {
		esas2r_log(ESAS2R_LOG_WARN,
			   "copy_from_user didn't copy everything (err %d, cmd %d)",
			   err,
			   cmd);
		kfree(ioctl);

		return -EFAULT;
	}

	/* verify the signature */

	if (memcmp(ioctl->header.signature,
		   EXPRESS_IOCTL_SIGNATURE,
		   EXPRESS_IOCTL_SIGNATURE_SIZE) != 0) {
		esas2r_log(ESAS2R_LOG_WARN, "invalid signature");
		kfree(ioctl);

		return -ENOTSUPP;
	}

	/* assume success */

	ioctl->header.return_code = IOCTL_SUCCESS;
	err = 0;

	/*
	 * handle EXPRESS_IOCTL_GET_CHANNELS
	 * without paying attention to channel
	 */

	if (cmd == EXPRESS_IOCTL_GET_CHANNELS) {
		int i = 0, k = 0;

		ioctl->data.chanlist.num_channels = 0;

		while (i < MAX_ADAPTERS) {
			if (esas2r_adapters[i]) {
				ioctl->data.chanlist.num_channels++;
				ioctl->data.chanlist.channel[k] = i;
				k++;
			}
			i++;
		}

		goto ioctl_done;
	}

	/* get the channel */

	if (ioctl->header.channel == 0xFF) {
		a = (struct esas2r_adapter *)hostdata;
	} else {
		a = esas2r_adapters[ioctl->header.channel];
		if (ioctl->header.channel >= MAX_ADAPTERS || (a == NULL)) {
			ioctl->header.return_code = IOCTL_BAD_CHANNEL;
			esas2r_log(ESAS2R_LOG_WARN, "bad channel value");
			kfree(ioctl);

			return -ENOTSUPP;
		}
	}

	switch (cmd) {
	case EXPRESS_IOCTL_RW_FIRMWARE:

		if (ioctl->data.fwrw.img_type == FW_IMG_FM_API) {
			err = esas2r_write_fw(a,
					      (char *)ioctl->data.fwrw.image,
					      0,
					      sizeof(struct
						     atto_express_ioctl));

			if (err >= 0) {
				err = esas2r_read_fw(a,
						     (char *)ioctl->data.fwrw.
						     image,
						     0,
						     sizeof(struct
							    atto_express_ioctl));
			}
		} else if (ioctl->data.fwrw.img_type == FW_IMG_FS_API) {
			err = esas2r_write_fs(a,
					      (char *)ioctl->data.fwrw.image,
					      0,
					      sizeof(struct
						     atto_express_ioctl));

			if (err >= 0) {
				err = esas2r_read_fs(a,
						     (char *)ioctl->data.fwrw.
						     image,
						     0,
						     sizeof(struct
							    atto_express_ioctl));
			}
		} else {
			ioctl->header.return_code = IOCTL_BAD_FLASH_IMGTYPE;
		}

		break;

	case EXPRESS_IOCTL_READ_PARAMS:

		memcpy(ioctl->data.prw.data_buffer, a->nvram,
		       sizeof(struct esas2r_sas_nvram));
		ioctl->data.prw.code = 1;
		break;

	case EXPRESS_IOCTL_WRITE_PARAMS:

		rq = esas2r_alloc_request(a);
		if (rq == NULL) {
			up(&a->nvram_semaphore);
			ioctl->data.prw.code = 0;
			break;
		}

		code = esas2r_write_params(a, rq,
					   (struct esas2r_sas_nvram *)ioctl->data.prw.data_buffer);
		ioctl->data.prw.code = code;

		esas2r_free_request(a, rq);

		break;

	case EXPRESS_IOCTL_DEFAULT_PARAMS:

		esas2r_nvram_get_defaults(a,
					  (struct esas2r_sas_nvram *)ioctl->data.prw.data_buffer);
		ioctl->data.prw.code = 1;
		break;

	case EXPRESS_IOCTL_CHAN_INFO:

		ioctl->data.chaninfo.major_rev = ESAS2R_MAJOR_REV;
		ioctl->data.chaninfo.minor_rev = ESAS2R_MINOR_REV;
		ioctl->data.chaninfo.IRQ = a->pcid->irq;
		ioctl->data.chaninfo.device_id = a->pcid->device;
		ioctl->data.chaninfo.vendor_id = a->pcid->vendor;
		ioctl->data.chaninfo.ven_dev_id = a->pcid->subsystem_device;
		ioctl->data.chaninfo.revision_id = a->pcid->revision;
		ioctl->data.chaninfo.pci_bus = a->pcid->bus->number;
		ioctl->data.chaninfo.pci_dev_func = a->pcid->devfn;
		ioctl->data.chaninfo.core_rev = 0;
		ioctl->data.chaninfo.host_no = a->host->host_no;
		ioctl->data.chaninfo.hbaapi_rev = 0;
		break;

	case EXPRESS_IOCTL_SMP:
		ioctl->header.return_code = handle_smp_ioctl(a,
							     &ioctl->data.
							     ioctl_smp);
		break;

	case EXPRESS_CSMI:
		ioctl->header.return_code =
			handle_csmi_ioctl(a, &ioctl->data.csmi);
		break;

	case EXPRESS_IOCTL_HBA:
		ioctl->header.return_code = handle_hba_ioctl(a,
							     &ioctl->data.
							     ioctl_hba);
		break;

	case EXPRESS_IOCTL_VDA:
		err = esas2r_write_vda(a,
				       (char *)&ioctl->data.ioctl_vda,
				       0,
				       sizeof(struct atto_ioctl_vda) +
				       ioctl->data.ioctl_vda.data_length);

		if (err >= 0) {
			err = esas2r_read_vda(a,
					      (char *)&ioctl->data.ioctl_vda,
					      0,
					      sizeof(struct atto_ioctl_vda) +
					      ioctl->data.ioctl_vda.data_length);
		}




		break;

	case EXPRESS_IOCTL_GET_MOD_INFO:

		ioctl->data.modinfo.adapter = a;
		ioctl->data.modinfo.pci_dev = a->pcid;
		ioctl->data.modinfo.scsi_host = a->host;
		ioctl->data.modinfo.host_no = a->host->host_no;

		break;

	default:
		esas2r_debug("esas2r_ioctl invalid cmd %p!", cmd);
		ioctl->header.return_code = IOCTL_ERR_INVCMD;
	}

ioctl_done:

	if (err < 0) {
		esas2r_log(ESAS2R_LOG_WARN, "err %d on ioctl cmd %d", err,
			   cmd);

		switch (err) {
		case -ENOMEM:
		case -EBUSY:
			ioctl->header.return_code = IOCTL_OUT_OF_RESOURCES;
			break;

		case -ENOSYS:
		case -EINVAL:
			ioctl->header.return_code = IOCTL_INVALID_PARAM;
			break;
		}

		ioctl->header.return_code = IOCTL_GENERAL_ERROR;
	}

	/* Always copy the buffer back, if only to pick up the status */
	err = __copy_to_user(arg, ioctl, sizeof(struct atto_express_ioctl));
	if (err != 0) {
		esas2r_log(ESAS2R_LOG_WARN,
			   "ioctl_handler copy_to_user didn't copy "
			   "everything (err %d, cmd %d)", err,
			   cmd);
		kfree(ioctl);

		return -EFAULT;
	}

	kfree(ioctl);

	return 0;
}

int esas2r_ioctl(struct scsi_device *sd, int cmd, void __user *arg)
{
	return esas2r_ioctl_handler(sd->host->hostdata, cmd, arg);
}

static void free_fw_buffers(struct esas2r_adapter *a)
{
	if (a->firmware.data) {
		dma_free_coherent(&a->pcid->dev,
				  (size_t)a->firmware.orig_len,
				  a->firmware.data,
				  (dma_addr_t)a->firmware.phys);

		a->firmware.data = NULL;
	}
}

static int allocate_fw_buffers(struct esas2r_adapter *a, u32 length)
{
	free_fw_buffers(a);

	a->firmware.orig_len = length;

	a->firmware.data = (u8 *)dma_alloc_coherent(&a->pcid->dev,
						    (size_t)length,
						    (dma_addr_t *)&a->firmware.
						    phys,
						    GFP_KERNEL);

	if (!a->firmware.data) {
		esas2r_debug("buffer alloc failed!");
		return 0;
	}

	return 1;
}

/* Handle a call to read firmware. */
int esas2r_read_fw(struct esas2r_adapter *a, char *buf, long off, int count)
{
	esas2r_trace_enter();
	/* if the cached header is a status, simply copy it over and return. */
	if (a->firmware.state == FW_STATUS_ST) {
		int size = min_t(int, count, sizeof(a->firmware.header));
		esas2r_trace_exit();
		memcpy(buf, &a->firmware.header, size);
		esas2r_debug("esas2r_read_fw: STATUS size %d", size);
		return size;
	}

	/*
	 * if the cached header is a command, do it if at
	 * offset 0, otherwise copy the pieces.
	 */

	if (a->firmware.state == FW_COMMAND_ST) {
		u32 length = a->firmware.header.length;
		esas2r_trace_exit();

		esas2r_debug("esas2r_read_fw: COMMAND length %d off %d",
			     length,
			     off);

		if (off == 0) {
			if (a->firmware.header.action == FI_ACT_UP) {
				if (!allocate_fw_buffers(a, length))
					return -ENOMEM;


				/* copy header over */

				memcpy(a->firmware.data,
				       &a->firmware.header,
				       sizeof(a->firmware.header));

				do_fm_api(a,
					  (struct esas2r_flash_img *)a->firmware.data);
			} else if (a->firmware.header.action == FI_ACT_UPSZ) {
				int size =
					min((int)count,
					    (int)sizeof(a->firmware.header));
				do_fm_api(a, &a->firmware.header);
				memcpy(buf, &a->firmware.header, size);
				esas2r_debug("FI_ACT_UPSZ size %d", size);
				return size;
			} else {
				esas2r_debug("invalid action %d",
					     a->firmware.header.action);
				return -ENOSYS;
			}
		}

		if (count + off > length)
			count = length - off;

		if (count < 0)
			return 0;

		if (!a->firmware.data) {
			esas2r_debug(
				"read: nonzero offset but no buffer available!");
			return -ENOMEM;
		}

		esas2r_debug("esas2r_read_fw: off %d count %d length %d ", off,
			     count,
			     length);

		memcpy(buf, &a->firmware.data[off], count);

		/* when done, release the buffer */

		if (length <= off + count) {
			esas2r_debug("esas2r_read_fw: freeing buffer!");

			free_fw_buffers(a);
		}

		return count;
	}

	esas2r_trace_exit();
	esas2r_debug("esas2r_read_fw: invalid firmware state %d",
		     a->firmware.state);

	return -EINVAL;
}

/* Handle a call to write firmware. */
int esas2r_write_fw(struct esas2r_adapter *a, const char *buf, long off,
		    int count)
{
	u32 length;

	if (off == 0) {
		struct esas2r_flash_img *header =
			(struct esas2r_flash_img *)buf;

		/* assume version 0 flash image */

		int min_size = sizeof(struct esas2r_flash_img_v0);

		a->firmware.state = FW_INVALID_ST;

		/* validate the version field first */

		if (count < 4
		    ||  header->fi_version > FI_VERSION_1) {
			esas2r_debug(
				"esas2r_write_fw: short header or invalid version");
			return -EINVAL;
		}

		/* See if its a version 1 flash image */

		if (header->fi_version == FI_VERSION_1)
			min_size = sizeof(struct esas2r_flash_img);

		/* If this is the start, the header must be full and valid. */
		if (count < min_size) {
			esas2r_debug("esas2r_write_fw: short header, aborting");
			return -EINVAL;
		}

		/* Make sure the size is reasonable. */
		length = header->length;

		if (length > 1024 * 1024) {
			esas2r_debug(
				"esas2r_write_fw: hosed, length %d  fi_version %d",
				length, header->fi_version);
			return -EINVAL;
		}

		/*
		 * If this is a write command, allocate memory because
		 * we have to cache everything. otherwise, just cache
		 * the header, because the read op will do the command.
		 */

		if (header->action == FI_ACT_DOWN) {
			if (!allocate_fw_buffers(a, length))
				return -ENOMEM;

			/*
			 * Store the command, so there is context on subsequent
			 * calls.
			 */
			memcpy(&a->firmware.header,
			       buf,
			       sizeof(*header));
		} else if (header->action == FI_ACT_UP
			   ||  header->action == FI_ACT_UPSZ) {
			/* Save the command, result will be picked up on read */
			memcpy(&a->firmware.header,
			       buf,
			       sizeof(*header));

			a->firmware.state = FW_COMMAND_ST;

			esas2r_debug(
				"esas2r_write_fw: COMMAND, count %d, action %d ",
				count, header->action);

			/*
			 * Pretend we took the whole buffer,
			 * so we don't get bothered again.
			 */

			return count;
		} else {
			esas2r_debug("esas2r_write_fw: invalid action %d ",
				     a->firmware.header.action);
			return -ENOSYS;
		}
	} else {
		length = a->firmware.header.length;
	}

	/*
	 * We only get here on a download command, regardless of offset.
	 * the chunks written by the system need to be cached, and when
	 * the final one arrives, issue the fmapi command.
	 */

	if (off + count > length)
		count = length - off;

	if (count > 0) {
		esas2r_debug("esas2r_write_fw: off %d count %d length %d", off,
			     count,
			     length);

		/*
		 * On a full upload, the system tries sending the whole buffer.
		 * there's nothing to do with it, so just drop it here, before
		 * trying to copy over into unallocated memory!
		 */
		if (a->firmware.header.action == FI_ACT_UP)
			return count;

		if (!a->firmware.data) {
			esas2r_debug(
				"write: nonzero offset but no buffer available!");
			return -ENOMEM;
		}

		memcpy(&a->firmware.data[off], buf, count);

		if (length == off + count) {
			do_fm_api(a,
				  (struct esas2r_flash_img *)a->firmware.data);

			/*
			 * Now copy the header result to be picked up by the
			 * next read
			 */
			memcpy(&a->firmware.header,
			       a->firmware.data,
			       sizeof(a->firmware.header));

			a->firmware.state = FW_STATUS_ST;

			esas2r_debug("write completed");

			/*
			 * Since the system has the data buffered, the only way
			 * this can leak is if a root user writes a program
			 * that writes a shorter buffer than it claims, and the
			 * copyin fails.
			 */
			free_fw_buffers(a);
		}
	}

	return count;
}

/* Callback for the completion of a VDA request. */
static void vda_complete_req(struct esas2r_adapter *a,
			     struct esas2r_request *rq)
{
	a->vda_command_done = 1;
	wake_up_interruptible(&a->vda_waiter);
}

/* Scatter/gather callback for VDA requests */
static u32 get_physaddr_vda(struct esas2r_sg_context *sgc, u64 *addr)
{
	struct esas2r_adapter *a = (struct esas2r_adapter *)sgc->adapter;
	int offset = (u8 *)sgc->cur_offset - (u8 *)a->vda_buffer;

	(*addr) = a->ppvda_buffer + offset;
	return VDA_MAX_BUFFER_SIZE - offset;
}

/* Handle a call to read a VDA command. */
int esas2r_read_vda(struct esas2r_adapter *a, char *buf, long off, int count)
{
	if (!a->vda_buffer)
		return -ENOMEM;

	if (off == 0) {
		struct esas2r_request *rq;
		struct atto_ioctl_vda *vi =
			(struct atto_ioctl_vda *)a->vda_buffer;
		struct esas2r_sg_context sgc;
		bool wait_for_completion;

		/*
		 * Presumeably, someone has already written to the vda_buffer,
		 * and now they are reading the node the response, so now we
		 * will actually issue the request to the chip and reply.
		 */

		/* allocate a request */
		rq = esas2r_alloc_request(a);
		if (rq == NULL) {
			esas2r_debug("esas2r_read_vda: out of requestss");
			return -EBUSY;
		}

		rq->comp_cb = vda_complete_req;

		sgc.first_req = rq;
		sgc.adapter = a;
		sgc.cur_offset = a->vda_buffer + VDA_BUFFER_HEADER_SZ;
		sgc.get_phys_addr = (PGETPHYSADDR)get_physaddr_vda;

		a->vda_command_done = 0;

		wait_for_completion =
			esas2r_process_vda_ioctl(a, vi, rq, &sgc);

		if (wait_for_completion) {
			/* now wait around for it to complete. */

			while (!a->vda_command_done)
				wait_event_interruptible(a->vda_waiter,
							 a->vda_command_done);
		}

		esas2r_free_request(a, (struct esas2r_request *)rq);
	}

	if (off > VDA_MAX_BUFFER_SIZE)
		return 0;

	if (count + off > VDA_MAX_BUFFER_SIZE)
		count = VDA_MAX_BUFFER_SIZE - off;

	if (count < 0)
		return 0;

	memcpy(buf, a->vda_buffer + off, count);

	return count;
}

/* Handle a call to write a VDA command. */
int esas2r_write_vda(struct esas2r_adapter *a, const char *buf, long off,
		     int count)
{
	/*
	 * allocate memory for it, if not already done.  once allocated,
	 * we will keep it around until the driver is unloaded.
	 */

	if (!a->vda_buffer) {
		dma_addr_t dma_addr;
		a->vda_buffer = (u8 *)dma_alloc_coherent(&a->pcid->dev,
							 (size_t)
							 VDA_MAX_BUFFER_SIZE,
							 &dma_addr,
							 GFP_KERNEL);

		a->ppvda_buffer = dma_addr;
	}

	if (!a->vda_buffer)
		return -ENOMEM;

	if (off > VDA_MAX_BUFFER_SIZE)
		return 0;

	if (count + off > VDA_MAX_BUFFER_SIZE)
		count = VDA_MAX_BUFFER_SIZE - off;

	if (count < 1)
		return 0;

	memcpy(a->vda_buffer + off, buf, count);

	return count;
}

/* Callback for the completion of an FS_API request.*/
static void fs_api_complete_req(struct esas2r_adapter *a,
				struct esas2r_request *rq)
{
	a->fs_api_command_done = 1;

	wake_up_interruptible(&a->fs_api_waiter);
}

/* Scatter/gather callback for VDA requests */
static u32 get_physaddr_fs_api(struct esas2r_sg_context *sgc, u64 *addr)
{
	struct esas2r_adapter *a = (struct esas2r_adapter *)sgc->adapter;
	struct esas2r_ioctl_fs *fs =
		(struct esas2r_ioctl_fs *)a->fs_api_buffer;
	u32 offset = (u8 *)sgc->cur_offset - (u8 *)fs;

	(*addr) = a->ppfs_api_buffer + offset;

	return a->fs_api_buffer_size - offset;
}

/* Handle a call to read firmware via FS_API. */
int esas2r_read_fs(struct esas2r_adapter *a, char *buf, long off, int count)
{
	if (!a->fs_api_buffer)
		return -ENOMEM;

	if (off == 0) {
		struct esas2r_request *rq;
		struct esas2r_sg_context sgc;
		struct esas2r_ioctl_fs *fs =
			(struct esas2r_ioctl_fs *)a->fs_api_buffer;

		/* If another flash request is already in progress, return. */
		if (down_interruptible(&a->fs_api_semaphore)) {
busy:
			fs->status = ATTO_STS_OUT_OF_RSRC;
			return -EBUSY;
		}

		/*
		 * Presumeably, someone has already written to the
		 * fs_api_buffer, and now they are reading the node the
		 * response, so now we will actually issue the request to the
		 * chip and reply. Allocate a request
		 */

		rq = esas2r_alloc_request(a);
		if (rq == NULL) {
			esas2r_debug("esas2r_read_fs: out of requests");
			up(&a->fs_api_semaphore);
			goto busy;
		}

		rq->comp_cb = fs_api_complete_req;

		/* Set up the SGCONTEXT for to build the s/g table */

		sgc.cur_offset = fs->data;
		sgc.get_phys_addr = (PGETPHYSADDR)get_physaddr_fs_api;

		a->fs_api_command_done = 0;

		if (!esas2r_process_fs_ioctl(a, fs, rq, &sgc)) {
			if (fs->status == ATTO_STS_OUT_OF_RSRC)
				count = -EBUSY;

			goto dont_wait;
		}

		/* Now wait around for it to complete. */

		while (!a->fs_api_command_done)
			wait_event_interruptible(a->fs_api_waiter,
						 a->fs_api_command_done);
		;
dont_wait:
		/* Free the request and keep going */
		up(&a->fs_api_semaphore);
		esas2r_free_request(a, (struct esas2r_request *)rq);

		/* Pick up possible error code from above */
		if (count < 0)
			return count;
	}

	if (off > a->fs_api_buffer_size)
		return 0;

	if (count + off > a->fs_api_buffer_size)
		count = a->fs_api_buffer_size - off;

	if (count < 0)
		return 0;

	memcpy(buf, a->fs_api_buffer + off, count);

	return count;
}

/* Handle a call to write firmware via FS_API. */
int esas2r_write_fs(struct esas2r_adapter *a, const char *buf, long off,
		    int count)
{
	if (off == 0) {
		struct esas2r_ioctl_fs *fs = (struct esas2r_ioctl_fs *)buf;
		u32 length = fs->command.length + offsetof(
			struct esas2r_ioctl_fs,
			data);

		/*
		 * Special case, for BEGIN commands, the length field
		 * is lying to us, so just get enough for the header.
		 */

		if (fs->command.command == ESAS2R_FS_CMD_BEGINW)
			length = offsetof(struct esas2r_ioctl_fs, data);

		/*
		 * Beginning a command.  We assume we'll get at least
		 * enough in the first write so we can look at the
		 * header and see how much we need to alloc.
		 */

		if (count < offsetof(struct esas2r_ioctl_fs, data))
			return -EINVAL;

		/* Allocate a buffer or use the existing buffer. */
		if (a->fs_api_buffer) {
			if (a->fs_api_buffer_size < length) {
				/* Free too-small buffer and get a new one */
				dma_free_coherent(&a->pcid->dev,
						  (size_t)a->fs_api_buffer_size,
						  a->fs_api_buffer,
						  (dma_addr_t)a->ppfs_api_buffer);

				goto re_allocate_buffer;
			}
		} else {
re_allocate_buffer:
			a->fs_api_buffer_size = length;

			a->fs_api_buffer = (u8 *)dma_alloc_coherent(
				&a->pcid->dev,
				(size_t)a->fs_api_buffer_size,
				(dma_addr_t *)&a->ppfs_api_buffer,
				GFP_KERNEL);
		}
	}

	if (!a->fs_api_buffer)
		return -ENOMEM;

	if (off > a->fs_api_buffer_size)
		return 0;

	if (count + off > a->fs_api_buffer_size)
		count = a->fs_api_buffer_size - off;

	if (count < 1)
		return 0;

	memcpy(a->fs_api_buffer + off, buf, count);

	return count;
}
