[MLX4] 1) added support for sending large multi-parameter messages to System Event...
[mirror/winof/.git] / hw / mlx4 / kernel / bus / core / l2w_debug.c
1 #include "l2w.h"
2 #include "ev_log.h"
3
4 #define MAX_BUFFER_SIZE         256
5
6 /* 
7  * This function sends to Event Log messages with one WCHAR string and several binary parameters.
8  * The string will be inserted instead of %2 parameter of the message.
9  * Binary parameters will be shown in Dump Area of the message.
10  * Binary parameters should be of type LONG.
11  */
12 VOID
13 WriteEventLogEntryStr(
14         PVOID   pi_pIoObject,
15         ULONG   pi_ErrorCode,
16         ULONG   pi_UniqueErrorCode,
17         ULONG   pi_FinalStatus,
18         PWCHAR  pi_InsertionStr,
19         ULONG   pi_nDataItems,
20         ...
21         )
22 /*++
23
24 Routine Description:
25     Writes an event log entry to the event log.
26
27 Arguments:
28
29         pi_pIoObject......... The IO object ( driver object or device object ).
30         pi_ErrorCode......... The error code.
31         pi_UniqueErrorCode... A specific error code.
32         pi_FinalStatus....... The final status.
33         pi_nDataItems........ Number of data items.
34         .
35         . data items values
36         .
37
38 Return Value:
39
40         None .
41
42 --*/
43 { /* WriteEventLogEntryStr */
44
45         /* Variable argument list */    
46         va_list                                 l_Argptr;
47         /* Pointer to an error log entry */
48         PIO_ERROR_LOG_PACKET    l_pErrorLogEntry; 
49         /* sizeof insertion string */
50         int     l_Size = (int)((pi_InsertionStr) ? ((wcslen(pi_InsertionStr) + 1) * sizeof( WCHAR )) : 0);
51         int l_PktSize =sizeof(IO_ERROR_LOG_PACKET)+pi_nDataItems*sizeof(ULONG);
52         int l_TotalSize =l_PktSize +l_Size;
53
54         if (pi_pIoObject == NULL) {
55                 ASSERT(pi_pIoObject != NULL);
56                 return;
57         }
58
59         /* Init the variable argument list */   
60         va_start(l_Argptr, pi_nDataItems);
61
62         /* Allocate an error log entry */ 
63         if (l_TotalSize >= ERROR_LOG_MAXIMUM_SIZE - 2) 
64                 l_TotalSize = ERROR_LOG_MAXIMUM_SIZE - 2;
65         l_pErrorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(
66                 pi_pIoObject,  (UCHAR)l_TotalSize );
67
68         /* Check allocation */
69         if ( l_pErrorLogEntry != NULL) 
70         { /* OK */
71
72                 /* Data item index */
73                 USHORT l_nDataItem ;
74
75                 /* Set the error log entry header */
76                 l_pErrorLogEntry->ErrorCode                     = pi_ErrorCode; 
77                 l_pErrorLogEntry->DumpDataSize          = (USHORT) (pi_nDataItems*sizeof(ULONG)); 
78                 l_pErrorLogEntry->SequenceNumber        = 0; 
79                 l_pErrorLogEntry->MajorFunctionCode = 0; 
80                 l_pErrorLogEntry->IoControlCode         = 0; 
81                 l_pErrorLogEntry->RetryCount            = 0; 
82                 l_pErrorLogEntry->UniqueErrorValue      = pi_UniqueErrorCode; 
83                 l_pErrorLogEntry->FinalStatus           = pi_FinalStatus; 
84
85                 /* Insert the data items */
86                 for (l_nDataItem = 0; l_nDataItem < pi_nDataItems; l_nDataItem++) 
87                 { /* Inset a data item */
88
89                         /* Current data item */
90                         int l_CurDataItem ;
91                                 
92                         /* Get next data item */
93                         l_CurDataItem = va_arg( l_Argptr, int);
94
95                         /* Put it into the data array */
96                         l_pErrorLogEntry->DumpData[l_nDataItem] = l_CurDataItem ;
97
98                 } /* Inset a data item */
99
100                 /* add insertion string */
101                 if (pi_InsertionStr) {
102                         char *ptr; 
103                         int sz = min( l_TotalSize - l_PktSize, l_Size );
104                         l_pErrorLogEntry->NumberOfStrings = 1;
105                         l_pErrorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET) + l_pErrorLogEntry->DumpDataSize;
106                         ptr = (char*)l_pErrorLogEntry + l_pErrorLogEntry->StringOffset;
107                         memcpy( ptr, pi_InsertionStr, sz );
108                         *(WCHAR*)&ptr[sz - 2] = (WCHAR)0;
109                 }
110                 
111                 /* Write the packet */
112                 IoWriteErrorLogEntry(l_pErrorLogEntry);
113
114         } /* OK */
115
116         /* Term the variable argument list */   
117         va_end(l_Argptr);
118
119 } /* WriteEventLogEntry */
120
121 /* 
122  * This function sends to Event Log messages with various parameters.
123  * Every parameter should be coded as a pair: a format specifier and the value.
124  * 'pi_nDataItems' presents the number of the pairs.
125  *
126  * Here is an example:
127  *
128  * To print a message (from MC file) like:
129  *
130  *              MessageId=0x0006 Facility=MLX4 Severity=Informational SymbolicName=EVENT_MLX4_INFO_TEST
131  *              Language=English
132  *              some_long %2, some_short %3, some_byte %4, some_wide_char_str %5, some_ansii_str %6
133  *
134  * you have to code:
135  *
136  *              WriteEventLogEntryData( pdev->p_self_do, (ULONG)EVENT_MLX4_INFO_TEST, 0, 0, 5,
137  *                      L"%d", long_int,                                                        // LONG
138  *                      L"%04x", (ULONG)short_int,                                      // SHORT
139  *                      L"%02x", (ULONG)byte_int,                                       // CHAR
140  *                      L"%s", wide_char_str,                                           // PWCHAR
141  *                      L"%S", ansii_str                                                        // PCHAR
142  *              );
143  */
144 VOID
145 WriteEventLogEntryData(
146         PVOID   pi_pIoObject,
147         ULONG   pi_ErrorCode,
148         ULONG   pi_UniqueErrorCode,
149         ULONG   pi_FinalStatus,
150         ULONG   pi_nDataItems,
151         ...
152         )
153 /*++
154
155 Routine Description:
156     Writes an event log entry to the event log.
157
158 Arguments:
159
160         pi_pIoObject......... The IO object ( driver object or device object ).
161         pi_ErrorCode......... The error code.
162         pi_UniqueErrorCode... A specific error code.
163         pi_FinalStatus....... The final status.
164         pi_nDataItems........ Number of data items (i.e. pairs of data parameters).
165         .
166         . data items values
167         .
168
169 Return Value:
170
171         None .
172
173 --*/
174 { /* WriteEventLogEntryData */
175
176         /* Variable argument list */    
177         va_list                                 l_Argptr;
178         /* Pointer to an error log entry */
179         PIO_ERROR_LOG_PACKET    l_pErrorLogEntry; 
180         /* sizeof insertion string */
181         int     l_Size = 0;     
182         /* temp buffer */
183         UCHAR l_Buf[ERROR_LOG_MAXIMUM_SIZE - 2];
184         /* position in buffer */
185         UCHAR * l_Ptr = l_Buf;
186         /* Data item index */
187         USHORT l_nDataItem ;
188         /* total packet size */
189         int l_TotalSize;
190
191         if (pi_pIoObject == NULL) {
192                 ASSERT(pi_pIoObject != NULL);
193                 return;
194         }
195
196         /* Init the variable argument list */   
197         va_start(l_Argptr, pi_nDataItems);
198
199         /* Create the insertion strings Insert the data items */
200         memset( l_Buf, 0, sizeof(l_Buf) );
201         for (l_nDataItem = 0; l_nDataItem < pi_nDataItems; l_nDataItem++) 
202         { 
203                 NTSTATUS status;
204                 /* Current binary data item */
205                 int l_CurDataItem ;
206                 /* Current pointer data item */
207                 void* l_CurPtrDataItem ;
208                 /* format specifier */
209                 WCHAR* l_FormatStr;
210                 /* the rest of the buffer */
211                 int l_BufSize = (int)(l_Buf + sizeof(l_Buf)- l_Ptr);
212                 /* size of insertion string */
213                 size_t l_StrSize;
214
215                 /* print as much as we can */
216                 if ( l_BufSize < 4 )
217                         break;
218                 
219                 /* Get format specifier */
220                 l_FormatStr = va_arg( l_Argptr, PWCHAR);
221         
222                 /* Get next data item */
223                 if ( !wcscmp( l_FormatStr, L"%s" ) || !wcscmp( l_FormatStr, L"%S" ) ) {
224                         l_CurPtrDataItem = va_arg( l_Argptr, PWCHAR);
225                         /* convert to string */ 
226                         status = RtlStringCchPrintfW( (NTSTRSAFE_PWSTR)l_Ptr, l_BufSize>>1, l_FormatStr , l_CurPtrDataItem );
227                 }
228                 else {
229                         l_CurDataItem = va_arg( l_Argptr, int);
230                         /* convert to string */ 
231                         status = RtlStringCchPrintfW( (NTSTRSAFE_PWSTR)l_Ptr, l_BufSize>>1, l_FormatStr , l_CurDataItem );
232                 }
233
234                 if (!NT_SUCCESS(status))
235                         return;
236
237                 /* prepare the next loop */
238                 status = RtlStringCbLengthW( (NTSTRSAFE_PWSTR)l_Ptr, l_BufSize, &l_StrSize );
239                 if (!NT_SUCCESS(status))
240                         return;
241                 *(WCHAR*)&l_Ptr[l_StrSize] = (WCHAR)0;
242                 l_StrSize += 2;
243                 l_Size = l_Size + (int)l_StrSize;
244                 l_Ptr = l_Buf + l_Size;
245                 l_BufSize = (int)(l_Buf + sizeof(l_Buf)- l_Ptr);
246         
247         } /* Inset a data item */
248
249         /* Term the variable argument list */   
250         va_end(l_Argptr);
251
252         /* Allocate an error log entry */ 
253         l_TotalSize =sizeof(IO_ERROR_LOG_PACKET) +l_Size;
254         if (l_TotalSize >= ERROR_LOG_MAXIMUM_SIZE - 2) {
255                 l_TotalSize = ERROR_LOG_MAXIMUM_SIZE - 2;
256                 l_Size = l_TotalSize - sizeof(IO_ERROR_LOG_PACKET);
257         }
258         l_pErrorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(
259                 pi_pIoObject,  (UCHAR)l_TotalSize );
260
261         /* Check allocation */
262         if ( l_pErrorLogEntry != NULL) 
263         { /* OK */
264
265                 /* Set the error log entry header */
266                 l_pErrorLogEntry->ErrorCode                     = pi_ErrorCode; 
267                 l_pErrorLogEntry->DumpDataSize          = 0; 
268                 l_pErrorLogEntry->SequenceNumber        = 0; 
269                 l_pErrorLogEntry->MajorFunctionCode = 0; 
270                 l_pErrorLogEntry->IoControlCode         = 0; 
271                 l_pErrorLogEntry->RetryCount            = 0; 
272                 l_pErrorLogEntry->UniqueErrorValue      = pi_UniqueErrorCode; 
273                 l_pErrorLogEntry->FinalStatus           = pi_FinalStatus; 
274                 l_pErrorLogEntry->NumberOfStrings = l_nDataItem;
275                 l_pErrorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET) + l_pErrorLogEntry->DumpDataSize;
276                 l_Ptr = (UCHAR*)l_pErrorLogEntry + l_pErrorLogEntry->StringOffset;
277                 if ( l_Size )
278                         memcpy( l_Ptr, l_Buf, l_Size );
279
280                 /* Write the packet */
281                 IoWriteErrorLogEntry(l_pErrorLogEntry);
282
283         } /* OK */
284
285 } /* WriteEventLogEntry */
286
287 // bsize is to be a strlen(src)
288 // dest has to have enough place, i.e at least (2*strlen(src) + 2)
289 void __ansi_to_wchar( USHORT *dest, UCHAR *src, int bsize)
290 {
291         int i;
292
293         for (i=0; i<bsize; ++i)
294                 *dest++ = *src++;
295         *dest = 0;
296 }
297
298 VOID
299 mlx4_err(
300         IN struct mlx4_dev *    mdev,
301         IN char*                                format,
302         ...
303         )
304 {
305         va_list         list;
306         UCHAR           buf[MAX_BUFFER_SIZE];
307         WCHAR           wbuf[MAX_BUFFER_SIZE];
308
309         // print to Debugger
310         va_start(list, format);
311         buf[MAX_BUFFER_SIZE - 1] = '\0';
312
313         if (mdev == NULL) {
314                 ASSERT(mdev != NULL);
315                 return;
316         }
317
318         
319         if (RtlStringCbVPrintfA( (char*)buf, sizeof(buf), format, list))
320                 return;
321         cl_dbg_out( "%s\n", (char*)buf );
322         va_end(list);
323
324         // print to Event Log
325         __ansi_to_wchar( wbuf, buf, (int)strlen((void*)buf) );
326         WriteEventLogEntryStr( mdev->pdev->p_self_do, (ULONG)EVENT_MLX4_ANY_ERROR, 0, 0, wbuf, 0, 0 ); 
327 }
328
329 VOID
330 mlx4_dbg(
331         IN struct mlx4_dev *    mdev,
332         IN char*                                format,
333         ...
334         )
335 {
336 #if DBG
337         va_list         list;
338         UCHAR           buf[MAX_BUFFER_SIZE];
339         UNUSED_PARAM(mdev);
340
341         // print to Debugger
342         va_start(list, format);
343         buf[MAX_BUFFER_SIZE - 1] = '\0';
344         RtlStringCbVPrintfA( (char*)buf, sizeof(buf), format, list);
345         cl_dbg_out( "%s\n", (char*)buf );
346         va_end(list);
347 #else   
348         UNUSED_PARAM(mdev);
349         UNUSED_PARAM(format);
350 #endif //DBG
351 }
352
353 VOID
354 dev_err(
355         IN struct mlx4_dev **   mdev,
356         IN char*                                format,
357         ...
358         )
359 {
360         va_list         list;
361         UCHAR           buf[MAX_BUFFER_SIZE];
362         WCHAR           wbuf[MAX_BUFFER_SIZE];
363
364         if (mdev == NULL) {
365                 ASSERT(mdev != NULL);
366                 return;
367         }
368
369         // print to Debugger
370         va_start(list, format);
371         buf[MAX_BUFFER_SIZE - 1] = '\0';
372         RtlStringCbVPrintfA( (char*)buf, sizeof(buf), format, list);
373         cl_dbg_out( "%s\n", (char*)buf );
374         va_end(list);
375
376         // print to Event Log
377         RtlStringCchPrintfW(wbuf, sizeof(wbuf)/sizeof(wbuf[0]), L"%S", buf);
378         WriteEventLogEntryStr( (*mdev)->pdev->p_self_do, (ULONG)EVENT_MLX4_ANY_ERROR, 0, 0, wbuf, 0, 0 ); 
379 }
380
381 VOID
382 dev_info(
383         IN struct mlx4_dev **   p_mdev,
384         IN char*                                format,
385         ...
386         )
387 {
388 #if DBG
389         va_list         list;
390         UCHAR           buf[MAX_BUFFER_SIZE];
391         UNUSED_PARAM(p_mdev);
392
393         // print to Debugger
394         va_start(list, format);
395         buf[MAX_BUFFER_SIZE - 1] = '\0';
396         RtlStringCbVPrintfA( (char*)buf, sizeof(buf), format, list);
397         cl_dbg_out( "%s\n", (char*)buf );
398         va_end(list);
399 #else   
400         UNUSED_PARAM(p_mdev);
401         UNUSED_PARAM(format);
402 #endif
403 }
404
405
406