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
;
198 Initialize run time queue structures.
199 base: base of the message queue
200 length: length of the message queue
201 do_init: perfor queue reset
203 return: zero on success, -1 on error
205 int diva_maint_init(byte
*base
, unsigned long length
, int do_init
) {
206 if (dbg_queue
|| (!base
) || (length
< (4096 * 4))) {
211 TraceFilterIdent
= -1;
212 TraceFilterChannel
= -1;
216 *(dword
*)base
= (dword
)DBG_MAGIC
; /* Store Magic */
217 base
+= sizeof(dword
);
218 length
-= sizeof(dword
);
220 *(dword
*)base
= 2048; /* Extension Field Length */
221 base
+= sizeof(dword
);
222 length
-= sizeof(dword
);
224 strcpy(base
, "KERNEL MODE BUFFER\n");
228 *(dword
*)base
= 0; /* Terminate extension */
229 base
+= sizeof(dword
);
230 length
-= sizeof(dword
);
232 *(void **)base
= (void *)(base
+ sizeof(void *)); /* Store Base */
233 base
+= sizeof(void *);
234 length
-= sizeof(void *);
236 dbg_queue
= (MSG_QUEUE
*)base
;
237 queueInit(dbg_queue
, base
+ sizeof(MSG_QUEUE
), length
- sizeof(MSG_QUEUE
) - 512);
238 external_dbg_queue
= 0;
241 external_dbg_queue
= 1; /* memory was located on the external device */
245 if (diva_os_initialize_spin_lock(&dbg_q_lock
, "dbg_init")) {
248 external_dbg_queue
= 0;
252 if (diva_os_initialize_spin_lock(&dbg_adapter_lock
, "dbg_init")) {
253 diva_os_destroy_spin_lock(&dbg_q_lock
, "dbg_init");
256 external_dbg_queue
= 0;
266 return address of internal queue or zero if queue
269 void *diva_maint_finit(void) {
270 void *ret
= (void *)dbg_base
;
277 diva_os_destroy_spin_lock(&dbg_q_lock
, "dbg_finit");
278 diva_os_destroy_spin_lock(&dbg_adapter_lock
, "dbg_finit");
281 if (external_dbg_queue
) {
284 external_dbg_queue
= 0;
286 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
287 if (clients
[i
].pmem
) {
288 diva_os_free(0, clients
[i
].pmem
);
297 Return amount of messages in debug queue
299 dword
diva_dbg_q_length(void) {
300 return (dbg_queue
? queueCount(dbg_queue
) : 0);
305 Lock message queue and return the pointer to the first
308 diva_dbg_entry_head_t
*diva_maint_get_message(word
*size
,
309 diva_os_spin_lock_magic_t
*old_irql
) {
310 diva_dbg_entry_head_t
*pmsg
= NULL
;
312 diva_os_enter_spin_lock(&dbg_q_lock
, old_irql
, "read");
314 diva_os_leave_spin_lock(&dbg_q_lock
, old_irql
, "read_busy");
319 if (!(pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, size
))) {
321 diva_os_leave_spin_lock(&dbg_q_lock
, old_irql
, "read_empty");
329 acknowledge last message and unlock queue
331 void diva_maint_ack_message(int do_release
,
332 diva_os_spin_lock_magic_t
*old_irql
) {
337 queueFreeMsg(dbg_queue
);
340 diva_os_leave_spin_lock(&dbg_q_lock
, old_irql
, "read_ack");
346 PRT COMP function used to register
347 with MAINT adapter or log in compatibility
348 mode in case older driver version is connected too
350 void diva_maint_prtComp(char *format
, ...) {
357 va_start(ap
, format
);
360 register to new log driver functions
362 if ((format
[0] == 0) && ((unsigned char)format
[1] == 255)) {
363 hDbg
= va_arg(ap
, void *); /* ptr to DbgHandle */
370 static void DI_register(void *arg
) {
371 diva_os_spin_lock_magic_t old_irql
;
374 int id
, free_id
= -1, best_id
= 0;
376 diva_os_get_time(&sec
, &usec
);
378 hDbg
= (pDbgHandle
)arg
;
380 Check for bad args, specially for the old obsolete debug handle
382 if ((hDbg
== NULL
) ||
383 ((hDbg
->id
== 0) && (((_OldDbgHandle_
*)hDbg
)->id
== -1)) ||
384 (hDbg
->Registered
!= 0)) {
388 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "register");
390 for (id
= 1; id
< ARRAY_SIZE(clients
); id
++) {
391 if (clients
[id
].hDbg
== hDbg
) {
393 driver already registered
395 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
398 if (clients
[id
].hDbg
) { /* slot is busy */
402 if (!strcmp(clients
[id
].drvName
, hDbg
->drvName
)) {
404 This driver was already registered with this name
405 and slot is still free - reuse it
410 if (!clients
[id
].hDbg
) { /* slot is busy */
416 diva_dbg_entry_head_t
*pmsg
= NULL
;
422 Register new driver with id == free_id
424 clients
[free_id
].hDbg
= hDbg
;
425 clients
[free_id
].sec
= sec
;
426 clients
[free_id
].usec
= usec
;
427 strcpy(clients
[free_id
].drvName
, hDbg
->drvName
);
429 clients
[free_id
].dbgMask
= hDbg
->dbgMask
;
431 hDbg
->dbgMask
|= clients
[free_id
].last_dbgMask
;
433 clients
[free_id
].last_dbgMask
= 0;
436 hDbg
->Registered
= DBG_HANDLE_REG_NEW
;
437 hDbg
->id
= (byte
)free_id
;
438 hDbg
->dbg_end
= DI_deregister
;
439 hDbg
->dbg_prt
= DI_format_locked
;
440 hDbg
->dbg_ev
= DiProcessEventLog
;
441 hDbg
->dbg_irq
= DI_format_locked
;
442 if (hDbg
->Version
> 0) {
443 hDbg
->dbg_old
= DI_format_old
;
445 hDbg
->next
= (pDbgHandle
)DBG_MAGIC
;
448 Log driver register, MAINT driver ID is '0'
450 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' registered",
451 free_id
, hDbg
->drvName
);
453 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
454 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
455 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
456 queueFreeMsg(dbg_queue
);
463 pmsg
->sequence
= dbg_sequence
++;
464 pmsg
->time_sec
= sec
;
465 pmsg
->time_usec
= usec
;
466 pmsg
->facility
= MSG_TYPE_STRING
;
468 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
470 pmsg
->data_length
= len
+ 1;
472 memcpy(&pmsg
[1], tmp
, len
+ 1);
473 queueCompleteMsg(pmsg
);
474 diva_maint_wakeup_read();
478 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
481 static void DI_deregister(pDbgHandle hDbg
) {
482 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
488 diva_os_get_time(&sec
, &usec
);
490 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read");
491 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "read");
493 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
494 if (clients
[i
].hDbg
== hDbg
) {
495 diva_dbg_entry_head_t
*pmsg
;
499 clients
[i
].hDbg
= NULL
;
503 hDbg
->dbg_end
= NULL
;
504 hDbg
->dbg_prt
= NULL
;
505 hDbg
->dbg_irq
= NULL
;
506 if (hDbg
->Version
> 0)
507 hDbg
->dbg_old
= NULL
;
508 hDbg
->Registered
= 0;
511 if (clients
[i
].pIdiLib
) {
512 (*(clients
[i
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[i
].pIdiLib
->hLib
);
513 clients
[i
].pIdiLib
= NULL
;
515 pmem
= clients
[i
].pmem
;
516 clients
[i
].pmem
= NULL
;
520 Log driver register, MAINT driver ID is '0'
522 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' de-registered",
525 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
526 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
527 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
528 queueFreeMsg(dbg_queue
);
535 pmsg
->sequence
= dbg_sequence
++;
536 pmsg
->time_sec
= sec
;
537 pmsg
->time_usec
= usec
;
538 pmsg
->facility
= MSG_TYPE_STRING
;
540 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
542 pmsg
->data_length
= len
+ 1;
544 memcpy(&pmsg
[1], tmp
, len
+ 1);
545 queueCompleteMsg(pmsg
);
546 diva_maint_wakeup_read();
553 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "read_ack");
554 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read_ack");
557 diva_os_free(0, pmem
);
561 static void DI_format_locked(unsigned short id
,
564 va_list argument_list
) {
565 DI_format(1, id
, type
, format
, argument_list
);
568 static void DI_format(int do_lock
,
573 diva_os_spin_lock_magic_t old_irql
;
575 diva_dbg_entry_head_t
*pmsg
= NULL
;
578 static char fmtBuf
[MSG_FRAME_MAX_SIZE
+ sizeof(*pmsg
) + 1];
582 if (diva_os_in_irq()) {
588 ((TraceFilter
[0] != 0) && ((TraceFilterIdent
< 0) || (TraceFilterChannel
< 0)))) {
594 diva_os_get_time(&sec
, &usec
);
597 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "format");
605 if (!(length
= va_arg(ap
, unsigned long))) {
608 if (length
> MaxDumpSize
) {
609 length
= MaxDumpSize
;
611 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
612 (word
)length
+ sizeof(*pmsg
)))) {
613 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
614 queueFreeMsg(dbg_queue
);
620 memcpy(&pmsg
[1], format
, length
);
621 pmsg
->sequence
= dbg_sequence
++;
622 pmsg
->time_sec
= sec
;
623 pmsg
->time_usec
= usec
;
624 pmsg
->facility
= MSG_TYPE_BINARY
;
625 pmsg
->dli
= type
; /* DLI_XXX */
626 pmsg
->drv_id
= id
; /* driver MAINT id */
628 pmsg
->data_length
= length
;
629 queueCompleteMsg(pmsg
);
635 data
= va_arg(ap
, char *);
636 code
= (unsigned short)va_arg(ap
, unsigned int);
637 length
= (unsigned long)va_arg(ap
, unsigned int);
639 if (length
> MaxXlogSize
)
640 length
= MaxXlogSize
;
642 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
643 (word
)length
+ sizeof(*pmsg
) + 2))) {
644 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
645 queueFreeMsg(dbg_queue
);
651 p
= (byte
*)&pmsg
[1];
653 p
[1] = (char)(code
>> 8);
654 if (data
&& length
) {
655 memcpy(&p
[2], &data
[0], length
);
659 pmsg
->sequence
= dbg_sequence
++;
660 pmsg
->time_sec
= sec
;
661 pmsg
->time_usec
= usec
;
662 pmsg
->facility
= MSG_TYPE_BINARY
;
663 pmsg
->dli
= type
; /* DLI_XXX */
664 pmsg
->drv_id
= id
; /* driver MAINT id */
666 pmsg
->data_length
= length
;
667 queueCompleteMsg(pmsg
);
688 if ((length
= (unsigned long)vsprintf(&fmtBuf
[0], format
, ap
)) > 0) {
689 length
+= (sizeof(*pmsg
) + 1);
691 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
693 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
694 queueFreeMsg(dbg_queue
);
700 pmsg
->sequence
= dbg_sequence
++;
701 pmsg
->time_sec
= sec
;
702 pmsg
->time_usec
= usec
;
703 pmsg
->facility
= MSG_TYPE_STRING
;
704 pmsg
->dli
= type
; /* DLI_XXX */
705 pmsg
->drv_id
= id
; /* driver MAINT id */
707 pmsg
->data_length
= length
- sizeof(*pmsg
);
709 memcpy(&pmsg
[1], fmtBuf
, pmsg
->data_length
);
710 queueCompleteMsg(pmsg
);
717 if (queueCount(dbg_queue
)) {
718 diva_maint_wakeup_read();
722 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "format");
727 Write driver ID and driver revision to callers buffer
729 int diva_get_driver_info(dword id
, byte
*data
, int data_length
) {
730 diva_os_spin_lock_magic_t old_irql
;
734 if (!data
|| !id
|| (data_length
< 17) ||
735 (id
>= ARRAY_SIZE(clients
))) {
739 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
741 if (clients
[id
].hDbg
) {
743 *p
++ = (byte
)clients
[id
].sec
; /* save seconds */
744 *p
++ = (byte
)(clients
[id
].sec
>> 8);
745 *p
++ = (byte
)(clients
[id
].sec
>> 16);
746 *p
++ = (byte
)(clients
[id
].sec
>> 24);
748 *p
++ = (byte
)(clients
[id
].usec
/ 1000); /* save mseconds */
749 *p
++ = (byte
)((clients
[id
].usec
/ 1000) >> 8);
750 *p
++ = (byte
)((clients
[id
].usec
/ 1000) >> 16);
751 *p
++ = (byte
)((clients
[id
].usec
/ 1000) >> 24);
755 if ((to_copy
= min(strlen(clients
[id
].drvName
), (size_t)(data_length
- 1)))) {
756 memcpy(p
, clients
[id
].drvName
, to_copy
);
758 data_length
-= to_copy
;
759 if ((data_length
>= 4) && clients
[id
].hDbg
->drvTag
[0]) {
762 if ((to_copy
= min(strlen(clients
[id
].hDbg
->drvTag
), (size_t)(data_length
- 2)))) {
763 memcpy(p
, clients
[id
].hDbg
->drvTag
, to_copy
);
765 data_length
-= to_copy
;
766 if (data_length
>= 2) {
776 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
781 int diva_get_driver_dbg_mask(dword id
, byte
*data
) {
782 diva_os_spin_lock_magic_t old_irql
;
785 if (!data
|| !id
|| (id
>= ARRAY_SIZE(clients
))) {
788 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
790 if (clients
[id
].hDbg
) {
792 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
);
793 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
>> 8);
794 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
>> 16);
795 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
>> 24);
798 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
803 int diva_set_driver_dbg_mask(dword id
, dword mask
) {
804 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
808 if (!id
|| (id
>= ARRAY_SIZE(clients
))) {
812 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
813 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "dbg mask");
815 if (clients
[id
].hDbg
) {
816 dword old_mask
= clients
[id
].hDbg
->dbgMask
;
818 clients
[id
].hDbg
->dbgMask
= mask
;
819 clients
[id
].last_dbgMask
= (clients
[id
].hDbg
->dbgMask
| clients
[id
].dbgMask
);
821 diva_change_management_debug_mask(&clients
[id
], old_mask
);
825 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "dbg mask");
827 if (clients
[id
].request_pending
) {
828 clients
[id
].request_pending
= 0;
829 (*(clients
[id
].request
))((ENTITY
*)(*(clients
[id
].pIdiLib
->DivaSTraceGetHandle
))(clients
[id
].pIdiLib
->hLib
));
832 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
837 static int diva_get_idi_adapter_info(IDI_CALL request
, dword
*serial
, dword
*logical
) {
838 IDI_SYNC_REQ sync_req
;
840 sync_req
.xdi_logical_adapter_number
.Req
= 0;
841 sync_req
.xdi_logical_adapter_number
.Rc
= IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER
;
842 (*request
)((ENTITY
*)&sync_req
);
843 *logical
= sync_req
.xdi_logical_adapter_number
.info
.logical_adapter_number
;
845 sync_req
.GetSerial
.Req
= 0;
846 sync_req
.GetSerial
.Rc
= IDI_SYNC_REQ_GET_SERIAL
;
847 sync_req
.GetSerial
.serial
= 0;
848 (*request
)((ENTITY
*)&sync_req
);
849 *serial
= sync_req
.GetSerial
.serial
;
855 Register XDI adapter as MAINT compatible driver
857 void diva_mnt_add_xdi_adapter(const DESCRIPTOR
*d
) {
858 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
859 dword sec
, usec
, logical
, serial
, org_mask
;
860 int id
, free_id
= -1;
862 diva_dbg_entry_head_t
*pmsg
= NULL
;
867 diva_os_get_time(&sec
, &usec
);
868 diva_get_idi_adapter_info(d
->request
, &serial
, &logical
);
869 if (serial
& 0xff000000) {
870 sprintf(tmp
, "ADAPTER:%d SN:%u-%d",
873 (byte
)(((serial
& 0xff000000) >> 24) + 1));
875 sprintf(tmp
, "ADAPTER:%d SN:%u", (int)logical
, serial
);
878 if (!(pmem
= diva_os_malloc(0, DivaSTraceGetMemotyRequirement(d
->channels
)))) {
881 memset(pmem
, 0x00, DivaSTraceGetMemotyRequirement(d
->channels
));
883 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
884 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "register");
886 for (id
= 1; id
< ARRAY_SIZE(clients
); id
++) {
887 if (clients
[id
].hDbg
&& (clients
[id
].request
== d
->request
)) {
888 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
889 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
890 diva_os_free(0, pmem
);
893 if (clients
[id
].hDbg
) { /* slot is busy */
899 if (!strcmp(clients
[id
].drvName
, tmp
)) {
901 This driver was already registered with this name
902 and slot is still free - reuse it
910 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
911 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
912 diva_os_free(0, pmem
);
917 clients
[id
].request
= d
->request
;
918 clients
[id
].request_pending
= 0;
919 clients
[id
].hDbg
= &clients
[id
].Dbg
;
920 clients
[id
].sec
= sec
;
921 clients
[id
].usec
= usec
;
922 strcpy(clients
[id
].drvName
, tmp
);
923 strcpy(clients
[id
].Dbg
.drvName
, tmp
);
924 clients
[id
].Dbg
.drvTag
[0] = 0;
925 clients
[id
].logical
= (int)logical
;
926 clients
[id
].channels
= (int)d
->channels
;
927 clients
[id
].dma_handle
= -1;
929 clients
[id
].Dbg
.dbgMask
= 0;
930 clients
[id
].dbgMask
= clients
[id
].Dbg
.dbgMask
;
932 clients
[id
].Dbg
.dbgMask
|= clients
[free_id
].last_dbgMask
;
934 clients
[id
].last_dbgMask
= 0;
936 clients
[id
].Dbg
.Registered
= DBG_HANDLE_REG_NEW
;
937 clients
[id
].Dbg
.id
= (byte
)id
;
938 clients
[id
].Dbg
.dbg_end
= DI_deregister
;
939 clients
[id
].Dbg
.dbg_prt
= DI_format_locked
;
940 clients
[id
].Dbg
.dbg_ev
= DiProcessEventLog
;
941 clients
[id
].Dbg
.dbg_irq
= DI_format_locked
;
942 clients
[id
].Dbg
.next
= (pDbgHandle
)DBG_MAGIC
;
945 diva_trace_library_user_interface_t diva_maint_user_ifc
= { &clients
[id
],
946 diva_maint_state_change_notify
,
947 diva_maint_trace_notify
,
951 Attach to adapter management interface
953 if ((clients
[id
].pIdiLib
=
954 DivaSTraceLibraryCreateInstance((int)logical
, &diva_maint_user_ifc
, pmem
))) {
955 if (((*(clients
[id
].pIdiLib
->DivaSTraceLibraryStart
))(clients
[id
].pIdiLib
->hLib
))) {
956 diva_mnt_internal_dprintf(0, DLI_ERR
, "Adapter(%d) Start failed", (int)logical
);
957 (*(clients
[id
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[id
].pIdiLib
->hLib
);
958 clients
[id
].pIdiLib
= NULL
;
961 diva_mnt_internal_dprintf(0, DLI_ERR
, "A(%d) management init failed", (int)logical
);
965 if (!clients
[id
].pIdiLib
) {
966 clients
[id
].request
= NULL
;
967 clients
[id
].request_pending
= 0;
968 clients
[id
].hDbg
= NULL
;
969 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
970 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
971 diva_os_free(0, pmem
);
976 Log driver register, MAINT driver ID is '0'
978 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' registered",
979 id
, clients
[id
].Dbg
.drvName
);
981 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
982 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
983 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
984 queueFreeMsg(dbg_queue
);
991 pmsg
->sequence
= dbg_sequence
++;
992 pmsg
->time_sec
= sec
;
993 pmsg
->time_usec
= usec
;
994 pmsg
->facility
= MSG_TYPE_STRING
;
996 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
998 pmsg
->data_length
= len
+ 1;
1000 memcpy(&pmsg
[1], tmp
, len
+ 1);
1001 queueCompleteMsg(pmsg
);
1002 diva_maint_wakeup_read();
1005 org_mask
= clients
[id
].Dbg
.dbgMask
;
1006 clients
[id
].Dbg
.dbgMask
= 0;
1008 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
1010 if (clients
[id
].request_pending
) {
1011 clients
[id
].request_pending
= 0;
1012 (*(clients
[id
].request
))((ENTITY
*)(*(clients
[id
].pIdiLib
->DivaSTraceGetHandle
))(clients
[id
].pIdiLib
->hLib
));
1015 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
1017 diva_set_driver_dbg_mask(id
, org_mask
);
1021 De-Register XDI adapter
1023 void diva_mnt_remove_xdi_adapter(const DESCRIPTOR
*d
) {
1024 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1030 diva_os_get_time(&sec
, &usec
);
1032 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read");
1033 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "read");
1035 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
1036 if (clients
[i
].hDbg
&& (clients
[i
].request
== d
->request
)) {
1037 diva_dbg_entry_head_t
*pmsg
;
1041 if (clients
[i
].pIdiLib
) {
1042 (*(clients
[i
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[i
].pIdiLib
->hLib
);
1043 clients
[i
].pIdiLib
= NULL
;
1045 pmem
= clients
[i
].pmem
;
1046 clients
[i
].pmem
= NULL
;
1049 clients
[i
].hDbg
= NULL
;
1050 clients
[i
].request_pending
= 0;
1051 if (clients
[i
].dma_handle
>= 0) {
1055 diva_free_dma_descriptor(clients
[i
].request
, clients
[i
].dma_handle
);
1056 clients
[i
].dma_handle
= -1;
1058 clients
[i
].request
= NULL
;
1061 Log driver register, MAINT driver ID is '0'
1063 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' de-registered",
1064 i
, clients
[i
].Dbg
.drvName
);
1066 memset(&clients
[i
].Dbg
, 0x00, sizeof(clients
[i
].Dbg
));
1068 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
1069 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
1070 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
1071 queueFreeMsg(dbg_queue
);
1078 pmsg
->sequence
= dbg_sequence
++;
1079 pmsg
->time_sec
= sec
;
1080 pmsg
->time_usec
= usec
;
1081 pmsg
->facility
= MSG_TYPE_STRING
;
1082 pmsg
->dli
= DLI_REG
;
1083 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
1085 pmsg
->data_length
= len
+ 1;
1087 memcpy(&pmsg
[1], tmp
, len
+ 1);
1088 queueCompleteMsg(pmsg
);
1089 diva_maint_wakeup_read();
1096 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "read_ack");
1097 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read_ack");
1100 diva_os_free(0, pmem
);
1104 /* ----------------------------------------------------------------
1105 Low level interface for management interface client
1106 ---------------------------------------------------------------- */
1108 Return handle to client structure
1110 void *SuperTraceOpenAdapter(int AdapterNumber
) {
1113 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
1114 if (clients
[i
].hDbg
&& clients
[i
].request
&& (clients
[i
].logical
== AdapterNumber
)) {
1115 return (&clients
[i
]);
1122 int SuperTraceCloseAdapter(void *AdapterHandle
) {
1126 int SuperTraceReadRequest(void *AdapterHandle
, const char *name
, byte
*data
) {
1127 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1129 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1130 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1131 byte
*xdata
= (byte
*)&pC
->xbuffer
[0];
1135 if (!strcmp(name
, "\\")) { /* Read ROOT */
1138 length
= SuperTraceCreateReadReq(xdata
, name
);
1139 single_p(xdata
, &length
, 0); /* End Of Message */
1143 e
->X
->PLength
= length
;
1144 e
->X
->P
= (byte
*)xdata
;
1146 pC
->request_pending
= 1;
1154 int SuperTraceGetNumberOfChannels(void *AdapterHandle
) {
1155 if (AdapterHandle
) {
1156 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1158 return (pC
->channels
);
1164 int SuperTraceASSIGN(void *AdapterHandle
, byte
*data
) {
1165 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1167 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1168 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1170 char buffer
[((sizeof(preq
->xdi_extended_features
) + 4) > sizeof(ENTITY
)) ? (sizeof(preq
->xdi_extended_features
) + 4) : sizeof(ENTITY
)];
1172 word assign_data_length
= 1;
1176 preq
= (IDI_SYNC_REQ
*)&buffer
[0];
1177 preq
->xdi_extended_features
.Req
= 0;
1178 preq
->xdi_extended_features
.Rc
= IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES
;
1179 preq
->xdi_extended_features
.info
.buffer_length_in_bytes
= sizeof(features
);
1180 preq
->xdi_extended_features
.info
.features
= &features
[0];
1182 (*(pC
->request
))((ENTITY
*)preq
);
1184 if ((features
[0] & DIVA_XDI_EXTENDED_FEATURES_VALID
) &&
1185 (features
[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA
)) {
1186 dword
uninitialized_var(rx_dma_magic
);
1187 if ((pC
->dma_handle
= diva_get_dma_descriptor(pC
->request
, &rx_dma_magic
)) >= 0) {
1188 pC
->xbuffer
[0] = LLI
;
1190 pC
->xbuffer
[2] = 0x40;
1191 pC
->xbuffer
[3] = (byte
)pC
->dma_handle
;
1192 pC
->xbuffer
[4] = (byte
)rx_dma_magic
;
1193 pC
->xbuffer
[5] = (byte
)(rx_dma_magic
>> 8);
1194 pC
->xbuffer
[6] = (byte
)(rx_dma_magic
>> 16);
1195 pC
->xbuffer
[7] = (byte
)(rx_dma_magic
>> 24);
1196 pC
->xbuffer
[8] = (byte
)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE
& 0xFF);
1197 pC
->xbuffer
[9] = (byte
)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE
>> 8);
1198 pC
->xbuffer
[10] = 0;
1200 assign_data_length
= 11;
1203 pC
->dma_handle
= -1;
1207 e
->callback
= diva_maint_xdi_cb
;
1212 e
->X
->PLength
= assign_data_length
;
1213 e
->X
->P
= (byte
*)&pC
->xbuffer
[0];
1215 pC
->request_pending
= 1;
1223 int SuperTraceREMOVE(void *AdapterHandle
) {
1224 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1226 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1227 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1234 e
->X
->P
= (byte
*)&pC
->xbuffer
[0];
1237 pC
->request_pending
= 1;
1245 int SuperTraceTraceOnRequest(void *hAdapter
, const char *name
, byte
*data
) {
1246 diva_maint_client_t
*pC
= (diva_maint_client_t
*)hAdapter
;
1248 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1249 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1250 byte
*xdata
= (byte
*)&pC
->xbuffer
[0];
1254 if (!strcmp(name
, "\\")) { /* Read ROOT */
1257 length
= SuperTraceCreateReadReq(xdata
, name
);
1258 single_p(xdata
, &length
, 0); /* End Of Message */
1259 e
->Req
= MAN_EVENT_ON
;
1261 e
->X
->PLength
= length
;
1262 e
->X
->P
= (byte
*)xdata
;
1264 pC
->request_pending
= 1;
1272 int SuperTraceWriteVar(void *AdapterHandle
,
1278 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1280 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1281 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1282 diva_man_var_header_t
*pVar
= (diva_man_var_header_t
*)&pC
->xbuffer
[0];
1283 word length
= SuperTraceCreateReadReq((byte
*)pVar
, name
);
1285 memcpy(&pC
->xbuffer
[length
], var
, var_length
);
1286 length
+= var_length
;
1287 pVar
->length
+= var_length
;
1288 pVar
->value_length
= var_length
;
1290 single_p((byte
*)pVar
, &length
, 0); /* End Of Message */
1294 e
->X
->PLength
= length
;
1295 e
->X
->P
= (byte
*)pVar
;
1297 pC
->request_pending
= 1;
1305 int SuperTraceExecuteRequest(void *AdapterHandle
,
1308 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1310 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1311 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1312 byte
*xdata
= (byte
*)&pC
->xbuffer
[0];
1315 length
= SuperTraceCreateReadReq(xdata
, name
);
1316 single_p(xdata
, &length
, 0); /* End Of Message */
1318 e
->Req
= MAN_EXECUTE
;
1320 e
->X
->PLength
= length
;
1321 e
->X
->P
= (byte
*)xdata
;
1323 pC
->request_pending
= 1;
1331 static word
SuperTraceCreateReadReq(byte
*P
, const char *path
) {
1335 var_length
= (byte
)strlen(path
);
1339 *P
++ = 0x80; /* MAN_IE */
1340 *P
++ = 0x00; /* Type */
1341 *P
++ = 0x00; /* Attribute */
1342 *P
++ = 0x00; /* Status */
1343 *P
++ = 0x00; /* Variable Length */
1345 memcpy(P
, path
, var_length
);
1347 *plen
= var_length
+ 0x06;
1349 return ((word
)(var_length
+ 0x08));
1352 static void single_p(byte
*P
, word
*PLength
, byte Id
) {
1353 P
[(*PLength
)++] = Id
;
1356 static void diva_maint_xdi_cb(ENTITY
*e
) {
1357 diva_strace_context_t
*pLib
= DIVAS_CONTAINING_RECORD(e
, diva_strace_context_t
, e
);
1358 diva_maint_client_t
*pC
;
1359 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1362 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "xdi_cb");
1363 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "xdi_cb");
1365 pC
= (diva_maint_client_t
*)pLib
->hAdapter
;
1367 if ((e
->complete
== 255) || (pC
->dma_handle
< 0)) {
1368 if ((*(pLib
->instance
.DivaSTraceMessageInput
))(&pLib
->instance
)) {
1369 diva_mnt_internal_dprintf(0, DLI_ERR
, "Trace internal library error");
1373 Process combined management interface indication
1375 if ((*(pLib
->instance
.DivaSTraceMessageInput
))(&pLib
->instance
)) {
1376 diva_mnt_internal_dprintf(0, DLI_ERR
, "Trace internal library error (DMA mode)");
1380 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "xdi_cb");
1383 if (pC
->request_pending
) {
1384 pC
->request_pending
= 0;
1385 (*(pC
->request
))(e
);
1388 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "xdi_cb");
1392 static void diva_maint_error(void *user_context
,
1393 diva_strace_library_interface_t
*hLib
,
1398 diva_mnt_internal_dprintf(0, DLI_ERR
,
1399 "Trace library error(%d) A(%d) %s %d", error
, Adapter
, file
, line
);
1402 static void print_ie(diva_trace_ie_t
*ie
, char *buffer
, int length
) {
1408 for (i
= 0; ((i
< ie
->length
) && (length
> 3)); i
++) {
1409 sprintf(buffer
, "%02x", ie
->data
[i
]);
1412 if (i
< (ie
->length
- 1)) {
1413 strcpy(buffer
, " ");
1421 static void diva_maint_state_change_notify(void *user_context
,
1422 diva_strace_library_interface_t
*hLib
,
1424 diva_trace_line_state_t
*channel
,
1425 int notify_subject
) {
1426 diva_maint_client_t
*pC
= (diva_maint_client_t
*)user_context
;
1427 diva_trace_fax_state_t
*fax
= &channel
->fax
;
1428 diva_trace_modem_state_t
*modem
= &channel
->modem
;
1435 switch (notify_subject
) {
1436 case DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE
: {
1437 int view
= (TraceFilter
[0] == 0);
1439 Process selective Trace
1441 if (channel
->Line
[0] == 'I' && channel
->Line
[1] == 'd' &&
1442 channel
->Line
[2] == 'l' && channel
->Line
[3] == 'e') {
1443 if ((TraceFilterIdent
== pC
->hDbg
->id
) && (TraceFilterChannel
== (int)channel
->ChannelNumber
)) {
1444 (*(hLib
->DivaSTraceSetBChannel
))(hLib
, (int)channel
->ChannelNumber
, 0);
1445 (*(hLib
->DivaSTraceSetAudioTap
))(hLib
, (int)channel
->ChannelNumber
, 0);
1446 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
, "Selective Trace OFF for Ch=%d",
1447 (int)channel
->ChannelNumber
);
1448 TraceFilterIdent
= -1;
1449 TraceFilterChannel
= -1;
1452 } else if (TraceFilter
[0] && (TraceFilterIdent
< 0) && !(diva_mnt_cmp_nmbr(&channel
->RemoteAddress
[0]) &&
1453 diva_mnt_cmp_nmbr(&channel
->LocalAddress
[0]))) {
1455 if ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_BCHANNEL
) != 0) { /* Activate B-channel trace */
1456 (*(hLib
->DivaSTraceSetBChannel
))(hLib
, (int)channel
->ChannelNumber
, 1);
1458 if ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_AUDIO
) != 0) { /* Activate AudioTap Trace */
1459 (*(hLib
->DivaSTraceSetAudioTap
))(hLib
, (int)channel
->ChannelNumber
, 1);
1462 TraceFilterIdent
= pC
->hDbg
->id
;
1463 TraceFilterChannel
= (int)channel
->ChannelNumber
;
1465 if (TraceFilterIdent
>= 0) {
1466 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
, "Selective Trace ON for Ch=%d",
1467 (int)channel
->ChannelNumber
);
1471 if (view
&& (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_LINE_EVENTS
)) {
1472 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Ch = %d",
1473 (int)channel
->ChannelNumber
);
1474 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Status = <%s>", &channel
->Line
[0]);
1475 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Layer1 = <%s>", &channel
->Framing
[0]);
1476 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Layer2 = <%s>", &channel
->Layer2
[0]);
1477 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Layer3 = <%s>", &channel
->Layer3
[0]);
1478 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L RAddr = <%s>",
1479 &channel
->RemoteAddress
[0]);
1480 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L RSAddr = <%s>",
1481 &channel
->RemoteSubAddress
[0]);
1482 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L LAddr = <%s>",
1483 &channel
->LocalAddress
[0]);
1484 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L LSAddr = <%s>",
1485 &channel
->LocalSubAddress
[0]);
1486 print_ie(&channel
->call_BC
, tmp
, sizeof(tmp
));
1487 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L BC = <%s>", tmp
);
1488 print_ie(&channel
->call_HLC
, tmp
, sizeof(tmp
));
1489 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L HLC = <%s>", tmp
);
1490 print_ie(&channel
->call_LLC
, tmp
, sizeof(tmp
));
1491 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L LLC = <%s>", tmp
);
1492 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L CR = 0x%x", channel
->CallReference
);
1493 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Disc = 0x%x",
1494 channel
->LastDisconnecCause
);
1495 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Owner = <%s>", &channel
->UserID
[0]);
1500 case DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE
:
1501 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_MDM_PROGRESS
) {
1503 int ch
= TraceFilterChannel
;
1504 int id
= TraceFilterIdent
;
1506 if ((id
>= 0) && (ch
>= 0) && (id
< ARRAY_SIZE(clients
)) &&
1507 (clients
[id
].Dbg
.id
== (byte
)id
) && (clients
[id
].pIdiLib
== hLib
)) {
1508 if (ch
!= (int)modem
->ChannelNumber
) {
1511 } else if (TraceFilter
[0] != 0) {
1517 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Ch = %lu",
1518 (int)modem
->ChannelNumber
);
1519 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Event = %lu", modem
->Event
);
1520 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Norm = %lu", modem
->Norm
);
1521 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Opts. = 0x%08x", modem
->Options
);
1522 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Tx = %lu Bps", modem
->TxSpeed
);
1523 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Rx = %lu Bps", modem
->RxSpeed
);
1524 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM RT = %lu mSec",
1525 modem
->RoundtripMsec
);
1526 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Sr = %lu", modem
->SymbolRate
);
1527 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Rxl = %d dBm", modem
->RxLeveldBm
);
1528 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM El = %d dBm", modem
->EchoLeveldBm
);
1529 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM SNR = %lu dB", modem
->SNRdb
);
1530 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM MAE = %lu", modem
->MAE
);
1531 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM LRet = %lu",
1532 modem
->LocalRetrains
);
1533 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM RRet = %lu",
1534 modem
->RemoteRetrains
);
1535 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM LRes = %lu", modem
->LocalResyncs
);
1536 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM RRes = %lu",
1537 modem
->RemoteResyncs
);
1538 if (modem
->Event
== 3) {
1539 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Disc = %lu", modem
->DiscReason
);
1542 if ((modem
->Event
== 3) && (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_MDM_STATISTICS
)) {
1543 (*(pC
->pIdiLib
->DivaSTraceGetModemStatistics
))(pC
->pIdiLib
);
1547 case DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE
:
1548 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_FAX_PROGRESS
) {
1550 int ch
= TraceFilterChannel
;
1551 int id
= TraceFilterIdent
;
1553 if ((id
>= 0) && (ch
>= 0) && (id
< ARRAY_SIZE(clients
)) &&
1554 (clients
[id
].Dbg
.id
== (byte
)id
) && (clients
[id
].pIdiLib
== hLib
)) {
1555 if (ch
!= (int)fax
->ChannelNumber
) {
1558 } else if (TraceFilter
[0] != 0) {
1563 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Ch = %lu", (int)fax
->ChannelNumber
);
1564 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Event = %lu", fax
->Event
);
1565 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Pages = %lu", fax
->Page_Counter
);
1566 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Feat. = 0x%08x", fax
->Features
);
1567 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX ID = <%s>", &fax
->Station_ID
[0]);
1568 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Saddr = <%s>", &fax
->Subaddress
[0]);
1569 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Pwd = <%s>", &fax
->Password
[0]);
1570 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Speed = %lu", fax
->Speed
);
1571 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Res. = 0x%08x", fax
->Resolution
);
1572 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Width = %lu", fax
->Paper_Width
);
1573 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Length= %lu", fax
->Paper_Length
);
1574 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX SLT = %lu", fax
->Scanline_Time
);
1575 if (fax
->Event
== 3) {
1576 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Disc = %lu", fax
->Disc_Reason
);
1579 if ((fax
->Event
== 3) && (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_FAX_STATISTICS
)) {
1580 (*(pC
->pIdiLib
->DivaSTraceGetFaxStatistics
))(pC
->pIdiLib
);
1584 case DIVA_SUPER_TRACE_INTERFACE_CHANGE
:
1585 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_EVENTS
) {
1586 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
,
1587 "Layer 1 -> [%s]", channel
->pInterface
->Layer1
);
1588 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
,
1589 "Layer 2 -> [%s]", channel
->pInterface
->Layer2
);
1593 case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE
:
1594 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_STATISTICS
) {
1598 if (channel
->pInterfaceStat
->inc
.Calls
) {
1599 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1600 "Inc Calls =%lu", channel
->pInterfaceStat
->inc
.Calls
);
1602 if (channel
->pInterfaceStat
->inc
.Connected
) {
1603 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1604 "Inc Connected =%lu", channel
->pInterfaceStat
->inc
.Connected
);
1606 if (channel
->pInterfaceStat
->inc
.User_Busy
) {
1607 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1608 "Inc Busy =%lu", channel
->pInterfaceStat
->inc
.User_Busy
);
1610 if (channel
->pInterfaceStat
->inc
.Call_Rejected
) {
1611 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1612 "Inc Rejected =%lu", channel
->pInterfaceStat
->inc
.Call_Rejected
);
1614 if (channel
->pInterfaceStat
->inc
.Wrong_Number
) {
1615 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1616 "Inc Wrong Nr =%lu", channel
->pInterfaceStat
->inc
.Wrong_Number
);
1618 if (channel
->pInterfaceStat
->inc
.Incompatible_Dst
) {
1619 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1620 "Inc Incomp. Dest =%lu", channel
->pInterfaceStat
->inc
.Incompatible_Dst
);
1622 if (channel
->pInterfaceStat
->inc
.Out_of_Order
) {
1623 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1624 "Inc Out of Order =%lu", channel
->pInterfaceStat
->inc
.Out_of_Order
);
1626 if (channel
->pInterfaceStat
->inc
.Ignored
) {
1627 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1628 "Inc Ignored =%lu", channel
->pInterfaceStat
->inc
.Ignored
);
1634 if (channel
->pInterfaceStat
->outg
.Calls
) {
1635 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1636 "Outg Calls =%lu", channel
->pInterfaceStat
->outg
.Calls
);
1638 if (channel
->pInterfaceStat
->outg
.Connected
) {
1639 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1640 "Outg Connected =%lu", channel
->pInterfaceStat
->outg
.Connected
);
1642 if (channel
->pInterfaceStat
->outg
.User_Busy
) {
1643 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1644 "Outg Busy =%lu", channel
->pInterfaceStat
->outg
.User_Busy
);
1646 if (channel
->pInterfaceStat
->outg
.No_Answer
) {
1647 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1648 "Outg No Answer =%lu", channel
->pInterfaceStat
->outg
.No_Answer
);
1650 if (channel
->pInterfaceStat
->outg
.Wrong_Number
) {
1651 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1652 "Outg Wrong Nr =%lu", channel
->pInterfaceStat
->outg
.Wrong_Number
);
1654 if (channel
->pInterfaceStat
->outg
.Call_Rejected
) {
1655 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1656 "Outg Rejected =%lu", channel
->pInterfaceStat
->outg
.Call_Rejected
);
1658 if (channel
->pInterfaceStat
->outg
.Other_Failures
) {
1659 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1660 "Outg Other Failures =%lu", channel
->pInterfaceStat
->outg
.Other_Failures
);
1665 case DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE
:
1666 if (channel
->pInterfaceStat
->mdm
.Disc_Normal
) {
1667 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1668 "MDM Disc Normal = %lu", channel
->pInterfaceStat
->mdm
.Disc_Normal
);
1670 if (channel
->pInterfaceStat
->mdm
.Disc_Unspecified
) {
1671 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1672 "MDM Disc Unsp. = %lu", channel
->pInterfaceStat
->mdm
.Disc_Unspecified
);
1674 if (channel
->pInterfaceStat
->mdm
.Disc_Busy_Tone
) {
1675 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1676 "MDM Disc Busy Tone = %lu", channel
->pInterfaceStat
->mdm
.Disc_Busy_Tone
);
1678 if (channel
->pInterfaceStat
->mdm
.Disc_Congestion
) {
1679 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1680 "MDM Disc Congestion = %lu", channel
->pInterfaceStat
->mdm
.Disc_Congestion
);
1682 if (channel
->pInterfaceStat
->mdm
.Disc_Carr_Wait
) {
1683 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1684 "MDM Disc Carrier Wait = %lu", channel
->pInterfaceStat
->mdm
.Disc_Carr_Wait
);
1686 if (channel
->pInterfaceStat
->mdm
.Disc_Trn_Timeout
) {
1687 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1688 "MDM Disc Trn. T.o. = %lu", channel
->pInterfaceStat
->mdm
.Disc_Trn_Timeout
);
1690 if (channel
->pInterfaceStat
->mdm
.Disc_Incompat
) {
1691 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1692 "MDM Disc Incompatible = %lu", channel
->pInterfaceStat
->mdm
.Disc_Incompat
);
1694 if (channel
->pInterfaceStat
->mdm
.Disc_Frame_Rej
) {
1695 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1696 "MDM Disc Frame Reject = %lu", channel
->pInterfaceStat
->mdm
.Disc_Frame_Rej
);
1698 if (channel
->pInterfaceStat
->mdm
.Disc_V42bis
) {
1699 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1700 "MDM Disc V.42bis = %lu", channel
->pInterfaceStat
->mdm
.Disc_V42bis
);
1704 case DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE
:
1705 if (channel
->pInterfaceStat
->fax
.Disc_Normal
) {
1706 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1707 "FAX Disc Normal = %lu", channel
->pInterfaceStat
->fax
.Disc_Normal
);
1709 if (channel
->pInterfaceStat
->fax
.Disc_Not_Ident
) {
1710 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1711 "FAX Disc Not Ident. = %lu", channel
->pInterfaceStat
->fax
.Disc_Not_Ident
);
1713 if (channel
->pInterfaceStat
->fax
.Disc_No_Response
) {
1714 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1715 "FAX Disc No Response = %lu", channel
->pInterfaceStat
->fax
.Disc_No_Response
);
1717 if (channel
->pInterfaceStat
->fax
.Disc_Retries
) {
1718 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1719 "FAX Disc Max Retries = %lu", channel
->pInterfaceStat
->fax
.Disc_Retries
);
1721 if (channel
->pInterfaceStat
->fax
.Disc_Unexp_Msg
) {
1722 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1723 "FAX Unexp. Msg. = %lu", channel
->pInterfaceStat
->fax
.Disc_Unexp_Msg
);
1725 if (channel
->pInterfaceStat
->fax
.Disc_No_Polling
) {
1726 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1727 "FAX Disc No Polling = %lu", channel
->pInterfaceStat
->fax
.Disc_No_Polling
);
1729 if (channel
->pInterfaceStat
->fax
.Disc_Training
) {
1730 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1731 "FAX Disc Training = %lu", channel
->pInterfaceStat
->fax
.Disc_Training
);
1733 if (channel
->pInterfaceStat
->fax
.Disc_Unexpected
) {
1734 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1735 "FAX Disc Unexpected = %lu", channel
->pInterfaceStat
->fax
.Disc_Unexpected
);
1737 if (channel
->pInterfaceStat
->fax
.Disc_Application
) {
1738 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1739 "FAX Disc Application = %lu", channel
->pInterfaceStat
->fax
.Disc_Application
);
1741 if (channel
->pInterfaceStat
->fax
.Disc_Incompat
) {
1742 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1743 "FAX Disc Incompatible = %lu", channel
->pInterfaceStat
->fax
.Disc_Incompat
);
1745 if (channel
->pInterfaceStat
->fax
.Disc_No_Command
) {
1746 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1747 "FAX Disc No Command = %lu", channel
->pInterfaceStat
->fax
.Disc_No_Command
);
1749 if (channel
->pInterfaceStat
->fax
.Disc_Long_Msg
) {
1750 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1751 "FAX Disc Long Msg. = %lu", channel
->pInterfaceStat
->fax
.Disc_Long_Msg
);
1753 if (channel
->pInterfaceStat
->fax
.Disc_Supervisor
) {
1754 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1755 "FAX Disc Supervisor = %lu", channel
->pInterfaceStat
->fax
.Disc_Supervisor
);
1757 if (channel
->pInterfaceStat
->fax
.Disc_SUB_SEP_PWD
) {
1758 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1759 "FAX Disc SUP SEP PWD = %lu", channel
->pInterfaceStat
->fax
.Disc_SUB_SEP_PWD
);
1761 if (channel
->pInterfaceStat
->fax
.Disc_Invalid_Msg
) {
1762 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1763 "FAX Disc Invalid Msg. = %lu", channel
->pInterfaceStat
->fax
.Disc_Invalid_Msg
);
1765 if (channel
->pInterfaceStat
->fax
.Disc_Page_Coding
) {
1766 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1767 "FAX Disc Page Coding = %lu", channel
->pInterfaceStat
->fax
.Disc_Page_Coding
);
1769 if (channel
->pInterfaceStat
->fax
.Disc_App_Timeout
) {
1770 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1771 "FAX Disc Appl. T.o. = %lu", channel
->pInterfaceStat
->fax
.Disc_App_Timeout
);
1773 if (channel
->pInterfaceStat
->fax
.Disc_Unspecified
) {
1774 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1775 "FAX Disc Unspec. = %lu", channel
->pInterfaceStat
->fax
.Disc_Unspecified
);
1782 Receive trace information from the Management Interface and store it in the
1783 internal trace buffer with MSG_TYPE_MLOG as is, without any filtering.
1784 Event Filtering and formatting is done in Management Interface self.
1786 static void diva_maint_trace_notify(void *user_context
,
1787 diva_strace_library_interface_t
*hLib
,
1791 diva_maint_client_t
*pC
= (diva_maint_client_t
*)user_context
;
1792 diva_dbg_entry_head_t
*pmsg
;
1795 int ch
= TraceFilterChannel
;
1796 int id
= TraceFilterIdent
;
1801 if ((id
>= 0) && (ch
>= 0) && (id
< ARRAY_SIZE(clients
)) &&
1802 (clients
[id
].Dbg
.id
== (byte
)id
) && (clients
[id
].pIdiLib
== hLib
)) {
1803 const char *p
= NULL
;
1805 MI_XLOG_HDR
*TrcData
= (MI_XLOG_HDR
*)xlog_buffer
;
1807 if (Adapter
!= clients
[id
].logical
) {
1808 return; /* Ignore all trace messages from other adapters */
1811 if (TrcData
->code
== 24) {
1812 p
= (char *)&TrcData
->code
;
1817 All L1 messages start as [dsp,ch], so we can filter this information
1818 and filter out all messages that use different channel
1820 if (p
&& p
[0] == '[') {
1823 ch_value
= *p
- '0';
1824 } else if (p
[3] == ',') {
1826 ch_value
= *p
- '0';
1828 if (ch_value
>= 0) {
1830 ch_value
= ch_value
* 10 + p
[1] - '0';
1832 if (ch_value
!= ch
) {
1833 return; /* Ignore other channels */
1838 } else if (TraceFilter
[0] != 0) {
1839 return; /* Ignore trace if trace filter is activated, but idle */
1842 diva_os_get_time(&sec
, &usec
);
1844 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
1845 (word
)length
+ sizeof(*pmsg
)))) {
1846 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
1847 queueFreeMsg(dbg_queue
);
1853 memcpy(&pmsg
[1], xlog_buffer
, length
);
1854 pmsg
->sequence
= dbg_sequence
++;
1855 pmsg
->time_sec
= sec
;
1856 pmsg
->time_usec
= usec
;
1857 pmsg
->facility
= MSG_TYPE_MLOG
;
1858 pmsg
->dli
= pC
->logical
;
1859 pmsg
->drv_id
= pC
->hDbg
->id
;
1861 pmsg
->data_length
= length
;
1862 queueCompleteMsg(pmsg
);
1863 if (queueCount(dbg_queue
)) {
1864 diva_maint_wakeup_read();
1871 Convert MAINT trace mask to management interface trace mask/work/facility and
1872 issue command to management interface
1874 static void diva_change_management_debug_mask(diva_maint_client_t
*pC
, dword old_mask
) {
1875 if (pC
->request
&& pC
->hDbg
&& pC
->pIdiLib
) {
1876 dword changed
= pC
->hDbg
->dbgMask
^ old_mask
;
1878 if (changed
& DIVA_MGT_DBG_TRACE
) {
1879 (*(pC
->pIdiLib
->DivaSTraceSetInfo
))(pC
->pIdiLib
,
1880 (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_TRACE
) != 0);
1882 if (changed
& DIVA_MGT_DBG_DCHAN
) {
1883 (*(pC
->pIdiLib
->DivaSTraceSetDChannel
))(pC
->pIdiLib
,
1884 (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_DCHAN
) != 0);
1886 if (!TraceFilter
[0]) {
1887 if (changed
& DIVA_MGT_DBG_IFC_BCHANNEL
) {
1888 int i
, state
= ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_BCHANNEL
) != 0);
1890 for (i
= 0; i
< pC
->channels
; i
++) {
1891 (*(pC
->pIdiLib
->DivaSTraceSetBChannel
))(pC
->pIdiLib
, i
+ 1, state
);
1894 if (changed
& DIVA_MGT_DBG_IFC_AUDIO
) {
1895 int i
, state
= ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_AUDIO
) != 0);
1897 for (i
= 0; i
< pC
->channels
; i
++) {
1898 (*(pC
->pIdiLib
->DivaSTraceSetAudioTap
))(pC
->pIdiLib
, i
+ 1, state
);
1906 void diva_mnt_internal_dprintf(dword drv_id
, dword type
, char *fmt
, ...) {
1910 DI_format(0, (word
)drv_id
, (int)type
, fmt
, ap
);
1915 Shutdown all adapters before driver removal
1917 int diva_mnt_shutdown_xdi_adapters(void) {
1918 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1923 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
1926 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "unload");
1927 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "unload");
1929 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
) {
1930 if ((*(clients
[i
].pIdiLib
->DivaSTraceLibraryStop
))(clients
[i
].pIdiLib
) == 1) {
1932 Adapter removal complete
1934 if (clients
[i
].pIdiLib
) {
1935 (*(clients
[i
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[i
].pIdiLib
->hLib
);
1936 clients
[i
].pIdiLib
= NULL
;
1938 pmem
= clients
[i
].pmem
;
1939 clients
[i
].pmem
= NULL
;
1941 clients
[i
].hDbg
= NULL
;
1942 clients
[i
].request_pending
= 0;
1944 if (clients
[i
].dma_handle
>= 0) {
1948 diva_free_dma_descriptor(clients
[i
].request
, clients
[i
].dma_handle
);
1949 clients
[i
].dma_handle
= -1;
1951 clients
[i
].request
= NULL
;
1957 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "unload");
1958 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
&& clients
[i
].request_pending
) {
1959 clients
[i
].request_pending
= 0;
1960 (*(clients
[i
].request
))((ENTITY
*)(*(clients
[i
].pIdiLib
->DivaSTraceGetHandle
))(clients
[i
].pIdiLib
->hLib
));
1961 if (clients
[i
].dma_handle
>= 0) {
1962 diva_free_dma_descriptor(clients
[i
].request
, clients
[i
].dma_handle
);
1963 clients
[i
].dma_handle
= -1;
1966 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "unload");
1969 diva_os_free(0, pmem
);
1977 Set/Read the trace filter used for selective tracing.
1978 Affects B- and Audio Tap trace mask at run time
1980 int diva_set_trace_filter(int filter_length
, const char *filter
) {
1981 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1982 int i
, ch
, on
, client_b_on
, client_atap_on
;
1984 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
1985 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
1987 if (filter_length
<= DIVA_MAX_SELECTIVE_FILTER_LENGTH
) {
1988 memcpy(&TraceFilter
[0], filter
, filter_length
);
1989 if (TraceFilter
[filter_length
]) {
1990 TraceFilter
[filter_length
] = 0;
1992 if (TraceFilter
[0] == '*') {
1999 TraceFilterIdent
= -1;
2000 TraceFilterChannel
= -1;
2002 on
= (TraceFilter
[0] == 0);
2004 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
2005 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
) {
2006 client_b_on
= on
&& ((clients
[i
].hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_BCHANNEL
) != 0);
2007 client_atap_on
= on
&& ((clients
[i
].hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_AUDIO
) != 0);
2008 for (ch
= 0; ch
< clients
[i
].channels
; ch
++) {
2009 (*(clients
[i
].pIdiLib
->DivaSTraceSetBChannel
))(clients
[i
].pIdiLib
->hLib
, ch
+ 1, client_b_on
);
2010 (*(clients
[i
].pIdiLib
->DivaSTraceSetAudioTap
))(clients
[i
].pIdiLib
->hLib
, ch
+ 1, client_atap_on
);
2015 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
2016 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
&& clients
[i
].request_pending
) {
2017 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
2018 clients
[i
].request_pending
= 0;
2019 (*(clients
[i
].request
))((ENTITY
*)(*(clients
[i
].pIdiLib
->DivaSTraceGetHandle
))(clients
[i
].pIdiLib
->hLib
));
2020 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
2024 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
2025 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
2027 return (filter_length
);
2030 int diva_get_trace_filter(int max_length
, char *filter
) {
2031 diva_os_spin_lock_magic_t old_irql
;
2034 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "read_filter");
2035 len
= strlen(&TraceFilter
[0]) + 1;
2036 if (max_length
>= len
) {
2037 memcpy(filter
, &TraceFilter
[0], len
);
2039 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "read_filter");
2044 static int diva_dbg_cmp_key(const char *ref
, const char *key
) {
2045 while (*key
&& (*ref
++ == *key
++));
2046 return (!*key
&& !*ref
);
2050 In case trace filter starts with "C" character then
2051 all following characters are interpreted as command.
2052 Followings commands are available:
2053 - single, trace single call at time, independent from CPN/CiPN
2055 static int diva_mnt_cmp_nmbr(const char *nmbr
) {
2056 const char *ref
= &TraceFilter
[0];
2057 int ref_len
= strlen(&TraceFilter
[0]), nmbr_len
= strlen(nmbr
);
2059 if (ref
[0] == 'C') {
2060 if (diva_dbg_cmp_key(&ref
[1], "single")) {
2066 if (!ref_len
|| (ref_len
> nmbr_len
)) {
2070 nmbr
= nmbr
+ nmbr_len
- 1;
2071 ref
= ref
+ ref_len
- 1;
2074 if (*nmbr
-- != *ref
--) {
2082 static int diva_get_dma_descriptor(IDI_CALL request
, dword
*dma_magic
) {
2084 IDI_SYNC_REQ
*pReq
= (IDI_SYNC_REQ
*)&e
;
2090 pReq
->xdi_dma_descriptor_operation
.Req
= 0;
2091 pReq
->xdi_dma_descriptor_operation
.Rc
= IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION
;
2093 pReq
->xdi_dma_descriptor_operation
.info
.operation
= IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC
;
2094 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
= -1;
2095 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_address
= NULL
;
2096 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
= 0;
2098 (*request
)((ENTITY
*)pReq
);
2100 if (!pReq
->xdi_dma_descriptor_operation
.info
.operation
&&
2101 (pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
>= 0) &&
2102 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
) {
2103 *dma_magic
= pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
;
2104 return (pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
);
2110 static void diva_free_dma_descriptor(IDI_CALL request
, int nr
) {
2112 IDI_SYNC_REQ
*pReq
= (IDI_SYNC_REQ
*)&e
;
2114 if (!request
|| (nr
< 0)) {
2118 pReq
->xdi_dma_descriptor_operation
.Req
= 0;
2119 pReq
->xdi_dma_descriptor_operation
.Rc
= IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION
;
2121 pReq
->xdi_dma_descriptor_operation
.info
.operation
= IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE
;
2122 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
= nr
;
2123 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_address
= NULL
;
2124 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
= 0;
2126 (*request
)((ENTITY
*)pReq
);