[ofw] RE: IPoIB partitioning support potential bug?

Slava Strebkov slavas at voltaire.com
Tue Jun 10 01:23:56 PDT 2008


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



More information about the ofw mailing list