
/*
 *  linux/drivers/scsi/esas2r/esas2r_flash.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"

/* local macro defs */
#define esas2r_nvramcalc_cksum(n)     \
	(esas2r_calc_byte_cksum((u8 *)(n), sizeof(struct esas2r_sas_nvram), \
				SASNVR_CKSUM_SEED))
#define esas2r_nvramcalc_xor_cksum(n)  \
	(esas2r_calc_byte_xor_cksum((u8 *)(n), \
				    sizeof(struct esas2r_sas_nvram), 0))

#define ESAS2R_FS_DRVR_VER 2

static struct esas2r_sas_nvram default_sas_nvram = {
	{ 'E',	'S',  'A',  'S'			     }, /* signature          */
	SASNVR_VERSION,                                 /* version            */
	0,                                              /* checksum           */
	31,                                             /* max_lun_for_target */
	SASNVR_PCILAT_MAX,                              /* pci_latency        */
	SASNVR1_BOOT_DRVR,                              /* options1           */
	SASNVR2_HEARTBEAT   | SASNVR2_SINGLE_BUS        /* options2           */
	| SASNVR2_SW_MUX_CTRL,
	SASNVR_COAL_DIS,                                /* int_coalescing     */
	SASNVR_CMDTHR_NONE,                             /* cmd_throttle       */
	3,                                              /* dev_wait_time      */
	1,                                              /* dev_wait_count     */
	0,                                              /* spin_up_delay      */
	0,                                              /* ssp_align_rate     */
	{ 0x50, 0x01, 0x08, 0x60,                       /* sas_addr           */
	  0x00, 0x00, 0x00, 0x00 },
	{ SASNVR_SPEED_AUTO },                          /* phy_speed          */
	{ SASNVR_MUX_DISABLED },                        /* SAS multiplexing   */
	{ 0 },                                          /* phy_flags          */
	SASNVR_SORT_SAS_ADDR,                           /* sort_type          */
	3,                                              /* dpm_reqcmd_lmt     */
	3,                                              /* dpm_stndby_time    */
	0,                                              /* dpm_active_time    */
	{ 0 },                                          /* phy_target_id      */
	SASNVR_VSMH_DISABLED,                           /* virt_ses_mode      */
	SASNVR_RWM_DEFAULT,                             /* read_write_mode    */
	0,                                              /* link down timeout  */
	{ 0 }                                           /* reserved           */
};

static u8 cmd_to_fls_func[] = {
	0xFF,
	VDA_FLASH_READ,
	VDA_FLASH_BEGINW,
	VDA_FLASH_WRITE,
	VDA_FLASH_COMMIT,
	VDA_FLASH_CANCEL
};

static u8 esas2r_calc_byte_xor_cksum(u8 *addr, u32 len, u8 seed)
{
	u32 cksum = seed;
	u8 *p = (u8 *)&cksum;

	while (len) {
		if (((uintptr_t)addr & 3) == 0)
			break;

		cksum = cksum ^ *addr;
		addr++;
		len--;
	}
	while (len >= sizeof(u32)) {
		cksum = cksum ^ *(u32 *)addr;
		addr += 4;
		len -= 4;
	}
	while (len--) {
		cksum = cksum ^ *addr;
		addr++;
	}
	return p[0] ^ p[1] ^ p[2] ^ p[3];
}

static u8 esas2r_calc_byte_cksum(void *addr, u32 len, u8 seed)
{
	u8 *p = (u8 *)addr;
	u8 cksum = seed;

	while (len--)
		cksum = cksum + p[len];
	return cksum;
}

/* Interrupt callback to process FM API write requests. */
static void esas2r_fmapi_callback(struct esas2r_adapter *a,
				  struct esas2r_request *rq)
{
	struct atto_vda_flash_req *vrq = &rq->vrq->flash;
	struct esas2r_flash_context *fc =
		(struct esas2r_flash_context *)rq->interrupt_cx;

	if (rq->req_stat == RS_SUCCESS) {
		/* Last request was successful.  See what to do now. */
		switch (vrq->sub_func) {
		case VDA_FLASH_BEGINW:
			if (fc->sgc.cur_offset == NULL)
				goto commit;

			vrq->sub_func = VDA_FLASH_WRITE;
			rq->req_stat = RS_PENDING;
			break;

		case VDA_FLASH_WRITE:
commit:
			vrq->sub_func = VDA_FLASH_COMMIT;
			rq->req_stat = RS_PENDING;
			rq->interrupt_cb = fc->interrupt_cb;
			break;

		default:
			break;
		}
	}

	if (rq->req_stat != RS_PENDING)
		/*
		 * All done. call the real callback to complete the FM API
		 * request.  We should only get here if a BEGINW or WRITE
		 * operation failed.
		 */
		(*fc->interrupt_cb)(a, rq);
}

/*
 * Build a flash request based on the flash context.  The request status
 * is filled in on an error.
 */
static void build_flash_msg(struct esas2r_adapter *a,
			    struct esas2r_request *rq)
{
	struct esas2r_flash_context *fc =
		(struct esas2r_flash_context *)rq->interrupt_cx;
	struct esas2r_sg_context *sgc = &fc->sgc;
	u8 cksum = 0;

	/* calculate the checksum */
	if (fc->func == VDA_FLASH_BEGINW) {
		if (sgc->cur_offset)
			cksum = esas2r_calc_byte_xor_cksum(sgc->cur_offset,
							   sgc->length,
							   0);
		rq->interrupt_cb = esas2r_fmapi_callback;
	} else {
		rq->interrupt_cb = fc->interrupt_cb;
	}
	esas2r_build_flash_req(a,
			       rq,
			       fc->func,
			       cksum,
			       fc->flsh_addr,
			       sgc->length);

	esas2r_rq_free_sg_lists(rq, a);

	/*
	 * remember the length we asked for.  we have to keep track of
	 * the current amount done so we know how much to compare when
	 * doing the verification phase.
	 */
	fc->curr_len = fc->sgc.length;

	if (sgc->cur_offset) {
		/* setup the S/G context to build the S/G table  */
		esas2r_sgc_init(sgc, a, rq, &rq->vrq->flash.data.sge[0]);

		if (!esas2r_build_sg_list(a, rq, sgc)) {
			rq->req_stat = RS_BUSY;
			return;
		}
	} else {
		fc->sgc.length = 0;
	}

	/* update the flsh_addr to the next one to write to  */
	fc->flsh_addr += fc->curr_len;
}

/* determine the method to process the flash request */
static bool load_image(struct esas2r_adapter *a, struct esas2r_request *rq)
{
	/*
	 * assume we have more to do.  if we return with the status set to
	 * RS_PENDING, FM API tasks will continue.
	 */
	rq->req_stat = RS_PENDING;
	if (a->flags & AF_DEGRADED_MODE)
		/* not suppported for now */;
	else
		build_flash_msg(a, rq);

	return rq->req_stat == RS_PENDING;
}

/*  boot image fixer uppers called before downloading the image. */
static void fix_bios(struct esas2r_adapter *a, struct esas2r_flash_img *fi)
{
	struct esas2r_component_header *ch = &fi->cmp_hdr[CH_IT_BIOS];
	struct esas2r_pc_image *pi;
	struct esas2r_boot_header *bh;

	pi = (struct esas2r_pc_image *)((u8 *)fi + ch->image_offset);
	bh =
		(struct esas2r_boot_header *)((u8 *)pi +
					      le16_to_cpu(pi->header_offset));
	bh->device_id = cpu_to_le16(a->pcid->device);

	/* Recalculate the checksum in the PNP header if there  */
	if (pi->pnp_offset) {
		u8 *pnp_header_bytes =
			((u8 *)pi + le16_to_cpu(pi->pnp_offset));

		/* Identifier - dword that starts at byte 10 */
		*((u32 *)&pnp_header_bytes[10]) =
			cpu_to_le32(MAKEDWORD(a->pcid->subsystem_vendor,
					      a->pcid->subsystem_device));

		/* Checksum - byte 9 */
		pnp_header_bytes[9] -= esas2r_calc_byte_cksum(pnp_header_bytes,
							      32, 0);
	}

	/* Recalculate the checksum needed by the PC */
	pi->checksum = pi->checksum -
		       esas2r_calc_byte_cksum((u8 *)pi, ch->length, 0);
}

static void fix_efi(struct esas2r_adapter *a, struct esas2r_flash_img *fi)
{
	struct esas2r_component_header *ch = &fi->cmp_hdr[CH_IT_EFI];
	u32 len = ch->length;
	u32 offset = ch->image_offset;
	struct esas2r_efi_image *ei;
	struct esas2r_boot_header *bh;

	while (len) {
		u32 thislen;

		ei = (struct esas2r_efi_image *)((u8 *)fi + offset);
		bh = (struct esas2r_boot_header *)((u8 *)ei +
						   le16_to_cpu(
							   ei->header_offset));
		bh->device_id = cpu_to_le16(a->pcid->device);
		thislen = (u32)le16_to_cpu(bh->image_length) * 512;

		if (thislen > len)
			break;

		len -= thislen;
		offset += thislen;
	}
}

/* Complete a FM API request with the specified status. */
static bool complete_fmapi_req(struct esas2r_adapter *a,
			       struct esas2r_request *rq, u8 fi_stat)
{
	struct esas2r_flash_context *fc =
		(struct esas2r_flash_context *)rq->interrupt_cx;
	struct esas2r_flash_img *fi = fc->fi;

	fi->status = fi_stat;
	fi->driver_error = rq->req_stat;
	rq->interrupt_cb = NULL;
	rq->req_stat = RS_SUCCESS;

	if (fi_stat != FI_STAT_IMG_VER)
		memset(fc->scratch, 0, FM_BUF_SZ);

	esas2r_enable_heartbeat(a);
	esas2r_lock_clear_flags(&a->flags, AF_FLASH_LOCK);
	return false;
}

/* Process each phase of the flash download process. */
static void fw_download_proc(struct esas2r_adapter *a,
			     struct esas2r_request *rq)
{
	struct esas2r_flash_context *fc =
		(struct esas2r_flash_context *)rq->interrupt_cx;
	struct esas2r_flash_img *fi = fc->fi;
	struct esas2r_component_header *ch;
	u32 len;
	u8 *p, *q;

	/* If the previous operation failed, just return. */
	if (rq->req_stat != RS_SUCCESS)
		goto error;

	/*
	 * If an upload just completed and the compare length is non-zero,
	 * then we just read back part of the image we just wrote.  verify the
	 * section and continue reading until the entire image is verified.
	 */
	if (fc->func == VDA_FLASH_READ
	    && fc->cmp_len) {
		ch = &fi->cmp_hdr[fc->comp_typ];

		p = fc->scratch;
		q = (u8 *)fi                    /* start of the whole gob     */
		    + ch->image_offset          /* start of the current image */
		    + ch->length                /* end of the current image   */
		    - fc->cmp_len;              /* where we are now           */

		/*
		 * NOTE - curr_len is the exact count of bytes for the read
		 *        even when the end is read and its not a full buffer
		 */
		for (len = fc->curr_len; len; len--)
			if (*p++ != *q++)
				goto error;

		fc->cmp_len -= fc->curr_len; /* # left to compare    */

		/* Update fc and determine the length for the next upload */
		if (fc->cmp_len > FM_BUF_SZ)
			fc->sgc.length = FM_BUF_SZ;
		else
			fc->sgc.length = fc->cmp_len;

		fc->sgc.cur_offset = fc->sgc_offset +
				     ((u8 *)fc->scratch - (u8 *)fi);
	}

	/*
	 * This code uses a 'while' statement since the next component may
	 * have a length = zero.  This can happen since some components are
	 * not required.  At the end of this 'while' we set up the length
	 * for the next request and therefore sgc.length can be = 0.
	 */
	while (fc->sgc.length == 0) {
		ch = &fi->cmp_hdr[fc->comp_typ];

		switch (fc->task) {
		case FMTSK_ERASE_BOOT:
			/* the BIOS image is written next */
			ch = &fi->cmp_hdr[CH_IT_BIOS];
			if (ch->length == 0)
				goto no_bios;

			fc->task = FMTSK_WRTBIOS;
			fc->func = VDA_FLASH_BEGINW;
			fc->comp_typ = CH_IT_BIOS;
			fc->flsh_addr = FLS_OFFSET_BOOT;
			fc->sgc.length = ch->length;
			fc->sgc.cur_offset = fc->sgc_offset +
					     ch->image_offset;
			break;

		case FMTSK_WRTBIOS:
			/*
			 * The BIOS image has been written - read it and
			 * verify it
			 */
			fc->task = FMTSK_READBIOS;
			fc->func = VDA_FLASH_READ;
			fc->flsh_addr = FLS_OFFSET_BOOT;
			fc->cmp_len = ch->length;
			fc->sgc.length = FM_BUF_SZ;
			fc->sgc.cur_offset = fc->sgc_offset
					     + ((u8 *)fc->scratch -
						(u8 *)fi);
			break;

		case FMTSK_READBIOS:
no_bios:
			/*
			 * Mark the component header status for the image
			 * completed
			 */
			ch->status = CH_STAT_SUCCESS;

			/* The MAC image is written next */
			ch = &fi->cmp_hdr[CH_IT_MAC];
			if (ch->length == 0)
				goto no_mac;

			fc->task = FMTSK_WRTMAC;
			fc->func = VDA_FLASH_BEGINW;
			fc->comp_typ = CH_IT_MAC;
			fc->flsh_addr = FLS_OFFSET_BOOT
					+ fi->cmp_hdr[CH_IT_BIOS].length;
			fc->sgc.length = ch->length;
			fc->sgc.cur_offset = fc->sgc_offset +
					     ch->image_offset;
			break;

		case FMTSK_WRTMAC:
			/* The MAC image has been written - read and verify */
			fc->task = FMTSK_READMAC;
			fc->func = VDA_FLASH_READ;
			fc->flsh_addr -= ch->length;
			fc->cmp_len = ch->length;
			fc->sgc.length = FM_BUF_SZ;
			fc->sgc.cur_offset = fc->sgc_offset
					     + ((u8 *)fc->scratch -
						(u8 *)fi);
			break;

		case FMTSK_READMAC:
no_mac:
			/*
			 * Mark the component header status for the image
			 * completed
			 */
			ch->status = CH_STAT_SUCCESS;

			/* The EFI image is written next */
			ch = &fi->cmp_hdr[CH_IT_EFI];
			if (ch->length == 0)
				goto no_efi;

			fc->task = FMTSK_WRTEFI;
			fc->func = VDA_FLASH_BEGINW;
			fc->comp_typ = CH_IT_EFI;
			fc->flsh_addr = FLS_OFFSET_BOOT
					+ fi->cmp_hdr[CH_IT_BIOS].length
					+ fi->cmp_hdr[CH_IT_MAC].length;
			fc->sgc.length = ch->length;
			fc->sgc.cur_offset = fc->sgc_offset +
					     ch->image_offset;
			break;

		case FMTSK_WRTEFI:
			/* The EFI image has been written - read and verify */
			fc->task = FMTSK_READEFI;
			fc->func = VDA_FLASH_READ;
			fc->flsh_addr -= ch->length;
			fc->cmp_len = ch->length;
			fc->sgc.length = FM_BUF_SZ;
			fc->sgc.cur_offset = fc->sgc_offset
					     + ((u8 *)fc->scratch -
						(u8 *)fi);
			break;

		case FMTSK_READEFI:
no_efi:
			/*
			 * Mark the component header status for the image
			 * completed
			 */
			ch->status = CH_STAT_SUCCESS;

			/* The CFG image is written next */
			ch = &fi->cmp_hdr[CH_IT_CFG];

			if (ch->length == 0)
				goto no_cfg;
			fc->task = FMTSK_WRTCFG;
			fc->func = VDA_FLASH_BEGINW;
			fc->comp_typ = CH_IT_CFG;
			fc->flsh_addr = FLS_OFFSET_CPYR - ch->length;
			fc->sgc.length = ch->length;
			fc->sgc.cur_offset = fc->sgc_offset +
					     ch->image_offset;
			break;

		case FMTSK_WRTCFG:
			/* The CFG image has been written - read and verify */
			fc->task = FMTSK_READCFG;
			fc->func = VDA_FLASH_READ;
			fc->flsh_addr = FLS_OFFSET_CPYR - ch->length;
			fc->cmp_len = ch->length;
			fc->sgc.length = FM_BUF_SZ;
			fc->sgc.cur_offset = fc->sgc_offset
					     + ((u8 *)fc->scratch -
						(u8 *)fi);
			break;

		case FMTSK_READCFG:
no_cfg:
			/*
			 * Mark the component header status for the image
			 * completed
			 */
			ch->status = CH_STAT_SUCCESS;

			/*
			 * The download is complete.  If in degraded mode,
			 * attempt a chip reset.
			 */
			if (a->flags & AF_DEGRADED_MODE)
				esas2r_local_reset_adapter(a);

			a->flash_ver = fi->cmp_hdr[CH_IT_BIOS].version;
			esas2r_print_flash_rev(a);

			/* Update the type of boot image on the card */
			memcpy(a->image_type, fi->rel_version,
			       sizeof(fi->rel_version));
			complete_fmapi_req(a, rq, FI_STAT_SUCCESS);
			return;
		}

		/* If verifying, don't try reading more than what's there */
		if (fc->func == VDA_FLASH_READ
		    && fc->sgc.length > fc->cmp_len)
			fc->sgc.length = fc->cmp_len;
	}

	/* Build the request to perform the next action */
	if (!load_image(a, rq)) {
error:
		if (fc->comp_typ < fi->num_comps) {
			ch = &fi->cmp_hdr[fc->comp_typ];
			ch->status = CH_STAT_FAILED;
		}

		complete_fmapi_req(a, rq, FI_STAT_FAILED);
	}
}

/* Determine the flash image adaptyp for this adapter */
static u8 get_fi_adap_type(struct esas2r_adapter *a)
{
	u8 type;

	/* use the device ID to get the correct adap_typ for this HBA */
	switch (a->pcid->device) {
	case ATTO_DID_INTEL_IOP348:
		type = FI_AT_SUN_LAKE;
		break;

	case ATTO_DID_MV_88RC9580:
	case ATTO_DID_MV_88RC9580TS:
	case ATTO_DID_MV_88RC9580TSE:
	case ATTO_DID_MV_88RC9580TL:
		type = FI_AT_MV_9580;
		break;

	default:
		type = FI_AT_UNKNWN;
		break;
	}

	return type;
}

/* Size of config + copyright + flash_ver images, 0 for failure. */
static u32 chk_cfg(u8 *cfg, u32 length, u32 *flash_ver)
{
	u16 *pw = (u16 *)cfg - 1;
	u32 sz = 0;
	u32 len = length;

	if (len == 0)
		len = FM_BUF_SZ;

	if (flash_ver)
		*flash_ver = 0;

	while (true) {
		u16 type;
		u16 size;

		type = le16_to_cpu(*pw--);
		size = le16_to_cpu(*pw--);

		if (type != FBT_CPYR
		    && type != FBT_SETUP
		    && type != FBT_FLASH_VER)
			break;

		if (type == FBT_FLASH_VER
		    && flash_ver)
			*flash_ver = le32_to_cpu(*(u32 *)(pw - 1));

		sz += size + (2 * sizeof(u16));
		pw -= size / sizeof(u16);

		if (sz > len - (2 * sizeof(u16)))
			break;
	}

	/* See if we are comparing the size to the specified length */
	if (length && sz != length)
		return 0;

	return sz;
}

/* Verify that the boot image is valid */
static u8 chk_boot(u8 *boot_img, u32 length)
{
	struct esas2r_boot_image *bi = (struct esas2r_boot_image *)boot_img;
	u16 hdroffset = le16_to_cpu(bi->header_offset);
	struct esas2r_boot_header *bh;

	if (bi->signature != le16_to_cpu(0xaa55)
	    || (long)hdroffset >
	    (long)(65536L - sizeof(struct esas2r_boot_header))
	    || (hdroffset & 3)
	    || (hdroffset < sizeof(struct esas2r_boot_image))
	    || ((u32)hdroffset + sizeof(struct esas2r_boot_header) > length))
		return 0xff;

	bh = (struct esas2r_boot_header *)((char *)bi + hdroffset);

	if (bh->signature[0] != 'P'
	    || bh->signature[1] != 'C'
	    || bh->signature[2] != 'I'
	    || bh->signature[3] != 'R'
	    || le16_to_cpu(bh->struct_length) <
	    (u16)sizeof(struct esas2r_boot_header)
	    || bh->class_code[2] != 0x01
	    || bh->class_code[1] != 0x04
	    || bh->class_code[0] != 0x00
	    || (bh->code_type != CODE_TYPE_PC
		&& bh->code_type != CODE_TYPE_OPEN
		&& bh->code_type != CODE_TYPE_EFI))
		return 0xff;

	return bh->code_type;
}

/* The sum of all the WORDS of the image */
static u16 calc_fi_checksum(struct esas2r_flash_context *fc)
{
	struct esas2r_flash_img *fi = fc->fi;
	u16 cksum;
	u32 len;
	u16 *pw;

	for (len = (fi->length - fc->fi_hdr_len) / 2,
	     pw = (u16 *)((u8 *)fi + fc->fi_hdr_len),
	     cksum = 0;
	     len;
	     len--, pw++)
		cksum = cksum + le16_to_cpu(*pw);

	return cksum;
}

/*
 * Verify the flash image structure.  The following verifications will
 * be performed:
 *              1)  verify the fi_version is correct
 *              2)  verify the checksum of the entire image.
 *              3)  validate the adap_typ, action and length fields.
 *              4)  valdiate each component header. check the img_type and
 *                  length fields
 *              5)  valdiate each component image.  validate signatures and
 *                  local checksums
 */
static bool verify_fi(struct esas2r_adapter *a,
		      struct esas2r_flash_context *fc)
{
	struct esas2r_flash_img *fi = fc->fi;
	u8 type;
	bool imgerr;
	u16 i;
	u32 len;
	struct esas2r_component_header *ch;

	/* Verify the length - length must even since we do a word checksum */
	len = fi->length;

	if ((len & 1)
	    || len < fc->fi_hdr_len) {
		fi->status = FI_STAT_LENGTH;
		return false;
	}

	/* Get adapter type and verify type in flash image */
	type = get_fi_adap_type(a);
	if ((type == FI_AT_UNKNWN) || (fi->adap_typ != type)) {
		fi->status = FI_STAT_ADAPTYP;
		return false;
	}

	/*
	 * Loop through each component and verify the img_type and length
	 * fields.  Keep a running count of the sizes sooze we can verify total
	 * size to additive size.
	 */
	imgerr = false;

	for (i = 0, len = 0, ch = fi->cmp_hdr;
	     i < fi->num_comps;
	     i++, ch++) {
		bool cmperr = false;

		/*
		 * Verify that the component header has the same index as the
		 * image type.  The headers must be ordered correctly
		 */
		if (i != ch->img_type) {
			imgerr = true;
			ch->status = CH_STAT_INVALID;
			continue;
		}

		switch (ch->img_type) {
		case CH_IT_BIOS:
			type = CODE_TYPE_PC;
			break;

		case CH_IT_MAC:
			type = CODE_TYPE_OPEN;
			break;

		case CH_IT_EFI:
			type = CODE_TYPE_EFI;
			break;
		}

		switch (ch->img_type) {
		case CH_IT_FW:
		case CH_IT_NVR:
			break;

		case CH_IT_BIOS:
		case CH_IT_MAC:
		case CH_IT_EFI:
			if (ch->length & 0x1ff)
				cmperr = true;

			/* Test if component image is present  */
			if (ch->length == 0)
				break;

			/* Image is present - verify the image */
			if (chk_boot((u8 *)fi + ch->image_offset, ch->length)
			    != type)
				cmperr = true;

			break;

		case CH_IT_CFG:

			/* Test if component image is present */
			if (ch->length == 0) {
				cmperr = true;
				break;
			}

			/* Image is present - verify the image */
			if (!chk_cfg((u8 *)fi + ch->image_offset + ch->length,
				     ch->length, NULL))
				cmperr = true;

			break;

		default:

			fi->status = FI_STAT_UNKNOWN;
			return false;
		}

		if (cmperr) {
			imgerr = true;
			ch->status = CH_STAT_INVALID;
		} else {
			ch->status = CH_STAT_PENDING;
			len += ch->length;
		}
	}

	if (imgerr) {
		fi->status = FI_STAT_MISSING;
		return false;
	}

	/* Compare fi->length to the sum of ch->length fields */
	if (len != fi->length - fc->fi_hdr_len) {
		fi->status = FI_STAT_LENGTH;
		return false;
	}

	/* Compute the checksum - it should come out zero */
	if (fi->checksum != calc_fi_checksum(fc)) {
		fi->status = FI_STAT_CHKSUM;
		return false;
	}

	return true;
}

/* Fill in the FS IOCTL response data from a completed request. */
static void esas2r_complete_fs_ioctl(struct esas2r_adapter *a,
				     struct esas2r_request *rq)
{
	struct esas2r_ioctl_fs *fs =
		(struct esas2r_ioctl_fs *)rq->interrupt_cx;

	if (rq->vrq->flash.sub_func == VDA_FLASH_COMMIT)
		esas2r_enable_heartbeat(a);

	fs->driver_error = rq->req_stat;

	if (fs->driver_error == RS_SUCCESS)
		fs->status = ATTO_STS_SUCCESS;
	else
		fs->status = ATTO_STS_FAILED;
}

/* Prepare an FS IOCTL request to be sent to the firmware. */
bool esas2r_process_fs_ioctl(struct esas2r_adapter *a,
			     struct esas2r_ioctl_fs *fs,
			     struct esas2r_request *rq,
			     struct esas2r_sg_context *sgc)
{
	u8 cmdcnt = (u8)ARRAY_SIZE(cmd_to_fls_func);
	struct esas2r_ioctlfs_command *fsc = &fs->command;
	u8 func = 0;
	u32 datalen;

	fs->status = ATTO_STS_FAILED;
	fs->driver_error = RS_PENDING;

	if (fs->version > ESAS2R_FS_VER) {
		fs->status = ATTO_STS_INV_VERSION;
		return false;
	}

	if (fsc->command >= cmdcnt) {
		fs->status = ATTO_STS_INV_FUNC;
		return false;
	}

	func = cmd_to_fls_func[fsc->command];
	if (func == 0xFF) {
		fs->status = ATTO_STS_INV_FUNC;
		return false;
	}

	if (fsc->command != ESAS2R_FS_CMD_CANCEL) {
		if ((a->pcid->device != ATTO_DID_MV_88RC9580
		     || fs->adap_type != ESAS2R_FS_AT_ESASRAID2)
		    && (a->pcid->device != ATTO_DID_MV_88RC9580TS
			|| fs->adap_type != ESAS2R_FS_AT_TSSASRAID2)
		    && (a->pcid->device != ATTO_DID_MV_88RC9580TSE
			|| fs->adap_type != ESAS2R_FS_AT_TSSASRAID2E)
		    && (a->pcid->device != ATTO_DID_MV_88RC9580TL
			|| fs->adap_type != ESAS2R_FS_AT_TLSASHBA)) {
			fs->status = ATTO_STS_INV_ADAPTER;
			return false;
		}

		if (fs->driver_ver > ESAS2R_FS_DRVR_VER) {
			fs->status = ATTO_STS_INV_DRVR_VER;
			return false;
		}
	}

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

	rq->interrupt_cb = esas2r_complete_fs_ioctl;
	rq->interrupt_cx = fs;
	datalen = le32_to_cpu(fsc->length);
	esas2r_build_flash_req(a,
			       rq,
			       func,
			       fsc->checksum,
			       le32_to_cpu(fsc->flash_addr),
			       datalen);

	if (func == VDA_FLASH_WRITE
	    || func == VDA_FLASH_READ) {
		if (datalen == 0) {
			fs->status = ATTO_STS_INV_FUNC;
			return false;
		}

		esas2r_sgc_init(sgc, a, rq, rq->vrq->flash.data.sge);
		sgc->length = datalen;

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

	if (func == VDA_FLASH_COMMIT)
		esas2r_disable_heartbeat(a);

	esas2r_start_request(a, rq);

	return true;
}

static bool esas2r_flash_access(struct esas2r_adapter *a, u32 function)
{
	u32 starttime;
	u32 timeout;
	u32 intstat;
	u32 doorbell;

	/* Disable chip interrupts awhile */
	if (function == DRBL_FLASH_REQ)
		esas2r_disable_chip_interrupts(a);

	/* Issue the request to the firmware */
	esas2r_write_register_dword(a, MU_DOORBELL_IN, function);

	/* Now wait for the firmware to process it */
	starttime = jiffies_to_msecs(jiffies);
	timeout = a->flags &
		  (AF_CHPRST_PENDING | AF_DISC_PENDING) ? 40000 : 5000;

	while (true) {
		intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT);

		if (intstat & MU_INTSTAT_DRBL) {
			/* Got a doorbell interrupt.  Check for the function */
			doorbell =
				esas2r_read_register_dword(a, MU_DOORBELL_OUT);
			esas2r_write_register_dword(a, MU_DOORBELL_OUT,
						    doorbell);
			if (doorbell & function)
				break;
		}

		schedule_timeout_interruptible(msecs_to_jiffies(100));

		if ((jiffies_to_msecs(jiffies) - starttime) > timeout) {
			/*
			 * Iimeout.  If we were requesting flash access,
			 * indicate we are done so the firmware knows we gave
			 * up.  If this was a REQ, we also need to re-enable
			 * chip interrupts.
			 */
			if (function == DRBL_FLASH_REQ) {
				esas2r_hdebug("flash access timeout");
				esas2r_write_register_dword(a, MU_DOORBELL_IN,
							    DRBL_FLASH_DONE);
				esas2r_enable_chip_interrupts(a);
			} else {
				esas2r_hdebug("flash release timeout");
			}

			return false;
		}
	}

	/* if we're done, re-enable chip interrupts */
	if (function == DRBL_FLASH_DONE)
		esas2r_enable_chip_interrupts(a);

	return true;
}

#define WINDOW_SIZE ((signed int)MW_DATA_WINDOW_SIZE)

bool esas2r_read_flash_block(struct esas2r_adapter *a,
			     void *to,
			     u32 from,
			     u32 size)
{
	u8 *end = (u8 *)to;

	/* Try to acquire access to the flash */
	if (!esas2r_flash_access(a, DRBL_FLASH_REQ))
		return false;

	while (size) {
		u32 len;
		u32 offset;
		u32 iatvr;

		if (a->flags2 & AF2_SERIAL_FLASH)
			iatvr = MW_DATA_ADDR_SER_FLASH + (from & -WINDOW_SIZE);
		else
			iatvr = MW_DATA_ADDR_PAR_FLASH + (from & -WINDOW_SIZE);

		esas2r_map_data_window(a, iatvr);
		offset = from & (WINDOW_SIZE - 1);
		len = size;

		if (len > WINDOW_SIZE - offset)
			len = WINDOW_SIZE - offset;

		from += len;
		size -= len;

		while (len--) {
			*end++ = esas2r_read_data_byte(a, offset);
			offset++;
		}
	}

	/* Release flash access */
	esas2r_flash_access(a, DRBL_FLASH_DONE);
	return true;
}

bool esas2r_read_flash_rev(struct esas2r_adapter *a)
{
	u8 bytes[256];
	u16 *pw;
	u16 *pwstart;
	u16 type;
	u16 size;
	u32 sz;

	sz = sizeof(bytes);
	pw = (u16 *)(bytes + sz);
	pwstart = (u16 *)bytes + 2;

	if (!esas2r_read_flash_block(a, bytes, FLS_OFFSET_CPYR - sz, sz))
		goto invalid_rev;

	while (pw >= pwstart) {
		pw--;
		type = le16_to_cpu(*pw);
		pw--;
		size = le16_to_cpu(*pw);
		pw -= size / 2;

		if (type == FBT_CPYR
		    || type == FBT_SETUP
		    || pw < pwstart)
			continue;

		if (type == FBT_FLASH_VER)
			a->flash_ver = le32_to_cpu(*(u32 *)pw);

		break;
	}

invalid_rev:
	return esas2r_print_flash_rev(a);
}

bool esas2r_print_flash_rev(struct esas2r_adapter *a)
{
	u16 year = LOWORD(a->flash_ver);
	u8 day = LOBYTE(HIWORD(a->flash_ver));
	u8 month = HIBYTE(HIWORD(a->flash_ver));

	if (day == 0
	    || month == 0
	    || day > 31
	    || month > 12
	    || year < 2006
	    || year > 9999) {
		strcpy(a->flash_rev, "not found");
		a->flash_ver = 0;
		return false;
	}

	sprintf(a->flash_rev, "%02d/%02d/%04d", month, day, year);
	esas2r_hdebug("flash version: %s", a->flash_rev);
	return true;
}

/*
 * Find the type of boot image type that is currently in the flash.
 * The chip only has a 64 KB PCI-e expansion ROM
 * size so only one image can be flashed at a time.
 */
bool esas2r_read_image_type(struct esas2r_adapter *a)
{
	u8 bytes[256];
	struct esas2r_boot_image *bi;
	struct esas2r_boot_header *bh;
	u32 sz;
	u32 len;
	u32 offset;

	/* Start at the base of the boot images and look for a valid image */
	sz = sizeof(bytes);
	len = FLS_LENGTH_BOOT;
	offset = 0;

	while (true) {
		if (!esas2r_read_flash_block(a, bytes, FLS_OFFSET_BOOT +
					     offset,
					     sz))
			goto invalid_rev;

		bi = (struct esas2r_boot_image *)bytes;
		bh = (struct esas2r_boot_header *)((u8 *)bi +
						   le16_to_cpu(
							   bi->header_offset));
		if (bi->signature != cpu_to_le16(0xAA55))
			goto invalid_rev;

		if (bh->code_type == CODE_TYPE_PC) {
			strcpy(a->image_type, "BIOS");

			return true;
		} else if (bh->code_type == CODE_TYPE_EFI) {
			struct esas2r_efi_image *ei;

			/*
			 * So we have an EFI image.  There are several types
			 * so see which architecture we have.
			 */
			ei = (struct esas2r_efi_image *)bytes;

			switch (le16_to_cpu(ei->machine_type)) {
			case EFI_MACHINE_IA32:
				strcpy(a->image_type, "EFI 32-bit");
				return true;

			case EFI_MACHINE_IA64:
				strcpy(a->image_type, "EFI itanium");
				return true;

			case EFI_MACHINE_X64:
				strcpy(a->image_type, "EFI 64-bit");
				return true;

			case EFI_MACHINE_EBC:
				strcpy(a->image_type, "EFI EBC");
				return true;

			default:
				goto invalid_rev;
			}
		} else {
			u32 thislen;

			/* jump to the next image */
			thislen = (u32)le16_to_cpu(bh->image_length) * 512;
			if (thislen == 0
			    || thislen + offset > len
			    || bh->indicator == INDICATOR_LAST)
				break;

			offset += thislen;
		}
	}

invalid_rev:
	strcpy(a->image_type, "no boot images");
	return false;
}

/*
 *  Read and validate current NVRAM parameters by accessing
 *  physical NVRAM directly.  if currently stored parameters are
 *  invalid, use the defaults.
 */
bool esas2r_nvram_read_direct(struct esas2r_adapter *a)
{
	bool result;

	if (down_interruptible(&a->nvram_semaphore))
		return false;

	if (!esas2r_read_flash_block(a, a->nvram, FLS_OFFSET_NVR,
				     sizeof(struct esas2r_sas_nvram))) {
		esas2r_hdebug("NVRAM read failed, using defaults");
		return false;
	}

	result = esas2r_nvram_validate(a);

	up(&a->nvram_semaphore);

	return result;
}

/* Interrupt callback to process NVRAM completions. */
static void esas2r_nvram_callback(struct esas2r_adapter *a,
				  struct esas2r_request *rq)
{
	struct atto_vda_flash_req *vrq = &rq->vrq->flash;

	if (rq->req_stat == RS_SUCCESS) {
		/* last request was successful.  see what to do now. */

		switch (vrq->sub_func) {
		case VDA_FLASH_BEGINW:
			vrq->sub_func = VDA_FLASH_WRITE;
			rq->req_stat = RS_PENDING;
			break;

		case VDA_FLASH_WRITE:
			vrq->sub_func = VDA_FLASH_COMMIT;
			rq->req_stat = RS_PENDING;
			break;

		case VDA_FLASH_READ:
			esas2r_nvram_validate(a);
			break;

		case VDA_FLASH_COMMIT:
		default:
			break;
		}
	}

	if (rq->req_stat != RS_PENDING) {
		/* update the NVRAM state */
		if (rq->req_stat == RS_SUCCESS)
			esas2r_lock_set_flags(&a->flags, AF_NVR_VALID);
		else
			esas2r_lock_clear_flags(&a->flags, AF_NVR_VALID);

		esas2r_enable_heartbeat(a);

		up(&a->nvram_semaphore);
	}
}

/*
 * Write the contents of nvram to the adapter's physical NVRAM.
 * The cached copy of the NVRAM is also updated.
 */
bool esas2r_nvram_write(struct esas2r_adapter *a, struct esas2r_request *rq,
			struct esas2r_sas_nvram *nvram)
{
	struct esas2r_sas_nvram *n = nvram;
	u8 sas_address_bytes[8];
	u32 *sas_address_dwords = (u32 *)&sas_address_bytes[0];
	struct atto_vda_flash_req *vrq = &rq->vrq->flash;

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

	if (down_interruptible(&a->nvram_semaphore))
		return false;

	if (n == NULL)
		n = a->nvram;

	/* check the validity of the settings */
	if (n->version > SASNVR_VERSION) {
		up(&a->nvram_semaphore);
		return false;
	}

	memcpy(&sas_address_bytes[0], n->sas_addr, 8);

	if (sas_address_bytes[0] != 0x50
	    || sas_address_bytes[1] != 0x01
	    || sas_address_bytes[2] != 0x08
	    || (sas_address_bytes[3] & 0xF0) != 0x60
	    || ((sas_address_bytes[3] & 0x0F) | sas_address_dwords[1]) == 0) {
		up(&a->nvram_semaphore);
		return false;
	}

	if (n->spin_up_delay > SASNVR_SPINUP_MAX)
		n->spin_up_delay = SASNVR_SPINUP_MAX;

	n->version = SASNVR_VERSION;
	n->checksum = n->checksum - esas2r_nvramcalc_cksum(n);
	memcpy(a->nvram, n, sizeof(struct esas2r_sas_nvram));

	/* write the NVRAM */
	n = a->nvram;
	esas2r_disable_heartbeat(a);

	esas2r_build_flash_req(a,
			       rq,
			       VDA_FLASH_BEGINW,
			       esas2r_nvramcalc_xor_cksum(n),
			       FLS_OFFSET_NVR,
			       sizeof(struct esas2r_sas_nvram));

	if (a->flags & AF_LEGACY_SGE_MODE) {

		vrq->data.sge[0].length =
			cpu_to_le32(SGE_LAST |
				    sizeof(struct esas2r_sas_nvram));
		vrq->data.sge[0].address = cpu_to_le64(
			a->uncached_phys + (u64)((u8 *)n - a->uncached));
	} else {
		vrq->data.prde[0].ctl_len =
			cpu_to_le32(sizeof(struct esas2r_sas_nvram));
		vrq->data.prde[0].address = cpu_to_le64(
			a->uncached_phys
			+ (u64)((u8 *)n - a->uncached));
	}
	rq->interrupt_cb = esas2r_nvram_callback;
	esas2r_start_request(a, rq);
	return true;
}

/* Validate the cached NVRAM.  if the NVRAM is invalid, load the defaults. */
bool esas2r_nvram_validate(struct esas2r_adapter *a)
{
	struct esas2r_sas_nvram *n = a->nvram;
	bool rslt = false;

	if (n->signature[0] != 'E'
	    || n->signature[1] != 'S'
	    || n->signature[2] != 'A'
	    || n->signature[3] != 'S') {
		esas2r_hdebug("invalid NVRAM signature");
	} else if (esas2r_nvramcalc_cksum(n)) {
		esas2r_hdebug("invalid NVRAM checksum");
	} else if (n->version > SASNVR_VERSION) {
		esas2r_hdebug("invalid NVRAM version");
	} else {
		esas2r_lock_set_flags(&a->flags, AF_NVR_VALID);
		rslt = true;
	}

	if (rslt == false) {
		esas2r_hdebug("using defaults");
		esas2r_nvram_set_defaults(a);
	}

	return rslt;
}

/*
 * Set the cached NVRAM to defaults.  note that this function sets the default
 * NVRAM when it has been determined that the physical NVRAM is invalid.
 * In this case, the SAS address is fabricated.
 */
void esas2r_nvram_set_defaults(struct esas2r_adapter *a)
{
	struct esas2r_sas_nvram *n = a->nvram;
	u32 time = jiffies_to_msecs(jiffies);

	esas2r_lock_clear_flags(&a->flags, AF_NVR_VALID);
	*n = default_sas_nvram;
	n->sas_addr[3] |= 0x0F;
	n->sas_addr[4] = HIBYTE(LOWORD(time));
	n->sas_addr[5] = LOBYTE(LOWORD(time));
	n->sas_addr[6] = a->pcid->bus->number;
	n->sas_addr[7] = a->pcid->devfn;
}

void esas2r_nvram_get_defaults(struct esas2r_adapter *a,
			       struct esas2r_sas_nvram *nvram)
{
	u8 sas_addr[8];

	/*
	 * in case we are copying the defaults into the adapter, copy the SAS
	 * address out first.
	 */
	memcpy(&sas_addr[0], a->nvram->sas_addr, 8);
	*nvram = default_sas_nvram;
	memcpy(&nvram->sas_addr[0], &sas_addr[0], 8);
}

bool esas2r_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi,
		   struct esas2r_request *rq, struct esas2r_sg_context *sgc)
{
	struct esas2r_flash_context *fc = &a->flash_context;
	u8 j;
	struct esas2r_component_header *ch;

	if (esas2r_lock_set_flags(&a->flags, AF_FLASH_LOCK) & AF_FLASH_LOCK) {
		/* flag was already set */
		fi->status = FI_STAT_BUSY;
		return false;
	}

	memcpy(&fc->sgc, sgc, sizeof(struct esas2r_sg_context));
	sgc = &fc->sgc;
	fc->fi = fi;
	fc->sgc_offset = sgc->cur_offset;
	rq->req_stat = RS_SUCCESS;
	rq->interrupt_cx = fc;

	switch (fi->fi_version) {
	case FI_VERSION_1:
		fc->scratch = ((struct esas2r_flash_img *)fi)->scratch_buf;
		fc->num_comps = FI_NUM_COMPS_V1;
		fc->fi_hdr_len = sizeof(struct esas2r_flash_img);
		break;

	default:
		return complete_fmapi_req(a, rq, FI_STAT_IMG_VER);
	}

	if (a->flags & AF_DEGRADED_MODE)
		return complete_fmapi_req(a, rq, FI_STAT_DEGRADED);

	switch (fi->action) {
	case FI_ACT_DOWN: /* Download the components */
		/* Verify the format of the flash image */
		if (!verify_fi(a, fc))
			return complete_fmapi_req(a, rq, fi->status);

		/* Adjust the BIOS fields that are dependent on the HBA */
		ch = &fi->cmp_hdr[CH_IT_BIOS];

		if (ch->length)
			fix_bios(a, fi);

		/* Adjust the EFI fields that are dependent on the HBA */
		ch = &fi->cmp_hdr[CH_IT_EFI];

		if (ch->length)
			fix_efi(a, fi);

		/*
		 * Since the image was just modified, compute the checksum on
		 * the modified image.  First update the CRC for the composite
		 * expansion ROM image.
		 */
		fi->checksum = calc_fi_checksum(fc);

		/* Disable the heartbeat */
		esas2r_disable_heartbeat(a);

		/* Now start up the download sequence */
		fc->task = FMTSK_ERASE_BOOT;
		fc->func = VDA_FLASH_BEGINW;
		fc->comp_typ = CH_IT_CFG;
		fc->flsh_addr = FLS_OFFSET_BOOT;
		fc->sgc.length = FLS_LENGTH_BOOT;
		fc->sgc.cur_offset = NULL;

		/* Setup the callback address */
		fc->interrupt_cb = fw_download_proc;
		break;

	case FI_ACT_UPSZ: /* Get upload sizes */
		fi->adap_typ = get_fi_adap_type(a);
		fi->flags = 0;
		fi->num_comps = fc->num_comps;
		fi->length = fc->fi_hdr_len;

		/* Report the type of boot image in the rel_version string */
		memcpy(fi->rel_version, a->image_type,
		       sizeof(fi->rel_version));

		/* Build the component headers */
		for (j = 0, ch = fi->cmp_hdr;
		     j < fi->num_comps;
		     j++, ch++) {
			ch->img_type = j;
			ch->status = CH_STAT_PENDING;
			ch->length = 0;
			ch->version = 0xffffffff;
			ch->image_offset = 0;
			ch->pad[0] = 0;
			ch->pad[1] = 0;
		}

		if (a->flash_ver != 0) {
			fi->cmp_hdr[CH_IT_BIOS].version =
				fi->cmp_hdr[CH_IT_MAC].version =
					fi->cmp_hdr[CH_IT_EFI].version =
						fi->cmp_hdr[CH_IT_CFG].version
							= a->flash_ver;

			fi->cmp_hdr[CH_IT_BIOS].status =
				fi->cmp_hdr[CH_IT_MAC].status =
					fi->cmp_hdr[CH_IT_EFI].status =
						fi->cmp_hdr[CH_IT_CFG].status =
							CH_STAT_SUCCESS;

			return complete_fmapi_req(a, rq, FI_STAT_SUCCESS);
		}

	/* fall through */

	case FI_ACT_UP: /* Upload the components */
	default:
		return complete_fmapi_req(a, rq, FI_STAT_INVALID);
	}

	/*
	 * If we make it here, fc has been setup to do the first task.  Call
	 * load_image to format the request, start it, and get out.  The
	 * interrupt code will call the callback when the first message is
	 * complete.
	 */
	if (!load_image(a, rq))
		return complete_fmapi_req(a, rq, FI_STAT_FAILED);

	esas2r_start_request(a, rq);

	return true;
}
