create_fw.c 3.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>

char blob_name[] = "isci_firmware.bin";
char id[] = "#SCU MAGIC#";
unsigned char version = 1;
unsigned char sub_version = 0;


/*
 * For all defined arrays:
 * elements 0-3 are for SCU0, ports 0-3
 * elements 4-7 are for SCU1, ports 0-3
 *
 * valid configurations for one SCU are:
 *  P0  P1  P2  P3
 * ----------------
 * 0xF,0x0,0x0,0x0 # 1 x4 port
 * 0x3,0x0,0x4,0x8 # Phys 0 and 1 are a x2 port, phy 2 and phy 3 are each x1
 *                 # ports
 * 0x1,0x2,0xC,0x0 # Phys 0 and 1 are each x1 ports, phy 2 and phy 3 are a x2
 *                 # port
 * 0x3,0x0,0xC,0x0 # Phys 0 and 1 are a x2 port, phy 2 and phy 3 are a x2 port
 * 0x1,0x2,0x4,0x8 # Each phy is a x1 port (this is the default configuration)
 *
 * if there is a port/phy on which you do not wish to override the default
 * values, use the value assigned to UNINIT_PARAM (255).
 */
unsigned int phy_mask[] = { 1, 2, 4, 8, 1, 2, 4, 8 };


/* denotes SAS generation. i.e. 3: SAS Gen 3 6G */
unsigned int phy_gen[] = { 3, 3, 3, 3, 3, 3, 3, 3 };

/*
 * if there is a port/phy on which you do not wish to override the default
 * values, use the value "0000000000000000". SAS address of zero's is
 * considered invalid and will not be used.
 */
unsigned long long sas_addr[] = { 0x5FCFFFFFF0000000ULL,
				  0x5FCFFFFFF1000000ULL,
				  0x5FCFFFFFF2000000ULL,
				  0x5FCFFFFFF3000000ULL,
				  0x5FCFFFFFF4000000ULL,
				  0x5FCFFFFFF5000000ULL,
				  0x5FCFFFFFF6000000ULL,
				  0x5FCFFFFFF7000000ULL };

int write_blob(void)
{
	FILE *fd;
	int err;

	fd = fopen(blob_name, "w+");
	if (!fd) {
		perror("Open file for write failed");
		return -EIO;
	}

	/* write id */
	err = fwrite((void *)id, sizeof(char), strlen(id)+1, fd);
	if (err == 0) {
		perror("write id failed");
		return err;
	}

	/* write version */
	err = fwrite((void *)&version, sizeof(version), 1, fd);
	if (err == 0) {
		perror("write version failed");
		return err;
	}

	/* write sub version */
	err = fwrite((void *)&sub_version, sizeof(sub_version), 1, fd);
	if (err == 0) {
		perror("write subversion failed");
		return err;
	}

	/* write phy mask header */
	err = fputc(0x1, fd);
	if (err == EOF) {
		perror("write phy mask header failed");
		return -EIO;
	}

	/* write size */
	err = fputc(8, fd);
	if (err == EOF) {
		perror("write phy mask size failed");
		return -EIO;
	}

	/* write phy masks */
	err = fwrite((void *)phy_mask, 1, sizeof(phy_mask), fd);
	if (err == 0) {
		perror("write phy_mask failed");
		return err;
	}

	/* write phy gen header */
	err = fputc(0x2, fd);
	if (err == EOF) {
		perror("write phy gen header failed");
		return -EIO;
	}

	/* write size */
	err = fputc(8, fd);
	if (err == EOF) {
		perror("write phy gen size failed");
		return -EIO;
	}

	/* write phy_gen */
	err = fwrite((void *)phy_gen,
		     1,
		     sizeof(phy_gen),
		     fd);
	if (err == 0) {
		perror("write phy_gen failed");
		return err;
	}

	/* write phy gen header */
	err = fputc(0x3, fd);
	if (err == EOF) {
		perror("write sas addr header failed");
		return -EIO;
	}

	/* write size */
	err = fputc(8, fd);
	if (err == EOF) {
		perror("write sas addr size failed");
		return -EIO;
	}

	/* write sas_addr */
	err = fwrite((void *)sas_addr,
		     1,
		     sizeof(sas_addr),
		     fd);
	if (err == 0) {
		perror("write sas_addr failed");
		return err;
	}

	/* write end header */
	err = fputc(0xff, fd);
	if (err == EOF) {
		perror("write end header failed");
		return -EIO;
	}

	fclose(fd);

	return 0;
}

int main(void)
{
	int err;

	err = write_blob();
	if (err < 0)
		return err;

	return 0;
}