13 #define DBG_MAGIC (0x47114711L)
15 static void DI_register(void *arg
);
16 static void DI_deregister(pDbgHandle hDbg
);
17 static void DI_format(int do_lock
, word id
, int type
, char *format
, va_list argument_list
);
18 static void DI_format_locked(word id
, int type
, char *format
, va_list argument_list
);
19 static void DI_format_old(word id
, char *format
, va_list ap
) { }
20 static void DiProcessEventLog(unsigned short id
, unsigned long msgID
, va_list ap
) { }
21 static void single_p(byte
*P
, word
*PLength
, byte Id
);
22 static void diva_maint_xdi_cb(ENTITY
*e
);
23 static word
SuperTraceCreateReadReq(byte
*P
, const char *path
);
24 static int diva_mnt_cmp_nmbr(const char *nmbr
);
25 static void diva_free_dma_descriptor(IDI_CALL request
, int nr
);
26 static int diva_get_dma_descriptor(IDI_CALL request
, dword
*dma_magic
);
27 void diva_mnt_internal_dprintf(dword drv_id
, dword type
, char *p
, ...);
29 static dword MaxDumpSize
= 256;
30 static dword MaxXlogSize
= 2 + 128;
31 static char TraceFilter
[DIVA_MAX_SELECTIVE_FILTER_LENGTH
+ 1];
32 static int TraceFilterIdent
= -1;
33 static int TraceFilterChannel
= -1;
35 typedef struct _diva_maint_client
{
46 diva_strace_library_interface_t
*pIdiLib
;
48 char xbuffer
[2048 + 512];
52 } diva_maint_client_t
;
53 static diva_maint_client_t clients
[MAX_DESCRIPTORS
];
55 static void diva_change_management_debug_mask(diva_maint_client_t
*pC
, dword old_mask
);
57 static void diva_maint_error(void *user_context
,
58 diva_strace_library_interface_t
*hLib
,
63 static void diva_maint_state_change_notify(void *user_context
,
64 diva_strace_library_interface_t
*hLib
,
66 diva_trace_line_state_t
*channel
,
68 static void diva_maint_trace_notify(void *user_context
,
69 diva_strace_library_interface_t
*hLib
,
76 typedef struct MSG_QUEUE
{
77 dword Size
; /* total size of queue (constant) */
78 byte
*Base
; /* lowest address (constant) */
79 byte
*High
; /* Base + Size (constant) */
80 byte
*Head
; /* first message in queue (if any) */
81 byte
*Tail
; /* first free position */
82 byte
*Wrap
; /* current wraparound position */
83 dword Count
; /* current no of bytes in queue */
86 typedef struct MSG_HEAD
{
87 volatile dword Size
; /* size of data following MSG_HEAD */
88 #define MSG_INCOMPLETE 0x8000 /* ored to Size until queueCompleteMsg */
91 #define queueCompleteMsg(p) do { ((MSG_HEAD *)p - 1)->Size &= ~MSG_INCOMPLETE; } while (0)
92 #define queueCount(q) ((q)->Count)
93 #define MSG_NEED(size) \
94 ((sizeof(MSG_HEAD) + size + sizeof(dword) - 1) & ~(sizeof(dword) - 1))
96 static void queueInit(MSG_QUEUE
*Q
, byte
*Buffer
, dword sizeBuffer
) {
98 Q
->Base
= Q
->Head
= Q
->Tail
= Buffer
;
99 Q
->High
= Buffer
+ sizeBuffer
;
104 static byte
*queueAllocMsg(MSG_QUEUE
*Q
, word size
) {
105 /* Allocate 'size' bytes at tail of queue which will be filled later
106 * directly with callers own message header info and/or message.
107 * An 'alloced' message is marked incomplete by oring the 'Size' field
108 * with MSG_INCOMPLETE.
109 * This must be reset via queueCompleteMsg() after the message is filled.
110 * As long as a message is marked incomplete queuePeekMsg() will return
111 * a 'queue empty' condition when it reaches such a message. */
114 word need
= MSG_NEED(size
);
116 if (Q
->Tail
== Q
->Head
) {
117 if (Q
->Wrap
|| need
> Q
->Size
) {
118 return NULL
; /* full */
120 goto alloc
; /* empty */
123 if (Q
->Tail
> Q
->Head
) {
124 if (Q
->Tail
+ need
<= Q
->High
) goto alloc
; /* append */
125 if (Q
->Base
+ need
> Q
->Head
) {
126 return NULL
; /* too much */
128 /* wraparound the queue (but not the message) */
134 if (Q
->Tail
+ need
> Q
->Head
) {
135 return NULL
; /* too much */
139 Msg
= (MSG_HEAD
*)Q
->Tail
;
141 Msg
->Size
= size
| MSG_INCOMPLETE
;
148 return ((byte
*)(Msg
+ 1));
151 static void queueFreeMsg(MSG_QUEUE
*Q
) {
152 /* Free the message at head of queue */
154 word size
= ((MSG_HEAD
*)Q
->Head
)->Size
& ~MSG_INCOMPLETE
;
156 Q
->Head
+= MSG_NEED(size
);
160 if (Q
->Head
>= Q
->Wrap
) {
164 } else if (Q
->Head
>= Q
->Tail
) {
165 Q
->Head
= Q
->Tail
= Q
->Base
;
169 static byte
*queuePeekMsg(MSG_QUEUE
*Q
, word
*size
) {
170 /* Show the first valid message in queue BUT DON'T free the message.
171 * After looking on the message contents it can be freed queueFreeMsg()
172 * or simply remain in message queue. */
174 MSG_HEAD
*Msg
= (MSG_HEAD
*)Q
->Head
;
176 if (((byte
*)Msg
== Q
->Tail
&& !Q
->Wrap
) ||
177 (Msg
->Size
& MSG_INCOMPLETE
)) {
181 return ((byte
*)(Msg
+ 1));
188 static MSG_QUEUE
*dbg_queue
;
189 static byte
*dbg_base
;
190 static int external_dbg_queue
;
191 static diva_os_spin_lock_t dbg_q_lock
;
192 static diva_os_spin_lock_t dbg_adapter_lock
;
193 static int dbg_q_busy
;
194 static volatile dword dbg_sequence
;
195 static dword start_sec
;
196 static dword start_usec
;
200 Initialize run time queue structures.
201 base: base of the message queue
202 length: length of the message queue
203 do_init: perfor queue reset
205 return: zero on success, -1 on error
207 int diva_maint_init(byte
*base
, unsigned long length
, int do_init
) {
208 if (dbg_queue
|| (!base
) || (length
< (4096 * 4))) {
213 TraceFilterIdent
= -1;
214 TraceFilterChannel
= -1;
218 diva_os_get_time(&start_sec
, &start_usec
);
220 *(dword
*)base
= (dword
)DBG_MAGIC
; /* Store Magic */
221 base
+= sizeof(dword
);
222 length
-= sizeof(dword
);
224 *(dword
*)base
= 2048; /* Extension Field Length */
225 base
+= sizeof(dword
);
226 length
-= sizeof(dword
);
228 strcpy(base
, "KERNEL MODE BUFFER\n");
232 *(dword
*)base
= 0; /* Terminate extension */
233 base
+= sizeof(dword
);
234 length
-= sizeof(dword
);
236 *(void **)base
= (void *)(base
+ sizeof(void *)); /* Store Base */
237 base
+= sizeof(void *);
238 length
-= sizeof(void *);
240 dbg_queue
= (MSG_QUEUE
*)base
;
241 queueInit(dbg_queue
, base
+ sizeof(MSG_QUEUE
), length
- sizeof(MSG_QUEUE
) - 512);
242 external_dbg_queue
= 0;
245 external_dbg_queue
= 1; /* memory was located on the external device */
249 if (diva_os_initialize_spin_lock(&dbg_q_lock
, "dbg_init")) {
252 external_dbg_queue
= 0;
256 if (diva_os_initialize_spin_lock(&dbg_adapter_lock
, "dbg_init")) {
257 diva_os_destroy_spin_lock(&dbg_q_lock
, "dbg_init");
260 external_dbg_queue
= 0;
270 return address of internal queue or zero if queue
273 void *diva_maint_finit(void) {
274 void *ret
= (void *)dbg_base
;
281 diva_os_destroy_spin_lock(&dbg_q_lock
, "dbg_finit");
282 diva_os_destroy_spin_lock(&dbg_adapter_lock
, "dbg_finit");
285 if (external_dbg_queue
) {
288 external_dbg_queue
= 0;
290 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
291 if (clients
[i
].pmem
) {
292 diva_os_free(0, clients
[i
].pmem
);
301 Return amount of messages in debug queue
303 dword
diva_dbg_q_length(void) {
304 return (dbg_queue
? queueCount(dbg_queue
) : 0);
309 Lock message queue and return the pointer to the first
312 diva_dbg_entry_head_t
*diva_maint_get_message(word
*size
,
313 diva_os_spin_lock_magic_t
*old_irql
) {
314 diva_dbg_entry_head_t
*pmsg
= NULL
;
316 diva_os_enter_spin_lock(&dbg_q_lock
, old_irql
, "read");
318 diva_os_leave_spin_lock(&dbg_q_lock
, old_irql
, "read_busy");
323 if (!(pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, size
))) {
325 diva_os_leave_spin_lock(&dbg_q_lock
, old_irql
, "read_empty");
333 acknowledge last message and unlock queue
335 void diva_maint_ack_message(int do_release
,
336 diva_os_spin_lock_magic_t
*old_irql
) {
341 queueFreeMsg(dbg_queue
);
344 diva_os_leave_spin_lock(&dbg_q_lock
, old_irql
, "read_ack");
350 PRT COMP function used to register
351 with MAINT adapter or log in compatibility
352 mode in case older driver version is connected too
354 void diva_maint_prtComp(char *format
, ...) {
361 va_start(ap
, format
);
364 register to new log driver functions
366 if ((format
[0] == 0) && ((unsigned char)format
[1] == 255)) {
367 hDbg
= va_arg(ap
, void *); /* ptr to DbgHandle */
374 static void DI_register(void *arg
) {
375 diva_os_spin_lock_magic_t old_irql
;
378 int id
, free_id
= -1, best_id
= 0;
380 diva_os_get_time(&sec
, &usec
);
382 hDbg
= (pDbgHandle
)arg
;
384 Check for bad args, specially for the old obsolete debug handle
386 if ((hDbg
== NULL
) ||
387 ((hDbg
->id
== 0) && (((_OldDbgHandle_
*)hDbg
)->id
== -1)) ||
388 (hDbg
->Registered
!= 0)) {
392 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "register");
394 for (id
= 1; id
< ARRAY_SIZE(clients
); id
++) {
395 if (clients
[id
].hDbg
== hDbg
) {
397 driver already registered
399 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
402 if (clients
[id
].hDbg
) { /* slot is busy */
406 if (!strcmp(clients
[id
].drvName
, hDbg
->drvName
)) {
408 This driver was already registered with this name
409 and slot is still free - reuse it
414 if (!clients
[id
].hDbg
) { /* slot is busy */
420 diva_dbg_entry_head_t
*pmsg
= NULL
;
426 Register new driver with id == free_id
428 clients
[free_id
].hDbg
= hDbg
;
429 clients
[free_id
].sec
= sec
;
430 clients
[free_id
].usec
= usec
;
431 strcpy(clients
[free_id
].drvName
, hDbg
->drvName
);
433 clients
[free_id
].dbgMask
= hDbg
->dbgMask
;
435 hDbg
->dbgMask
|= clients
[free_id
].last_dbgMask
;
437 clients
[free_id
].last_dbgMask
= 0;
440 hDbg
->Registered
= DBG_HANDLE_REG_NEW
;
441 hDbg
->id
= (byte
)free_id
;
442 hDbg
->dbg_end
= DI_deregister
;
443 hDbg
->dbg_prt
= DI_format_locked
;
444 hDbg
->dbg_ev
= DiProcessEventLog
;
445 hDbg
->dbg_irq
= DI_format_locked
;
446 if (hDbg
->Version
> 0) {
447 hDbg
->dbg_old
= DI_format_old
;
449 hDbg
->next
= (pDbgHandle
)DBG_MAGIC
;
452 Log driver register, MAINT driver ID is '0'
454 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' registered",
455 free_id
, hDbg
->drvName
);
457 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
458 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
459 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
460 queueFreeMsg(dbg_queue
);
467 pmsg
->sequence
= dbg_sequence
++;
468 pmsg
->time_sec
= sec
;
469 pmsg
->time_usec
= usec
;
470 pmsg
->facility
= MSG_TYPE_STRING
;
472 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
474 pmsg
->data_length
= len
+ 1;
476 memcpy(&pmsg
[1], tmp
, len
+ 1);
477 queueCompleteMsg(pmsg
);
478 diva_maint_wakeup_read();
482 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
485 static void DI_deregister(pDbgHandle hDbg
) {
486 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
492 diva_os_get_time(&sec
, &usec
);
494 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read");
495 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "read");
497 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
498 if (clients
[i
].hDbg
== hDbg
) {
499 diva_dbg_entry_head_t
*pmsg
;
503 clients
[i
].hDbg
= NULL
;
507 hDbg
->dbg_end
= NULL
;
508 hDbg
->dbg_prt
= NULL
;
509 hDbg
->dbg_irq
= NULL
;
510 if (hDbg
->Version
> 0)
511 hDbg
->dbg_old
= NULL
;
512 hDbg
->Registered
= 0;
515 if (clients
[i
].pIdiLib
) {
516 (*(clients
[i
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[i
].pIdiLib
->hLib
);
517 clients
[i
].pIdiLib
= NULL
;
519 pmem
= clients
[i
].pmem
;
520 clients
[i
].pmem
= NULL
;
524 Log driver register, MAINT driver ID is '0'
526 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' de-registered",
529 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
530 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
531 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
532 queueFreeMsg(dbg_queue
);
539 pmsg
->sequence
= dbg_sequence
++;
540 pmsg
->time_sec
= sec
;
541 pmsg
->time_usec
= usec
;
542 pmsg
->facility
= MSG_TYPE_STRING
;
544 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
546 pmsg
->data_length
= len
+ 1;
548 memcpy(&pmsg
[1], tmp
, len
+ 1);
549 queueCompleteMsg(pmsg
);
550 diva_maint_wakeup_read();
557 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "read_ack");
558 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read_ack");
561 diva_os_free(0, pmem
);
565 static void DI_format_locked(unsigned short id
,
568 va_list argument_list
) {
569 DI_format(1, id
, type
, format
, argument_list
);
572 static void DI_format(int do_lock
,
577 diva_os_spin_lock_magic_t old_irql
;
579 diva_dbg_entry_head_t
*pmsg
= NULL
;
582 static char fmtBuf
[MSG_FRAME_MAX_SIZE
+ sizeof(*pmsg
) + 1];
586 if (diva_os_in_irq()) {
592 ((TraceFilter
[0] != 0) && ((TraceFilterIdent
< 0) || (TraceFilterChannel
< 0)))) {
598 diva_os_get_time(&sec
, &usec
);
601 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "format");
609 if (!(length
= va_arg(ap
, unsigned long))) {
612 if (length
> MaxDumpSize
) {
613 length
= MaxDumpSize
;
615 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
616 (word
)length
+ sizeof(*pmsg
)))) {
617 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
618 queueFreeMsg(dbg_queue
);
624 memcpy(&pmsg
[1], format
, length
);
625 pmsg
->sequence
= dbg_sequence
++;
626 pmsg
->time_sec
= sec
;
627 pmsg
->time_usec
= usec
;
628 pmsg
->facility
= MSG_TYPE_BINARY
;
629 pmsg
->dli
= type
; /* DLI_XXX */
630 pmsg
->drv_id
= id
; /* driver MAINT id */
632 pmsg
->data_length
= length
;
633 queueCompleteMsg(pmsg
);
639 data
= va_arg(ap
, char *);
640 code
= (unsigned short)va_arg(ap
, unsigned int);
641 length
= (unsigned long)va_arg(ap
, unsigned int);
643 if (length
> MaxXlogSize
)
644 length
= MaxXlogSize
;
646 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
647 (word
)length
+ sizeof(*pmsg
) + 2))) {
648 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
649 queueFreeMsg(dbg_queue
);
655 p
= (byte
*)&pmsg
[1];
657 p
[1] = (char)(code
>> 8);
658 if (data
&& length
) {
659 memcpy(&p
[2], &data
[0], length
);
663 pmsg
->sequence
= dbg_sequence
++;
664 pmsg
->time_sec
= sec
;
665 pmsg
->time_usec
= usec
;
666 pmsg
->facility
= MSG_TYPE_BINARY
;
667 pmsg
->dli
= type
; /* DLI_XXX */
668 pmsg
->drv_id
= id
; /* driver MAINT id */
670 pmsg
->data_length
= length
;
671 queueCompleteMsg(pmsg
);
692 if ((length
= (unsigned long)vsprintf(&fmtBuf
[0], format
, ap
)) > 0) {
693 length
+= (sizeof(*pmsg
) + 1);
695 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
697 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
698 queueFreeMsg(dbg_queue
);
704 pmsg
->sequence
= dbg_sequence
++;
705 pmsg
->time_sec
= sec
;
706 pmsg
->time_usec
= usec
;
707 pmsg
->facility
= MSG_TYPE_STRING
;
708 pmsg
->dli
= type
; /* DLI_XXX */
709 pmsg
->drv_id
= id
; /* driver MAINT id */
711 pmsg
->data_length
= length
- sizeof(*pmsg
);
713 memcpy(&pmsg
[1], fmtBuf
, pmsg
->data_length
);
714 queueCompleteMsg(pmsg
);
721 if (queueCount(dbg_queue
)) {
722 diva_maint_wakeup_read();
726 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "format");
731 Write driver ID and driver revision to callers buffer
733 int diva_get_driver_info(dword id
, byte
*data
, int data_length
) {
734 diva_os_spin_lock_magic_t old_irql
;
738 if (!data
|| !id
|| (data_length
< 17) ||
739 (id
>= ARRAY_SIZE(clients
))) {
743 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
745 if (clients
[id
].hDbg
) {
747 *p
++ = (byte
)clients
[id
].sec
; /* save seconds */
748 *p
++ = (byte
)(clients
[id
].sec
>> 8);
749 *p
++ = (byte
)(clients
[id
].sec
>> 16);
750 *p
++ = (byte
)(clients
[id
].sec
>> 24);
752 *p
++ = (byte
)(clients
[id
].usec
/ 1000); /* save mseconds */
753 *p
++ = (byte
)((clients
[id
].usec
/ 1000) >> 8);
754 *p
++ = (byte
)((clients
[id
].usec
/ 1000) >> 16);
755 *p
++ = (byte
)((clients
[id
].usec
/ 1000) >> 24);
759 if ((to_copy
= min(strlen(clients
[id
].drvName
), (size_t)(data_length
- 1)))) {
760 memcpy(p
, clients
[id
].drvName
, to_copy
);
762 data_length
-= to_copy
;
763 if ((data_length
>= 4) && clients
[id
].hDbg
->drvTag
[0]) {
766 if ((to_copy
= min(strlen(clients
[id
].hDbg
->drvTag
), (size_t)(data_length
- 2)))) {
767 memcpy(p
, clients
[id
].hDbg
->drvTag
, to_copy
);
769 data_length
-= to_copy
;
770 if (data_length
>= 2) {
780 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
785 int diva_get_driver_dbg_mask(dword id
, byte
*data
) {
786 diva_os_spin_lock_magic_t old_irql
;
789 if (!data
|| !id
|| (id
>= ARRAY_SIZE(clients
))) {
792 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
794 if (clients
[id
].hDbg
) {
796 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
);
797 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
>> 8);
798 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
>> 16);
799 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
>> 24);
802 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
807 int diva_set_driver_dbg_mask(dword id
, dword mask
) {
808 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
812 if (!id
|| (id
>= ARRAY_SIZE(clients
))) {
816 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
817 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "dbg mask");
819 if (clients
[id
].hDbg
) {
820 dword old_mask
= clients
[id
].hDbg
->dbgMask
;
822 clients
[id
].hDbg
->dbgMask
= mask
;
823 clients
[id
].last_dbgMask
= (clients
[id
].hDbg
->dbgMask
| clients
[id
].dbgMask
);
825 diva_change_management_debug_mask(&clients
[id
], old_mask
);
829 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "dbg mask");
831 if (clients
[id
].request_pending
) {
832 clients
[id
].request_pending
= 0;
833 (*(clients
[id
].request
))((ENTITY
*)(*(clients
[id
].pIdiLib
->DivaSTraceGetHandle
))(clients
[id
].pIdiLib
->hLib
));
836 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
841 static int diva_get_idi_adapter_info(IDI_CALL request
, dword
*serial
, dword
*logical
) {
842 IDI_SYNC_REQ sync_req
;
844 sync_req
.xdi_logical_adapter_number
.Req
= 0;
845 sync_req
.xdi_logical_adapter_number
.Rc
= IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER
;
846 (*request
)((ENTITY
*)&sync_req
);
847 *logical
= sync_req
.xdi_logical_adapter_number
.info
.logical_adapter_number
;
849 sync_req
.GetSerial
.Req
= 0;
850 sync_req
.GetSerial
.Rc
= IDI_SYNC_REQ_GET_SERIAL
;
851 sync_req
.GetSerial
.serial
= 0;
852 (*request
)((ENTITY
*)&sync_req
);
853 *serial
= sync_req
.GetSerial
.serial
;
859 Register XDI adapter as MAINT compatible driver
861 void diva_mnt_add_xdi_adapter(const DESCRIPTOR
*d
) {
862 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
863 dword sec
, usec
, logical
, serial
, org_mask
;
864 int id
, free_id
= -1;
866 diva_dbg_entry_head_t
*pmsg
= NULL
;
871 diva_os_get_time(&sec
, &usec
);
872 diva_get_idi_adapter_info(d
->request
, &serial
, &logical
);
873 if (serial
& 0xff000000) {
874 sprintf(tmp
, "ADAPTER:%d SN:%u-%d",
877 (byte
)(((serial
& 0xff000000) >> 24) + 1));
879 sprintf(tmp
, "ADAPTER:%d SN:%u", (int)logical
, serial
);
882 if (!(pmem
= diva_os_malloc(0, DivaSTraceGetMemotyRequirement(d
->channels
)))) {
885 memset(pmem
, 0x00, DivaSTraceGetMemotyRequirement(d
->channels
));
887 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
888 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "register");
890 for (id
= 1; id
< ARRAY_SIZE(clients
); id
++) {
891 if (clients
[id
].hDbg
&& (clients
[id
].request
== d
->request
)) {
892 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
893 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
894 diva_os_free(0, pmem
);
897 if (clients
[id
].hDbg
) { /* slot is busy */
903 if (!strcmp(clients
[id
].drvName
, tmp
)) {
905 This driver was already registered with this name
906 and slot is still free - reuse it
914 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
915 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
916 diva_os_free(0, pmem
);
921 clients
[id
].request
= d
->request
;
922 clients
[id
].request_pending
= 0;
923 clients
[id
].hDbg
= &clients
[id
].Dbg
;
924 clients
[id
].sec
= sec
;
925 clients
[id
].usec
= usec
;
926 strcpy(clients
[id
].drvName
, tmp
);
927 strcpy(clients
[id
].Dbg
.drvName
, tmp
);
928 clients
[id
].Dbg
.drvTag
[0] = 0;
929 clients
[id
].logical
= (int)logical
;
930 clients
[id
].channels
= (int)d
->channels
;
931 clients
[id
].dma_handle
= -1;
933 clients
[id
].Dbg
.dbgMask
= 0;
934 clients
[id
].dbgMask
= clients
[id
].Dbg
.dbgMask
;
936 clients
[id
].Dbg
.dbgMask
|= clients
[free_id
].last_dbgMask
;
938 clients
[id
].last_dbgMask
= 0;
940 clients
[id
].Dbg
.Registered
= DBG_HANDLE_REG_NEW
;
941 clients
[id
].Dbg
.id
= (byte
)id
;
942 clients
[id
].Dbg
.dbg_end
= DI_deregister
;
943 clients
[id
].Dbg
.dbg_prt
= DI_format_locked
;
944 clients
[id
].Dbg
.dbg_ev
= DiProcessEventLog
;
945 clients
[id
].Dbg
.dbg_irq
= DI_format_locked
;
946 clients
[id
].Dbg
.next
= (pDbgHandle
)DBG_MAGIC
;
949 diva_trace_library_user_interface_t diva_maint_user_ifc
= { &clients
[id
],
950 diva_maint_state_change_notify
,
951 diva_maint_trace_notify
,
955 Attach to adapter management interface
957 if ((clients
[id
].pIdiLib
=
958 DivaSTraceLibraryCreateInstance((int)logical
, &diva_maint_user_ifc
, pmem
))) {
959 if (((*(clients
[id
].pIdiLib
->DivaSTraceLibraryStart
))(clients
[id
].pIdiLib
->hLib
))) {
960 diva_mnt_internal_dprintf(0, DLI_ERR
, "Adapter(%d) Start failed", (int)logical
);
961 (*(clients
[id
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[id
].pIdiLib
->hLib
);
962 clients
[id
].pIdiLib
= NULL
;
965 diva_mnt_internal_dprintf(0, DLI_ERR
, "A(%d) management init failed", (int)logical
);
969 if (!clients
[id
].pIdiLib
) {
970 clients
[id
].request
= NULL
;
971 clients
[id
].request_pending
= 0;
972 clients
[id
].hDbg
= NULL
;
973 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
974 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
975 diva_os_free(0, pmem
);
980 Log driver register, MAINT driver ID is '0'
982 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' registered",
983 id
, clients
[id
].Dbg
.drvName
);
985 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
986 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
987 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
988 queueFreeMsg(dbg_queue
);
995 pmsg
->sequence
= dbg_sequence
++;
996 pmsg
->time_sec
= sec
;
997 pmsg
->time_usec
= usec
;
998 pmsg
->facility
= MSG_TYPE_STRING
;
1000 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
1002 pmsg
->data_length
= len
+ 1;
1004 memcpy(&pmsg
[1], tmp
, len
+ 1);
1005 queueCompleteMsg(pmsg
);
1006 diva_maint_wakeup_read();
1009 org_mask
= clients
[id
].Dbg
.dbgMask
;
1010 clients
[id
].Dbg
.dbgMask
= 0;
1012 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
1014 if (clients
[id
].request_pending
) {
1015 clients
[id
].request_pending
= 0;
1016 (*(clients
[id
].request
))((ENTITY
*)(*(clients
[id
].pIdiLib
->DivaSTraceGetHandle
))(clients
[id
].pIdiLib
->hLib
));
1019 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
1021 diva_set_driver_dbg_mask(id
, org_mask
);
1025 De-Register XDI adapter
1027 void diva_mnt_remove_xdi_adapter(const DESCRIPTOR
*d
) {
1028 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1034 diva_os_get_time(&sec
, &usec
);
1036 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read");
1037 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "read");
1039 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
1040 if (clients
[i
].hDbg
&& (clients
[i
].request
== d
->request
)) {
1041 diva_dbg_entry_head_t
*pmsg
;
1045 if (clients
[i
].pIdiLib
) {
1046 (*(clients
[i
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[i
].pIdiLib
->hLib
);
1047 clients
[i
].pIdiLib
= NULL
;
1049 pmem
= clients
[i
].pmem
;
1050 clients
[i
].pmem
= NULL
;
1053 clients
[i
].hDbg
= NULL
;
1054 clients
[i
].request_pending
= 0;
1055 if (clients
[i
].dma_handle
>= 0) {
1059 diva_free_dma_descriptor(clients
[i
].request
, clients
[i
].dma_handle
);
1060 clients
[i
].dma_handle
= -1;
1062 clients
[i
].request
= NULL
;
1065 Log driver register, MAINT driver ID is '0'
1067 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' de-registered",
1068 i
, clients
[i
].Dbg
.drvName
);
1070 memset(&clients
[i
].Dbg
, 0x00, sizeof(clients
[i
].Dbg
));
1072 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
1073 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
1074 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
1075 queueFreeMsg(dbg_queue
);
1082 pmsg
->sequence
= dbg_sequence
++;
1083 pmsg
->time_sec
= sec
;
1084 pmsg
->time_usec
= usec
;
1085 pmsg
->facility
= MSG_TYPE_STRING
;
1086 pmsg
->dli
= DLI_REG
;
1087 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
1089 pmsg
->data_length
= len
+ 1;
1091 memcpy(&pmsg
[1], tmp
, len
+ 1);
1092 queueCompleteMsg(pmsg
);
1093 diva_maint_wakeup_read();
1100 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "read_ack");
1101 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read_ack");
1104 diva_os_free(0, pmem
);
1108 /* ----------------------------------------------------------------
1109 Low level interface for management interface client
1110 ---------------------------------------------------------------- */
1112 Return handle to client structure
1114 void *SuperTraceOpenAdapter(int AdapterNumber
) {
1117 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
1118 if (clients
[i
].hDbg
&& clients
[i
].request
&& (clients
[i
].logical
== AdapterNumber
)) {
1119 return (&clients
[i
]);
1126 int SuperTraceCloseAdapter(void *AdapterHandle
) {
1130 int SuperTraceReadRequest(void *AdapterHandle
, const char *name
, byte
*data
) {
1131 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1133 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1134 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1135 byte
*xdata
= (byte
*)&pC
->xbuffer
[0];
1139 if (!strcmp(name
, "\\")) { /* Read ROOT */
1142 length
= SuperTraceCreateReadReq(xdata
, name
);
1143 single_p(xdata
, &length
, 0); /* End Of Message */
1147 e
->X
->PLength
= length
;
1148 e
->X
->P
= (byte
*)xdata
;
1150 pC
->request_pending
= 1;
1158 int SuperTraceGetNumberOfChannels(void *AdapterHandle
) {
1159 if (AdapterHandle
) {
1160 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1162 return (pC
->channels
);
1168 int SuperTraceASSIGN(void *AdapterHandle
, byte
*data
) {
1169 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1171 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1172 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1174 char buffer
[((sizeof(preq
->xdi_extended_features
) + 4) > sizeof(ENTITY
)) ? (sizeof(preq
->xdi_extended_features
) + 4) : sizeof(ENTITY
)];
1176 word assign_data_length
= 1;
1180 preq
= (IDI_SYNC_REQ
*)&buffer
[0];
1181 preq
->xdi_extended_features
.Req
= 0;
1182 preq
->xdi_extended_features
.Rc
= IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES
;
1183 preq
->xdi_extended_features
.info
.buffer_length_in_bytes
= sizeof(features
);
1184 preq
->xdi_extended_features
.info
.features
= &features
[0];
1186 (*(pC
->request
))((ENTITY
*)preq
);
1188 if ((features
[0] & DIVA_XDI_EXTENDED_FEATURES_VALID
) &&
1189 (features
[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA
)) {
1190 dword
uninitialized_var(rx_dma_magic
);
1191 if ((pC
->dma_handle
= diva_get_dma_descriptor(pC
->request
, &rx_dma_magic
)) >= 0) {
1192 pC
->xbuffer
[0] = LLI
;
1194 pC
->xbuffer
[2] = 0x40;
1195 pC
->xbuffer
[3] = (byte
)pC
->dma_handle
;
1196 pC
->xbuffer
[4] = (byte
)rx_dma_magic
;
1197 pC
->xbuffer
[5] = (byte
)(rx_dma_magic
>> 8);
1198 pC
->xbuffer
[6] = (byte
)(rx_dma_magic
>> 16);
1199 pC
->xbuffer
[7] = (byte
)(rx_dma_magic
>> 24);
1200 pC
->xbuffer
[8] = (byte
)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE
& 0xFF);
1201 pC
->xbuffer
[9] = (byte
)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE
>> 8);
1202 pC
->xbuffer
[10] = 0;
1204 assign_data_length
= 11;
1207 pC
->dma_handle
= -1;
1211 e
->callback
= diva_maint_xdi_cb
;
1216 e
->X
->PLength
= assign_data_length
;
1217 e
->X
->P
= (byte
*)&pC
->xbuffer
[0];
1219 pC
->request_pending
= 1;
1227 int SuperTraceREMOVE(void *AdapterHandle
) {
1228 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1230 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1231 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1238 e
->X
->P
= (byte
*)&pC
->xbuffer
[0];
1241 pC
->request_pending
= 1;
1249 int SuperTraceTraceOnRequest(void *hAdapter
, const char *name
, byte
*data
) {
1250 diva_maint_client_t
*pC
= (diva_maint_client_t
*)hAdapter
;
1252 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1253 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1254 byte
*xdata
= (byte
*)&pC
->xbuffer
[0];
1258 if (!strcmp(name
, "\\")) { /* Read ROOT */
1261 length
= SuperTraceCreateReadReq(xdata
, name
);
1262 single_p(xdata
, &length
, 0); /* End Of Message */
1263 e
->Req
= MAN_EVENT_ON
;
1265 e
->X
->PLength
= length
;
1266 e
->X
->P
= (byte
*)xdata
;
1268 pC
->request_pending
= 1;
1276 int SuperTraceWriteVar(void *AdapterHandle
,
1282 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1284 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1285 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1286 diva_man_var_header_t
*pVar
= (diva_man_var_header_t
*)&pC
->xbuffer
[0];
1287 word length
= SuperTraceCreateReadReq((byte
*)pVar
, name
);
1289 memcpy(&pC
->xbuffer
[length
], var
, var_length
);
1290 length
+= var_length
;
1291 pVar
->length
+= var_length
;
1292 pVar
->value_length
= var_length
;
1294 single_p((byte
*)pVar
, &length
, 0); /* End Of Message */
1298 e
->X
->PLength
= length
;
1299 e
->X
->P
= (byte
*)pVar
;
1301 pC
->request_pending
= 1;
1309 int SuperTraceExecuteRequest(void *AdapterHandle
,
1312 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1314 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1315 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1316 byte
*xdata
= (byte
*)&pC
->xbuffer
[0];
1319 length
= SuperTraceCreateReadReq(xdata
, name
);
1320 single_p(xdata
, &length
, 0); /* End Of Message */
1322 e
->Req
= MAN_EXECUTE
;
1324 e
->X
->PLength
= length
;
1325 e
->X
->P
= (byte
*)xdata
;
1327 pC
->request_pending
= 1;
1335 static word
SuperTraceCreateReadReq(byte
*P
, const char *path
) {
1339 var_length
= (byte
)strlen(path
);
1343 *P
++ = 0x80; /* MAN_IE */
1344 *P
++ = 0x00; /* Type */
1345 *P
++ = 0x00; /* Attribute */
1346 *P
++ = 0x00; /* Status */
1347 *P
++ = 0x00; /* Variable Length */
1349 memcpy(P
, path
, var_length
);
1351 *plen
= var_length
+ 0x06;
1353 return ((word
)(var_length
+ 0x08));
1356 static void single_p(byte
*P
, word
*PLength
, byte Id
) {
1357 P
[(*PLength
)++] = Id
;
1360 static void diva_maint_xdi_cb(ENTITY
*e
) {
1361 diva_strace_context_t
*pLib
= DIVAS_CONTAINING_RECORD(e
, diva_strace_context_t
, e
);
1362 diva_maint_client_t
*pC
;
1363 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1366 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "xdi_cb");
1367 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "xdi_cb");
1369 pC
= (diva_maint_client_t
*)pLib
->hAdapter
;
1371 if ((e
->complete
== 255) || (pC
->dma_handle
< 0)) {
1372 if ((*(pLib
->instance
.DivaSTraceMessageInput
))(&pLib
->instance
)) {
1373 diva_mnt_internal_dprintf(0, DLI_ERR
, "Trace internal library error");
1377 Process combined management interface indication
1379 if ((*(pLib
->instance
.DivaSTraceMessageInput
))(&pLib
->instance
)) {
1380 diva_mnt_internal_dprintf(0, DLI_ERR
, "Trace internal library error (DMA mode)");
1384 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "xdi_cb");
1387 if (pC
->request_pending
) {
1388 pC
->request_pending
= 0;
1389 (*(pC
->request
))(e
);
1392 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "xdi_cb");
1396 static void diva_maint_error(void *user_context
,
1397 diva_strace_library_interface_t
*hLib
,
1402 diva_mnt_internal_dprintf(0, DLI_ERR
,
1403 "Trace library error(%d) A(%d) %s %d", error
, Adapter
, file
, line
);
1406 static void print_ie(diva_trace_ie_t
*ie
, char *buffer
, int length
) {
1412 for (i
= 0; ((i
< ie
->length
) && (length
> 3)); i
++) {
1413 sprintf(buffer
, "%02x", ie
->data
[i
]);
1416 if (i
< (ie
->length
- 1)) {
1417 strcpy(buffer
, " ");
1425 static void diva_maint_state_change_notify(void *user_context
,
1426 diva_strace_library_interface_t
*hLib
,
1428 diva_trace_line_state_t
*channel
,
1429 int notify_subject
) {
1430 diva_maint_client_t
*pC
= (diva_maint_client_t
*)user_context
;
1431 diva_trace_fax_state_t
*fax
= &channel
->fax
;
1432 diva_trace_modem_state_t
*modem
= &channel
->modem
;
1439 switch (notify_subject
) {
1440 case DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE
: {
1441 int view
= (TraceFilter
[0] == 0);
1443 Process selective Trace
1445 if (channel
->Line
[0] == 'I' && channel
->Line
[1] == 'd' &&
1446 channel
->Line
[2] == 'l' && channel
->Line
[3] == 'e') {
1447 if ((TraceFilterIdent
== pC
->hDbg
->id
) && (TraceFilterChannel
== (int)channel
->ChannelNumber
)) {
1448 (*(hLib
->DivaSTraceSetBChannel
))(hLib
, (int)channel
->ChannelNumber
, 0);
1449 (*(hLib
->DivaSTraceSetAudioTap
))(hLib
, (int)channel
->ChannelNumber
, 0);
1450 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
, "Selective Trace OFF for Ch=%d",
1451 (int)channel
->ChannelNumber
);
1452 TraceFilterIdent
= -1;
1453 TraceFilterChannel
= -1;
1456 } else if (TraceFilter
[0] && (TraceFilterIdent
< 0) && !(diva_mnt_cmp_nmbr(&channel
->RemoteAddress
[0]) &&
1457 diva_mnt_cmp_nmbr(&channel
->LocalAddress
[0]))) {
1459 if ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_BCHANNEL
) != 0) { /* Activate B-channel trace */
1460 (*(hLib
->DivaSTraceSetBChannel
))(hLib
, (int)channel
->ChannelNumber
, 1);
1462 if ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_AUDIO
) != 0) { /* Activate AudioTap Trace */
1463 (*(hLib
->DivaSTraceSetAudioTap
))(hLib
, (int)channel
->ChannelNumber
, 1);
1466 TraceFilterIdent
= pC
->hDbg
->id
;
1467 TraceFilterChannel
= (int)channel
->ChannelNumber
;
1469 if (TraceFilterIdent
>= 0) {
1470 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
, "Selective Trace ON for Ch=%d",
1471 (int)channel
->ChannelNumber
);
1475 if (view
&& (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_LINE_EVENTS
)) {
1476 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Ch = %d",
1477 (int)channel
->ChannelNumber
);
1478 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Status = <%s>", &channel
->Line
[0]);
1479 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Layer1 = <%s>", &channel
->Framing
[0]);
1480 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Layer2 = <%s>", &channel
->Layer2
[0]);
1481 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Layer3 = <%s>", &channel
->Layer3
[0]);
1482 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L RAddr = <%s>",
1483 &channel
->RemoteAddress
[0]);
1484 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L RSAddr = <%s>",
1485 &channel
->RemoteSubAddress
[0]);
1486 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L LAddr = <%s>",
1487 &channel
->LocalAddress
[0]);
1488 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L LSAddr = <%s>",
1489 &channel
->LocalSubAddress
[0]);
1490 print_ie(&channel
->call_BC
, tmp
, sizeof(tmp
));
1491 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L BC = <%s>", tmp
);
1492 print_ie(&channel
->call_HLC
, tmp
, sizeof(tmp
));
1493 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L HLC = <%s>", tmp
);
1494 print_ie(&channel
->call_LLC
, tmp
, sizeof(tmp
));
1495 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L LLC = <%s>", tmp
);
1496 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L CR = 0x%x", channel
->CallReference
);
1497 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Disc = 0x%x",
1498 channel
->LastDisconnecCause
);
1499 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Owner = <%s>", &channel
->UserID
[0]);
1504 case DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE
:
1505 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_MDM_PROGRESS
) {
1507 int ch
= TraceFilterChannel
;
1508 int id
= TraceFilterIdent
;
1510 if ((id
>= 0) && (ch
>= 0) && (id
< ARRAY_SIZE(clients
)) &&
1511 (clients
[id
].Dbg
.id
== (byte
)id
) && (clients
[id
].pIdiLib
== hLib
)) {
1512 if (ch
!= (int)modem
->ChannelNumber
) {
1515 } else if (TraceFilter
[0] != 0) {
1521 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Ch = %lu",
1522 (int)modem
->ChannelNumber
);
1523 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Event = %lu", modem
->Event
);
1524 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Norm = %lu", modem
->Norm
);
1525 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Opts. = 0x%08x", modem
->Options
);
1526 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Tx = %lu Bps", modem
->TxSpeed
);
1527 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Rx = %lu Bps", modem
->RxSpeed
);
1528 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM RT = %lu mSec",
1529 modem
->RoundtripMsec
);
1530 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Sr = %lu", modem
->SymbolRate
);
1531 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Rxl = %d dBm", modem
->RxLeveldBm
);
1532 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM El = %d dBm", modem
->EchoLeveldBm
);
1533 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM SNR = %lu dB", modem
->SNRdb
);
1534 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM MAE = %lu", modem
->MAE
);
1535 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM LRet = %lu",
1536 modem
->LocalRetrains
);
1537 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM RRet = %lu",
1538 modem
->RemoteRetrains
);
1539 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM LRes = %lu", modem
->LocalResyncs
);
1540 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM RRes = %lu",
1541 modem
->RemoteResyncs
);
1542 if (modem
->Event
== 3) {
1543 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Disc = %lu", modem
->DiscReason
);
1546 if ((modem
->Event
== 3) && (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_MDM_STATISTICS
)) {
1547 (*(pC
->pIdiLib
->DivaSTraceGetModemStatistics
))(pC
->pIdiLib
);
1551 case DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE
:
1552 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_FAX_PROGRESS
) {
1554 int ch
= TraceFilterChannel
;
1555 int id
= TraceFilterIdent
;
1557 if ((id
>= 0) && (ch
>= 0) && (id
< ARRAY_SIZE(clients
)) &&
1558 (clients
[id
].Dbg
.id
== (byte
)id
) && (clients
[id
].pIdiLib
== hLib
)) {
1559 if (ch
!= (int)fax
->ChannelNumber
) {
1562 } else if (TraceFilter
[0] != 0) {
1567 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Ch = %lu", (int)fax
->ChannelNumber
);
1568 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Event = %lu", fax
->Event
);
1569 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Pages = %lu", fax
->Page_Counter
);
1570 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Feat. = 0x%08x", fax
->Features
);
1571 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX ID = <%s>", &fax
->Station_ID
[0]);
1572 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Saddr = <%s>", &fax
->Subaddress
[0]);
1573 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Pwd = <%s>", &fax
->Password
[0]);
1574 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Speed = %lu", fax
->Speed
);
1575 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Res. = 0x%08x", fax
->Resolution
);
1576 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Width = %lu", fax
->Paper_Width
);
1577 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Length= %lu", fax
->Paper_Length
);
1578 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX SLT = %lu", fax
->Scanline_Time
);
1579 if (fax
->Event
== 3) {
1580 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Disc = %lu", fax
->Disc_Reason
);
1583 if ((fax
->Event
== 3) && (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_FAX_STATISTICS
)) {
1584 (*(pC
->pIdiLib
->DivaSTraceGetFaxStatistics
))(pC
->pIdiLib
);
1588 case DIVA_SUPER_TRACE_INTERFACE_CHANGE
:
1589 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_EVENTS
) {
1590 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
,
1591 "Layer 1 -> [%s]", channel
->pInterface
->Layer1
);
1592 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
,
1593 "Layer 2 -> [%s]", channel
->pInterface
->Layer2
);
1597 case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE
:
1598 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_STATISTICS
) {
1602 if (channel
->pInterfaceStat
->inc
.Calls
) {
1603 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1604 "Inc Calls =%lu", channel
->pInterfaceStat
->inc
.Calls
);
1606 if (channel
->pInterfaceStat
->inc
.Connected
) {
1607 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1608 "Inc Connected =%lu", channel
->pInterfaceStat
->inc
.Connected
);
1610 if (channel
->pInterfaceStat
->inc
.User_Busy
) {
1611 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1612 "Inc Busy =%lu", channel
->pInterfaceStat
->inc
.User_Busy
);
1614 if (channel
->pInterfaceStat
->inc
.Call_Rejected
) {
1615 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1616 "Inc Rejected =%lu", channel
->pInterfaceStat
->inc
.Call_Rejected
);
1618 if (channel
->pInterfaceStat
->inc
.Wrong_Number
) {
1619 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1620 "Inc Wrong Nr =%lu", channel
->pInterfaceStat
->inc
.Wrong_Number
);
1622 if (channel
->pInterfaceStat
->inc
.Incompatible_Dst
) {
1623 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1624 "Inc Incomp. Dest =%lu", channel
->pInterfaceStat
->inc
.Incompatible_Dst
);
1626 if (channel
->pInterfaceStat
->inc
.Out_of_Order
) {
1627 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1628 "Inc Out of Order =%lu", channel
->pInterfaceStat
->inc
.Out_of_Order
);
1630 if (channel
->pInterfaceStat
->inc
.Ignored
) {
1631 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1632 "Inc Ignored =%lu", channel
->pInterfaceStat
->inc
.Ignored
);
1638 if (channel
->pInterfaceStat
->outg
.Calls
) {
1639 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1640 "Outg Calls =%lu", channel
->pInterfaceStat
->outg
.Calls
);
1642 if (channel
->pInterfaceStat
->outg
.Connected
) {
1643 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1644 "Outg Connected =%lu", channel
->pInterfaceStat
->outg
.Connected
);
1646 if (channel
->pInterfaceStat
->outg
.User_Busy
) {
1647 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1648 "Outg Busy =%lu", channel
->pInterfaceStat
->outg
.User_Busy
);
1650 if (channel
->pInterfaceStat
->outg
.No_Answer
) {
1651 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1652 "Outg No Answer =%lu", channel
->pInterfaceStat
->outg
.No_Answer
);
1654 if (channel
->pInterfaceStat
->outg
.Wrong_Number
) {
1655 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1656 "Outg Wrong Nr =%lu", channel
->pInterfaceStat
->outg
.Wrong_Number
);
1658 if (channel
->pInterfaceStat
->outg
.Call_Rejected
) {
1659 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1660 "Outg Rejected =%lu", channel
->pInterfaceStat
->outg
.Call_Rejected
);
1662 if (channel
->pInterfaceStat
->outg
.Other_Failures
) {
1663 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1664 "Outg Other Failures =%lu", channel
->pInterfaceStat
->outg
.Other_Failures
);
1669 case DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE
:
1670 if (channel
->pInterfaceStat
->mdm
.Disc_Normal
) {
1671 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1672 "MDM Disc Normal = %lu", channel
->pInterfaceStat
->mdm
.Disc_Normal
);
1674 if (channel
->pInterfaceStat
->mdm
.Disc_Unspecified
) {
1675 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1676 "MDM Disc Unsp. = %lu", channel
->pInterfaceStat
->mdm
.Disc_Unspecified
);
1678 if (channel
->pInterfaceStat
->mdm
.Disc_Busy_Tone
) {
1679 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1680 "MDM Disc Busy Tone = %lu", channel
->pInterfaceStat
->mdm
.Disc_Busy_Tone
);
1682 if (channel
->pInterfaceStat
->mdm
.Disc_Congestion
) {
1683 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1684 "MDM Disc Congestion = %lu", channel
->pInterfaceStat
->mdm
.Disc_Congestion
);
1686 if (channel
->pInterfaceStat
->mdm
.Disc_Carr_Wait
) {
1687 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1688 "MDM Disc Carrier Wait = %lu", channel
->pInterfaceStat
->mdm
.Disc_Carr_Wait
);
1690 if (channel
->pInterfaceStat
->mdm
.Disc_Trn_Timeout
) {
1691 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1692 "MDM Disc Trn. T.o. = %lu", channel
->pInterfaceStat
->mdm
.Disc_Trn_Timeout
);
1694 if (channel
->pInterfaceStat
->mdm
.Disc_Incompat
) {
1695 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1696 "MDM Disc Incompatible = %lu", channel
->pInterfaceStat
->mdm
.Disc_Incompat
);
1698 if (channel
->pInterfaceStat
->mdm
.Disc_Frame_Rej
) {
1699 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1700 "MDM Disc Frame Reject = %lu", channel
->pInterfaceStat
->mdm
.Disc_Frame_Rej
);
1702 if (channel
->pInterfaceStat
->mdm
.Disc_V42bis
) {
1703 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1704 "MDM Disc V.42bis = %lu", channel
->pInterfaceStat
->mdm
.Disc_V42bis
);
1708 case DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE
:
1709 if (channel
->pInterfaceStat
->fax
.Disc_Normal
) {
1710 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1711 "FAX Disc Normal = %lu", channel
->pInterfaceStat
->fax
.Disc_Normal
);
1713 if (channel
->pInterfaceStat
->fax
.Disc_Not_Ident
) {
1714 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1715 "FAX Disc Not Ident. = %lu", channel
->pInterfaceStat
->fax
.Disc_Not_Ident
);
1717 if (channel
->pInterfaceStat
->fax
.Disc_No_Response
) {
1718 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1719 "FAX Disc No Response = %lu", channel
->pInterfaceStat
->fax
.Disc_No_Response
);
1721 if (channel
->pInterfaceStat
->fax
.Disc_Retries
) {
1722 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1723 "FAX Disc Max Retries = %lu", channel
->pInterfaceStat
->fax
.Disc_Retries
);
1725 if (channel
->pInterfaceStat
->fax
.Disc_Unexp_Msg
) {
1726 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1727 "FAX Unexp. Msg. = %lu", channel
->pInterfaceStat
->fax
.Disc_Unexp_Msg
);
1729 if (channel
->pInterfaceStat
->fax
.Disc_No_Polling
) {
1730 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1731 "FAX Disc No Polling = %lu", channel
->pInterfaceStat
->fax
.Disc_No_Polling
);
1733 if (channel
->pInterfaceStat
->fax
.Disc_Training
) {
1734 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1735 "FAX Disc Training = %lu", channel
->pInterfaceStat
->fax
.Disc_Training
);
1737 if (channel
->pInterfaceStat
->fax
.Disc_Unexpected
) {
1738 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1739 "FAX Disc Unexpected = %lu", channel
->pInterfaceStat
->fax
.Disc_Unexpected
);
1741 if (channel
->pInterfaceStat
->fax
.Disc_Application
) {
1742 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1743 "FAX Disc Application = %lu", channel
->pInterfaceStat
->fax
.Disc_Application
);
1745 if (channel
->pInterfaceStat
->fax
.Disc_Incompat
) {
1746 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1747 "FAX Disc Incompatible = %lu", channel
->pInterfaceStat
->fax
.Disc_Incompat
);
1749 if (channel
->pInterfaceStat
->fax
.Disc_No_Command
) {
1750 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1751 "FAX Disc No Command = %lu", channel
->pInterfaceStat
->fax
.Disc_No_Command
);
1753 if (channel
->pInterfaceStat
->fax
.Disc_Long_Msg
) {
1754 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1755 "FAX Disc Long Msg. = %lu", channel
->pInterfaceStat
->fax
.Disc_Long_Msg
);
1757 if (channel
->pInterfaceStat
->fax
.Disc_Supervisor
) {
1758 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1759 "FAX Disc Supervisor = %lu", channel
->pInterfaceStat
->fax
.Disc_Supervisor
);
1761 if (channel
->pInterfaceStat
->fax
.Disc_SUB_SEP_PWD
) {
1762 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1763 "FAX Disc SUP SEP PWD = %lu", channel
->pInterfaceStat
->fax
.Disc_SUB_SEP_PWD
);
1765 if (channel
->pInterfaceStat
->fax
.Disc_Invalid_Msg
) {
1766 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1767 "FAX Disc Invalid Msg. = %lu", channel
->pInterfaceStat
->fax
.Disc_Invalid_Msg
);
1769 if (channel
->pInterfaceStat
->fax
.Disc_Page_Coding
) {
1770 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1771 "FAX Disc Page Coding = %lu", channel
->pInterfaceStat
->fax
.Disc_Page_Coding
);
1773 if (channel
->pInterfaceStat
->fax
.Disc_App_Timeout
) {
1774 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1775 "FAX Disc Appl. T.o. = %lu", channel
->pInterfaceStat
->fax
.Disc_App_Timeout
);
1777 if (channel
->pInterfaceStat
->fax
.Disc_Unspecified
) {
1778 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1779 "FAX Disc Unspec. = %lu", channel
->pInterfaceStat
->fax
.Disc_Unspecified
);
1786 Receive trace information from the Management Interface and store it in the
1787 internal trace buffer with MSG_TYPE_MLOG as is, without any filtering.
1788 Event Filtering and formatting is done in Management Interface self.
1790 static void diva_maint_trace_notify(void *user_context
,
1791 diva_strace_library_interface_t
*hLib
,
1795 diva_maint_client_t
*pC
= (diva_maint_client_t
*)user_context
;
1796 diva_dbg_entry_head_t
*pmsg
;
1799 int ch
= TraceFilterChannel
;
1800 int id
= TraceFilterIdent
;
1805 if ((id
>= 0) && (ch
>= 0) && (id
< ARRAY_SIZE(clients
)) &&
1806 (clients
[id
].Dbg
.id
== (byte
)id
) && (clients
[id
].pIdiLib
== hLib
)) {
1807 const char *p
= NULL
;
1809 MI_XLOG_HDR
*TrcData
= (MI_XLOG_HDR
*)xlog_buffer
;
1811 if (Adapter
!= clients
[id
].logical
) {
1812 return; /* Ignore all trace messages from other adapters */
1815 if (TrcData
->code
== 24) {
1816 p
= (char *)&TrcData
->code
;
1821 All L1 messages start as [dsp,ch], so we can filter this information
1822 and filter out all messages that use different channel
1824 if (p
&& p
[0] == '[') {
1827 ch_value
= *p
- '0';
1828 } else if (p
[3] == ',') {
1830 ch_value
= *p
- '0';
1832 if (ch_value
>= 0) {
1834 ch_value
= ch_value
* 10 + p
[1] - '0';
1836 if (ch_value
!= ch
) {
1837 return; /* Ignore other channels */
1842 } else if (TraceFilter
[0] != 0) {
1843 return; /* Ignore trace if trace filter is activated, but idle */
1846 diva_os_get_time(&sec
, &usec
);
1848 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
1849 (word
)length
+ sizeof(*pmsg
)))) {
1850 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
1851 queueFreeMsg(dbg_queue
);
1857 memcpy(&pmsg
[1], xlog_buffer
, length
);
1858 pmsg
->sequence
= dbg_sequence
++;
1859 pmsg
->time_sec
= sec
;
1860 pmsg
->time_usec
= usec
;
1861 pmsg
->facility
= MSG_TYPE_MLOG
;
1862 pmsg
->dli
= pC
->logical
;
1863 pmsg
->drv_id
= pC
->hDbg
->id
;
1865 pmsg
->data_length
= length
;
1866 queueCompleteMsg(pmsg
);
1867 if (queueCount(dbg_queue
)) {
1868 diva_maint_wakeup_read();
1875 Convert MAINT trace mask to management interface trace mask/work/facility and
1876 issue command to management interface
1878 static void diva_change_management_debug_mask(diva_maint_client_t
*pC
, dword old_mask
) {
1879 if (pC
->request
&& pC
->hDbg
&& pC
->pIdiLib
) {
1880 dword changed
= pC
->hDbg
->dbgMask
^ old_mask
;
1882 if (changed
& DIVA_MGT_DBG_TRACE
) {
1883 (*(pC
->pIdiLib
->DivaSTraceSetInfo
))(pC
->pIdiLib
,
1884 (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_TRACE
) != 0);
1886 if (changed
& DIVA_MGT_DBG_DCHAN
) {
1887 (*(pC
->pIdiLib
->DivaSTraceSetDChannel
))(pC
->pIdiLib
,
1888 (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_DCHAN
) != 0);
1890 if (!TraceFilter
[0]) {
1891 if (changed
& DIVA_MGT_DBG_IFC_BCHANNEL
) {
1892 int i
, state
= ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_BCHANNEL
) != 0);
1894 for (i
= 0; i
< pC
->channels
; i
++) {
1895 (*(pC
->pIdiLib
->DivaSTraceSetBChannel
))(pC
->pIdiLib
, i
+ 1, state
);
1898 if (changed
& DIVA_MGT_DBG_IFC_AUDIO
) {
1899 int i
, state
= ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_AUDIO
) != 0);
1901 for (i
= 0; i
< pC
->channels
; i
++) {
1902 (*(pC
->pIdiLib
->DivaSTraceSetAudioTap
))(pC
->pIdiLib
, i
+ 1, state
);
1910 void diva_mnt_internal_dprintf(dword drv_id
, dword type
, char *fmt
, ...) {
1914 DI_format(0, (word
)drv_id
, (int)type
, fmt
, ap
);
1919 Shutdown all adapters before driver removal
1921 int diva_mnt_shutdown_xdi_adapters(void) {
1922 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1927 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
1930 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "unload");
1931 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "unload");
1933 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
) {
1934 if ((*(clients
[i
].pIdiLib
->DivaSTraceLibraryStop
))(clients
[i
].pIdiLib
) == 1) {
1936 Adapter removal complete
1938 if (clients
[i
].pIdiLib
) {
1939 (*(clients
[i
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[i
].pIdiLib
->hLib
);
1940 clients
[i
].pIdiLib
= NULL
;
1942 pmem
= clients
[i
].pmem
;
1943 clients
[i
].pmem
= NULL
;
1945 clients
[i
].hDbg
= NULL
;
1946 clients
[i
].request_pending
= 0;
1948 if (clients
[i
].dma_handle
>= 0) {
1952 diva_free_dma_descriptor(clients
[i
].request
, clients
[i
].dma_handle
);
1953 clients
[i
].dma_handle
= -1;
1955 clients
[i
].request
= NULL
;
1961 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "unload");
1962 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
&& clients
[i
].request_pending
) {
1963 clients
[i
].request_pending
= 0;
1964 (*(clients
[i
].request
))((ENTITY
*)(*(clients
[i
].pIdiLib
->DivaSTraceGetHandle
))(clients
[i
].pIdiLib
->hLib
));
1965 if (clients
[i
].dma_handle
>= 0) {
1966 diva_free_dma_descriptor(clients
[i
].request
, clients
[i
].dma_handle
);
1967 clients
[i
].dma_handle
= -1;
1970 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "unload");
1973 diva_os_free(0, pmem
);
1981 Set/Read the trace filter used for selective tracing.
1982 Affects B- and Audio Tap trace mask at run time
1984 int diva_set_trace_filter(int filter_length
, const char *filter
) {
1985 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1986 int i
, ch
, on
, client_b_on
, client_atap_on
;
1988 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
1989 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
1991 if (filter_length
<= DIVA_MAX_SELECTIVE_FILTER_LENGTH
) {
1992 memcpy(&TraceFilter
[0], filter
, filter_length
);
1993 if (TraceFilter
[filter_length
]) {
1994 TraceFilter
[filter_length
] = 0;
1996 if (TraceFilter
[0] == '*') {
2003 TraceFilterIdent
= -1;
2004 TraceFilterChannel
= -1;
2006 on
= (TraceFilter
[0] == 0);
2008 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
2009 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
) {
2010 client_b_on
= on
&& ((clients
[i
].hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_BCHANNEL
) != 0);
2011 client_atap_on
= on
&& ((clients
[i
].hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_AUDIO
) != 0);
2012 for (ch
= 0; ch
< clients
[i
].channels
; ch
++) {
2013 (*(clients
[i
].pIdiLib
->DivaSTraceSetBChannel
))(clients
[i
].pIdiLib
->hLib
, ch
+ 1, client_b_on
);
2014 (*(clients
[i
].pIdiLib
->DivaSTraceSetAudioTap
))(clients
[i
].pIdiLib
->hLib
, ch
+ 1, client_atap_on
);
2019 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
2020 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
&& clients
[i
].request_pending
) {
2021 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
2022 clients
[i
].request_pending
= 0;
2023 (*(clients
[i
].request
))((ENTITY
*)(*(clients
[i
].pIdiLib
->DivaSTraceGetHandle
))(clients
[i
].pIdiLib
->hLib
));
2024 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
2028 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
2029 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
2031 return (filter_length
);
2034 int diva_get_trace_filter(int max_length
, char *filter
) {
2035 diva_os_spin_lock_magic_t old_irql
;
2038 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "read_filter");
2039 len
= strlen(&TraceFilter
[0]) + 1;
2040 if (max_length
>= len
) {
2041 memcpy(filter
, &TraceFilter
[0], len
);
2043 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "read_filter");
2048 static int diva_dbg_cmp_key(const char *ref
, const char *key
) {
2049 while (*key
&& (*ref
++ == *key
++));
2050 return (!*key
&& !*ref
);
2054 In case trace filter starts with "C" character then
2055 all following characters are interpreted as command.
2056 Followings commands are available:
2057 - single, trace single call at time, independent from CPN/CiPN
2059 static int diva_mnt_cmp_nmbr(const char *nmbr
) {
2060 const char *ref
= &TraceFilter
[0];
2061 int ref_len
= strlen(&TraceFilter
[0]), nmbr_len
= strlen(nmbr
);
2063 if (ref
[0] == 'C') {
2064 if (diva_dbg_cmp_key(&ref
[1], "single")) {
2070 if (!ref_len
|| (ref_len
> nmbr_len
)) {
2074 nmbr
= nmbr
+ nmbr_len
- 1;
2075 ref
= ref
+ ref_len
- 1;
2078 if (*nmbr
-- != *ref
--) {
2086 static int diva_get_dma_descriptor(IDI_CALL request
, dword
*dma_magic
) {
2088 IDI_SYNC_REQ
*pReq
= (IDI_SYNC_REQ
*)&e
;
2094 pReq
->xdi_dma_descriptor_operation
.Req
= 0;
2095 pReq
->xdi_dma_descriptor_operation
.Rc
= IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION
;
2097 pReq
->xdi_dma_descriptor_operation
.info
.operation
= IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC
;
2098 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
= -1;
2099 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_address
= NULL
;
2100 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
= 0;
2102 (*request
)((ENTITY
*)pReq
);
2104 if (!pReq
->xdi_dma_descriptor_operation
.info
.operation
&&
2105 (pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
>= 0) &&
2106 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
) {
2107 *dma_magic
= pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
;
2108 return (pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
);
2114 static void diva_free_dma_descriptor(IDI_CALL request
, int nr
) {
2116 IDI_SYNC_REQ
*pReq
= (IDI_SYNC_REQ
*)&e
;
2118 if (!request
|| (nr
< 0)) {
2122 pReq
->xdi_dma_descriptor_operation
.Req
= 0;
2123 pReq
->xdi_dma_descriptor_operation
.Rc
= IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION
;
2125 pReq
->xdi_dma_descriptor_operation
.info
.operation
= IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE
;
2126 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
= nr
;
2127 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_address
= NULL
;
2128 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
= 0;
2130 (*request
)((ENTITY
*)pReq
);