[IBBUS] Fix for hibernate in case of several child devices of IBBUS.
authorleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 24 Mar 2009 16:04:45 +0000 (16:04 +0000)
committerleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 24 Mar 2009 16:04:45 +0000 (16:04 +0000)
Signed off by: James Yang

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2046 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

core/bus/kernel/bus_port_mgr.c

index 4241f6b..c11150a 100644 (file)
@@ -421,12 +421,11 @@ free_port_mgr(
                        deref_al_obj( &p_ext->h_ca->obj );\r
                }\r
 \r
-               BUS_TRACE( BUS_DBG_PNP, ("%s Deleted device %s: PDO %p, ext %p\n",\r
-                                       p_bfi->whoami, p_ext->cl_ext.vfptr_pnp_po->identity,\r
-                                       p_ext->cl_ext.p_self_do, p_ext ) );\r
-\r
-               IoDeleteDevice( p_ext->cl_ext.p_self_do );\r
-       }\r
+                       BUS_TRACE( BUS_DBG_PNP, ("%s Deleted device %s: PDO %p, ext %p\n",\r
+                                               p_bfi->whoami, p_ext->cl_ext.vfptr_pnp_po->identity,\r
+                                               p_ext->cl_ext.p_self_do, p_ext ) );\r
+                       IoDeleteDevice( p_ext->cl_ext.p_self_do );\r
+               }\r
 \r
        cl_mutex_destroy( &p_port_mgr->pdo_mutex );\r
        cl_obj_deinit( p_obj );\r
@@ -586,7 +585,7 @@ __port_was_hibernated(
        ib_api_status_t status;\r
        cl_list_item_t  *p_list_item;\r
        bus_port_ext_t  *p_port_ext;\r
-       bus_pdo_ext_t   *p_pdo_ext = NULL;\r
+       bus_pdo_ext_t   *p_shadow_pdo_ext, *p_pdo_ext = NULL;\r
        size_t                  n_devs = 0;\r
        port_mgr_t              *p_port_mgr = p_bfi->p_port_mgr;\r
        cl_qlist_t              *p_pdo_list = &p_port_mgr->port_list;\r
@@ -612,14 +611,14 @@ __port_was_hibernated(
                p_pdo_ext = PARENT_STRUCT( p_list_item, bus_pdo_ext_t, list_item );\r
                p_port_ext = (bus_port_ext_t*)p_pdo_ext;\r
        \r
-               if( p_pdo_ext->b_present && p_pdo_ext->b_hibernating &&\r
+               if( p_pdo_ext->b_present && p_pdo_ext->b_hibernating && p_pdo_ext->hca_acquired &&\r
                        (p_port_ext->port_guid.guid == p_pnp_rec->p_port_attr->port_guid) )\r
                {\r
                        n_devs++;\r
                        break;\r
                }\r
 \r
-               BUS_TRACE( BUS_DBG_PNP, ("%s Skipped PDO for %s: PDO %p, ext %p, "\r
+               BUS_TRACE( BUS_DBG_PNP, ("%s Skipped acquire hca on PDO for %s: PDO %p, ext %p, "\r
                        "present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
                        p_bfi->whoami,\r
                        p_pdo_ext->cl_ext.vfptr_pnp_po->identity,\r
@@ -655,6 +654,31 @@ __port_was_hibernated(
                                p_pdo_ext->cl_ext.p_self_do, \r
                                p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing, \r
                                p_pdo_ext->b_hibernating, p_port_ext->port_guid.guid ) );\r
+\r
+                       for( p_list_item = cl_qlist_head( p_pdo_list );\r
+                               p_list_item != cl_qlist_end( p_pdo_list );\r
+                               p_list_item = cl_qlist_next( p_list_item ) )\r
+                       {\r
+                               p_shadow_pdo_ext = PARENT_STRUCT( p_list_item, bus_pdo_ext_t, list_item );\r
+                               p_port_ext = (bus_port_ext_t*)p_shadow_pdo_ext;\r
+\r
+                               if( p_shadow_pdo_ext->b_present && p_shadow_pdo_ext->b_hibernating &&\r
+                                       (p_port_ext->port_guid.guid == p_pnp_rec->p_port_attr->port_guid) )\r
+                               {\r
+                                       p_shadow_pdo_ext->b_hibernating = FALSE;\r
+                                       p_shadow_pdo_ext->h_ca = p_pdo_ext->h_ca;\r
+\r
+\r
+                                       BUS_TRACE( BUS_DBG_PNP, ("%s set shadow h_ca PDO for %s: PDO %p, ext %p, "\r
+                                                                                        "present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
+                                                                                        p_bfi->whoami,\r
+                                                                                        p_shadow_pdo_ext->cl_ext.vfptr_pnp_po->identity,\r
+                                                                                        p_shadow_pdo_ext->cl_ext.p_self_do, \r
+                                                                                        p_shadow_pdo_ext, p_shadow_pdo_ext->b_present, p_shadow_pdo_ext->b_reported_missing, \r
+                                                                                        p_shadow_pdo_ext->b_hibernating, p_port_ext->port_guid.guid  ) );\r
+                               }\r
+                       }\r
+\r
                }\r
        }\r
        else \r
@@ -1145,6 +1169,10 @@ port_mgr_port_remove(
        port_mgr_t              *p_port_mgr;\r
        bus_filter_t    *p_bfi;\r
        port_pnp_ctx_t  *p_ctx = p_pnp_rec->pnp_rec.context;\r
+       cl_list_item_t          *p_list_item;\r
+       bus_port_ext_t          *p_port_ext;\r
+       bus_pdo_ext_t           *p_pdo_ext;\r
+       cl_qlist_t*                     p_pdo_list;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
@@ -1211,6 +1239,23 @@ port_mgr_port_remove(
        }\r
 \r
        p_ext->b_present = FALSE;\r
+\r
+       p_pdo_list = &p_port_mgr->port_list;\r
+\r
+       for( p_list_item = cl_qlist_head( p_pdo_list );\r
+                p_list_item != cl_qlist_end( p_pdo_list );\r
+                p_list_item = cl_qlist_next( p_list_item ) )\r
+               {\r
+               p_pdo_ext = PARENT_STRUCT( p_list_item, bus_pdo_ext_t, list_item );\r
+               p_port_ext =  (bus_port_ext_t*) p_pdo_ext;\r
+\r
+               if( (p_port_ext->port_guid.guid == ((bus_port_ext_t*)p_ext)->port_guid.guid) )\r
+                       {\r
+                       p_pdo_ext->b_present = FALSE;\r
+               }                       \r
+       }\r
+\r
+\r
        BUS_TRACE( BUS_DBG_PNP,\r
                ("Mark removing %s: PDO %p, ext %p, present %d, missing %d .\n",\r
                p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext,\r
@@ -1236,6 +1281,21 @@ hca_deref:
        // after arriving IB_PNP_PORT_ADD event from IBAL\r
        p_ext->h_ca = NULL;\r
 \r
+       p_pdo_list = &p_port_mgr->port_list;\r
+\r
+       for( p_list_item = cl_qlist_head( p_pdo_list );\r
+                p_list_item != cl_qlist_end( p_pdo_list );\r
+                p_list_item = cl_qlist_next( p_list_item ) )\r
+               {\r
+               p_pdo_ext = PARENT_STRUCT( p_list_item, bus_pdo_ext_t, list_item );\r
+               p_port_ext =  (bus_port_ext_t*) p_pdo_ext;\r
+\r
+               if( p_port_ext->port_guid.guid == ((bus_port_ext_t*)p_ext)->port_guid.guid )\r
+               {\r
+                       p_pdo_ext->h_ca = NULL;\r
+               }                       \r
+       }\r
+\r
        cl_mutex_release( &p_port_mgr->pdo_mutex );\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r