summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/firmware/create_fw.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-03-08 09:52:49 -0800
committerDan Williams <dan.j.williams@intel.com>2011-07-03 03:55:30 -0700
commitd044af17aacd03a1f4fced1af4b7570d205c8fd9 (patch)
tree1304fd0c7fa979fb229a4bf57771e9e6cde7b37d /drivers/scsi/isci/firmware/create_fw.c
parent9affa289e2f9ef4721e85edbde86466524bfe957 (diff)
downloadop-kernel-dev-d044af17aacd03a1f4fced1af4b7570d205c8fd9.zip
op-kernel-dev-d044af17aacd03a1f4fced1af4b7570d205c8fd9.tar.gz
isci: Add support for probing OROM for OEM params
We need to scan the OROM for signature and grab the OEM parameters. We also need to do the same for EFI. If all fails then we resort to user binary blob, and if that fails then we go to the defaults. Share the format with the create_fw utility so that all possible sources of the parameters are in-sync. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
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 442caac..f8f96d6 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;
}
OpenPOWER on IntegriCloud