Skip to contentSkip to conversation

aic94xx: update BIOS image from user space.

PATCH In review Gilbert Wu 2 participants 2 messages Oct 12, 2007 – Oct 19, 2007 SCSI

lore
Share & tools
lore

Gilbert Wu

author
#0 lore raw

PATCH 1/1 aic94xx: update BIOS image from user space.

1. Create a file "update_bios" in sysfs to allow user to update bios from user space.

2. The BIOS image file can be downloaded from web site "http://www.adaptec.com/en-US/downloads/bios_fw/bios_fw_ver?productId=SAS-48300&dn=Adaptec+Serial+Attached+SCSI+48300" and copy the BIOS image into /lib/firmware folder.

3. The aic994xx will accept "update bios_file" and "verify bios_file" commands to perform update and verify BIOS image .

For example:

Type "echo "update asc483c01.ufi" > /sys/devices/.../update_bios"
to update BIOS image from /lib/firmware/as483c01.ufi file into HBA's flash memory.

Type "echo "verify asc483c01.ufi" > /sys/devices/.../update_bios"
to verify BIOS image between /lib/firmware/asc48c01.ufi file and HBA's flash memory.

4. Type "cat /sys/devices/.../update_bios" to view the status or result of updating BIOS.

drivers/scsi/aic94xx/aic94xx_hwi.h +3 -0
diff -urN a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h
@@ -72,6 +72,7 @@
 	u8     manuf;
 	u8     dev_id;
 	u8     sec_prot;
+	u8     method;
 
 	u32    dir_offs;
 };
@@ -216,6 +217,8 @@
 	struct dma_pool  *scb_pool;
 
 	struct asd_seq_data  seq; /* sequencer related */
+	u32    bios_status;
+	const struct firmware *bios_image;
 };
 
 /* ---------- Common macros ---------- */
drivers/scsi/aic94xx/aic94xx_init.c +183 -0

221 lines not on this page · raw message

drivers/scsi/aic94xx/aic94xx_sds.c +430 -0

439 lines not on this page · raw message

drivers/scsi/aic94xx/aic94xx_sds.h +167 -0

167 lines not on this page · raw message

#1 lore raw
Quoted 18 lines · Gilbert Wu

diff -urN a/drivers/scsi/aic94xx/aic94xx_init.c
b/drivers/scsi/aic94xx/aic94xx_init.c ---
a/drivers/scsi/aic94xx/aic94xx_init.c 2007-10-10 17:13:29.000000000 -0700
+++ b/drivers/scsi/aic94xx/aic94xx_init.c 2007-10-11 19:31:03.000000000
-0700

drivers/scsi/aic94xx/aic94xx_init.c +9 -0
@@ -313,6 +315,180 @@
 }
 static DEVICE_ATTR(pcba_sn, S_IRUGO, asd_show_dev_pcba_sn, NULL);
 
+#define FLASH_CMD_NONE      0x00
+#define FLASH_CMD_UPDATE    0x01
+#define FLASH_CMD_VERIFY    0x02
+
+struct flash_command {
+     u8      command[8];
+     int     code;
+};
+

drivers/scsi/aic94xx/aic94xx_init.c line 336

Quoted 10 lines
drivers/scsi/aic94xx/aic94xx_init.c +10 -0
+static struct flash_command flash_command_table[] =
+{
+     {"verify",      FLASH_CMD_VERIFY},
+     {"update",      FLASH_CMD_UPDATE},
+     {"",            FLASH_CMD_NONE}      /* Last entry should be NULL. */
+};
+
+
+struct error_bios{     char    *reason;     int     err_code;
+};

Make this definition multi-line like the one of flash_command above.

Quoted 16 lines

diff -urN a/drivers/scsi/aic94xx/aic94xx_sds.c
b/drivers/scsi/aic94xx/aic94xx_sds.c ---
a/drivers/scsi/aic94xx/aic94xx_sds.c 2007-10-10 17:13:43.000000000 -0700
+++ b/drivers/scsi/aic94xx/aic94xx_sds.c 2007-10-11 18:38:09.000000000
-0700

drivers/scsi/aic94xx/aic94xx_sds.c +7 -0
@@ -1083,3 +1084,432 @@
 	kfree(flash_dir);
 	return err;
 }
+
+/**
+ * asd_verify_flash_seg - verify data with flash memory
+ * @asd_ha: pointer to the host adapter structure
+ * @src: pointer to the source data to be verified
+ * @dest_offset: offset from flash memory
+ * @bytes_to_verify: total bytes to verify

drivers/scsi/aic94xx/aic94xx_sds.c line 1103

Quoted 10 lines
drivers/scsi/aic94xx/aic94xx_sds.c +10 -0
+ */
+int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
+		void *src, u32 dest_offset, u32 bytes_to_verify)
+{
+	u8 *src_buf;
+	u8 flash_char;
+	int err;
+	u32 nv_offset, reg, i;
+
+

Double newline.

Quoted 22 lines
drivers/scsi/aic94xx/aic94xx_sds.c +22 -0
+	reg = asd_ha->hw_prof.flash.bar;
+	src_buf = NULL;
+
+	err = FLASH_OK;
+	nv_offset = dest_offset;
+	src_buf = (u8 *)src;
+	for (i = 0; i < bytes_to_verify; i++) {
+
+		flash_char = asd_read_reg_byte(asd_ha, reg + nv_offset + i);
+		if (flash_char != src_buf[i]) {
+			err = FAIL_VERIFY;
+			break;
+		}
+	}
+	return err;
+}
+
+/**
+ * asd_write_flash_seg - write data into flash memory
+ * @asd_ha: pointer to the host adapter structure
+ * @src: pointer to the source data to be written
+ * @dest_offset: offset from flash memory

drivers/scsi/aic94xx/aic94xx_sds.c line 1135

Quoted 10 lines
drivers/scsi/aic94xx/aic94xx_sds.c +10 -0
+ * @bytes_to_write: total bytes to write
+ */
+int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
+		void *src, u32 dest_offset, u32 bytes_to_write)
+{
+	u8 *src_buf;
+	u32 nv_offset, reg, i;
+	int err;
+
+

Again.

Quoted 187 lines
drivers/scsi/aic94xx/aic94xx_sds.c +137 -0
+	reg = asd_ha->hw_prof.flash.bar;
+	src_buf = NULL;
+
+	err = asd_check_flash_type(asd_ha);
+	if (err) {
+		ASD_DPRINTK("couldn't find the type of flash. err=%d\n", err);
+		return err;
+	}
+
+	nv_offset = dest_offset;
+	err = asd_erase_nv_sector(asd_ha, nv_offset, bytes_to_write);
+	if (err) {
+		ASD_DPRINTK("Erase failed at offset:0x%x\n",
+			nv_offset);
+		return err;
+	}
+
+	err = asd_reset_flash(asd_ha);
+	if (err) {
+		ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
+		return err;
+	}
+
+	src_buf = (u8 *)src;
+	for (i = 0; i < bytes_to_write; i++) {
+		/* Setup program command sequence */
+		switch (asd_ha->hw_prof.flash.method) {
+
+		case FLASH_METHOD_A:
+		{
+			asd_write_reg_byte(asd_ha,
+					(reg + 0xAAA), 0xAA);
+			asd_write_reg_byte(asd_ha,
+					(reg + 0x555), 0x55);
+			asd_write_reg_byte(asd_ha,
+					(reg + 0xAAA), 0xA0);
+			asd_write_reg_byte(asd_ha,
+					(reg + nv_offset + i),
+					(*(src_buf + i)));
+			break;
+		}
+		case FLASH_METHOD_B:
+		{
+			asd_write_reg_byte(asd_ha,
+					(reg + 0x555), 0xAA);
+			asd_write_reg_byte(asd_ha,
+					(reg + 0x2AA), 0x55);
+			asd_write_reg_byte(asd_ha,
+					(reg + 0x555), 0xA0);
+			asd_write_reg_byte(asd_ha,
+					(reg + nv_offset + i),
+					(*(src_buf + i)));
+			break;
+		}
+		default:
+			break;
+		}
+		if (asd_chk_write_status(asd_ha,
+				(nv_offset + i), 0) != 0) {
+			ASD_DPRINTK("aicx: Write failed at offset:0x%x\n",
+				reg + nv_offset + i);
+			return FAIL_WRITE_FLASH;
+		}
+	}
+
+	err = asd_reset_flash(asd_ha);
+	if (err) {
+		ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
+		return err;
+	}
+	return 0;
+}
+
+int asd_chk_write_status(struct asd_ha_struct *asd_ha,
+	 u32 sector_addr, u8 erase_flag)
+{
+	u32 reg;
+	u32 loop_cnt;
+	u8  nv_data1, nv_data2;
+	u8  toggle_bit1;
+
+	/*
+	 * Read from DQ2 requires sector address
+	 * while it's dont care for DQ6
+	 */
+	reg = asd_ha->hw_prof.flash.bar;
+
+	for (loop_cnt = 0; loop_cnt < 50000; loop_cnt++) {
+		nv_data1 = asd_read_reg_byte(asd_ha, reg);
+		nv_data2 = asd_read_reg_byte(asd_ha, reg);
+
+		toggle_bit1 = ((nv_data1 & FLASH_STATUS_BIT_MASK_DQ6)
+				 ^ (nv_data2 & FLASH_STATUS_BIT_MASK_DQ6));
+
+		if (toggle_bit1 == 0) {
+			return 0;
+		} else {
+			if (nv_data2 & FLASH_STATUS_BIT_MASK_DQ5) {
+				nv_data1 = asd_read_reg_byte(asd_ha,
+								reg);
+				nv_data2 = asd_read_reg_byte(asd_ha,
+								reg);
+				toggle_bit1 =
+				((nv_data1 & FLASH_STATUS_BIT_MASK_DQ6)
+				^ (nv_data2 & FLASH_STATUS_BIT_MASK_DQ6));
+
+				if (toggle_bit1 == 0)
+					return 0;
+			}
+		}
+
+		/*
+		 * ERASE is a sector-by-sector operation and requires
+		 * more time to finish while WRITE is byte-byte-byte
+		 * operation and takes lesser time to finish.
+		 *
+		 * For some strange reason a reduced ERASE delay gives different
+		 * behaviour across different spirit boards. Hence we set
+		 * a optimum balance of 50mus for ERASE which works well
+		 * across all boards.
+		 */
+		if (erase_flag) {
+			udelay(FLASH_STATUS_ERASE_DELAY_COUNT);
+		} else {
+			udelay(FLASH_STATUS_WRITE_DELAY_COUNT);
+		}
+	}
+	return -1;
+}
+
+/**
+ * asd_hwi_erase_nv_sector - Erase the flash memory sectors.
+ * @asd_ha: pointer to the host adapter structure
+ * @flash_addr: pointer to offset from flash memory
+ * @size: total bytes to erase.
+ */
+int asd_erase_nv_sector(struct asd_ha_struct *asd_ha, u32 flash_addr, u32

size) +{

drivers/scsi/aic94xx/aic94xx_sds.c +49 -0
+	u32 reg;
+	u32 sector_addr;
+
+	reg = asd_ha->hw_prof.flash.bar;
+
+	/* sector staring address */
+	sector_addr = flash_addr & FLASH_SECTOR_SIZE_MASK;
+
+	/*
+	 * Erasing an flash sector needs to be done in six consecutive
+	 * write cyles.
+	 */
+	while (sector_addr < flash_addr+size) {
+		switch (asd_ha->hw_prof.flash.method) {
+
+		case FLASH_METHOD_A:
+			asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0xAA);
+			asd_write_reg_byte(asd_ha, (reg + 0x555), 0x55);
+			asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0x80);
+			asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0xAA);
+			asd_write_reg_byte(asd_ha, (reg + 0x555), 0x55);
+			asd_write_reg_byte(asd_ha, (reg + sector_addr), 0x30);
+			break;
+
+		case FLASH_METHOD_B:
+			asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA);
+			asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55);
+			asd_write_reg_byte(asd_ha, (reg + 0x555), 0x80);
+			asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA);
+			asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55);
+			asd_write_reg_byte(asd_ha, (reg + sector_addr), 0x30);
+			break;
+
+		default:
+			break;
+		}
+
+		if (asd_chk_write_status(asd_ha, sector_addr, 1) != 0)
+			return FAIL_ERASE_FLASH;
+
+		sector_addr += FLASH_SECTOR_SIZE;
+	}
+
+	return 0;
+}
+
+int asd_check_flash_type(struct asd_ha_struct *asd_ha)
+{
+	u8 manuf_id;

drivers/scsi/aic94xx/aic94xx_sds.c line 1332

Quoted 10 lines
drivers/scsi/aic94xx/aic94xx_sds.c +10 -0
+	u8 dev_id;
+	u8 sec_prot;
+	u32 inc;
+	u32 reg;
+	int err;
+
+	/* get Flash memory base address */
+	reg = asd_ha->hw_prof.flash.bar;
+
+

Again.

Quoted 263 lines
drivers/scsi/aic94xx/aic94xx_sds.c +183 -0
+	/* Determine flash info */
+	err = asd_reset_flash(asd_ha);
+	if (err) {
+		ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
+		return err;
+	}
+
+	asd_ha->hw_prof.flash.method = FLASH_METHOD_UNKNOWN;
+	asd_ha->hw_prof.flash.manuf = FLASH_MANUF_ID_UNKNOWN;
+	asd_ha->hw_prof.flash.dev_id = FLASH_DEV_ID_UNKNOWN;
+
+	/* Get flash info. This would most likely be AMD Am29LV family flash.
+	 * First try the sequence for word mode.  It is the same as for
+	 * 008B (byte mode only), 160B (word mode) and 800D (word mode).
+	 */
+	inc = asd_ha->hw_prof.flash.wide ? 2 : 1;
+	asd_write_reg_byte(asd_ha, reg + 0xAAA, 0xAA);
+	asd_write_reg_byte(asd_ha, reg + 0x555, 0x55);
+	asd_write_reg_byte(asd_ha, reg + 0xAAA, 0x90);
+	manuf_id = asd_read_reg_byte(asd_ha, reg);
+	dev_id = asd_read_reg_byte(asd_ha, reg + inc);
+	sec_prot = asd_read_reg_byte(asd_ha, reg + inc + inc);
+	/* Get out of autoselect mode. */
+	err = asd_reset_flash(asd_ha);
+	if (err) {
+		ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
+		return err;
+	}
+	ASD_DPRINTK("Flash MethodA manuf_id(0x%x) dev_id(0x%x) "
+		"sec_prot(0x%x)\n", manuf_id, dev_id, sec_prot);
+	err = asd_reset_flash(asd_ha);
+	if (err != 0)
+		return err;
+
+	switch (manuf_id) {
+
+	case FLASH_MANUF_ID_AMD:
+
+		switch (sec_prot) {
+
+		case FLASH_DEV_ID_AM29LV800DT:
+		case FLASH_DEV_ID_AM29LV640MT:
+		case FLASH_DEV_ID_AM29F800B:
+			asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case FLASH_MANUF_ID_ST:
+
+		switch (sec_prot) {
+
+		case FLASH_DEV_ID_STM29W800DT:
+		case FLASH_DEV_ID_STM29LV640:
+			asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case FLASH_MANUF_ID_FUJITSU:
+
+		switch (sec_prot) {
+
+		case FLASH_DEV_ID_MBM29LV800TE:
+		case FLASH_DEV_ID_MBM29DL800TA:
+			asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
+			break;
+
+		}
+		break;
+
+	case FLASH_MANUF_ID_MACRONIX:
+
+		switch (sec_prot) {
+
+		case FLASH_DEV_ID_MX29LV800BT:
+			asd_ha->hw_prof.flash.method = FLASH_METHOD_A;
+			break;
+		}
+		break;
+	}
+
+	if (asd_ha->hw_prof.flash.method == FLASH_METHOD_UNKNOWN) {
+
+		err = asd_reset_flash(asd_ha);
+		if (err) {
+			ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
+			return err;
+		}
+
+		/* Issue Unlock sequence for AM29LV008BT */
+		asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA);
+		asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55);
+		asd_write_reg_byte(asd_ha, (reg + 0x555), 0x90);
+		manuf_id = asd_read_reg_byte(asd_ha, reg);
+		dev_id = asd_read_reg_byte(asd_ha, reg + inc);
+		sec_prot = asd_read_reg_byte(asd_ha, reg + inc + inc);
+
+		ASD_DPRINTK("Flash MethodB manuf_id(0x%x) dev_id(0x%x) sec_prot"
+			"(0x%x)\n", manuf_id, dev_id, sec_prot);
+
+		err = asd_reset_flash(asd_ha);
+		if (err != 0) {
+			ASD_DPRINTK("couldn't reset flash. err=%d\n", err);
+			return err;
+		}
+
+		switch (manuf_id) {
+		case FLASH_MANUF_ID_AMD:
+
+			switch (dev_id) {
+
+			case FLASH_DEV_ID_AM29LV008BT:
+				asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
+				break;
+			default:
+				break;
+			}
+			break;
+
+		case FLASH_MANUF_ID_ST:
+
+			switch (dev_id) {
+
+			case FLASH_DEV_ID_STM29008:
+				asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
+				break;
+			default:
+				break;
+			}
+			break;
+
+		case FLASH_MANUF_ID_FUJITSU:
+
+			switch (dev_id) {
+
+			case FLASH_DEV_ID_MBM29LV008TA:
+				asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
+				break;
+
+			}
+			break;
+
+		case FLASH_MANUF_ID_INTEL:
+
+			switch (dev_id) {
+
+			case FLASH_DEV_ID_I28LV00TAT:
+				asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
+				break;
+
+			}
+			break;
+
+		case FLASH_MANUF_ID_MACRONIX:
+
+			switch (dev_id) {
+
+			case FLASH_DEV_ID_I28LV00TAT:
+				asd_ha->hw_prof.flash.method = FLASH_METHOD_B;
+				break;
+
+			}
+			break;
+
+		default:
+			return FAIL_FIND_FLASH_ID;
+		}
+	}
+
+	if (asd_ha->hw_prof.flash.method == FLASH_METHOD_UNKNOWN)
+	      return FAIL_FIND_FLASH_ID;
+
+
+	asd_ha->hw_prof.flash.manuf = manuf_id;
+	asd_ha->hw_prof.flash.dev_id = dev_id;
+	asd_ha->hw_prof.flash.sec_prot = sec_prot;
+	return 0;
+}

diff -urN a/drivers/scsi/aic94xx/aic94xx_sds.h b/drivers/scsi/aic94xx/aic94xx_sds.h ---
a/drivers/scsi/aic94xx/aic94xx_sds.h 1969-12-31 16:00:00.000000000 -0800
+++ b/drivers/scsi/aic94xx/aic94xx_sds.h 2007-10-11 18:38:06.000000000
-0700 @@ -0,0 +1,167 @@
+/*
+ * Aic94xx SAS/SATA driver hardware interface header file.
+ *
+ * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
+ * Copyright (C) 2005 Gilbert Wu <[email protected]>
+ *
+ * This file is licensed under GPLv2.
+ *
+ * This file is part of the aic94xx driver.
+ *
+ * The aic94xx driver is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * The aic94xx driver 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with the aic94xx driver; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + *
+ */

drivers/scsi/aic94xx/aic94xx_sds.h +50 -0
+#ifndef _AIC94XX_SDS_H_
+#define _AIC94XX_SDS_H_
+
+enum {
+	FLASH_METHOD_UNKNOWN,
+	FLASH_METHOD_A,
+	FLASH_METHOD_B
+};
+
+#define FLASH_MANUF_ID_AMD              0x01
+#define FLASH_MANUF_ID_ST               0x20
+#define FLASH_MANUF_ID_FUJITSU          0x04
+#define FLASH_MANUF_ID_MACRONIX         0xC2
+#define FLASH_MANUF_ID_INTEL            0x89
+#define FLASH_MANUF_ID_UNKNOWN          0xFF
+
+#define FLASH_DEV_ID_AM29LV008BT        0x3E
+#define FLASH_DEV_ID_AM29LV800DT        0xDA
+#define FLASH_DEV_ID_STM29W800DT        0xD7
+#define FLASH_DEV_ID_STM29LV640         0xDE
+#define FLASH_DEV_ID_STM29008           0xEA
+#define FLASH_DEV_ID_MBM29LV800TE       0xDA
+#define FLASH_DEV_ID_MBM29DL800TA       0x4A
+#define FLASH_DEV_ID_MBM29LV008TA       0x3E
+#define FLASH_DEV_ID_AM29LV640MT        0x7E
+#define FLASH_DEV_ID_AM29F800B          0xD6
+#define FLASH_DEV_ID_MX29LV800BT        0xDA
+#define FLASH_DEV_ID_MX29LV008CT        0xDA
+#define FLASH_DEV_ID_I28LV00TAT         0x3E
+#define FLASH_DEV_ID_UNKNOWN            0xFF
+/* status bit mask values */
+#define FLASH_STATUS_BIT_MASK_DQ6       0x40
+#define FLASH_STATUS_BIT_MASK_DQ5       0x20
+#define FLASH_STATUS_BIT_MASK_DQ2       0x04
+
+/* minimum value in micro seconds needed for checking status */
+#define FLASH_STATUS_ERASE_DELAY_COUNT  50
+#define FLASH_STATUS_WRITE_DELAY_COUNT  25
+
+#define FLASH_SECTOR_SIZE               0x010000
+#define FLASH_SECTOR_SIZE_MASK          0xffff0000
+
+
+
+#define FLASH_OK                        0x000000
+#define FAIL_OPEN_BIOS_FILE             0x000100
+#define FAIL_CHECK_PCI_ID               0x000200
+#define FAIL_CHECK_SUM                  0x000300
+#define FAIL_UNKNOWN                    0x000400
+#define FAIL_VERIFY                     0x000500

drivers/scsi/aic94xx/aic94xx_sds.h line 85

Quoted 10 lines
drivers/scsi/aic94xx/aic94xx_sds.h +10 -0
+#define FAIL_RESET_FLASH                0x000600
+#define FAIL_FIND_FLASH_ID              0x000700
+#define FAIL_ERASE_FLASH                0x000800
+#define FAIL_WRITE_FLASH                0x000900
+#define FAIL_FILE_SIZE                  0x000a00
+#define FAIL_PARAMETERS                 0x000b00
+#define FAIL_OUT_MEMORY                 0x000c00
+#define FLASH_IN_PROGRESS               0x001000
+
+

Double newline again.

Quoted 6 lines
drivers/scsi/aic94xx/aic94xx_sds.h +6 -0
+struct controller_id
+{
+    u32 vendor;
+    /* PCI Vendor ID */
+
+    u32 device;

drivers/scsi/aic94xx/aic94xx_sds.h line 101

Quoted 10 lines
drivers/scsi/aic94xx/aic94xx_sds.h +10 -0
+    /* PCI Device ID */
+
+    u32 sub_vendor;
+    /* PCI Subvendor ID */
+
+    u32 sub_device;
+    /* PCI Subdevice ID */
+
+};
+struct image_info

Newline missing here.

Quoted 56 lines
drivers/scsi/aic94xx/aic94xx_sds.h +56 -0
+{
+	u32 ImageId;
+	/*Identifies the image(e.g 0=Footbridge image,1=Drawbridge image)*/
+
+	u32 ImageOffset;
+	/*Offset of the image from the beginning of the file*/
+
+	u32 ImageLength;
+	/*length of the image*/
+
+	u32 ImageChecksum;
+	/*Image checksum*/
+
+	u32 ImageVersion;
+	/*Version of the image, could be build number*/
+};
+
+struct bios_file_header
+{
+	u8 signature[32];
+	/* Signature/Cookie to identify the file*/
+	/* The signature above is only 25 characters long.  */
+
+	u32 checksum;
+	/*Entire file checksum with this field zero*/
+
+	u32 antidote;
+	/*Entire file checksum antidote with this field 0xFFFFFFFF*/
+
+	struct controller_id contrl_id;
+	/*Controller id to identify the controller whose images are*/
+	/*stored in the file.  */
+
+	u32 filelen;
+	/*Length of the entire file*/
+
+	u32 chunk_num;
+	/*The chunk/part number of this DOS file in case the Image */
+	/*is stored in parts in multiple DOS files across floppies*/
+
+	u32 total_chunks;
+	/*Total number of chunks/parts in which the image file is stored*/
+
+	u32 num_images;
+	/*Number of images in the file,e.g Footbridge image, Drawbridge image*/
+
+	u32 build_num;
+	/*Build number of the process that generated this image*/
+
+	struct image_info image_header;
+};
+
+int asd_verify_flash_seg(struct asd_ha_struct *asd_ha,
+		void *src, u32 dest_offset, u32 bytes_to_verify);
+int asd_write_flash_seg(struct asd_ha_struct *asd_ha,
+		void *src, u32 dest_offset, u32 bytes_to_write);

drivers/scsi/aic94xx/aic94xx_sds.h line 167

Quoted 10 lines
drivers/scsi/aic94xx/aic94xx_sds.h +10 -0
+int asd_chk_write_status(struct asd_ha_struct *asd_ha,
+		u32 sector_addr, u8 erase_flag);
+int asd_check_flash_type(struct asd_ha_struct *asd_ha);
+int asd_erase_nv_sector(struct asd_ha_struct *asd_ha,
+		u32 flash_addr, u32 size);
+#endif
+
+
+
+

Trailing newline garbage.