[ofw] RE: IPoIB partitioning support potential bug?

Tzachi Dar tzachid at mellanox.co.il
Thu Jun 12 14:13:36 PDT 2008


Hi Slava,

I'll not be in office next week, so I'll be looking at your patch only
on the following week.

Thanks
Tzachi 

> -----Original Message-----
> From: Slava Strebkov [mailto:slavas at voltaire.com] 
> Sent: Tuesday, June 10, 2008 11:24 AM
> To: Tzachi Dar; chas at cmf.nrl.navy.mil; Leonid Keller
> Cc: ofw at lists.openfabrics.org; Fab Tillier
> Subject: RE: [ofw] RE: IPoIB partitioning support potential bug?
> 
> Hi,
> Added option to remove pkey adapter. Part_man has a new 
> parameter - port guid for add|rem partition - based adapter.
> e.g:
> part_man.exe add 0xcd7c970304f10800 0xdead
> 
> The above command will create new adapter on existed port 
> guid 0xcd7c970304f10800 with partition key 0xdead.
>  
> Changed registry format for partition keys storage and 
> routines operating with it.
> 
> Slava
> 
> -----Original Message-----
> From: Tzachi Dar [mailto:tzachid at mellanox.co.il]
> Sent: Tuesday, June 10, 2008 11:18 AM
> To: Slava Strebkov; chas at cmf.nrl.navy.mil; Leonid Keller
> Cc: ofw at lists.openfabrics.org; Fab Tillier
> Subject: RE: [ofw] RE: IPoIB partitioning support potential bug?
> 
> Hi Slava,
> 
> Can you please give us more information about what your patch is?
> 
> It seems to me much more than just trying to solve the initial issue.
> 
> Thanks
> Tzachi
> 
> > -----Original Message-----
> > From: ofw-bounces at lists.openfabrics.org 
> > [mailto:ofw-bounces at lists.openfabrics.org] On Behalf Of 
> Slava Strebkov
> > Sent: Tuesday, June 10, 2008 8:45 AM
> > To: chas at cmf.nrl.navy.mil; Leonid Keller
> > Cc: ofw at lists.openfabrics.org; Fab Tillier
> > Subject: RE: [ofw] RE: IPoIB partitioning support potential bug?
> > 
> > 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_p
> > key.pkey_n
> > um]);
> >  		else
> >  
> > sscanf(cmd[i],"%x",&input->u.guid_pkey.pkeys[input->u.guid_pke
> > y.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 );
> > > 	/*
> > 
> 
> 
> --
> Tzachi Dar
> Mellanox Technologies LTD.
> SW- Windows
> Phone: +972 (4) 909 7200 (ext 271)
> Mobile: +972 (57) 741 1269
> E-mail: tzachid at mellanox.co.il
> 
> ----------------------------------------------------------------------
> Emails belong on computers, trees belong in forests; if you 
> must print this, do it on recycled paper.
> http://www.greenpeace.org/international/
> ----------------------------------------------------------------------
> 
> 
> Disclaimer added by CodeTwo Exchange Rules http://www.codetwo.com
> 


--
Tzachi Dar
Mellanox Technologies LTD.
SW- Windows
Phone: +972 (4) 909 7200 (ext 271)
Mobile: +972 (57) 741 1269
E-mail: tzachid at mellanox.co.il

----------------------------------------------------------------------
Emails belong on computers, trees belong in forests; if you must print
this, do it on recycled paper.
http://www.greenpeace.org/international/
----------------------------------------------------------------------


Disclaimer added by CodeTwo Exchange Rules
http://www.codetwo.com



More information about the ofw mailing list