aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak Ukey <deepak.ukey@microchip.com>2018-09-11 04:48:02 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2018-09-11 21:13:08 -0400
commitcd135754d837bc4b15a9211d30bfc23f2247afb9 (patch)
tree9443a9c827b0e13c9d79d0730927ab78f1c74305
parent0b1b1d88614fcd90c65d27dbd14490dcbf2c9b5f (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.h8
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c3
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.h4
-rw-r--r--drivers/scsi/pm8001/pm8001_init.c3
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.c28
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.c14
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.h6
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
140struct mpi_msg_hdr{ 136struct 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
1072err_out_shost: 1073err_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