[CORE] ibbus as an upper class HCA filter
authorstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 25 Aug 2008 22:05:17 +0000 (22:05 +0000)
committerstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 25 Aug 2008 22:05:17 +0000 (22:05 +0000)
core/bus/kernel/bus_driver.c
core/bus/kernel/bus_driver.h
core/bus/kernel/bus_iou_mgr.c
core/bus/kernel/bus_iou_mgr.h
core/bus/kernel/bus_pnp.c
core/bus/kernel/bus_pnp.h
core/bus/kernel/bus_port_mgr.c
core/bus/kernel/bus_port_mgr.h
[HW]
hw/mlx4/kernel/hca/mlx4_hca.cdf
hw/mlx4/kernel/hca/mlx4_hca.inx
hw/mlx4/kernel/hca/mlx4_hca32.cdf
hw/mthca/kernel/mthca.cdf
hw/mthca/kernel/mthca.inx
hw/mthca/kernel/mthca32.cdf

etc/makebin.bat

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

15 files changed:
core/bus/kernel/bus_driver.c
core/bus/kernel/bus_driver.h
core/bus/kernel/bus_iou_mgr.c
core/bus/kernel/bus_iou_mgr.h
core/bus/kernel/bus_pnp.c
core/bus/kernel/bus_pnp.h
core/bus/kernel/bus_port_mgr.c
core/bus/kernel/bus_port_mgr.h
etc/makebin.bat
hw/mlx4/kernel/hca/mlx4_hca.cdf
hw/mlx4/kernel/hca/mlx4_hca.inx
hw/mlx4/kernel/hca/mlx4_hca32.cdf
hw/mthca/kernel/mthca.cdf
hw/mthca/kernel/mthca.inx
hw/mthca/kernel/mthca32.cdf [new file with mode: 0644]

index ba48792..3ece07a 100644 (file)
@@ -56,8 +56,8 @@
 #else\r
 #define DEFAULT_NODE_DESC      "OpenIB Windows® Host"\r
 #endif\r
-\r
-\r
+/* pkey array to be read */\r
+pkey_array_t  g_pkeys;\r
 \r
 char   node_desc[IB_NODE_DESCRIPTION_SIZE];\r
 \r
@@ -66,7 +66,7 @@ bus_globals_t bus_globals = {
        TRUE,\r
        NULL,\r
        NULL,\r
-       NULL,\r
+       NULL\r
 };\r
 \r
 static void\r
@@ -183,7 +183,6 @@ __read_machine_name( void )
                RtlStringCbCopyNA( node_desc, sizeof(node_desc),\r
                        DEFAULT_NODE_DESC, sizeof(DEFAULT_NODE_DESC) );\r
        }\r
-       BUS_EXIT( BUS_DBG_DRV );\r
 }\r
 /************************************************************************************\r
 * name :       __prepare_pKey_array\r
@@ -193,184 +192,144 @@ __read_machine_name( void )
 * output:      pkey_array\r
 * return:      uint16_t number of pkey(s) found\r
 *************************************************************************************/\r
-static void __prepare_pKey_array(IN const char *str, size_t str_len,OUT pkey_array_t *cur_pkey)\r
+static uint16_t\r
+__prepare_pKey_array(IN const UNICODE_STRING *str, OUT uint16_t *pkey_array)\r
 {\r
+       uint16_t i, num_pKeys, cur_pkey_length;\r
        NTSTATUS status;\r
-       size_t i;\r
-       uint8_t j;\r
-       char pkey_str[7];\r
-       ULONG   tmp_val;\r
+       ANSI_STRING ansi_str;\r
+       static const uint16_t PATTERN_LENGTH = 6;\r
        BUS_ENTER( BUS_DBG_DRV );\r
 \r
-       CL_ASSERT(cur_pkey);\r
+       CL_ASSERT(pkey_array);\r
        CL_ASSERT(str);\r
 \r
-       cur_pkey->pkey_num = 0;\r
-       j = 0;\r
-\r
-       for (i = 0; (i < str_len) && (cur_pkey->pkey_num < MAX_NUM_PKEY) ; i++)\r
-    {\r
-               if(str[i] == ' ')\r
-                       continue;\r
-\r
-               if( (str[i] != ',') && (str[i] != '\0'))\r
-               {\r
-                   if(j >= 7)\r
-                       {\r
-                               BUS_TRACE(BUS_DBG_ERROR ,\r
-                               ("Incorrect format of pkey value\n") );\r
-                               break;\r
-                       }\r
-                       pkey_str[j] = str[i];\r
-                       j++;\r
-               }\r
-               else\r
-               {\r
-                       pkey_str[j] = '\0';\r
-                       status = RtlCharToInteger(&pkey_str[2],16,&tmp_val);\r
-                       if(! NT_SUCCESS(status))\r
-                       {\r
-                               BUS_TRACE(BUS_DBG_ERROR ,\r
-                               ("Failed to convert, status = 0x%08X\n",status) );\r
-                               break;   \r
-                       }\r
-                       cur_pkey->pkey_array[cur_pkey->pkey_num++] = (uint16_t)tmp_val;\r
-                       j = 0;\r
-               }\r
-       }\r
-       BUS_EXIT( BUS_DBG_DRV );\r
-}\r
-\r
-static pkey_conf_t*\r
-create_pkey_conf(pkey_conf_t **pp_cur_conf, char *guid_str, uint32_t guid_str_len)\r
-{\r
-       NTSTATUS status;\r
-       char    tmp_char;\r
-       uint32_t tmp_val;\r
-\r
-       if (! *pp_cur_conf)\r
-               pp_cur_conf = &bus_globals.p_pkey_conf;\r
-       else\r
-               pp_cur_conf = &((*pp_cur_conf)->next_conf);\r
-\r
-       *pp_cur_conf = cl_zalloc( sizeof( pkey_conf_t ) );\r
-       if (!(*pp_cur_conf) )\r
-       {\r
-               BUS_TRACE(BUS_DBG_ERROR ,\r
-               ("Failed to allocate pkey configuration\n") );\r
-               return NULL;    \r
-       }\r
-\r
-       tmp_char = guid_str[1 + guid_str_len/2];\r
-       guid_str[1 + guid_str_len/2] = '\0';\r
-       status = RtlCharToInteger(&guid_str[2],16,(PULONG)&tmp_val);\r
-       if(! NT_SUCCESS(status))\r
-       {\r
-               cl_free((*pp_cur_conf));\r
-               (*pp_cur_conf) = NULL;\r
-               BUS_TRACE(BUS_DBG_ERROR ,\r
-               ("Failed to convert, status = 0x%08X\n",status) );\r
-               return NULL;    \r
-       }\r
-       guid_str[1 + guid_str_len/2] = tmp_char;\r
-       (*pp_cur_conf)->pkeys_per_port.port_guid = tmp_val;\r
-\r
-       status = RtlCharToInteger(&guid_str[1 + guid_str_len/2],16,(PULONG)&tmp_val);\r
-       if(! NT_SUCCESS(status))\r
-       {\r
-               cl_free((*pp_cur_conf));\r
-               (*pp_cur_conf) = NULL;\r
-               BUS_TRACE(BUS_DBG_ERROR ,\r
-               ("Failed to convert, status = 0x%08X\n",status) );\r
-               return NULL;    \r
-       }\r
-       (*pp_cur_conf)->pkeys_per_port.port_guid = ((*pp_cur_conf)->pkeys_per_port.port_guid << 32) | tmp_val;\r
-       return (*pp_cur_conf);\r
-}\r
-\r
-/************************************************************************\r
-* name:                __build_pkeys_per_port\r
-*                      extracts pkeys and port guids from registry string.\r
-*                      builds pkey array per port\r
-* input:       UNICODE_STRING *str\r
-* return:      NTSTATUS\r
-************************************************************************/\r
-static NTSTATUS\r
-__build_pkeys_per_port(IN const UNICODE_STRING *str)\r
-{\r
-       NTSTATUS    status;\r
-       ANSI_STRING ansi_str;\r
-       uint32_t i,j;\r
-       char *p_end, *p_start;\r
-       boolean_t       port_guid_found;\r
-       pkey_conf_t     *cur_pkey_conf = NULL;\r
-       char tmp_guid[32] = {'\0'};\r
-       p_start = NULL;\r
+       num_pKeys = 0;\r
+    cur_pkey_length = 0;\r
 \r
        status = RtlUnicodeStringToAnsiString(&ansi_str,str,TRUE);\r
        if(! NT_SUCCESS(status))\r
        {\r
                BUS_TRACE(BUS_DBG_ERROR ,\r
                ("RtlUnicodeStringToAnsiString returned 0x%.8x\n", status) );\r
-               return status;\r
+               return 0;\r
        }\r
-\r
-       port_guid_found = FALSE;\r
-       j = 0;\r
-       for ( i = 0; i < ansi_str.MaximumLength; i++)\r
-       {\r
-               if(! port_guid_found)\r
+       \r
+       for (i = 0; (i < ansi_str.MaximumLength) && (num_pKeys < MAX_NUM_PKEY) ; i++)\r
+    {\r
+               switch(ansi_str.Buffer[i])\r
                {\r
-                       if(ansi_str.Buffer[i] == ':')\r
+               case '0':\r
+                       cur_pkey_length++;\r
+                       if (((i+1) < ansi_str.Length) && ( ( ansi_str.Buffer[i+1] == 'x') || ( ansi_str.Buffer[i+1] == 'X')))\r
+                               break;\r
+                       else\r
+                       {\r
+                               pkey_array[num_pKeys] = \\r
+                               (pkey_array[num_pKeys] << 4)| 0;\r
+                               break;\r
+                       }\r
+\r
+               case 'x':\r
+               case 'X':\r
+                       cur_pkey_length++;\r
+                       break;\r
+\r
+               case ',':\r
+                       if(cur_pkey_length == PATTERN_LENGTH)\r
+                       {\r
+                               cur_pkey_length = 0;\r
+                               num_pKeys++;\r
+                       }\r
+                       break;\r
+\r
+               case 'A':\r
+               case 'a':\r
+                       pkey_array[num_pKeys] = \\r
+                       (pkey_array[num_pKeys] << 4)| 0xA;\r
+                       cur_pkey_length++;\r
+                       break;\r
+\r
+               case 'B':\r
+               case 'b':\r
+                       pkey_array[num_pKeys] = \\r
+                       (pkey_array[num_pKeys] << 4)| 0xB;\r
+                       cur_pkey_length++;\r
+                       break;\r
+\r
+               case 'C':\r
+               case 'c':\r
+                       pkey_array[num_pKeys] = \\r
+                       (pkey_array[num_pKeys] << 4)| 0xC;\r
+                       cur_pkey_length++;\r
+                       break;\r
+\r
+               case 'D':\r
+               case 'd':\r
+                       pkey_array[num_pKeys] = \\r
+                       (pkey_array[num_pKeys] << 4)| 0xD;\r
+                       cur_pkey_length++;\r
+                       break;\r
+\r
+               case 'E':\r
+               case 'e':\r
+                       pkey_array[num_pKeys] = \\r
+                       (pkey_array[num_pKeys] << 4)| 0xE;\r
+                       cur_pkey_length++;\r
+                       break;\r
+\r
+               case 'F':\r
+               case 'f':\r
+                       pkey_array[num_pKeys] = \\r
+                       (pkey_array[num_pKeys] << 4)| 0xF;\r
+                       cur_pkey_length++;\r
+                       break;\r
+\r
+               case '1':\r
+               case '2':\r
+               case '3':\r
+               case '4':\r
+               case '5':\r
+               case '6':\r
+               case '7':\r
+               case '8':\r
+               case '9':\r
+                       pkey_array[num_pKeys] = \\r
+                       (pkey_array[num_pKeys] << 4)| (ansi_str.Buffer[i] - '0');\r
+                       cur_pkey_length++;\r
+                       break;\r
+                       \r
+               case '\0':\r
+                       if(cur_pkey_length == PATTERN_LENGTH)\r
                        {\r
-                               port_guid_found = TRUE;\r
-                               tmp_guid[j] = '\0';\r
-                               cur_pkey_conf = create_pkey_conf(&cur_pkey_conf,(char*)tmp_guid,j);\r
-                               if(! cur_pkey_conf)\r
-                               {\r
-                                  RtlFreeAnsiString(&ansi_str);\r
-                                  BUS_TRACE(BUS_DBG_ERROR ,\r
-                                  ("Failed to create pkey configuration\n"));\r
-                                  return STATUS_INVALID_PARAMETER;\r
-                               }\r
-                           RtlZeroMemory(tmp_guid,sizeof(tmp_guid));\r
-                               j = 0;\r
-                               p_start = NULL;\r
+                               cur_pkey_length = 0;\r
+                               num_pKeys++;\r
                        }\r
                        else\r
                        {\r
-                               tmp_guid[j] = ansi_str.Buffer[i]; \r
-                               j++;\r
-                               continue;\r
+                               RtlFreeAnsiString(&ansi_str);\r
+                               return num_pKeys;\r
                        }\r
-               }\r
-               else\r
-               {\r
-                       if(!p_start)\r
-                               p_start = &ansi_str.Buffer[i]; \r
+                       break;\r
 \r
-                       if(ansi_str.Buffer[i] == ';')\r
-                       {\r
-                               p_end = &ansi_str.Buffer[i];\r
-                               ansi_str.Buffer[i] = '\0';\r
-                               __prepare_pKey_array(p_start,(size_t)(p_end - p_start) + 1,&cur_pkey_conf->pkeys_per_port);\r
+               default:\r
+                       break;\r
 \r
-                               ansi_str.Buffer[i] = ';';\r
-                               p_start = NULL;\r
-                               port_guid_found = FALSE;\r
-                       }\r
                }\r
        }\r
+\r
     RtlFreeAnsiString(&ansi_str);\r
-       return STATUS_SUCCESS;\r
+       BUS_EXIT( BUS_DBG_DRV );\r
+       return num_pKeys;\r
 }\r
+\r
 static NTSTATUS\r
 __read_registry(\r
        IN                              UNICODE_STRING* const           p_registry_path )\r
 {\r
        NTSTATUS                                        status;\r
        /* Remember the terminating entry in the table below. */\r
-       RTL_QUERY_REGISTRY_TABLE        table[12];\r
+       RTL_QUERY_REGISTRY_TABLE        table[10];\r
        UNICODE_STRING                          param_path;\r
        UNICODE_STRING                          pkeyString;\r
        UNICODE_STRING                          empty_string;\r
@@ -404,6 +363,8 @@ __read_registry(
         return STATUS_INSUFFICIENT_RESOURCES;\r
     }\r
 \r
+       cl_memclr(&g_pkeys,sizeof(pkey_array_t));\r
+\r
        /*\r
         * Clear the table.  This clears all the query callback pointers,\r
         * and sets up the terminating table entry.\r
@@ -474,19 +435,16 @@ __read_registry(
        table[8].DefaultType  = REG_SZ;\r
        table[8].DefaultData  = &empty_string;\r
        table[8].DefaultLength = 0;\r
-\r
        /* Have at it! */\r
        status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
                param_path.Buffer, table, NULL, NULL );\r
        if (NT_SUCCESS(status))\r
-       {\r
-                       if( !NT_SUCCESS(__build_pkeys_per_port(&pkeyString)))\r
-                               BUS_TRACE(BUS_DBG_ERROR ,\r
-                                                ("Failed to build pkey configuration\n"));\r
-       }\r
+                       g_pkeys.pkey_num = __prepare_pKey_array(&pkeyString, (uint16_t*)g_pkeys.pkey_array);\r
 #if DBG\r
        if( g_al_dbg_flags & AL_DBG_ERR )\r
                g_al_dbg_flags |= CL_DBG_ERROR;\r
+\r
+       bus_globals.dbg_lvl |= BUS_DBG_DRV | BUS_DBG_PNP;\r
 #endif\r
 \r
        BUS_TRACE(BUS_DBG_DRV ,\r
@@ -655,37 +613,6 @@ bus_add_pkey(cl_ioctl_handle_t                     h_ioctl)
        return status;\r
 }\r
 \r
-cl_status_t\r
-bus_rem_pkey(cl_ioctl_handle_t                 h_ioctl)\r
-{\r
-       cl_status_t                             status;\r
-       pkey_array_t                            *pkeys;\r
-       PIO_STACK_LOCATION                      pIoStack;\r
-\r
-       BUS_ENTER( BUS_DBG_DRV );\r
-\r
-       pIoStack = IoGetCurrentIrpStackLocation(h_ioctl);\r
-       if ( (! h_ioctl->AssociatedIrp.SystemBuffer) || \r
-                pIoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof (pkey_array_t))\r
-    {\r
-               BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
-                       ("Invalid parameters.\n") );\r
-               return CL_INVALID_PARAMETER;\r
-       }\r
-\r
-       pkeys =  (pkey_array_t*)h_ioctl->AssociatedIrp.SystemBuffer;\r
-\r
-       /* removes pdo */\r
-       status = port_mgr_pkey_rem(pkeys);\r
-       if (! NT_SUCCESS(status))\r
-       {\r
-               BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
-                       ("port_mgr_pkey_rem returned %08x.\n", status) );\r
-       }\r
-\r
-       BUS_EXIT( BUS_DBG_DRV );\r
-       return status;\r
-}\r
 static NTSTATUS\r
 bus_drv_sysctl(\r
        IN                              DEVICE_OBJECT                           *p_dev_obj,\r
@@ -721,21 +648,14 @@ static void
 bus_drv_unload(\r
        IN                              DRIVER_OBJECT                           *p_driver_obj )\r
 {\r
-       pkey_conf_t *cur_conf,*tmp;\r
        UNICODE_STRING           dos_name;\r
+       UNUSED_PARAM( p_driver_obj );\r
 \r
        BUS_ENTER( BUS_DBG_DRV );\r
        \r
        RtlInitUnicodeString( &dos_name, L"\\DosDevices\\Global\\ibal" );\r
-       UNUSED_PARAM( p_driver_obj );\r
        IoDeleteSymbolicLink( &dos_name );\r
-       cur_conf = bus_globals.p_pkey_conf;\r
-       while(cur_conf)\r
-       {\r
-               tmp = cur_conf;\r
-               cur_conf = cur_conf->next_conf;\r
-               cl_free(tmp);\r
-       }\r
+\r
        CL_DEINIT;\r
 \r
 #if defined(EVENT_TRACING)\r
@@ -752,7 +672,7 @@ DriverEntry(
        IN                              DRIVER_OBJECT                           *p_driver_obj,\r
        IN                              UNICODE_STRING                          *p_registry_path )\r
 {\r
-       NTSTATUS                        status;\r
+       NTSTATUS                status;\r
 \r
        BUS_ENTER( BUS_DBG_DRV );\r
 \r
@@ -792,6 +712,15 @@ DriverEntry(
        p_driver_obj->DriverUnload = bus_drv_unload;\r
        p_driver_obj->DriverExtension->AddDevice = bus_add_device;\r
 \r
+       // Mutex to synchronize multiple threads creating & deleting \r
+       // control deviceobjects. \r
+\r
+       ExInitializeFastMutex(&ControlMutex);\r
+       bfi_InstanceCount = 0;\r
+       memset(  __out_bcount(sizeof(bus_filters)) (void*)bus_filters, 0,\r
+                       sizeof(bus_filters) );\r
+\r
        BUS_EXIT( BUS_DBG_DRV );\r
        return STATUS_SUCCESS;\r
 }\r
+\r
index 3732b5b..e4ff16e 100644 (file)
@@ -45,7 +45,7 @@
 #include "iba/ib_al.h"\r
 #include "bus_port_mgr.h"\r
 #include "bus_iou_mgr.h"\r
-#include "al_dev.h"\r
+\r
 /* Safe string functions. */\r
 #if WINVER == 0x500\r
 /*\r
        CL_TRACE_EXIT( lvl, bus_globals.dbg_lvl, msg )\r
 \r
 #define BUS_PRINT( lvl, msg )          \\r
-       CL_PRINT( lvl, bus_globals.dbl_lvl, msg )\r
+       CL_PRINT( lvl, bus_globals.dbg_lvl, msg )\r
+\r
+/* single character Macro elemination */\r
+#define XBUS_PRINT( lvl, msg )\r
+#define XBUS_ENTER( lvl )\r
+#define XBUS_EXIT( lvl )\r
 \r
 #define BUS_DBG_ERROR  CL_DBG_ERROR\r
 #define BUS_DBG_DRV            (1 << 0)\r
@@ -93,7 +98,6 @@
  *             in the paging, crash dump, or hibernation path.\r
  */\r
 \r
-\r
 /*\r
  * Device extension for the device object that serves as entry point for \r
  * the interface and IOCTL requests.\r
@@ -112,15 +116,13 @@ typedef struct _bus_fdo_ext
        port_mgr_t                              *p_port_mgr;\r
        iou_mgr_t                               *p_iou_mgr;\r
 \r
-       /* Interface names are generated by IoRegisterDeviceInterface. */\r
-       UNICODE_STRING                  al_ifc_name;\r
-       UNICODE_STRING                  ci_ifc_name;\r
-\r
        /* Number of references on the upper interface. */\r
        atomic32_t                              n_al_ifc_ref;\r
        /* Number of references on the CI interface. */\r
        atomic32_t                              n_ci_ifc_ref;\r
 \r
+       struct _bus_filter_instance *bus_filter;\r
+\r
 }      bus_fdo_ext_t;\r
 \r
 \r
@@ -174,19 +176,13 @@ typedef struct _bus_pdo_ext
        boolean_t                               b_reported_missing;\r
 \r
        /* Flag to control the behaviour of the driver during hibernation */\r
-       uint32_t                                        b_hibernating;\r
+       uint32_t                                b_hibernating;\r
 \r
        /* work item for handling Power Management request */\r
        PIO_WORKITEM                    p_po_work_item;\r
-       boolean_t                           is_partition_pdo;\r
+       \r
 }      bus_pdo_ext_t;\r
 \r
-/* pkey configuration */\r
-typedef struct _pkey_conf_t\r
-{\r
-       pkey_array_t    pkeys_per_port;\r
-       struct _pkey_conf_t *next_conf;\r
-}pkey_conf_t;\r
 \r
 /*\r
  * Global Driver parameters.\r
@@ -202,15 +198,62 @@ typedef struct _bus_globals
        /* Driver object.  Used for registering of Plug and Play notifications. */\r
        DRIVER_OBJECT                   *p_driver_obj;\r
 \r
-       /* Pointer to the one and only bus root. */\r
-       bus_fdo_ext_t                   *p_bus_ext;\r
+       /* IBAL PNP event register handles */\r
+       ib_pnp_handle_t                 h_pnp_port;\r
+       ib_pnp_handle_t                 h_pnp_iou;\r
 \r
-       /* pkey array to be read */\r
-       pkey_conf_t                             *p_pkey_conf;\r
 }      bus_globals_t;\r
 \r
 \r
 extern bus_globals_t   bus_globals;\r
 \r
+/*\r
+ * Each instance of a bus filter on an HCA device stack (InfiniBandController)\r
+ * populates a bus_filter_t slot in bus_filters[MAX_BUS_FILTERS]; see\r
+ * bus_add_device(). Therefore MAX_BUS_FILTERS represents the MAX number of\r
+ * HCA's supported in a single system.\r
+ */\r
+#define MAX_BUS_FILTERS        16\r
+#define BFI_MAGIC              0xcafebabe\r
+\r
+#define BFI_PORT_MGR_OBJ       1\r
+#define BFI_IOU_MGR_OBJ                2\r
+\r
+\r
+typedef struct _bus_filter_instance\r
+{\r
+       /* Pointer to the bus filter instance FDO extention.\r
+        * if p_bus_ext is NULL, then it's an empty slot available for allocation\r
+        */\r
+       bus_fdo_ext_t                   *p_bus_ext;\r
+\r
+       /* HCA guid for which this bus filter is servicing */\r
+       ib_net64_t                              ca_guid;\r
+\r
+       /* PORT management - on a per HCA basis */\r
+       port_mgr_t                              *p_port_mgr;\r
+       cl_obj_t                                *p_port_mgr_obj;\r
+\r
+       /* IOU management - on a per HCA basis */\r
+       iou_mgr_t                               *p_iou_mgr;\r
+       cl_obj_t                                *p_iou_mgr_obj;\r
+#if DBG\r
+       ULONG                                   magic; // initial/temp debug\r
+       char                                    whoami[8];\r
+#endif\r
+\r
+}      bus_filter_t;\r
+\r
+extern bus_filter_t    bus_filters[MAX_BUS_FILTERS];\r
+extern ULONG bfi_InstanceCount;\r
+extern FAST_MUTEX ControlMutex;        // serializes InstanceCount & bus_filters\r
+\r
+extern bus_filter_t *alloc_bfi( IN DRIVER_OBJECT *, OUT int * );\r
+extern int free_bfi( IN bus_filter_t *p_bfi );\r
+extern int get_bfi_count( void );\r
+extern bus_filter_t *get_bfi_by_obj( IN int obj_type, IN cl_obj_t *p_obj );\r
+extern bus_filter_t *get_bfi_by_ca_guid( IN net64_t ca_guid );\r
+extern bus_filter_t *get_set_bfi_by_ca_guid( IN net64_t ca_guid );\r
+extern char *get_obj_state_str(cl_state_t state);\r
 \r
 #endif /* !defined _BUS_DRIVER_H_ */\r
index 277730f..209837f 100644 (file)
@@ -83,7 +83,12 @@ typedef struct _bus_iou_ext
 }      bus_iou_ext_t;\r
 \r
 \r
-iou_mgr_t*                                             gp_iou_mgr = NULL;\r
+typedef struct _iou_pnp_context\r
+{\r
+       bus_filter_t    *p_bus_filter;\r
+       void                    *p_pdo_ext;\r
+\r
+}      iou_pnp_ctx_t;\r
 \r
 \r
 /*\r
@@ -98,7 +103,8 @@ free_iou_mgr(
        IN                              cl_obj_t*                                       p_obj );\r
 \r
 ib_api_status_t\r
-bus_reg_iou_pnp( void );\r
+bus_reg_iou_pnp(\r
+       IN                              bus_filter_t*                           p_bfi );\r
 \r
 ib_api_status_t\r
 iou_mgr_pnp_cb(\r
@@ -278,25 +284,29 @@ static const cl_vfptr_query_txt_t         vfptr_iou_query_txt = {
  */\r
 ib_api_status_t\r
 create_iou_mgr(\r
+       IN                              bus_filter_t*                           p_bfi,\r
                OUT                     iou_mgr_t** const                       pp_iou_mgr )\r
 {\r
        ib_api_status_t         status;\r
        cl_status_t                     cl_status;\r
+       iou_mgr_t                       *gp_iou_mgr;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
-       CL_ASSERT( !gp_iou_mgr );\r
+       CL_ASSERT( p_bfi->p_iou_mgr == NULL );\r
 \r
        gp_iou_mgr = cl_zalloc( sizeof(iou_mgr_t) );\r
        if( !gp_iou_mgr )\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
-                       ("Failed to allocate port manager.\n") );\r
+                       ("Failed to allocate IOU manager.\n") );\r
                return IB_INSUFFICIENT_MEMORY;\r
        }\r
+       p_bfi->p_iou_mgr = gp_iou_mgr;\r
 \r
        /* Construct the load service. */\r
        cl_obj_construct( &gp_iou_mgr->obj, AL_OBJ_TYPE_LOADER );\r
+       p_bfi->p_iou_mgr_obj = &p_bfi->p_iou_mgr->obj; // save for destroy & free\r
        cl_mutex_construct( &gp_iou_mgr->pdo_mutex );\r
        cl_qlist_init( &gp_iou_mgr->iou_list );\r
 \r
@@ -311,7 +321,7 @@ create_iou_mgr(
 \r
        /* Initialize the load service object. */\r
        cl_status = cl_obj_init( &gp_iou_mgr->obj, CL_DESTROY_SYNC,\r
-               destroying_iou_mgr, NULL, free_iou_mgr );\r
+                                                        destroying_iou_mgr, NULL, free_iou_mgr );\r
        if( cl_status != CL_SUCCESS )\r
        {\r
                free_iou_mgr( &gp_iou_mgr->obj );\r
@@ -320,11 +330,12 @@ create_iou_mgr(
                return ib_convert_cl_status( cl_status );\r
        }\r
 \r
-       /* Register for port PnP events. */\r
-       status = bus_reg_iou_pnp();\r
+       /* Register for IOU PnP events. */\r
+       status = bus_reg_iou_pnp( p_bfi );\r
        if( status != IB_SUCCESS )\r
        {\r
-               cl_obj_destroy( &gp_iou_mgr->obj );\r
+//             cl_obj_destroy( &gp_iou_mgr->obj );\r
+               free_iou_mgr( &gp_iou_mgr->obj );\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
                        ("bus_reg_iou_pnp returned %s.\n", ib_get_err_str(status)) );\r
                return status;\r
@@ -345,20 +356,34 @@ destroying_iou_mgr(
        IN                              cl_obj_t*                                       p_obj )\r
 {\r
        ib_api_status_t                 status;\r
+       bus_filter_t                    *p_bfi;\r
+       iou_mgr_t                               *gp_iou_mgr;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
        CL_ASSERT( p_obj );\r
+       p_bfi = get_bfi_by_obj( BFI_IOU_MGR_OBJ, p_obj );\r
+       if (p_bfi == NULL) {\r
+               BUS_PRINT(BUS_DBG_PNP, ("%s() failed to find p_bfi by obj %p?\n",\r
+                       __FUNCTION__,p_obj));\r
+               return;\r
+       }\r
+       gp_iou_mgr = p_bfi->p_iou_mgr;\r
+\r
+       BUS_PRINT(BUS_DBG_PNP, ("%s(%s) obj %p port_mgr %p\n",\r
+                       __FUNCTION__, p_bfi->whoami, p_obj, gp_iou_mgr));\r
+\r
        CL_ASSERT( gp_iou_mgr == PARENT_STRUCT( p_obj, iou_mgr_t, obj ) );\r
-       UNUSED_PARAM( p_obj );\r
 \r
-       /* Deregister for port PnP events. */\r
-       if( gp_iou_mgr->h_pnp )\r
+       /* Deregister for iou PnP events. */\r
+       if( get_bfi_count() == 1 && bus_globals.h_pnp_iou )\r
        {\r
-               status = ib_dereg_pnp( gp_iou_mgr->h_pnp,\r
-                       (ib_pfn_destroy_cb_t)cl_obj_deref );\r
+               status = ib_dereg_pnp( bus_globals.h_pnp_iou, NULL );\r
+               bus_globals.h_pnp_iou = NULL;\r
                CL_ASSERT( status == IB_SUCCESS );\r
        }\r
+       cl_obj_deref( p_bfi->p_iou_mgr_obj );\r
+\r
        BUS_EXIT( BUS_DBG_PNP );\r
 }\r
 \r
@@ -372,14 +397,30 @@ free_iou_mgr(
 {\r
        bus_pdo_ext_t   *p_ext;\r
        cl_list_item_t  *p_list_item;\r
+       bus_filter_t    *p_bfi;\r
+       iou_mgr_t               *gp_iou_mgr;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
        CL_ASSERT( p_obj );\r
+       p_bfi = get_bfi_by_obj( BFI_IOU_MGR_OBJ, p_obj );\r
+       if ( p_bfi == NULL ) {\r
+               BUS_PRINT( BUS_DBG_PNP, ("%s: unable to get p_bfi iou_obj %p?\n",\r
+                                       __FUNCTION__,p_obj) );\r
+               return;\r
+       }\r
+       gp_iou_mgr = p_bfi->p_iou_mgr;\r
+       if ( !gp_iou_mgr ) {\r
+               // if create fails & then free is called, p_bfi->p_iou_mgr == NULL\r
+               return;\r
+       }\r
+\r
        CL_ASSERT( gp_iou_mgr == PARENT_STRUCT( p_obj, iou_mgr_t, obj ) );\r
 \r
+       BUS_PRINT( BUS_DBG_PNP, ("%s(%s) Mark all IOU PDOs as no longer present\n",\r
+                               __FUNCTION__, p_bfi->whoami));\r
        /*\r
-        * Mark all IPoIB PDOs as no longer present.  This will cause them\r
+        * Mark all IOU PDOs as no longer present.  This will cause them\r
         * to be removed when they process the IRP_MN_REMOVE_DEVICE.\r
         */\r
        p_list_item = cl_qlist_remove_head( &gp_iou_mgr->iou_list );\r
@@ -391,8 +432,10 @@ free_iou_mgr(
                {\r
                        CL_ASSERT( !p_ext->b_present );\r
                        p_ext->b_reported_missing = TRUE;\r
-                       BUS_TRACE( BUS_DBG_PNP, ("%s: ext %p, present %d, missing %d .\n",\r
-                               p_ext->cl_ext.vfptr_pnp_po->identity, p_ext, p_ext->b_present, p_ext->b_reported_missing ) );\r
+                       BUS_TRACE( BUS_DBG_PNP, ("%s %s: ext %p, present %d, missing %d\n",\r
+                                               p_bfi->whoami,\r
+                                               p_ext->cl_ext.vfptr_pnp_po->identity, p_ext,\r
+                                               p_ext->b_present, p_ext->b_reported_missing ) );\r
                        continue;\r
                }\r
                if( p_ext->h_ca )\r
@@ -404,13 +447,25 @@ free_iou_mgr(
                        /* Release the reference on the CA object. */\r
                        deref_al_obj( &p_ext->h_ca->obj );\r
                }\r
+               BUS_TRACE( BUS_DBG_PNP, ("Deleted device %s %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
+               BUS_TRACE( BUS_DBG_PNP,("%s(%s) p_ext->h_ca->obj.state %d ref_cnt %d\n",\r
+                                       __FUNCTION__, p_bfi->whoami,\r
+                                       p_ext->h_ca->obj.state,\r
+                                       p_ext->h_ca->obj.ref_cnt));\r
+\r
                IoDeleteDevice( p_ext->cl_ext.p_self_do );\r
        }\r
 \r
        cl_mutex_destroy( &gp_iou_mgr->pdo_mutex );\r
        cl_obj_deinit( p_obj );\r
        cl_free( gp_iou_mgr );\r
-       gp_iou_mgr = NULL;\r
+\r
+       p_bfi->p_iou_mgr = NULL;\r
+       p_bfi->p_iou_mgr_obj = NULL;\r
+\r
        BUS_EXIT( BUS_DBG_PNP );\r
 }\r
 \r
@@ -419,22 +474,41 @@ free_iou_mgr(
  * Register the load service for the given PnP class events.\r
  */\r
 ib_api_status_t\r
-bus_reg_iou_pnp( void )\r
+bus_reg_iou_pnp( IN bus_filter_t *p_bfi )\r
 {\r
        ib_pnp_req_t                    pnp_req;\r
-       ib_api_status_t                 status;\r
+       ib_api_status_t                 status = IB_SUCCESS;\r
+       boolean_t                               need_pnp_reg = FALSE;\r
 \r
-       cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) );\r
-       pnp_req.pnp_class       = IB_PNP_IOU | IB_PNP_FLAG_REG_SYNC;\r
-       pnp_req.pnp_context = gp_iou_mgr;\r
-       pnp_req.pfn_pnp_cb      = iou_mgr_pnp_cb;\r
+       /* only need to register for IOU PNP events once.\r
+        * do not hold mutex over pnp_reg() call as callback which needs mutex\r
+        * could occur.\r
+        */\r
+       if ( !bus_globals.h_pnp_iou )\r
+       {\r
+               ExAcquireFastMutexUnsafe(&ControlMutex);\r
+               if ( !bus_globals.h_pnp_iou )\r
+               {\r
+                       bus_globals.h_pnp_iou = (ib_pnp_handle_t)1; /* block others */ \r
+                       need_pnp_reg = TRUE;\r
+               }\r
+               ExReleaseFastMutexUnsafe(&ControlMutex);\r
 \r
-       status = ib_reg_pnp( gh_al, &pnp_req, &gp_iou_mgr->h_pnp );\r
+               if ( need_pnp_reg )\r
+               {\r
+                       cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) );\r
+                       pnp_req.pnp_class       = IB_PNP_IOU | IB_PNP_FLAG_REG_SYNC;\r
+                       pnp_req.pnp_context = NULL;\r
+                       pnp_req.pfn_pnp_cb      = iou_mgr_pnp_cb;\r
 \r
-       if( status == IB_SUCCESS )\r
+                       status = ib_reg_pnp( gh_al, &pnp_req, &bus_globals.h_pnp_iou );\r
+               }\r
+       }\r
+\r
+       if ( status == IB_SUCCESS )\r
        {\r
                /* Reference the load service on behalf of the ib_reg_pnp call. */\r
-               cl_obj_ref( &gp_iou_mgr->obj );\r
+               cl_obj_ref( &p_bfi->p_iou_mgr->obj );\r
        }\r
 \r
        return status;\r
@@ -448,12 +522,11 @@ ib_api_status_t
 iou_mgr_pnp_cb(\r
        IN                              ib_pnp_rec_t*                           p_pnp_rec )\r
 {\r
-       ib_api_status_t         status;\r
+       ib_api_status_t         status=IB_SUCCESS;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
        CL_ASSERT( p_pnp_rec );\r
-       CL_ASSERT( gp_iou_mgr == p_pnp_rec->pnp_context );\r
 \r
        switch( p_pnp_rec->pnp_event )\r
        {\r
@@ -463,9 +536,11 @@ iou_mgr_pnp_cb(
 \r
        case IB_PNP_IOU_REMOVE:\r
                iou_mgr_iou_remove( (ib_pnp_iou_rec_t*)p_pnp_rec );\r
+               break;\r
 \r
        default:\r
-               status = IB_SUCCESS;\r
+               BUS_PRINT( BUS_DBG_PNP, ("%s() Unhandled PNP Event %s\n",\r
+                                       __FUNCTION__, ib_get_pnp_event_str(p_pnp_rec->pnp_event) ));\r
                break;\r
        }\r
        BUS_EXIT( BUS_DBG_PNP );\r
@@ -482,9 +557,47 @@ iou_mgr_get_bus_relations(
        IN                              IRP* const                                      p_irp )\r
 {\r
        NTSTATUS                        status;\r
+       bus_filter_t            *p_bfi;\r
+       iou_mgr_t                       *gp_iou_mgr;\r
+       DEVICE_RELATIONS        *p_rel;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
+       BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid %I64x\n",__FUNCTION__,ca_guid));\r
+\r
+       /* special case guid == 0 - walk all bus filter instances */\r
+       if ( ca_guid == 0ULL ) {\r
+               for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) {\r
+                       gp_iou_mgr = p_bfi->p_iou_mgr;\r
+                       if ( !gp_iou_mgr )\r
+                               continue;\r
+                       cl_mutex_acquire( &gp_iou_mgr->pdo_mutex );\r
+                       status = bus_get_relations( &gp_iou_mgr->iou_list, ca_guid, p_irp );\r
+                       cl_mutex_release( &gp_iou_mgr->pdo_mutex );\r
+               }\r
+               p_rel = (DEVICE_RELATIONS*)p_irp->IoStatus.Information;\r
+               if ( p_rel ) {\r
+                       BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid 0 Reports %d\n",\r
+                                               __FUNCTION__,p_rel->Count));\r
+               }\r
+               BUS_EXIT( BUS_DBG_PNP );\r
+               return STATUS_SUCCESS;\r
+       }\r
+\r
+       p_bfi = get_bfi_by_ca_guid(ca_guid);\r
+       if (p_bfi == NULL) {\r
+               BUS_PRINT(BUS_DBG_PNP,\r
+                       ("%s() Null p_bfi from ca_guid %I64x ?\n",__FUNCTION__,ca_guid));\r
+               BUS_EXIT( BUS_DBG_PNP );\r
+               return STATUS_UNSUCCESSFUL;\r
+       }\r
+       gp_iou_mgr = p_bfi->p_iou_mgr;\r
+\r
+       BUS_PRINT(BUS_DBG_PNP, ("%s(%s) for ca_guid %I64x iou_mgr %p\n",\r
+                               __FUNCTION__, p_bfi->whoami, ca_guid, gp_iou_mgr) );\r
+       if (!gp_iou_mgr)\r
+               return STATUS_NO_SUCH_DEVICE;\r
+\r
        cl_mutex_acquire( &gp_iou_mgr->pdo_mutex );\r
        status = bus_get_relations( &gp_iou_mgr->iou_list, ca_guid, p_irp );\r
        cl_mutex_release( &gp_iou_mgr->pdo_mutex );\r
@@ -496,14 +609,17 @@ iou_mgr_get_bus_relations(
 \r
 static ib_api_status_t\r
 __iou_was_hibernated(\r
-       IN                              ib_pnp_iou_rec_t*                       p_pnp_rec )\r
+       IN                              ib_pnp_iou_rec_t*                       p_pnp_rec,\r
+       IN                              bus_filter_t*                           p_bfi )\r
 {\r
        NTSTATUS                status;\r
-       cl_list_item_t          *p_list_item;\r
-       bus_iou_ext_t           *p_iou_ext;\r
+       cl_list_item_t  *p_list_item;\r
+       bus_iou_ext_t   *p_iou_ext;\r
        bus_pdo_ext_t   *p_pdo_ext = NULL;\r
        size_t                  n_devs = 0;\r
-       cl_qlist_t*             p_pdo_list = &gp_iou_mgr->iou_list;\r
+       iou_mgr_t               *gp_iou_mgr = p_bfi->p_iou_mgr;\r
+       cl_qlist_t              *p_pdo_list = &gp_iou_mgr->iou_list;\r
+       iou_pnp_ctx_t   *p_ctx = p_pnp_rec->pnp_rec.context;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
        \r
@@ -525,9 +641,11 @@ __iou_was_hibernated(
                        break;\r
                }\r
 \r
-               BUS_TRACE( BUS_DBG_PNP, \r
-                       ("Skipped PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
-                       p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, \r
+               BUS_TRACE( BUS_DBG_PNP, ("%s Skipped 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
+                       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_iou_ext->guid ) );\r
        }\r
@@ -538,27 +656,31 @@ __iou_was_hibernated(
                p_pdo_ext->h_ca = acquire_ca( p_pnp_rec->ca_guid );\r
                if( !p_pdo_ext->h_ca )\r
                {\r
-                       BUS_TRACE( BUS_DBG_ERROR, ("acquire_ca failed to find CA by guid %I64x\n",\r
+                       BUS_TRACE( BUS_DBG_ERROR,\r
+                               ("acquire_ca failed to find CA by guid %I64x\n",\r
                                p_pnp_rec->ca_guid ) );\r
                        status = IB_INVALID_GUID;\r
                }\r
                else \r
                {\r
                        p_pdo_ext->b_hibernating = FALSE;\r
-                       p_pnp_rec->pnp_rec.context = p_pdo_ext;\r
+                       p_ctx->p_pdo_ext = p_pdo_ext; // for iou_mgr_iou_remove()\r
+\r
                        status = IB_SUCCESS;\r
                        p_iou_ext = (bus_iou_ext_t*)p_pdo_ext;\r
-                       BUS_TRACE( BUS_DBG_PNP, \r
-                               ("Found PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
-                               p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, \r
+                       BUS_TRACE( BUS_DBG_PNP, ("%s Found 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
+                               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_iou_ext->guid ) );\r
                }\r
        }\r
        else \r
        {\r
-               BUS_TRACE( BUS_DBG_PNP, ("Failed to find PDO for guid  %I64x .\n",\r
-                       p_pnp_rec->pnp_rec.guid ) );\r
+               BUS_TRACE( BUS_DBG_PNP, ("%s Failed to find PDO for guid  %I64x .\n",\r
+                                       p_bfi->whoami, p_pnp_rec->pnp_rec.guid ) );\r
                status = IB_NOT_FOUND;\r
        }\r
 \r
@@ -575,13 +697,48 @@ iou_mgr_iou_add(
        NTSTATUS                status;\r
        DEVICE_OBJECT   *p_pdo;\r
        bus_iou_ext_t   *p_iou_ext;\r
+       bus_filter_t    *p_bfi;\r
+       iou_mgr_t               *gp_iou_mgr;\r
+       iou_pnp_ctx_t   *p_ctx = p_pnp_rec->pnp_rec.context;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
-       /* Upon hibernating of the computer IB_BUS driver doesn't remove PDO, but\r
+       p_bfi = get_set_bfi_by_ca_guid( p_pnp_rec->ca_guid );\r
+       if ( !p_bfi ) {\r
+               BUS_TRACE_EXIT( BUS_DBG_PNP,("%s() NULL p_bfi? ca_guid 0x%I64x\n",\r
+                                                                       __FUNCTION__, p_pnp_rec->ca_guid ) );\r
+               return IB_ERROR;\r
+       }\r
+\r
+       if ( !p_ctx ) {\r
+               /*\r
+                * Allocate a PNP context for this object. pnp_rec.context is object\r
+                * unique.\r
+                */\r
+               p_ctx = cl_zalloc( sizeof(*p_ctx) );\r
+               if( !p_ctx )\r
+               {\r
+                       BUS_TRACE_EXIT(BUS_DBG_PNP, ("%s(%s) ca_guid %I64x iou_guid(%I64x) "\r
+                                       "BAD alloc for PNP context\n", __FUNCTION__,\r
+                                       p_bfi->whoami, p_bfi->ca_guid, p_pnp_rec->guid ));\r
+\r
+                       return IB_ERROR;\r
+               }\r
+               p_ctx->p_bus_filter = p_bfi;\r
+               p_pnp_rec->pnp_rec.context = p_ctx;\r
+\r
+               BUS_PRINT(BUS_DBG_PNP,\r
+                                       ("%s(%s) ca_guid %I64x iou_guid(%I64x) ALLOC p_ctx @ %p\n",\r
+                                       __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, \r
+                                       p_pnp_rec->guid,p_ctx));\r
+       }\r
+       gp_iou_mgr = p_bfi->p_iou_mgr;\r
+\r
+       /* Upon hibernating the computer IB_BUS driver doesn't remove PDO, but\r
           marks with a flag. So we first try to find an existing PDO for this port,\r
-          marked with this flag. If it was found, we turn off the flag and use this PDO */\r
-       status = __iou_was_hibernated(p_pnp_rec);\r
+          marked with this flag. If it was found, we turn off the flag and use\r
+          this PDO */\r
+       status = __iou_was_hibernated( p_pnp_rec, p_bfi );\r
        if( status != IB_NOT_FOUND )\r
        {\r
                BUS_EXIT( BUS_DBG_PNP );\r
@@ -590,9 +747,11 @@ iou_mgr_iou_add(
 \r
        /* Create the PDO for the new port device. */\r
        status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_iou_ext_t),\r
-               NULL, FILE_DEVICE_CONTROLLER, \r
-               FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,\r
-               FALSE, &p_pdo );\r
+                                                        NULL, FILE_DEVICE_CONTROLLER, \r
+                                                        FILE_DEVICE_SECURE_OPEN |\r
+                                                                                       FILE_AUTOGENERATED_DEVICE_NAME,\r
+                                                        FALSE, &p_pdo );\r
+\r
        if( !NT_SUCCESS( status ) )\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
@@ -602,18 +761,19 @@ iou_mgr_iou_add(
 \r
        /* Initialize the device extension. */\r
        cl_init_pnp_po_ext( p_pdo, NULL, p_pdo, bus_globals.dbg_lvl,\r
-               &vfptr_iou_pnp, &vfptr_iou_query_txt );\r
+                                               &vfptr_iou_pnp, &vfptr_iou_query_txt );\r
 \r
        /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */\r
        p_pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;\r
        \r
        p_iou_ext = p_pdo->DeviceExtension;\r
        p_iou_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;\r
-       p_iou_ext->pdo.p_parent_ext = bus_globals.p_bus_ext;\r
+       p_iou_ext->pdo.p_parent_ext = p_bfi->p_bus_ext;\r
        p_iou_ext->pdo.b_present = TRUE;\r
        p_iou_ext->pdo.b_reported_missing = FALSE;\r
        BUS_TRACE( BUS_DBG_PNP, ("%s: ext %p, present %d, missing %d .\n",\r
-               p_iou_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_iou_ext, p_iou_ext->pdo.b_present, p_iou_ext->pdo.b_reported_missing ) );\r
+               p_iou_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_iou_ext,\r
+               p_iou_ext->pdo.b_present, p_iou_ext->pdo.b_reported_missing ) );\r
 \r
        p_iou_ext->guid = p_pnp_rec->guid;\r
        p_iou_ext->chassis_guid = p_pnp_rec->chassis_guid;\r
@@ -626,6 +786,7 @@ iou_mgr_iou_add(
        p_iou_ext->revision = cl_ntoh32( p_pnp_rec->revision );\r
        cl_memcpy( p_iou_ext->desc, p_pnp_rec->desc,\r
                IB_NODE_DESCRIPTION_SIZE + 1 );\r
+       p_iou_ext->n_ifc_ref = 0;\r
 \r
        /* Cache the CA GUID. */\r
        p_iou_ext->pdo.ca_guid = p_pnp_rec->ca_guid;\r
@@ -641,23 +802,20 @@ iou_mgr_iou_add(
 \r
        /* Store the device extension in the PDO list for future queries. */\r
        cl_mutex_acquire( &gp_iou_mgr->pdo_mutex );\r
-       cl_qlist_insert_tail( &gp_iou_mgr->iou_list,\r
-               &p_iou_ext->pdo.list_item );\r
+       cl_qlist_insert_tail( &gp_iou_mgr->iou_list, &p_iou_ext->pdo.list_item );\r
        cl_mutex_release( &gp_iou_mgr->pdo_mutex );\r
 \r
        /*\r
         * Set the context of the PNP event.  The context is passed in for future\r
         * events on the same port.\r
         */\r
-       p_pnp_rec->pnp_rec.context = p_iou_ext;\r
+       /* if not set in iou_was_hibernated(), set now */\r
+       if ( !p_ctx->p_pdo_ext )\r
+               p_ctx->p_pdo_ext = p_iou_ext;\r
 \r
        /* Tell the PnP Manager to rescan for the HCA's bus relations. */\r
        IoInvalidateDeviceRelations(\r
-               p_iou_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
-\r
-       /* Invalidate removal relations for the bus driver. */\r
-       IoInvalidateDeviceRelations(\r
-               bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations );\r
+                       p_iou_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
 \r
@@ -670,13 +828,50 @@ iou_mgr_iou_remove(
        IN                              ib_pnp_iou_rec_t*                       p_pnp_rec )\r
 {\r
        bus_pdo_ext_t   *p_ext;\r
+       iou_mgr_t               *gp_iou_mgr;\r
+       bus_filter_t    *p_bfi;\r
+       iou_pnp_ctx_t   *p_ctx = p_pnp_rec->pnp_rec.context;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
-       /* The PNP record's context is the port extension. */\r
-       p_ext = p_pnp_rec->pnp_rec.context;\r
+       if ( !p_ctx ) {\r
+               BUS_EXIT( BUS_DBG_PNP );\r
+               return;\r
+       }\r
+\r
+       CL_ASSERT( p_ctx->p_bus_filter->magic == BFI_MAGIC );\r
+       p_bfi = p_ctx->p_bus_filter;\r
+       CL_ASSERT( p_bfi );\r
+\r
+       BUS_PRINT(BUS_DBG_PNP,("%s(%s) ca_guid 0x%I64x iou_mgr %p\n",\r
+                               __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, p_bfi->p_iou_mgr));\r
+\r
+       /* fdo_release_resources() has destroyed the IOU mgr, all that needs to be\r
+        * done is cleanup the PNP IOU context; one per port.\r
+        */\r
+       if ( p_bfi->ca_guid == 0ULL || !p_bfi->p_iou_mgr ) {\r
+               cl_free( p_ctx );\r
+               p_pnp_rec->pnp_rec.context = NULL;\r
+               BUS_EXIT( BUS_DBG_PNP );\r
+               return;\r
+       }\r
+\r
+       gp_iou_mgr = p_bfi->p_iou_mgr;\r
+\r
+       /* Within the PNP record's context is the IOU extension; see\r
+        * was_hibernated().\r
+        */\r
+       p_ext = p_ctx->p_pdo_ext;\r
        CL_ASSERT( p_ext );\r
 \r
+       if (p_bfi != p_ext->p_parent_ext->bus_filter) {\r
+               BUS_PRINT(BUS_DBG_PNP,\r
+                       ("%s() p_bfi(%p) != p_ext->bus_filter(%p) line %d file %s\n",\r
+                       __FUNCTION__,p_bfi,p_ext->p_parent_ext->bus_filter,\r
+                       __LINE__,__FILE__));\r
+               CL_ASSERT (p_bfi == p_ext->p_parent_ext->bus_filter);\r
+       }\r
+\r
        /*\r
         * Flag the port PDO as no longer being present.  We have to wait until\r
         * the PnP manager removes it to clean up.  However, we do release the\r
@@ -684,31 +879,42 @@ iou_mgr_iou_remove(
         * to proceed should it occur before the port's PDO is cleaned up.\r
         */\r
        cl_mutex_acquire( &gp_iou_mgr->pdo_mutex );\r
-       CL_ASSERT( p_ext->h_ca );\r
+       if ( !p_ext->h_ca )\r
+       {\r
+               BUS_TRACE_EXIT( BUS_DBG_PNP, ("%s() NULL h_ca? p_ext %p\n",\r
+                                       __FUNCTION__, p_ext ) );\r
+               return;\r
+       }\r
 \r
        if( p_ext->b_hibernating )\r
        {\r
-               BUS_TRACE( BUS_DBG_PNP, ("Skip port removing for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d .\n",\r
-                       p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext, p_ext->b_present, \r
+               BUS_TRACE( BUS_DBG_PNP, ("%s Skip port removing for %s: PDO %p ext %p "\r
+                       "present %d missing %d hibernating %d\n",\r
+                       p_bfi->whoami,\r
+                       p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do,\r
+                       p_ext, p_ext->b_present, \r
                        p_ext->b_reported_missing, p_ext->b_hibernating ) );\r
                goto hca_deref;\r
        }\r
 \r
        p_ext->b_present = FALSE;\r
-       BUS_TRACE( BUS_DBG_PNP, ("%s: ext %p, present %d, missing %d .\n",\r
-               p_ext->cl_ext.vfptr_pnp_po->identity, p_ext, p_ext->b_present, p_ext->b_reported_missing ) );\r
+       p_ext->b_reported_missing = TRUE;\r
 \r
-       /* Invalidate removal relations for the bus driver. */\r
-       IoInvalidateDeviceRelations( bus_globals.p_bus_ext->cl_ext.p_pdo,\r
-               RemovalRelations );\r
+       BUS_TRACE( BUS_DBG_PNP, ("%s %s: ext %p, present %d, missing %d .\n",\r
+                               p_bfi->whoami,\r
+                               p_ext->cl_ext.vfptr_pnp_po->identity, p_ext, p_ext->b_present,\r
+                               p_ext->b_reported_missing ) );\r
 \r
        /* Invalidate bus relations for the HCA. */\r
        IoInvalidateDeviceRelations(\r
                p_ext->h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
 \r
+       /* free PNP context */\r
+       cl_free( p_ctx );\r
+       p_pnp_rec->pnp_rec.context = NULL;\r
+\r
 hca_deref:\r
        deref_al_obj( &p_ext->h_ca->obj );\r
-       p_ext->h_ca = NULL;\r
        cl_mutex_release( &gp_iou_mgr->pdo_mutex );\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
@@ -778,10 +984,12 @@ iou_release_resources(
 {\r
        bus_iou_ext_t   *p_ext;\r
        POWER_STATE             po_state;\r
+       iou_mgr_t               *gp_iou_mgr;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
        p_ext = p_dev_obj->DeviceExtension;\r
+       gp_iou_mgr = p_ext->pdo.p_parent_ext->bus_filter->p_iou_mgr;\r
 \r
        /* Remove this PDO from its list. */\r
        cl_mutex_acquire( &gp_iou_mgr->pdo_mutex );\r
index 2199be4..bfe420f 100644 (file)
@@ -43,7 +43,6 @@
 typedef struct _iou_mgr\r
 {\r
        cl_obj_t                                        obj;\r
-       ib_pnp_handle_t                         h_pnp;  /* Handle for iou PnP events */\r
 \r
        /* Mutex protects both pointer vectors. */\r
        cl_mutex_t                                      pdo_mutex;\r
@@ -54,9 +53,12 @@ typedef struct _iou_mgr
 }      iou_mgr_t;\r
 \r
 \r
+struct _bus_filter_instance;\r
+\r
 ib_api_status_t\r
 create_iou_mgr(\r
-               OUT                     iou_mgr_t** const                       pp_iou_mgr );\r
+               IN                      struct _bus_filter_instance*    p_bfi,\r
+               OUT                     iou_mgr_t** const                               pp_iou_mgr );\r
 \r
 \r
 NTSTATUS\r
index e0188c5..af842ee 100644 (file)
@@ -36,7 +36,6 @@
  * Implemenation of all PnP functionality for FDO (power policy owners).\r
  */\r
 \r
-\r
 #include "bus_pnp.h"\r
 #include "al_ca.h"\r
 #include "al_init.h"\r
 #include "iba/ib_ci_ifc.h"\r
 \r
 \r
+/* Interface names are generated by IoRegisterDeviceInterface. */\r
+static UNICODE_STRING  al_ifc_name;\r
+static UNICODE_STRING  ci_ifc_name;\r
+\r
+FAST_MUTEX                             ControlMutex;\r
+ULONG                                  bfi_InstanceCount;\r
+bus_filter_t                   bus_filters[MAX_BUS_FILTERS];\r
+\r
+extern ib_al_handle_t  gh_al; // NULL if AL needs init.\r
+\r
+\r
 static NTSTATUS\r
 fdo_start(\r
        IN                                      DEVICE_OBJECT* const    p_dev_obj,\r
@@ -71,7 +81,7 @@ fdo_query_capabilities(
                OUT                             cl_irp_action_t* const  p_action );\r
 \r
 static NTSTATUS\r
-fdo_query_remove_relations(\r
+fdo_query_bus_relations(\r
        IN                                      DEVICE_OBJECT* const    p_dev_obj,\r
        IN                                      IRP* const                              p_irp, \r
                OUT                             cl_irp_action_t* const  p_action );\r
@@ -117,7 +127,7 @@ __fdo_set_power(
 #pragma alloc_text (PAGE, fdo_query_remove)\r
 #pragma alloc_text (PAGE, fdo_release_resources)\r
 #pragma alloc_text (PAGE, fdo_query_capabilities)\r
-#pragma alloc_text (PAGE, fdo_query_remove_relations)\r
+#pragma alloc_text (PAGE, fdo_query_bus_relations)\r
 #pragma alloc_text (PAGE, __query_al_ifc)\r
 #pragma alloc_text (PAGE, __query_ci_ifc)\r
 #pragma alloc_text (PAGE, __get_relations)\r
@@ -143,9 +153,9 @@ static const cl_vfptr_pnp_po_t              vfptr_fdo_pnp = {
        cl_irp_skip,\r
        cl_irp_skip,\r
        cl_do_sync_pnp,\r
+       fdo_query_bus_relations,\r
        cl_irp_ignore,\r
-       cl_irp_ignore,\r
-       fdo_query_remove_relations,\r
+       cl_irp_skip,\r
        cl_irp_ignore,\r
        cl_irp_ignore,\r
        cl_irp_ignore,\r
@@ -170,86 +180,133 @@ bus_add_device(
 {\r
        NTSTATUS                status;\r
        DEVICE_OBJECT   *p_dev_obj, *p_next_do;\r
-       bus_fdo_ext_t   *p_ext;\r
+       bus_fdo_ext_t   *p_ext=NULL;\r
        UNICODE_STRING  dev_name, dos_name;\r
+       bus_filter_t    *p_bfi;\r
+       int                             ic;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
-       if( bus_globals.p_bus_ext )\r
+       /* allocate a Bus Filter Instance */\r
+       p_bfi = alloc_bfi( p_driver_obj, &ic );\r
+       if ( !p_bfi )\r
        {\r
-               BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
-                       ("Bus root already exists.  Only one bus root allowed.\n") );\r
-               return STATUS_NO_SUCH_DEVICE;\r
+               BUS_TRACE_EXIT( BUS_DBG_PNP,\r
+                       ("%s() Err - Exceeded MAX_BUS_FILTERS(%d)\n",MAX_BUS_FILTERS));\r
+               return STATUS_UNSUCCESSFUL;\r
        }\r
 \r
-       RtlInitUnicodeString( &dev_name, AL_DEVICE_NAME );\r
-       RtlInitUnicodeString( &dos_name, L"\\DosDevices\\Global\\ibal" );\r
-\r
        /* Create the FDO device object to attach to the stack. */\r
-       status = IoCreateDevice( p_driver_obj, sizeof(bus_fdo_ext_t),\r
-               &dev_name, FILE_DEVICE_BUS_EXTENDER,\r
-               FILE_DEVICE_SECURE_OPEN, FALSE, &p_dev_obj );\r
-       if( !NT_SUCCESS(status) )\r
-       {\r
-               BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
-                       ("Failed to create bus root FDO device.\n") );\r
-               return status;\r
-       }\r
 \r
-       IoDeleteSymbolicLink( &dos_name );\r
-       status = IoCreateSymbolicLink( &dos_name, &dev_name );\r
-       if( !NT_SUCCESS(status) )\r
+       /* if 1st Bus Filter Instance, then create device names for user ioctl */\r
+       if ( ic == 1 )\r
        {\r
-               IoDeleteDevice( p_dev_obj );\r
-               BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
-                       ("Failed to create symlink for dos name.\n") );\r
-               return status;\r
+               RtlInitUnicodeString( &dev_name, AL_DEVICE_NAME );\r
+               RtlInitUnicodeString( &dos_name, L"\\DosDevices\\Global\\ibal" );\r
+\r
+               status = IoCreateDevice( p_driver_obj, sizeof(bus_fdo_ext_t),\r
+                                                                &dev_name, FILE_DEVICE_BUS_EXTENDER,\r
+                                                                FILE_DEVICE_SECURE_OPEN, FALSE, &p_dev_obj );\r
+               if( !NT_SUCCESS(status) )\r
+               {\r
+                       BUS_PRINT( BUS_DBG_ERROR, \r
+                               ("Failed to create ControlDeviceObject, status %x.\n",status) );\r
+                       goto bail;\r
+               }\r
+               IoDeleteSymbolicLink( &dos_name );\r
+               status = IoCreateSymbolicLink( &dos_name, &dev_name );\r
+               if( !NT_SUCCESS(status) )\r
+               {\r
+                       IoDeleteDevice( p_dev_obj );\r
+                       BUS_PRINT( BUS_DBG_ERROR,\r
+                               ("Failed to create symlink for dos name.\n") );\r
+                       goto bail;\r
+               }\r
+       }\r
+       else {\r
+               status = IoCreateDevice( p_driver_obj, sizeof(bus_fdo_ext_t),\r
+                                                                NULL, FILE_DEVICE_BUS_EXTENDER,\r
+                                                                FILE_DEVICE_SECURE_OPEN, FALSE, &p_dev_obj );\r
+               if( !NT_SUCCESS(status) )\r
+               {\r
+                       BUS_PRINT( BUS_DBG_ERROR, \r
+                               ("Failed to create bus root FDO device.\n") );\r
+                       goto bail;\r
+               }\r
        }\r
 \r
        p_ext = p_dev_obj->DeviceExtension;\r
+       p_ext->n_al_ifc_ref = 0;\r
+       p_ext->n_ci_ifc_ref = 0;\r
 \r
        p_next_do = IoAttachDeviceToDeviceStack( p_dev_obj, p_pdo );\r
        if( !p_next_do )\r
        {\r
                IoDeleteDevice( p_dev_obj );\r
-               BUS_TRACE_EXIT( BUS_DBG_ERROR, ("IoAttachToDeviceStack failed.\n") );\r
-               return STATUS_NO_SUCH_DEVICE;\r
+               BUS_PRINT( BUS_DBG_ERROR, ("IoAttachToDeviceStack failed.\n") );\r
+               status = STATUS_NO_SUCH_DEVICE;\r
+               goto bail;\r
        }\r
 \r
        cl_init_pnp_po_ext( p_dev_obj, p_next_do, p_pdo, bus_globals.dbg_lvl,\r
-               &vfptr_fdo_pnp, NULL );\r
+                                               &vfptr_fdo_pnp, NULL );\r
+\r
+       p_bfi->p_bus_ext = p_ext;\r
+       p_ext->bus_filter = p_bfi;\r
+\r
+       /*\r
+        * if not 1st Bus Filter Instance, then finished...\r
+        */\r
+       if ( ic > 1 )\r
+               goto adxit;\r
 \r
        /* Register the upper interface (the one used by clients). */\r
-       status = IoRegisterDeviceInterface( p_pdo, \r
-               &GUID_IB_AL_INTERFACE, NULL, &p_ext->al_ifc_name );\r
+       status = IoRegisterDeviceInterface( p_pdo, &GUID_IB_AL_INTERFACE, NULL,\r
+                                                                               &al_ifc_name );\r
        if( !NT_SUCCESS( status ) )\r
        {\r
                IoDetachDevice( p_ext->cl_ext.p_next_do );\r
                IoDeleteDevice( p_dev_obj );\r
-               BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
+               BUS_PRINT( BUS_DBG_ERROR, \r
                        ("IoRegisterDeviceInterface for upper interface returned %08x\n",\r
                        status) );\r
-               return STATUS_NO_SUCH_DEVICE;\r
+               status = STATUS_NO_SUCH_DEVICE;\r
+               goto bail;\r
        }\r
 \r
-       /* Register the lower interface (the one used by HCA VPDs). */\r
-       status = IoRegisterDeviceInterface( p_pdo, \r
-               &GUID_IB_CI_INTERFACE, NULL, &p_ext->ci_ifc_name );\r
+       /* Register the lower (CI) interface (the one used by HCA VPDs). */\r
+       status = IoRegisterDeviceInterface( p_pdo, &GUID_IB_CI_INTERFACE, NULL,\r
+                                                                               &ci_ifc_name );\r
        if( !NT_SUCCESS( status ) )\r
        {\r
-               RtlFreeUnicodeString( &p_ext->al_ifc_name );\r
                IoDetachDevice( p_ext->cl_ext.p_next_do );\r
                IoDeleteDevice( p_dev_obj );\r
-               BUS_TRACE_EXIT( BUS_DBG_ERROR, \r
+               BUS_PRINT( BUS_DBG_ERROR, \r
                        ("IoRegisterDeviceInterface for lower interface returned %08x\n",\r
                        status) );\r
-               return STATUS_NO_SUCH_DEVICE;\r
+               status = STATUS_NO_SUCH_DEVICE;\r
+               goto bail;\r
        }\r
 \r
-       bus_globals.p_bus_ext = p_ext;\r
+adxit:\r
+       BUS_PRINT( BUS_DBG_PNP, ("%s(%s) exit status 0\n",\r
+                               __FUNCTION__, p_bfi->whoami) );\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
        return STATUS_SUCCESS;\r
+\r
+bail:\r
+       BUS_PRINT( BUS_DBG_PNP, ("%s(%s) exit status 0x%x\n",\r
+                                                               __FUNCTION__,p_bfi->whoami,status) );\r
+       ic = free_bfi(p_bfi);\r
+       /* if last Bus filter, then cleanup */\r
+       if ( ic == 0 )\r
+       {\r
+               IoDeleteSymbolicLink( &dos_name );\r
+               RtlFreeUnicodeString( &al_ifc_name );\r
+       }\r
+       BUS_EXIT( BUS_DBG_PNP );\r
+       return status;\r
 }\r
 \r
 \r
@@ -262,10 +319,13 @@ fdo_start(
        NTSTATUS                status;\r
        bus_fdo_ext_t   *p_ext;\r
        ib_api_status_t ib_status;\r
+       bus_filter_t    *p_bfi;\r
+       boolean_t               AL_init_here = FALSE;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
        p_ext = p_dev_obj->DeviceExtension;\r
+       p_bfi = p_ext->bus_filter;\r
 \r
        /* Handled on the way up. */\r
        status = cl_do_sync_pnp( p_dev_obj, p_irp, p_action );\r
@@ -276,18 +336,24 @@ fdo_start(
                return status;\r
        }\r
 \r
-       /* Initialize AL */\r
-       ib_status = al_initialize();\r
-       if( ib_status != IB_SUCCESS )\r
-       {\r
-               al_cleanup();\r
-               BUS_TRACE_EXIT( BUS_DBG_ERROR, ("al_initialize returned %s.\n",\r
-                       ib_get_err_str(ib_status)) );\r
-               return STATUS_UNSUCCESSFUL;\r
+       ExAcquireFastMutexUnsafe(&ControlMutex);\r
+       if ( !gh_al ) {\r
+               /* Initialize AL */\r
+               ib_status = al_initialize();\r
+               if( ib_status != IB_SUCCESS )\r
+               {\r
+                       al_cleanup();\r
+                       BUS_TRACE_EXIT( BUS_DBG_ERROR, ("al_initialize returned %s.\n",\r
+                                                       ib_get_err_str(ib_status)) );\r
+                       ExReleaseFastMutexUnsafe(&ControlMutex);\r
+                       return STATUS_UNSUCCESSFUL;\r
+               }\r
+               AL_init_here = TRUE;\r
        }\r
+       ExReleaseFastMutexUnsafe(&ControlMutex);\r
 \r
        /* Initialize the port manager. */\r
-       ib_status = create_port_mgr( &p_ext->p_port_mgr );\r
+       ib_status = create_port_mgr( p_ext->bus_filter, &p_ext->p_port_mgr );\r
        if( ib_status != IB_SUCCESS )\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR, ("create_port_mgr returned %s.\n",\r
@@ -296,7 +362,7 @@ fdo_start(
        }\r
 \r
        /* Initialize the IOU manager. */\r
-       ib_status = create_iou_mgr( &p_ext->p_iou_mgr );\r
+       ib_status = create_iou_mgr( p_ext->bus_filter, &p_ext->p_iou_mgr );\r
        if( ib_status != IB_SUCCESS )\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR, ("create_iou_mgr returned %s.\n",\r
@@ -304,13 +370,18 @@ fdo_start(
                return STATUS_UNSUCCESSFUL;\r
        }\r
 \r
-       status = IoSetDeviceInterfaceState( &p_ext->al_ifc_name, TRUE );\r
-       ASSERT( NT_SUCCESS( status ) );\r
+       if ( AL_init_here ) {\r
+               status = IoSetDeviceInterfaceState( &al_ifc_name, TRUE );\r
+               ASSERT( NT_SUCCESS( status ) );\r
 \r
-       status = IoSetDeviceInterfaceState( &p_ext->ci_ifc_name, TRUE );\r
-       ASSERT( NT_SUCCESS( status ) );\r
+               status = IoSetDeviceInterfaceState( &ci_ifc_name, TRUE );\r
+               ASSERT( NT_SUCCESS( status ) );\r
+       }\r
 \r
+       BUS_PRINT(BUS_DBG_PNP,\r
+                               ("%s() %s exit %x\n",__FUNCTION__,p_bfi->whoami,status));\r
        BUS_EXIT( BUS_DBG_PNP );\r
+\r
        return status;\r
 }\r
 \r
@@ -322,11 +393,17 @@ fdo_query_remove(
                OUT                             cl_irp_action_t* const  p_action )\r
 {\r
        bus_fdo_ext_t   *p_ext;\r
+       bus_filter_t    *p_bfi;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
        p_ext = p_dev_obj->DeviceExtension;\r
 \r
+       BUS_PRINT( BUS_DBG_PNP,\r
+               ("%s() IRP_MN_QUERY_REMOVE_DEVICE %s @ %p refs CI %d AL %d\n", \r
+               __FUNCTION__, p_ext->cl_ext.vfptr_pnp_po->identity, p_ext,\r
+               p_ext->n_ci_ifc_ref,p_ext->n_al_ifc_ref ) );\r
+\r
        if( p_ext->n_ci_ifc_ref )\r
        {\r
                /*\r
@@ -344,9 +421,23 @@ fdo_query_remove(
                return STATUS_UNSUCCESSFUL;\r
        }\r
 \r
+       /* remove port & iou managers */        \r
+       p_bfi = p_ext->bus_filter;\r
+       CL_ASSERT( p_bfi );\r
+\r
+       //TODO: Fail outstanding I/O operations.\r
+\r
+       if ( p_ext->p_port_mgr && p_bfi->p_port_mgr )\r
+               cl_obj_destroy( &p_ext->p_port_mgr->obj );\r
+\r
+       if ( p_ext->p_iou_mgr && p_bfi->p_iou_mgr )\r
+               cl_obj_destroy( &p_ext->p_iou_mgr->obj );\r
+\r
+\r
        *p_action = IrpSkip;\r
        /* The FDO driver must set the status even when passing down. */\r
        p_irp->IoStatus.Status = STATUS_SUCCESS;\r
+\r
        BUS_EXIT( BUS_DBG_PNP );\r
        return STATUS_SUCCESS;\r
 }\r
@@ -363,30 +454,53 @@ fdo_release_resources(
 {\r
        bus_fdo_ext_t   *p_ext;\r
        NTSTATUS                status;\r
+       bus_filter_t    *p_bfi;\r
+       int                             ic;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
        p_ext = p_dev_obj->DeviceExtension;\r
+       ic = get_bfi_count();\r
+\r
+       p_bfi = p_ext->bus_filter;\r
+       CL_ASSERT( p_bfi );\r
 \r
        //TODO: Fail outstanding I/O operations.\r
 \r
+       if ( p_ext->p_port_mgr && p_bfi->p_port_mgr )\r
+               cl_obj_destroy( &p_ext->p_port_mgr->obj );\r
+\r
+       if ( p_ext->p_iou_mgr && p_bfi->p_iou_mgr )\r
+               cl_obj_destroy( &p_ext->p_iou_mgr->obj );\r
+\r
+       BUS_PRINT( BUS_DBG_PNP, ("%s() Releasing BusFilter %s\n",\r
+                                                       __FUNCTION__, p_bfi->whoami ));\r
+       if (p_bfi) {\r
+               p_ext->bus_filter = NULL;\r
+               p_bfi->p_bus_ext = NULL;\r
+       }\r
+\r
+       ic = free_bfi( p_bfi );\r
+\r
+       /* if not last Buf Filter Instance, then exit, otherwise cleanup/shutdown */\r
+       if ( ic > 0 ) {\r
+               BUS_PRINT( BUS_DBG_PNP, ("%s() %d remaining BusFilters\n",\r
+                                               __FUNCTION__, ic ));\r
+               return;\r
+       }\r
+\r
        /* Disable any exported interfaces. */\r
-       status = IoSetDeviceInterfaceState( &p_ext->al_ifc_name, FALSE );\r
+       status = IoSetDeviceInterfaceState( &al_ifc_name, FALSE );\r
        ASSERT( NT_SUCCESS( status ) );\r
-       status = IoSetDeviceInterfaceState( &p_ext->ci_ifc_name, FALSE );\r
+       status = IoSetDeviceInterfaceState( &ci_ifc_name, FALSE );\r
        ASSERT( NT_SUCCESS( status ) );\r
 \r
        /* Release the memory allocated for the interface symbolic names. */\r
-       RtlFreeUnicodeString( &p_ext->ci_ifc_name );\r
-       RtlFreeUnicodeString( &p_ext->al_ifc_name );\r
-\r
-       cl_obj_destroy( &p_ext->p_port_mgr->obj );\r
-       cl_obj_destroy( &p_ext->p_iou_mgr->obj );\r
+       RtlFreeUnicodeString( &ci_ifc_name );\r
+       RtlFreeUnicodeString( &al_ifc_name );\r
 \r
        al_cleanup();\r
 \r
-       bus_globals.p_bus_ext = NULL;\r
-\r
        BUS_EXIT( BUS_DBG_PNP );\r
 }\r
 \r
@@ -432,25 +546,48 @@ fdo_query_capabilities(
 \r
 \r
 static NTSTATUS\r
-fdo_query_remove_relations(\r
+fdo_query_bus_relations(\r
        IN                                      DEVICE_OBJECT* const    p_dev_obj,\r
        IN                                      IRP* const                              p_irp, \r
                OUT                             cl_irp_action_t* const  p_action )\r
 {\r
        NTSTATUS                        status;\r
+       bus_fdo_ext_t           *p_ext;\r
+       bus_filter_t            *p_bfi;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
-       UNUSED_PARAM( p_dev_obj );\r
+       p_ext = p_dev_obj->DeviceExtension;\r
 \r
-       status = port_mgr_get_bus_relations( 0, p_irp );\r
-       if( status == STATUS_SUCCESS || \r
-               status == STATUS_NO_SUCH_DEVICE )\r
+       if ( !p_ext->bus_filter )\r
        {\r
-               status = iou_mgr_get_bus_relations( 0, p_irp );\r
+               /* BFI has already been released */\r
+               *p_action = IrpComplete;\r
+               BUS_TRACE_EXIT( BUS_DBG_PNP, ("%s() NULL BFI\n", __FUNCTION__) );\r
+               return STATUS_SUCCESS;\r
        }\r
-       if( status == STATUS_NO_SUCH_DEVICE )\r
+\r
+       p_bfi = p_ext->bus_filter;\r
+       CL_ASSERT( p_bfi->magic == BFI_MAGIC );\r
+\r
+       if ( p_bfi->ca_guid == 0ULL )\r
+       {\r
+               /* HCA not yet bound to a BFI slot (no PNP ADD event seen), no bus\r
+                * relations yet.\r
+                */\r
                status = STATUS_SUCCESS;\r
+       }\r
+       else\r
+       {\r
+               status = port_mgr_get_bus_relations( p_bfi->ca_guid, p_irp );\r
+               if( status == STATUS_SUCCESS || \r
+                       status == STATUS_NO_SUCH_DEVICE )\r
+               {\r
+                       status = iou_mgr_get_bus_relations( p_bfi->ca_guid, p_irp );\r
+               }\r
+               if( status == STATUS_NO_SUCH_DEVICE )\r
+                       status = STATUS_SUCCESS;\r
+       }\r
 \r
        switch( status )\r
        {\r
@@ -700,22 +837,18 @@ __get_relations(
        IN              const   net64_t                                         ca_guid,\r
        IN                              IRP* const                                      p_irp )\r
 {\r
-       NTSTATUS                        status;\r
-\r
        BUS_ENTER( BUS_DBG_PNP );\r
+       UNUSED_PARAM( ca_guid );\r
+       UNUSED_PARAM( p_irp );\r
 \r
-       /* TODO: For IOUs, filter relations based on multi-HCA support. */\r
-       status = port_mgr_get_bus_relations( ca_guid, p_irp );\r
-       if( status == STATUS_SUCCESS || \r
-               status == STATUS_NO_SUCH_DEVICE )\r
-       {\r
-               status = iou_mgr_get_bus_relations( ca_guid, p_irp );\r
-       }\r
-       if( status == STATUS_NO_SUCH_DEVICE )\r
-               status = STATUS_SUCCESS;\r
+       /*\r
+        * Now that ibbus is in the same device stack as the HCA driver, skip\r
+        * returning relations here as ibbus has already done the deed.\r
+        * This interface remains to minimize changes to HCA drivers for now.\r
+        */\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
-       return status;\r
+       return STATUS_SUCCESS;\r
 }\r
 \r
 \r
@@ -777,9 +910,7 @@ fdo_query_interface(
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
-#pragma warning( push, 3 )\r
        PAGED_CODE();\r
-#pragma warning( pop )\r
 \r
        p_io_stack = IoGetCurrentIrpStackLocation( p_irp );\r
        \r
@@ -971,7 +1102,8 @@ __fdo_set_power(
        BUS_TRACE( BUS_DBG_POWER, \r
                ("SET_POWER for FDO %p (ext %p): type %s, state %d, action %d \n",\r
                p_dev_obj, p_ext,\r
-               (p_io_stack->Parameters.Power.Type) ? "DevicePowerState" : "SystemPowerState",\r
+               (p_io_stack->Parameters.Power.Type)\r
+                       ? "DevicePowerState" : "SystemPowerState",\r
                p_io_stack->Parameters.Power.State.DeviceState, \r
                p_io_stack->Parameters.Power.ShutdownType ));\r
 \r
@@ -1073,16 +1205,18 @@ bus_get_relations(
                         * the PDO will get cleaned up.\r
                         */\r
                        p_pdo_ext->b_reported_missing = TRUE;\r
-                       BUS_TRACE( BUS_DBG_PNP, ("Don't report PDO! %s: PDO %p, ext %p, present %d, missing %d .\n",\r
-                               p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, \r
-                               p_pdo_ext, p_pdo_ext->b_present, p_pdo_ext->b_reported_missing ) );\r
+                       BUS_TRACE( BUS_DBG_PNP, ("Don't report PDO! %s: PDO %p, ext %p, "\r
+                               "present %d, missing %d .\n",\r
+                               p_pdo_ext->cl_ext.vfptr_pnp_po->identity,\r
+                               p_pdo_ext->cl_ext.p_self_do, p_pdo_ext, p_pdo_ext->b_present,\r
+                               p_pdo_ext->b_reported_missing ) );\r
                        continue;\r
                }\r
 \r
                if( ca_guid && p_pdo_ext->ca_guid != ca_guid )\r
                        continue;\r
 \r
-               BUS_TRACE( BUS_DBG_PNP, ("Reported PDO %p(=%p), ext %p.\n", \r
+               BUS_TRACE( BUS_DBG_PNP, ("Reported PDO %p(=%p), ext %p\n", \r
                        p_pdo_ext->cl_ext.p_self_do, p_pdo_ext->cl_ext.p_pdo, p_pdo_ext ));\r
                \r
                p_rel->Objects[p_rel->Count] = p_pdo_ext->cl_ext.p_pdo;\r
@@ -1092,3 +1226,256 @@ bus_get_relations(
        BUS_EXIT( BUS_DBG_PNP );\r
        return STATUS_SUCCESS;\r
 }\r
+\r
+\r
+/*\r
+ * find a bus filter instance (p_bfi) given an *cl_obj: port_mgr or iou_mgr. \r
+ */\r
+\r
+bus_filter_t *\r
+get_bfi_by_obj(IN int obj_type, IN cl_obj_t *p_obj )\r
+{\r
+       bus_filter_t    *p_bfi;\r
+       bus_filter_t    *matched=NULL;\r
+\r
+       CL_ASSERT((obj_type == BFI_PORT_MGR_OBJ) || (obj_type == BFI_IOU_MGR_OBJ));\r
+\r
+    ExAcquireFastMutexUnsafe(&ControlMutex);\r
+\r
+       for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) {\r
+\r
+               if ( !p_bfi->p_bus_ext )\r
+                       continue;\r
+\r
+               if ( obj_type == BFI_PORT_MGR_OBJ ) {\r
+                       if ( p_obj == p_bfi->p_port_mgr_obj ) {\r
+                               matched = p_bfi;\r
+                               break;\r
+                       }\r
+               }\r
+               else {\r
+                       if ( p_obj == p_bfi->p_iou_mgr_obj ) {\r
+                               matched = p_bfi;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+       ExReleaseFastMutexUnsafe(&ControlMutex);\r
+\r
+       BUS_PRINT( BUS_DBG_PNP,\r
+                               ("%s() cl_obj %p type %s_MGR_OBJ --> bfi[%d] %p\n",\r
+                               __FUNCTION__,p_obj,\r
+                               (obj_type == BFI_PORT_MGR_OBJ ? "PORT": "IOU"),\r
+                               (matched ? (matched - bus_filters) : (-1)), matched ) );\r
+\r
+       return matched;\r
+}\r
+\r
+/*\r
+ * find a bus filter instance given an HCA guid.\r
+ */\r
+\r
+bus_filter_t *\r
+get_bfi_by_ca_guid( IN net64_t ca_guid )\r
+{\r
+       bus_filter_t    *p_bfi;\r
+       bus_filter_t    *matched=NULL;\r
+\r
+       if ( ca_guid == 0ULL )\r
+       {\r
+               matched = bus_filters;\r
+               BUS_PRINT( BUS_DBG_PNP, ("%s() ERR guid %I64x -> bfi[0] %p\n",\r
+                                                               __FUNCTION__, ca_guid, matched) );\r
+               CL_ASSERT( ca_guid );\r
+               return matched;\r
+       }\r
+\r
+       ExAcquireFastMutexUnsafe(&ControlMutex);\r
+\r
+       for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++)\r
+       {\r
+               if ( !p_bfi->p_bus_ext )\r
+                       continue;\r
+\r
+               if ( ca_guid == p_bfi->ca_guid )\r
+               {\r
+                       matched = p_bfi;\r
+                       break;\r
+               }\r
+       }\r
+       ExReleaseFastMutexUnsafe(&ControlMutex);\r
+\r
+       BUS_PRINT( BUS_DBG_PNP,\r
+                               ("%s() guid 0x%I64x -> bfi[%d] %p\n",\r
+                               __FUNCTION__, ca_guid,\r
+                               (matched ? (matched - bus_filters) : (-1)), matched ) );\r
+\r
+       return matched;\r
+}\r
+\r
+\r
+/*\r
+ * find/bind the specified ca_guid to a bus filter instance.\r
+ * Called from PORT_ADD or IOU_ADD pnp callback routines with the ca_guid from\r
+ * the pnp event record.\r
+ * Assumption is a BFI slot has been allocated in add_device() although the\r
+ * ca_guid was not known at that time; hence !ca_bound. When PNP generates an\r
+ * 'ADD' event, the port_mgr/iou_mgr pnp callback routine calls here to match\r
+ * the input ca_guid which caused the PNP event to the BFI instance by ca_guid.\r
+ * In the 1st call after add_device() the BFI slot is allocated but not yet \r
+ * bound to a CA guid. If the input ca_guid is not matched, then the 1st\r
+ * allocated but not bound BFI slot is then 'bound' by setting\r
+ * bfi->ca_guid = input ca_guid.\r
+ */\r
+\r
+bus_filter_t *\r
+get_set_bfi_by_ca_guid( IN net64_t ca_guid )\r
+{\r
+       bus_filter_t    *p_bfi;\r
+       bus_filter_t    *matched=NULL;\r
+       boolean_t               ca_bound = FALSE;\r
+\r
+       if ( ca_guid == 0ULL )\r
+       {\r
+               matched = bus_filters;\r
+               BUS_PRINT( BUS_DBG_PNP, ("%s() ERR guid 0x%I64x -> bfi[0] %p\n",\r
+                                       __FUNCTION__, ca_guid, matched) );\r
+               CL_ASSERT( ca_guid );\r
+               return matched;\r
+       }\r
+\r
+       for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++)\r
+       {\r
+               if ( !p_bfi->p_bus_ext )\r
+                       continue;\r
+\r
+               if ( ca_guid == p_bfi->ca_guid )\r
+               {\r
+                       matched = p_bfi;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       /*\r
+        * if no match, find an 'allocated' bfi slot which does not have a bound CA.\r
+        * Bound == ca_guid != 0ULL.\r
+        */\r
+       if ( !matched )\r
+       {\r
+               ExAcquireFastMutexUnsafe(&ControlMutex);\r
+\r
+               for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++)\r
+               {\r
+                       if ( !p_bfi->p_bus_ext )\r
+                               continue;       // not allocated.\r
+\r
+                       if ( p_bfi->ca_guid == 0ULL )\r
+                       {\r
+                               ca_bound = TRUE;\r
+                               p_bfi->ca_guid = ca_guid;       // bind CA & this BFI slot; RTU.\r
+                               matched = p_bfi;\r
+                               break;\r
+                       }\r
+               }\r
+               ExReleaseFastMutexUnsafe(&ControlMutex);\r
+       }\r
+\r
+       BUS_PRINT( BUS_DBG_PNP,\r
+                               ("%s()%sguid 0x%I64x @ bfi[%d] %p \n",\r
+                               __FUNCTION__, (ca_bound ? "SET ":" "), ca_guid,\r
+                               (matched ? (matched - bus_filters) : (-1)), matched ) );\r
+\r
+       return matched;\r
+}\r
+\r
+\r
+bus_filter_t *\r
+alloc_bfi( IN DRIVER_OBJECT  *p_driver_obj, OUT int *p_instance_count )\r
+{\r
+       bus_filter_t    *p_bfi;\r
+       bus_filter_t    *matched=NULL;\r
+\r
+    /* Using unsafe function so that the IRQL remains at PASSIVE_LEVEL.\r
+     * IoCreateDeviceSecure & IoCreateSymbolicLink must be called at\r
+     * PASSIVE_LEVEL.\r
+        */\r
+       ExAcquireFastMutexUnsafe(&ControlMutex);\r
+\r
+       // find 1st unused bfi slot.\r
+       for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++)\r
+       {\r
+               if ( !p_bfi->p_bus_ext )\r
+               {\r
+                       /* temp setting until 'real' p_bus_ext is alloc; see bus_add_device.\r
+                        * If p_bus_ext is ! 0, then bfi slot is allocated, although it\r
+                        * may not yet have a bound CA guid; set set_get_\r
+                        */\r
+                       p_bfi->p_bus_ext = (bus_fdo_ext_t*)p_driver_obj;\r
+                       matched = p_bfi;\r
+                       *p_instance_count = ++bfi_InstanceCount; // record in-use\r
+                       break;\r
+               }\r
+       }\r
+       ExReleaseFastMutexUnsafe(&ControlMutex);\r
+\r
+#if DBG\r
+       RtlStringCbPrintfA ( p_bfi->whoami,\r
+                                                sizeof(p_bfi->whoami),\r
+                                                "bfi-%d",\r
+                                                (bfi_InstanceCount - 1) );\r
+\r
+       p_bfi->magic = BFI_MAGIC;\r
+#endif\r
+\r
+       BUS_PRINT( BUS_DBG_PNP, ("%s() %s %p\n",\r
+                               __FUNCTION__, (matched ? matched->whoami:"Nobody"), matched) );\r
+\r
+       return matched;\r
+}\r
+\r
+\r
+int\r
+free_bfi( IN  bus_filter_t  *p_bfi )\r
+{\r
+       int     remaining;\r
+\r
+       ExAcquireFastMutexUnsafe(&ControlMutex);\r
+       p_bfi->p_bus_ext = NULL;\r
+       p_bfi->ca_guid = 0ULL;\r
+       remaining = --bfi_InstanceCount; // one less bfi in-use\r
+       ExReleaseFastMutexUnsafe(&ControlMutex);\r
+\r
+       return remaining;\r
+}\r
+\r
+int\r
+get_bfi_count( void )\r
+{\r
+       int     ic;\r
+\r
+       ExAcquireFastMutexUnsafe(&ControlMutex);\r
+       ic = bfi_InstanceCount;\r
+       ExReleaseFastMutexUnsafe(&ControlMutex);\r
+\r
+       return ic;\r
+}\r
+\r
+#if DBG\r
+char *get_obj_state_str(cl_state_t state)\r
+{\r
+       switch( state ) {\r
+         case CL_UNINITIALIZED:\r
+               return "UNINITIALIZED";\r
+         case CL_INITIALIZED:\r
+               return "INITIALIZED";\r
+         case CL_DESTROYING:\r
+               return "DESTROYING";\r
+         case CL_DESTROYED:\r
+               return "DESTROYED";\r
+         default:\r
+               break;\r
+       }\r
+       return "Err - Bad obj state";\r
+}\r
+#endif\r
+\r
index 30f5cf9..83fd743 100644 (file)
@@ -87,5 +87,4 @@ bus_get_relations(
        IN                              IRP* const                                      p_irp );\r
 \r
 NTSTATUS port_mgr_pkey_add();\r
-NTSTATUS port_mgr_pkey_rem();\r
 #endif // !defined _BUS_DRV_PNP_H_\r
index f9cce24..3626b33 100644 (file)
 #include "iba/ipoib_ifc.h"\r
 #include "al_dev.h"\r
 \r
-#define IPOIB_PART_DEVICE_ID   L"IBA\\IPoIBP"\r
 #define IPOIB_DEVICE_ID                        L"IBA\\IPoIB"\r
 #define IPOIB_COMPAT_ID                        L"IBA\\SID_1000066a00020000\0\0"\r
 /* Hardware ID is a MULTI_SZ, so is terminated with a double NULL. */\r
 #define IPOIB_HARDWARE_ID              IPOIB_DEVICE_ID L"\0"\r
-#define IPOIB_PART_HARDWARE_ID IPOIB_PART_DEVICE_ID L"\0"\r
 #define IPOIB_DESCRIPTION              L"OpenIB IPoIB Adapter"\r
 \r
 /* {5A9649F4-0101-4a7c-8337-796C48082DA2} */\r
@@ -64,7 +62,7 @@ typedef struct _bus_port_ext
 {\r
        bus_pdo_ext_t                   pdo;\r
 \r
-       port_guid_pkey_t                port_guid;\r
+       port_guid_pkey                  port_guid;\r
        uint32_t                                n_port;\r
 \r
        /* Number of references on the upper interface. */\r
@@ -73,8 +71,18 @@ typedef struct _bus_port_ext
 }      bus_port_ext_t;\r
 \r
 \r
-port_mgr_t*                                            gp_port_mgr = NULL;\r
+typedef struct _port_pnp_context\r
+{\r
+       bus_filter_t    *p_bus_filter;\r
+       void                    *p_pdo_ext;\r
+       int                             port_num;\r
+\r
+}      port_pnp_ctx_t;\r
+\r
+\r
+extern pkey_array_t  g_pkeys;\r
 \r
+static boolean_t pkeys_enumerated = FALSE;\r
 /*\r
  * Function prototypes.\r
  */\r
@@ -87,7 +95,8 @@ free_port_mgr(
        IN                              cl_obj_t*                                       p_obj );\r
 \r
 ib_api_status_t\r
-bus_reg_port_pnp( void );\r
+bus_reg_port_pnp(\r
+       IN                              bus_filter_t*                           p_bfi );\r
 \r
 ib_api_status_t\r
 port_mgr_pnp_cb(\r
@@ -273,14 +282,16 @@ static const cl_vfptr_query_txt_t         vfptr_port_query_txt = {
  */\r
 ib_api_status_t\r
 create_port_mgr(\r
+               IN                      bus_filter_t*                           p_bfi,\r
                OUT                     port_mgr_t** const                      pp_port_mgr )\r
 {\r
        ib_api_status_t         status;\r
        cl_status_t                     cl_status;\r
+       port_mgr_t                      *gp_port_mgr;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
-       CL_ASSERT( !gp_port_mgr );\r
+       CL_ASSERT( p_bfi->p_port_mgr == NULL );\r
 \r
        gp_port_mgr = cl_zalloc( sizeof( port_mgr_t ) );\r
        if( !gp_port_mgr )\r
@@ -289,9 +300,11 @@ create_port_mgr(
                        ("Failed to allocate port manager.\n") );\r
                return IB_INSUFFICIENT_MEMORY;\r
        }\r
+       p_bfi->p_port_mgr = gp_port_mgr;\r
 \r
        /* Construct the load service. */\r
        cl_obj_construct( &gp_port_mgr->obj, AL_OBJ_TYPE_LOADER );\r
+       p_bfi->p_port_mgr_obj = &gp_port_mgr->obj;\r
        cl_mutex_construct( &gp_port_mgr->pdo_mutex );\r
        cl_qlist_init( &gp_port_mgr->port_list );\r
 \r
@@ -306,7 +319,8 @@ create_port_mgr(
 \r
        /* Initialize the load service object. */\r
        cl_status = cl_obj_init( &gp_port_mgr->obj, CL_DESTROY_SYNC,\r
-               destroying_port_mgr, NULL, free_port_mgr );\r
+                                                        destroying_port_mgr, NULL, free_port_mgr );\r
+\r
        if( cl_status != CL_SUCCESS )\r
        {\r
                free_port_mgr( &gp_port_mgr->obj );\r
@@ -315,13 +329,13 @@ create_port_mgr(
                return ib_convert_cl_status( cl_status );\r
        }\r
 \r
-       /* Register for port PnP events. */\r
-       status = bus_reg_port_pnp();\r
+       /* Register for port PnP events */\r
+       status = bus_reg_port_pnp(p_bfi);\r
        if( status != IB_SUCCESS )\r
        {\r
-               cl_obj_destroy( &gp_port_mgr->obj );\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
                        ("bus_reg_port_pnp returned %s.\n", ib_get_err_str(status)) );\r
+               free_port_mgr( &gp_port_mgr->obj );\r
                return status;\r
        }\r
 \r
@@ -340,20 +354,35 @@ destroying_port_mgr(
        IN                              cl_obj_t*                                       p_obj )\r
 {\r
        ib_api_status_t                 status;\r
+       bus_filter_t                    *p_bfi;\r
+       port_mgr_t                              *gp_port_mgr;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
        CL_ASSERT( p_obj );\r
+       p_bfi = get_bfi_by_obj(BFI_PORT_MGR_OBJ, p_obj);\r
+       if (p_bfi == NULL) {\r
+               BUS_PRINT(BUS_DBG_PNP, ("%s() failed to find p_bfi by obj %p?\n",\r
+                       __FUNCTION__,p_obj));\r
+               return;\r
+       }\r
+       gp_port_mgr = p_bfi->p_port_mgr;\r
+\r
+       BUS_PRINT(BUS_DBG_PNP, ("%s(%s) obj %p port_mgr %p port_mgr_obj %p\n",\r
+                       __FUNCTION__,p_bfi->whoami,p_obj,gp_port_mgr,\r
+                       p_bfi->p_port_mgr_obj) );\r
+\r
+       CL_ASSERT( (void*)p_bfi->p_port_mgr == (void*)p_bfi->p_port_mgr_obj );\r
        CL_ASSERT( gp_port_mgr == PARENT_STRUCT( p_obj, port_mgr_t, obj ) );\r
-       UNUSED_PARAM( p_obj );\r
 \r
-       /* Deregister for port PnP events. */\r
-       if( gp_port_mgr->h_pnp )\r
-       {\r
-               status = ib_dereg_pnp( gp_port_mgr->h_pnp,\r
-                       (ib_pfn_destroy_cb_t)cl_obj_deref );\r
+       /* Deregister for port PnP events if this is the last Port manager. */\r
+       if ( get_bfi_count() == 1 && bus_globals.h_pnp_port ) {\r
+               status = ib_dereg_pnp( bus_globals.h_pnp_port, NULL );\r
+               bus_globals.h_pnp_port = NULL;\r
                CL_ASSERT( status == IB_SUCCESS );\r
        }\r
+       cl_obj_deref( p_bfi->p_port_mgr_obj );\r
+\r
        BUS_EXIT( BUS_DBG_PNP );\r
 }\r
 \r
@@ -367,12 +396,32 @@ free_port_mgr(
 {\r
        bus_pdo_ext_t   *p_ext;\r
        cl_list_item_t  *p_list_item;\r
+       bus_filter_t    *p_bfi;\r
+       port_mgr_t              *gp_port_mgr;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
        CL_ASSERT( p_obj );\r
+       p_bfi = get_bfi_by_obj(BFI_PORT_MGR_OBJ, p_obj);\r
+       if (p_bfi == NULL) {\r
+               BUS_PRINT(BUS_DBG_PNP, ("%s: unable to get p_bfi for port obj %p?\n",\r
+                       __FUNCTION__,p_obj));\r
+               return;\r
+       }\r
+       gp_port_mgr = p_bfi->p_port_mgr;\r
+       if ( !gp_port_mgr ) {\r
+               // if create fails & then free is called, p_bfi->p_port_mgr == NULL\r
+               return;\r
+       }\r
        CL_ASSERT( gp_port_mgr == PARENT_STRUCT( p_obj, port_mgr_t, obj ) );\r
 \r
+       BUS_PRINT(BUS_DBG_PNP, ("%s(%s) obj %p port_mgr %p port_mgr_obj %p\n",\r
+                       __FUNCTION__, p_bfi->whoami, p_obj,gp_port_mgr,\r
+                       p_bfi->p_port_mgr_obj) );\r
+\r
+       BUS_PRINT( BUS_DBG_PNP,\r
+                               ("%s(%s) Mark all IPoIB PDOs as no longer present\n",\r
+                               __FUNCTION__, p_bfi->whoami));\r
        /*\r
         * Mark all IPoIB PDOs as no longer present.  This will cause them\r
         * to be removed when they process the IRP_MN_REMOVE_DEVICE.\r
@@ -386,11 +435,14 @@ free_port_mgr(
                {\r
                        CL_ASSERT( !p_ext->b_present );\r
                        p_ext->b_reported_missing = TRUE;\r
-                       BUS_TRACE( BUS_DBG_PNP, ("%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, p_ext->b_present, p_ext->b_reported_missing ) );\r
+                       BUS_TRACE( BUS_DBG_PNP,\r
+                               ("%s %s: PDO %p, ext %p, present %d, missing %d .\n",\r
+                               p_bfi->whoami,\r
+                               p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do,\r
+                               p_ext, p_ext->b_present, p_ext->b_reported_missing ) );\r
                        continue;\r
                }\r
-               if( p_ext->h_ca && (!p_ext->is_partition_pdo))\r
+               if( p_ext->h_ca )\r
                {\r
                        /* Invalidate bus relations for the HCA. */\r
                        IoInvalidateDeviceRelations(\r
@@ -399,15 +451,21 @@ free_port_mgr(
                        /* Release the reference on the CA object. */\r
                        deref_al_obj( &p_ext->h_ca->obj );\r
                }\r
-               BUS_TRACE( BUS_DBG_PNP, ("Deleted device %s: PDO %p, ext %p\n",\r
-                       p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext ) );\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
 \r
        cl_mutex_destroy( &gp_port_mgr->pdo_mutex );\r
        cl_obj_deinit( p_obj );\r
        cl_free( gp_port_mgr );\r
-       gp_port_mgr = NULL;\r
+\r
+       p_bfi->p_port_mgr = NULL;\r
+       p_bfi->p_port_mgr_obj = NULL;\r
+\r
        BUS_EXIT( BUS_DBG_PNP );\r
 }\r
 \r
@@ -416,22 +474,40 @@ free_port_mgr(
  * Register the load service for the given PnP class events.\r
  */\r
 ib_api_status_t\r
-bus_reg_port_pnp( void )\r
+bus_reg_port_pnp( IN bus_filter_t *p_bfi )\r
 {\r
        ib_pnp_req_t                    pnp_req;\r
-       ib_api_status_t                 status;\r
+       ib_api_status_t                 status = IB_SUCCESS;\r
+       boolean_t                               need_pnp_reg = FALSE;\r
 \r
-       cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) );\r
-       pnp_req.pnp_class       = IB_PNP_PORT | IB_PNP_FLAG_REG_SYNC;\r
-       pnp_req.pnp_context = gp_port_mgr;\r
-       pnp_req.pfn_pnp_cb      = port_mgr_pnp_cb;\r
+       /* only need to register for port PNP events once.\r
+        * Do not hold mutex over pnp_reg() call as callback which needs mutex\r
+        * could occur.\r
+        */\r
+       if ( !bus_globals.h_pnp_port )\r
+       {\r
+               ExAcquireFastMutexUnsafe(&ControlMutex);\r
+               if ( !bus_globals.h_pnp_port ) {\r
+                       bus_globals.h_pnp_port = (ib_pnp_handle_t)1; /* block others */\r
+                       need_pnp_reg = TRUE;\r
+               }\r
+               ExReleaseFastMutexUnsafe(&ControlMutex);\r
+\r
+               if ( need_pnp_reg )\r
+               {\r
+                       cl_memclr( &pnp_req, sizeof( ib_pnp_req_t ) );\r
+                       pnp_req.pnp_class       = IB_PNP_PORT | IB_PNP_FLAG_REG_SYNC;\r
+                       pnp_req.pnp_context = NULL;\r
+                       pnp_req.pfn_pnp_cb      = port_mgr_pnp_cb;\r
 \r
-       status = ib_reg_pnp( gh_al, &pnp_req, &gp_port_mgr->h_pnp );\r
+                       status = ib_reg_pnp( gh_al, &pnp_req, &bus_globals.h_pnp_port );\r
+               }\r
+       }\r
 \r
-       if( status == IB_SUCCESS )\r
+       if ( status == IB_SUCCESS )\r
        {\r
-               /* Reference the load service on behalf of the ib_reg_pnp call. */\r
-               cl_obj_ref( &gp_port_mgr->obj );\r
+               /* Reference this bus filter's port load service */\r
+               cl_obj_ref( &p_bfi->p_port_mgr->obj );\r
        }\r
 \r
        return status;\r
@@ -445,12 +521,11 @@ ib_api_status_t
 port_mgr_pnp_cb(\r
        IN                              ib_pnp_rec_t*                           p_pnp_rec )\r
 {\r
-       ib_api_status_t         status;\r
+       ib_api_status_t         status=IB_SUCCESS;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
        CL_ASSERT( p_pnp_rec );\r
-       CL_ASSERT( gp_port_mgr == p_pnp_rec->pnp_context );\r
 \r
        switch( p_pnp_rec->pnp_event )\r
        {\r
@@ -460,12 +535,15 @@ port_mgr_pnp_cb(
 \r
        case IB_PNP_PORT_REMOVE:\r
                port_mgr_port_remove( (ib_pnp_port_rec_t*)p_pnp_rec );\r
+               break;\r
 \r
        default:\r
-               status = IB_SUCCESS;\r
+               XBUS_PRINT( BUS_DBG_PNP, ("%s() Unhandled PNP Event %s\n",\r
+                                       __FUNCTION__, ib_get_pnp_event_str(p_pnp_rec->pnp_event) ));\r
                break;\r
        }\r
        BUS_EXIT( BUS_DBG_PNP );\r
+\r
        return status;\r
 }\r
 \r
@@ -479,9 +557,50 @@ port_mgr_get_bus_relations(
        IN                              IRP* const                                      p_irp )\r
 {\r
        NTSTATUS                        status;\r
+       bus_filter_t            *p_bfi;\r
+       port_mgr_t                      *gp_port_mgr;\r
+       DEVICE_RELATIONS        *p_rel;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
+       BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid %I64x\n",__FUNCTION__,ca_guid));\r
+\r
+       /* special case guid == 0 - walk all bus filter instances */\r
+       if ( ca_guid == 0ULL ) {\r
+               for(p_bfi=bus_filters; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) {\r
+                       gp_port_mgr = p_bfi->p_port_mgr;\r
+                       if ( !gp_port_mgr )\r
+                               continue;\r
+                       cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
+                       status = bus_get_relations( &gp_port_mgr->port_list,\r
+                                                                               ca_guid,\r
+                                                                               p_irp );\r
+                       cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
+               }\r
+\r
+               p_rel = (DEVICE_RELATIONS*)p_irp->IoStatus.Information;\r
+               if ( p_rel ) {\r
+                       BUS_PRINT(BUS_DBG_PNP, ("%s() ca_guid 0 Reports %d\n",\r
+                                               __FUNCTION__,p_rel->Count));\r
+               }\r
+               BUS_EXIT( BUS_DBG_PNP );\r
+               return STATUS_SUCCESS;\r
+       }\r
+\r
+       p_bfi = get_bfi_by_ca_guid(ca_guid);\r
+       if (p_bfi == NULL) {\r
+               BUS_PRINT(BUS_DBG_PNP,\r
+                       ("%s() Null *p_bfi from ca_guid %I64x\n",__FUNCTION__,ca_guid));\r
+               BUS_EXIT( BUS_DBG_PNP );\r
+               return STATUS_NO_SUCH_DEVICE;\r
+       }\r
+       gp_port_mgr = p_bfi->p_port_mgr;\r
+\r
+       BUS_PRINT(BUS_DBG_PNP, ("%s(%s) for ca_guid %I64x port_mgr %p\n",\r
+                               __FUNCTION__, p_bfi->whoami, ca_guid, gp_port_mgr) );\r
+       if (!gp_port_mgr)\r
+               return STATUS_NO_SUCH_DEVICE;\r
+\r
        cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
        status = bus_get_relations( &gp_port_mgr->port_list, ca_guid, p_irp );\r
        cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
@@ -492,14 +611,17 @@ port_mgr_get_bus_relations(
 \r
 static ib_api_status_t\r
 __port_was_hibernated(\r
-       IN                              ib_pnp_port_rec_t*                      p_pnp_rec )\r
+       IN                              ib_pnp_port_rec_t*                      p_pnp_rec,\r
+       IN                              bus_filter_t*                           p_bfi )\r
 {\r
        NTSTATUS                status;\r
-       cl_list_item_t          *p_list_item;\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
        size_t                  n_devs = 0;\r
-       cl_qlist_t*             p_pdo_list = &gp_port_mgr->port_list;\r
+       port_mgr_t              *gp_port_mgr = p_bfi->p_port_mgr;\r
+       cl_qlist_t              *p_pdo_list = &gp_port_mgr->port_list;\r
+       port_pnp_ctx_t  *p_ctx = p_pnp_rec->pnp_rec.context;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
        \r
@@ -520,9 +642,11 @@ __port_was_hibernated(
                        break;\r
                }\r
 \r
-               BUS_TRACE( BUS_DBG_PNP, \r
-                       ("Skipped PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
-                       p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, \r
+               BUS_TRACE( BUS_DBG_PNP, ("%s Skipped 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
+                       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
@@ -533,27 +657,33 @@ __port_was_hibernated(
                p_pdo_ext->h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid );\r
                if( !p_pdo_ext->h_ca )\r
                {\r
-                       BUS_TRACE( BUS_DBG_ERROR, ("acquire_ca failed to find CA by guid %I64x\n",\r
-                               p_pnp_rec->p_ca_attr->ca_guid ) );\r
+                       BUS_TRACE( BUS_DBG_ERROR,\r
+                               ("%s acquire_ca failed to find CA by guid %I64x\n",\r
+                               p_bfi->whoami, p_pnp_rec->p_ca_attr->ca_guid ) );\r
                        status = IB_INVALID_GUID;\r
                }\r
                else \r
                {\r
                        p_pdo_ext->b_hibernating = FALSE;\r
-                       p_pnp_rec->pnp_rec.context = p_pdo_ext;\r
+\r
+                       CL_ASSERT( p_ctx );\r
+                       p_ctx->p_pdo_ext = p_pdo_ext; // save for port_mgr_port_remove\r
+\r
                        status = IB_SUCCESS;\r
                        p_port_ext = (bus_port_ext_t*)p_pdo_ext;\r
-                       BUS_TRACE( BUS_DBG_PNP, \r
-                               ("Found PDO for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d, port_guid %I64x.\n",\r
-                               p_pdo_ext->cl_ext.vfptr_pnp_po->identity, p_pdo_ext->cl_ext.p_self_do, \r
+                       BUS_TRACE( BUS_DBG_PNP, ("%s Found 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
+                               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
        }\r
        else \r
        {\r
-               BUS_TRACE( BUS_DBG_PNP, ("Failed to find PDO for guid  %I64x .\n",\r
-                       p_pnp_rec->p_ca_attr->ca_guid ) );\r
+               BUS_TRACE( BUS_DBG_PNP, ("%s Failed to find PDO for guid  %I64x .\n",\r
+                                       p_bfi->whoami, p_pnp_rec->p_ca_attr->ca_guid ) );\r
                status = IB_NOT_FOUND;\r
        }\r
 \r
@@ -563,6 +693,70 @@ __port_was_hibernated(
        return status;\r
 }\r
 \r
+#if DBG\r
+\r
+void\r
+dump_pnp_port_rec( ib_pnp_port_rec_t*  pr )\r
+{\r
+       BUS_PRINT( BUS_DBG_PNP, ("%s() ib_pnp_port_rec_t* @ %p\nib_pnp_rec_t*:\n",\r
+                               __FUNCTION__,pr));\r
+\r
+\r
+       BUS_PRINT( BUS_DBG_PNP, ("  Event %s\n",\r
+                               ib_get_pnp_event_str(pr->pnp_rec.pnp_event) ));\r
+\r
+       BUS_PRINT( BUS_DBG_PNP, ("  pnp_context %p\n",pr->pnp_rec.pnp_context));\r
+       BUS_PRINT( BUS_DBG_PNP, ("  context %p\n",pr->pnp_rec.context));\r
+       BUS_PRINT( BUS_DBG_PNP, ("  guid %I64x\n",pr->pnp_rec.guid));\r
+       BUS_PRINT( BUS_DBG_PNP, ("  ca_guid %I64x\n",pr->pnp_rec.ca_guid));\r
+\r
+       if ( !pr->p_ca_attr ) {\r
+               BUS_PRINT( BUS_DBG_PNP, ("  NULL *p_ca_attr ?\n"));\r
+       }\r
+       else {\r
+               BUS_PRINT( BUS_DBG_PNP, ("*p_ca_attr\n"));\r
+               BUS_PRINT( BUS_DBG_PNP, ("  ca_guid 0x%I64x\n",\r
+                                                               pr->p_ca_attr->ca_guid ) );\r
+       }\r
+       if ( !pr->p_port_attr ) {\r
+               BUS_PRINT( BUS_DBG_PNP, ("  NULL *p_port_attr?\n"));\r
+       }\r
+       else {\r
+               BUS_PRINT( BUS_DBG_PNP, ("*p_port_attr:\n"));\r
+               BUS_PRINT( BUS_DBG_PNP, ("  port_guid 0x%I64x port_num %d\n",\r
+                                                               pr->p_port_attr->port_guid,\r
+                                                               pr->p_port_attr->port_num ));\r
+       }\r
+}\r
+\r
+void\r
+dump_pnp_iou_rec( ib_pnp_iou_rec_t*    pr )\r
+{\r
+       BUS_PRINT( BUS_DBG_PNP, ("%s() ib_pnp_iou_rec_t* @ %p\nib_pnp_rec_t*:\n",\r
+                               __FUNCTION__,pr));\r
+\r
+\r
+       BUS_PRINT( BUS_DBG_PNP, ("  Event %s\n",\r
+                               ib_get_pnp_event_str(pr->pnp_rec.pnp_event) ));\r
+\r
+       BUS_PRINT( BUS_DBG_PNP, ("  pnp_context %p\n",pr->pnp_rec.pnp_context));\r
+       BUS_PRINT( BUS_DBG_PNP, ("  context %p\n",pr->pnp_rec.context));\r
+       BUS_PRINT( BUS_DBG_PNP, ("  guid %I64x\n",pr->pnp_rec.guid));\r
+       BUS_PRINT( BUS_DBG_PNP, ("  ca_guid %I64x\n",pr->pnp_rec.ca_guid));\r
+\r
+       BUS_PRINT( BUS_DBG_PNP, ("pnp_iou_rec_t:\n" ));\r
+       BUS_PRINT( BUS_DBG_PNP,\r
+                               ("  guid 0x%I64x\n  ca_guid %I64x\n  chassis_guid %I64x\n",\r
+                               pr->guid, pr->ca_guid, pr->chassis_guid ));\r
+       BUS_PRINT( BUS_DBG_PNP,\r
+                               ("  slot 0x%x\n  vend_id 0x%x\n  dev_id 0x%x  revision 0x%x\n",\r
+                               pr->slot, pr->vend_id, pr->dev_id, pr->revision ));\r
+       if ( pr->desc[0] ) {\r
+               BUS_PRINT( BUS_DBG_PNP, ("  Desc %s\n",pr->desc ));\r
+       }\r
+}\r
+#endif\r
+\r
 \r
 ib_api_status_t\r
 port_mgr_port_add(\r
@@ -573,181 +767,158 @@ port_mgr_port_add(
     uint8_t         num_pdo;\r
        bus_port_ext_t  *p_port_ext;\r
        ib_net16_t      pdo_cnt;\r
-       pkey_conf_t             *cur_conf; \r
-       pkey_array_t    *cur_pkeys = NULL;\r
+       bus_filter_t    *p_bfi;\r
+       port_mgr_t              *gp_port_mgr;\r
+       port_pnp_ctx_t  *p_ctx = p_pnp_rec->pnp_rec.context;\r
+\r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
+       CL_ASSERT( p_pnp_rec->p_ca_attr->ca_guid );\r
+\r
+       p_bfi = get_set_bfi_by_ca_guid( p_pnp_rec->p_ca_attr->ca_guid );\r
+       if ( !p_bfi ) {\r
+               BUS_TRACE_EXIT( BUS_DBG_PNP,("%s() NULL p_bfi? ca_guid 0x%I64x\n",\r
+                                                               __FUNCTION__, p_pnp_rec->p_ca_attr->ca_guid ) );\r
+               return IB_ERROR;\r
+       }\r
+\r
+       /*\r
+        * Allocate a PNP context for this object. pnp_rec.context is obj unique.\r
+        */\r
+       if ( !p_ctx ) {\r
+               p_ctx = cl_zalloc( sizeof(*p_ctx) );\r
+               if( !p_ctx )\r
+               {\r
+                       BUS_TRACE_EXIT(BUS_DBG_PNP,\r
+                                       ("%s(%s) ca_guid %I64x port(%d) BAD alloc PNP context\n",\r
+                                       __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, \r
+                                       p_pnp_rec->p_port_attr->port_num));\r
+                       return IB_ERROR;\r
+               }\r
+               p_ctx->p_bus_filter = p_bfi;\r
+               p_ctx->port_num = p_pnp_rec->p_port_attr->port_num;\r
+               p_pnp_rec->pnp_rec.context = p_ctx;\r
+\r
+               BUS_PRINT(BUS_DBG_PNP,\r
+                                       ("%s(%s) ca_guid %I64x port %d ALLOC p_ctx @ %p\n",\r
+                                       __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid, \r
+                                       p_pnp_rec->p_port_attr->port_num,p_ctx));\r
+       }\r
+       gp_port_mgr = p_bfi->p_port_mgr;\r
+\r
        if( !bus_globals.b_report_port_nic )\r
        {\r
                BUS_EXIT( BUS_DBG_PNP );\r
                return IB_NOT_DONE;\r
        }\r
 \r
-       /* Upon hibernating of the computer IB_BUS driver doesn't remove PDO, but\r
+       /* Upon hibernating the computer IB_BUS driver doesn't remove PDO, but\r
           marks with a flag. So we first try to find an existing PDO for this port,\r
-          marked with this flag. If it was found, we turn off the flag and use this PDO */\r
-       status = __port_was_hibernated(p_pnp_rec);\r
+          marked with this flag. If it was found, we turn off the flag and use\r
+          this PDO */\r
+       status = __port_was_hibernated( p_pnp_rec, p_bfi );\r
        if( status != IB_NOT_FOUND )\r
        {\r
                BUS_EXIT( BUS_DBG_PNP );\r
                return status;\r
        }\r
 \r
-       cur_conf = bus_globals.p_pkey_conf;\r
-       while(cur_conf)\r
-       {\r
-               if(p_pnp_rec->p_port_attr->port_guid == cur_conf->pkeys_per_port.port_guid)\r
-               {\r
-                       cur_pkeys = &cur_conf->pkeys_per_port;\r
-                       break;\r
-               }\r
-               cur_conf = cur_conf->next_conf;\r
-       }\r
     p_port_ext = NULL;\r
 \r
-       if( !cur_pkeys)\r
+       if( pkeys_enumerated)\r
                pdo_cnt = 1;\r
        else\r
-               pdo_cnt = cur_conf->pkeys_per_port.pkey_num + 1;\r
+               pdo_cnt = g_pkeys.pkey_num + 1;\r
 \r
     for (num_pdo = 0; num_pdo < pdo_cnt; num_pdo++)\r
     {\r
-       /* Create the PDO for the new port device. */\r
-       status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_port_ext_t),\r
-               NULL, FILE_DEVICE_CONTROLLER,\r
-               FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,\r
-                       FALSE, &p_pdo[num_pdo] );\r
-       if( !NT_SUCCESS( status ) )\r
-       {\r
-               BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
-                       ("IoCreateDevice returned %08x.\n", status) );\r
-               return IB_ERROR;\r
-       }\r
+               /* Create the PDO for the new port device. */\r
+               status = IoCreateDevice( bus_globals.p_driver_obj,\r
+                                                                sizeof(bus_port_ext_t),\r
+                                                                NULL, FILE_DEVICE_CONTROLLER,\r
+                                                                FILE_DEVICE_SECURE_OPEN |\r
+                                                                                       FILE_AUTOGENERATED_DEVICE_NAME,\r
+                                                                FALSE, &p_pdo[num_pdo] );\r
+               if( !NT_SUCCESS( status ) )\r
+               {\r
+                       BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
+                               ("IoCreateDevice returned %08x.\n", status) );\r
+                       return IB_ERROR;\r
+               }\r
 \r
-       /* Initialize the device extension. */\r
-               cl_init_pnp_po_ext( p_pdo[num_pdo], NULL, p_pdo[num_pdo], bus_globals.dbg_lvl,\r
-               &vfptr_port_pnp, &vfptr_port_query_txt );\r
+               /* Initialize the device extension. */\r
+               cl_init_pnp_po_ext( p_pdo[num_pdo], NULL, p_pdo[num_pdo],\r
+                                                       bus_globals.dbg_lvl, &vfptr_port_pnp,\r
+                                                       &vfptr_port_query_txt );\r
 \r
-       /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */\r
+               /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */\r
                p_pdo[num_pdo]->Flags |= DO_BUS_ENUMERATED_DEVICE;\r
 \r
                p_port_ext = p_pdo[num_pdo]->DeviceExtension;\r
-       p_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;\r
-       p_port_ext->pdo.p_parent_ext = bus_globals.p_bus_ext;\r
-       p_port_ext->pdo.b_present = TRUE;\r
-       p_port_ext->pdo.b_reported_missing = FALSE;\r
-       p_port_ext->pdo.b_hibernating = FALSE;\r
-       p_port_ext->pdo.p_po_work_item = NULL;\r
-       BUS_TRACE( BUS_DBG_PNP, ("Created device for %s: PDO %p,ext %p, present %d, missing %d .\n",\r
-                       p_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[num_pdo], p_port_ext, p_port_ext->pdo.b_present, \r
-               p_port_ext->pdo.b_reported_missing ) );\r
-\r
-       /* Cache the CA GUID. */\r
-       p_port_ext->pdo.ca_guid = p_pnp_rec->p_ca_attr->ca_guid;\r
-\r
-       /* Take a reference on the parent HCA. */\r
+               p_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;\r
+               p_port_ext->pdo.p_parent_ext = p_bfi->p_bus_ext;\r
+               p_port_ext->pdo.b_present = TRUE;\r
+               p_port_ext->pdo.b_reported_missing = FALSE;\r
+               p_port_ext->pdo.b_hibernating = FALSE;\r
+               p_port_ext->pdo.p_po_work_item = NULL;\r
+               BUS_TRACE( BUS_DBG_PNP,\r
+                       ("Created %s %s: PDO %p,ext %p, present %d, missing %d .\n",\r
+                       p_bfi->whoami,\r
+                       p_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[num_pdo],\r
+                       p_port_ext, p_port_ext->pdo.b_present,\r
+                       p_port_ext->pdo.b_reported_missing ) );\r
+\r
+               /* Cache the CA GUID. */\r
+               p_port_ext->pdo.ca_guid = p_pnp_rec->p_ca_attr->ca_guid;\r
+\r
+               /* Take a reference on the parent HCA. */\r
                if(num_pdo > 0)\r
                {\r
                        p_port_ext->pdo.h_ca = ((bus_port_ext_t*)p_pdo[0]->DeviceExtension)->pdo.h_ca;\r
-                       p_port_ext->pdo.is_partition_pdo = TRUE;\r
                }\r
                else\r
-       p_port_ext->pdo.h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid );\r
-       if( !p_port_ext->pdo.h_ca )\r
-       {\r
+                       p_port_ext->pdo.h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid );\r
+\r
+               if( !p_port_ext->pdo.h_ca )\r
+               {\r
                        BUS_TRACE( BUS_DBG_PNP, ("Deleted device: PDO %p\n", p_pdo[num_pdo]));\r
                        IoDeleteDevice( p_pdo[num_pdo]);\r
-               BUS_TRACE_EXIT( BUS_DBG_ERROR, ("acquire_ca failed to find CA.\n") );\r
-               return IB_INVALID_GUID;\r
-       }\r
+                       BUS_TRACE_EXIT( BUS_DBG_ERROR, ("acquire_ca failed to find CA.\n") );\r
+                       return IB_INVALID_GUID;\r
+               }\r
                p_port_ext->port_guid.guid = p_pnp_rec->p_port_attr->port_guid;\r
-       p_port_ext->n_port = p_pnp_rec->p_port_attr->port_num;\r
+               p_port_ext->n_port = p_pnp_rec->p_port_attr->port_num;\r
                p_port_ext->port_guid.pkey = IB_DEFAULT_PKEY;\r
+               p_port_ext->n_ifc_ref = 0;\r
 \r
                if(num_pdo > 0)\r
-                       p_port_ext->port_guid.pkey = cur_pkeys->pkey_array[num_pdo -1];\r
+               {\r
+                 p_port_ext->port_guid.pkey = g_pkeys.pkey_array[num_pdo -1];\r
+               }\r
 \r
-       /* Store the device extension in the port vector for future queries. */\r
-       cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
-       cl_qlist_insert_tail( &gp_port_mgr->port_list,\r
-               &p_port_ext->pdo.list_item );\r
-       cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
+               /* Store the device extension in the port vector for future queries. */\r
+               cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
+               cl_qlist_insert_tail( &gp_port_mgr->port_list,\r
+                                                         &p_port_ext->pdo.list_item );\r
+               cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
 \r
-       /*\r
-        * Set the context of the PNP event.  The context is passed in for future\r
-        * events on the same port.\r
-        */\r
+               /*\r
+                * save the port_ext, as the context is passed in for future events on\r
+                * the same port.\r
+                */\r
                if(num_pdo == 0)\r
-                       p_pnp_rec->pnp_rec.context = p_port_ext;\r
+                       p_ctx->p_pdo_ext = p_port_ext;\r
        }\r
+       pkeys_enumerated = TRUE;\r
 \r
        /* Tell the PnP Manager to rescan for the HCA's bus relations. */\r
        IoInvalidateDeviceRelations(\r
                p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
 \r
-       /* Invalidate removal relations for the bus driver. */\r
-       IoInvalidateDeviceRelations(\r
-               bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations );\r
-\r
        BUS_EXIT( BUS_DBG_PNP );\r
        return IB_SUCCESS;\r
 }\r
 \r
-/************************************************************************************\r
-* name :       port_mgr_pkey_rem\r
-*           removes pdo for each pkey value in pkey_array \r
-* input        :       g_pkeys\r
-* output:      none\r
-* return:      cl_status\r
-*************************************************************************************/\r
-cl_status_t port_mgr_pkey_rem(pkey_array_t *pkeys)\r
-{\r
-\r
-       uint16_t                        cnt;\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
-       cl_qlist_t*                     p_pdo_list = &gp_port_mgr->port_list;\r
-\r
-       BUS_ENTER( BUS_DBG_PNP );\r
-\r
-       p_port_ext = NULL;\r
-       cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
-       \r
-       /* Count the number of child devices. */\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 == pkeys->port_guid)\r
-               {\r
-                       for(cnt = 0; cnt < pkeys->pkey_num; cnt++)\r
-                       {\r
-                               if( (p_port_ext->port_guid.pkey == pkeys->pkey_array[cnt]) &&\r
-                                       (p_port_ext->port_guid.pkey != IB_DEFAULT_PKEY))\r
-                               {\r
-                                       p_port_ext->pdo.b_present = FALSE;\r
-                                       break;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
-\r
-       /* Tell the PnP Manager to rescan for the HCA's bus relations. */\r
-       IoInvalidateDeviceRelations(\r
-               p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
-\r
-       /* Invalidate removal relations for the bus driver. */\r
-       IoInvalidateDeviceRelations(\r
-               bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations );\r
-\r
-       BUS_EXIT( BUS_DBG_PNP );\r
-       return CL_SUCCESS;\r
-}\r
 /************************************************************************************\r
 * name :       port_mgr_pkey_add\r
 *           creates pdo for each pkey value in pkey_array \r
@@ -755,64 +926,53 @@ cl_status_t port_mgr_pkey_rem(pkey_array_t *pkeys)
 * output:      none\r
 * return:      cl_status\r
 *************************************************************************************/\r
-cl_status_t port_mgr_pkey_add(pkey_array_t *req_pkeys)\r
+cl_status_t _port_mgr_pkey_add ( IN    pkey_array_t    *pkeys,\r
+                                                                IN     bus_filter_t    *p_bfi,\r
+                                                                IN     port_mgr_t              *gp_port_mgr )\r
 {\r
        uint16_t                        cnt;\r
        NTSTATUS            status;\r
        cl_list_item_t          *p_list_item;\r
-       bus_port_ext_t          *p_port_ext, *pkey_port_ext, *pmatched_guid_ext;\r
+       bus_port_ext_t          *p_port_ext, *pkey_port_ext;\r
        DEVICE_OBJECT       *p_pdo[MAX_NUM_PKEY];\r
-       cl_qlist_t*                     p_pdo_list = &gp_port_mgr->port_list;\r
+       bus_pdo_ext_t           *p_pdo_ext = NULL;\r
+       cl_qlist_t*                     p_pdo_list;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
-       pmatched_guid_ext = NULL;\r
        p_port_ext = NULL;\r
        cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
+       p_pdo_list = &gp_port_mgr->port_list;\r
        \r
        /* Count the number of child devices. */\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_port_ext = (bus_port_ext_t*)PARENT_STRUCT( p_list_item, bus_pdo_ext_t, list_item );\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 == req_pkeys->port_guid)\r
-               {\r
-                       uint16_t i;\r
-                       for(i = 0; i < req_pkeys->pkey_num; i++)\r
-                       {\r
-                               if(p_port_ext->port_guid.pkey == req_pkeys->pkey_array[i])\r
-                               {\r
-                                       /* was removed previously */\r
-                                       p_port_ext->pdo.b_present = TRUE;\r
-                                       p_port_ext->pdo.b_reported_missing = FALSE;\r
-                                       req_pkeys->pkey_array[i] = 0;  \r
-                               }\r
-                       }\r
-                       if(!pmatched_guid_ext)\r
-                               pmatched_guid_ext = p_port_ext;\r
-               }\r
+               if(p_port_ext->port_guid.pkey != IB_DEFAULT_PKEY)\r
+                       break;\r
        }\r
        cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
 \r
-       if (!pmatched_guid_ext)\r
+       if (!p_port_ext)\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
-                       ("No existed pdo found.\n") );\r
-               return CL_NOT_FOUND;\r
+                       ("No existing pdo found.\n") );\r
+               return CL_ERROR;\r
        }\r
 \r
-    for (cnt = 0; cnt < req_pkeys->pkey_num; cnt++)\r
+    for (cnt = 0; cnt < pkeys->pkey_num; cnt++)\r
     {\r
-               if(! (cl_hton16(req_pkeys->pkey_array[cnt]) & IB_PKEY_BASE_MASK) )\r
-                       continue;\r
-\r
                /* Create the PDO for the new port device. */\r
-               status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_port_ext_t),\r
-                       NULL, FILE_DEVICE_CONTROLLER,\r
-                       FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,\r
-                       FALSE, &p_pdo[cnt] );\r
+               status = IoCreateDevice( bus_globals.p_driver_obj,\r
+                                                                sizeof(bus_port_ext_t),\r
+                                                                NULL, FILE_DEVICE_CONTROLLER,\r
+                                                                FILE_DEVICE_SECURE_OPEN\r
+                                                                                       | FILE_AUTOGENERATED_DEVICE_NAME,\r
+                                                                FALSE, &p_pdo[cnt] );\r
                if( !NT_SUCCESS( status ) )\r
                {\r
                        BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
@@ -822,29 +982,31 @@ cl_status_t port_mgr_pkey_add(pkey_array_t *req_pkeys)
        \r
                /* Initialize the device extension. */\r
                cl_init_pnp_po_ext( p_pdo[cnt], NULL, p_pdo[cnt], bus_globals.dbg_lvl,\r
-                       &vfptr_port_pnp, &vfptr_port_query_txt );\r
+                                                       &vfptr_port_pnp, &vfptr_port_query_txt );\r
        \r
                /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */\r
                p_pdo[cnt]->Flags |= DO_BUS_ENUMERATED_DEVICE;\r
        \r
                pkey_port_ext = p_pdo[cnt]->DeviceExtension;\r
                pkey_port_ext->pdo.dev_po_state.DeviceState = PowerDeviceD0;\r
-               pkey_port_ext->pdo.p_parent_ext = bus_globals.p_bus_ext;\r
+               pkey_port_ext->pdo.p_parent_ext = p_bfi->p_bus_ext;\r
                pkey_port_ext->pdo.b_present = TRUE;\r
                pkey_port_ext->pdo.b_reported_missing = FALSE;\r
                pkey_port_ext->pdo.b_hibernating = FALSE;\r
                pkey_port_ext->pdo.p_po_work_item = NULL;\r
-               BUS_TRACE( BUS_DBG_PNP, ("Created device for %s: PDO %p,ext %p, present %d, missing %d .\n",\r
-                       pkey_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[cnt], pkey_port_ext, pkey_port_ext->pdo.b_present, \r
+               BUS_TRACE( BUS_DBG_PNP,\r
+                       ("Created device for %s: PDO %p,ext %p, present %d, missing %d\n",\r
+                       pkey_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[cnt],\r
+                       pkey_port_ext, pkey_port_ext->pdo.b_present, \r
                        pkey_port_ext->pdo.b_reported_missing ) );\r
        \r
                /* Cache the CA GUID. */\r
-               pkey_port_ext->pdo.ca_guid = pmatched_guid_ext->pdo.ca_guid;\r
-               pkey_port_ext->pdo.h_ca = pmatched_guid_ext->pdo.h_ca;\r
-               pkey_port_ext->port_guid.guid = pmatched_guid_ext->port_guid.guid;\r
-               pkey_port_ext->n_port = pmatched_guid_ext->n_port;\r
-               pkey_port_ext->port_guid.pkey = req_pkeys->pkey_array[cnt];\r
-               pkey_port_ext->pdo.is_partition_pdo = TRUE;\r
+               pkey_port_ext->pdo.ca_guid = p_port_ext->pdo.ca_guid;\r
+               pkey_port_ext->pdo.h_ca = p_port_ext->pdo.h_ca;\r
+               pkey_port_ext->port_guid.guid = p_port_ext->port_guid.guid;\r
+               pkey_port_ext->n_port = p_port_ext->n_port;\r
+               pkey_port_ext->port_guid.pkey = pkeys->pkey_array[cnt];\r
+\r
                /* Store the device extension in the port vector for future queries. */\r
                cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
                cl_qlist_insert_tail( &gp_port_mgr->port_list,\r
@@ -854,27 +1016,83 @@ cl_status_t port_mgr_pkey_add(pkey_array_t *req_pkeys)
 \r
        /* Tell the PnP Manager to rescan for the HCA's bus relations. */\r
        IoInvalidateDeviceRelations(\r
-               pmatched_guid_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
-\r
-       /* Invalidate removal relations for the bus driver. */\r
-       IoInvalidateDeviceRelations(\r
-               bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations );\r
+               p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
        return CL_SUCCESS;\r
 }\r
 \r
+\r
+cl_status_t port_mgr_pkey_add(pkey_array_t *pkeys)\r
+{\r
+       bus_filter_t    *p_bfi;\r
+       cl_status_t             status;\r
+       boolean_t               GO;\r
+       int                             success_cnt=0;\r
+\r
+       for(p_bfi=&bus_filters[0]; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++)\r
+       {\r
+               if ( !p_bfi->p_bus_ext )\r
+                       continue;\r
+               GO = FALSE;\r
+               ExAcquireFastMutexUnsafe(&ControlMutex);\r
+               if ( p_bfi->ca_guid && p_bfi->p_port_mgr )\r
+                       GO = TRUE;\r
+               ExReleaseFastMutexUnsafe(&ControlMutex);\r
+               if ( GO == FALSE )\r
+                       continue;\r
+               status = _port_mgr_pkey_add( pkeys, p_bfi, p_bfi->p_port_mgr );\r
+               if ( status == CL_SUCCESS )\r
+                       success_cnt++;\r
+       }\r
+       return ( success_cnt ? CL_SUCCESS : CL_ERROR );\r
+}\r
+\r
+\r
 void\r
 port_mgr_port_remove(\r
-       IN                              ib_pnp_port_rec_t*                      p_pnp_rec )\r
+       IN                              ib_pnp_port_rec_t*              p_pnp_rec )\r
 {\r
        bus_pdo_ext_t   *p_ext;\r
+       port_mgr_t              *gp_port_mgr;\r
+       bus_filter_t    *p_bfi;\r
+       port_pnp_ctx_t  *p_ctx = p_pnp_rec->pnp_rec.context;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
-       /* The PNP record's context is the port extension. */\r
-       p_ext = p_pnp_rec->pnp_rec.context;\r
+       if ( !p_ctx ) {\r
+               BUS_EXIT( BUS_DBG_PNP );\r
+               return;\r
+       }\r
+\r
+       CL_ASSERT( p_ctx->p_bus_filter->magic == BFI_MAGIC );\r
+       p_bfi = p_ctx->p_bus_filter;\r
+       CL_ASSERT( p_bfi );\r
+\r
+       BUS_PRINT(BUS_DBG_PNP,("%s(%s) ca_guid 0x%I64x port_num %d port_mgr %p\n",\r
+                                               __FUNCTION__, p_bfi->whoami, p_bfi->ca_guid,\r
+                                               p_ctx->port_num, p_bfi->p_port_mgr));\r
+\r
+       /* in the process of device remove, port_mgr has been destroyed.\r
+        * cleanup allocated PNP port context; one per port.\r
+        * The issue is the PNP PORT_REMOVE event occurs after\r
+        * fdo_release_resources() completes.\r
+        */\r
+       if ( p_bfi->ca_guid == 0ULL || !p_bfi->p_port_mgr ) {\r
+               cl_free( p_ctx );\r
+               p_pnp_rec->pnp_rec.context = NULL;\r
+               BUS_EXIT( BUS_DBG_PNP );\r
+               return;\r
+       }\r
+\r
+       gp_port_mgr = p_bfi->p_port_mgr;\r
+\r
+       /* Within the PNP record's context is the port extension ptr;\r
+        * see port_was_hibernated().\r
+        */\r
+       p_ext = p_ctx->p_pdo_ext;\r
        CL_ASSERT( p_ext );\r
+       CL_ASSERT(p_bfi == p_ext->p_parent_ext->bus_filter);\r
 \r
        /*\r
         * Flag the port PDO as no longer being present.  We have to wait until\r
@@ -882,32 +1100,44 @@ port_mgr_port_remove(
         * reference on the CA object in order to allow the removal of the HCA\r
         * to proceed should it occur before the port's PDO is cleaned up.\r
         */\r
+       if ( !p_ext->h_ca )\r
+       {\r
+               BUS_TRACE_EXIT( BUS_DBG_PNP, ("%s() %s NULL h_ca? p_ext %p\n",\r
+                                       __FUNCTION__, p_bfi->whoami, p_ext ) );\r
+               return;\r
+       }\r
+\r
        cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
        CL_ASSERT( p_ext->h_ca );\r
 \r
        if( p_ext->b_hibernating )\r
        {\r
-               BUS_TRACE( BUS_DBG_PNP, ("Skip port removing for %s: PDO %p, ext %p, present %d, missing %d, hibernating %d .\n",\r
-                       p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do, p_ext, p_ext->b_present, \r
-                       p_ext->b_reported_missing, p_ext->b_hibernating ) );\r
+               BUS_TRACE( BUS_DBG_PNP, ("Skip port removing for %s: PDO %p, ext %p, "\r
+                       "present %d, missing %d, hibernating %d .\n",\r
+                       p_ext->cl_ext.vfptr_pnp_po->identity, p_ext->cl_ext.p_self_do,\r
+                       p_ext, p_ext->b_present, p_ext->b_reported_missing,\r
+                       p_ext->b_hibernating ) );\r
                goto hca_deref;\r
        }\r
 \r
        p_ext->b_present = FALSE;\r
-       BUS_TRACE( BUS_DBG_PNP, ("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, p_ext->b_present, p_ext->b_reported_missing ) );\r
+       p_ext->b_reported_missing = TRUE;\r
 \r
-       /* Invalidate removal relations for the bus driver. */\r
-       IoInvalidateDeviceRelations( bus_globals.p_bus_ext->cl_ext.p_pdo,\r
-               RemovalRelations );\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
+               p_ext->b_present, p_ext->b_reported_missing ) );\r
 \r
        /* Invalidate bus relations for the HCA. */\r
        IoInvalidateDeviceRelations(\r
                p_ext->h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations );\r
 \r
+       /* Free PNP context memory */\r
+       cl_free( p_ctx );\r
+       p_pnp_rec->pnp_rec.context = NULL;\r
+\r
 hca_deref:\r
        deref_al_obj( &p_ext->h_ca->obj );\r
-       p_ext->h_ca = NULL;\r
        cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
@@ -931,7 +1161,9 @@ port_start(
        /* Notify the Power Manager that the device is started. */\r
        PoSetPowerState( p_dev_obj, DevicePowerState, p_ext->dev_po_state );\r
        *p_action = IrpComplete;\r
+\r
        BUS_EXIT( BUS_DBG_PNP );\r
+\r
        return STATUS_SUCCESS;\r
 }\r
 \r
@@ -976,14 +1208,17 @@ port_release_resources(
 {\r
        bus_port_ext_t  *p_ext;\r
        POWER_STATE             po_state;\r
+       port_mgr_t              *gp_port_mgr;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
        p_ext = p_dev_obj->DeviceExtension;\r
+       gp_port_mgr = p_ext->pdo.p_parent_ext->bus_filter->p_port_mgr;\r
 \r
        /* Remove this PDO from its list. */\r
        cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
-       BUS_TRACE( BUS_DBG_PNP, ("Removing port from vector: PDO %p, ext %p\n", p_dev_obj, p_ext) );\r
+       BUS_TRACE( BUS_DBG_PNP, ("Removing port from vector: PDO %p, ext %p\n",\r
+                               p_dev_obj, p_ext) );\r
        cl_qlist_remove_item( &gp_port_mgr->port_list, &p_ext->pdo.list_item );\r
        cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
        po_state.DeviceState = PowerDeviceD3;\r
@@ -1013,7 +1248,9 @@ port_remove(
                cl_set_pnp_state( &p_ext->pdo.cl_ext, NotStarted );\r
                /* Don't delete the device.  It may simply be disabled. */\r
                *p_action = IrpComplete;\r
-               BUS_TRACE_EXIT( BUS_DBG_PNP, ("Device still present: PDO %p, ext %p\n", p_dev_obj, p_ext) );\r
+               BUS_TRACE_EXIT( BUS_DBG_PNP,\r
+                               ("Device %s still present: PDO %p, ext %p\n",\r
+                               p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_dev_obj, p_ext) );\r
                return STATUS_SUCCESS;\r
        }\r
 \r
@@ -1022,7 +1259,10 @@ port_remove(
                /* Reset the state to RemovePending.  Complib set it to Deleted. */\r
                cl_rollback_pnp_state( &p_ext->pdo.cl_ext );\r
                *p_action = IrpComplete;\r
-               BUS_TRACE_EXIT( BUS_DBG_PNP, ("Device not reported missing yet: PDO %p, ext %p\n", p_dev_obj, p_ext) );\r
+               BUS_TRACE_EXIT( BUS_DBG_PNP,\r
+                                               ("Device %s not reported missing yet: PDO %p, ext %p\n",\r
+                                               p_ext->pdo.cl_ext.vfptr_pnp_po->identity,\r
+                                               p_dev_obj, p_ext) );\r
                return STATUS_SUCCESS;\r
        }\r
 \r
@@ -1037,7 +1277,9 @@ port_remove(
        IoCompleteRequest( p_irp, IO_NO_INCREMENT );\r
 \r
        BUS_TRACE( BUS_DBG_PNP, ("Deleted device %s: PDO %p(=%p), ext %p\n",\r
-               p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_ext->pdo.cl_ext.p_self_do, p_dev_obj, p_ext ) );\r
+               p_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_ext->pdo.cl_ext.p_self_do,\r
+               p_dev_obj, p_ext ) );\r
+\r
        IoDeleteDevice( p_dev_obj );\r
 \r
        *p_action = IrpDoNothing;\r
@@ -1160,7 +1402,6 @@ port_query_device_id(
 {\r
        WCHAR                           *p_string;\r
        bus_port_ext_t          *p_ext;\r
-       size_t                          dev_id_size;\r
        \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
@@ -1171,24 +1412,17 @@ port_query_device_id(
                BUS_TRACE_EXIT( BUS_DBG_ERROR, ("Device not present.\n") );\r
                return STATUS_NO_SUCH_DEVICE;\r
        }\r
-       if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)\r
-               dev_id_size = sizeof(IPOIB_DEVICE_ID);\r
-       else\r
-               dev_id_size = sizeof(IPOIB_PART_DEVICE_ID );\r
+\r
        /* Device ID is "IBA\SID_<sid> where <sid> is the IPoIB Service ID. */\r
-       p_string = ExAllocatePoolWithTag( PagedPool, dev_id_size, 'vedq' );\r
+       p_string = ExAllocatePoolWithTag( PagedPool, sizeof(IPOIB_DEVICE_ID), 'vedq' );\r
        if( !p_string )\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
                        ("Failed to allocate device ID buffer (%d bytes).\n",\r
-                       dev_id_size) );\r
+                       sizeof(IPOIB_DEVICE_ID)) );\r
                return STATUS_INSUFFICIENT_RESOURCES;\r
        }\r
-\r
-       if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)\r
-               cl_memcpy( p_string, IPOIB_DEVICE_ID, sizeof(IPOIB_DEVICE_ID) );\r
-       else\r
-               cl_memcpy( p_string, IPOIB_PART_DEVICE_ID, sizeof(IPOIB_PART_DEVICE_ID) );\r
+       cl_memcpy( p_string, IPOIB_DEVICE_ID, sizeof(IPOIB_DEVICE_ID) );\r
        p_irp->IoStatus.Information = (ULONG_PTR)p_string;\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
@@ -1203,30 +1437,26 @@ port_query_hardware_ids(
 {\r
        WCHAR                           *p_string;\r
        bus_port_ext_t          *p_ext;\r
-       size_t                          dev_id_size;\r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
 \r
        p_ext = (bus_port_ext_t*)p_dev_obj->DeviceExtension;\r
+       if( !p_ext->pdo.b_present )\r
+       {\r
+               BUS_TRACE_EXIT( BUS_DBG_ERROR, ("Device not present.\n") );\r
+               return STATUS_NO_SUCH_DEVICE;\r
+       }\r
 \r
-       if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)\r
-               dev_id_size = sizeof(IPOIB_HARDWARE_ID);\r
-       else\r
-               dev_id_size = sizeof(IPOIB_PART_HARDWARE_ID );\r
-\r
-       p_string = ExAllocatePoolWithTag( PagedPool, dev_id_size, 'ihqp' );\r
+       p_string = ExAllocatePoolWithTag( PagedPool, sizeof(IPOIB_HARDWARE_ID), 'ihqp' );\r
        if( !p_string )\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
                        ("Failed to allocate hardware ID buffer (%d bytes).\n",\r
-                       dev_id_size) );\r
+                       sizeof(IPOIB_HARDWARE_ID)) );\r
                return STATUS_INSUFFICIENT_RESOURCES;\r
        }\r
-       if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)\r
-               cl_memcpy( p_string, IPOIB_HARDWARE_ID, sizeof(IPOIB_HARDWARE_ID) );\r
-       else\r
-               cl_memcpy( p_string, IPOIB_PART_HARDWARE_ID, sizeof(IPOIB_PART_HARDWARE_ID) );\r
+       cl_memcpy( p_string, IPOIB_HARDWARE_ID, sizeof(IPOIB_HARDWARE_ID) );\r
        p_irp->IoStatus.Information = (ULONG_PTR)p_string;\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
@@ -1475,7 +1705,6 @@ port_query_ipoib_ifc(
        ipoib_ifc_data_t                *p_ipoib_data;\r
        bus_port_ext_t                  *p_ext;\r
        const GUID                              *p_guid;\r
-       \r
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
@@ -1565,9 +1794,7 @@ port_query_interface(
 \r
        BUS_ENTER( BUS_DBG_PNP );\r
 \r
-#pragma warning( push, 3 )\r
        PAGED_CODE();\r
-#pragma warning( pop )\r
 \r
        p_io_stack = IoGetCurrentIrpStackLocation( p_irp );\r
 \r
index 9bb70f0..1d0eb7f 100644 (file)
@@ -43,7 +43,6 @@
 typedef struct _port_mgr\r
 {\r
        cl_obj_t                                        obj;\r
-       ib_pnp_handle_t                         h_pnp;  /* Handle for port PnP events */\r
 \r
        /* Mutex protects both pointer vectors. */\r
        cl_mutex_t                                      pdo_mutex;\r
@@ -54,8 +53,11 @@ typedef struct _port_mgr
 }      port_mgr_t;\r
 \r
 \r
+struct _bus_filter_instance;\r
+\r
 ib_api_status_t\r
 create_port_mgr(\r
+       IN                              struct _bus_filter_instance     *p_bfi,\r
                OUT                     port_mgr_t** const                      pp_port_mgr );\r
 \r
 \r
index ed2a6a3..a4b77f5 100644 (file)
@@ -628,7 +628,6 @@ xcopy %1\hw\mlx4\kernel\hca\mlx4_hca.cdf %2\HCA\amd64\ /yq
 xcopy %1\hw\mlx4\kernel\hca\mlx4_hca32.cdf %2\HCA\amd64\ /yq\r
 xcopy %1\hw\mlx4\kernel\bus\drv\mlx4_bus.cdf %2\HCA\amd64\ /yq\r
 \r
-\r
 xcopy %1\core\bus\kernel\ib_bus.cdf %2\HCA\amd64\ /yq\r
 xcopy %1\core\iou\kernel\ib_iou.cdf %2\HCA\amd64\ /yq\r
 xcopy %1\core\winverbs\kernel\winverbs.cdf %2\HCA\amd64\ /yq\r
@@ -644,6 +643,8 @@ rem xcopy %1\hw\mlx4\kernel\bus\drv\mlx4_bus.cdf %2\HCA\ia64\ /yq
 \r
 xcopy %1\core\bus\kernel\ib_bus.cdf %2\HCA\ia64\ /yq\r
 xcopy %1\core\iou\kernel\ib_iou.cdf %2\HCA\ia64\ /yq\r
+xcopy %1\core\winverbs\kernel\winverbs.cdf %2\HCA\ia64\ /yq\r
+\r
 xcopy %1\hw\mthca\kernel\mthca.cdf %2\HCA\ia64\ /yq\r
 \r
 xcopy %1\ulp\ipoib\kernel\ipoib.cdf %2\net\ia64\ /yq\r
index 20ddfa4..39f0df9 100644 (file)
@@ -10,4 +10,12 @@ CATATTR1=0x10010001:OSAttr:2:6.0
 <hash>mlx4ud.dll=mlx4ud.dll\r
 <hash>mlx4u32.dll=mlx4u32.dll\r
 <hash>mlx4u32d.dll=mlx4u32d.dll\r
-<hash>IbInstaller.dll=IbInstaller.dll\r
+<hash>ibal.dll=ibal.dll\r
+<hash>ibald.dll=ibald.dll\r
+<hash>complib.dll=complib.dll\r
+<hash>complibd.dll=complibd.dll\r
+<hash>cl32.dll=cl32.dll\r
+<hash>cl32d.dll=cl32d.dll\r
+<hash>ibal32.dll=ibal32.dll\r
+<hash>ibal32d.dll=ibal32d.dll\r
+<hash>ibbus.sys=ibbus.sys\r
index 8830bfd..96ba542 100644 (file)
@@ -3,7 +3,7 @@
 \r
 [Version]\r
 Signature="$WINDOWS NT$"\r
-Class=InfiniBandHca\r
+Class=InfiniBandController\r
 ClassGUID={58517E00-D3CF-40c9-A679-CEE5752F4491}\r
 Provider=%MTL%\r
 ; must be synchronized with hca\drv.c\r
@@ -17,28 +17,26 @@ CatalogFile=mlx4_hca.cat
 \r
 [DestinationDirs]\r
 DefaultDestDir = %DIRID_DRIVERS%\r
-ClassCopyFiles = %DIRID_SYSTEM%\r
 MLX4HCA.UMCopyFiles = %DIRID_SYSTEM%\r
 MLX4HCA.WOW64CopyFiles = %DIRID_SYSTEM_X86%\r
 ;Wdf_CoInstaller_CopyFiles = %DIRID_SYSTEM%\r
+Ibal.UMCopyFiles=%DIRID_SYSTEM%\r
+Ibal.WOW64CopyFiles=%DIRID_SYSTEM_X86%\r
+\r
 \r
 ;*****************************************\r
 ; Class Install section\r
 ;*****************************************\r
 \r
 [ClassInstall32]\r
-CopyFiles=ClassCopyFiles\r
 AddReg=ClassAddReg\r
 \r
-[ClassCopyFiles]\r
-IbInstaller.dll\r
-\r
 [ClassAddReg]\r
-HKR,,,,"Mellanox ConnectX Virtual InfiniBand Adapters"\r
+HKR,,,,"InfiniBand Channel Adapters"\r
 HKR,,Icon,,-5\r
-HKR,,SilentInstall,,1\r
-HKLM,"System\CurrentControlSet\Control\CoDeviceInstallers", \\r
- %Mlx4HcaClassGuid%,%REG_MULTI_SZ_APPEND%, "IbInstaller.dll,IbCoInstaller"\r
+HKR,,SilentInstall,,0\r
+HKR,,"UpperFilters",0x00010000,"ibbus" ; enable IBBUS/AL Filter driver loading.\r
+\r
 \r
 ;*****************************************\r
 ; Device Install section\r
@@ -54,29 +52,50 @@ HKLM,"System\CurrentControlSet\Control\CoDeviceInstallers", \
 1=%DiskId%,,,""\r
 \r
 [SourceDisksFiles.x86]\r
-IbInstaller.dll = 1,,\r
 mlx4_hca.sys = 1,,\r
 mlx4u.dll = 1,,\r
 mlx4ud.dll = 1,,\r
 ;wdfcoinstaller01005.dll = 1,,\r
+ibal.dll=1,,\r
+complib.dll=1,,\r
+ibald.dll=1,,\r
+complibd.dll=1,,\r
+ibbus.sys=1,,\r
 \r
 [SourceDisksFiles.amd64]\r
-IbInstaller.dll = 1,,\r
 mlx4_hca.sys = 1,,\r
 mlx4u.dll = 1,,\r
 mlx4ud.dll = 1,,\r
 mlx4u32.dll = 1,,\r
 mlx4u32d.dll = 1,,\r
 ;wdfcoinstaller01005.dll = 1,,\r
+ibal.dll=1,,\r
+ibald.dll=1,,\r
+complib.dll=1,,\r
+complibd.dll=1,,\r
+cl32.dll=1,,\r
+cl32d.dll=1,,\r
+ibal32.dll=1,,\r
+ibal32d.dll=1,,\r
+ibbus.sys=1,,\r
 \r
 [SourceDisksFiles.ia64]\r
-IbInstaller.dll = 1,,\r
 mlx4_hca.sys = 1,,\r
 mlx4u.dll = 1,,\r
 mlx4ud.dll = 1,,\r
 mlx4u32.dll = 1,,\r
 mlx4u32d.dll = 1,,\r
 ;wdfcoinstaller01005.dll = 1,,\r
+ibal.dll=1,,\r
+ibald.dll=1,,\r
+complib.dll=1,,\r
+complibd.dll=1,,\r
+cl32.dll=1,,\r
+cl32d.dll=1,,\r
+ibal32.dll=1,,\r
+ibal32d.dll=1,,\r
+ibbus.sys=1,,\r
+\r
 \r
 ;*****************************************\r
 ; Mlx4Bus  Install Section\r
@@ -100,28 +119,41 @@ mlx4u32d.dll = 1,,
 [MLX4HCA.DDInstall.ntx86]\r
 CopyFiles = MLX4HCA.CopyFiles\r
 CopyFiles = MLX4HCA.UMCopyFiles\r
-CopyINF=ib_bus.inf\r
+CopyFiles = Ibal.UMCopyFiles\r
+CopyFiles = Ibbus.CopyFiles\r
 \r
 [MLX4HCA.DDInstall.ntamd64]\r
 CopyFiles = MLX4HCA.CopyFiles\r
 CopyFiles = MLX4HCA.UMCopyFiles\r
 CopyFiles = MLX4HCA.WOW64CopyFiles\r
-CopyINF=ib_bus.inf\r
+CopyFiles = Ibal.UMCopyFiles\r
+CopyFiles = Ibal.WOW64CopyFiles\r
+CopyFiles = Ibbus.CopyFiles\r
 \r
 [MLX4HCA.DDInstall.ntia64]\r
 CopyFiles = MLX4HCA.CopyFiles\r
 CopyFiles = MLX4HCA.UMCopyFiles\r
 CopyFiles = MLX4HCA.WOW64CopyFiles\r
-CopyINF=ib_bus.inf\r
+CopyFiles = Ibal.UMCopyFiles\r
+CopyFiles = Ibal.WOW64CopyFiles\r
+CopyFiles = Ibbus.CopyFiles\r
 \r
 [MLX4HCA.DDInstall.ntx86.Services]\r
 AddService = mlx4_hca,%SPSVCINST_ASSOCSERVICE%,MLX4HCA.ServiceInstall,MLX4HCA.EventLog\r
+AddService = ibbus,,Ibbus.ServiceInstall\r
 \r
 [MLX4HCA.DDInstall.ntamd64.Services]\r
 AddService = mlx4_hca,%SPSVCINST_ASSOCSERVICE%,MLX4HCA.ServiceInstall,MLX4HCA.EventLog\r
+AddService = ibbus,,Ibbus.ServiceInstall\r
 \r
 [MLX4HCA.DDInstall.ntia64.Services]\r
 AddService = mlx4_hca,%SPSVCINST_ASSOCSERVICE%,MLX4HCA.ServiceInstall,MLX4HCA.EventLog\r
+AddService = ibbus,,Ibbus.ServiceInstall\r
+\r
+\r
+;*****************************************\r
+; File Copy\r
+;*****************************************\r
 \r
 [MLX4HCA.CopyFiles]\r
 mlx4_hca.sys\r
@@ -134,9 +166,24 @@ mlx4ud.dll,,,2
 mlx4u.dll,mlx4u32.dll,,2\r
 mlx4ud.dll,mlx4u32d.dll,,2\r
 \r
+[Ibal.UMCopyFiles]\r
+ibal.dll,,,2\r
+ibald.dll,,,2\r
+complib.dll,,,2\r
+complibd.dll,,,2\r
+\r
+[Ibal.WOW64CopyFiles]\r
+ibal.dll,ibal32.dll,,2\r
+ibald.dll,ibal32d.dll,,2\r
+complib.dll,cl32.dll,,2\r
+complibd.dll,cl32d.dll,,2\r
+\r
+[Ibbus.CopyFiles]\r
+ibbus.sys\r
+\r
 \r
 ;*****************************************\r
-; Service Install section\r
+; MLX4 Service Install section\r
 ;*****************************************\r
 \r
 [MLX4HCA.ServiceInstall]\r
@@ -163,6 +210,74 @@ HKR,"Parameters","DebugFlags",%REG_DWORD%,0x0000ffff
 HKLM,"System\CurrentControlSet\Control\WMI\GlobalLogger\F8C96A49-AE22-41e9-8025-D7E416884D89","Flags",%REG_DWORD%,0xffff\r
 HKLM,"System\CurrentControlSet\Control\WMI\GlobalLogger\F8C96A49-AE22-41e9-8025-D7E416884D89","Level",%REG_DWORD%,0x3\r
 \r
+\r
+;*****************************************\r
+; IBBUS Service Install section\r
+;*****************************************\r
+\r
+[Ibbus.ServiceInstall]\r
+DisplayName     = %Ibbus.ServiceDesc%\r
+ServiceType     = %SERVICE_KERNEL_DRIVER%\r
+StartType       = %SERVICE_DEMAND_START%\r
+ErrorControl    = %SERVICE_ERROR_NORMAL%\r
+ServiceBinary   = %12%\ibbus.sys\r
+LoadOrderGroup  = PnP Filter\r
+AddReg          = Ibbus.ParamsReg\r
+Dependencies   = mlx4_hca\r
+\r
+[Ibbus.ParamsReg]\r
+HKR,"Parameters","IbalDebugLevel",%REG_DWORD%,2\r
+HKR,"Parameters","IbalDebugFlags",%REG_DWORD%,0x00ffffff\r
+HKR,"Parameters","SmiPollInterval",%REG_DWORD_NO_CLOBBER%,20000\r
+HKR,"Parameters","IocQueryTimeout",%REG_DWORD_NO_CLOBBER%,250\r
+HKR,"Parameters","IocQueryRetries",%REG_DWORD_NO_CLOBBER%,4\r
+HKR,"Parameters","IocPollInterval",%REG_DWORD_NO_CLOBBER%,30000\r
+HKR,"Parameters","DebugFlags",%REG_DWORD%,0x80000000\r
+HKR,"Parameters","ReportPortNIC",%REG_DWORD%,1\r
+\r
+\r
+;*****************************************\r
+; Uninstall section (not used now)\r
+;*****************************************\r
+\r
+[DefaultUninstall.ntx86]\r
+DelFiles   = MLX4HCA.CopyFiles\r
+DelFiles   = MLX4HCA.UMCopyFiles\r
+DelReg     = MLX4HCA.ParamsReg\r
+DelReg     = MLX4HCA.AddEventLogReg\r
+DelReg     = ClassAddReg\r
+DelFiles   = Ibal.UMCopyFiles\r
+\r
+\r
+[DefaultUninstall.ntamd64]\r
+DelFiles   = MLX4HCA.CopyFiles\r
+DelFiles   = MLX4HCA.UMCopyFiles\r
+DelFiles   = MLX4HCA.WOW64CopyFiles\r
+DelReg     = MLX4HCA.ParamsReg\r
+DelReg     = MLX4HCA.AddEventLogReg\r
+DelReg     = ClassAddReg\r
+DelFiles   = Ibal.UMCopyFiles\r
+DelFiles   = Ibal.WOW64CopyFiles\r
+DelFiles   = Ibbus.CopyFiles\r
+DelReg     = Ibbus.ParamsReg\r
+\r
+[DefaultUninstall.ntia64]\r
+DelFiles   = MLX4HCA.CopyFiles\r
+DelFiles   = MLX4HCA.UMCopyFiles\r
+DelFiles   = MLX4HCA.WOW64CopyFiles\r
+DelReg     = MLX4HCA.ParamsReg\r
+DelReg     = MLX4HCA.AddEventLogReg\r
+DelReg     = ClassAddReg\r
+DelFiles   = Ibal.UMCopyFiles\r
+DelFiles   = Ibal.WOW64CopyFiles\r
+DelFiles   = Ibbus.CopyFiles\r
+DelReg     = Ibbus.ParamsReg\r
+\r
+[DefaultUninstall.Services]\r
+DelService = Ibbus,%SPSVCINST_STOPSERVICE%\r
+DelService = mthca,%SPSVCINST_STOPSERVICE%\r
+\r
+\r
 ;\r
 ; The below section is temporarily disabled.\r
 ; It should be uncommented after returning MLX4_HCA to WDF model.\r
@@ -208,17 +323,20 @@ HKLM,"System\CurrentControlSet\Control\WMI\GlobalLogger\F8C96A49-AE22-41e9-8025-
 ;*****************************************\r
 \r
 [Strings]\r
-Mlx4HcaClassGuid = "{58517E00-D3CF-40c9-A679-CEE5752F4491}"\r
+Mlx4HcaClassGuid = "{31B0B28A-26FF-4dca-A6FA-E767C7DFBA20}"\r
 MTL="Mellanox Technologies Ltd."\r
 MLX4HCA.ServiceDesc = "Mellanox ConnectX Virtual Infiband Driver"\r
+Ibbus.ServiceDesc = "InfiniBand Bus/Fabric/AL (Filter Driver)"\r
 Mlx4_Hca.DeviceDesc="Mellanox ConnectX Virtual Channel Adapter"\r
 DiskId = "Mellanox Mlx4 Bus installation disk"\r
 SPSVCINST_NULL = 0x0\r
 SPSVCINST_ASSOCSERVICE = 0x00000002\r
+SPSVCINST_STOPSERVICE  = 0x00000200\r
 SERVICE_KERNEL_DRIVER  = 1\r
 SERVICE_DEMAND_START   = 3\r
 SERVICE_ERROR_NORMAL   = 1\r
 REG_DWORD              = 0x00010001\r
+REG_DWORD_NO_CLOBBER   = 0x00010003\r
 REG_MULTI_SZ_APPEND    = 0x00010008\r
 DIRID_SYSTEM           = 11\r
 DIRID_DRIVERS          = 12\r
index f2a1444..d104c1f 100644 (file)
@@ -8,4 +8,8 @@ CATATTR1=0x10010001:OSAttr:2:6.0
 <hash>mlx4_hca.sys=mlx4_hca.sys\r
 <hash>mlx4u.dll=mlx4u.dll\r
 <hash>mlx4ud.dll=mlx4ud.dll\r
-<hash>IbInstaller.dll=IbInstaller.dll\r
+<hash>ibal.dll=ibal.dll\r
+<hash>ibald.dll=ibald.dll\r
+<hash>complib.dll=complib.dll\r
+<hash>complibd.dll=complibd.dll\r
+<hash>ibbus.sys=ibbus.sys\r
index af10df1..c7003df 100644 (file)
@@ -10,5 +10,13 @@ CATATTR1=0x10010001:OSAttr:2:6.0
 <hash>mthcaud.dll=mthcaud.dll\r
 <hash>mthca32.dll=mthca32.dll\r
 <hash>mthca32d.dll=mthca32d.dll\r
-<hash>IbInstaller.dll=IbInstaller.dll\r
+<hash>ibal.dll=ibal.dll\r
+<hash>ibald.dll=ibald.dll\r
+<hash>complib.dll=complib.dll\r
+<hash>complibd.dll=complibd.dll\r
+<hash>cl32.dll=cl32.dll\r
+<hash>cl32d.dll=cl32d.dll\r
+<hash>ibal32.dll=ibal32.dll\r
+<hash>ibal32d.dll=ibal32d.dll\r
+<hash>ibbus.sys=ibbus.sys\r
 \r
index a553ba2..d85707f 100644 (file)
@@ -3,9 +3,9 @@
 \r
 [Version]\r
 Signature="$Windows NT$"\r
-Class=InfiniBandHca\r
+Class=InfiniBandController\r
 ClassGUID={58517E00-D3CF-40c9-A679-CEE5752F4491}\r
-Provider=%OPENIB%\r
+Provider=%OFA%\r
 ; must be synchronized with MTHCA_DEV.H\r
 DriverVer=03/08/2006,1.0.0000.614\r
 CatalogFile=mthca.cat\r
@@ -14,25 +14,22 @@ CatalogFile=mthca.cat
 \r
 [DestinationDirs]\r
 DefaultDestDir=%DIRID_DRIVERS%\r
-ClassCopyFiles=%DIRID_SYSTEM%\r
 MTHCA.UMCopyFiles=%DIRID_SYSTEM%\r
 MTHCA.WOW64CopyFiles=%DIRID_SYSTEM_X86%\r
+Ibal.UMCopyFiles=%DIRID_SYSTEM%\r
+Ibal.WOW64CopyFiles=%DIRID_SYSTEM_X86%\r
 \r
 ; ================= Class Install section =====================\r
 \r
 [ClassInstall32]\r
-CopyFiles=ClassCopyFiles\r
 AddReg=ClassAddReg\r
 \r
-[ClassCopyFiles]\r
-IbInstaller.dll\r
-\r
 [ClassAddReg]\r
-HKR,,,,"InfiniBand Host Channel Adapters"\r
+HKR,,,,"InfiniBand Channel Adapters"\r
 HKR,,Icon,,-5\r
 HKR,,SilentInstall,,1\r
-HKLM,"System\CurrentControlSet\Control\CoDeviceInstallers", \\r
- %HcaClassGuid%,%REG_MULTI_SZ_APPEND%, "IbInstaller.dll,IbCoInstaller"\r
+HKR,,"UpperFilters",0x00010000,"ibbus" ; enable IBBUS/AL Filter driver loading.\r
+\r
 \r
 ; ================= Device Install section =====================\r
 \r
@@ -46,26 +43,46 @@ HKLM,"System\CurrentControlSet\Control\CoDeviceInstallers", \
 1=%DiskId%,,,""\r
 \r
 [SourceDisksFiles]\r
-IbInstaller.dll=1\r
-mthca.sys=1\r
-mthcau.dll=1\r
-mthcaud.dll=1\r
+mthca.sys=1,,\r
+mthcau.dll=1,,\r
+mthcaud.dll=1,,\r
+ibal.dll=1,,\r
+complib.dll=1,,\r
+ibald.dll=1,,\r
+complibd.dll=1,,\r
+ibbus.sys=1,,\r
 \r
 [SourceDisksFiles.amd64]\r
-IbInstaller.dll=1\r
-mthca.sys=1\r
-mthcau.dll=1\r
-mthcaud.dll=1\r
-mthca32.dll=1\r
-mthca32d.dll=1\r
+mthca.sys=1,,\r
+mthcau.dll=1,,\r
+mthcaud.dll=1,,\r
+mthca32.dll=1,,\r
+mthca32d.dll=1,,\r
+ibal.dll=1,,\r
+ibald.dll=1,,\r
+complib.dll=1,,\r
+complibd.dll=1,,\r
+cl32.dll=1,,\r
+cl32d.dll=1,,\r
+ibal32.dll=1,,\r
+ibal32d.dll=1,,\r
+ibbus.sys=1,,\r
 \r
 [SourceDisksFiles.ia64]\r
-IbInstaller.dll=1\r
-mthca.sys=1\r
-mthcau.dll=1\r
-mthcaud.dll=1\r
-mthca32.dll=1\r
-mthca32d.dll=1\r
+mthca.sys=1,,\r
+mthcau.dll=1,,\r
+mthcaud.dll=1,,\r
+mthca32.dll=1,,\r
+mthca32d.dll=1,,\r
+ibal.dll=1,,\r
+ibald.dll=1,,\r
+complib.dll=1,,\r
+complibd.dll=1,,\r
+cl32.dll=1,,\r
+cl32d.dll=1,,\r
+ibal32.dll=1,,\r
+ibal32d.dll=1,,\r
+ibbus.sys=1,,\r
 \r
 [Manufacturer]\r
 %MTL% = HCA.DeviceSection,ntx86,ntamd64,ntia64\r
@@ -109,28 +126,42 @@ mthca32d.dll=1
 [MTHCA.DDInstall.ntx86]\r
 CopyFiles = MTHCA.CopyFiles\r
 CopyFiles = MTHCA.UMCopyFiles\r
-CopyINF=ib_bus.inf\r
+CopyFiles = Ibal.UMCopyFiles\r
+CopyFiles = Ibbus.CopyFiles\r
 \r
 [MTHCA.DDInstall.ntamd64]\r
 CopyFiles = MTHCA.CopyFiles\r
 CopyFiles = MTHCA.UMCopyFiles\r
 CopyFiles = MTHCA.WOW64CopyFiles\r
-CopyINF=ib_bus.inf\r
+CopyFiles = Ibal.UMCopyFiles\r
+CopyFiles = Ibal.WOW64CopyFiles\r
+CopyFiles = Ibbus.CopyFiles\r
 \r
 [MTHCA.DDInstall.ntia64]\r
 CopyFiles = MTHCA.CopyFiles\r
 CopyFiles = MTHCA.UMCopyFiles\r
 CopyFiles = MTHCA.WOW64CopyFiles\r
-CopyINF=ib_bus.inf\r
+CopyFiles = Ibal.UMCopyFiles\r
+CopyFiles = Ibal.WOW64CopyFiles\r
+CopyFiles = Ibbus.CopyFiles\r
+\r
+\r
+; ============== Services ==============\r
 \r
 [MTHCA.DDInstall.ntx86.Services]\r
 AddService = mthca,%SPSVCINST_ASSOCSERVICE%,MTHCA.ServiceInstall,MTHCA.EventLog\r
+AddService = ibbus,,Ibbus.ServiceInstall\r
 \r
 [MTHCA.DDInstall.ntamd64.Services]\r
 AddService = mthca,%SPSVCINST_ASSOCSERVICE%,MTHCA.ServiceInstall,MTHCA.EventLog\r
+AddService = ibbus,,Ibbus.ServiceInstall\r
 \r
 [MTHCA.DDInstall.ntia64.Services]\r
 AddService = mthca,%SPSVCINST_ASSOCSERVICE%,MTHCA.ServiceInstall,MTHCA.EventLog\r
+AddService = ibbus,,Ibbus.ServiceInstall\r
+\r
+\r
+; ============= File Copy ==============\r
 \r
 [MTHCA.CopyFiles]\r
 mthca.sys\r
@@ -143,8 +174,24 @@ mthcaud.dll,,,2
 mthcau.dll,mthca32.dll,,2\r
 mthcaud.dll,mthca32d.dll,,2\r
 \r
+[Ibal.UMCopyFiles]\r
+ibal.dll,,,2\r
+ibald.dll,,,2\r
+complib.dll,,,2\r
+complibd.dll,,,2\r
+\r
+[Ibal.WOW64CopyFiles]\r
+ibal.dll,ibal32.dll,,2\r
+ibald.dll,ibal32d.dll,,2\r
+complib.dll,cl32.dll,,2\r
+complibd.dll,cl32d.dll,,2\r
+\r
+[Ibbus.CopyFiles]\r
+ibbus.sys\r
+\r
+\r
 ;\r
-; ============= Service Install section ==============\r
+; ============= MTHCA Service Install section ==============\r
 ;\r
 \r
 [MTHCA.ServiceInstall]\r
@@ -177,9 +224,72 @@ HKR,"Parameters","ProfileRdOut",%REG_DWORD%,0xffffffff
 HKLM,"System\CurrentControlSet\Control\WMI\GlobalLogger\8bf1f640-63fe-4743-b9ef-fa38c695bfde","Flags",%REG_DWORD%,0xffff\r
 HKLM,"System\CurrentControlSet\Control\WMI\GlobalLogger\8bf1f640-63fe-4743-b9ef-fa38c695bfde","Level",%REG_DWORD%,0x3\r
 \r
+\r
+; ============= IBBUS/AL Service Install section ==============\r
+;\r
+\r
+[Ibbus.ServiceInstall]\r
+DisplayName     = %Ibbus.ServiceDesc%\r
+ServiceType     = %SERVICE_KERNEL_DRIVER%\r
+StartType       = %SERVICE_DEMAND_START%\r
+ErrorControl    = %SERVICE_ERROR_NORMAL%\r
+ServiceBinary   = %12%\ibbus.sys\r
+LoadOrderGroup  = PnP Filter\r
+AddReg          = Ibbus.ParamsReg\r
+Dependencies   = mthca\r
+\r
+[Ibbus.ParamsReg]\r
+HKR,"Parameters","IbalDebugLevel",%REG_DWORD%,2\r
+HKR,"Parameters","IbalDebugFlags",%REG_DWORD%,0x00ffffff\r
+HKR,"Parameters","SmiPollInterval",%REG_DWORD_NO_CLOBBER%,20000\r
+HKR,"Parameters","IocQueryTimeout",%REG_DWORD_NO_CLOBBER%,250\r
+HKR,"Parameters","IocQueryRetries",%REG_DWORD_NO_CLOBBER%,4\r
+HKR,"Parameters","IocPollInterval",%REG_DWORD_NO_CLOBBER%,30000\r
+HKR,"Parameters","DebugFlags",%REG_DWORD%,0x80000000\r
+HKR,"Parameters","ReportPortNIC",%REG_DWORD%,1\r
+\r
+\r
+; ============= Uninstall Section =============\r
+\r
+[DefaultUninstall.ntx86]\r
+DelFiles   = MTHCA.CopyFiles\r
+DelFiles   = MTHCA.UMCopyFiles\r
+DelReg     = MTHCA.ParamsReg\r
+DelReg     = MTHCA.AddEventLogReg\r
+DelReg     = ClassAddReg\r
+DelFiles   = Ibal.UMCopyFiles\r
+\r
+\r
+[DefaultUninstall.ntamd64]\r
+DelFiles   = MTHCA.CopyFiles\r
+DelFiles   = MTHCA.UMCopyFiles\r
+DelFiles   = MTHCA.WOW64CopyFiles\r
+DelReg     = MTHCA.ParamsReg\r
+DelReg     = MTHCA.AddEventLogReg\r
+DelReg     = ClassAddReg\r
+DelFiles   = Ibal.UMCopyFiles\r
+DelFiles   = Ibal.WOW64CopyFiles\r
+\r
+\r
+[DefaultUninstall.ntia64]\r
+DelFiles   = MTHCA.CopyFiles\r
+DelFiles   = MTHCA.UMCopyFiles\r
+DelFiles   = MTHCA.WOW64CopyFiles\r
+DelReg     = MTHCA.ParamsReg\r
+DelReg     = MTHCA.AddEventLogReg\r
+DelReg     = ClassAddReg\r
+DelFiles   = Ibal.UMCopyFiles\r
+DelFiles   = Ibal.WOW64CopyFiles\r
+\r
+\r
+[DefaultUninstall.Services]\r
+DelService = Ibbus,%SPSVCINST_STOPSERVICE%\r
+DelService = mthca,%SPSVCINST_STOPSERVICE%\r
+\r
+\r
 [Strings]\r
-HcaClassGuid = "{58517E00-D3CF-40c9-A679-CEE5752F4491}"\r
-OPENIB = "OpenIB Alliance"\r
+IBClassGuid = "{58517E00-D3CF-40c9-A679-CEE5752F4491}"\r
+OFA = "OpenFabrics Alliance"\r
 MTL="Mellanox Technologies Ltd."\r
 MTHCA.ServiceDesc = "Driver for Mellanox InfiniHost Devices"\r
 MT23108.DeviceDesc="InfiniHost (MT23108) - Mellanox InfiniBand HCA"\r
@@ -192,12 +302,15 @@ MT24205.DeviceDesc="InfiniHost III Lx (MT24205) - Mellanox InfiniBand HCA for PC
 MT25204.DeviceDesc="InfiniHost III Lx (MT25204) - Mellanox InfiniBand HCA for PCI Express"\r
 MT25205.DeviceDesc="InfiniHost III Lx (MT25205) - Mellanox InfiniBand HCA for PCI Express (burner device)"\r
 DiskId = "Mellanox InfiniBand HCA installation disk"\r
+Ibbus.ServiceDesc = "InfiniBand Bus/AL (Filter Driver)"\r
 SPSVCINST_NULL = 0x0\r
 SPSVCINST_ASSOCSERVICE = 0x00000002\r
+SPSVCINST_STOPSERVICE  = 0x00000200\r
 SERVICE_KERNEL_DRIVER  = 1\r
 SERVICE_DEMAND_START   = 3\r
 SERVICE_ERROR_NORMAL   = 1\r
 REG_DWORD              = 0x00010001\r
+REG_DWORD_NO_CLOBBER   = 0x00010003\r
 REG_MULTI_SZ_APPEND    = 0x00010008\r
 DIRID_SYSTEM           = 11\r
 DIRID_DRIVERS          = 12\r
diff --git a/hw/mthca/kernel/mthca32.cdf b/hw/mthca/kernel/mthca32.cdf
new file mode 100644 (file)
index 0000000..230ea6c
--- /dev/null
@@ -0,0 +1,16 @@
+[CatalogHeader]\r
+Name=mthca.cat\r
+PublicVersion=0x0000001\r
+EncodingType=0x00010001\r
+CATATTR1=0x10010001:OSAttr:2:6.0\r
+[CatalogFiles]\r
+<hash>mthca.inf=mthca.inf\r
+<hash>mthca.sys=mthca.sys\r
+<hash>mthcau.dll=mthcau.dll\r
+<hash>mthcaud.dll=mthcaud.dll\r
+<hash>ibal.dll=ibal.dll\r
+<hash>ibald.dll=ibald.dll\r
+<hash>complib.dll=complib.dll\r
+<hash>complibd.dll=complibd.dll\r
+<hash>ibbus.sys=ibbus.sys\r
+\r