Commit efdcad62 authored by John Garry's avatar John Garry Committed by Martin K. Petersen

scsi: hisi_sas: Set PHY linkrate when disconnected

When the PHY comes down, we currently do not set the negotiated linkrate:

root@(none)$ pwd
/sys/class/sas_phy/phy-0:0
root@(none)$ more enable
1
root@(none)$ more negotiated_linkrate
12.0 Gbit
root@(none)$ echo 0 > enable
root@(none)$ more negotiated_linkrate
12.0 Gbit
root@(none)$

This patch fixes the driver code to set it properly when the PHY comes
down.

If the PHY had been enabled, then set unknown; otherwise, flag as disabled.

The logical place to set the negotiated linkrate for this scenario is PHY
down routine, which is called from the PHY down ISR.

However, it is not possible to know if the PHY comes down due to PHY
disable or loss of link, as sas_phy.enabled member is not set until after
the transport disable routine is complete, which races with the PHY down
ISR.

As an imperfect solution, use sas_phy_data.enable as the flag to know if
the PHY is down due to disable. It's imperfect, as sas_phy_data is internal
to libsas.

I can't see another way without adding a new field to hisi_sas_phy and
managing it, or changing SCSI SAS transport.
Signed-off-by: default avatarJohn Garry <john.garry@huawei.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent aaeb8232
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#include "hisi_sas.h" #include "hisi_sas.h"
#include "../libsas/sas_internal.h"
#define DRV_NAME "hisi_sas" #define DRV_NAME "hisi_sas"
#define DEV_IS_GONE(dev) \ #define DEV_IS_GONE(dev) \
...@@ -2126,9 +2127,18 @@ static int hisi_sas_write_gpio(struct sas_ha_struct *sha, u8 reg_type, ...@@ -2126,9 +2127,18 @@ static int hisi_sas_write_gpio(struct sas_ha_struct *sha, u8 reg_type,
static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy) static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy)
{ {
struct asd_sas_phy *sas_phy = &phy->sas_phy;
struct sas_phy *sphy = sas_phy->phy;
struct sas_phy_data *d = sphy->hostdata;
phy->phy_attached = 0; phy->phy_attached = 0;
phy->phy_type = 0; phy->phy_type = 0;
phy->port = NULL; phy->port = NULL;
if (d->enable)
sphy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
else
sphy->negotiated_linkrate = SAS_PHY_DISABLED;
} }
void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment