[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