From: stansmith Date: Tue, 26 Aug 2008 19:01:49 +0000 (+0000) Subject: [IBBUS] reconstituted omitted commits from 1499. X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=4995d12cb9060a3b0f9cd9051ce9a00abb20bf67;p=~shefty%2Frdma-win.git [IBBUS] reconstituted omitted commits from 1499. git-svn-id: svn://openib.tc.cornell.edu/gen1@1516 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- diff --git a/trunk/core/bus/kernel/bus_driver.c b/trunk/core/bus/kernel/bus_driver.c index cdd2c43e..addc2f9b 100644 --- a/trunk/core/bus/kernel/bus_driver.c +++ b/trunk/core/bus/kernel/bus_driver.c @@ -56,8 +56,8 @@ #else #define DEFAULT_NODE_DESC "OpenIB Windows® Host" #endif -/* pkey array to be read */ -pkey_array_t g_pkeys; + + char node_desc[IB_NODE_DESCRIPTION_SIZE]; @@ -183,7 +183,9 @@ __read_machine_name( void ) RtlStringCbCopyNA( node_desc, sizeof(node_desc), DEFAULT_NODE_DESC, sizeof(DEFAULT_NODE_DESC) ); } + BUS_EXIT( BUS_DBG_DRV ); } + /************************************************************************************ * name : __prepare_pKey_array * parses registry string and exrtacts pkey value(s) from it. @@ -192,135 +194,176 @@ __read_machine_name( void ) * 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; - - case 'A': - case 'a': - pkey_array[num_pKeys] = \ - (pkey_array[num_pKeys] << 4)| 0xA; - cur_pkey_length++; - break; - - case 'B': - case 'b': - pkey_array[num_pKeys] = \ - (pkey_array[num_pKeys] << 4)| 0xB; - cur_pkey_length++; - break; - - case 'C': - case 'c': - pkey_array[num_pKeys] = \ - (pkey_array[num_pKeys] << 4)| 0xC; - cur_pkey_length++; - break; - - case 'D': - case 'd': - pkey_array[num_pKeys] = \ - (pkey_array[num_pKeys] << 4)| 0xD; - cur_pkey_length++; - break; - - case 'E': - case 'e': - pkey_array[num_pKeys] = \ - (pkey_array[num_pKeys] << 4)| 0xE; - cur_pkey_length++; - break; - - case 'F': - case 'f': - pkey_array[num_pKeys] = \ - (pkey_array[num_pKeys] << 4)| 0xF; - cur_pkey_length++; - break; - - 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) + cur_pkey->pkey_array[cur_pkey->pkey_num++] = (uint16_t)tmp_val; + j = 0; + } + } + BUS_EXIT( BUS_DBG_DRV ); +} + +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; + + if (! *pp_cur_conf) + pp_cur_conf = &bus_globals.p_pkey_conf; + else + pp_cur_conf = &((*pp_cur_conf)->next_conf); + + *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; + } + + 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; + + 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); +} + +/************************************************************************ +* 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; + + 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 @@ -329,7 +372,7 @@ __read_registry( { NTSTATUS status; /* Remember the terminating entry in the table below. */ - RTL_QUERY_REGISTRY_TABLE table[10]; + RTL_QUERY_REGISTRY_TABLE table[12]; UNICODE_STRING param_path; UNICODE_STRING pkeyString; UNICODE_STRING empty_string; @@ -363,8 +406,6 @@ __read_registry( 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. @@ -435,16 +476,21 @@ __read_registry( table[8].DefaultType = REG_SZ; table[8].DefaultData = &empty_string; table[8].DefaultLength = 0; + /* 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; - bus_globals.dbg_lvl |= BUS_DBG_DRV | BUS_DBG_PNP; + //bus_globals.dbg_lvl |= BUS_DBG_DRV | BUS_DBG_PNP; #endif BUS_TRACE(BUS_DBG_DRV , @@ -613,12 +659,15 @@ bus_add_pkey(cl_ioctl_handle_t h_ioctl) 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)) @@ -627,10 +676,20 @@ bus_rem_pkey(cl_ioctl_handle_t h_ioctl) ("Invalid parameters.\n") ); return CL_INVALID_PARAMETER; } - 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, @@ -666,6 +725,7 @@ static void bus_drv_unload( IN DRIVER_OBJECT *p_driver_obj ) { + pkey_conf_t *cur_conf,*tmp; UNICODE_STRING dos_name; UNUSED_PARAM( p_driver_obj ); @@ -673,7 +733,13 @@ bus_drv_unload( RtlInitUnicodeString( &dos_name, L"\\DosDevices\\Global\\ibal" ); 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) @@ -741,4 +807,3 @@ DriverEntry( BUS_EXIT( BUS_DBG_DRV ); return STATUS_SUCCESS; } - diff --git a/trunk/core/bus/kernel/bus_driver.h b/trunk/core/bus/kernel/bus_driver.h index e4ff16e0..ecb0e659 100644 --- a/trunk/core/bus/kernel/bus_driver.h +++ b/trunk/core/bus/kernel/bus_driver.h @@ -45,7 +45,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,9 +180,15 @@ typedef struct _bus_pdo_ext /* work item for handling Power Management request */ PIO_WORKITEM p_po_work_item; - + boolean_t is_partition_pdo; } 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. @@ -202,6 +208,9 @@ typedef struct _bus_globals ib_pnp_handle_t h_pnp_port; ib_pnp_handle_t h_pnp_iou; + /* pkey array to be read */ + pkey_conf_t *p_pkey_conf; + } bus_globals_t; diff --git a/trunk/core/bus/kernel/bus_iou_mgr.c b/trunk/core/bus/kernel/bus_iou_mgr.c index 209837f9..39dc6558 100644 --- a/trunk/core/bus/kernel/bus_iou_mgr.c +++ b/trunk/core/bus/kernel/bus_iou_mgr.c @@ -334,7 +334,6 @@ create_iou_mgr( status = bus_reg_iou_pnp( p_bfi ); if( status != IB_SUCCESS ) { -// cl_obj_destroy( &gp_iou_mgr->obj ); free_iou_mgr( &gp_iou_mgr->obj ); BUS_TRACE_EXIT( BUS_DBG_ERROR, ("bus_reg_iou_pnp returned %s.\n", ib_get_err_str(status)) ); diff --git a/trunk/core/bus/kernel/bus_pnp.h b/trunk/core/bus/kernel/bus_pnp.h index 83fd743d..30f5cf90 100644 --- a/trunk/core/bus/kernel/bus_pnp.h +++ b/trunk/core/bus/kernel/bus_pnp.h @@ -87,4 +87,5 @@ bus_get_relations( IN IRP* const p_irp ); NTSTATUS port_mgr_pkey_add(); +NTSTATUS port_mgr_pkey_rem(); #endif // !defined _BUS_DRV_PNP_H_ diff --git a/trunk/core/bus/kernel/bus_port_mgr.c b/trunk/core/bus/kernel/bus_port_mgr.c index 435c167a..1cfeb675 100644 --- a/trunk/core/bus/kernel/bus_port_mgr.c +++ b/trunk/core/bus/kernel/bus_port_mgr.c @@ -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} */ @@ -82,7 +84,6 @@ typedef struct _port_pnp_context extern pkey_array_t g_pkeys; -static boolean_t pkeys_enumerated = FALSE; /* * Function prototypes. */ @@ -442,7 +443,7 @@ free_port_mgr( p_ext, p_ext->b_present, p_ext->b_reported_missing ) ); continue; } - if( p_ext->h_ca ) + if( p_ext->h_ca && (!p_ext->is_partition_pdo)) { /* Invalidate bus relations for the HCA. */ IoInvalidateDeviceRelations( @@ -767,6 +768,8 @@ port_mgr_port_add( 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_filter_t *p_bfi; port_mgr_t *gp_port_mgr; port_pnp_ctx_t *p_ctx = p_pnp_rec->pnp_rec.context; @@ -823,12 +826,22 @@ port_mgr_port_add( 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++) { @@ -875,6 +888,7 @@ port_mgr_port_add( if(num_pdo > 0) { p_port_ext->pdo.h_ca = ((bus_port_ext_t*)p_pdo[0]->DeviceExtension)->pdo.h_ca; + p_port_ext->pdo.is_partition_pdo = TRUE; } else p_port_ext->pdo.h_ca = acquire_ca( p_pnp_rec->p_ca_attr->ca_guid ); @@ -892,9 +906,7 @@ port_mgr_port_add( p_port_ext->n_ifc_ref = 0; 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 ); @@ -903,13 +915,12 @@ port_mgr_port_add( cl_mutex_release( &gp_port_mgr->pdo_mutex ); /* - * save the port_ext, as the context is passed in for future events on - * the same port. + * Set the context of the PNP event. The context is passed in for future + * events on the same port. */ if(num_pdo == 0) p_ctx->p_pdo_ext = p_port_ext; } - pkeys_enumerated = TRUE; /* Tell the PnP Manager to rescan for the HCA's bus relations. */ IoInvalidateDeviceRelations( @@ -919,6 +930,86 @@ port_mgr_port_add( return IB_SUCCESS; } +/************************************************************************************ +* 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( IN pkey_array_t *pkeys, + IN port_mgr_t *gp_port_mgr ) +{ + + 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 ); + + BUS_EXIT( BUS_DBG_PNP ); + return CL_SUCCESS; +} + + +cl_status_t port_mgr_pkey_rem( IN pkey_array_t *pkeys ) +{ + bus_filter_t *p_bfi; + cl_status_t status; + boolean_t GO; + int success_cnt=0; + + for(p_bfi=&bus_filters[0]; p_bfi < &bus_filters[MAX_BUS_FILTERS]; p_bfi++) + { + if ( !p_bfi->p_bus_ext ) + continue; + GO = FALSE; + ExAcquireFastMutexUnsafe(&ControlMutex); + if ( p_bfi->ca_guid && p_bfi->p_port_mgr ) + GO = TRUE; + ExReleaseFastMutexUnsafe(&ControlMutex); + if ( GO == FALSE ) + continue; + status = _port_mgr_pkey_rem( pkeys, p_bfi->p_port_mgr ); + if ( status == CL_SUCCESS ) + success_cnt++; + } + return ( success_cnt ? CL_SUCCESS : CL_ERROR ); +} + + /************************************************************************************ * name : port_mgr_pkey_add * creates pdo for each pkey value in pkey_array @@ -926,53 +1017,66 @@ port_mgr_port_add( * output: none * return: cl_status *************************************************************************************/ -cl_status_t _port_mgr_pkey_add ( IN pkey_array_t *pkeys, - IN bus_filter_t *p_bfi, - IN port_mgr_t *gp_port_mgr ) +cl_status_t _port_mgr_pkey_add( IN pkey_array_t *req_pkeys, + IN bus_filter_t *p_bfi, + IN port_mgr_t *gp_port_mgr ) { 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; + 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 ); - p_pdo_list = &gp_port_mgr->port_list; /* 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; + 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 existing pdo found.\n") ); - return CL_ERROR; + ("No existed pdo found.\n") ); + return CL_NOT_FOUND; } - 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), - NULL, FILE_DEVICE_CONTROLLER, - FILE_DEVICE_SECURE_OPEN - | FILE_AUTOGENERATED_DEVICE_NAME, - FALSE, &p_pdo[cnt] ); + status = IoCreateDevice( bus_globals.p_driver_obj, sizeof(bus_port_ext_t), + NULL, FILE_DEVICE_CONTROLLER, + FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME, + FALSE, &p_pdo[cnt] ); if( !NT_SUCCESS( status ) ) { BUS_TRACE_EXIT( BUS_DBG_ERROR, @@ -982,7 +1086,7 @@ cl_status_t _port_mgr_pkey_add ( IN pkey_array_t *pkeys, /* Initialize the device extension. */ cl_init_pnp_po_ext( p_pdo[cnt], NULL, p_pdo[cnt], bus_globals.dbg_lvl, - &vfptr_port_pnp, &vfptr_port_query_txt ); + &vfptr_port_pnp, &vfptr_port_query_txt ); /* Set the DO_BUS_ENUMERATED_DEVICE flag to mark it as a PDO. */ p_pdo[cnt]->Flags |= DO_BUS_ENUMERATED_DEVICE; @@ -994,19 +1098,17 @@ cl_status_t _port_mgr_pkey_add ( IN pkey_array_t *pkeys, pkey_port_ext->pdo.b_reported_missing = FALSE; pkey_port_ext->pdo.b_hibernating = FALSE; pkey_port_ext->pdo.p_po_work_item = NULL; - BUS_TRACE( BUS_DBG_PNP, - ("Created device for %s: PDO %p,ext %p, present %d, missing %d\n", - pkey_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[cnt], - pkey_port_ext, pkey_port_ext->pdo.b_present, + BUS_TRACE( BUS_DBG_PNP, ("Created device for %s: PDO %p,ext %p, present %d, missing %d .\n", + pkey_port_ext->pdo.cl_ext.vfptr_pnp_po->identity, p_pdo[cnt], pkey_port_ext, pkey_port_ext->pdo.b_present, 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]; + pkey_port_ext->pdo.is_partition_pdo = TRUE; /* Store the device extension in the port vector for future queries. */ cl_mutex_acquire( &gp_port_mgr->pdo_mutex ); cl_qlist_insert_tail( &gp_port_mgr->port_list, @@ -1016,13 +1118,12 @@ cl_status_t _port_mgr_pkey_add ( IN pkey_array_t *pkeys, /* 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 ); BUS_EXIT( BUS_DBG_PNP ); return CL_SUCCESS; } - cl_status_t port_mgr_pkey_add(pkey_array_t *pkeys) { bus_filter_t *p_bfi; @@ -1161,7 +1262,6 @@ port_start( /* Notify the Power Manager that the device is started. */ PoSetPowerState( p_dev_obj, DevicePowerState, p_ext->dev_po_state ); *p_action = IrpComplete; - BUS_EXIT( BUS_DBG_PNP ); return STATUS_SUCCESS; @@ -1402,6 +1502,7 @@ port_query_device_id( { WCHAR *p_string; bus_port_ext_t *p_ext; + size_t dev_id_size; BUS_ENTER( BUS_DBG_PNP ); @@ -1412,17 +1513,24 @@ port_query_device_id( 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_ where 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 ); @@ -1437,26 +1545,30 @@ port_query_hardware_ids( { 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_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 );