[IBBUS,HW] add standby/hibernation support to IBBUS. [mlnx: 4750]
[mirror/winof/.git] / tools / part_man / user / part_man.c
1 \r
2 #include "stdio.h"\r
3 #include "string.h"\r
4 #include "stdlib.h"\r
5 #include <windows.h>\r
6 #include <iba/ib_types.h>\r
7 #include <iba/ib_al.h>\r
8 #include "al_dev.h"\r
9 \r
10 #define IS_FULL_MEMBER_PKEY(pkey)       (0x8000 & (pkey))\r
11 \r
12 typedef enum\r
13 {\r
14         pkey_show = 0,\r
15         pkey_add,\r
16         pkey_rem\r
17 }Pkey_action;\r
18 \r
19 /* common query parameters */\r
20 typedef struct _REQUEST_IN\r
21 {\r
22         union\r
23         {\r
24                 struct\r
25                 {\r
26                         net64_t                    port_guid;\r
27                         unsigned short     pkey_num;\r
28                         unsigned __int16   pkeys[MAX_NUM_PKEY];\r
29                         Pkey_action                action;\r
30                 }guid_pkey;\r
31                 }u;\r
32 }REQUEST_IN;\r
33 \r
34 #define DEFAULT_BUFER_SIZE      1024\r
35 static const char IBBUS_SERV_KEY[] = {"SYSTEM\\CurrentControlSet\\Services\\ibbus\\Parameters"};\r
36 \r
37 void show_help()\r
38 {\r
39         printf("Usage : part_man.exe <show|add|rem> <port_guid> <pkey1 pkey2 ...>\n");\r
40 }\r
41 \r
42 /********************************************************************\r
43 * name  :       reg_ibbus_pkey_show\r
44 *                       read registry pkey and optionally prints it\r
45 * input :       show - whether to print\r
46 * output:       partKey - contains read pkeys, reg_handle\r
47 * return:   number of characters read\r
48 ********************************************************************/\r
49 static int reg_ibbus_pkey_show(IN BOOLEAN show,OUT char *partKey, OUT HKEY *reg_handle)\r
50 {\r
51         LONG   ret;\r
52         int retval;\r
53         DWORD  read_length = DEFAULT_BUFER_SIZE;\r
54         const char *sep_group = ";";\r
55         const char *sep_guid_pkey = ":,";\r
56         ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,IBBUS_SERV_KEY,0,KEY_SET_VALUE | KEY_QUERY_VALUE ,reg_handle);\r
57         if (ERROR_SUCCESS != ret)\r
58         {\r
59                 return 0;\r
60         }       \r
61 \r
62         do\r
63         {\r
64                 ret = RegQueryValueEx(*reg_handle,"PartitionKey",NULL,NULL,(LPBYTE)partKey,&read_length);\r
65                 if (ERROR_MORE_DATA == ret)\r
66                 {\r
67                         retval = 0;\r
68                         break;\r
69                 }\r
70 \r
71                 if (ERROR_SUCCESS != ret)\r
72                 {\r
73                         retval = 0;\r
74                         break;\r
75                 }\r
76                 retval = (int)read_length;\r
77                 if(retval > 4)\r
78                 {\r
79                         if(show)\r
80                         {\r
81                                 char *pkey_group, *pkey_group_next, *pkey_guid, tmp;\r
82                                 int i,j,k;\r
83                                 unsigned short *guid_vstat;\r
84                                 pkey_group = partKey;\r
85                                 while(pkey_group && (*pkey_group != '\0'))\r
86                                 {\r
87                                         pkey_group_next = strstr(pkey_group,sep_group);\r
88                                         if(pkey_group_next)\r
89                                                 *pkey_group_next = '\0';\r
90                                         pkey_guid = strtok(pkey_group,sep_guid_pkey);\r
91                                         i = 0;\r
92                                         while(pkey_guid)\r
93                                         {\r
94                                                 if(i == 0)\r
95                                                 {\r
96                                                         j = 1;\r
97                                                         for (k = strlen(pkey_guid) -1; k > 1; k--)\r
98                                                         {\r
99                                                                 if (j%2)\r
100                                                                 {\r
101                                                                         tmp = pkey_guid[k -1];\r
102                                                                         pkey_guid[k -1] = pkey_guid[k];\r
103                                                                         pkey_guid[k] = tmp;\r
104                                                                 }\r
105                                                                 printf("%c",pkey_guid[k]);\r
106                                                                 if ((j%4 == 0) && (k > 2))\r
107                                                                 {\r
108                                                                         printf(":");\r
109                                                                         j = 1;\r
110                                                                 }\r
111                                                                 else\r
112                                                                         j++;\r
113                                                         }\r
114                                                         printf("\t");\r
115                                                 }\r
116                                                 else\r
117                                                 {\r
118                                                         printf("%s\t",pkey_guid);\r
119                                                 }\r
120                                                 pkey_guid = strtok(NULL,sep_guid_pkey);\r
121                                                 if((++i)%5 == 0)\r
122                                                         printf("\n\t\t\t");\r
123                                         }\r
124                                         printf("\n\n");\r
125                                         if(pkey_group_next)\r
126                                                 pkey_group = pkey_group_next + 1;\r
127                                         else\r
128                                                 pkey_group = NULL;\r
129                                 }\r
130                         }\r
131                 }\r
132                 else\r
133                         retval = 0;\r
134         }\r
135         while(FALSE);\r
136         return retval;\r
137 }\r
138 \r
139 static int reg_ibbus_print_pkey()\r
140 {\r
141         int result;\r
142         char pkeyBuf[DEFAULT_BUFER_SIZE];\r
143         HKEY hreg = NULL;\r
144 \r
145         result = reg_ibbus_pkey_show(TRUE,(char*)pkeyBuf,&hreg);\r
146         if(hreg)\r
147                 RegCloseKey( hreg );\r
148 \r
149         if (result < 4)\r
150         {\r
151                 printf("No configured pkey found\n");\r
152                 return 1;\r
153         }\r
154         return 0;\r
155 }\r
156 \r
157 static int reg_ibbus_pkey_add(const uint16_t *pkeys, uint16_t pkey_num,OUT pkey_array_t *pkey, OUT char **final_reg_string, OUT DWORD *reg_length)\r
158 {\r
159         static char partKey[DEFAULT_BUFER_SIZE];\r
160         char tmp[20];\r
161         char *guid_string, *p;\r
162         HKEY reg_handle;\r
163         LONG   ret;\r
164         char *tmpbuff = NULL;\r
165         int cnt;\r
166         int retval = 0;\r
167         uint16_t i = 0;\r
168         DWORD  read_length;\r
169 \r
170         *final_reg_string = NULL;\r
171         read_length = reg_ibbus_pkey_show(FALSE,(char*)partKey,&reg_handle);\r
172         p = NULL;\r
173         guid_string = NULL;\r
174         if (read_length < 4)\r
175         {\r
176                 /* empty string read, simply write to registry */\r
177                 cnt = sprintf(partKey,"0x%I64X:",pkey->port_guid);\r
178         }\r
179         else\r
180         {\r
181                 /* update the existed registry list */\r
182                 sprintf(tmp,"0x%I64X",pkey->port_guid);\r
183                 guid_string = strstr(partKey,tmp);\r
184                 if(guid_string)\r
185                 {\r
186                         p = strstr(guid_string,";");\r
187                         tmpbuff = (char*)malloc(strlen(p) + 1);\r
188                         if(!tmpbuff)\r
189                         {\r
190                                 printf("Failed memory allocation\n");\r
191                                 return 1;\r
192                         }\r
193                         /* save the rest of the string */\r
194                         strcpy(tmpbuff,p);\r
195                         cnt = (int)(p - partKey);\r
196                 }\r
197                 else\r
198                 {\r
199                         sprintf(partKey + strlen(partKey),"%s:",tmp);\r
200                         cnt = strlen(partKey);\r
201                 }\r
202         }       \r
203 \r
204         for (i = 0 ;i < pkey_num; i++)\r
205         {\r
206                 char *same_pkey;\r
207                 sprintf(tmp,"0x%04X",pkeys[i]);\r
208                 if ( guid_string )\r
209                 {\r
210                         same_pkey = strstr(guid_string,tmp);\r
211                         if( same_pkey && (same_pkey < p) )\r
212                                 continue;\r
213                 }\r
214                 pkey->pkey_array[pkey->pkey_num] = pkeys[i];\r
215                 pkey->pkey_num++;\r
216                 if( (i == 0) && (!guid_string))\r
217                         cnt += sprintf(partKey + cnt,"0x%04X",pkeys[i]);\r
218                 else\r
219                         cnt += sprintf(partKey + cnt,",0x%04X",pkeys[i]);\r
220         }\r
221         if(tmpbuff)\r
222         {\r
223                 cnt += sprintf(partKey + cnt,"%s",tmpbuff);\r
224                 free(tmpbuff);\r
225         }\r
226         else\r
227                 cnt += sprintf(partKey + cnt,";\0");\r
228 \r
229         if(pkey->pkey_num)\r
230         {                       \r
231                         *final_reg_string = partKey;\r
232                         *reg_length = (DWORD)cnt;\r
233         }\r
234         else\r
235         {\r
236                 printf("Required pkeys already exist\n");\r
237                 retval = 1;\r
238         }\r
239         RegCloseKey( reg_handle );\r
240         return retval;\r
241 }\r
242 \r
243 static int reg_ibbus_pkey_rem(const unsigned __int16 *pkeys, unsigned short pkey_num,OUT pkey_array_t *pkey)\r
244 {\r
245         static char partKey[DEFAULT_BUFER_SIZE];\r
246         static char newKey[DEFAULT_BUFER_SIZE] = {'\0'};\r
247 \r
248         HKEY reg_handle;\r
249         LONG   ret;\r
250         DWORD  read_length;\r
251         int converted,cnt;\r
252         unsigned __int16 cur_pkey;\r
253         int retval = 0;\r
254         unsigned short i = 0;\r
255         char pkey_sep[] = ",";\r
256         char *pfrom, *pto;\r
257         char *guid_string;\r
258         char tmp[20];\r
259         char *token;\r
260         char *pafter = NULL;\r
261         boolean_t found2remove;\r
262         boolean_t pkey_not_written = TRUE;\r
263 \r
264         read_length = reg_ibbus_pkey_show(FALSE,(char*)partKey,&reg_handle);\r
265         do\r
266         {\r
267                 if (read_length < 4)\r
268                 {\r
269                         /* empty string read, nothing to delete */\r
270                         printf("No pkey configured - nothing to remove\n");\r
271                         retval = 1;\r
272                         break;\r
273                 }\r
274 \r
275                 sprintf(tmp,"0x%I64X\0",pkey->port_guid);\r
276                 guid_string = strstr(partKey,tmp);\r
277                 if (! guid_string)\r
278                 {\r
279                         printf("No guid configured - nothing to remove\n");\r
280                         retval = 1;\r
281                         break;\r
282                 }\r
283                 pfrom = strstr(guid_string,":");\r
284                 pto   = strstr(guid_string,";");\r
285                 if ( (!pfrom) || (!pto))\r
286                 {\r
287                         printf("Error configuration\n");\r
288                         retval = 1;\r
289                         break;\r
290                 }\r
291 \r
292                 pfrom++;\r
293                 pafter  = (char*)malloc(strlen(pto) + 1);\r
294 \r
295                 if(!pafter)\r
296                 {\r
297                         printf("Allocation failed\n");\r
298                         retval = 1;\r
299                         break;\r
300                 }\r
301                 _snprintf(newKey,(int)(pfrom - partKey),"%s",partKey);\r
302                 cnt = (int)(pfrom - partKey);\r
303                 strcpy(pafter,pto);\r
304                 pto[0] = '\0';\r
305                 strcpy(partKey,pfrom);\r
306                 token = strtok(partKey,pkey_sep);\r
307                 while(token)\r
308                 {\r
309                         found2remove = FALSE;\r
310                         converted = sscanf(token,"0x%X",&cur_pkey);\r
311                         if(!converted || (converted == EOF))\r
312                         {\r
313                                 printf("invalid registry format\n");\r
314                                 retval = 1;\r
315                                 break;\r
316                         }\r
317 \r
318                         for (i = 0; i < pkey_num; i++)\r
319                         {\r
320                                 found2remove = (boolean_t)(cur_pkey == pkeys[i]);\r
321                                 if(found2remove)\r
322                                 {\r
323                                         pkey->pkey_array[pkey->pkey_num] = pkeys[i];\r
324                                         break;\r
325                                 }\r
326                         }\r
327                         \r
328                         if(found2remove)\r
329                         {\r
330                                 pkey->pkey_num++;\r
331                         }\r
332                         else\r
333                         {\r
334                                 if(pkey_not_written)\r
335                                 {\r
336                                         cnt += sprintf(newKey + cnt,"0x%04X",cur_pkey);\r
337                                         pkey_not_written = FALSE;\r
338                                 }\r
339                                 else\r
340                                         cnt += sprintf(newKey + cnt,",0x%04X",cur_pkey);\r
341                         }\r
342                         token = strtok(NULL,pkey_sep);\r
343                 }\r
344 \r
345                 if(! pkey->pkey_num)\r
346                 {\r
347                         /* nothing to delete */\r
348                         printf("Nothing to remove\n");\r
349                         retval = 1;\r
350                         break;\r
351                 }\r
352 \r
353                 if(pkey_not_written)\r
354                         cnt -= (2 + strlen(tmp));\r
355                 \r
356                 strcpy(newKey + cnt,pafter);\r
357                 ret = RegSetValueEx(reg_handle,"PartitionKey",0,REG_SZ,(BYTE*)newKey, (DWORD)strlen(newKey));\r
358                 if (ERROR_SUCCESS != ret)\r
359                 {\r
360                         printf("registry operation failed error = %d\n",GetLastError());\r
361                         retval = 1;\r
362                         break;\r
363                 }\r
364         }\r
365         while(FALSE);\r
366         if(pafter)\r
367                 free(pafter);\r
368 \r
369         RegCloseKey( reg_handle );\r
370         return retval;\r
371 }\r
372 \r
373 static int send_pdo_req(pkey_array_t *pkeys,DWORD iocode)\r
374 {\r
375         HANDLE hKernelLib;\r
376         DWORD           bytesReturned;\r
377 \r
378         hKernelLib =\r
379                 CreateFile(\r
380                 "\\\\.\\ibal",\r
381                 GENERIC_READ | GENERIC_WRITE,\r
382                 FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode none\r
383                 NULL,                               // no security\r
384                 OPEN_EXISTING,\r
385                 FILE_ATTRIBUTE_NORMAL,\r
386                 NULL                                // no template\r
387                 );\r
388 \r
389         if (hKernelLib == INVALID_HANDLE_VALUE)\r
390         {\r
391                 printf("failed to open the kernel device : error = %d\n",GetLastError());\r
392                 return 1;\r
393         }\r
394 \r
395         if (! DeviceIoControl(hKernelLib,\r
396                                                   iocode,\r
397                                                   pkeys,sizeof(pkey_array_t),\r
398                                                   NULL,0,\r
399                                                   &bytesReturned,\r
400                                                   NULL))\r
401         {\r
402                 DWORD err = GetLastError();\r
403                 if (err == 1168)\r
404                         printf("No matched port guid (0x%I64X) found\n",pkeys->port_guid);\r
405                 else if (err == 1117)\r
406                         printf("operation failed - internal driver error\n");\r
407                 else if(err == 87)\r
408                         printf("operation failed - invalid input to driver\n");\r
409                 else\r
410                         printf("operation failed with error %d\n",err);\r
411 \r
412                 CloseHandle(hKernelLib);\r
413                 return 1;\r
414         }\r
415         CloseHandle(hKernelLib);\r
416         return 0;\r
417 }\r
418 \r
419 \r
420 boolean_t reg_pkey_operation(const REQUEST_IN *input)\r
421 {\r
422         pkey_array_t pkeys;\r
423         HKEY reg_handle;\r
424         char *p_reg_string;\r
425         DWORD reg_length = 0;\r
426         int result;\r
427         int i;\r
428         LONG   ret;\r
429         if(!input)\r
430         {\r
431                 printf("invalid input parameter\n");\r
432                 return FALSE;\r
433         }\r
434 \r
435         RtlZeroMemory(&pkeys,sizeof(pkeys));\r
436         pkeys.port_guid = input->u.guid_pkey.port_guid;\r
437 \r
438         if(input->u.guid_pkey.action == pkey_add)\r
439                 result = reg_ibbus_pkey_add((unsigned __int16*)input->u.guid_pkey.pkeys, input->u.guid_pkey.pkey_num, &pkeys,&p_reg_string,&reg_length);\r
440         else if(input->u.guid_pkey.action == pkey_rem)\r
441                 result = reg_ibbus_pkey_rem((unsigned __int16*)input->u.guid_pkey.pkeys, input->u.guid_pkey.pkey_num, &pkeys);\r
442         else if(input->u.guid_pkey.action == pkey_show)\r
443         {       \r
444                 reg_ibbus_print_pkey();\r
445                 return TRUE;\r
446         }\r
447         else\r
448                 printf("Invalid command to part_man.exe\n");\r
449 \r
450         if( 0 != result)\r
451                 return FALSE;\r
452 \r
453         if(pkeys.pkey_num)\r
454         {\r
455                 if(input->u.guid_pkey.action == pkey_add)\r
456                 {\r
457                         if( 0 == send_pdo_req(&pkeys,UAL_REQ_CREATE_PDO))\r
458                         {\r
459                                 ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,IBBUS_SERV_KEY,0,KEY_SET_VALUE | KEY_QUERY_VALUE ,&reg_handle);\r
460                                 ret = RegSetValueEx(reg_handle,"PartitionKey",0,REG_SZ,(BYTE*)p_reg_string,reg_length);\r
461                                 RegCloseKey( reg_handle );\r
462                                 if (ERROR_SUCCESS == ret)\r
463                                 {\r
464                                         return TRUE;\r
465                                 }\r
466                                 else\r
467                                 {\r
468                                         printf("registry operation failed = %d\n",GetLastError());\r
469                                 }\r
470                         }\r
471                 }\r
472                 else if(input->u.guid_pkey.action == pkey_rem)\r
473                 {\r
474                         return (boolean_t)( 0 == send_pdo_req(&pkeys,UAL_REQ_REMOVE_PDO));\r
475                 }\r
476         }\r
477         return FALSE;\r
478 }\r
479 \r
480 int prepare_reg_pkey_input(OUT REQUEST_IN *input,char* cmd[],int num)\r
481 {\r
482         int i;\r
483         input->u.guid_pkey.pkey_num = 0;\r
484 \r
485         if(strstr(cmd[1],"add"))\r
486                 input->u.guid_pkey.action = pkey_add;\r
487         else if(strstr(cmd[1],"rem"))\r
488                 input->u.guid_pkey.action = pkey_rem;\r
489         else if(strstr(cmd[1],"show"))\r
490         {\r
491                 input->u.guid_pkey.action = pkey_show;\r
492                 return 1;\r
493         }\r
494         else\r
495         {\r
496                 printf("invalid command %s\n",cmd[1]);\r
497                 return 0;\r
498         }\r
499 \r
500         if(num < 4)\r
501         {\r
502                 printf("invalid command %s\n",cmd[1]);\r
503                 return 0;\r
504         }\r
505 \r
506     /* vstat output format 0008:f104:0397:7ccc \r
507            For port guid add 1 for each port \r
508          */\r
509         if (strstr(cmd[2],":"))\r
510         {\r
511                 int i;\r
512                 unsigned short *guid_vstat;\r
513                 guid_vstat = (unsigned short*)&input->u.guid_pkey.port_guid;\r
514                 if (4 == sscanf(cmd[2],"%x:%x:%x:%x",&guid_vstat[0],&guid_vstat[1],&guid_vstat[2],&guid_vstat[3]))\r
515                 {\r
516                         for( i = 0; i < 4; i++)\r
517                                 guid_vstat[i] = (guid_vstat[i] << 8) | (guid_vstat[i] >> 8);\r
518                 }\r
519                 else\r
520                 {\r
521                         goto bad_inp;\r
522                 }\r
523         }\r
524         else\r
525         {\r
526                 goto bad_inp;\r
527         }\r
528 \r
529         for( i = 3; i < num; i++)\r
530         {\r
531                 if((strstr(cmd[i],"ffff")) || (strstr(cmd[i],"FFFF")))\r
532                         continue;\r
533                 if (strstr(cmd[i],"0x") || strstr(cmd[i],"0X"))\r
534                         sscanf(cmd[i],"0x%x",&input->u.guid_pkey.pkeys[input->u.guid_pkey.pkey_num]);\r
535                 else\r
536                         sscanf(cmd[i],"%x",&input->u.guid_pkey.pkeys[input->u.guid_pkey.pkey_num]);\r
537 \r
538                 if (! IS_FULL_MEMBER_PKEY(input->u.guid_pkey.pkeys[input->u.guid_pkey.pkey_num]))\r
539             {\r
540                         printf("partial member pkey %s is not suported\n",cmd[i]);\r
541                         return 0;\r
542                 }\r
543                 input->u.guid_pkey.pkey_num++;\r
544         }\r
545         return 1;\r
546 bad_inp:\r
547         printf("port guid %s - illegal port guid format, expected xxxx:xxxx:xxxx:xxxx\n",cmd[2]);\r
548         return 0;       \r
549 }\r
550 \r
551 void partition_operation(char* cmd[],int num)\r
552 {\r
553         REQUEST_IN input;\r
554 \r
555         if (! prepare_reg_pkey_input(&input, cmd, num))\r
556                 return;\r
557 \r
558         if(! reg_pkey_operation(&input))\r
559                 printf("Pkey operation failed\n");      \r
560         else\r
561                 printf("Done...\n");\r
562 }\r
563 \r
564 int32_t __cdecl\r
565 main(\r
566         int32_t argc,\r
567         char* argv[])\r
568 {\r
569         BOOLEAN showHelp = FALSE;\r
570         if (argc < 2)\r
571         {\r
572                 showHelp = TRUE;\r
573         }\r
574         else\r
575         {\r
576                 if(!_stricmp(argv[1], "-h") || !_stricmp(argv[1], "-help"))\r
577                 {\r
578                         showHelp = TRUE;\r
579                 }\r
580                 else\r
581                         partition_operation(argv,argc);\r
582         }\r
583         if (showHelp)\r
584                 show_help();\r
585 }\r
586 \r
587 \r