@@ -26,6 +26,28 @@ static int sas_configure_phy(struct domain_device *dev, int phy_id,
2626 u8 * sas_addr , int include );
2727static int sas_disable_routing (struct domain_device * dev , u8 * sas_addr );
2828
29+ static void sas_port_add_ex_phy (struct sas_port * port , struct ex_phy * ex_phy )
30+ {
31+ sas_port_add_phy (port , ex_phy -> phy );
32+ ex_phy -> port = port ;
33+ ex_phy -> phy_state = PHY_DEVICE_DISCOVERED ;
34+ }
35+
36+ static void sas_ex_add_parent_port (struct domain_device * dev , int phy_id )
37+ {
38+ struct expander_device * ex = & dev -> ex_dev ;
39+ struct ex_phy * ex_phy = & ex -> ex_phy [phy_id ];
40+
41+ if (!ex -> parent_port ) {
42+ ex -> parent_port = sas_port_alloc (& dev -> rphy -> dev , phy_id );
43+ /* FIXME: error handling */
44+ BUG_ON (!ex -> parent_port );
45+ BUG_ON (sas_port_add (ex -> parent_port ));
46+ sas_port_mark_backlink (ex -> parent_port );
47+ }
48+ sas_port_add_ex_phy (ex -> parent_port , ex_phy );
49+ }
50+
2951/* ---------- SMP task management ---------- */
3052
3153/* Give it some long enough timeout. In seconds. */
@@ -239,8 +261,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
239261 /* help some expanders that fail to zero sas_address in the 'no
240262 * device' case
241263 */
242- if (phy -> attached_dev_type == SAS_PHY_UNUSED ||
243- phy -> linkrate < SAS_LINK_RATE_1_5_GBPS )
264+ if (phy -> attached_dev_type == SAS_PHY_UNUSED )
244265 memset (phy -> attached_sas_addr , 0 , SAS_ADDR_SIZE );
245266 else
246267 memcpy (phy -> attached_sas_addr , dr -> attached_sas_addr , SAS_ADDR_SIZE );
@@ -857,9 +878,7 @@ static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
857878
858879 if (!memcmp (phy -> attached_sas_addr , ephy -> attached_sas_addr ,
859880 SAS_ADDR_SIZE ) && ephy -> port ) {
860- sas_port_add_phy (ephy -> port , phy -> phy );
861- phy -> port = ephy -> port ;
862- phy -> phy_state = PHY_DEVICE_DISCOVERED ;
881+ sas_port_add_ex_phy (ephy -> port , phy );
863882 return true;
864883 }
865884 }
@@ -963,11 +982,11 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
963982
964983 /* Parent and domain coherency */
965984 if (!dev -> parent && sas_phy_match_port_addr (dev -> port , ex_phy )) {
966- sas_add_parent_port (dev , phy_id );
985+ sas_ex_add_parent_port (dev , phy_id );
967986 return 0 ;
968987 }
969988 if (dev -> parent && sas_phy_match_dev_addr (dev -> parent , ex_phy )) {
970- sas_add_parent_port (dev , phy_id );
989+ sas_ex_add_parent_port (dev , phy_id );
971990 if (ex_phy -> routing_attr == TABLE_ROUTING )
972991 sas_configure_phy (dev , phy_id , dev -> port -> sas_addr , 1 );
973992 return 0 ;
@@ -1849,9 +1868,12 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent,
18491868 if (phy -> port ) {
18501869 sas_port_delete_phy (phy -> port , phy -> phy );
18511870 sas_device_set_phy (found , phy -> port );
1852- if (phy -> port -> num_phys == 0 )
1871+ if (phy -> port -> num_phys == 0 ) {
18531872 list_add_tail (& phy -> port -> del_list ,
18541873 & parent -> port -> sas_port_del_list );
1874+ if (ex_dev -> parent_port == phy -> port )
1875+ ex_dev -> parent_port = NULL ;
1876+ }
18551877 phy -> port = NULL ;
18561878 }
18571879}
0 commit comments