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>
This commit is contained in:
Родитель
0b1b1d8861
Коммит
cd135754d8
|
@ -132,4 +132,12 @@ enum pm8001_hba_info_flags {
|
||||||
PM8001F_RUN_TIME = (1U << 1),
|
PM8001F_RUN_TIME = (1U << 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Phy Status
|
||||||
|
*/
|
||||||
|
#define PHY_LINK_DISABLE 0x00
|
||||||
|
#define PHY_LINK_DOWN 0x01
|
||||||
|
#define PHY_STATE_LINK_UP_SPCV 0x2
|
||||||
|
#define PHY_STATE_LINK_UP_SPC 0x1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3810,7 +3810,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
||||||
" status = %x\n", status));
|
" status = %x\n", status));
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
phy->phy_state = 1;
|
phy->phy_state = 1;
|
||||||
if (pm8001_ha->flags == PM8001F_RUN_TIME)
|
if (pm8001_ha->flags == PM8001F_RUN_TIME &&
|
||||||
|
phy->enable_completion != NULL)
|
||||||
complete(phy->enable_completion);
|
complete(phy->enable_completion);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -131,10 +131,6 @@
|
||||||
#define LINKRATE_30 (0x02 << 8)
|
#define LINKRATE_30 (0x02 << 8)
|
||||||
#define LINKRATE_60 (0x04 << 8)
|
#define LINKRATE_60 (0x04 << 8)
|
||||||
|
|
||||||
/* for phy state */
|
|
||||||
|
|
||||||
#define PHY_STATE_LINK_UP_SPC 0x1
|
|
||||||
|
|
||||||
/* for new SPC controllers MEMBASE III is shared between BIOS and DATA */
|
/* for new SPC controllers MEMBASE III is shared between BIOS and DATA */
|
||||||
#define GSM_SM_BASE 0x4F0000
|
#define GSM_SM_BASE 0x4F0000
|
||||||
struct mpi_msg_hdr{
|
struct mpi_msg_hdr{
|
||||||
|
|
|
@ -121,7 +121,7 @@ static void pm8001_phy_init(struct pm8001_hba_info *pm8001_ha, int phy_id)
|
||||||
{
|
{
|
||||||
struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
|
struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
|
||||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||||
phy->phy_state = 0;
|
phy->phy_state = PHY_LINK_DISABLE;
|
||||||
phy->pm8001_ha = pm8001_ha;
|
phy->pm8001_ha = pm8001_ha;
|
||||||
sas_phy->enabled = (phy_id < pm8001_ha->chip->n_phy) ? 1 : 0;
|
sas_phy->enabled = (phy_id < pm8001_ha->chip->n_phy) ? 1 : 0;
|
||||||
sas_phy->class = SAS;
|
sas_phy->class = SAS;
|
||||||
|
@ -1067,6 +1067,7 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_out_shost;
|
goto err_out_shost;
|
||||||
scsi_scan_host(pm8001_ha->shost);
|
scsi_scan_host(pm8001_ha->shost);
|
||||||
|
pm8001_ha->flags = PM8001F_RUN_TIME;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_out_shost:
|
err_out_shost:
|
||||||
|
|
|
@ -157,9 +157,12 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
|
||||||
int rc = 0, phy_id = sas_phy->id;
|
int rc = 0, phy_id = sas_phy->id;
|
||||||
struct pm8001_hba_info *pm8001_ha = NULL;
|
struct pm8001_hba_info *pm8001_ha = NULL;
|
||||||
struct sas_phy_linkrates *rates;
|
struct sas_phy_linkrates *rates;
|
||||||
|
struct sas_ha_struct *sas_ha;
|
||||||
|
struct pm8001_phy *phy;
|
||||||
DECLARE_COMPLETION_ONSTACK(completion);
|
DECLARE_COMPLETION_ONSTACK(completion);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
pm8001_ha = sas_phy->ha->lldd_ha;
|
pm8001_ha = sas_phy->ha->lldd_ha;
|
||||||
|
phy = &pm8001_ha->phy[phy_id];
|
||||||
pm8001_ha->phy[phy_id].enable_completion = &completion;
|
pm8001_ha->phy[phy_id].enable_completion = &completion;
|
||||||
switch (func) {
|
switch (func) {
|
||||||
case PHY_FUNC_SET_LINK_RATE:
|
case PHY_FUNC_SET_LINK_RATE:
|
||||||
|
@ -172,7 +175,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
|
||||||
pm8001_ha->phy[phy_id].maximum_linkrate =
|
pm8001_ha->phy[phy_id].maximum_linkrate =
|
||||||
rates->maximum_linkrate;
|
rates->maximum_linkrate;
|
||||||
}
|
}
|
||||||
if (pm8001_ha->phy[phy_id].phy_state == 0) {
|
if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) {
|
||||||
PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
|
PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
|
||||||
wait_for_completion(&completion);
|
wait_for_completion(&completion);
|
||||||
}
|
}
|
||||||
|
@ -180,7 +183,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
|
||||||
PHY_LINK_RESET);
|
PHY_LINK_RESET);
|
||||||
break;
|
break;
|
||||||
case PHY_FUNC_HARD_RESET:
|
case PHY_FUNC_HARD_RESET:
|
||||||
if (pm8001_ha->phy[phy_id].phy_state == 0) {
|
if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) {
|
||||||
PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
|
PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
|
||||||
wait_for_completion(&completion);
|
wait_for_completion(&completion);
|
||||||
}
|
}
|
||||||
|
@ -188,7 +191,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
|
||||||
PHY_HARD_RESET);
|
PHY_HARD_RESET);
|
||||||
break;
|
break;
|
||||||
case PHY_FUNC_LINK_RESET:
|
case PHY_FUNC_LINK_RESET:
|
||||||
if (pm8001_ha->phy[phy_id].phy_state == 0) {
|
if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) {
|
||||||
PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
|
PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
|
||||||
wait_for_completion(&completion);
|
wait_for_completion(&completion);
|
||||||
}
|
}
|
||||||
|
@ -200,6 +203,25 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
|
||||||
PHY_LINK_RESET);
|
PHY_LINK_RESET);
|
||||||
break;
|
break;
|
||||||
case PHY_FUNC_DISABLE:
|
case PHY_FUNC_DISABLE:
|
||||||
|
if (pm8001_ha->chip_id != chip_8001) {
|
||||||
|
if (pm8001_ha->phy[phy_id].phy_state ==
|
||||||
|
PHY_STATE_LINK_UP_SPCV) {
|
||||||
|
sas_ha = pm8001_ha->sas;
|
||||||
|
sas_phy_disconnected(&phy->sas_phy);
|
||||||
|
sas_ha->notify_phy_event(&phy->sas_phy,
|
||||||
|
PHYE_LOSS_OF_SIGNAL);
|
||||||
|
phy->phy_attached = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pm8001_ha->phy[phy_id].phy_state ==
|
||||||
|
PHY_STATE_LINK_UP_SPC) {
|
||||||
|
sas_ha = pm8001_ha->sas;
|
||||||
|
sas_phy_disconnected(&phy->sas_phy);
|
||||||
|
sas_ha->notify_phy_event(&phy->sas_phy,
|
||||||
|
PHYE_LOSS_OF_SIGNAL);
|
||||||
|
phy->phy_attached = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
PM8001_CHIP_DISP->phy_stop_req(pm8001_ha, phy_id);
|
PM8001_CHIP_DISP->phy_stop_req(pm8001_ha, phy_id);
|
||||||
break;
|
break;
|
||||||
case PHY_FUNC_GET_EVENTS:
|
case PHY_FUNC_GET_EVENTS:
|
||||||
|
|
|
@ -3118,8 +3118,9 @@ static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||||
pm8001_printk("phy start resp status:0x%x, phyid:0x%x\n",
|
pm8001_printk("phy start resp status:0x%x, phyid:0x%x\n",
|
||||||
status, phy_id));
|
status, phy_id));
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
phy->phy_state = 1;
|
phy->phy_state = PHY_LINK_DOWN;
|
||||||
if (pm8001_ha->flags == PM8001F_RUN_TIME)
|
if (pm8001_ha->flags == PM8001F_RUN_TIME &&
|
||||||
|
phy->enable_completion != NULL)
|
||||||
complete(phy->enable_completion);
|
complete(phy->enable_completion);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3211,7 +3212,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
phy->phy_attached = 0;
|
phy->phy_attached = 0;
|
||||||
phy->phy_state = 0;
|
phy->phy_state = PHY_LINK_DISABLE;
|
||||||
break;
|
break;
|
||||||
case HW_EVENT_PORT_INVALID:
|
case HW_EVENT_PORT_INVALID:
|
||||||
PM8001_MSG_DBG(pm8001_ha,
|
PM8001_MSG_DBG(pm8001_ha,
|
||||||
|
@ -3384,13 +3385,14 @@ static int mpi_phy_stop_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||||
u32 status =
|
u32 status =
|
||||||
le32_to_cpu(pPayload->status);
|
le32_to_cpu(pPayload->status);
|
||||||
u32 phyid =
|
u32 phyid =
|
||||||
le32_to_cpu(pPayload->phyid);
|
le32_to_cpu(pPayload->phyid) & 0xFF;
|
||||||
struct pm8001_phy *phy = &pm8001_ha->phy[phyid];
|
struct pm8001_phy *phy = &pm8001_ha->phy[phyid];
|
||||||
PM8001_MSG_DBG(pm8001_ha,
|
PM8001_MSG_DBG(pm8001_ha,
|
||||||
pm8001_printk("phy:0x%x status:0x%x\n",
|
pm8001_printk("phy:0x%x status:0x%x\n",
|
||||||
phyid, status));
|
phyid, status));
|
||||||
if (status == 0)
|
if (status == PHY_STOP_SUCCESS ||
|
||||||
phy->phy_state = 0;
|
status == PHY_STOP_ERR_DEVICE_ATTACHED)
|
||||||
|
phy->phy_state = PHY_LINK_DISABLE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,10 @@
|
||||||
#define LINKRATE_60 (0x04 << 8)
|
#define LINKRATE_60 (0x04 << 8)
|
||||||
#define LINKRATE_120 (0x08 << 8)
|
#define LINKRATE_120 (0x08 << 8)
|
||||||
|
|
||||||
|
/*phy_stop*/
|
||||||
|
#define PHY_STOP_SUCCESS 0x00
|
||||||
|
#define PHY_STOP_ERR_DEVICE_ATTACHED 0x1046
|
||||||
|
|
||||||
/* phy_profile */
|
/* phy_profile */
|
||||||
#define SAS_PHY_ANALOG_SETTINGS_PAGE 0x04
|
#define SAS_PHY_ANALOG_SETTINGS_PAGE 0x04
|
||||||
#define PHY_DWORD_LENGTH 0xC
|
#define PHY_DWORD_LENGTH 0xC
|
||||||
|
@ -216,8 +220,6 @@
|
||||||
#define SAS_DOPNRJT_RTRY_TMO 128
|
#define SAS_DOPNRJT_RTRY_TMO 128
|
||||||
#define SAS_COPNRJT_RTRY_TMO 128
|
#define SAS_COPNRJT_RTRY_TMO 128
|
||||||
|
|
||||||
/* for phy state */
|
|
||||||
#define PHY_STATE_LINK_UP_SPCV 0x2
|
|
||||||
/*
|
/*
|
||||||
Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second.
|
Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second.
|
||||||
Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128
|
Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128
|
||||||
|
|
Загрузка…
Ссылка в новой задаче