[ofw] ibbus filter driver patch 6/18 - bus_port_mgr.c

Smith, Stan stan.smith at intel.com
Mon Aug 18 14:43:52 PDT 2008


Signed-off by: Stan Smith (stan.smith at intel.com)

Having problems with Intel mailer, hence formatting of patch is incorrect, see attached patch file.

diff -Naur --exclude-from=./SKIP kernel-svn/bus_port_mgr.c kernel/bus_port_mgr.c
--- kernel-svn/bus_port_mgr.c   2008-08-06 14:09:36.000000000 -0700
+++ kernel/bus_port_mgr.c       2008-08-18 10:02:19.519681900 -0700
@@ -27,7 +27,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: bus_port_mgr.c 1160 2008-05-12 13:01:47Z tzachid $
+ * $Id: bus_port_mgr.c 1484 2008-08-18 15:49:36Z stansmith $
  */


@@ -71,7 +71,14 @@
 }      bus_port_ext_t;


-port_mgr_t*                                            gp_port_mgr = NULL;
+typedef struct _port_pnp_context
+{
+       bus_filter_t    *p_bus_filter;
+       void                    *p_pdo_ext;
+       int                             port_num;
+
+}      port_pnp_ctx_t;
+

 extern pkey_array_t  g_pkeys;

@@ -88,7 +95,8 @@
        IN                              cl_obj_t*                                       p_obj );

 ib_api_status_t
-bus_reg_port_pnp( void );
+bus_reg_port_pnp(
+       IN                              bus_filter_t*                           p_bfi );

 ib_api_status_t
 port_mgr_pnp_cb(
@@ -274,14 +282,16 @@
  */
 ib_api_status_t
 create_port_mgr(
+               IN                      bus_filter_t*                           p_bfi,
                OUT                     port_mgr_t** const                      pp_port_mgr )
 {
        ib_api_status_t         status;
        cl_status_t                     cl_status;
+       port_mgr_t                      *gp_port_mgr;

        BUS_ENTER( BUS_DBG_PNP );

-       CL_ASSERT( !gp_port_mgr );
+       CL_ASSERT( p_bfi->p_port_mgr == NULL );

        gp_port_mgr = cl_zalloc( sizeof( port_mgr_t ) );
        if( !gp_port_mgr )
@@ -290,9 +300,11 @@
                        ("Failed to allocate port manager.\n") );
                return IB_INSUFFICIENT_MEMORY;
        }
+       p_bfi->p_port_mgr = gp_port_mgr;

        /* Construct the load service. */
        cl_obj_construct( &gp_port_mgr->obj, AL_OBJ_TYPE_LOADER );
+       p_bfi->p_port_mgr_obj = &gp_port_mgr->obj;
        cl_mutex_construct( &gp_port_mgr->pdo_mutex );
        cl_qlist_init( &gp_port_mgr->port_list );

@@ -307,7 +319,8 @@

        /* Initialize the load service object. */
        cl_status = cl_obj_init( &gp_port_mgr->obj, CL_DESTROY_SYNC,
-               destroying_port_mgr, NULL, free_port_mgr );
+                                                        destroying_port_mgr, NULL, free_port_mgr );
+
        if( cl_status != CL_SUCCESS )
        {
                free_port_mgr( &gp_port_mgr->obj );
@@ -316,13 +329,13 @@
                return ib_convert_cl_status( cl_status );
        }

-       /* Register for port PnP events. */
-       status = bus_reg_port_pnp();
+       /* Register for port PnP events */
+       status = bus_reg_port_pnp(p_bfi);
        if( status != IB_SUCCESS )
        {
-               cl_obj_destroy( &gp_port_mgr->obj );
                BUS_TRACE_EXIT( BUS_DBG_ERROR,
                        ("bus_reg_port_pnp returned %s.\n", ib_get_err_str(status)) );
+               free_port_mgr( &gp_port_mgr->obj );
                return status;
        }

@@ -341,20 +354,35 @@
        IN                              cl_obj_t*                                       p_obj )
 {
        ib_api_status_t                 status;
+       bus_filter_t                    *p_bfi;
+       port_mgr_t                              *gp_port_mgr;

        BUS_ENTER( BUS_DBG_PNP );

        CL_ASSERT( p_obj );
+       p_bfi = get_bfi_by_obj(BFI_PORT_MGR_OBJ, p_obj);
+       if (p_bfi == NULL) {
+               BUS_PRINT(BUS_DBG_PNP, ("%s() failed to find p_bfi by obj %p?\n",
+                       __FUNCTION__,p_obj));
+               return;
+       }
+       gp_port_mgr = p_bfi->p_port_mgr;
+
+       BUS_PRINT(BUS_DBG_PNP, ("%s(%s) obj %p port_mgr %p port_mgr_obj %p\n",
+                       __FUNCTION__,p_bfi->whoami,p_obj,gp_port_mgr,
+                       p_bfi->p_port_mgr_obj) );
+
+       CL_ASSERT( (void*)p_bfi->p_port_mgr == (void*)p_bfi->p_port_mgr_obj );
        CL_ASSERT( gp_port_mgr == PARENT_STRUCT( p_obj, port_mgr_t, obj ) );
-       UNUSED_PARAM( p_obj );

-       /* Deregister for port PnP events. */
-       if( gp_port_mgr->h_pnp )
-       {
-               status = ib_dereg_pnp( gp_port_mgr->h_pnp,
-                       (ib_pfn_destroy_cb_t)cl_obj_deref );
+       /* Deregister for port PnP events if this is the last Port manager. */
+       if ( get_bfi_count() == 1 && bus_globals.h_pnp_port ) {
+               status = ib_dereg_pnp( bus_globals.h_pnp_port, NULL );
+               bus_globals.h_pnp_port = NULL;
                CL_ASSERT( status == IB_SUCCESS );
        }
+       cl_obj_deref( p_bfi->p_port_mgr_obj );
+
        BUS_EXIT( BUS_DBG_PNP );
 }

@@ -368,12 +396,32 @@
 {
        bus_pdo_ext_t   *p_ext;
        cl_list_item_t  *p_list_item;
+       bus_filter_t    *p_bfi;
+       port_mgr_t              *gp_port_mgr;

        BUS_ENTER( BUS_DBG_PNP );

        CL_ASSERT( p_obj );
+       p_bfi = get_bfi_by_obj(BFI_PORT_MGR_OBJ, p_obj);
+       if (p_bfi == NULL) {
+               BUS_PRINT(BUS_DBG_PNP, ("%s: unable to get p_bfi for port obj %p?\n",
+                       __FUNCTION__,p_obj));
+               return;
+       }
+       gp_port_mgr = p_bfi->p_port_mgr;
+       if ( !gp_port_mgr ) {
+               // if create fails & then free is called, p_bfi->p_port_mgr == NULL
+               return;
+       }
        CL_ASSERT( gp_port_mgr == PARENT_STRUCT( p_obj, port_mgr_t, obj ) );

+       BUS_PRINT(BUS_DBG_PNP, ("%s(%s) obj %p port_mgr %p port_mgr_obj %p\n",
+                       __FUNCTION__, p_bfi->whoami, p_obj,gp_port_mgr,
+                       p_bfi->p_port_mgr_obj) );
+
+       BUS_PRINT( BUS_DBG_PNP,
+                               ("%s(%s) Mark all IPoIB PDOs as no longer present\n",
+                               __FUNCTION__, p_bfi->whoami));
        /*
         * Mark all IPoIB PDOs as no longer present.  This will cause them
         * to be removed when they process the IRP_MN_REMOVE_DEVICE.
@@ -387,8 +435,11 @@
                {
                        CL_ASSERT( !p_ext->b_present );
                        p_ext->b_reported_missing = TRUE;
-                       BUS_TRACE( BUS_DBG_PNP, ("%s: PDO %p, ext %p, present %d, missing %d .\n",
-                               p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext, p_ext->b_present, p_ext->b_reported_missing ) );
+                       BUS_TRACE( BUS_DBG_PNP,
+                               ("%s %s: PDO %p, ext %p, present %d, missing %d .\n",
+                               p_bfi->whoami,
+                               p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do,
+                               p_ext, p_ext->b_present, p_ext->b_reported_missing ) );
                        continue;
                }
                if( p_ext->h_ca )
@@ -400,15 +451,21 @@
                        /* Release the reference on the CA object. */
                        deref_al_obj( &p_ext->h_ca->obj );
                }
-               BUS_TRACE( BUS_DBG_PNP, ("Deleted device %s: PDO %p, ext %p\n",
-                       p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext ) );
+
+               BUS_TRACE( BUS_DBG_PNP, ("%s Deleted device %s: PDO %p, ext %p\n",
+                                       p_bfi->whoami, p_ext->cl_ext.vfptr_pnp_po->identity,
+                                       p_ext->cl_ext.p_self_do, p_ext ) );
+
                IoDeleteDevice( p_ext->cl_ext.p_self_do );
        }

        cl_mutex_destroy( &gp_port_mgr->pdo_mutex );
        cl_obj_deinit( p_obj );
        cl_free( gp_port_mgr );
-       gp_port_mgr = NULL;
+
+       p_bfi->p_port_mgr = NULL;
+       p_bfi->p_port_mgr_obj = NULL;
+
        BUS_EXIT( BUS_DBG_PNP );
 }

@@ -417,22 +474,26 @@
  * Register the load service for the given PnP class events.
  */
 ib_api_status_t
-bus_reg_port_pnp( void )
+bus_reg_port_pnp( IN bus_filter_t *p_bfi )
 {
        ib_pnp_req_t                    pnp_req;
-       ib_api_status_t                 status;
+       ib_api_status_t                 status = IB_SUCCESS;

-       cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) );
-       pnp_req.pnp_class       = IB_PNP_PORT | IB_PNP_FLAG_REG_SYNC;
-       pnp_req.pnp_context = gp_port_mgr;
-       pnp_req.pfn_pnp_cb      = port_mgr_pnp_cb;
-
-       status = ib_reg_pnp( gh_al, &pnp_req, &gp_port_mgr->h_pnp );
-
-       if( status == IB_SUCCESS )
-       {
-               /* Reference the load service on behalf of the ib_reg_pnp call. */
-               cl_obj_ref( &gp_port_mgr->obj );
+       /* only need to register for port PNP events once */
+       ExAcquireFastMutexUnsafe(&ControlMutex);
+       if ( !bus_globals.h_pnp_port ) {
+               cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) );
+               pnp_req.pnp_class       = IB_PNP_PORT | IB_PNP_FLAG_REG_SYNC;
+               pnp_req.pnp_context = NULL;
+               pnp_req.pfn_pnp_cb      = port_mgr_pnp_cb;
+
+               status = ib_reg_pnp( gh_al, &pnp_req, &bus_globals.h_pnp_port );
+       }
+       ExReleaseFastMutexUnsafe(&ControlMutex);
+
+       if( status == IB_SUCCESS ) {
+               /* Reference this bus filter's port load service */
+               cl_obj_ref( &p_bfi->p_port_mgr->obj );
        }

        return status;
@@ -446,12 +507,11 @@
 port_mgr_pnp_cb(
        IN                              ib_pnp_rec_t*                           p_pnp_rec )
 {
-       ib_api_status_t         status;
+       ib_api_status_t         status=IB_SUCCESS;

        BUS_ENTER( BUS_DBG_PNP );

        CL_ASSERT( p_pnp_rec );
-       CL_ASSERT( gp_port_mgr == p_pnp_rec->pnp_context );

        switch( p_pnp_rec->pnp_event )
        {
@@ -461,12 +521,15 @@

        case IB_PNP_PORT_REMOVE:
                port_mgr_port_remove( (ib_pnp_port_rec_t*)p_pnp_rec );
+               break;

        default:
-               status = IB_SUCCESS;
+               XBUS_PRINT( BUS_DBG_PNP, ("%s() Unhandled PNP Event %s\n",
+                                       __FUNCTION__, ib_get_pnp_event_str(p_pnp_rec->pnp_event) ));
                break;
        }
        BUS_EXIT( BUS_DBG_PNP );
+
        return status;
 }

@@ -480,9 +543,50 @@
        IN                              IRP* const                                      p_irp )
 {
        NTSTATUS                        status;
+       bus_filter_t            *p_bfi;
+       port_mgr_t                      *gp_port_mgr;
+       DEVICE_RELATIONS        *p_rel;

        BUS_ENTER( BUS_DBG_PNP );

+       BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid %I64x\n",__FUNCTION__,ca_guid));
+
+       /* special case guid == 0 - walk all bus filter instances */
+       if ( ca_guid == 0ULL ) {
+               for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) {
+                       gp_port_mgr = p_bfi->p_port_mgr;
+                       if ( !gp_port_mgr )
+                               continue;
+                       cl_mutex_acquire( &gp_port_mgr->pdo_mutex );
+                       status = bus_get_relations( &gp_port_mgr->port_list,
+                                                                               ca_guid,
+                                                                               p_irp );
+                       cl_mutex_release( &gp_port_mgr->pdo_mutex );
+               }
+
+               p_rel = (DEVICE_RELATIONS*)p_irp->IoStatus.Information;
+               if ( p_rel ) {
+                       BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid 0 Reports %d\n",
+                                               __FUNCTION__,p_rel->Count));
+               }
+               BUS_EXIT( BUS_DBG_PNP );
+               return STATUS_SUCCESS;
+       }
+
+       p_bfi = get_bfi_by_ca_guid(ca_guid);
+       if (p_bfi == NULL) {
+               BUS_PRINT(BUS_DBG_PNP,
+                       ("%s() Null *p_bfi from ca_guid %I64x\n",__FUNCTION__,ca_guid));
+               BUS_EXIT( BUS_DBG_PNP );
+               return STATUS_NO_SUCH_DEVICE;
+       }
+       gp_port_mgr = p_bfi->p_port_mgr;
+
+       BUS_PRINT(BUS_DBG_PNP, ("%s(%s) for ca_guid %I64x port_mgr %p\n",
+                               __FUNCTION__, p_bfi->whoami, ca_guid, gp_port_mgr) );
+       if (!gp_port_mgr)
+               return STATUS_NO_SUCH_DEVICE;
+
        cl_mutex_acquire( &gp_port_mgr->pdo_mutex );
        status = bus_get_relations( &gp_port_mgr->port_list, ca_guid, p_irp );
        cl_mutex_release( &gp_port_mgr->pdo_mutex );
@@ -493,14 +597,17 @@

 static ib_api_status_t
 __port_was_hibernated(
-       IN                              ib_pnp_port_rec_t*                      p_pnp_rec )
+       IN                              ib_pnp_port_rec_t*                      p_pnp_rec,
+       IN                              bus_filter_t*                           p_bfi )
 {
        NTSTATUS                status;
-       cl_list_item_t          *p_list_item;
+       cl_list_item_t  *p_list_item;
        bus_port_ext_t  *p_port_ext;
        bus_pdo_ext_t   *p_pdo_ext = NULL;
        size_t                  n_devs = 0;
-       cl_qlist_t*             p_pdo_list = &gp_port_mgr->port_list;
+       port_mgr_t              *gp_port_mgr = p_bfi->p_port_mgr;
+       cl_qlist_t              *p_pdo_list = &gp_port_mgr->port_list;
+       port_pnp_ctx_t  *p_ctx = p_pnp_rec->pnp_rec.context;

        BUS_ENTER( BUS_DBG_PNP );

@@ -521,9 +628,11 @@
                        break;
                }

-               BUS_TRACE( BUS_DBG_PNP,
-                       ("Skipped PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n",
-                       p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do,
+               BUS_TRACE( BUS_DBG_PNP, ("%s Skipped PDO for %s: PDO %p, ext %p, "
+                       "present %d, missing %d, hibernating %d, port_guid %I64x.\n",
+                       p_bfi->whoami,
+                       p_pdo_ext->cl_ext.vfptr_pnp_po->identity,
+                       p_pdo_ext->cl_ext.p_self_do,
                        p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing,
                        p_pdo_ext->b_hibernating, p_port_ext->port_guid.guid  ) );
        }
@@ -534,27 +643,33 @@
                p_pdo_ext->h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid );
                if( !p_pdo_ext->h_ca )
                {
-                       BUS_TRACE( BUS_DBG_ERROR, ("acquire_ca failed to find CA by guid %I64x\n",
-                               p_pnp_rec->p_ca_attr->ca_guid ) );
+                       BUS_TRACE( BUS_DBG_ERROR,
+                               ("%s acquire_ca failed to find CA by guid %I64x\n",
+                               p_bfi->whoami, p_pnp_rec->p_ca_attr->ca_guid ) );
                        status = IB_INVALID_GUID;
                }
                else
                {
                        p_pdo_ext->b_hibernating = FALSE;
-                       p_pnp_rec->pnp_rec.context = p_pdo_ext;
+
+                       CL_ASSERT( p_ctx );
+                       p_ctx->p_pdo_ext = p_pdo_ext; // save for port_mgr_port_remove
+
                        status = IB_SUCCESS;
                        p_port_ext = (bus_port_ext_t*)p_pdo_ext;
-                       BUS_TRACE( BUS_DBG_PNP,
-                               ("Found PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n",
-                               p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do,
+                       BUS_TRACE( BUS_DBG_PNP, ("%s Found PDO for %s: PDO %p, ext %p, "
+                               "present %d, missing %d, hibernating %d, port_guid %I64x.\n",
+                               p_bfi->whoami,
+                               p_pdo_ext->cl_ext.vfptr_pnp_po->identity,
+                               p_pdo_ext->cl_ext.p_self_do,
                                p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing,
                                p_pdo_ext->b_hibernating, p_port_ext->port_guid.guid ) );
                }
        }
        else
        {
-               BUS_TRACE( BUS_DBG_PNP, ("Failed to find PDO for guid  %I64x .\n",
-                       p_pnp_rec->p_ca_attr->ca_guid ) );
+               BUS_TRACE( BUS_DBG_PNP, ("%s Failed to find PDO for guid  %I64x .\n",
+                                       p_bfi->whoami, p_pnp_rec->p_ca_attr->ca_guid ) );
                status = IB_NOT_FOUND;
        }

@@ -564,6 +679,71 @@
        return status;
 }

+#if DBG
+
+void
+dump_pnp_port_rec( ib_pnp_port_rec_t*  pr )
+{
+       BUS_PRINT( BUS_DBG_PNP, ("%s() ib_pnp_port_rec_t* @ %p\nib_pnp_rec_t*:\n",
+                               __FUNCTION__,pr));
+
+
+       BUS_PRINT( BUS_DBG_PNP, ("  Event %s\n",
+                               ib_get_pnp_event_str(pr->pnp_rec.pnp_event) ));
+
+       BUS_PRINT( BUS_DBG_PNP, ("  pnp_context %p\n",pr->pnp_rec.pnp_context));
+       BUS_PRINT( BUS_DBG_PNP, ("  context %p\n",pr->pnp_rec.context));
+       BUS_PRINT( BUS_DBG_PNP, ("  guid %I64x\n",pr->pnp_rec.guid));
+       BUS_PRINT( BUS_DBG_PNP, ("  ca_guid %I64x\n",pr->pnp_rec.ca_guid));
+
+       if ( !pr->p_ca_attr ) {
+               BUS_PRINT( BUS_DBG_PNP, ("  NULL *p_ca_attr ?\n"));
+       }
+       else {
+               BUS_PRINT( BUS_DBG_PNP, ("*p_ca_attr\n"));
+               BUS_PRINT( BUS_DBG_PNP, ("  ca_guid 0x%I64x\n",
+                                                               pr->p_ca_attr->ca_guid ) );
+       }
+       if ( !pr->p_port_attr ) {
+               BUS_PRINT( BUS_DBG_PNP, ("  NULL *p_port_attr?\n"));
+       }
+       else {
+               BUS_PRINT( BUS_DBG_PNP, ("*p_port_attr:\n"));
+               BUS_PRINT( BUS_DBG_PNP, ("  port_guid 0x%I64x port_num %d\n",
+                                                               pr->p_port_attr->port_guid,
+                                                               pr->p_port_attr->port_num ));
+       }
+}
+
+void
+dump_pnp_iou_rec( ib_pnp_iou_rec_t*    pr )
+{
+       BUS_PRINT( BUS_DBG_PNP, ("%s() ib_pnp_iou_rec_t* @ %p\nib_pnp_rec_t*:\n",
+                               __FUNCTION__,pr));
+
+
+       BUS_PRINT( BUS_DBG_PNP, ("  Event %s\n",
+                               ib_get_pnp_event_str(pr->pnp_rec.pnp_event) ));
+
+       BUS_PRINT( BUS_DBG_PNP, ("  pnp_context %p\n",pr->pnp_rec.pnp_context));
+       BUS_PRINT( BUS_DBG_PNP, ("  context %p\n",pr->pnp_rec.context));
+       BUS_PRINT( BUS_DBG_PNP, ("  guid %I64x\n",pr->pnp_rec.guid));
+       BUS_PRINT( BUS_DBG_PNP, ("  ca_guid %I64x\n",pr->pnp_rec.ca_guid));
+
+       BUS_PRINT( BUS_DBG_PNP, ("pnp_iou_rec_t:\n" ));
+       BUS_PRINT( BUS_DBG_PNP,
+                               ("  guid 0x%I64x\n  ca_guid %I64x\n  chassis_guid %I64x\n",
+                               pr->guid, pr->ca_guid, pr->chassis_guid ));
+       BUS_PRINT( BUS_DBG_PNP,
+                               ("  slot 0x%x\n  vend_id 0x%x\n  dev_id 0x%x  revision 0x%x\n",
+                               pr->slot, pr->vend_id, pr->dev_id, pr->revision ));
+       if ( pr->desc[0] ) {
+               BUS_PRINT( BUS_DBG_PNP, ("  Desc %s\n",pr->desc ));
+       }
+}
+#endif
+
+
 ib_api_status_t
 port_mgr_port_add(
        IN                              ib_pnp_port_rec_t*                      p_pnp_rec )
@@ -573,18 +753,56 @@
     uint8_t         num_pdo;
        bus_port_ext_t  *p_port_ext;
        ib_net16_t      pdo_cnt;
+       bus_filter_t    *p_bfi;
+       port_mgr_t              *gp_port_mgr;
+       port_pnp_ctx_t  *p_ctx = p_pnp_rec->pnp_rec.context;
+
        BUS_ENTER( BUS_DBG_PNP );

+       CL_ASSERT( p_pnp_rec->p_ca_attr->ca_guid );
+
+       p_bfi = get_set_bfi_by_ca_guid( p_pnp_rec->p_ca_attr->ca_guid );
+       if ( !p_bfi ) {
+               BUS_TRACE_EXIT( BUS_DBG_PNP,("%s() NULL p_bfi? ca_guid 0x%I64x\n",
+                                                               __FUNCTION__, p_pnp_rec->p_ca_attr->ca_guid ) );
+               return IB_ERROR;
+       }
+
+       /*
+        * Allocate a PNP context for this object. pnp_rec.context is obj unique.
+        */
+       if ( !p_ctx ) {
+               p_ctx = cl_zalloc( sizeof(*p_ctx) );
+               if( !p_ctx )
+               {
+                       BUS_TRACE_EXIT(BUS_DBG_PNP,
+                                       ("%s(%s) ca_guid %I64x port(%d) BAD alloc PNP context\n",
+                                       __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid,
+                                       p_pnp_rec->p_port_attr->port_num));
+                       return IB_ERROR;
+               }
+               p_ctx->p_bus_filter = p_bfi;
+               p_ctx->port_num = p_pnp_rec->p_port_attr->port_num;
+               p_pnp_rec->pnp_rec.context = p_ctx;
+
+               BUS_PRINT(BUS_DBG_PNP,
+                                       ("%s(%s) ca_guid %I64x port %d ALLOC p_ctx @ %p\n",
+                                       __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid,
+                                       p_pnp_rec->p_port_attr->port_num,p_ctx));
+       }
+       gp_port_mgr = p_bfi->p_port_mgr;
+
        if( !bus_globals.b_report_port_nic )
        {
                BUS_EXIT( BUS_DBG_PNP );
                return IB_NOT_DONE;
        }

-       /* Upon hibernating of the computer IB_BUS driver doesn't remove PDO, but
+       /* Upon hibernating the computer IB_BUS driver doesn't remove PDO, but
           marks with a flag. So we first try to find an existing PDO for this port,
-          marked with this flag. If it was found, we turn off the flag and use this PDO */
-       status = __port_was_hibernated(p_pnp_rec);
+          marked with this flag. If it was found, we turn off the flag and use
+          this PDO */
+       status = __port_was_hibernated( p_pnp_rec, p_bfi );
        if( status != IB_NOT_FOUND )
        {
                BUS_EXIT( BUS_DBG_PNP );
@@ -600,73 +818,82 @@

     for (num_pdo = 0; num_pdo < pdo_cnt; num_pdo++)
     {
-       /* Create the PDO for the new port device. */
-       status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_port_ext_t),
-               NULL, FILE_DEVICE_CONTROLLER,
-               FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,
-                       FALSE, &p_pdo[num_pdo] );
-       if( !NT_SUCCESS( status ) )
-       {
-               BUS_TRACE_EXIT( BUS_DBG_ERROR,
-                       ("IoCreateDevice returned %08x.\n", status) );
-               return IB_ERROR;
-       }
+               /* Create the PDO for the new port device. */
+               status = IoCreateDevice( bus_globals.p_driver_obj,
+                                                                sizeof(bus_port_ext_t),
+                                                                NULL, FILE_DEVICE_CONTROLLER,
+                                                                FILE_DEVICE_SECURE_OPEN |
+                                                                                       FILE_AUTOGENERATED_DEVICE_NAME,
+                                                                FALSE, &p_pdo[num_pdo] );
+               if( !NT_SUCCESS( status ) )
+               {
+                       BUS_TRACE_EXIT( BUS_DBG_ERROR,
+                               ("IoCreateDevice returned %08x.\n", status) );
+                       return IB_ERROR;
+               }

-       /* Initialize the device extension. */
-               cl_init_pnp_po_ext( p_pdo[num_pdo], NULL, p_pdo[num_pdo], bus_globals.dbg_lvl,
-               &vfptr_port_pnp, &vfptr_port_query_txt );
+               /* Initialize the device extension. */
+               cl_init_pnp_po_ext( p_pdo[num_pdo], NULL, p_pdo[num_pdo],
+                                                       bus_globals.dbg_lvl, &vfptr_port_pnp,
+                                                       &vfptr_port_query_txt );

-       /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */
+               /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */
                p_pdo[num_pdo]->Flags |= DO_BUS_ENUMERATED_DEVICE;

                p_port_ext = p_pdo[num_pdo]->DeviceExtension;
-       p_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;
-       p_port_ext->pdo.p_parent_ext = bus_globals.p_bus_ext;
-       p_port_ext->pdo.b_present = TRUE;
-       p_port_ext->pdo.b_reported_missing = FALSE;
-       p_port_ext->pdo.b_hibernating = FALSE;
-       p_port_ext->pdo.p_po_work_item = NULL;
-       BUS_TRACE( BUS_DBG_PNP, ("Created device for %s: PDO %p,ext %p, present %d, missing %d .\n",
-                       p_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[num_pdo], p_port_ext, p_port_ext->pdo.b_present,
-               p_port_ext->pdo.b_reported_missing ) );
+               p_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;
+               p_port_ext->pdo.p_parent_ext = p_bfi->p_bus_ext;
+               p_port_ext->pdo.b_present = TRUE;
+               p_port_ext->pdo.b_reported_missing = FALSE;
+               p_port_ext->pdo.b_hibernating = FALSE;
+               p_port_ext->pdo.p_po_work_item = NULL;
+               BUS_TRACE( BUS_DBG_PNP,
+                       ("Created %s %s: PDO %p,ext %p, present %d, missing %d .\n",
+                       p_bfi->whoami,
+                       p_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[num_pdo],
+                       p_port_ext, p_port_ext->pdo.b_present,
+                       p_port_ext->pdo.b_reported_missing ) );

-       /* Cache the CA GUID. */
-       p_port_ext->pdo.ca_guid = p_pnp_rec->p_ca_attr->ca_guid;
+               /* Cache the CA GUID. */
+               p_port_ext->pdo.ca_guid = p_pnp_rec->p_ca_attr->ca_guid;

-       /* Take a reference on the parent HCA. */
+               /* Take a reference on the parent HCA. */
                if(num_pdo > 0)
                {
                        p_port_ext->pdo.h_ca = ((bus_port_ext_t*)p_pdo[0]->DeviceExtension)->pdo.h_ca;
                }
                else
-       p_port_ext->pdo.h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid );
-       if( !p_port_ext->pdo.h_ca )
-       {
+                       p_port_ext->pdo.h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid );
+
+               if( !p_port_ext->pdo.h_ca )
+               {
                        BUS_TRACE( BUS_DBG_PNP, ("Deleted device: PDO %p\n", p_pdo[num_pdo]));
                        IoDeleteDevice( p_pdo[num_pdo]);
-               BUS_TRACE_EXIT( BUS_DBG_ERROR, ("acquire_ca failed to find CA.\n") );
-               return IB_INVALID_GUID;
-       }
+                       BUS_TRACE_EXIT( BUS_DBG_ERROR, ("acquire_ca failed to find CA.\n") );
+                       return IB_INVALID_GUID;
+               }
                p_port_ext->port_guid.guid = p_pnp_rec->p_port_attr->port_guid;
-       p_port_ext->n_port = p_pnp_rec->p_port_attr->port_num;
+               p_port_ext->n_port = p_pnp_rec->p_port_attr->port_num;
                p_port_ext->port_guid.pkey = IB_DEFAULT_PKEY;
+               p_port_ext->n_ifc_ref = 0;

                if(num_pdo > 0)
                {
                  p_port_ext->port_guid.pkey = g_pkeys.pkey_array[num_pdo -1];
                }
-       /* Store the device extension in the port vector for future queries. */
-       cl_mutex_acquire( &gp_port_mgr->pdo_mutex );
-       cl_qlist_insert_tail( &gp_port_mgr->port_list,
-               &p_port_ext->pdo.list_item );
-       cl_mutex_release( &gp_port_mgr->pdo_mutex );

-       /*
-        * Set the context of the PNP event.  The context is passed in for future
-        * events on the same port.
-        */
+               /* Store the device extension in the port vector for future queries. */
+               cl_mutex_acquire( &gp_port_mgr->pdo_mutex );
+               cl_qlist_insert_tail( &gp_port_mgr->port_list,
+                                                         &p_port_ext->pdo.list_item );
+               cl_mutex_release( &gp_port_mgr->pdo_mutex );
+
+               /*
+                * save the port_ext, as the context is passed in for future events on
+                * the same port.
+                */
                if(num_pdo == 0)
-                       p_pnp_rec->pnp_rec.context = p_port_ext;
+                       p_ctx->p_pdo_ext = p_port_ext;
        }
        pkeys_enumerated = TRUE;

@@ -674,10 +901,6 @@
        IoInvalidateDeviceRelations(
                p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );

-       /* Invalidate removal relations for the bus driver. */
-       IoInvalidateDeviceRelations(
-               bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations );
-
        BUS_EXIT( BUS_DBG_PNP );
        return IB_SUCCESS;
 }
@@ -689,7 +912,9 @@
 * output:      none
 * return:      cl_status
 *************************************************************************************/
-cl_status_t port_mgr_pkey_add(pkey_array_t *pkeys)
+cl_status_t _port_mgr_pkey_add ( IN    pkey_array_t    *pkeys,
+                                                                IN     bus_filter_t    *p_bfi,
+                                                                IN     port_mgr_t              *gp_port_mgr )
 {
        uint16_t                        cnt;
        NTSTATUS            status;
@@ -697,12 +922,13 @@
        bus_port_ext_t          *p_port_ext, *pkey_port_ext;
        DEVICE_OBJECT       *p_pdo[MAX_NUM_PKEY];
        bus_pdo_ext_t           *p_pdo_ext = NULL;
-       cl_qlist_t*                     p_pdo_list = &gp_port_mgr->port_list;
+       cl_qlist_t*                     p_pdo_list;

        BUS_ENTER( BUS_DBG_PNP );

        p_port_ext = NULL;
        cl_mutex_acquire( &gp_port_mgr->pdo_mutex );
+       p_pdo_list = &gp_port_mgr->port_list;

        /* Count the number of child devices. */
        for( p_list_item = cl_qlist_head( p_pdo_list );
@@ -720,18 +946,19 @@
        if (!p_port_ext)
        {
                BUS_TRACE_EXIT( BUS_DBG_ERROR,
-                       ("No existed pdo found.\n") );
+                       ("No existing pdo found.\n") );
                return CL_ERROR;
        }

     for (cnt = 0; cnt < pkeys->pkey_num; cnt++)
     {
-
                /* Create the PDO for the new port device. */
-               status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_port_ext_t),
-                       NULL, FILE_DEVICE_CONTROLLER,
-                       FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,
-                       FALSE, &p_pdo[cnt] );
+               status = IoCreateDevice( bus_globals.p_driver_obj,
+                                                                sizeof(bus_port_ext_t),
+                                                                NULL, FILE_DEVICE_CONTROLLER,
+                                                                FILE_DEVICE_SECURE_OPEN
+                                                                                       | FILE_AUTOGENERATED_DEVICE_NAME,
+                                                                FALSE, &p_pdo[cnt] );
                if( !NT_SUCCESS( status ) )
                {
                        BUS_TRACE_EXIT( BUS_DBG_ERROR,
@@ -741,20 +968,22 @@

                /* Initialize the device extension. */
                cl_init_pnp_po_ext( p_pdo[cnt], NULL, p_pdo[cnt], bus_globals.dbg_lvl,
-                       &vfptr_port_pnp, &vfptr_port_query_txt );
+                                                       &vfptr_port_pnp, &vfptr_port_query_txt );

                /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */
                p_pdo[cnt]->Flags |= DO_BUS_ENUMERATED_DEVICE;

                pkey_port_ext = p_pdo[cnt]->DeviceExtension;
                pkey_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;
-               pkey_port_ext->pdo.p_parent_ext = bus_globals.p_bus_ext;
+               pkey_port_ext->pdo.p_parent_ext = p_bfi->p_bus_ext;
                pkey_port_ext->pdo.b_present = TRUE;
                pkey_port_ext->pdo.b_reported_missing = FALSE;
                pkey_port_ext->pdo.b_hibernating = FALSE;
                pkey_port_ext->pdo.p_po_work_item = NULL;
-               BUS_TRACE( BUS_DBG_PNP, ("Created device for %s: PDO %p,ext %p, present %d, missing %d .\n",
-                       pkey_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[cnt], pkey_port_ext, pkey_port_ext->pdo.b_present,
+               BUS_TRACE( BUS_DBG_PNP,
+                       ("Created device for %s: PDO %p,ext %p, present %d, missing %d\n",
+                       pkey_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[cnt],
+                       pkey_port_ext, pkey_port_ext->pdo.b_present,
                        pkey_port_ext->pdo.b_reported_missing ) );

                /* Cache the CA GUID. */
@@ -775,25 +1004,81 @@
        IoInvalidateDeviceRelations(
                p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );

-       /* Invalidate removal relations for the bus driver. */
-       IoInvalidateDeviceRelations(
-               bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations );
-
        BUS_EXIT( BUS_DBG_PNP );
        return CL_SUCCESS;
 }

+
+cl_status_t port_mgr_pkey_add(pkey_array_t *pkeys)
+{
+       bus_filter_t    *p_bfi;
+       cl_status_t             status;
+       boolean_t               GO;
+       int                             success_cnt=0;
+
+       for(p_bfi=&bus_filters[0]; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++)
+       {
+               if ( !p_bfi->p_bus_ext )
+                       continue;
+               GO = FALSE;
+               ExAcquireFastMutexUnsafe(&ControlMutex);
+               if ( p_bfi->ca_guid && p_bfi->p_port_mgr )
+                       GO = TRUE;
+               ExReleaseFastMutexUnsafe(&ControlMutex);
+               if ( GO == FALSE )
+                       continue;
+               status = _port_mgr_pkey_add( pkeys, p_bfi, p_bfi->p_port_mgr );
+               if ( status == CL_SUCCESS )
+                       success_cnt++;
+       }
+       return ( success_cnt ? CL_SUCCESS : CL_ERROR );
+}
+
+
 void
 port_mgr_port_remove(
-       IN                              ib_pnp_port_rec_t*                      p_pnp_rec )
+       IN                              ib_pnp_port_rec_t*              p_pnp_rec )
 {
        bus_pdo_ext_t   *p_ext;
+       port_mgr_t              *gp_port_mgr;
+       bus_filter_t    *p_bfi;
+       port_pnp_ctx_t  *p_ctx = p_pnp_rec->pnp_rec.context;

        BUS_ENTER( BUS_DBG_PNP );

-       /* The PNP record's context is the port extension. */
-       p_ext = p_pnp_rec->pnp_rec.context;
+       if ( !p_ctx ) {
+               BUS_EXIT( BUS_DBG_PNP );
+               return;
+       }
+
+       CL_ASSERT( p_ctx->p_bus_filter->magic == BFI_MAGIC );
+       p_bfi = p_ctx->p_bus_filter;
+       CL_ASSERT( p_bfi );
+
+       BUS_PRINT(BUS_DBG_PNP,("%s(%s) ca_guid 0x%I64x port_num %d port_mgr %p\n",
+                                               __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid,
+                                               p_ctx->port_num, p_bfi->p_port_mgr));
+
+       /* in the process of device remove, port_mgr has been destroyed.
+        * cleanup allocated PNP port context; one per port.
+        * The issue is the PNP PORT_REMOVE event occurs after
+        * fdo_release_resources() completes.
+        */
+       if ( p_bfi->ca_guid == 0ULL || !p_bfi->p_port_mgr ) {
+               cl_free( p_ctx );
+               p_pnp_rec->pnp_rec.context = NULL;
+               BUS_EXIT( BUS_DBG_PNP );
+               return;
+       }
+
+       gp_port_mgr = p_bfi->p_port_mgr;
+
+       /* Within the PNP record's context is the port extension ptr;
+        * see port_was_hibernated().
+        */
+       p_ext = p_ctx->p_pdo_ext;
        CL_ASSERT( p_ext );
+       CL_ASSERT(p_bfi == p_ext->p_parent_ext->bus_filter);

        /*
         * Flag the port PDO as no longer being present.  We have to wait until
@@ -801,32 +1086,44 @@
         * reference on the CA object in order to allow the removal of the HCA
         * to proceed should it occur before the port's PDO is cleaned up.
         */
+       if ( !p_ext->h_ca )
+       {
+               BUS_TRACE_EXIT( BUS_DBG_PNP, ("%s() %s NULL h_ca? p_ext %p\n",
+                                       __FUNCTION__, p_bfi->whoami, p_ext ) );
+               return;
+       }
+
        cl_mutex_acquire( &gp_port_mgr->pdo_mutex );
        CL_ASSERT( p_ext->h_ca );

        if( p_ext->b_hibernating )
        {
-               BUS_TRACE( BUS_DBG_PNP, ("Skip port removing for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d .\n",
-                       p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext, p_ext->b_present,
-                       p_ext->b_reported_missing, p_ext->b_hibernating ) );
+               BUS_TRACE( BUS_DBG_PNP, ("Skip port removing for %s: PDO %p, ext %p, "
+                       "present %d, missing %d, hibernating %d .\n",
+                       p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do,
+                       p_ext, p_ext->b_present, p_ext->b_reported_missing,
+                       p_ext->b_hibernating ) );
                goto hca_deref;
        }

        p_ext->b_present = FALSE;
-       BUS_TRACE( BUS_DBG_PNP, ("Mark removing %s: PDO %p, ext %p, present %d, missing %d .\n",
-               p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext, p_ext->b_present, p_ext->b_reported_missing ) );
+       p_ext->b_reported_missing = TRUE;

-       /* Invalidate removal relations for the bus driver. */
-       IoInvalidateDeviceRelations( bus_globals.p_bus_ext->cl_ext.p_pdo,
-               RemovalRelations );
+       BUS_TRACE( BUS_DBG_PNP,
+               ("Mark removing %s: PDO %p, ext %p, present %d, missing %d .\n",
+               p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext,
+               p_ext->b_present, p_ext->b_reported_missing ) );

        /* Invalidate bus relations for the HCA. */
        IoInvalidateDeviceRelations(
                p_ext->h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );

+       /* Free PNP context memory */
+       cl_free( p_ctx );
+       p_pnp_rec->pnp_rec.context = NULL;
+
 hca_deref:
        deref_al_obj( &p_ext->h_ca->obj );
-       p_ext->h_ca = NULL;
        cl_mutex_release( &gp_port_mgr->pdo_mutex );

        BUS_EXIT( BUS_DBG_PNP );
@@ -850,7 +1147,9 @@
        /* Notify the Power Manager that the device is started. */
        PoSetPowerState( p_dev_obj, DevicePowerState, p_ext->dev_po_state );
        *p_action = IrpComplete;
+
        BUS_EXIT( BUS_DBG_PNP );
+
        return STATUS_SUCCESS;
 }

@@ -895,14 +1194,17 @@
 {
        bus_port_ext_t  *p_ext;
        POWER_STATE             po_state;
+       port_mgr_t              *gp_port_mgr;

        BUS_ENTER( BUS_DBG_PNP );

        p_ext = p_dev_obj->DeviceExtension;
+       gp_port_mgr = p_ext->pdo.p_parent_ext->bus_filter->p_port_mgr;

        /* Remove this PDO from its list. */
        cl_mutex_acquire( &gp_port_mgr->pdo_mutex );
-       BUS_TRACE( BUS_DBG_PNP, ("Removing port from vector: PDO %p, ext %p\n", p_dev_obj, p_ext) );
+       BUS_TRACE( BUS_DBG_PNP, ("Removing port from vector: PDO %p, ext %p\n",
+                               p_dev_obj, p_ext) );
        cl_qlist_remove_item( &gp_port_mgr->port_list, &p_ext->pdo.list_item );
        cl_mutex_release( &gp_port_mgr->pdo_mutex );
        po_state.DeviceState = PowerDeviceD3;
@@ -932,7 +1234,9 @@
                cl_set_pnp_state( &p_ext->pdo.cl_ext, NotStarted );
                /* Don't delete the device.  It may simply be disabled. */
                *p_action = IrpComplete;
-               BUS_TRACE_EXIT( BUS_DBG_PNP, ("Device still present: PDO %p, ext %p\n", p_dev_obj, p_ext) );
+               BUS_TRACE_EXIT( BUS_DBG_PNP,
+                               ("Device %s still present: PDO %p, ext %p\n",
+                               p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_dev_obj, p_ext) );
                return STATUS_SUCCESS;
        }

@@ -941,7 +1245,10 @@
                /* Reset the state to RemovePending.  Complib set it to Deleted. */
                cl_rollback_pnp_state( &p_ext->pdo.cl_ext );
                *p_action = IrpComplete;
-               BUS_TRACE_EXIT( BUS_DBG_PNP, ("Device not reported missing yet: PDO %p, ext %p\n", p_dev_obj, p_ext) );
+               BUS_TRACE_EXIT( BUS_DBG_PNP,
+                                               ("Device %s not reported missing yet: PDO %p, ext %p\n",
+                                               p_ext->pdo.cl_ext.vfptr_pnp_po->identity,
+                                               p_dev_obj, p_ext) );
                return STATUS_SUCCESS;
        }

@@ -956,7 +1263,9 @@
        IoCompleteRequest( p_irp, IO_NO_INCREMENT );

        BUS_TRACE( BUS_DBG_PNP, ("Deleted device %s: PDO %p(=%p), ext %p\n",
-               p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_ext->pdo.cl_ext.p_self_do, p_dev_obj, p_ext ) );
+               p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_ext->pdo.cl_ext.p_self_do,
+               p_dev_obj, p_ext ) );
+
        IoDeleteDevice( p_dev_obj );

        *p_action = IrpDoNothing;
@@ -1382,7 +1691,6 @@
        ipoib_ifc_data_t                *p_ipoib_data;
        bus_port_ext_t                  *p_ext;
        const GUID                              *p_guid;
-

        BUS_ENTER( BUS_DBG_PNP );

@@ -1472,9 +1780,7 @@

        BUS_ENTER( BUS_DBG_PNP );

-#pragma warning( push, 3 )
        PAGED_CODE();
-#pragma warning( pop )

        p_io_stack = IoGetCurrentIrpStackLocation( p_irp );

-------------- next part --------------
A non-text attachment was scrubbed...
Name: bus_port_mgr.c.pat
Type: application/octet-stream
Size: 32218 bytes
Desc: bus_port_mgr.c.pat
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20080818/35bff5b1/attachment.obj>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: bus_port_mgr.c
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20080818/35bff5b1/attachment.c>


More information about the ofw mailing list