[IBBUS] reconstituted omitted commits from 1499.
authorstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 26 Aug 2008 19:01:49 +0000 (19:01 +0000)
committerstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 26 Aug 2008 19:01:49 +0000 (19:01 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@1516 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

core/bus/kernel/bus_driver.c
core/bus/kernel/bus_driver.h
core/bus/kernel/bus_iou_mgr.c
core/bus/kernel/bus_pnp.h
core/bus/kernel/bus_port_mgr.c

index cdd2c43..addc2f9 100644 (file)
@@ -56,8 +56,8 @@
 #else\r
 #define DEFAULT_NODE_DESC      "OpenIB Windows® Host"\r
 #endif\r
-/* pkey array to be read */\r
-pkey_array_t  g_pkeys;\r
+\r
+\r
 \r
 char   node_desc[IB_NODE_DESCRIPTION_SIZE];\r
 \r
@@ -183,7 +183,9 @@ __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
 /************************************************************************************\r
 * name :       __prepare_pKey_array\r
 *           parses registry string and exrtacts pkey value(s) from it.\r
@@ -192,135 +194,176 @@ __read_machine_name( void )
 * output:      pkey_array\r
 * return:      uint16_t number of pkey(s) found\r
 *************************************************************************************/\r
-static uint16_t\r
-__prepare_pKey_array(IN const UNICODE_STRING *str, OUT uint16_t *pkey_array)\r
+static void __prepare_pKey_array(IN const char *str, size_t str_len,OUT pkey_array_t *cur_pkey)\r
 {\r
-       uint16_t i, num_pKeys, cur_pkey_length;\r
        NTSTATUS status;\r
-       ANSI_STRING ansi_str;\r
-       static const uint16_t PATTERN_LENGTH = 6;\r
+       size_t i;\r
+       uint8_t j;\r
+       char pkey_str[7];\r
+       ULONG   tmp_val;\r
        BUS_ENTER( BUS_DBG_DRV );\r
 \r
-       CL_ASSERT(pkey_array);\r
+       CL_ASSERT(cur_pkey);\r
        CL_ASSERT(str);\r
 \r
-       num_pKeys = 0;\r
-    cur_pkey_length = 0;\r
+       cur_pkey->pkey_num = 0;\r
+       j = 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 0;\r
-       }\r
-       \r
-       for (i = 0; (i < ansi_str.MaximumLength) && (num_pKeys < MAX_NUM_PKEY) ; i++)\r
+       for (i = 0; (i < str_len) && (cur_pkey->pkey_num < MAX_NUM_PKEY) ; i++)\r
     {\r
-               switch(ansi_str.Buffer[i])\r
+               if(str[i] == ' ')\r
+                       continue;\r
+\r
+               if( (str[i] != ',') && (str[i] != '\0'))\r
                {\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
+                   if(j >= 7)\r
                        {\r
-                               pkey_array[num_pKeys] = \\r
-                               (pkey_array[num_pKeys] << 4)| 0;\r
+                               BUS_TRACE(BUS_DBG_ERROR ,\r
+                               ("Incorrect format of pkey value\n") );\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
+                       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
-                               cur_pkey_length = 0;\r
-                               num_pKeys++;\r
+                               BUS_TRACE(BUS_DBG_ERROR ,\r
+                               ("Failed to convert, status = 0x%08X\n",status) );\r
+                               break;   \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
+                       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
+\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
+       }\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
+                       if(ansi_str.Buffer[i] == ':')\r
                        {\r
-                               cur_pkey_length = 0;\r
-                               num_pKeys++;\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
                        }\r
                        else\r
                        {\r
-                               RtlFreeAnsiString(&ansi_str);\r
-                               return num_pKeys;\r
+                               tmp_guid[j] = ansi_str.Buffer[i]; \r
+                               j++;\r
+                               continue;\r
                        }\r
-                       break;\r
+               }\r
+               else\r
+               {\r
+                       if(!p_start)\r
+                               p_start = &ansi_str.Buffer[i]; \r
 \r
-               default:\r
-                       break;\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
 \r
+                               ansi_str.Buffer[i] = ';';\r
+                               p_start = NULL;\r
+                               port_guid_found = FALSE;\r
+                       }\r
                }\r
        }\r
-\r
     RtlFreeAnsiString(&ansi_str);\r
-       BUS_EXIT( BUS_DBG_DRV );\r
-       return num_pKeys;\r
+       return STATUS_SUCCESS;\r
 }\r
 \r
 static NTSTATUS\r
@@ -329,7 +372,7 @@ __read_registry(
 {\r
        NTSTATUS                                        status;\r
        /* Remember the terminating entry in the table below. */\r
-       RTL_QUERY_REGISTRY_TABLE        table[10];\r
+       RTL_QUERY_REGISTRY_TABLE        table[12];\r
        UNICODE_STRING                          param_path;\r
        UNICODE_STRING                          pkeyString;\r
        UNICODE_STRING                          empty_string;\r
@@ -363,8 +406,6 @@ __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
@@ -435,16 +476,21 @@ __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
-                       g_pkeys.pkey_num = __prepare_pKey_array(&pkeyString, (uint16_t*)g_pkeys.pkey_array);\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
 #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
+       //bus_globals.dbg_lvl |= BUS_DBG_DRV | BUS_DBG_PNP;\r
 #endif\r
 \r
        BUS_TRACE(BUS_DBG_DRV ,\r
@@ -613,12 +659,15 @@ bus_add_pkey(cl_ioctl_handle_t                    h_ioctl)
        return status;\r
 }\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
@@ -627,10 +676,20 @@ bus_rem_pkey(cl_ioctl_handle_t                    h_ioctl)
                        ("Invalid parameters.\n") );\r
                return CL_INVALID_PARAMETER;\r
        }\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
@@ -666,6 +725,7 @@ 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
@@ -673,7 +733,13 @@ bus_drv_unload(
        \r
        RtlInitUnicodeString( &dos_name, L"\\DosDevices\\Global\\ibal" );\r
        IoDeleteSymbolicLink( &dos_name );\r
-\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
        CL_DEINIT;\r
 \r
 #if defined(EVENT_TRACING)\r
@@ -741,4 +807,3 @@ DriverEntry(
        BUS_EXIT( BUS_DBG_DRV );\r
        return STATUS_SUCCESS;\r
 }\r
-\r
index e4ff16e..ecb0e65 100644 (file)
@@ -45,7 +45,7 @@
 #include "iba/ib_al.h"\r
 #include "bus_port_mgr.h"\r
 #include "bus_iou_mgr.h"\r
-\r
+#include "al_dev.h"\r
 /* Safe string functions. */\r
 #if WINVER == 0x500\r
 /*\r
@@ -180,9 +180,15 @@ typedef struct _bus_pdo_ext
 \r
        /* work item for handling Power Management request */\r
        PIO_WORKITEM                    p_po_work_item;\r
-       \r
+       boolean_t                           is_partition_pdo;\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,6 +208,9 @@ typedef struct _bus_globals
        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
+\r
 }      bus_globals_t;\r
 \r
 \r
index 209837f..39dc655 100644 (file)
@@ -334,7 +334,6 @@ create_iou_mgr(
        status = bus_reg_iou_pnp( p_bfi );\r
        if( status != IB_SUCCESS )\r
        {\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
index 83fd743..30f5cf9 100644 (file)
@@ -87,4 +87,5 @@ 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 435c167..1cfeb67 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
@@ -82,7 +84,6 @@ typedef struct _port_pnp_context
 \r
 extern pkey_array_t  g_pkeys;\r
 \r
-static boolean_t pkeys_enumerated = FALSE;\r
 /*\r
  * Function prototypes.\r
  */\r
@@ -442,7 +443,7 @@ free_port_mgr(
                                p_ext, p_ext->b_present, p_ext->b_reported_missing ) );\r
                        continue;\r
                }\r
-               if( p_ext->h_ca )\r
+               if( p_ext->h_ca && (!p_ext->is_partition_pdo))\r
                {\r
                        /* Invalidate bus relations for the HCA. */\r
                        IoInvalidateDeviceRelations(\r
@@ -767,6 +768,8 @@ 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
@@ -823,12 +826,22 @@ port_mgr_port_add(
                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( pkeys_enumerated)\r
+       if( !cur_pkeys)\r
                pdo_cnt = 1;\r
        else\r
-               pdo_cnt = g_pkeys.pkey_num + 1;\r
+               pdo_cnt = cur_conf->pkeys_per_port.pkey_num + 1;\r
 \r
     for (num_pdo = 0; num_pdo < pdo_cnt; num_pdo++)\r
     {\r
@@ -875,6 +888,7 @@ port_mgr_port_add(
                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
@@ -892,9 +906,7 @@ port_mgr_port_add(
                p_port_ext->n_ifc_ref = 0;\r
 \r
                if(num_pdo > 0)\r
-               {\r
-                 p_port_ext->port_guid.pkey = g_pkeys.pkey_array[num_pdo -1];\r
-               }\r
+                       p_port_ext->port_guid.pkey = cur_pkeys->pkey_array[num_pdo -1];\r
 \r
                /* Store the device extension in the port vector for future queries. */\r
                cl_mutex_acquire( &gp_port_mgr->pdo_mutex );\r
@@ -903,13 +915,12 @@ port_mgr_port_add(
                cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
 \r
                /*\r
-                * save the port_ext, as the context is passed in for future events on\r
-                * the same port.\r
+                * Set the context of the PNP event. The context is passed in for future\r
+                * events on the same port.\r
                 */\r
                if(num_pdo == 0)\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
@@ -919,6 +930,86 @@ port_mgr_port_add(
        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(        IN      pkey_array_t    *pkeys,\r
+                                                               IN      port_mgr_t              *gp_port_mgr )\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
+       BUS_EXIT( BUS_DBG_PNP );\r
+       return CL_SUCCESS;\r
+}\r
+\r
+\r
+cl_status_t port_mgr_pkey_rem( IN 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_rem( pkeys, 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
 /************************************************************************************\r
 * name :       port_mgr_pkey_add\r
 *           creates pdo for each pkey value in pkey_array \r
@@ -926,53 +1017,66 @@ port_mgr_port_add(
 * output:      none\r
 * return:      cl_status\r
 *************************************************************************************/\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
+cl_status_t _port_mgr_pkey_add( IN     pkey_array_t    *req_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;\r
+       bus_port_ext_t          *p_port_ext, *pkey_port_ext, *pmatched_guid_ext;\r
        DEVICE_OBJECT       *p_pdo[MAX_NUM_PKEY];\r
-       bus_pdo_ext_t           *p_pdo_ext = NULL;\r
-       cl_qlist_t*                     p_pdo_list;\r
+       cl_qlist_t*                     p_pdo_list = &gp_port_mgr->port_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_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
+               p_port_ext = (bus_port_ext_t*)PARENT_STRUCT( p_list_item, bus_pdo_ext_t, list_item );\r
 \r
-               if(p_port_ext->port_guid.pkey != IB_DEFAULT_PKEY)\r
-                       break;\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
        }\r
        cl_mutex_release( &gp_port_mgr->pdo_mutex );\r
 \r
-       if (!p_port_ext)\r
+       if (!pmatched_guid_ext)\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
-                       ("No existing pdo found.\n") );\r
-               return CL_ERROR;\r
+                       ("No existed pdo found.\n") );\r
+               return CL_NOT_FOUND;\r
        }\r
 \r
-    for (cnt = 0; cnt < pkeys->pkey_num; cnt++)\r
+    for (cnt = 0; cnt < req_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,\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
+               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
                if( !NT_SUCCESS( status ) )\r
                {\r
                        BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
@@ -982,7 +1086,7 @@ cl_status_t _port_mgr_pkey_add ( IN        pkey_array_t    *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
@@ -994,19 +1098,17 @@ cl_status_t _port_mgr_pkey_add ( IN      pkey_array_t    *pkeys,
                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,\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
+               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
                        pkey_port_ext->pdo.b_reported_missing ) );\r
        \r
                /* Cache the CA GUID. */\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
+               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
                /* 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
@@ -1016,13 +1118,12 @@ cl_status_t _port_mgr_pkey_add ( IN     pkey_array_t    *pkeys,
 \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
+               pmatched_guid_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
@@ -1161,7 +1262,6 @@ 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
@@ -1402,6 +1502,7 @@ 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
@@ -1412,17 +1513,24 @@ port_query_device_id(
                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_DEVICE_ID);\r
+       else\r
+               dev_id_size = sizeof(IPOIB_PART_DEVICE_ID );\r
        /* Device ID is "IBA\SID_<sid> where <sid> is the IPoIB Service ID. */\r
-       p_string = ExAllocatePoolWithTag( PagedPool, sizeof(IPOIB_DEVICE_ID), 'vedq' );\r
+       p_string = ExAllocatePoolWithTag( PagedPool, dev_id_size, 'vedq' );\r
        if( !p_string )\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
                        ("Failed to allocate device ID buffer (%d bytes).\n",\r
-                       sizeof(IPOIB_DEVICE_ID)) );\r
+                       dev_id_size) );\r
                return STATUS_INSUFFICIENT_RESOURCES;\r
        }\r
-       cl_memcpy( p_string, IPOIB_DEVICE_ID, sizeof(IPOIB_DEVICE_ID) );\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
        p_irp->IoStatus.Information = (ULONG_PTR)p_string;\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r
@@ -1437,26 +1545,30 @@ 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
-       p_string = ExAllocatePoolWithTag( PagedPool, sizeof(IPOIB_HARDWARE_ID), 'ihqp' );\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
        if( !p_string )\r
        {\r
                BUS_TRACE_EXIT( BUS_DBG_ERROR,\r
                        ("Failed to allocate hardware ID buffer (%d bytes).\n",\r
-                       sizeof(IPOIB_HARDWARE_ID)) );\r
+                       dev_id_size) );\r
                return STATUS_INSUFFICIENT_RESOURCES;\r
        }\r
-       cl_memcpy( p_string, IPOIB_HARDWARE_ID, sizeof(IPOIB_HARDWARE_ID) );\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
        p_irp->IoStatus.Information = (ULONG_PTR)p_string;\r
 \r
        BUS_EXIT( BUS_DBG_PNP );\r