Commit 4711ba10b13891edf228944a9d0a21dfe7fe90f0
1 parent
2e8320f751
Exists in
master
and in
39 other branches
isci: fix oem parameter initialization and mode detection
1/ Since commit 858d4aa7 "isci: Move firmware loading to per PCI device" we have been silently falling back to built-in defaults for the parameter settings by skipping the call to scic_oem_parameters_set(). 2/ The afe parameters from the firmware were not being honored 3/ The latest oem parameter definition flips the mode_type values which are now 0: for APC 1: for MPC. For APC we need to make sure all the phys default to the same address otherwise strict_wide_ports will cause duplicate domains. 4/ Fix up the driver announcement to indicate the source of the parameters. 5/ Fix up the sas addresses to be unique per controller (in the fallback case) Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Showing 9 changed files with 87 additions and 72 deletions Side-by-side Diff
- drivers/scsi/isci/core/sci_base_controller.h
- drivers/scsi/isci/core/scic_sds_controller.c
- drivers/scsi/isci/firmware/create_fw.c
- drivers/scsi/isci/firmware/create_fw.h
- drivers/scsi/isci/host.c
- drivers/scsi/isci/init.c
- drivers/scsi/isci/probe_roms.c
- drivers/scsi/isci/probe_roms.h
- firmware/isci/isci_firmware.bin.ihex
drivers/scsi/isci/core/sci_base_controller.h
drivers/scsi/isci/core/scic_sds_controller.c
... | ... | @@ -595,6 +595,7 @@ |
595 | 595 | */ |
596 | 596 | void scic_sds_controller_afe_initialization(struct scic_sds_controller *scic) |
597 | 597 | { |
598 | + const struct scic_sds_oem_params *oem = &scic->oem_parameters.sds1; | |
598 | 599 | u32 afe_status; |
599 | 600 | u32 phy_id; |
600 | 601 | |
... | ... | @@ -632,6 +633,8 @@ |
632 | 633 | } |
633 | 634 | |
634 | 635 | for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) { |
636 | + const struct sci_phy_oem_params *oem_phy = &oem->phys[phy_id]; | |
637 | + | |
635 | 638 | if (is_b0()) { |
636 | 639 | /* Configure transmitter SSC parameters */ |
637 | 640 | scu_afe_txreg_write(scic, phy_id, afe_tx_ssc_control, 0x00030000); |
638 | 641 | |
639 | 642 | |
640 | 643 | |
... | ... | @@ -691,16 +694,16 @@ |
691 | 694 | } |
692 | 695 | udelay(AFE_REGISTER_WRITE_DELAY); |
693 | 696 | |
694 | - scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control0, 0x000E7C03); | |
697 | + scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control0, oem_phy->afe_tx_amp_control0); | |
695 | 698 | udelay(AFE_REGISTER_WRITE_DELAY); |
696 | 699 | |
697 | - scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control1, 0x000E7C03); | |
700 | + scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control0, oem_phy->afe_tx_amp_control1); | |
698 | 701 | udelay(AFE_REGISTER_WRITE_DELAY); |
699 | 702 | |
700 | - scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control2, 0x000E7C03); | |
703 | + scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control0, oem_phy->afe_tx_amp_control2); | |
701 | 704 | udelay(AFE_REGISTER_WRITE_DELAY); |
702 | 705 | |
703 | - scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control3, 0x000E7C03); | |
706 | + scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control0, oem_phy->afe_tx_amp_control3); | |
704 | 707 | udelay(AFE_REGISTER_WRITE_DELAY); |
705 | 708 | } |
706 | 709 | |
... | ... | @@ -2027,6 +2030,7 @@ |
2027 | 2030 | */ |
2028 | 2031 | static void scic_sds_controller_set_default_config_parameters(struct scic_sds_controller *scic) |
2029 | 2032 | { |
2033 | + struct isci_host *ihost = sci_object_get_association(scic); | |
2030 | 2034 | u16 index; |
2031 | 2035 | |
2032 | 2036 | /* Default to APC mode. */ |
... | ... | @@ -2058,7 +2062,7 @@ |
2058 | 2062 | * is worked around by having the upper 32-bits of SAS address |
2059 | 2063 | * with a value greater then the Vitesse company identifier. |
2060 | 2064 | * Hence, usage of 0x5FCFFFFF. */ |
2061 | - scic->oem_parameters.sds1.phys[index].sas_address.low = 0x00000001; | |
2065 | + scic->oem_parameters.sds1.phys[index].sas_address.low = 0x1 + ihost->id; | |
2062 | 2066 | scic->oem_parameters.sds1.phys[index].sas_address.high = 0x5FCFFFFF; |
2063 | 2067 | } |
2064 | 2068 | |
... | ... | @@ -2604,14 +2608,11 @@ |
2604 | 2608 | struct scic_sds_controller *scic, |
2605 | 2609 | union scic_oem_parameters *scic_parms) |
2606 | 2610 | { |
2607 | - if ( | |
2608 | - (scic->parent.state_machine.current_state_id | |
2609 | - == SCI_BASE_CONTROLLER_STATE_RESET) | |
2610 | - || (scic->parent.state_machine.current_state_id | |
2611 | - == SCI_BASE_CONTROLLER_STATE_INITIALIZING) | |
2612 | - || (scic->parent.state_machine.current_state_id | |
2613 | - == SCI_BASE_CONTROLLER_STATE_INITIALIZED) | |
2614 | - ) { | |
2611 | + u32 state = scic->parent.state_machine.current_state_id; | |
2612 | + | |
2613 | + if (state == SCI_BASE_CONTROLLER_STATE_RESET || | |
2614 | + state == SCI_BASE_CONTROLLER_STATE_INITIALIZING || | |
2615 | + state == SCI_BASE_CONTROLLER_STATE_INITIALIZED) { | |
2615 | 2616 | u16 index; |
2616 | 2617 | u8 combined_phy_mask = 0; |
2617 | 2618 | |
... | ... | @@ -2651,7 +2652,8 @@ |
2651 | 2652 | if (scic_parms->sds1.controller.max_concurrent_dev_spin_up > MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT) |
2652 | 2653 | return SCI_FAILURE_INVALID_PARAMETER_VALUE; |
2653 | 2654 | |
2654 | - memcpy(&scic->oem_parameters, scic_parms, sizeof(*scic_parms)); | |
2655 | + scic->oem_parameters.sds1 = scic_parms->sds1; | |
2656 | + | |
2655 | 2657 | return SCI_SUCCESS; |
2656 | 2658 | } |
2657 | 2659 |
drivers/scsi/isci/firmware/create_fw.c
... | ... | @@ -44,7 +44,7 @@ |
44 | 44 | |
45 | 45 | /* setting OROM signature */ |
46 | 46 | strncpy(isci_orom->hdr.signature, sig, strlen(sig)); |
47 | - isci_orom->hdr.version = 0x10; | |
47 | + isci_orom->hdr.version = version; | |
48 | 48 | isci_orom->hdr.total_block_length = sizeof(struct isci_orom); |
49 | 49 | isci_orom->hdr.hdr_length = sizeof(struct sci_bios_oem_param_block_hdr); |
50 | 50 | isci_orom->hdr.num_elements = num_elements; |
... | ... | @@ -65,6 +65,15 @@ |
65 | 65 | (__u32)(sas_addr[ctrl_idx][phy_idx] >> 32); |
66 | 66 | isci_orom->ctrl[ctrl_idx].phys[phy_idx].sas_address.low = |
67 | 67 | (__u32)(sas_addr[ctrl_idx][phy_idx]); |
68 | + | |
69 | + isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control0 = | |
70 | + afe_tx_amp_control0; | |
71 | + isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control1 = | |
72 | + afe_tx_amp_control1; | |
73 | + isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control2 = | |
74 | + afe_tx_amp_control2; | |
75 | + isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control3 = | |
76 | + afe_tx_amp_control3; | |
68 | 77 | } |
69 | 78 | } |
70 | 79 | } |
drivers/scsi/isci/firmware/create_fw.h
... | ... | @@ -25,14 +25,37 @@ |
25 | 25 | * if there is a port/phy on which you do not wish to override the default |
26 | 26 | * values, use the value assigned to UNINIT_PARAM (255). |
27 | 27 | */ |
28 | + | |
28 | 29 | /* discovery mode type (port auto config mode by default ) */ |
30 | + | |
31 | +/* | |
32 | + * if there is a port/phy on which you do not wish to override the default | |
33 | + * values, use the value "0000000000000000". SAS address of zero's is | |
34 | + * considered invalid and will not be used. | |
35 | + */ | |
29 | 36 | #ifdef MPC |
30 | 37 | static const int mode_type = SCIC_PORT_MANUAL_CONFIGURATION_MODE; |
31 | 38 | static const __u8 phy_mask[2][4] = { {1, 2, 4, 8}, |
32 | 39 | {1, 2, 4, 8} }; |
40 | +static const unsigned long long sas_addr[2][4] = { { 0x5FCFFFFFF0000001ULL, | |
41 | + 0x5FCFFFFFF0000002ULL, | |
42 | + 0x5FCFFFFFF0000003ULL, | |
43 | + 0x5FCFFFFFF0000004ULL }, | |
44 | + { 0x5FCFFFFFF0000005ULL, | |
45 | + 0x5FCFFFFFF0000006ULL, | |
46 | + 0x5FCFFFFFF0000007ULL, | |
47 | + 0x5FCFFFFFF0000008ULL } }; | |
33 | 48 | #else /* APC (default) */ |
34 | 49 | static const int mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE; |
35 | 50 | static const __u8 phy_mask[2][4]; |
51 | +static const unsigned long long sas_addr[2][4] = { { 0x5FCFFFFF00000001ULL, | |
52 | + 0x5FCFFFFF00000001ULL, | |
53 | + 0x5FCFFFFF00000001ULL, | |
54 | + 0x5FCFFFFF00000001ULL }, | |
55 | + { 0x5FCFFFFF00000002ULL, | |
56 | + 0x5FCFFFFF00000002ULL, | |
57 | + 0x5FCFFFFF00000002ULL, | |
58 | + 0x5FCFFFFF00000002ULL } }; | |
36 | 59 | #endif |
37 | 60 | |
38 | 61 | /* Maximum number of concurrent device spin up */ |
39 | 62 | |
... | ... | @@ -47,23 +70,9 @@ |
47 | 70 | static const unsigned int afe_tx_amp_control2 = 0x000e7c03; |
48 | 71 | static const unsigned int afe_tx_amp_control3 = 0x000e7c03; |
49 | 72 | |
50 | -/* | |
51 | - * if there is a port/phy on which you do not wish to override the default | |
52 | - * values, use the value "0000000000000000". SAS address of zero's is | |
53 | - * considered invalid and will not be used. | |
54 | - */ | |
55 | -static const unsigned long long sas_addr[2][4] = { { 0x5FCFFFFFF0000000ULL, | |
56 | - 0x5FCFFFFFF1000000ULL, | |
57 | - 0x5FCFFFFFF2000000ULL, | |
58 | - 0x5FCFFFFFF3000000ULL }, | |
59 | - { 0x5FCFFFFFF4000000ULL, | |
60 | - 0x5FCFFFFFF5000000ULL, | |
61 | - 0x5FCFFFFFF6000000ULL, | |
62 | - 0x5FCFFFFFF7000000ULL } }; | |
63 | - | |
64 | 73 | static const char blob_name[] = "isci_firmware.bin"; |
65 | 74 | static const char sig[] = "ISCUOEMB"; |
66 | -static const unsigned char version = 1; | |
75 | +static const unsigned char version = 0x10; | |
67 | 76 | |
68 | 77 | #endif |
drivers/scsi/isci/host.c
... | ... | @@ -418,7 +418,7 @@ |
418 | 418 | int err = 0, i; |
419 | 419 | enum sci_status status; |
420 | 420 | struct scic_sds_controller *controller; |
421 | - union scic_oem_parameters scic_oem_params; | |
421 | + union scic_oem_parameters oem; | |
422 | 422 | union scic_user_parameters scic_user_params; |
423 | 423 | struct isci_pci_info *pci_info = to_pci_info(isci_host->pdev); |
424 | 424 | |
... | ... | @@ -435,6 +435,7 @@ |
435 | 435 | } |
436 | 436 | |
437 | 437 | isci_host->core_controller = controller; |
438 | + sci_object_set_association(isci_host->core_controller, isci_host); | |
438 | 439 | spin_lock_init(&isci_host->state_lock); |
439 | 440 | spin_lock_init(&isci_host->scic_lock); |
440 | 441 | spin_lock_init(&isci_host->queue_lock); |
... | ... | @@ -457,12 +458,6 @@ |
457 | 458 | isci_host->sas_ha.dev = &isci_host->pdev->dev; |
458 | 459 | isci_host->sas_ha.lldd_ha = isci_host; |
459 | 460 | |
460 | - /*----------- SCIC controller Initialization Stuff ------------------ | |
461 | - * set association host adapter struct in core controller. | |
462 | - */ | |
463 | - sci_object_set_association(isci_host->core_controller, | |
464 | - (void *)isci_host); | |
465 | - | |
466 | 461 | /* |
467 | 462 | * grab initial values stored in the controller object for OEM and USER |
468 | 463 | * parameters |
469 | 464 | |
... | ... | @@ -477,11 +472,11 @@ |
477 | 472 | return -ENODEV; |
478 | 473 | } |
479 | 474 | |
480 | - scic_oem_parameters_get(controller, &scic_oem_params); | |
475 | + scic_oem_parameters_get(controller, &oem); | |
481 | 476 | |
482 | 477 | /* grab any OEM parameters specified in orom */ |
483 | 478 | if (pci_info->orom) { |
484 | - status = isci_parse_oem_parameters(&scic_oem_params, | |
479 | + status = isci_parse_oem_parameters(&oem, | |
485 | 480 | pci_info->orom, |
486 | 481 | isci_host->id); |
487 | 482 | if (status != SCI_SUCCESS) { |
... | ... | @@ -489,15 +484,14 @@ |
489 | 484 | "parsing firmware oem parameters failed\n"); |
490 | 485 | return -EINVAL; |
491 | 486 | } |
492 | - } else { | |
493 | - status = scic_oem_parameters_set(isci_host->core_controller, | |
494 | - &scic_oem_params); | |
495 | - if (status != SCI_SUCCESS) { | |
496 | - dev_warn(&isci_host->pdev->dev, | |
497 | - "%s: scic_oem_parameters_set failed\n", | |
498 | - __func__); | |
499 | - return -ENODEV; | |
500 | - } | |
487 | + } | |
488 | + | |
489 | + status = scic_oem_parameters_set(isci_host->core_controller, &oem); | |
490 | + if (status != SCI_SUCCESS) { | |
491 | + dev_warn(&isci_host->pdev->dev, | |
492 | + "%s: scic_oem_parameters_set failed\n", | |
493 | + __func__); | |
494 | + return -ENODEV; | |
501 | 495 | } |
502 | 496 | |
503 | 497 | tasklet_init(&isci_host->completion_tasklet, |
drivers/scsi/isci/init.c
... | ... | @@ -466,6 +466,7 @@ |
466 | 466 | struct isci_host *isci_host; |
467 | 467 | const struct firmware *fw = NULL; |
468 | 468 | struct isci_orom *orom; |
469 | + char *source = "(platform)"; | |
469 | 470 | |
470 | 471 | check_si_rev(pdev); |
471 | 472 | |
... | ... | @@ -480,6 +481,7 @@ |
480 | 481 | orom = isci_request_oprom(pdev); |
481 | 482 | |
482 | 483 | if (!orom) { |
484 | + source = "(firmware)"; | |
483 | 485 | orom = isci_request_firmware(pdev, fw); |
484 | 486 | if (!orom) { |
485 | 487 | /* TODO convert this to WARN_TAINT_ONCE once the |
486 | 488 | |
... | ... | @@ -496,9 +498,9 @@ |
496 | 498 | |
497 | 499 | if (orom) |
498 | 500 | dev_info(&pdev->dev, |
499 | - "OEM SAS parameters (version: %u.%u) loaded\n", | |
501 | + "OEM SAS parameters (version: %u.%u) loaded %s\n", | |
500 | 502 | (orom->hdr.version & 0xf0) >> 4, |
501 | - (orom->hdr.version & 0xf)); | |
503 | + (orom->hdr.version & 0xf), source); | |
502 | 504 | |
503 | 505 | pci_info->orom = orom; |
504 | 506 |
drivers/scsi/isci/probe_roms.c
... | ... | @@ -138,10 +138,7 @@ |
138 | 138 | scu_index > orom->hdr.num_elements || !oem_params) |
139 | 139 | return -EINVAL; |
140 | 140 | |
141 | - memcpy(oem_params, | |
142 | - &orom->ctrl[scu_index], | |
143 | - sizeof(struct scic_sds_oem_params)); | |
144 | - | |
141 | + oem_params->sds1 = orom->ctrl[scu_index]; | |
145 | 142 | return 0; |
146 | 143 | } |
147 | 144 |
drivers/scsi/isci/probe_roms.h
... | ... | @@ -96,6 +96,10 @@ |
96 | 96 | #define ISCI_ROM_SIG "ISCUOEMB" |
97 | 97 | #define ISCI_ROM_SIG_SIZE 8 |
98 | 98 | |
99 | +#define ISCI_PREBOOT_SOURCE_INIT (0x00) | |
100 | +#define ISCI_PREBOOT_SOURCE_OROM (0x80) | |
101 | +#define ISCI_PREBOOT_SOURCE_EFI (0x81) | |
102 | + | |
99 | 103 | #define ISCI_EFI_VENDOR_GUID \ |
100 | 104 | EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, \ |
101 | 105 | 0x1a, 0x04, 0xc6) |
... | ... | @@ -112,8 +116,8 @@ |
112 | 116 | * being assigned is sufficient to declare manual PORT configuration. |
113 | 117 | */ |
114 | 118 | enum SCIC_PORT_CONFIGURATION_MODE { |
115 | - SCIC_PORT_MANUAL_CONFIGURATION_MODE = 0, | |
116 | - SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE = 1 | |
119 | + SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE = 0, | |
120 | + SCIC_PORT_MANUAL_CONFIGURATION_MODE = 1 | |
117 | 121 | }; |
118 | 122 | |
119 | 123 | struct sci_bios_oem_param_block_hdr { |
firmware/isci/isci_firmware.bin.ihex
1 | 1 | :10000000495343554F454D42E70017100002000089 |
2 | -:10001000000000000000000101000000000000FFDF | |
3 | -:10002000FFCF5F000000F0000000000000000000B3 | |
4 | -:1000300000000000000000FFFFCF5F000000F100A3 | |
5 | -:10004000000000000000000000000000000000FFB1 | |
6 | -:10005000FFCF5F000000F200000000000000000081 | |
7 | -:1000600000000000000000FFFFCF5F000000F30071 | |
8 | -:10007000000000000000000000000000000000017F | |
9 | -:1000800001000000000000FFFFCF5F000000F4004F | |
10 | -:10009000000000000000000000000000000000FF61 | |
11 | -:1000A000FFCF5F000000F50000000000000000002E | |
12 | -:1000B00000000000000000FFFFCF5F000000F6001E | |
13 | -:1000C000000000000000000000000000000000FF31 | |
14 | -:1000D000FFCF5F000000F7000000000000000000FC | |
15 | -:0700E0000000000000000019 | |
2 | +:10001000000000000000000001000000000000FFE0 | |
3 | +:10002000FFCF5F01000000037C0E00037C0E000385 | |
4 | +:100030007C0E00037C0E00FFFFCF5F010000000379 | |
5 | +:100040007C0E00037C0E00037C0E00037C0E00FF80 | |
6 | +:10005000FFCF5F01000000037C0E00037C0E000355 | |
7 | +:100060007C0E00037C0E00FFFFCF5F010000000349 | |
8 | +:100070007C0E00037C0E00037C0E00037C0E00004F | |
9 | +:1000800001000000000000FFFFCF5F02000000033E | |
10 | +:100090007C0E00037C0E00037C0E00037C0E00FF30 | |
11 | +:1000A000FFCF5F02000000037C0E00037C0E000304 | |
12 | +:1000B0007C0E00037C0E00FFFFCF5F0200000003F8 | |
13 | +:1000C0007C0E00037C0E00037C0E00037C0E00FF00 | |
14 | +:1000D000FFCF5F02000000037C0E00037C0E0003D4 | |
15 | +:0700E0007C0E00037C0E0002 | |
16 | 16 | :00000001FF |