summaryrefslogtreecommitdiff
path: root/drivers/scsi/isci/firmware/create_fw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/isci/firmware/create_fw.c')
-rw-r--r--drivers/scsi/isci/firmware/create_fw.c197
1 files changed, 55 insertions, 142 deletions
diff --git a/drivers/scsi/isci/firmware/create_fw.c b/drivers/scsi/isci/firmware/create_fw.c
index 442caac9675d..f8f96d6eb7df 100644
--- a/drivers/scsi/isci/firmware/create_fw.c
+++ b/drivers/scsi/isci/firmware/create_fw.c
@@ -6,157 +6,30 @@
#include <fcntl.h>
#include <string.h>
#include <errno.h>
+#include <asm/types.h>
+#include <strings.h>
+#include <stdint.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)
+#include "create_fw.h"
+#include "../probe_roms.h"
+
+int write_blob(struct isci_orom *isci_orom)
{
FILE *fd;
int err;
+ size_t count;
fd = fopen(blob_name, "w+");
if (!fd) {
perror("Open file for write failed");
+ fclose(fd);
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");
+ count = fwrite(isci_orom, sizeof(struct isci_orom), 1, fd);
+ if (count != 1) {
+ perror("Write data failed");
+ fclose(fd);
return -EIO;
}
@@ -165,13 +38,53 @@ int write_blob(void)
return 0;
}
+void set_binary_values(struct isci_orom *isci_orom)
+{
+ int ctrl_idx, phy_idx, port_idx;
+
+ /* setting OROM signature */
+ strncpy(isci_orom->hdr.signature, sig, strlen(sig));
+ isci_orom->hdr.version = 0x10;
+ isci_orom->hdr.total_block_length = sizeof(struct isci_orom);
+ isci_orom->hdr.hdr_length = sizeof(struct sci_bios_oem_param_block_hdr);
+ isci_orom->hdr.num_elements = num_elements;
+
+ for (ctrl_idx = 0; ctrl_idx < 2; ctrl_idx++) {
+ isci_orom->ctrl[ctrl_idx].controller.mode_type = mode_type;
+ isci_orom->ctrl[ctrl_idx].controller.max_concurrent_dev_spin_up =
+ max_num_concurrent_dev_spin_up;
+ isci_orom->ctrl[ctrl_idx].controller.do_enable_ssc =
+ enable_ssc;
+
+ for (port_idx = 0; port_idx < 4; port_idx++)
+ isci_orom->ctrl[ctrl_idx].ports[port_idx].phy_mask =
+ phy_mask[ctrl_idx][port_idx];
+
+ for (phy_idx = 0; phy_idx < 4; phy_idx++) {
+ isci_orom->ctrl[ctrl_idx].phys[phy_idx].sas_address.high =
+ (__u32)(sas_addr[ctrl_idx][phy_idx] >> 32);
+ isci_orom->ctrl[ctrl_idx].phys[phy_idx].sas_address.low =
+ (__u32)(sas_addr[ctrl_idx][phy_idx]);
+ }
+ }
+}
+
int main(void)
{
int err;
+ struct isci_orom *isci_orom;
+
+ isci_orom = malloc(sizeof(struct isci_orom));
+ memset(isci_orom, 0, sizeof(struct isci_orom));
- err = write_blob();
- if (err < 0)
+ set_binary_values(isci_orom);
+
+ err = write_blob(isci_orom);
+ if (err < 0) {
+ free(isci_orom);
return err;
+ }
+ free(isci_orom);
return 0;
}