diff options
| author | Dan Williams <dan.j.williams@intel.com> | 2011-03-08 12:52:49 -0500 |
|---|---|---|
| committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 06:55:30 -0400 |
| commit | d044af17aacd03a1f4fced1af4b7570d205c8fd9 (patch) | |
| tree | 1304fd0c7fa979fb229a4bf57771e9e6cde7b37d | |
| parent | 9affa289e2f9ef4721e85edbde86466524bfe957 (diff) | |
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>
| -rw-r--r-- | drivers/scsi/isci/Makefile | 2 | ||||
| -rw-r--r-- | drivers/scsi/isci/core/scic_config_parameters.h | 41 | ||||
| -rw-r--r-- | drivers/scsi/isci/core/scic_sds_controller.c | 6 | ||||
| -rw-r--r-- | drivers/scsi/isci/firmware/create_fw.c | 197 | ||||
| -rw-r--r-- | drivers/scsi/isci/firmware/create_fw.h | 67 | ||||
| -rw-r--r-- | drivers/scsi/isci/host.c | 47 | ||||
| -rw-r--r-- | drivers/scsi/isci/host.h | 2 | ||||
| -rw-r--r-- | drivers/scsi/isci/init.c | 191 | ||||
| -rw-r--r-- | drivers/scsi/isci/isci.h | 39 | ||||
| -rw-r--r-- | drivers/scsi/isci/probe_roms.c | 133 | ||||
| -rw-r--r-- | drivers/scsi/isci/probe_roms.h | 130 | ||||
| -rw-r--r-- | firmware/isci/isci_firmware.bin.ihex | 25 |
12 files changed, 453 insertions, 427 deletions
diff --git a/drivers/scsi/isci/Makefile b/drivers/scsi/isci/Makefile index d402d679a31..1252d768c42 100644 --- a/drivers/scsi/isci/Makefile +++ b/drivers/scsi/isci/Makefile | |||
| @@ -9,7 +9,7 @@ EXTRA_CFLAGS += -Idrivers/scsi/isci/core/ -Idrivers/scsi/isci/ | |||
| 9 | obj-$(CONFIG_SCSI_ISCI) += isci.o | 9 | obj-$(CONFIG_SCSI_ISCI) += isci.o |
| 10 | isci-objs := init.o phy.o request.o sata.o \ | 10 | isci-objs := init.o phy.o request.o sata.o \ |
| 11 | remote_device.o port.o timers.o \ | 11 | remote_device.o port.o timers.o \ |
| 12 | host.o task.o events.o \ | 12 | host.o task.o events.o probe_roms.o \ |
| 13 | core/scic_sds_controller.o \ | 13 | core/scic_sds_controller.o \ |
| 14 | core/scic_sds_remote_device.o \ | 14 | core/scic_sds_remote_device.o \ |
| 15 | core/scic_sds_request.o \ | 15 | core/scic_sds_request.o \ |
diff --git a/drivers/scsi/isci/core/scic_config_parameters.h b/drivers/scsi/isci/core/scic_config_parameters.h index 485fefc0888..5e1345daf01 100644 --- a/drivers/scsi/isci/core/scic_config_parameters.h +++ b/drivers/scsi/isci/core/scic_config_parameters.h | |||
| @@ -68,6 +68,7 @@ | |||
| 68 | #include "sci_status.h" | 68 | #include "sci_status.h" |
| 69 | #include "intel_sas.h" | 69 | #include "intel_sas.h" |
| 70 | #include "sci_controller_constants.h" | 70 | #include "sci_controller_constants.h" |
| 71 | #include "probe_roms.h" | ||
| 71 | 72 | ||
| 72 | struct scic_sds_controller; | 73 | struct scic_sds_controller; |
| 73 | 74 | ||
| @@ -224,44 +225,6 @@ union scic_user_parameters { | |||
| 224 | #define SCIC_SDS_PARM_PHY_MASK_MAX 0xF | 225 | #define SCIC_SDS_PARM_PHY_MASK_MAX 0xF |
| 225 | 226 | ||
| 226 | /** | 227 | /** |
| 227 | * struct scic_sds_oem_parameters - This structure delineates the various OEM | ||
| 228 | * parameters that must be set the core user. | ||
| 229 | * | ||
| 230 | * | ||
| 231 | */ | ||
| 232 | struct scic_sds_oem_parameters { | ||
| 233 | struct { | ||
| 234 | /** | ||
| 235 | * This field indicates whether Spread Spectrum Clocking (SSC) | ||
| 236 | * should be enabled or disabled. | ||
| 237 | */ | ||
| 238 | bool do_enable_ssc; | ||
| 239 | |||
| 240 | } controller; | ||
| 241 | |||
| 242 | struct { | ||
| 243 | /** | ||
| 244 | * This field specifies the phys to be contained inside a port. | ||
| 245 | * The bit position in the mask specifies the index of the phy | ||
| 246 | * to be contained in the port. Multiple bits (i.e. phys) | ||
| 247 | * can be contained in a single port. | ||
| 248 | */ | ||
| 249 | u8 phy_mask; | ||
| 250 | |||
| 251 | } ports[SCI_MAX_PORTS]; | ||
| 252 | |||
| 253 | struct sci_phy_oem_params { | ||
| 254 | /** | ||
| 255 | * This field specifies the SAS address to be transmitted on | ||
| 256 | * for this phy index. | ||
| 257 | */ | ||
| 258 | struct sci_sas_address sas_address; | ||
| 259 | |||
| 260 | } phys[SCI_MAX_PHYS]; | ||
| 261 | |||
| 262 | }; | ||
| 263 | |||
| 264 | /** | ||
| 265 | * This structure/union specifies the various different OEM parameter sets | 228 | * This structure/union specifies the various different OEM parameter sets |
| 266 | * available. Each type is specific to a hardware controller version. | 229 | * available. Each type is specific to a hardware controller version. |
| 267 | * | 230 | * |
| @@ -273,7 +236,7 @@ union scic_oem_parameters { | |||
| 273 | * Storage Controller Unit (SCU) Driver Standard (SDS) version | 236 | * Storage Controller Unit (SCU) Driver Standard (SDS) version |
| 274 | * 1. | 237 | * 1. |
| 275 | */ | 238 | */ |
| 276 | struct scic_sds_oem_parameters sds1; | 239 | struct scic_sds_oem_params sds1; |
| 277 | 240 | ||
| 278 | }; | 241 | }; |
| 279 | 242 | ||
diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c index 799a04bc093..e7f3711b4af 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.c +++ b/drivers/scsi/isci/core/scic_sds_controller.c | |||
| @@ -2039,10 +2039,8 @@ static void scic_sds_controller_set_default_config_parameters(struct scic_sds_co | |||
| 2039 | 2039 | ||
| 2040 | /* Initialize all of the phy parameter information. */ | 2040 | /* Initialize all of the phy parameter information. */ |
| 2041 | for (index = 0; index < SCI_MAX_PHYS; index++) { | 2041 | for (index = 0; index < SCI_MAX_PHYS; index++) { |
| 2042 | /* | 2042 | /* Default to 6G (i.e. Gen 3) for now. */ |
| 2043 | * Default to 3G (i.e. Gen 2) for now. User can override if | 2043 | scic->user_parameters.sds1.phys[index].max_speed_generation = 3; |
| 2044 | * they choose. */ | ||
| 2045 | scic->user_parameters.sds1.phys[index].max_speed_generation = 2; | ||
| 2046 | 2044 | ||
| 2047 | /* the frequencies cannot be 0 */ | 2045 | /* the frequencies cannot be 0 */ |
| 2048 | scic->user_parameters.sds1.phys[index].align_insertion_frequency = 0x7f; | 2046 | scic->user_parameters.sds1.phys[index].align_insertion_frequency = 0x7f; |
diff --git a/drivers/scsi/isci/firmware/create_fw.c b/drivers/scsi/isci/firmware/create_fw.c index 442caac9675..f8f96d6eb7d 100644 --- a/drivers/scsi/isci/firmware/create_fw.c +++ b/drivers/scsi/isci/firmware/create_fw.c | |||
| @@ -6,157 +6,30 @@ | |||
| 6 | #include <fcntl.h> | 6 | #include <fcntl.h> |
| 7 | #include <string.h> | 7 | #include <string.h> |
| 8 | #include <errno.h> | 8 | #include <errno.h> |
| 9 | #include <asm/types.h> | ||
| 10 | #include <strings.h> | ||
| 11 | #include <stdint.h> | ||
| 9 | 12 | ||
| 10 | char blob_name[] = "isci_firmware.bin"; | 13 | #include "create_fw.h" |
| 11 | char id[] = "#SCU MAGIC#"; | 14 | #include "../probe_roms.h" |
| 12 | unsigned char version = 1; | 15 | |
| 13 | unsigned char sub_version = 0; | 16 | int write_blob(struct isci_orom *isci_orom) |
| 14 | |||
| 15 | |||
| 16 | /* | ||
| 17 | * For all defined arrays: | ||
| 18 | * elements 0-3 are for SCU0, ports 0-3 | ||
| 19 | * elements 4-7 are for SCU1, ports 0-3 | ||
| 20 | * | ||
| 21 | * valid configurations for one SCU are: | ||
| 22 | * P0 P1 P2 P3 | ||
| 23 | * ---------------- | ||
| 24 | * 0xF,0x0,0x0,0x0 # 1 x4 port | ||
| 25 | * 0x3,0x0,0x4,0x8 # Phys 0 and 1 are a x2 port, phy 2 and phy 3 are each x1 | ||
| 26 | * # ports | ||
| 27 | * 0x1,0x2,0xC,0x0 # Phys 0 and 1 are each x1 ports, phy 2 and phy 3 are a x2 | ||
| 28 | * # port | ||
| 29 | * 0x3,0x0,0xC,0x0 # Phys 0 and 1 are a x2 port, phy 2 and phy 3 are a x2 port | ||
| 30 | * 0x1,0x2,0x4,0x8 # Each phy is a x1 port (this is the default configuration) | ||
| 31 | * | ||
| 32 | * if there is a port/phy on which you do not wish to override the default | ||
| 33 | * values, use the value assigned to UNINIT_PARAM (255). | ||
| 34 | */ | ||
| 35 | unsigned int phy_mask[] = { 1, 2, 4, 8, 1, 2, 4, 8 }; | ||
| 36 | |||
| 37 | |||
| 38 | /* denotes SAS generation. i.e. 3: SAS Gen 3 6G */ | ||
| 39 | unsigned int phy_gen[] = { 3, 3, 3, 3, 3, 3, 3, 3 }; | ||
| 40 | |||
| 41 | /* | ||
| 42 | * if there is a port/phy on which you do not wish to override the default | ||
| 43 | * values, use the value "0000000000000000". SAS address of zero's is | ||
| 44 | * considered invalid and will not be used. | ||
| 45 | */ | ||
| 46 | unsigned long long sas_addr[] = { 0x5FCFFFFFF0000000ULL, | ||
| 47 | 0x5FCFFFFFF1000000ULL, | ||
| 48 | 0x5FCFFFFFF2000000ULL, | ||
| 49 | 0x5FCFFFFFF3000000ULL, | ||
| 50 | 0x5FCFFFFFF4000000ULL, | ||
| 51 | 0x5FCFFFFFF5000000ULL, | ||
| 52 | 0x5FCFFFFFF6000000ULL, | ||
| 53 | 0x5FCFFFFFF7000000ULL }; | ||
| 54 | |||
| 55 | int write_blob(void) | ||
| 56 | { | 17 | { |
| 57 | FILE *fd; | 18 | FILE *fd; |
| 58 | int err; | 19 | int err; |
| 20 | size_t count; | ||
| 59 | 21 | ||
| 60 | fd = fopen(blob_name, "w+"); | 22 | fd = fopen(blob_name, "w+"); |
| 61 | if (!fd) { | 23 | if (!fd) { |
| 62 | perror("Open file for write failed"); | 24 | perror("Open file for write failed"); |
| 25 | fclose(fd); | ||
| 63 | return -EIO; | 26 | return -EIO; |
| 64 | } | 27 | } |
| 65 | 28 | ||
| 66 | /* write id */ | 29 | count = fwrite(isci_orom, sizeof(struct isci_orom), 1, fd); |
| 67 | err = fwrite((void *)id, sizeof(char), strlen(id)+1, fd); | 30 | if (count != 1) { |
| 68 | if (err == 0) { | ||
