6 #include <complib/cl_byteswap.h>
\r
7 #include <complib/cl_memory.h>
\r
9 #define MAX_DEVICE_ID_LEN 200
\r
10 #define MAX_DEVICE_STRING_LEN MAX_DEVICE_ID_LEN + 2 /* add extra 4 bytes in case we need double NULL ending */
\r
12 #pragma pack(push, 1)
\r
13 typedef struct _ca_ioc_info {
\r
16 ib_svc_entry_t svc_entry_array[1];
\r
19 typedef struct _child_device_info {
\r
20 wchar_t device_id[MAX_DEVICE_STRING_LEN];
\r
21 uint32_t device_id_size;
\r
22 wchar_t compatible_id[MAX_DEVICE_STRING_LEN];
\r
23 uint32_t compatible_id_size;
\r
24 wchar_t hardware_id[MAX_DEVICE_STRING_LEN];
\r
25 uint32_t hardware_id_size;
\r
26 wchar_t description[MAX_DEVICE_STRING_LEN];
\r
27 uint32_t description_size;
\r
28 ca_ioc_info_t ca_ioc_path;
\r
29 uint32_t uniqueinstanceid;
\r
30 } child_device_info_t;
\r
36 printf( "Correct usage to create VNIC child devices is:-\n" );
\r
37 printf( "qlgcvnic_config -c <CAGUID> <IOCGUID> "
\r
38 "<InstanceID> <Interface Description>\n" );
\r
39 printf( "Executing qlgcvnic_config without any option or with -l "
\r
40 "option will list the IOCs reachable from the host\n" );
\r
44 DWORD send_device_ioctl( DWORD ioctlcode, PVOID input_buf, DWORD in_size, PVOID *output_buf, PDWORD out_size )
\r
46 DWORD dwRet = 0, dwMemSize, dwBytesRet = 0;
\r
49 HANDLE hDevice = INVALID_HANDLE_VALUE;
\r
51 hDevice = CreateFileW ( L"\\\\.\\VNICCONFIG",
\r
52 GENERIC_READ | GENERIC_WRITE,
\r
53 FILE_SHARE_READ | FILE_SHARE_WRITE, /* share mode none */
\r
54 NULL, /* no security */
\r
56 FILE_ATTRIBUTE_NORMAL,
\r
57 NULL ); /* no template; */
\r
59 if ( hDevice == INVALID_HANDLE_VALUE )
\r
61 printf( "Error opening VNICCONFIG device file\n" );
\r
62 return ERROR_FILE_NOT_FOUND;
\r
65 switch( ioctlcode )
\r
67 case UAL_IOC_DEVICE_CREATE:
\r
68 bRet = DeviceIoControl( hDevice, ioctlcode, input_buf, in_size, NULL, 0, &dwBytesRet, NULL );
\r
72 dwRet = GetLastError();
\r
73 printf( "GetLastError after UAL_IOC_DEVICE_CREATE gives %d\n", dwRet );
\r
78 dwMemSize = sizeof(ca_ioc_info_t ) * 2;
\r
90 pBuf = cl_malloc( dwMemSize );
\r
94 printf( "Insufficient memory\n" );
\r
95 dwRet = ERROR_NOT_ENOUGH_MEMORY;
\r
99 bRet = DeviceIoControl( hDevice, ioctlcode, NULL, 0, pBuf, dwMemSize, &dwBytesRet, NULL );
\r
100 dwRet = GetLastError();
\r
108 }while( dwRet == ERROR_INSUFFICIENT_BUFFER );
\r
110 *output_buf = pBuf;
\r
111 *out_size = dwBytesRet;
\r
116 CloseHandle( hDevice );
\r
120 ca_ioc_info_t *find_ca_ioc_path ( ca_ioc_info_t *pList, DWORD nListSize,
\r
121 uint64_t ca_guid, uint64_t ioc_guid )
\r
123 while ( nListSize )
\r
126 if ( pList->ca_guid == ca_guid && pList->info.profile.ioc_guid == ioc_guid )
\r
137 #define IBIOU_SERVICE_PARAM_KEY "SYSTEM\\CurrentControlSet\\Services\\ibiou"
\r
138 #define IBIOU_PARAM_KEY_DEVICE_VALUE "StaticChild"
\r
139 #define IBIOU_PARAMETER_NAME "Parameters"
\r
140 #define MAX_VALUE_LENGTH 2048
\r
142 DWORD write_device_name( char *device_name )
\r
145 DWORD dwRet = 0, dwBytesRet = 0, n_size = 100, dwType;
\r
146 HKEY hKey = INVALID_HANDLE_VALUE;
\r
148 PVOID pOldValue, pNewValue, pBuf;
\r
149 char szKeyName[200];
\r
151 sprintf( szKeyName, "%s\\%s", IBIOU_SERVICE_PARAM_KEY, IBIOU_PARAMETER_NAME );
\r
152 lRet = RegOpenKeyExA( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
\r
156 if ( lRet != ERROR_SUCCESS )
\r
158 printf( "Opening services key of ibiou failed\n" );
\r
165 pOldValue = cl_malloc( n_size );
\r
169 printf( "Not enough memory on system\n" );
\r
172 dwType = REG_MULTI_SZ;
\r
174 lRet = RegQueryValueExA( hKey, IBIOU_PARAM_KEY_DEVICE_VALUE, 0, &dwType, pOldValue, &dwBytesRet );
\r
177 if ( lRet == ERROR_MORE_DATA )
\r
179 cl_free( pOldValue );
\r
184 } while( lRet == ERROR_MORE_DATA && n_size < MAX_VALUE_LENGTH );
\r
186 if ( lRet != ERROR_SUCCESS )
\r
188 cl_free( pOldValue );
\r
193 n_size = dwBytesRet + strlen( device_name )*sizeof( char ) + 2*sizeof( char ); /* more for NULLs */
\r
194 pNewValue = cl_malloc( n_size );
\r
196 cl_memset( pNewValue, 0x00, n_size );
\r
199 printf( "Not enough memory on system\n" );
\r
204 { /* Come here only when "StaticChild" key was there already*/
\r
205 cl_memcpy( pBuf, pOldValue, dwBytesRet );
\r
207 while ( *( ( PBYTE )pBuf ) != 0 || *( ( PBYTE ) pBuf + 1 ) != 0 )
\r
208 pBuf = ( PBYTE ) pBuf + 1;
\r
210 pBuf = ( PBYTE ) pBuf + 1;
\r
211 cl_free( pOldValue );
\r
215 cl_memcpy( pBuf, device_name, strlen( device_name ) );
\r
216 lRet = RegSetValueExA( hKey, IBIOU_PARAM_KEY_DEVICE_VALUE, 0, REG_MULTI_SZ,
\r
217 pNewValue, ( strlen( device_name ) + dwBytesRet + 2 ) ); /* Two bytes for extra NULLs*/
\r
218 cl_free( pNewValue );
\r
219 RegCloseKey( hKey );
\r
220 if ( lRet != ERROR_SUCCESS )
\r
222 printf( "Error setting device name in value of services key of ibiou\n" );
\r
231 static const char *value_names[] = {
\r
233 #define CAGUID_INDEX 0
\r
235 #define IOCGUID_INDEX 1
\r
237 #define COMPATIBLEID_INDEX 2
\r
239 #define DESCRIPTION_INDEX 3
\r
241 #define DEVICEID_INDEX 4
\r
243 #define HARDWAREID_INDEX 5
\r
245 #define INSTANCEID_INDEX 6
\r
246 #define MAXVALUE_INDEX 7
\r
249 DWORD write_deviceinfo_to_registry( uint64_t ca_guid, uint64_t ioc_guid,
\r
250 uint32_t instance_id, char *device_name )
\r
252 DWORD dwRet = 0, dwDisposition, dwType, dwSize;
\r
253 HKEY hKey = INVALID_HANDLE_VALUE;
\r
254 char szKeyName[250];
\r
259 dwRet = write_device_name( device_name );
\r
263 sprintf( szKeyName, "%s\\%s\\%s",
\r
264 IBIOU_SERVICE_PARAM_KEY, IBIOU_PARAMETER_NAME, device_name );
\r
265 lRet = RegCreateKeyExA( HKEY_LOCAL_MACHINE, szKeyName, 0,
\r
266 NULL, REG_OPTION_NON_VOLATILE,
\r
267 KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition );
\r
269 if ( dwDisposition == REG_CREATED_NEW_KEY )
\r
271 dwIndex = CAGUID_INDEX;
\r
273 while ( dwIndex < MAXVALUE_INDEX )
\r
280 dwType = REG_BINARY;
\r
281 dwSize = sizeof( uint64_t );
\r
284 case IOCGUID_INDEX:
\r
286 dwType = REG_BINARY;
\r
287 dwSize = sizeof( uint64_t );
\r
290 case DEVICEID_INDEX:
\r
291 pBuf = "IBA\\qlgcvnic";
\r
293 dwSize = strlen( pBuf ) + 1;
\r
296 case COMPATIBLEID_INDEX: /* Currently all id's used are same. */
\r
297 case HARDWAREID_INDEX:
\r
298 pBuf = "IBA\\qlgcvnic";
\r
299 dwType = REG_MULTI_SZ;
\r
300 dwSize = strlen( pBuf ) + 1;
\r
303 case DESCRIPTION_INDEX:
\r
304 pBuf = device_name;
\r
306 dwSize = strlen( pBuf ) + 1;
\r
309 case INSTANCEID_INDEX:
\r
310 pBuf = &instance_id;
\r
311 dwType = REG_DWORD;
\r
312 dwSize = sizeof( instance_id );
\r
318 lRet = RegSetValueExA( hKey, value_names[dwIndex], 0,
\r
319 dwType, pBuf, dwSize );
\r
321 if ( lRet != ERROR_SUCCESS )
\r
323 printf( "Failed in setting device information as Parameters of ibiou driver\n" );
\r
332 if ( hKey != INVALID_HANDLE_VALUE )
\r
334 RegCloseKey( hKey );
\r
341 DWORD create_child_device( uint64_t ca_guid, uint64_t ioc_guid, uint32_t instance_id, char *device_name )
\r
343 ca_ioc_info_t *pList = NULL, *p_ca_ioc_entry = NULL;
\r
344 DWORD dwRet = 0, dwBytesRet;
\r
345 child_device_info_t *child_dev = NULL;
\r
346 WCHAR szDevName[200];
\r
349 dwRet = send_device_ioctl( UAL_IOC_LIST, NULL, 0, &pList, &dwBytesRet );
\r
353 printf( "Obtaining IOC LIST from ibiou failed\n" );
\r
357 p_ca_ioc_entry = find_ca_ioc_path( pList, dwBytesRet/sizeof( ca_ioc_info_t ),
\r
358 ca_guid, ioc_guid );
\r
360 if ( p_ca_ioc_entry )
\r
362 child_dev = cl_malloc( sizeof( child_device_info_t ) );
\r
363 cl_memset( child_dev, 0x00, sizeof( child_device_info_t ) );
\r
367 printf( "Allocating memory for child device failed\n" );
\r
371 child_dev->ca_ioc_path = *p_ca_ioc_entry;
\r
372 wcscpy( child_dev->device_id, L"IBA\\qlgcvnic" );
\r
373 child_dev->device_id_size = ( wcslen( child_dev->device_id ) + 1 )*sizeof( WCHAR );
\r
374 wcscpy( child_dev->hardware_id, L"IBA\\qlgcvnic" );
\r
375 child_dev->hardware_id_size = ( wcslen( child_dev->hardware_id ) + 2 )*sizeof( WCHAR );
\r
376 wcscpy( child_dev->compatible_id, L"IBA\\qlgcvnic" );
\r
377 child_dev->compatible_id_size = ( wcslen( child_dev->compatible_id ) + 2 )*sizeof( WCHAR );
\r
378 swprintf( szDevName, L"%S", device_name );
\r
379 wcscpy( child_dev->description, szDevName );
\r
380 child_dev->description_size = ( wcslen( child_dev->description ) + 1 )*sizeof( WCHAR );
\r
381 child_dev->uniqueinstanceid = instance_id;
\r
383 dwRet = send_device_ioctl( UAL_IOC_DEVICE_CREATE, child_dev, sizeof( *child_dev ), NULL, NULL );
\r
387 printf( "Child device creation for CA = %I64X and IOC = %I64X was successful\n",
\r
388 cl_ntoh64( ca_guid ), cl_ntoh64( ioc_guid ) );
\r
389 dwRet = write_deviceinfo_to_registry( ca_guid, ioc_guid, instance_id, device_name );
\r
396 printf( "No path CA=%I64X to IOC=%I64X found\n",
\r
397 cl_ntoh64( ca_guid ), cl_ntoh64( ioc_guid ) );
\r
403 printf( "Child device creation for CA = %I64X and IOC = %I64X failed\n",
\r
404 cl_ntoh64( ca_guid ), cl_ntoh64( ioc_guid ) );
\r
416 DWORD list_ca_ioc_paths()
\r
418 DWORD dwBytesRet = 0, dwRet, n_ca_ioc_path = 0;
\r
419 ca_ioc_info_t *pList = NULL;
\r
422 dwRet = send_device_ioctl( UAL_IOC_LIST, NULL, 0, &pList, &dwBytesRet );
\r
426 printf( "Obtaining IOC list from ibiou failed\n" );
\r
428 else if ( dwBytesRet )
\r
431 n_ca_ioc_path = dwBytesRet/sizeof( ca_ioc_info_t );
\r
433 while ( n_ca_ioc_path )
\r
435 printf( "Channel Adapter %I64X reaches to IOC %I64X\n",
\r
436 cl_ntoh64( pList->ca_guid ), cl_ntoh64( pList->info.profile.ioc_guid ) );
\r
437 pList++; n_ca_ioc_path--;
\r
442 printf( "No IOCs are reachable from the host\nPlease check the connections of host\n" );
\r
453 int _cdecl main ( int argc, char *argv[] )
\r
455 char device_name[200];
\r
457 BOOLEAN b_list_ioc_paths = FALSE;
\r
458 BOOLEAN b_create_device = FALSE;
\r
459 uint64_t ca_guid, ioc_guid;
\r
460 uint32_t unique_id;
\r
463 while ( i < argc )
\r
465 if ( !strcmp( argv[i], "-l" ) )
\r
467 b_list_ioc_paths = TRUE;
\r
469 else if ( !strcmp( argv[i], "-c" ) )
\r
471 b_create_device = TRUE;
\r
475 ca_guid = _strtoui64( argv[i], NULL, 16 );
\r
483 ioc_guid = _strtoui64( argv[i], NULL, 16 );
\r
491 unique_id = strtoul( argv[i], NULL, 10 );
\r
499 strcpy( device_name, argv[i] );
\r
514 if ( b_list_ioc_paths && b_create_device )
\r
519 else if ( b_create_device )
\r
521 ret = create_child_device( cl_hton64( ca_guid ), cl_hton64( ioc_guid ), unique_id, device_name );
\r
525 ret = list_ca_ioc_paths();
\r