diff options
Diffstat (limited to 'drivers/scsi/isci/firmware/create_fw.c')
-rw-r--r-- | drivers/scsi/isci/firmware/create_fw.c | 197 |
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; } |