
/*
 *  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 (test_bit(AF_DEGRADED_MODE, &a->flags))
		/* 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);
	clear_bit(AF_FLASH_LOCK, &a->flags);
	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 (test_bit(AF_DEGRADED_MODE, &a->flags))
				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)  validate each component header. check the img_type and
 *                  length fields
 *              5)  validate 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 (test_bit(AF_DEGRADED_MODE, &a->flags)) {
		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);

	if (test_bit(AF_CHPRST_PENDING, &a->flags) ||
	    test_bit(AF_DISC_PENDING, &a->flags))
		timeout = 40000;
	else
		timeout = 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 (test_bit(AF2_SERIAL_FLASH, &a->flags2))
			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)
			set_bit(AF_NVR_VALID, &a->flags);
		else
			clear_bit(AF_NVR_VALID, &a->flags);

		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 (test_bit(AF_DEGRADED_MODE, &a->flags))
		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 (test_bit(AF_LEGACY_SGE_MODE, &a->flags)) {

		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 {
		set_bit(AF_NVR_VALID, &a->flags);
		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);

	clear_bit(AF_NVR_VALID, &a->flags);
	*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 (test_and_set_bit(AF_FLASH_LOCK, &a->flags)) {
		/* 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 (test_bit(AF_DEGRADED_MODE, &a->flags))
		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;
}
