@@ -1621,6 +1621,16 @@ int sas_discover_root_expander(struct domain_device *dev)
16211621
16221622/* ---------- Domain revalidation ---------- */
16231623
1624+ static void sas_get_sas_addr_and_dev_type (struct smp_disc_resp * disc_resp ,
1625+ u8 * sas_addr ,
1626+ enum sas_device_type * type )
1627+ {
1628+ memcpy (sas_addr , disc_resp -> disc .attached_sas_addr , SAS_ADDR_SIZE );
1629+ * type = to_dev_type (& disc_resp -> disc );
1630+ if (* type == SAS_PHY_UNUSED )
1631+ memset (sas_addr , 0 , SAS_ADDR_SIZE );
1632+ }
1633+
16241634static int sas_get_phy_discover (struct domain_device * dev ,
16251635 int phy_id , struct smp_disc_resp * disc_resp )
16261636{
@@ -1674,13 +1684,8 @@ int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
16741684 return - ENOMEM ;
16751685
16761686 res = sas_get_phy_discover (dev , phy_id , disc_resp );
1677- if (res == 0 ) {
1678- memcpy (sas_addr , disc_resp -> disc .attached_sas_addr ,
1679- SAS_ADDR_SIZE );
1680- * type = to_dev_type (& disc_resp -> disc );
1681- if (* type == 0 )
1682- memset (sas_addr , 0 , SAS_ADDR_SIZE );
1683- }
1687+ if (res == 0 )
1688+ sas_get_sas_addr_and_dev_type (disc_resp , sas_addr , type );
16841689 kfree (disc_resp );
16851690 return res ;
16861691}
@@ -1940,6 +1945,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
19401945 struct expander_device * ex = & dev -> ex_dev ;
19411946 struct ex_phy * phy = & ex -> ex_phy [phy_id ];
19421947 enum sas_device_type type = SAS_PHY_UNUSED ;
1948+ struct smp_disc_resp * disc_resp ;
19431949 u8 sas_addr [SAS_ADDR_SIZE ];
19441950 char msg [80 ] = "" ;
19451951 int res ;
@@ -1951,33 +1957,41 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
19511957 SAS_ADDR (dev -> sas_addr ), phy_id , msg );
19521958
19531959 memset (sas_addr , 0 , SAS_ADDR_SIZE );
1954- res = sas_get_phy_attached_dev (dev , phy_id , sas_addr , & type );
1960+ disc_resp = alloc_smp_resp (DISCOVER_RESP_SIZE );
1961+ if (!disc_resp )
1962+ return - ENOMEM ;
1963+
1964+ res = sas_get_phy_discover (dev , phy_id , disc_resp );
19551965 switch (res ) {
19561966 case SMP_RESP_NO_PHY :
19571967 phy -> phy_state = PHY_NOT_PRESENT ;
19581968 sas_unregister_devs_sas_addr (dev , phy_id , last );
1959- return res ;
1969+ goto out_free_resp ;
19601970 case SMP_RESP_PHY_VACANT :
19611971 phy -> phy_state = PHY_VACANT ;
19621972 sas_unregister_devs_sas_addr (dev , phy_id , last );
1963- return res ;
1973+ goto out_free_resp ;
19641974 case SMP_RESP_FUNC_ACC :
19651975 break ;
19661976 case - ECOMM :
19671977 break ;
19681978 default :
1969- return res ;
1979+ goto out_free_resp ;
19701980 }
19711981
1982+ if (res == 0 )
1983+ sas_get_sas_addr_and_dev_type (disc_resp , sas_addr , & type );
1984+
19721985 if ((SAS_ADDR (sas_addr ) == 0 ) || (res == - ECOMM )) {
19731986 phy -> phy_state = PHY_EMPTY ;
19741987 sas_unregister_devs_sas_addr (dev , phy_id , last );
19751988 /*
1976- * Even though the PHY is empty, for convenience we discover
1977- * the PHY to update the PHY info, like negotiated linkrate.
1989+ * Even though the PHY is empty, for convenience we update
1990+ * the PHY info, like negotiated linkrate.
19781991 */
1979- sas_ex_phy_discover (dev , phy_id );
1980- return res ;
1992+ if (res == 0 )
1993+ sas_set_ex_phy (dev , phy_id , disc_resp );
1994+ goto out_free_resp ;
19811995 } else if (SAS_ADDR (sas_addr ) == SAS_ADDR (phy -> attached_sas_addr ) &&
19821996 dev_type_flutter (type , phy -> attached_dev_type )) {
19831997 struct domain_device * ata_dev = sas_ex_to_ata (dev , phy_id );
@@ -1989,7 +2003,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
19892003 action = ", needs recovery" ;
19902004 pr_debug ("ex %016llx phy%02d broadcast flutter%s\n" ,
19912005 SAS_ADDR (dev -> sas_addr ), phy_id , action );
1992- return res ;
2006+ goto out_free_resp ;
19932007 }
19942008
19952009 /* we always have to delete the old device when we went here */
@@ -1998,7 +2012,10 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
19982012 SAS_ADDR (phy -> attached_sas_addr ));
19992013 sas_unregister_devs_sas_addr (dev , phy_id , last );
20002014
2001- return sas_discover_new (dev , phy_id );
2015+ res = sas_discover_new (dev , phy_id );
2016+ out_free_resp :
2017+ kfree (disc_resp );
2018+ return res ;
20022019}
20032020
20042021/**
0 commit comments