[ofw] RE: IPoIB partitioning support potential bug?

Slava Strebkov slavas at voltaire.com
Mon Jun 9 22:45:07 PDT 2008


Hi,
Attached is a patch for partition implementation.
IPoIB is using pkey in network order.

Slava


Index: core/al/al_dev.h
===================================================================
--- core/al/al_dev.h	(revision 1244)
+++ core/al/al_dev.h	(working copy)
@@ -61,6 +61,7 @@
 
 typedef struct _pkey_array
 {
+	ib_net64_t	   port_guid;
 	ib_net16_t	   pkey_num;
 	ib_net16_t     pkey_array[MAX_NUM_PKEY];
 }pkey_array_t;
@@ -92,6 +93,9 @@
 cl_status_t
 bus_add_pkey(
 	IN				cl_ioctl_handle_t
h_ioctl );
+cl_status_t
+bus_rem_pkey(
+	IN				cl_ioctl_handle_t
h_ioctl );
 
 /* Define data structures for user-mode proxy */
 #else		/* CL_KERNEL */
@@ -142,7 +146,7 @@
 	ual_bind_cq,
 	ual_bind_destroy,
 	ual_bind_nd,
-	ual_req_create_pdo,
+
 	al_proxy_maxops
 
 }	al_proxy_ops_t;
@@ -166,8 +170,8 @@
 #define UAL_BIND_CQ			IOCTL_CODE(ALDEV_KEY,
ual_bind_cq)
 #define UAL_BIND_DESTROY	IOCTL_CODE(ALDEV_KEY, ual_bind_destroy)
 #define UAL_BIND_ND			IOCTL_CODE(ALDEV_KEY,
ual_bind_nd)
-#define UAL_REQ_CREATE_PDO  IOCTL_CODE(ALDEV_KEY, ual_req_create_pdo)
 
+
 #define AL_PROXY_OPS_START	IOCTL_CODE(ALDEV_KEY,
al_proxy_ops_start)
 #define AL_PROXY_MAXOPS		IOCTL_CODE(ALDEV_KEY,
al_proxy_maxops)
 
@@ -288,7 +292,8 @@
 	ual_reject_ioc_cmd,
 	ual_add_svc_entry_cmd,
 	ual_remove_svc_entry_cmd,
-
+	ual_req_create_pdo,
+	ual_req_remove_pdo,
 	al_ioc_maxops
 
 }	al_ioc_ops_t;
@@ -531,6 +536,8 @@
 
 
 #define UAL_GET_CA_ATTR_INFO	IOCTL_CODE(ALDEV_KEY, ual_get_ca_attr)
+#define UAL_REQ_CREATE_PDO		IOCTL_CODE(ALDEV_KEY,
ual_req_create_pdo)
+#define UAL_REQ_REMOVE_PDO		IOCTL_CODE(ALDEV_KEY,
ual_req_remove_pdo)
 
 /* PnP related ioctl commands. */
 #define UAL_REG_PNP			IOCTL_CODE(ALDEV_KEY,
ual_reg_pnp_cmd)
Index: core/bus/kernel/bus_driver.c
===================================================================
--- core/bus/kernel/bus_driver.c	(revision 1244)
+++ core/bus/kernel/bus_driver.c	(working copy)
@@ -56,16 +56,17 @@
 #else
 #define DEFAULT_NODE_DESC	"OpenIB Windows(r) Host"
 #endif
-/* pkey array to be read */
-pkey_array_t  g_pkeys;
 
+
+
 char	node_desc[IB_NODE_DESCRIPTION_SIZE];
 
 bus_globals_t	bus_globals = {
 	BUS_DBG_ERROR,
 	TRUE,
 	NULL,
-	NULL
+	NULL,
+	NULL,
 };
 
 static void
@@ -182,6 +183,7 @@
 		RtlStringCbCopyNA( node_desc, sizeof(node_desc),
 			DEFAULT_NODE_DESC, sizeof(DEFAULT_NODE_DESC) );
 	}
+	BUS_EXIT( BUS_DBG_DRV );
 }
 
/***********************************************************************
*************
 * name	:	__prepare_pKey_array
@@ -191,134 +193,176 @@
 * output:	pkey_array
 * return:	uint16_t number of pkey(s) found
 
************************************************************************
*************/
-static uint16_t __prepare_pKey_array(IN const UNICODE_STRING *str, OUT
uint16_t *pkey_array)
+static void __prepare_pKey_array(IN const char *str, size_t str_len,OUT
pkey_array_t *cur_pkey)
 {
-	uint16_t i, num_pKeys, cur_pkey_length;
 	NTSTATUS status;
-	ANSI_STRING ansi_str;
-	static const uint16_t PATTERN_LENGTH = 6;
+	size_t i;
+	uint8_t j;
+	char pkey_str[7];
+	ULONG	tmp_val;
 	BUS_ENTER( BUS_DBG_DRV );
 
-	CL_ASSERT(pkey_array);
+	CL_ASSERT(cur_pkey);
 	CL_ASSERT(str);
 
-	num_pKeys = 0;
-    cur_pkey_length = 0;
+	cur_pkey->pkey_num = 0;
+	j = 0;
 
-	status = RtlUnicodeStringToAnsiString(&ansi_str,str,TRUE);
-	if(! NT_SUCCESS(status))
-	{
-		BUS_TRACE(BUS_DBG_ERROR ,
-		("RtlUnicodeStringToAnsiString returned 0x%.8x\n",
status) );
-		return 0;
-	}
-	
-	for (i = 0; (i < ansi_str.MaximumLength) && (num_pKeys <
MAX_NUM_PKEY) ; i++)
+	for (i = 0; (i < str_len) && (cur_pkey->pkey_num < MAX_NUM_PKEY)
; i++)
     {
-		switch(ansi_str.Buffer[i])
+		if(str[i] == ' ')
+			continue;
+
+		if( (str[i] != ',') && (str[i] != '\0'))
 		{
-		case '0':
-			cur_pkey_length++;
-			if (((i+1) < ansi_str.Length) && ( (
ansi_str.Buffer[i+1] == 'x') || ( ansi_str.Buffer[i+1] == 'X')))
-				break;
-			else
+		    if(j >= 7)
 			{
-				pkey_array[num_pKeys] = \
-				(pkey_array[num_pKeys] << 4)| 0;
+				BUS_TRACE(BUS_DBG_ERROR ,
+				("Incorrect format of pkey value\n") );
 				break;
 			}
-
-		case 'x':
-		case 'X':
-			cur_pkey_length++;
-			break;
-
-		case ',':
-			if(cur_pkey_length == PATTERN_LENGTH)
+			pkey_str[j] = str[i];
+			j++;
+		}
+		else
+		{
+			pkey_str[j] = '\0';
+			status =
RtlCharToInteger(&pkey_str[2],16,&tmp_val);
+			if(! NT_SUCCESS(status))
 			{
-				cur_pkey_length = 0;
-				num_pKeys++;
+				BUS_TRACE(BUS_DBG_ERROR ,
+				("Failed to convert, status =
0x%08X\n",status) );
+				break;   
 			}
-			break;
+			cur_pkey->pkey_array[cur_pkey->pkey_num++] =
(uint16_t)tmp_val;
+			j = 0;
+		}
+	}
+	BUS_EXIT( BUS_DBG_DRV );
+}
 
-		case 'A':
-		case 'a':
-			pkey_array[num_pKeys] = \
-			(pkey_array[num_pKeys] << 4)| 0xA;
-			cur_pkey_length++;
-			break;
+static pkey_conf_t*
+create_pkey_conf(pkey_conf_t **pp_cur_conf, char *guid_str, uint32_t
guid_str_len)
+{
+	NTSTATUS status;
+	char	tmp_char;
+	uint32_t tmp_val;
 
-		case 'B':
-		case 'b':
-			pkey_array[num_pKeys] = \
-			(pkey_array[num_pKeys] << 4)| 0xB;
-			cur_pkey_length++;
-			break;
+	if (! *pp_cur_conf)
+		pp_cur_conf = &bus_globals.p_pkey_conf;
+	else
+		pp_cur_conf = &((*pp_cur_conf)->next_conf);
 
-		case 'C':
-		case 'c':
-			pkey_array[num_pKeys] = \
-			(pkey_array[num_pKeys] << 4)| 0xC;
-			cur_pkey_length++;
-			break;
+	*pp_cur_conf = cl_zalloc( sizeof( pkey_conf_t ) );
+	if (!(*pp_cur_conf) )
+	{
+		BUS_TRACE(BUS_DBG_ERROR ,
+		("Failed to allocate pkey configuration\n") );
+		return NULL;   	
+	}
 
-		case 'D':
-		case 'd':
-			pkey_array[num_pKeys] = \
-			(pkey_array[num_pKeys] << 4)| 0xD;
-			cur_pkey_length++;
-			break;
+	tmp_char = guid_str[1 + guid_str_len/2];
+	guid_str[1 + guid_str_len/2] = '\0';
+	status = RtlCharToInteger(&guid_str[2],16,(PULONG)&tmp_val);
+	if(! NT_SUCCESS(status))
+	{
+		cl_free((*pp_cur_conf));
+		(*pp_cur_conf) = NULL;
+		BUS_TRACE(BUS_DBG_ERROR ,
+		("Failed to convert, status = 0x%08X\n",status) );
+		return NULL;   	
+	}
+	guid_str[1 + guid_str_len/2] = tmp_char;
+	(*pp_cur_conf)->pkeys_per_port.port_guid = tmp_val;
 
-		case 'E':
-		case 'e':
-			pkey_array[num_pKeys] = \
-			(pkey_array[num_pKeys] << 4)| 0xE;
-			cur_pkey_length++;
-			break;
+	status = RtlCharToInteger(&guid_str[1 +
guid_str_len/2],16,(PULONG)&tmp_val);
+	if(! NT_SUCCESS(status))
+	{
+		cl_free((*pp_cur_conf));
+		(*pp_cur_conf) = NULL;
+		BUS_TRACE(BUS_DBG_ERROR ,
+		("Failed to convert, status = 0x%08X\n",status) );
+		return NULL;   	
+	}
+	(*pp_cur_conf)->pkeys_per_port.port_guid =
((*pp_cur_conf)->pkeys_per_port.port_guid << 32) | tmp_val;
+	return (*pp_cur_conf);
+}
 
-		case 'F':
-		case 'f':
-			pkey_array[num_pKeys] = \
-			(pkey_array[num_pKeys] << 4)| 0xF;
-			cur_pkey_length++;
-			break;
+/**********************************************************************
**
+* name:		__build_pkeys_per_port
+*			extracts pkeys and port guids from registry
string.
+*			builds pkey array per port
+* input:	UNICODE_STRING *str
+* return:	NTSTATUS
+***********************************************************************
*/
+static NTSTATUS
+__build_pkeys_per_port(IN const UNICODE_STRING *str)
+{
+	NTSTATUS    status;
+	ANSI_STRING ansi_str;
+	uint32_t i,j;
+	char *p_end, *p_start;
+	boolean_t	port_guid_found;
+	pkey_conf_t	*cur_pkey_conf = NULL;
+	char tmp_guid[32] = {'\0'};
+	p_start = NULL;
 
-		case '1':
-		case '2':
-		case '3':
-		case '4':
-		case '5':
-		case '6':
-		case '7':
-		case '8':
-		case '9':
-			pkey_array[num_pKeys] = \
-			(pkey_array[num_pKeys] << 4)|
(ansi_str.Buffer[i] - '0');
-			cur_pkey_length++;
-			break;
-			
-		case '\0':
-			if(cur_pkey_length == PATTERN_LENGTH)
+	status = RtlUnicodeStringToAnsiString(&ansi_str,str,TRUE);
+	if(! NT_SUCCESS(status))
+	{
+		BUS_TRACE(BUS_DBG_ERROR ,
+		("RtlUnicodeStringToAnsiString returned 0x%.8x\n",
status) );
+		return status;
+	}
+
+	port_guid_found = FALSE;
+	j = 0;
+	for ( i = 0; i < ansi_str.MaximumLength; i++)
+	{
+		if(! port_guid_found)
+		{
+			if(ansi_str.Buffer[i] == ':')
 			{
-				cur_pkey_length = 0;
-				num_pKeys++;
+				port_guid_found = TRUE;
+				tmp_guid[j] = '\0';
+				cur_pkey_conf =
create_pkey_conf(&cur_pkey_conf,(char*)tmp_guid,j);
+				if(! cur_pkey_conf)
+				{
+				   RtlFreeAnsiString(&ansi_str);
+				   BUS_TRACE(BUS_DBG_ERROR ,
+				   ("Failed to create pkey
configuration\n"));
+				   return STATUS_INVALID_PARAMETER;
+				}
+			    RtlZeroMemory(tmp_guid,sizeof(tmp_guid));
+				j = 0;
+				p_start = NULL;
 			}
 			else
 			{
-				RtlFreeAnsiString(&ansi_str);
-				return num_pKeys;
+				tmp_guid[j] = ansi_str.Buffer[i]; 
+				j++;
+				continue;
 			}
-			break;
+		}
+		else
+		{
+			if(!p_start)
+				p_start = &ansi_str.Buffer[i]; 
 
-		default:
-			break;
+			if(ansi_str.Buffer[i] == ';')
+			{
+				p_end = &ansi_str.Buffer[i];
+				ansi_str.Buffer[i] = '\0';
+
__prepare_pKey_array(p_start,(size_t)(p_end - p_start) +
1,&cur_pkey_conf->pkeys_per_port);
 
+				ansi_str.Buffer[i] = ';';
+				p_start = NULL;
+				port_guid_found = FALSE;
+			}
 		}
 	}
-
     RtlFreeAnsiString(&ansi_str);
-	BUS_EXIT( BUS_DBG_DRV );
-	return num_pKeys;
+	return STATUS_SUCCESS;
 }
 static NTSTATUS
 __read_registry(
@@ -329,13 +373,13 @@
 	RTL_QUERY_REGISTRY_TABLE	table[10];
 	UNICODE_STRING				param_path;
 	UNICODE_STRING				pkeyString;
-	UNICODE_STRING				empy_string;
+	UNICODE_STRING				empty_string;
 
 	BUS_ENTER( BUS_DBG_DRV );
 
 	__read_machine_name();
 
-	RtlInitUnicodeString( &empy_string,NULL);
+	RtlInitUnicodeString( &empty_string,NULL);
 	RtlInitUnicodeString( &param_path, NULL );
 	param_path.MaximumLength = p_registry_path->Length + 
 		sizeof(L"\\Parameters");
@@ -360,8 +404,6 @@
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-	cl_memclr(&g_pkeys,sizeof(pkey_array_t));
-
 	/*
 	 * Clear the table.  This clears all the query callback
pointers,
 	 * and sets up the terminating table entry.
@@ -430,13 +472,17 @@
 	table[8].Name = L"PartitionKey";
 	table[8].EntryContext = &pkeyString;
 	table[8].DefaultType  = REG_SZ;
-	table[8].DefaultData  = &empy_string;
-	table[8].DefaultLength = 1024*sizeof(WCHAR);
+	table[8].DefaultData  = &empty_string;
+
 	/* Have at it! */
 	status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, 
 		param_path.Buffer, table, NULL, NULL );
 	if (NT_SUCCESS(status))
-			g_pkeys.pkey_num =
__prepare_pKey_array(&pkeyString, (uint16_t*)g_pkeys.pkey_array);
+	{
+			if(
!NT_SUCCESS(__build_pkeys_per_port(&pkeyString)))
+				BUS_TRACE(BUS_DBG_ERROR ,
+						 ("Failed to build pkey
configuration\n"));
+	}
 #if DBG
 	if( g_al_dbg_flags & AL_DBG_ERR )
 		g_al_dbg_flags |= CL_DBG_ERROR;
@@ -608,6 +654,37 @@
 	return status;
 }
 
+cl_status_t
+bus_rem_pkey(cl_ioctl_handle_t			h_ioctl)
+{
+	cl_status_t 				status;
+	pkey_array_t 				*pkeys;
+	PIO_STACK_LOCATION			pIoStack;
+
+	BUS_ENTER( BUS_DBG_DRV );
+
+	pIoStack = IoGetCurrentIrpStackLocation(h_ioctl);
+	if ( (! h_ioctl->AssociatedIrp.SystemBuffer) || 
+		 pIoStack->Parameters.DeviceIoControl.InputBufferLength
< sizeof (pkey_array_t))
+    {
+		BUS_TRACE_EXIT( BUS_DBG_ERROR, 
+			("Invalid parameters.\n") );
+		return CL_INVALID_PARAMETER;
+	}
+
+	pkeys =  (pkey_array_t*)h_ioctl->AssociatedIrp.SystemBuffer;
+
+	/* removes pdo */
+	status = port_mgr_pkey_rem(pkeys);
+	if (! NT_SUCCESS(status))
+	{
+		BUS_TRACE_EXIT( BUS_DBG_ERROR, 
+			("port_mgr_pkey_rem returned %08x.\n", status)
);
+	}
+
+	BUS_EXIT( BUS_DBG_DRV );
+	return status;
+}
 static NTSTATUS
 bus_drv_sysctl(
 	IN				DEVICE_OBJECT
*p_dev_obj,
@@ -643,14 +720,21 @@
 bus_drv_unload(
 	IN				DRIVER_OBJECT
*p_driver_obj )
 {
+	pkey_conf_t *cur_conf,*tmp;
 	UNICODE_STRING		 dos_name;
-	UNUSED_PARAM( p_driver_obj );
 
 	BUS_ENTER( BUS_DBG_DRV );
 	
 	RtlInitUnicodeString( &dos_name, L"\\DosDevices\\Global\\ibal"
);
+	UNUSED_PARAM( p_driver_obj );
 	IoDeleteSymbolicLink( &dos_name );
-
+	cur_conf = bus_globals.p_pkey_conf;
+	while(cur_conf)
+	{
+		tmp = cur_conf;
+		cur_conf = cur_conf->next_conf;
+		cl_free(tmp);
+	}
 	CL_DEINIT;
 
 #if defined(EVENT_TRACING)
Index: core/bus/kernel/bus_driver.h
===================================================================
--- core/bus/kernel/bus_driver.h	(revision 1244)
+++ core/bus/kernel/bus_driver.h	(working copy)
@@ -44,7 +44,7 @@
 #include "iba/ib_al.h"
 #include "bus_port_mgr.h"
 #include "bus_iou_mgr.h"
-
+#include "al_dev.h"
 /* Safe string functions. */
 #if WINVER == 0x500
 /*
@@ -180,6 +180,12 @@
 	
 }	bus_pdo_ext_t;
 
+/* pkey configuration */
+typedef struct _pkey_conf_t
+{
+	pkey_array_t    pkeys_per_port;
+	struct _pkey_conf_t *next_conf;
+}pkey_conf_t;
 
 /*
  * Global Driver parameters.
@@ -198,6 +204,8 @@
 	/* Pointer to the one and only bus root. */
 	bus_fdo_ext_t			*p_bus_ext;
 
+	/* pkey array to be read */
+	pkey_conf_t				*p_pkey_conf;
 }	bus_globals_t;
 
 
Index: core/bus/kernel/bus_iou_mgr.c
===================================================================
--- core/bus/kernel/bus_iou_mgr.c	(revision 1244)
+++ core/bus/kernel/bus_iou_mgr.c	(working copy)
@@ -615,7 +615,7 @@
 	BUS_TRACE( BUS_DBG_PNP, ("%s: ext %p, present %d, missing %d
.\n",
 		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 ) );
 
-	p_iou_ext->guid = p_pnp_rec->guid;
+	p_iou_ext->guid = p_pnp_rec->pnp_rec.guid;
 	p_iou_ext->chassis_guid = p_pnp_rec->chassis_guid;
 	p_iou_ext->slot = p_pnp_rec->slot;
 	p_iou_ext->vend_id = cl_ntoh32( p_pnp_rec->vend_id );
Index: core/bus/kernel/bus_pnp.h
===================================================================
--- core/bus/kernel/bus_pnp.h	(revision 1244)
+++ core/bus/kernel/bus_pnp.h	(working copy)
@@ -87,4 +87,5 @@
 	IN				IRP* const
p_irp );
 
 NTSTATUS port_mgr_pkey_add();
+NTSTATUS port_mgr_pkey_rem();
 #endif	// !defined _BUS_DRV_PNP_H_
Index: core/bus/kernel/bus_port_mgr.c
===================================================================
--- core/bus/kernel/bus_port_mgr.c	(revision 1244)
+++ core/bus/kernel/bus_port_mgr.c	(working copy)
@@ -44,10 +44,12 @@
 #include "iba/ipoib_ifc.h"
 #include "al_dev.h"
 
+#define IPOIB_PART_DEVICE_ID	L"IBA\\IPoIBP"
 #define IPOIB_DEVICE_ID			L"IBA\\IPoIB"
 #define IPOIB_COMPAT_ID
L"IBA\\SID_1000066a00020000\0\0"
 /* Hardware ID is a MULTI_SZ, so is terminated with a double NULL. */
 #define IPOIB_HARDWARE_ID		IPOIB_DEVICE_ID L"\0"
+#define IPOIB_PART_HARDWARE_ID	IPOIB_PART_DEVICE_ID L"\0"
 #define IPOIB_DESCRIPTION		L"OpenIB IPoIB Adapter"
 
 /* {5A9649F4-0101-4a7c-8337-796C48082DA2} */
@@ -62,7 +64,7 @@
 {
 	bus_pdo_ext_t			pdo;
 
-	port_guid_pkey			port_guid;
+	port_guid_pkey_t		port_guid;
 	uint32_t				n_port;
 
 	/* Number of references on the upper interface. */
@@ -73,9 +75,6 @@
 
 port_mgr_t*						gp_port_mgr =
NULL;
 
-extern pkey_array_t  g_pkeys;
-
-static boolean_t pkeys_enumerated = FALSE;
 /*
  * Function prototypes.
  */
@@ -573,6 +572,8 @@
     uint8_t         num_pdo;
 	bus_port_ext_t	*p_port_ext;
 	ib_net16_t      pdo_cnt;
+	pkey_conf_t		*cur_conf; 
+	pkey_array_t	*cur_pkeys = NULL;
 	BUS_ENTER( BUS_DBG_PNP );
 
 	if( !bus_globals.b_report_port_nic )
@@ -591,12 +592,22 @@
 		return status;
 	}
 
+	cur_conf = bus_globals.p_pkey_conf;
+	while(cur_conf)
+	{
+		if(p_pnp_rec->p_port_attr->port_guid ==
cur_conf->pkeys_per_port.port_guid)
+		{
+			cur_pkeys = &cur_conf->pkeys_per_port;
+			break;
+		}
+		cur_conf = cur_conf->next_conf;
+	}
     p_port_ext = NULL;
 
-	if( pkeys_enumerated)
+	if( !cur_pkeys)
 		pdo_cnt = 1;
 	else
-		pdo_cnt = g_pkeys.pkey_num + 1;
+		pdo_cnt = cur_conf->pkeys_per_port.pkey_num + 1;
 
     for (num_pdo = 0; num_pdo < pdo_cnt; num_pdo++)
     {
@@ -653,7 +664,7 @@
 
 		if(num_pdo > 0)
 		{
-		  p_port_ext->port_guid.pkey =
g_pkeys.pkey_array[num_pdo -1];
+			p_port_ext->port_guid.pkey =
cur_pkeys->pkey_array[num_pdo -1];
 		}
 	/* Store the device extension in the port vector for future
queries. */
 	cl_mutex_acquire( &gp_port_mgr->pdo_mutex );
@@ -668,7 +679,6 @@
 		if(num_pdo == 0)
 			p_pnp_rec->pnp_rec.context = p_port_ext;
 	}
-	pkeys_enumerated = TRUE;
 
 	/* Tell the PnP Manager to rescan for the HCA's bus relations.
*/
 	IoInvalidateDeviceRelations(
@@ -683,24 +693,80 @@
 }
 
 
/***********************************************************************
*************
+* name	:	port_mgr_pkey_rem
+*           removes pdo for each pkey value in pkey_array 
+* input	:	g_pkeys
+* output:	none
+* return:	cl_status
+***********************************************************************
**************/
+cl_status_t port_mgr_pkey_rem(pkey_array_t *pkeys)
+{
+	uint16_t 			cnt;
+
+	cl_list_item_t		*p_list_item;
+	bus_port_ext_t		*p_port_ext;
+
+	bus_pdo_ext_t		*p_pdo_ext = NULL;
+	cl_qlist_t*			p_pdo_list =
&gp_port_mgr->port_list;
+
+	BUS_ENTER( BUS_DBG_PNP );
+
+	p_port_ext = NULL;
+	cl_mutex_acquire( &gp_port_mgr->pdo_mutex );
+	
+	/* Count the number of child devices. */
+	for( p_list_item = cl_qlist_head( p_pdo_list );
+		p_list_item != cl_qlist_end( p_pdo_list );
+		p_list_item = cl_qlist_next( p_list_item ) )
+	{
+		p_pdo_ext = PARENT_STRUCT( p_list_item, bus_pdo_ext_t,
list_item );
+		p_port_ext = (bus_port_ext_t*)p_pdo_ext;
+
+		if(p_port_ext->port_guid.guid == pkeys->port_guid)
+		{
+			for(cnt = 0; cnt < pkeys->pkey_num; cnt++)
+			{
+				if( (p_port_ext->port_guid.pkey ==
pkeys->pkey_array[cnt]) &&
+					(p_port_ext->port_guid.pkey !=
IB_DEFAULT_PKEY))
+				{
+					p_port_ext->pdo.b_present =
FALSE;
+					break;
+				}
+			}
+		}
+	}
+	cl_mutex_release( &gp_port_mgr->pdo_mutex );
+
+	/* Tell the PnP Manager to rescan for the HCA's bus relations.
*/
+	IoInvalidateDeviceRelations(
+		p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev,
BusRelations );
+
+	/* Invalidate removal relations for the bus driver. */
+	IoInvalidateDeviceRelations(
+		bus_globals.p_bus_ext->cl_ext.p_pdo, RemovalRelations );
+
+	BUS_EXIT( BUS_DBG_PNP );
+	return CL_SUCCESS;
+}
+/**********************************************************************
**************
 * name	:	port_mgr_pkey_add
 *           creates pdo for each pkey value in pkey_array 
 * input	:	g_pkeys
 * output:	none
 * return:	cl_status
 
************************************************************************
*************/
-cl_status_t port_mgr_pkey_add(pkey_array_t *pkeys)
+cl_status_t port_mgr_pkey_add(pkey_array_t *req_pkeys)
 {
 	uint16_t 			cnt;
 	NTSTATUS            status;
 	cl_list_item_t		*p_list_item;
-	bus_port_ext_t		*p_port_ext, *pkey_port_ext;
+	bus_port_ext_t		*p_port_ext, *pkey_port_ext,
*pmatched_guid_ext;
 	DEVICE_OBJECT       *p_pdo[MAX_NUM_PKEY];
-	bus_pdo_ext_t		*p_pdo_ext = NULL;
 	cl_qlist_t*			p_pdo_list =
&gp_port_mgr->port_list;
 
 	BUS_ENTER( BUS_DBG_PNP );
 
+	pmatched_guid_ext = NULL;
 	p_port_ext = NULL;
 	cl_mutex_acquire( &gp_port_mgr->pdo_mutex );
 	
@@ -709,23 +775,38 @@
 		p_list_item != cl_qlist_end( p_pdo_list );
 		p_list_item = cl_qlist_next( p_list_item ) )
 	{
-		p_pdo_ext = PARENT_STRUCT( p_list_item, bus_pdo_ext_t,
list_item );
-		p_port_ext = (bus_port_ext_t*)p_pdo_ext;
+		p_port_ext = (bus_port_ext_t*)PARENT_STRUCT(
p_list_item, bus_pdo_ext_t, list_item );
 
-		if(p_port_ext->port_guid.pkey != IB_DEFAULT_PKEY)
-			break;
+		if(p_port_ext->port_guid.guid == req_pkeys->port_guid)
+		{
+			uint16_t i;
+			for(i = 0; i < req_pkeys->pkey_num; i++)
+			{
+				if(p_port_ext->port_guid.pkey ==
req_pkeys->pkey_array[i])
+				{
+					/* was removed previously */
+					p_port_ext->pdo.b_present =
TRUE;
+
p_port_ext->pdo.b_reported_missing = FALSE;
+					req_pkeys->pkey_array[i] = 0;  
+				}
+			}
+			if(!pmatched_guid_ext)
+				pmatched_guid_ext = p_port_ext;
+		}
 	}
 	cl_mutex_release( &gp_port_mgr->pdo_mutex );
 
-	if (!p_port_ext)
+	if (!pmatched_guid_ext)
 	{
 		BUS_TRACE_EXIT( BUS_DBG_ERROR,
 			("No existed pdo found.\n") );
 		return CL_ERROR;
 	}
 
-    for (cnt = 0; cnt < pkeys->pkey_num; cnt++)
+    for (cnt = 0; cnt < req_pkeys->pkey_num; cnt++)
     {
+		if(! (cl_hton16(req_pkeys->pkey_array[cnt]) &
IB_PKEY_BASE_MASK) )
+			continue;
 
 		/* Create the PDO for the new port device. */
 		status = IoCreateDevice( bus_globals.p_driver_obj,
sizeof(bus_port_ext_t),
@@ -758,11 +839,11 @@
 			pkey_port_ext->pdo.b_reported_missing ) );
 	
 		/* Cache the CA GUID. */
-		pkey_port_ext->pdo.ca_guid = p_port_ext->pdo.ca_guid;
-		pkey_port_ext->pdo.h_ca = p_port_ext->pdo.h_ca;
-		pkey_port_ext->port_guid.guid =
p_port_ext->port_guid.guid;
-		pkey_port_ext->n_port = p_port_ext->n_port;
-		pkey_port_ext->port_guid.pkey = pkeys->pkey_array[cnt];
+		pkey_port_ext->pdo.ca_guid =
pmatched_guid_ext->pdo.ca_guid;
+		pkey_port_ext->pdo.h_ca = pmatched_guid_ext->pdo.h_ca;
+		pkey_port_ext->port_guid.guid =
pmatched_guid_ext->port_guid.guid;
+		pkey_port_ext->n_port = pmatched_guid_ext->n_port;
+		pkey_port_ext->port_guid.pkey =
req_pkeys->pkey_array[cnt];
 
 		/* Store the device extension in the port vector for
future queries. */
 		cl_mutex_acquire( &gp_port_mgr->pdo_mutex );
@@ -773,7 +854,7 @@
 
 	/* Tell the PnP Manager to rescan for the HCA's bus relations.
*/
 	IoInvalidateDeviceRelations(
-		p_port_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev,
BusRelations );
+
pmatched_guid_ext->pdo.h_ca->obj.p_ci_ca->verbs.p_hca_dev, BusRelations
);
 
 	/* Invalidate removal relations for the bus driver. */
 	IoInvalidateDeviceRelations(
@@ -1079,6 +1160,7 @@
 {
 	WCHAR				*p_string;
 	bus_port_ext_t		*p_ext;
+	size_t				dev_id_size;
 	
 	BUS_ENTER( BUS_DBG_PNP );
 
@@ -1089,17 +1171,23 @@
 		BUS_TRACE_EXIT( BUS_DBG_ERROR, ("Device not present.\n")
);
 		return STATUS_NO_SUCH_DEVICE;
 	}
-
+	if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)
+		dev_id_size = sizeof(IPOIB_DEVICE_ID);
+	else
+		dev_id_size = sizeof(IPOIB_PART_DEVICE_ID );
 	/* Device ID is "IBA\SID_<sid> where <sid> is the IPoIB Service
ID. */
-	p_string = ExAllocatePoolWithTag( PagedPool,
sizeof(IPOIB_DEVICE_ID), 'vedq' );
+	p_string = ExAllocatePoolWithTag( PagedPool, dev_id_size, 'vedq'
);
 	if( !p_string )
 	{
 		BUS_TRACE_EXIT( BUS_DBG_ERROR,
 			("Failed to allocate device ID buffer (%d
bytes).\n",
-			sizeof(IPOIB_DEVICE_ID)) );
+			dev_id_size) );
 		return STATUS_INSUFFICIENT_RESOURCES;
 	}
-	cl_memcpy( p_string, IPOIB_DEVICE_ID, sizeof(IPOIB_DEVICE_ID) );
+	if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)
+		cl_memcpy( p_string, IPOIB_DEVICE_ID,
sizeof(IPOIB_DEVICE_ID) );
+	else
+		cl_memcpy( p_string, IPOIB_PART_DEVICE_ID,
sizeof(IPOIB_PART_DEVICE_ID) );
 	p_irp->IoStatus.Information = (ULONG_PTR)p_string;
 
 	BUS_EXIT( BUS_DBG_PNP );
@@ -1114,26 +1202,30 @@
 {
 	WCHAR				*p_string;
 	bus_port_ext_t		*p_ext;
+	size_t				dev_id_size;
 
 	BUS_ENTER( BUS_DBG_PNP );
 
 
-	p_ext = (bus_port_ext_t*)p_dev_obj->DeviceExtension;
-	if( !p_ext->pdo.b_present )
-	{
-		BUS_TRACE_EXIT( BUS_DBG_ERROR, ("Device not present.\n")
);
-		return STATUS_NO_SUCH_DEVICE;
-	}
+	p_ext = p_dev_obj->DeviceExtension;
 
-	p_string = ExAllocatePoolWithTag( PagedPool,
sizeof(IPOIB_HARDWARE_ID), 'ihqp' );
+	if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)
+		dev_id_size = sizeof(IPOIB_HARDWARE_ID);
+	else
+		dev_id_size = sizeof(IPOIB_PART_HARDWARE_ID );
+
+	p_string = ExAllocatePoolWithTag( PagedPool, dev_id_size, 'ihqp'
);
 	if( !p_string )
 	{
 		BUS_TRACE_EXIT( BUS_DBG_ERROR,
 			("Failed to allocate hardware ID buffer (%d
bytes).\n",
-			sizeof(IPOIB_HARDWARE_ID)) );
+			dev_id_size) );
 		return STATUS_INSUFFICIENT_RESOURCES;
 	}
-	cl_memcpy( p_string, IPOIB_HARDWARE_ID,
sizeof(IPOIB_HARDWARE_ID) );
+	if(p_ext->port_guid.pkey == IB_DEFAULT_PKEY)
+		cl_memcpy( p_string, IPOIB_HARDWARE_ID,
sizeof(IPOIB_HARDWARE_ID) );
+	else
+		cl_memcpy( p_string, IPOIB_PART_HARDWARE_ID,
sizeof(IPOIB_PART_HARDWARE_ID) );
 	p_irp->IoStatus.Information = (ULONG_PTR)p_string;
 
 	BUS_EXIT( BUS_DBG_PNP );
Index: inc/kernel/iba/ipoib_ifc.h
===================================================================
--- inc/kernel/iba/ipoib_ifc.h	(revision 1244)
+++ inc/kernel/iba/ipoib_ifc.h	(working copy)
@@ -68,7 +68,7 @@
 {
 	net64_t		guid;
 	ib_net16_t	pkey;
-} port_guid_pkey;
+} port_guid_pkey_t;
 
 
 /*
@@ -79,7 +79,7 @@
 typedef struct _ipoib_ifc_data
 {
 	net64_t						ca_guid;
-	port_guid_pkey				port_guid;
+	port_guid_pkey_t			port_guid;
 	uint8_t						port_num;
 
 }	ipoib_ifc_data_t;
Index: tools/part_man/user/part_man.c
===================================================================
--- tools/part_man/user/part_man.c	(revision 1244)
+++ tools/part_man/user/part_man.c	(working copy)
@@ -21,6 +21,7 @@
 	{
 		struct
 		{
+			net64_t			   port_guid;
 			unsigned short     pkey_num;
 			unsigned __int16   pkeys[MAX_NUM_PKEY];
 			Pkey_action		   action;
@@ -33,7 +34,7 @@
 
 void show_help()
 {
-	printf("Usage : part_man.exe <show|add|rem> <pkey1 pkey2
...>\n");
+	printf("Usage : part_man.exe <show|add|rem> <port_guid> <pkey1,
pkey2, ...>\n");
 }
 
 /********************************************************************
@@ -106,43 +107,72 @@
 static int reg_ibbus_pkey_add(const uint16_t *pkeys, uint16_t
pkey_num,OUT pkey_array_t *pkey)
 {
 	char partKey[DEFAULT_BUFER_SIZE];
-	char tmp[10];
+	char tmp[20];
+	char *guid_string, *p;
 	HKEY reg_handle;
 	LONG   ret;
+	char *tmpbuff = NULL;
 	int cnt;
 	int retval = 0;
 	uint16_t i = 0;
 	DWORD  read_length;
 
 	read_length =
reg_ibbus_pkey_show(FALSE,(char*)partKey,&reg_handle);
-
+	p = NULL;
+	guid_string = NULL;
 	if (read_length < 4)
 	{
 		/* empty string read, simply write to registry */
-		cnt = sprintf(partKey,"0x%04X",pkeys[0]);
-		pkey->pkey_array[pkey->pkey_num] = pkeys[0];
-		pkey->pkey_num++;
-		i = 1;
+		cnt = sprintf(partKey,"0x%I64X:",pkey->port_guid);
 	}
 	else
 	{
 		/* update the existed registry list */
-		cnt = (int)strlen(partKey);
-		i = 0;
+		sprintf(tmp,"0x%I64X",pkey->port_guid);
+		guid_string = strstr(partKey,tmp);
+		if(guid_string)
+		{
+			p = strstr(guid_string,";");
+			tmpbuff = (char*)malloc(strlen(p) + 1);
+			if(!tmpbuff)
+			{
+				printf("Failed memory allocation\n");
+				return 1;
+			}
+			/* save the rest of the string */
+			strcpy(tmpbuff,p);
+			cnt = (int)(p - partKey);
+		}
+		else
+		{
+			cnt = strlen(partKey) + sprintf(partKey +
strlen(partKey),"%s:",tmp);
+		}
 	}	
 
-	for ( ;i < pkey_num; i++)
+	for (i = 0 ;i < pkey_num; i++)
 	{
+		char *same_pkey;
 		sprintf(tmp,"0x%04X",pkeys[i]);
-		if (strstr(partKey,tmp))
+		if ( guid_string )
 		{
+			same_pkey = strstr(guid_string,tmp);
+			if( same_pkey && (same_pkey < p) )
 			continue;
 		}
 		pkey->pkey_array[pkey->pkey_num] = pkeys[i];
 		pkey->pkey_num++;
-		cnt += sprintf(partKey + cnt,",0x%04X",pkeys[i]);
+		if( (i == 0) && (!guid_string))
+			cnt += sprintf(partKey + cnt,"0x%04X",pkeys[i]);
+		else
+			cnt += sprintf(partKey +
cnt,",0x%04X",pkeys[i]);
 	}
-	cnt += sprintf(partKey + cnt,"\0");
+	if(tmpbuff)
+	{
+		cnt += sprintf(partKey + cnt,"%s",tmpbuff);
+		free(tmpbuff);
+	}
+	else
+		cnt += sprintf(partKey + cnt,";\0");
 
 	if(pkey->pkey_num)
 	{
@@ -171,9 +201,14 @@
 	unsigned __int16 cur_pkey;
 	int retval = 0;
 	unsigned short i = 0;
-	char seps[] = ",";
+	char pkey_sep[] = ",";
+	char *pfrom, *pto;
+	char *guid_string;
+	char tmp[20];
 	char *token;
+	char *pafter = NULL;
 	boolean_t found2remove;
+	boolean_t pkey_not_written = TRUE;
 
 	read_length =
reg_ibbus_pkey_show(FALSE,(char*)partKey,&reg_handle);
 	do
@@ -186,8 +221,38 @@
 			break;
 		}
 
-		token = strtok(partKey,seps);
-		cnt = 0;
+		sprintf(tmp,"0x%I64X\0",pkey->port_guid);
+		guid_string = strstr(partKey,tmp);
+		if (! guid_string)
+		{
+			printf("No guid configured - nothing to
remove\n");
+			retval = 1;
+			break;
+		}
+		pfrom = strstr(guid_string,":");
+		pto   = strstr(guid_string,";");
+		if ( (!pfrom) || (!pto))
+		{
+			printf("Error configuration\n");
+			retval = 1;
+			break;
+		}
+
+		pfrom++;
+		pafter  = (char*)malloc(strlen(pto) + 1);
+
+		if(!pafter)
+		{
+			printf("Allocation failed\n");
+			retval = 1;
+			break;
+		}
+		_snprintf(newKey,(int)(pfrom - partKey),"%s",partKey);
+		cnt = (int)(pfrom - partKey);
+		strcpy(pafter,pto);
+		pto[0] = '\0';
+		strcpy(partKey,pfrom);
+		token = strtok(partKey,pkey_sep);
 		while(token)
 		{
 			found2remove = FALSE;
@@ -202,7 +267,10 @@
 			{
 				found2remove = (boolean_t)(cur_pkey ==
pkeys[i]);
 				if(found2remove)
+				{
+					pkey->pkey_array[pkey->pkey_num]
= pkeys[i];
 					break;
+				}
 			}
 			
 			if(found2remove)
@@ -211,12 +279,15 @@
 			}
 			else
 			{
-				if(!cnt)
+				if(pkey_not_written)
+				{
 					cnt += sprintf(newKey +
cnt,"0x%04X",cur_pkey);
+					pkey_not_written = FALSE;
+				}
 				else
 					cnt += sprintf(newKey +
cnt,",0x%04X",cur_pkey);
 			}
-			token = strtok(NULL,seps);
+			token = strtok(NULL,pkey_sep);
 		}
 
 		if(! pkey->pkey_num)
@@ -227,6 +298,10 @@
 			break;
 		}
 
+		if(pkey_not_written)
+			cnt -= (2 + strlen(tmp));
+		
+		strcpy(newKey + cnt,pafter);
 		ret =
RegSetValueEx(reg_handle,"PartitionKey",0,REG_SZ,(BYTE*)newKey,
(DWORD)strlen(newKey));
 		if (ERROR_SUCCESS != ret)
 		{
@@ -236,12 +311,14 @@
 		}
 	}
 	while(FALSE);
+	if(pafter)
+		free(pafter);
 
 	RegCloseKey( reg_handle );
 	return retval;
 }
 
-int send_create_pdo_req(pkey_array_t *pkeys)
+int send_pdo_req(pkey_array_t *pkeys,DWORD iocode)
 {
 	HANDLE hKernelLib;
 	DWORD		bytesReturned;
@@ -264,7 +341,7 @@
 	}
 
 	if (! DeviceIoControl(hKernelLib,
-						  UAL_REQ_CREATE_PDO,
+						  iocode,
 
pkeys,sizeof(pkey_array_t),
 						  NULL,0,
 						  &bytesReturned,
@@ -290,20 +367,25 @@
 	}
 
 	RtlZeroMemory(&pkeys,sizeof(pkeys));
+	pkeys.port_guid = input->u.guid_pkey.port_guid;
 	if(input->u.guid_pkey.action == pkey_add)
 		result = reg_ibbus_pkey_add((unsigned
__int16*)input->u.guid_pkey.pkeys, input->u.guid_pkey.pkey_num, &pkeys);
 	else if(input->u.guid_pkey.action == pkey_rem)
-	{
+
 		result = reg_ibbus_pkey_rem((unsigned
__int16*)input->u.guid_pkey.pkeys, input->u.guid_pkey.pkey_num, &pkeys);
-		return (boolean_t)(result == 0);
-	}
 	else if(input->u.guid_pkey.action == pkey_show)
 		return reg_ibbus_print_pkey();
 
-	if(0 == result)
+	if( (0 == result) && pkeys.pkey_num)
 	{
-		if(pkeys.pkey_num)
-			return (boolean_t)( 0 ==
send_create_pdo_req(&pkeys));
+		if(input->u.guid_pkey.action == pkey_add)
+		{
+			return (boolean_t)( 0 ==
send_pdo_req(&pkeys,UAL_REQ_CREATE_PDO));
+		}
+		else if(input->u.guid_pkey.action == pkey_rem)
+		{
+			return (boolean_t)( 0 ==
send_pdo_req(&pkeys,UAL_REQ_REMOVE_PDO));
+		}
 	}
 	return FALSE;
 }
@@ -328,14 +410,21 @@
 		return 0;
 	}
 
-	if(num < 3)
+	if(num < 4)
 	{
 		printf("invalid command %s\n",cmd[1]);
 		return 0;
 	}
-	for( i = 2; i < num; i++)
+
+	if (strstr(cmd[2],"0x"))
+		sscanf(cmd[2],"0x%I64x",&input->u.guid_pkey.port_guid);
+	else
+		sscanf(cmd[2],"%I64x",&input->u.guid_pkey.port_guid);
+	for( i = 3; i < num; i++)
 	{
-		if (strstr(cmd[i],"0x"))
+		if((strstr(cmd[i],"ffff")) || (strstr(cmd[i],"FFFF")))
+			continue;
+		if (strstr(cmd[i],"0x") || strstr(cmd[i],"0X"))
 
sscanf(cmd[i],"0x%x",&input->u.guid_pkey.pkeys[input->u.guid_pkey.pkey_n
um]);
 		else
 
sscanf(cmd[i],"%x",&input->u.guid_pkey.pkeys[input->u.guid_pkey.pkey_num
]);
Index: ulp/ipoib/kernel/ipoib_port.c
===================================================================
--- ulp/ipoib/kernel/ipoib_port.c	(revision 1244)
+++ ulp/ipoib/kernel/ipoib_port.c	(working copy)
@@ -844,20 +844,25 @@
 		CL_ASSERT(ca_attr->p_port_attr->p_pkey_table[0] ==
IB_DEFAULT_PKEY);
 		for(index = 0; index < ca_attr->p_port_attr->num_pkeys;
index++)
 		{
-			if(p_port->p_adapter->guids.port_guid.pkey ==
ca_attr->p_port_attr->p_pkey_table[index])
+
if(cl_hton16(p_port->p_adapter->guids.port_guid.pkey) ==
ca_attr->p_port_attr->p_pkey_table[index])
 				break;
 		}
 		if(index >= ca_attr->p_port_attr->num_pkeys)
 		{
 			IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,
IPOIB_DBG_ERROR,
 			("Pkey table is invalid, index not found\n"));
+			cl_free(ca_attr);
 		    return IB_NOT_FOUND;
 		}
 		p_port->pkey_index = index;
 		IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_IB,
 			("for PKEY = 0x%04X got index =
%d\n",p_port->p_adapter->guids.port_guid.pkey,index));
 	}
-	cl_free(ca_attr);
+	else
+	{
+		cl_free(ca_attr);
+		return IB_NOT_FOUND;
+	}
 	/* Allocate the PD. */
 	status = p_port->p_adapter->p_ifc->alloc_pd(
 		p_port->ib_mgr.h_ca, IB_PDT_UD, p_port,
&p_port->ib_mgr.h_pd );
@@ -4942,9 +4947,9 @@
 	cl_memclr( &member_rec, sizeof(ib_member_rec_t) );
 	member_rec.mgid = bcast_mgid_template;
 
-    member_rec.mgid.raw[4] = (uint8_t)
p_port->p_adapter->guids.port_guid.pkey ;
-	member_rec.mgid.raw[5] = (uint8_t)
(p_port->p_adapter->guids.port_guid.pkey >> 8);
-	member_rec.pkey = p_port->p_adapter->guids.port_guid.pkey;
+    member_rec.mgid.raw[4] =
(uint8_t)(p_port->p_adapter->guids.port_guid.pkey >> 8);
+	member_rec.mgid.raw[5] =
(uint8_t)p_port->p_adapter->guids.port_guid.pkey;
+	member_rec.pkey =
cl_hton16(p_port->p_adapter->guids.port_guid.pkey);
 	cl_memclr( &query, sizeof(ib_query_req_t) );
 	query.query_type = IB_QUERY_USER_DEFINED;
 	query.p_query_input = &info;
@@ -5136,8 +5141,8 @@
 	 * We specify the MGID since we don't want the SA to generate it
for us.
 	 */
 	mcast_req.member_rec.mgid = bcast_mgid_template;
-	mcast_req.member_rec.mgid.raw[4] = (uint8_t)
p_port->p_adapter->guids.port_guid.pkey; 
-	mcast_req.member_rec.mgid.raw[5] = (uint8_t)
(p_port->p_adapter->guids.port_guid.pkey >> 8);
+	mcast_req.member_rec.mgid.raw[4] =
(uint8_t)(p_port->p_adapter->guids.port_guid.pkey >> 8); 
+	mcast_req.member_rec.mgid.raw[5] =
(uint8_t)p_port->p_adapter->guids.port_guid.pkey;
 	ib_gid_set_default( &mcast_req.member_rec.port_gid,
 		p_port->p_adapter->guids.port_guid.guid );
 	/*
@@ -5149,8 +5154,9 @@
 	mcast_req.member_rec.mtu =
 		(IB_PATH_SELECTOR_EXACTLY << 6) | IB_MTU_LEN_2048;
 
-	mcast_req.member_rec.pkey =
p_port->p_adapter->guids.port_guid.pkey;
+	mcast_req.member_rec.pkey =
cl_hton16(p_port->p_adapter->guids.port_guid.pkey);
 
+
 	mcast_req.member_rec.sl_flow_hop = ib_member_set_sl_flow_hop( 0,
0, 0 );
 	mcast_req.member_rec.scope_state =
 		ib_member_set_scope_state( 2,
IB_MC_REC_STATE_FULL_MEMBER );
@@ -5519,7 +5525,7 @@
 	mcast_req.retry_cnt = p_port->p_adapter->params.sa_retry_cnt;
 	mcast_req.port_guid = p_port->p_adapter->guids.port_guid.guid;
 	mcast_req.pkey_index = p_port->pkey_index;
-	mcast_req.member_rec.pkey =
p_port->p_adapter->guids.port_guid.pkey;
+	mcast_req.member_rec.pkey =
cl_hton16(p_port->p_adapter->guids.port_guid.pkey);
 	/*
 	 * Create the endpoint and insert it in the port.  Since we
don't wait for
 	 * the mcast SA operations to complete before returning from the
multicast
Index: ulp/ipoib/kernel/netipoib.inf
===================================================================
--- ulp/ipoib/kernel/netipoib.inf	(revision 1244)
+++ ulp/ipoib/kernel/netipoib.inf	(working copy)
@@ -21,12 +21,15 @@
 
 [OPENIB.ntx86]
 %IpoibDesc%      = Ipoib.DDInstall,    IBA\IPoIB   ; Internet Protocol
over InfiniBand Adapter
+%IpoibDescP%     = Ipoib.DDInstall,    IBA\IPoIBP  ; Internet Protocol
over InfiniBand Adapter with partition key
 
 [OPENIB.ntamd64]
 %IpoibDesc%      = Ipoib.DDInstall,    IBA\IPoIB   ; Internet Protocol
over InfiniBand Adapter
+%IpoibDescP%     = Ipoib.DDInstall,    IBA\IPoIBP  ; Internet Protocol
over InfiniBand Adapter with partition key
 
 [OPENIB.ntia64]
 %IpoibDesc%      = Ipoib.DDInstall,    IBA\IPoIB   ; Internet Protocol
over InfiniBand Adapter
+%IpoibDescP%     = Ipoib.DDInstall,    IBA\IPoIBP  ; Internet Protocol
over InfiniBand Adapter with partition key
 
 [Ipoib.DDInstall.ntx86]
 Characteristics = 0x81 ; NCF_HAS_UI | NCF_VIRTUAL
@@ -189,6 +192,7 @@
 [Strings]
 OPENIB               = "OpenIB Alliance"
 IpoibDesc            = "OpenIB IPoIB Adapter"
+IpoibDescP           = "OpenIB IPoIB Adapter Partition"
 IpoibServiceDispName = "IPoIB"
 IcsDisk1             = "OpenIB IPoIB Disk #1"
 DIRID_SYSTEM         = 11

-----Original Message-----
From: chas at cmf.nrl.navy.mil [mailto:chas at cmf.nrl.navy.mil] 
Sent: Monday, June 09, 2008 7:12 PM
To: Leonid Keller
Cc: Fab Tillier; Sean Hefty; Slava Strebkov; ofw at lists.openfabrics.org
Subject: Re: [ofw] RE: IPoIB partitioning support potential bug?

In message
<6C2C79E72C305246B504CBA17B5500C9042D5399 at mtlexch01.mtl.com>,"Leonid
Keller" writes:
>Please, review the attached patch. 

we had to make the following additional changes to get this patch to
work correctly.  since the port_guid.pkey is copied directly from
the g_pkeys array, the g_pkeys array needs to be in network order.
otherwise the test for the pkey in the pkey table table fails in
ulp/ipoib/kernel/ipoib_port.c at:

                for(index = 0; index < ca_attr->p_port_attr->num_pkeys;
index++)
                {
                        if(p_port->p_adapter->guids.port_guid.pkey ==
ca_attr->p_port_attr->p_pkey_table[index])
                                break;
                }

p_pkey_table[] is in network order (its copied directly from the wire)
and guids.port_guid.pkey is in host order from __prepare_pKey_array().
for consistency, we just decided to make guids.port_guid.pkey network
order as well.

Index: core/bu(/kernel/bus_driver.c
===================================================================
--- core/bus/kernel/bus_driver.c        (revision 1255)
+++ core/bus/kernel/bus_driver.c        (working copy)
@@ -191,7 +191,7 @@
 * output:      pkey_array
 * return:      uint16_t number of pkey(s) found
 
************************************************************************
*************/
-static uint16_t __prepare_pKey_array(IN const UNICODE_STRING *str, OUT
uint16_t *pkey_array)
+static uint16_t __prepare_pKey_array(IN const UNICODE_STRING *str, OUT
ib_net16_t *pkey_array)
 {
        uint16_t i, num_pKeys, cur_pkey_length;
        NTSTATUS status;
@@ -300,6 +300,8 @@
                case '\0':
                        if(cur_pkey_length == PATTERN_LENGTH)
                        {
+                               pkey_array[num_pKeys] =
cl_hton16(pkey_array[num_pKeys]);
+
                                cur_pkey_length = 0;
                                num_pKeys++;
                        }
@@ -436,7 +438,7 @@
        status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE,
                param_path.Buffer, table, NULL, NULL );
        if (NT_SUCCESS(status))
-                       g_pkeys.pkey_num =
__prepare_pKey_array(&pkeyString, (uint16_t*)g_pkeys.pkey_array);
+                       g_pkeys.pkey_num =
__prepare_pKey_array(&pkeyString, (ib_net16_t *)g_pkeys.pkey_array);
 #if DBG
        if( g_al_dbg_flags & AL_DBG_ERR )
                g_al_dbg_flags |= CL_DBG_ERROR;


with the above patch, this part of the your patch is no longer necessary
since the port_guid.pkey is already in network order at this point.

>Index: ulp/ipoib/kernel/ipoib_port.c
>===================================================================
>--- ulp/ipoib/kernel/ipoib_port.c	(revision 1222)
>+++ ulp/ipoib/kernel/ipoib_port.c	(working copy)
>@@ -4942,8 +4942,8 @@
> 	cl_memclr( &member_rec, sizeof(ib_member_rec_t) );
> 	member_rec.mgid = bcast_mgid_template;
> 
>-    member_rec.mgid.raw[4] = (uint8_t)
p_port->p_adapter->guids.port_guid.pkey ;
>-	member_rec.mgid.raw[5] = (uint8_t)
(p_port->p_adapter->guids.port_guid.pkey >> 8);
>+    member_rec.mgid.raw[4] = (uint8_t)
(p_port->p_adapter->guids.port_guid.pkey >> 8) ;
>+	member_rec.mgid.raw[5] = (uint8_t)
p_port->p_adapter->guids.port_guid.pkey;
> 	member_rec.pkey = p_port->p_adapter->guids.port_guid.pkey;
> 	cl_memclr( &query, sizeof(ib_query_req_t) );
> 	query.query_type = IB_QUERY_USER_DEFINED;
>@@ -5136,8 +5136,8 @@
> 	 * We specify the MGID since we don't want the SA to generate it
for us.
> 	 */
> 	mcast_req.member_rec.mgid = bcast_mgid_template;
>-	mcast_req.member_rec.mgid.raw[4] = (uint8_t)
p_port->p_adapter->guids.port_guid.pkey; 
>-	mcast_req.member_rec.mgid.raw[5] = (uint8_t)
(p_port->p_adapter->guids.port_guid.pkey >> 8);
>+	mcast_req.member_rec.mgid.raw[4] = (uint8_t)
(p_port->p_adapter->guids.port_guid.pkey >> 8); 
>+	mcast_req.member_rec.mgid.raw[5] = (uint8_t)
p_port->p_adapter->guids.port_guid.pkey;
> 	ib_gid_set_default( &mcast_req.member_rec.port_gid,
> 		p_port->p_adapter->guids.port_guid.guid );
> 	/*
-------------- next part --------------
A non-text attachment was scrubbed...
Name: partitions_tool2.diff
Type: application/octet-stream
Size: 36925 bytes
Desc: partitions_tool2.diff
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20080610/924088b2/attachment.obj>


More information about the ofw mailing list