diff options
author | Deepak Ukey <deepak.ukey@microchip.com> | 2018-09-11 04:48:02 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-09-11 21:13:08 -0400 |
commit | cd135754d837bc4b15a9211d30bfc23f2247afb9 (patch) | |
tree | 9443a9c827b0e13c9d79d0730927ab78f1c74305 | |
parent | 0b1b1d88614fcd90c65d27dbd14490dcbf2c9b5f (diff) |
scsi: pm80xx: Fix for phy enable/disable functionality
Added proper mask for phy id in mpi_phy_stop_resp().
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Acked-by: Jack Wang <jinpu.wang@profitbricks.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/pm8001/pm8001_defs.h | 8 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.c | 3 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.h | 4 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_init.c | 3 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_sas.c | 28 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm80xx_hwi.c | 14 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm80xx_hwi.h | 6 |
7 files changed, 49 insertions, 17 deletions
diff --git a/drivers/scsi/pm8001/pm8001_defs.h b/drivers/scsi/pm8001/pm8001_defs.h index 199527dbaaa1..48e0624ecc68 100644 --- a/drivers/scsi/pm8001/pm8001_defs.h +++ b/drivers/scsi/pm8001/pm8001_defs.h | |||
@@ -132,4 +132,12 @@ enum pm8001_hba_info_flags { | |||
132 | PM8001F_RUN_TIME = (1U << 1), | 132 | PM8001F_RUN_TIME = (1U << 1), |
133 | }; | 133 | }; |
134 | 134 | ||
135 | /** | ||
136 | * Phy Status | ||
137 | */ | ||
138 | #define PHY_LINK_DISABLE 0x00 | ||
139 | #define PHY_LINK_DOWN 0x01 | ||
140 | #define PHY_STATE_LINK_UP_SPCV 0x2 | ||
141 | #define PHY_STATE_LINK_UP_SPC 0x1 | ||
142 | |||
135 | #endif | 143 | #endif |
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 4dd6cad330e8..a14bf50a76d7 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c | |||
@@ -3810,7 +3810,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) | |||
3810 | " status = %x\n", status)); | 3810 | " status = %x\n", status)); |
3811 | if (status == 0) { | 3811 | if (status == 0) { |
3812 | phy->phy_state = 1; | 3812 | phy->phy_state = 1; |
3813 | if (pm8001_ha->flags == PM8001F_RUN_TIME) | 3813 | if (pm8001_ha->flags == PM8001F_RUN_TIME && |
3814 | phy->enable_completion != NULL) | ||
3814 | complete(phy->enable_completion); | 3815 | complete(phy->enable_completion); |
3815 | } | 3816 | } |
3816 | break; | 3817 | break; |
diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h index e4867e690c84..6d91e2446542 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.h +++ b/drivers/scsi/pm8001/pm8001_hwi.h | |||
@@ -131,10 +131,6 @@ | |||
131 | #define LINKRATE_30 (0x02 << 8) | 131 | #define LINKRATE_30 (0x02 << 8) |
132 | #define LINKRATE_60 (0x04 << 8) | 132 | #define LINKRATE_60 (0x04 << 8) |
133 | 133 | ||
134 | /* for phy state */ | ||
135 | |||
136 | #define PHY_STATE_LINK_UP_SPC 0x1 | ||
137 | |||
138 | /* for new SPC controllers MEMBASE III is shared between BIOS and DATA */ | 134 | /* for new SPC controllers MEMBASE III is shared between BIOS and DATA */ |
139 | #define GSM_SM_BASE 0x4F0000 | 135 | #define GSM_SM_BASE 0x4F0000 |
140 | struct mpi_msg_hdr{ | 136 | struct mpi_msg_hdr{ |
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 7a697ca68501..501830caba21 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c | |||
@@ -121,7 +121,7 @@ static void pm8001_phy_init(struct pm8001_hba_info *pm8001_ha, int phy_id) | |||
121 | { | 121 | { |
122 | struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; | 122 | struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; |
123 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | 123 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
124 | phy->phy_state = 0; | 124 | phy->phy_state = PHY_LINK_DISABLE; |
125 | phy->pm8001_ha = pm8001_ha; | 125 | phy->pm8001_ha = pm8001_ha; |
126 | sas_phy->enabled = (phy_id < pm8001_ha->chip->n_phy) ? 1 : 0; | 126 | sas_phy->enabled = (phy_id < pm8001_ha->chip->n_phy) ? 1 : 0; |
127 | sas_phy->class = SAS; | 127 | sas_phy->class = SAS; |
@@ -1067,6 +1067,7 @@ static int pm8001_pci_probe(struct pci_dev *pdev, | |||
1067 | if (rc) | 1067 | if (rc) |
1068 | goto err_out_shost; | 1068 | goto err_out_shost; |
1069 | scsi_scan_host(pm8001_ha->shost); | 1069 | scsi_scan_host(pm8001_ha->shost); |
1070 | pm8001_ha->flags = PM8001F_RUN_TIME; | ||
1070 | return 0; | 1071 | return 0; |
1071 | 1072 | ||
1072 | err_out_shost: | 1073 | err_out_shost: |
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 947d6017d004..d8249675371e 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c | |||
@@ -157,9 +157,12 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, | |||
157 | int rc = 0, phy_id = sas_phy->id; | 157 | int rc = 0, phy_id = sas_phy->id; |
158 | struct pm8001_hba_info *pm8001_ha = NULL; | 158 | struct pm8001_hba_info *pm8001_ha = NULL; |
159 | struct sas_phy_linkrates *rates; | 159 | struct sas_phy_linkrates *rates; |
160 | struct sas_ha_struct *sas_ha; | ||
161 | struct pm8001_phy *phy; | ||
160 | DECLARE_COMPLETION_ONSTACK(completion); | 162 | DECLARE_COMPLETION_ONSTACK(completion); |
161 | unsigned long flags; | 163 | unsigned long flags; |
162 | pm8001_ha = sas_phy->ha->lldd_ha; | 164 | pm8001_ha = sas_phy->ha->lldd_ha; |
165 | phy = &pm8001_ha->phy[phy_id]; | ||
163 | pm8001_ha->phy[phy_id].enable_completion = &completion; | 166 | pm8001_ha->phy[phy_id].enable_completion = &completion; |
164 | switch (func) { | 167 | switch (func) { |
165 | case PHY_FUNC_SET_LINK_RATE: | 168 | case PHY_FUNC_SET_LINK_RATE: |
@@ -172,7 +175,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, | |||
172 | pm8001_ha->phy[phy_id].maximum_linkrate = | 175 | pm8001_ha->phy[phy_id].maximum_linkrate = |
173 | rates->maximum_linkrate; | 176 | rates->maximum_linkrate; |
174 | } | 177 | } |
175 | if (pm8001_ha->phy[phy_id].phy_state == 0) { | 178 | if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { |
176 | PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); | 179 | PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); |
177 | wait_for_completion(&completion); | 180 | wait_for_completion(&completion); |
178 | } | 181 | } |
@@ -180,7 +183,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, | |||
180 | PHY_LINK_RESET); | 183 | PHY_LINK_RESET); |
181 | break; | 184 | break; |
182 | case PHY_FUNC_HARD_RESET: | 185 | case PHY_FUNC_HARD_RESET: |
183 | if (pm8001_ha->phy[phy_id].phy_state == 0) { | 186 | if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { |
184 | PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); | 187 | PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); |
185 | wait_for_completion(&completion); | 188 | wait_for_completion(&completion); |
186 | } | 189 | } |
@@ -188,7 +191,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, | |||
188 | PHY_HARD_RESET); | 191 | PHY_HARD_RESET); |
189 | break; | 192 | break; |
190 | case PHY_FUNC_LINK_RESET: | 193 | case PHY_FUNC_LINK_RESET: |
191 | if (pm8001_ha->phy[phy_id].phy_state == 0) { | 194 | if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { |
192 | PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); | 195 | PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); |
193 | wait_for_completion(&completion); | 196 | wait_for_completion(&completion); |
194 | } | 197 | } |
@@ -200,6 +203,25 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, | |||
200 | PHY_LINK_RESET); | 203 | PHY_LINK_RESET); |
201 | break; | 204 | break; |
202 | case PHY_FUNC_DISABLE: | 205 | case PHY_FUNC_DISABLE: |
206 | if (pm8001_ha->chip_id != chip_8001) { | ||
207 | if (pm8001_ha->phy[phy_id].phy_state == | ||
208 | PHY_STATE_LINK_UP_SPCV) { | ||
209 | sas_ha = pm8001_ha->sas; | ||
210 | sas_phy_disconnected(&phy->sas_phy); | ||
211 | sas_ha->notify_phy_event(&phy->sas_phy, | ||
212 | PHYE_LOSS_OF_SIGNAL); | ||
213 | phy->phy_attached = 0; | ||
214 | } | ||
215 | } else { | ||
216 | if (pm8001_ha->phy[phy_id].phy_state == | ||
217 | PHY_STATE_LINK_UP_SPC) { | ||
218 | sas_ha = pm8001_ha->sas; | ||
219 | sas_phy_disconnected(&phy->sas_phy); | ||
220 | sas_ha->notify_phy_event(&phy->sas_phy, | ||
221 | PHYE_LOSS_OF_SIGNAL); | ||
222 | phy->phy_attached = 0; | ||
223 | } | ||
224 | } | ||
203 | PM8001_CHIP_DISP->phy_stop_req(pm8001_ha, phy_id); | 225 | PM8001_CHIP_DISP->phy_stop_req(pm8001_ha, phy_id); |
204 | break; | 226 | break; |
205 | case PHY_FUNC_GET_EVENTS: | 227 | case PHY_FUNC_GET_EVENTS: |
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 42f0405601ad..91ff6a44e9d9 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c | |||
@@ -3118,8 +3118,9 @@ static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
3118 | pm8001_printk("phy start resp status:0x%x, phyid:0x%x\n", | 3118 | pm8001_printk("phy start resp status:0x%x, phyid:0x%x\n", |
3119 | status, phy_id)); | 3119 | status, phy_id)); |
3120 | if (status == 0) { | 3120 | if (status == 0) { |
3121 | phy->phy_state = 1; | 3121 | phy->phy_state = PHY_LINK_DOWN; |
3122 | if (pm8001_ha->flags == PM8001F_RUN_TIME) | 3122 | if (pm8001_ha->flags == PM8001F_RUN_TIME && |
3123 | phy->enable_completion != NULL) | ||
3123 | complete(phy->enable_completion); | 3124 | complete(phy->enable_completion); |
3124 | } | 3125 | } |
3125 | return 0; | 3126 | return 0; |
@@ -3211,7 +3212,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
3211 | return 0; | 3212 | return 0; |
3212 | } | 3213 | } |
3213 | phy->phy_attached = 0; | 3214 | phy->phy_attached = 0; |
3214 | phy->phy_state = 0; | 3215 | phy->phy_state = PHY_LINK_DISABLE; |
3215 | break; | 3216 | break; |
3216 | case HW_EVENT_PORT_INVALID: | 3217 | case HW_EVENT_PORT_INVALID: |
3217 | PM8001_MSG_DBG(pm8001_ha, | 3218 | PM8001_MSG_DBG(pm8001_ha, |
@@ -3384,13 +3385,14 @@ static int mpi_phy_stop_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
3384 | u32 status = | 3385 | u32 status = |
3385 | le32_to_cpu(pPayload->status); | 3386 | le32_to_cpu(pPayload->status); |
3386 | u32 phyid = | 3387 | u32 phyid = |
3387 | le32_to_cpu(pPayload->phyid); | 3388 | le32_to_cpu(pPayload->phyid) & 0xFF; |
3388 | struct pm8001_phy *phy = &pm8001_ha->phy[phyid]; | 3389 | struct pm8001_phy *phy = &pm8001_ha->phy[phyid]; |
3389 | PM8001_MSG_DBG(pm8001_ha, | 3390 | PM8001_MSG_DBG(pm8001_ha, |
3390 | pm8001_printk("phy:0x%x status:0x%x\n", | 3391 | pm8001_printk("phy:0x%x status:0x%x\n", |
3391 | phyid, status)); | 3392 | phyid, status)); |
3392 | if (status == 0) | 3393 | if (status == PHY_STOP_SUCCESS || |
3393 | phy->phy_state = 0; | 3394 | status == PHY_STOP_ERR_DEVICE_ATTACHED) |
3395 | phy->phy_state = PHY_LINK_DISABLE; | ||
3394 | return 0; | 3396 | return 0; |
3395 | } | 3397 | } |
3396 | 3398 | ||
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h index 889e69ce3689..dead05a55aab 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.h +++ b/drivers/scsi/pm8001/pm80xx_hwi.h | |||
@@ -170,6 +170,10 @@ | |||
170 | #define LINKRATE_60 (0x04 << 8) | 170 | #define LINKRATE_60 (0x04 << 8) |
171 | #define LINKRATE_120 (0x08 << 8) | 171 | #define LINKRATE_120 (0x08 << 8) |
172 | 172 | ||
173 | /*phy_stop*/ | ||
174 | #define PHY_STOP_SUCCESS 0x00 | ||
175 | #define PHY_STOP_ERR_DEVICE_ATTACHED 0x1046 | ||
176 | |||
173 | /* phy_profile */ | 177 | /* phy_profile */ |
174 | #define SAS_PHY_ANALOG_SETTINGS_PAGE 0x04 | 178 | #define SAS_PHY_ANALOG_SETTINGS_PAGE 0x04 |
175 | #define PHY_DWORD_LENGTH 0xC | 179 | #define PHY_DWORD_LENGTH 0xC |
@@ -216,8 +220,6 @@ | |||
216 | #define SAS_DOPNRJT_RTRY_TMO 128 | 220 | #define SAS_DOPNRJT_RTRY_TMO 128 |
217 | #define SAS_COPNRJT_RTRY_TMO 128 | 221 | #define SAS_COPNRJT_RTRY_TMO 128 |
218 | 222 | ||
219 | /* for phy state */ | ||
220 | #define PHY_STATE_LINK_UP_SPCV 0x2 | ||
221 | /* | 223 | /* |
222 | Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second. | 224 | Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second. |
223 | Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128 | 225 | Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128 |