1 // SPDX-License-Identifier: GPL-2.0
14 #define DBG_MAGIC (0x47114711L)
16 static void DI_register(void *arg
);
17 static void DI_deregister(pDbgHandle hDbg
);
18 static void DI_format(int do_lock
, word id
, int type
, char *format
, va_list argument_list
);
19 static void DI_format_locked(word id
, int type
, char *format
, va_list argument_list
);
20 static void DI_format_old(word id
, char *format
, va_list ap
) { }
21 static void DiProcessEventLog(unsigned short id
, unsigned long msgID
, va_list ap
) { }
22 static void single_p(byte
*P
, word
*PLength
, byte Id
);
23 static void diva_maint_xdi_cb(ENTITY
*e
);
24 static word
SuperTraceCreateReadReq(byte
*P
, const char *path
);
25 static int diva_mnt_cmp_nmbr(const char *nmbr
);
26 static void diva_free_dma_descriptor(IDI_CALL request
, int nr
);
27 static int diva_get_dma_descriptor(IDI_CALL request
, dword
*dma_magic
);
28 void diva_mnt_internal_dprintf(dword drv_id
, dword type
, char *p
, ...);
30 static dword MaxDumpSize
= 256;
31 static dword MaxXlogSize
= 2 + 128;
32 static char TraceFilter
[DIVA_MAX_SELECTIVE_FILTER_LENGTH
+ 1];
33 static int TraceFilterIdent
= -1;
34 static int TraceFilterChannel
= -1;
36 typedef struct _diva_maint_client
{
47 diva_strace_library_interface_t
*pIdiLib
;
49 char xbuffer
[2048 + 512];
53 } diva_maint_client_t
;
54 static diva_maint_client_t clients
[MAX_DESCRIPTORS
];
56 static void diva_change_management_debug_mask(diva_maint_client_t
*pC
, dword old_mask
);
58 static void diva_maint_error(void *user_context
,
59 diva_strace_library_interface_t
*hLib
,
64 static void diva_maint_state_change_notify(void *user_context
,
65 diva_strace_library_interface_t
*hLib
,
67 diva_trace_line_state_t
*channel
,
69 static void diva_maint_trace_notify(void *user_context
,
70 diva_strace_library_interface_t
*hLib
,
77 typedef struct MSG_QUEUE
{
78 dword Size
; /* total size of queue (constant) */
79 byte
*Base
; /* lowest address (constant) */
80 byte
*High
; /* Base + Size (constant) */
81 byte
*Head
; /* first message in queue (if any) */
82 byte
*Tail
; /* first free position */
83 byte
*Wrap
; /* current wraparound position */
84 dword Count
; /* current no of bytes in queue */
87 typedef struct MSG_HEAD
{
88 volatile dword Size
; /* size of data following MSG_HEAD */
89 #define MSG_INCOMPLETE 0x8000 /* ored to Size until queueCompleteMsg */
92 #define queueCompleteMsg(p) do { ((MSG_HEAD *)p - 1)->Size &= ~MSG_INCOMPLETE; } while (0)
93 #define queueCount(q) ((q)->Count)
94 #define MSG_NEED(size) \
95 ((sizeof(MSG_HEAD) + size + sizeof(dword) - 1) & ~(sizeof(dword) - 1))
97 static void queueInit(MSG_QUEUE
*Q
, byte
*Buffer
, dword sizeBuffer
) {
99 Q
->Base
= Q
->Head
= Q
->Tail
= Buffer
;
100 Q
->High
= Buffer
+ sizeBuffer
;
105 static byte
*queueAllocMsg(MSG_QUEUE
*Q
, word size
) {
106 /* Allocate 'size' bytes at tail of queue which will be filled later
107 * directly with callers own message header info and/or message.
108 * An 'alloced' message is marked incomplete by oring the 'Size' field
109 * with MSG_INCOMPLETE.
110 * This must be reset via queueCompleteMsg() after the message is filled.
111 * As long as a message is marked incomplete queuePeekMsg() will return
112 * a 'queue empty' condition when it reaches such a message. */
115 word need
= MSG_NEED(size
);
117 if (Q
->Tail
== Q
->Head
) {
118 if (Q
->Wrap
|| need
> Q
->Size
) {
119 return NULL
; /* full */
121 goto alloc
; /* empty */
124 if (Q
->Tail
> Q
->Head
) {
125 if (Q
->Tail
+ need
<= Q
->High
) goto alloc
; /* append */
126 if (Q
->Base
+ need
> Q
->Head
) {
127 return NULL
; /* too much */
129 /* wraparound the queue (but not the message) */
135 if (Q
->Tail
+ need
> Q
->Head
) {
136 return NULL
; /* too much */
140 Msg
= (MSG_HEAD
*)Q
->Tail
;
142 Msg
->Size
= size
| MSG_INCOMPLETE
;
149 return ((byte
*)(Msg
+ 1));
152 static void queueFreeMsg(MSG_QUEUE
*Q
) {
153 /* Free the message at head of queue */
155 word size
= ((MSG_HEAD
*)Q
->Head
)->Size
& ~MSG_INCOMPLETE
;
157 Q
->Head
+= MSG_NEED(size
);
161 if (Q
->Head
>= Q
->Wrap
) {
165 } else if (Q
->Head
>= Q
->Tail
) {
166 Q
->Head
= Q
->Tail
= Q
->Base
;
170 static byte
*queuePeekMsg(MSG_QUEUE
*Q
, word
*size
) {
171 /* Show the first valid message in queue BUT DON'T free the message.
172 * After looking on the message contents it can be freed queueFreeMsg()
173 * or simply remain in message queue. */
175 MSG_HEAD
*Msg
= (MSG_HEAD
*)Q
->Head
;
177 if (((byte
*)Msg
== Q
->Tail
&& !Q
->Wrap
) ||
178 (Msg
->Size
& MSG_INCOMPLETE
)) {
182 return ((byte
*)(Msg
+ 1));
189 static MSG_QUEUE
*dbg_queue
;
190 static byte
*dbg_base
;
191 static int external_dbg_queue
;
192 static diva_os_spin_lock_t dbg_q_lock
;
193 static diva_os_spin_lock_t dbg_adapter_lock
;
194 static int dbg_q_busy
;
195 static volatile dword dbg_sequence
;
199 Initialize run time queue structures.
200 base: base of the message queue
201 length: length of the message queue
202 do_init: perfor queue reset
204 return: zero on success, -1 on error
206 int diva_maint_init(byte
*base
, unsigned long length
, int do_init
) {
207 if (dbg_queue
|| (!base
) || (length
< (4096 * 4))) {
212 TraceFilterIdent
= -1;
213 TraceFilterChannel
= -1;
217 *(dword
*)base
= (dword
)DBG_MAGIC
; /* Store Magic */
218 base
+= sizeof(dword
);
219 length
-= sizeof(dword
);
221 *(dword
*)base
= 2048; /* Extension Field Length */
222 base
+= sizeof(dword
);
223 length
-= sizeof(dword
);
225 strcpy(base
, "KERNEL MODE BUFFER\n");
229 *(dword
*)base
= 0; /* Terminate extension */
230 base
+= sizeof(dword
);
231 length
-= sizeof(dword
);
233 *(void **)base
= (void *)(base
+ sizeof(void *)); /* Store Base */
234 base
+= sizeof(void *);
235 length
-= sizeof(void *);
237 dbg_queue
= (MSG_QUEUE
*)base
;
238 queueInit(dbg_queue
, base
+ sizeof(MSG_QUEUE
), length
- sizeof(MSG_QUEUE
) - 512);
239 external_dbg_queue
= 0;
242 external_dbg_queue
= 1; /* memory was located on the external device */
246 if (diva_os_initialize_spin_lock(&dbg_q_lock
, "dbg_init")) {
249 external_dbg_queue
= 0;
253 if (diva_os_initialize_spin_lock(&dbg_adapter_lock
, "dbg_init")) {
254 diva_os_destroy_spin_lock(&dbg_q_lock
, "dbg_init");
257 external_dbg_queue
= 0;
267 return address of internal queue or zero if queue
270 void *diva_maint_finit(void) {
271 void *ret
= (void *)dbg_base
;
278 diva_os_destroy_spin_lock(&dbg_q_lock
, "dbg_finit");
279 diva_os_destroy_spin_lock(&dbg_adapter_lock
, "dbg_finit");
282 if (external_dbg_queue
) {
285 external_dbg_queue
= 0;
287 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
288 if (clients
[i
].pmem
) {
289 diva_os_free(0, clients
[i
].pmem
);
298 Return amount of messages in debug queue
300 dword
diva_dbg_q_length(void) {
301 return (dbg_queue
? queueCount(dbg_queue
) : 0);
306 Lock message queue and return the pointer to the first
309 diva_dbg_entry_head_t
*diva_maint_get_message(word
*size
,
310 diva_os_spin_lock_magic_t
*old_irql
) {
311 diva_dbg_entry_head_t
*pmsg
= NULL
;
313 diva_os_enter_spin_lock(&dbg_q_lock
, old_irql
, "read");
315 diva_os_leave_spin_lock(&dbg_q_lock
, old_irql
, "read_busy");
320 if (!(pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, size
))) {
322 diva_os_leave_spin_lock(&dbg_q_lock
, old_irql
, "read_empty");
330 acknowledge last message and unlock queue
332 void diva_maint_ack_message(int do_release
,
333 diva_os_spin_lock_magic_t
*old_irql
) {
338 queueFreeMsg(dbg_queue
);
341 diva_os_leave_spin_lock(&dbg_q_lock
, old_irql
, "read_ack");
347 PRT COMP function used to register
348 with MAINT adapter or log in compatibility
349 mode in case older driver version is connected too
351 void diva_maint_prtComp(char *format
, ...) {
358 va_start(ap
, format
);
361 register to new log driver functions
363 if ((format
[0] == 0) && ((unsigned char)format
[1] == 255)) {
364 hDbg
= va_arg(ap
, void *); /* ptr to DbgHandle */
371 static void DI_register(void *arg
) {
372 diva_os_spin_lock_magic_t old_irql
;
375 int id
, free_id
= -1, best_id
= 0;
377 diva_os_get_time(&sec
, &usec
);
379 hDbg
= (pDbgHandle
)arg
;
381 Check for bad args, specially for the old obsolete debug handle
383 if ((hDbg
== NULL
) ||
384 ((hDbg
->id
== 0) && (((_OldDbgHandle_
*)hDbg
)->id
== -1)) ||
385 (hDbg
->Registered
!= 0)) {
389 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "register");
391 for (id
= 1; id
< ARRAY_SIZE(clients
); id
++) {
392 if (clients
[id
].hDbg
== hDbg
) {
394 driver already registered
396 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
399 if (clients
[id
].hDbg
) { /* slot is busy */
403 if (!strcmp(clients
[id
].drvName
, hDbg
->drvName
)) {
405 This driver was already registered with this name
406 and slot is still free - reuse it
411 if (!clients
[id
].hDbg
) { /* slot is busy */
417 diva_dbg_entry_head_t
*pmsg
= NULL
;
423 Register new driver with id == free_id
425 clients
[free_id
].hDbg
= hDbg
;
426 clients
[free_id
].sec
= sec
;
427 clients
[free_id
].usec
= usec
;
428 strcpy(clients
[free_id
].drvName
, hDbg
->drvName
);
430 clients
[free_id
].dbgMask
= hDbg
->dbgMask
;
432 hDbg
->dbgMask
|= clients
[free_id
].last_dbgMask
;
434 clients
[free_id
].last_dbgMask
= 0;
437 hDbg
->Registered
= DBG_HANDLE_REG_NEW
;
438 hDbg
->id
= (byte
)free_id
;
439 hDbg
->dbg_end
= DI_deregister
;
440 hDbg
->dbg_prt
= DI_format_locked
;
441 hDbg
->dbg_ev
= DiProcessEventLog
;
442 hDbg
->dbg_irq
= DI_format_locked
;
443 if (hDbg
->Version
> 0) {
444 hDbg
->dbg_old
= DI_format_old
;
446 hDbg
->next
= (pDbgHandle
)DBG_MAGIC
;
449 Log driver register, MAINT driver ID is '0'
451 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' registered",
452 free_id
, hDbg
->drvName
);
454 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
455 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
456 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
457 queueFreeMsg(dbg_queue
);
464 pmsg
->sequence
= dbg_sequence
++;
465 pmsg
->time_sec
= sec
;
466 pmsg
->time_usec
= usec
;
467 pmsg
->facility
= MSG_TYPE_STRING
;
469 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
471 pmsg
->data_length
= len
+ 1;
473 memcpy(&pmsg
[1], tmp
, len
+ 1);
474 queueCompleteMsg(pmsg
);
475 diva_maint_wakeup_read();
479 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
482 static void DI_deregister(pDbgHandle hDbg
) {
483 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
489 diva_os_get_time(&sec
, &usec
);
491 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read");
492 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "read");
494 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
495 if (clients
[i
].hDbg
== hDbg
) {
496 diva_dbg_entry_head_t
*pmsg
;
500 clients
[i
].hDbg
= NULL
;
504 hDbg
->dbg_end
= NULL
;
505 hDbg
->dbg_prt
= NULL
;
506 hDbg
->dbg_irq
= NULL
;
507 if (hDbg
->Version
> 0)
508 hDbg
->dbg_old
= NULL
;
509 hDbg
->Registered
= 0;
512 if (clients
[i
].pIdiLib
) {
513 (*(clients
[i
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[i
].pIdiLib
->hLib
);
514 clients
[i
].pIdiLib
= NULL
;
516 pmem
= clients
[i
].pmem
;
517 clients
[i
].pmem
= NULL
;
521 Log driver register, MAINT driver ID is '0'
523 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' de-registered",
526 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
527 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
528 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
529 queueFreeMsg(dbg_queue
);
536 pmsg
->sequence
= dbg_sequence
++;
537 pmsg
->time_sec
= sec
;
538 pmsg
->time_usec
= usec
;
539 pmsg
->facility
= MSG_TYPE_STRING
;
541 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
543 pmsg
->data_length
= len
+ 1;
545 memcpy(&pmsg
[1], tmp
, len
+ 1);
546 queueCompleteMsg(pmsg
);
547 diva_maint_wakeup_read();
554 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "read_ack");
555 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read_ack");
558 diva_os_free(0, pmem
);
562 static void DI_format_locked(unsigned short id
,
565 va_list argument_list
) {
566 DI_format(1, id
, type
, format
, argument_list
);
569 static void DI_format(int do_lock
,
574 diva_os_spin_lock_magic_t old_irql
;
576 diva_dbg_entry_head_t
*pmsg
= NULL
;
579 static char fmtBuf
[MSG_FRAME_MAX_SIZE
+ sizeof(*pmsg
) + 1];
583 if (diva_os_in_irq()) {
589 ((TraceFilter
[0] != 0) && ((TraceFilterIdent
< 0) || (TraceFilterChannel
< 0)))) {
595 diva_os_get_time(&sec
, &usec
);
598 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "format");
606 if (!(length
= va_arg(ap
, unsigned long))) {
609 if (length
> MaxDumpSize
) {
610 length
= MaxDumpSize
;
612 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
613 (word
)length
+ sizeof(*pmsg
)))) {
614 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
615 queueFreeMsg(dbg_queue
);
621 memcpy(&pmsg
[1], format
, length
);
622 pmsg
->sequence
= dbg_sequence
++;
623 pmsg
->time_sec
= sec
;
624 pmsg
->time_usec
= usec
;
625 pmsg
->facility
= MSG_TYPE_BINARY
;
626 pmsg
->dli
= type
; /* DLI_XXX */
627 pmsg
->drv_id
= id
; /* driver MAINT id */
629 pmsg
->data_length
= length
;
630 queueCompleteMsg(pmsg
);
636 data
= va_arg(ap
, char *);
637 code
= (unsigned short)va_arg(ap
, unsigned int);
638 length
= (unsigned long)va_arg(ap
, unsigned int);
640 if (length
> MaxXlogSize
)
641 length
= MaxXlogSize
;
643 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
644 (word
)length
+ sizeof(*pmsg
) + 2))) {
645 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
646 queueFreeMsg(dbg_queue
);
652 p
= (byte
*)&pmsg
[1];
654 p
[1] = (char)(code
>> 8);
655 if (data
&& length
) {
656 memcpy(&p
[2], &data
[0], length
);
660 pmsg
->sequence
= dbg_sequence
++;
661 pmsg
->time_sec
= sec
;
662 pmsg
->time_usec
= usec
;
663 pmsg
->facility
= MSG_TYPE_BINARY
;
664 pmsg
->dli
= type
; /* DLI_XXX */
665 pmsg
->drv_id
= id
; /* driver MAINT id */
667 pmsg
->data_length
= length
;
668 queueCompleteMsg(pmsg
);
689 if ((length
= (unsigned long)vsprintf(&fmtBuf
[0], format
, ap
)) > 0) {
690 length
+= (sizeof(*pmsg
) + 1);
692 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
694 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
695 queueFreeMsg(dbg_queue
);
701 pmsg
->sequence
= dbg_sequence
++;
702 pmsg
->time_sec
= sec
;
703 pmsg
->time_usec
= usec
;
704 pmsg
->facility
= MSG_TYPE_STRING
;
705 pmsg
->dli
= type
; /* DLI_XXX */
706 pmsg
->drv_id
= id
; /* driver MAINT id */
708 pmsg
->data_length
= length
- sizeof(*pmsg
);
710 memcpy(&pmsg
[1], fmtBuf
, pmsg
->data_length
);
711 queueCompleteMsg(pmsg
);
718 if (queueCount(dbg_queue
)) {
719 diva_maint_wakeup_read();
723 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "format");
728 Write driver ID and driver revision to callers buffer
730 int diva_get_driver_info(dword id
, byte
*data
, int data_length
) {
731 diva_os_spin_lock_magic_t old_irql
;
735 if (!data
|| !id
|| (data_length
< 17) ||
736 (id
>= ARRAY_SIZE(clients
))) {
740 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
742 if (clients
[id
].hDbg
) {
744 *p
++ = (byte
)clients
[id
].sec
; /* save seconds */
745 *p
++ = (byte
)(clients
[id
].sec
>> 8);
746 *p
++ = (byte
)(clients
[id
].sec
>> 16);
747 *p
++ = (byte
)(clients
[id
].sec
>> 24);
749 *p
++ = (byte
)(clients
[id
].usec
/ 1000); /* save mseconds */
750 *p
++ = (byte
)((clients
[id
].usec
/ 1000) >> 8);
751 *p
++ = (byte
)((clients
[id
].usec
/ 1000) >> 16);
752 *p
++ = (byte
)((clients
[id
].usec
/ 1000) >> 24);
756 if ((to_copy
= min(strlen(clients
[id
].drvName
), (size_t)(data_length
- 1)))) {
757 memcpy(p
, clients
[id
].drvName
, to_copy
);
759 data_length
-= to_copy
;
760 if ((data_length
>= 4) && clients
[id
].hDbg
->drvTag
[0]) {
763 if ((to_copy
= min(strlen(clients
[id
].hDbg
->drvTag
), (size_t)(data_length
- 2)))) {
764 memcpy(p
, clients
[id
].hDbg
->drvTag
, to_copy
);
766 data_length
-= to_copy
;
767 if (data_length
>= 2) {
777 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
782 int diva_get_driver_dbg_mask(dword id
, byte
*data
) {
783 diva_os_spin_lock_magic_t old_irql
;
786 if (!data
|| !id
|| (id
>= ARRAY_SIZE(clients
))) {
789 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
791 if (clients
[id
].hDbg
) {
793 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
);
794 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
>> 8);
795 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
>> 16);
796 *data
++ = (byte
)(clients
[id
].hDbg
->dbgMask
>> 24);
799 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "driver info");
804 int diva_set_driver_dbg_mask(dword id
, dword mask
) {
805 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
809 if (!id
|| (id
>= ARRAY_SIZE(clients
))) {
813 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
814 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "dbg mask");
816 if (clients
[id
].hDbg
) {
817 dword old_mask
= clients
[id
].hDbg
->dbgMask
;
819 clients
[id
].hDbg
->dbgMask
= mask
;
820 clients
[id
].last_dbgMask
= (clients
[id
].hDbg
->dbgMask
| clients
[id
].dbgMask
);
822 diva_change_management_debug_mask(&clients
[id
], old_mask
);
826 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "dbg mask");
828 if (clients
[id
].request_pending
) {
829 clients
[id
].request_pending
= 0;
830 (*(clients
[id
].request
))((ENTITY
*)(*(clients
[id
].pIdiLib
->DivaSTraceGetHandle
))(clients
[id
].pIdiLib
->hLib
));
833 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
838 static int diva_get_idi_adapter_info(IDI_CALL request
, dword
*serial
, dword
*logical
) {
839 IDI_SYNC_REQ sync_req
;
841 sync_req
.xdi_logical_adapter_number
.Req
= 0;
842 sync_req
.xdi_logical_adapter_number
.Rc
= IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER
;
843 (*request
)((ENTITY
*)&sync_req
);
844 *logical
= sync_req
.xdi_logical_adapter_number
.info
.logical_adapter_number
;
846 sync_req
.GetSerial
.Req
= 0;
847 sync_req
.GetSerial
.Rc
= IDI_SYNC_REQ_GET_SERIAL
;
848 sync_req
.GetSerial
.serial
= 0;
849 (*request
)((ENTITY
*)&sync_req
);
850 *serial
= sync_req
.GetSerial
.serial
;
856 Register XDI adapter as MAINT compatible driver
858 void diva_mnt_add_xdi_adapter(const DESCRIPTOR
*d
) {
859 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
860 dword sec
, usec
, logical
, serial
, org_mask
;
861 int id
, free_id
= -1;
863 diva_dbg_entry_head_t
*pmsg
= NULL
;
868 diva_os_get_time(&sec
, &usec
);
869 diva_get_idi_adapter_info(d
->request
, &serial
, &logical
);
870 if (serial
& 0xff000000) {
871 sprintf(tmp
, "ADAPTER:%d SN:%u-%d",
874 (byte
)(((serial
& 0xff000000) >> 24) + 1));
876 sprintf(tmp
, "ADAPTER:%d SN:%u", (int)logical
, serial
);
879 if (!(pmem
= diva_os_malloc(0, DivaSTraceGetMemotyRequirement(d
->channels
)))) {
882 memset(pmem
, 0x00, DivaSTraceGetMemotyRequirement(d
->channels
));
884 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
885 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "register");
887 for (id
= 1; id
< ARRAY_SIZE(clients
); id
++) {
888 if (clients
[id
].hDbg
&& (clients
[id
].request
== d
->request
)) {
889 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
890 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
891 diva_os_free(0, pmem
);
894 if (clients
[id
].hDbg
) { /* slot is busy */
900 if (!strcmp(clients
[id
].drvName
, tmp
)) {
902 This driver was already registered with this name
903 and slot is still free - reuse it
911 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
912 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
913 diva_os_free(0, pmem
);
918 clients
[id
].request
= d
->request
;
919 clients
[id
].request_pending
= 0;
920 clients
[id
].hDbg
= &clients
[id
].Dbg
;
921 clients
[id
].sec
= sec
;
922 clients
[id
].usec
= usec
;
923 strcpy(clients
[id
].drvName
, tmp
);
924 strcpy(clients
[id
].Dbg
.drvName
, tmp
);
925 clients
[id
].Dbg
.drvTag
[0] = 0;
926 clients
[id
].logical
= (int)logical
;
927 clients
[id
].channels
= (int)d
->channels
;
928 clients
[id
].dma_handle
= -1;
930 clients
[id
].Dbg
.dbgMask
= 0;
931 clients
[id
].dbgMask
= clients
[id
].Dbg
.dbgMask
;
933 clients
[id
].Dbg
.dbgMask
|= clients
[free_id
].last_dbgMask
;
935 clients
[id
].last_dbgMask
= 0;
937 clients
[id
].Dbg
.Registered
= DBG_HANDLE_REG_NEW
;
938 clients
[id
].Dbg
.id
= (byte
)id
;
939 clients
[id
].Dbg
.dbg_end
= DI_deregister
;
940 clients
[id
].Dbg
.dbg_prt
= DI_format_locked
;
941 clients
[id
].Dbg
.dbg_ev
= DiProcessEventLog
;
942 clients
[id
].Dbg
.dbg_irq
= DI_format_locked
;
943 clients
[id
].Dbg
.next
= (pDbgHandle
)DBG_MAGIC
;
946 diva_trace_library_user_interface_t diva_maint_user_ifc
= { &clients
[id
],
947 diva_maint_state_change_notify
,
948 diva_maint_trace_notify
,
952 Attach to adapter management interface
954 if ((clients
[id
].pIdiLib
=
955 DivaSTraceLibraryCreateInstance((int)logical
, &diva_maint_user_ifc
, pmem
))) {
956 if (((*(clients
[id
].pIdiLib
->DivaSTraceLibraryStart
))(clients
[id
].pIdiLib
->hLib
))) {
957 diva_mnt_internal_dprintf(0, DLI_ERR
, "Adapter(%d) Start failed", (int)logical
);
958 (*(clients
[id
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[id
].pIdiLib
->hLib
);
959 clients
[id
].pIdiLib
= NULL
;
962 diva_mnt_internal_dprintf(0, DLI_ERR
, "A(%d) management init failed", (int)logical
);
966 if (!clients
[id
].pIdiLib
) {
967 clients
[id
].request
= NULL
;
968 clients
[id
].request_pending
= 0;
969 clients
[id
].hDbg
= NULL
;
970 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
971 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
972 diva_os_free(0, pmem
);
977 Log driver register, MAINT driver ID is '0'
979 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' registered",
980 id
, clients
[id
].Dbg
.drvName
);
982 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
983 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
984 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
985 queueFreeMsg(dbg_queue
);
992 pmsg
->sequence
= dbg_sequence
++;
993 pmsg
->time_sec
= sec
;
994 pmsg
->time_usec
= usec
;
995 pmsg
->facility
= MSG_TYPE_STRING
;
997 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
999 pmsg
->data_length
= len
+ 1;
1001 memcpy(&pmsg
[1], tmp
, len
+ 1);
1002 queueCompleteMsg(pmsg
);
1003 diva_maint_wakeup_read();
1006 org_mask
= clients
[id
].Dbg
.dbgMask
;
1007 clients
[id
].Dbg
.dbgMask
= 0;
1009 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "register");
1011 if (clients
[id
].request_pending
) {
1012 clients
[id
].request_pending
= 0;
1013 (*(clients
[id
].request
))((ENTITY
*)(*(clients
[id
].pIdiLib
->DivaSTraceGetHandle
))(clients
[id
].pIdiLib
->hLib
));
1016 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "register");
1018 diva_set_driver_dbg_mask(id
, org_mask
);
1022 De-Register XDI adapter
1024 void diva_mnt_remove_xdi_adapter(const DESCRIPTOR
*d
) {
1025 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1031 diva_os_get_time(&sec
, &usec
);
1033 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read");
1034 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "read");
1036 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
1037 if (clients
[i
].hDbg
&& (clients
[i
].request
== d
->request
)) {
1038 diva_dbg_entry_head_t
*pmsg
;
1042 if (clients
[i
].pIdiLib
) {
1043 (*(clients
[i
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[i
].pIdiLib
->hLib
);
1044 clients
[i
].pIdiLib
= NULL
;
1046 pmem
= clients
[i
].pmem
;
1047 clients
[i
].pmem
= NULL
;
1050 clients
[i
].hDbg
= NULL
;
1051 clients
[i
].request_pending
= 0;
1052 if (clients
[i
].dma_handle
>= 0) {
1056 diva_free_dma_descriptor(clients
[i
].request
, clients
[i
].dma_handle
);
1057 clients
[i
].dma_handle
= -1;
1059 clients
[i
].request
= NULL
;
1062 Log driver register, MAINT driver ID is '0'
1064 len
= sprintf(tmp
, "DIMAINT - drv # %d = '%s' de-registered",
1065 i
, clients
[i
].Dbg
.drvName
);
1067 memset(&clients
[i
].Dbg
, 0x00, sizeof(clients
[i
].Dbg
));
1069 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
1070 (word
)(len
+ 1 + sizeof(*pmsg
))))) {
1071 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
1072 queueFreeMsg(dbg_queue
);
1079 pmsg
->sequence
= dbg_sequence
++;
1080 pmsg
->time_sec
= sec
;
1081 pmsg
->time_usec
= usec
;
1082 pmsg
->facility
= MSG_TYPE_STRING
;
1083 pmsg
->dli
= DLI_REG
;
1084 pmsg
->drv_id
= 0; /* id 0 - DIMAINT */
1086 pmsg
->data_length
= len
+ 1;
1088 memcpy(&pmsg
[1], tmp
, len
+ 1);
1089 queueCompleteMsg(pmsg
);
1090 diva_maint_wakeup_read();
1097 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "read_ack");
1098 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "read_ack");
1101 diva_os_free(0, pmem
);
1105 /* ----------------------------------------------------------------
1106 Low level interface for management interface client
1107 ---------------------------------------------------------------- */
1109 Return handle to client structure
1111 void *SuperTraceOpenAdapter(int AdapterNumber
) {
1114 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
1115 if (clients
[i
].hDbg
&& clients
[i
].request
&& (clients
[i
].logical
== AdapterNumber
)) {
1116 return (&clients
[i
]);
1123 int SuperTraceCloseAdapter(void *AdapterHandle
) {
1127 int SuperTraceReadRequest(void *AdapterHandle
, const char *name
, byte
*data
) {
1128 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1130 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1131 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1132 byte
*xdata
= (byte
*)&pC
->xbuffer
[0];
1136 if (!strcmp(name
, "\\")) { /* Read ROOT */
1139 length
= SuperTraceCreateReadReq(xdata
, name
);
1140 single_p(xdata
, &length
, 0); /* End Of Message */
1144 e
->X
->PLength
= length
;
1145 e
->X
->P
= (byte
*)xdata
;
1147 pC
->request_pending
= 1;
1155 int SuperTraceGetNumberOfChannels(void *AdapterHandle
) {
1156 if (AdapterHandle
) {
1157 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1159 return (pC
->channels
);
1165 int SuperTraceASSIGN(void *AdapterHandle
, byte
*data
) {
1166 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1168 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1169 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1171 char buffer
[((sizeof(preq
->xdi_extended_features
) + 4) > sizeof(ENTITY
)) ? (sizeof(preq
->xdi_extended_features
) + 4) : sizeof(ENTITY
)];
1173 word assign_data_length
= 1;
1177 preq
= (IDI_SYNC_REQ
*)&buffer
[0];
1178 preq
->xdi_extended_features
.Req
= 0;
1179 preq
->xdi_extended_features
.Rc
= IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES
;
1180 preq
->xdi_extended_features
.info
.buffer_length_in_bytes
= sizeof(features
);
1181 preq
->xdi_extended_features
.info
.features
= &features
[0];
1183 (*(pC
->request
))((ENTITY
*)preq
);
1185 if ((features
[0] & DIVA_XDI_EXTENDED_FEATURES_VALID
) &&
1186 (features
[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA
)) {
1187 dword
uninitialized_var(rx_dma_magic
);
1188 if ((pC
->dma_handle
= diva_get_dma_descriptor(pC
->request
, &rx_dma_magic
)) >= 0) {
1189 pC
->xbuffer
[0] = LLI
;
1191 pC
->xbuffer
[2] = 0x40;
1192 pC
->xbuffer
[3] = (byte
)pC
->dma_handle
;
1193 pC
->xbuffer
[4] = (byte
)rx_dma_magic
;
1194 pC
->xbuffer
[5] = (byte
)(rx_dma_magic
>> 8);
1195 pC
->xbuffer
[6] = (byte
)(rx_dma_magic
>> 16);
1196 pC
->xbuffer
[7] = (byte
)(rx_dma_magic
>> 24);
1197 pC
->xbuffer
[8] = (byte
)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE
& 0xFF);
1198 pC
->xbuffer
[9] = (byte
)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE
>> 8);
1199 pC
->xbuffer
[10] = 0;
1201 assign_data_length
= 11;
1204 pC
->dma_handle
= -1;
1208 e
->callback
= diva_maint_xdi_cb
;
1213 e
->X
->PLength
= assign_data_length
;
1214 e
->X
->P
= (byte
*)&pC
->xbuffer
[0];
1216 pC
->request_pending
= 1;
1224 int SuperTraceREMOVE(void *AdapterHandle
) {
1225 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1227 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1228 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1235 e
->X
->P
= (byte
*)&pC
->xbuffer
[0];
1238 pC
->request_pending
= 1;
1246 int SuperTraceTraceOnRequest(void *hAdapter
, const char *name
, byte
*data
) {
1247 diva_maint_client_t
*pC
= (diva_maint_client_t
*)hAdapter
;
1249 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1250 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1251 byte
*xdata
= (byte
*)&pC
->xbuffer
[0];
1255 if (!strcmp(name
, "\\")) { /* Read ROOT */
1258 length
= SuperTraceCreateReadReq(xdata
, name
);
1259 single_p(xdata
, &length
, 0); /* End Of Message */
1260 e
->Req
= MAN_EVENT_ON
;
1262 e
->X
->PLength
= length
;
1263 e
->X
->P
= (byte
*)xdata
;
1265 pC
->request_pending
= 1;
1273 int SuperTraceWriteVar(void *AdapterHandle
,
1279 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1281 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1282 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1283 diva_man_var_header_t
*pVar
= (diva_man_var_header_t
*)&pC
->xbuffer
[0];
1284 word length
= SuperTraceCreateReadReq((byte
*)pVar
, name
);
1286 memcpy(&pC
->xbuffer
[length
], var
, var_length
);
1287 length
+= var_length
;
1288 pVar
->length
+= var_length
;
1289 pVar
->value_length
= var_length
;
1291 single_p((byte
*)pVar
, &length
, 0); /* End Of Message */
1295 e
->X
->PLength
= length
;
1296 e
->X
->P
= (byte
*)pVar
;
1298 pC
->request_pending
= 1;
1306 int SuperTraceExecuteRequest(void *AdapterHandle
,
1309 diva_maint_client_t
*pC
= (diva_maint_client_t
*)AdapterHandle
;
1311 if (pC
&& pC
->pIdiLib
&& pC
->request
) {
1312 ENTITY
*e
= (ENTITY
*)(*(pC
->pIdiLib
->DivaSTraceGetHandle
))(pC
->pIdiLib
->hLib
);
1313 byte
*xdata
= (byte
*)&pC
->xbuffer
[0];
1316 length
= SuperTraceCreateReadReq(xdata
, name
);
1317 single_p(xdata
, &length
, 0); /* End Of Message */
1319 e
->Req
= MAN_EXECUTE
;
1321 e
->X
->PLength
= length
;
1322 e
->X
->P
= (byte
*)xdata
;
1324 pC
->request_pending
= 1;
1332 static word
SuperTraceCreateReadReq(byte
*P
, const char *path
) {
1336 var_length
= (byte
)strlen(path
);
1340 *P
++ = 0x80; /* MAN_IE */
1341 *P
++ = 0x00; /* Type */
1342 *P
++ = 0x00; /* Attribute */
1343 *P
++ = 0x00; /* Status */
1344 *P
++ = 0x00; /* Variable Length */
1346 memcpy(P
, path
, var_length
);
1348 *plen
= var_length
+ 0x06;
1350 return ((word
)(var_length
+ 0x08));
1353 static void single_p(byte
*P
, word
*PLength
, byte Id
) {
1354 P
[(*PLength
)++] = Id
;
1357 static void diva_maint_xdi_cb(ENTITY
*e
) {
1358 diva_strace_context_t
*pLib
= DIVAS_CONTAINING_RECORD(e
, diva_strace_context_t
, e
);
1359 diva_maint_client_t
*pC
;
1360 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1363 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "xdi_cb");
1364 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "xdi_cb");
1366 pC
= (diva_maint_client_t
*)pLib
->hAdapter
;
1368 if ((e
->complete
== 255) || (pC
->dma_handle
< 0)) {
1369 if ((*(pLib
->instance
.DivaSTraceMessageInput
))(&pLib
->instance
)) {
1370 diva_mnt_internal_dprintf(0, DLI_ERR
, "Trace internal library error");
1374 Process combined management interface indication
1376 if ((*(pLib
->instance
.DivaSTraceMessageInput
))(&pLib
->instance
)) {
1377 diva_mnt_internal_dprintf(0, DLI_ERR
, "Trace internal library error (DMA mode)");
1381 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "xdi_cb");
1384 if (pC
->request_pending
) {
1385 pC
->request_pending
= 0;
1386 (*(pC
->request
))(e
);
1389 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "xdi_cb");
1393 static void diva_maint_error(void *user_context
,
1394 diva_strace_library_interface_t
*hLib
,
1399 diva_mnt_internal_dprintf(0, DLI_ERR
,
1400 "Trace library error(%d) A(%d) %s %d", error
, Adapter
, file
, line
);
1403 static void print_ie(diva_trace_ie_t
*ie
, char *buffer
, int length
) {
1409 for (i
= 0; ((i
< ie
->length
) && (length
> 3)); i
++) {
1410 sprintf(buffer
, "%02x", ie
->data
[i
]);
1413 if (i
< (ie
->length
- 1)) {
1414 strcpy(buffer
, " ");
1422 static void diva_maint_state_change_notify(void *user_context
,
1423 diva_strace_library_interface_t
*hLib
,
1425 diva_trace_line_state_t
*channel
,
1426 int notify_subject
) {
1427 diva_maint_client_t
*pC
= (diva_maint_client_t
*)user_context
;
1428 diva_trace_fax_state_t
*fax
= &channel
->fax
;
1429 diva_trace_modem_state_t
*modem
= &channel
->modem
;
1436 switch (notify_subject
) {
1437 case DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE
: {
1438 int view
= (TraceFilter
[0] == 0);
1440 Process selective Trace
1442 if (channel
->Line
[0] == 'I' && channel
->Line
[1] == 'd' &&
1443 channel
->Line
[2] == 'l' && channel
->Line
[3] == 'e') {
1444 if ((TraceFilterIdent
== pC
->hDbg
->id
) && (TraceFilterChannel
== (int)channel
->ChannelNumber
)) {
1445 (*(hLib
->DivaSTraceSetBChannel
))(hLib
, (int)channel
->ChannelNumber
, 0);
1446 (*(hLib
->DivaSTraceSetAudioTap
))(hLib
, (int)channel
->ChannelNumber
, 0);
1447 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
, "Selective Trace OFF for Ch=%d",
1448 (int)channel
->ChannelNumber
);
1449 TraceFilterIdent
= -1;
1450 TraceFilterChannel
= -1;
1453 } else if (TraceFilter
[0] && (TraceFilterIdent
< 0) && !(diva_mnt_cmp_nmbr(&channel
->RemoteAddress
[0]) &&
1454 diva_mnt_cmp_nmbr(&channel
->LocalAddress
[0]))) {
1456 if ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_BCHANNEL
) != 0) { /* Activate B-channel trace */
1457 (*(hLib
->DivaSTraceSetBChannel
))(hLib
, (int)channel
->ChannelNumber
, 1);
1459 if ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_AUDIO
) != 0) { /* Activate AudioTap Trace */
1460 (*(hLib
->DivaSTraceSetAudioTap
))(hLib
, (int)channel
->ChannelNumber
, 1);
1463 TraceFilterIdent
= pC
->hDbg
->id
;
1464 TraceFilterChannel
= (int)channel
->ChannelNumber
;
1466 if (TraceFilterIdent
>= 0) {
1467 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
, "Selective Trace ON for Ch=%d",
1468 (int)channel
->ChannelNumber
);
1472 if (view
&& (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_LINE_EVENTS
)) {
1473 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Ch = %d",
1474 (int)channel
->ChannelNumber
);
1475 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Status = <%s>", &channel
->Line
[0]);
1476 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Layer1 = <%s>", &channel
->Framing
[0]);
1477 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Layer2 = <%s>", &channel
->Layer2
[0]);
1478 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Layer3 = <%s>", &channel
->Layer3
[0]);
1479 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L RAddr = <%s>",
1480 &channel
->RemoteAddress
[0]);
1481 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L RSAddr = <%s>",
1482 &channel
->RemoteSubAddress
[0]);
1483 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L LAddr = <%s>",
1484 &channel
->LocalAddress
[0]);
1485 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L LSAddr = <%s>",
1486 &channel
->LocalSubAddress
[0]);
1487 print_ie(&channel
->call_BC
, tmp
, sizeof(tmp
));
1488 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L BC = <%s>", tmp
);
1489 print_ie(&channel
->call_HLC
, tmp
, sizeof(tmp
));
1490 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L HLC = <%s>", tmp
);
1491 print_ie(&channel
->call_LLC
, tmp
, sizeof(tmp
));
1492 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L LLC = <%s>", tmp
);
1493 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L CR = 0x%x", channel
->CallReference
);
1494 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Disc = 0x%x",
1495 channel
->LastDisconnecCause
);
1496 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "L Owner = <%s>", &channel
->UserID
[0]);
1501 case DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE
:
1502 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_MDM_PROGRESS
) {
1504 int ch
= TraceFilterChannel
;
1505 int id
= TraceFilterIdent
;
1507 if ((id
>= 0) && (ch
>= 0) && (id
< ARRAY_SIZE(clients
)) &&
1508 (clients
[id
].Dbg
.id
== (byte
)id
) && (clients
[id
].pIdiLib
== hLib
)) {
1509 if (ch
!= (int)modem
->ChannelNumber
) {
1512 } else if (TraceFilter
[0] != 0) {
1518 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Ch = %lu",
1519 (int)modem
->ChannelNumber
);
1520 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Event = %lu", modem
->Event
);
1521 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Norm = %lu", modem
->Norm
);
1522 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Opts. = 0x%08x", modem
->Options
);
1523 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Tx = %lu Bps", modem
->TxSpeed
);
1524 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Rx = %lu Bps", modem
->RxSpeed
);
1525 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM RT = %lu mSec",
1526 modem
->RoundtripMsec
);
1527 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Sr = %lu", modem
->SymbolRate
);
1528 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Rxl = %d dBm", modem
->RxLeveldBm
);
1529 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM El = %d dBm", modem
->EchoLeveldBm
);
1530 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM SNR = %lu dB", modem
->SNRdb
);
1531 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM MAE = %lu", modem
->MAE
);
1532 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM LRet = %lu",
1533 modem
->LocalRetrains
);
1534 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM RRet = %lu",
1535 modem
->RemoteRetrains
);
1536 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM LRes = %lu", modem
->LocalResyncs
);
1537 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM RRes = %lu",
1538 modem
->RemoteResyncs
);
1539 if (modem
->Event
== 3) {
1540 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "MDM Disc = %lu", modem
->DiscReason
);
1543 if ((modem
->Event
== 3) && (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_MDM_STATISTICS
)) {
1544 (*(pC
->pIdiLib
->DivaSTraceGetModemStatistics
))(pC
->pIdiLib
);
1548 case DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE
:
1549 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_FAX_PROGRESS
) {
1551 int ch
= TraceFilterChannel
;
1552 int id
= TraceFilterIdent
;
1554 if ((id
>= 0) && (ch
>= 0) && (id
< ARRAY_SIZE(clients
)) &&
1555 (clients
[id
].Dbg
.id
== (byte
)id
) && (clients
[id
].pIdiLib
== hLib
)) {
1556 if (ch
!= (int)fax
->ChannelNumber
) {
1559 } else if (TraceFilter
[0] != 0) {
1564 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Ch = %lu", (int)fax
->ChannelNumber
);
1565 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Event = %lu", fax
->Event
);
1566 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Pages = %lu", fax
->Page_Counter
);
1567 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Feat. = 0x%08x", fax
->Features
);
1568 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX ID = <%s>", &fax
->Station_ID
[0]);
1569 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Saddr = <%s>", &fax
->Subaddress
[0]);
1570 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Pwd = <%s>", &fax
->Password
[0]);
1571 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Speed = %lu", fax
->Speed
);
1572 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Res. = 0x%08x", fax
->Resolution
);
1573 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Width = %lu", fax
->Paper_Width
);
1574 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Length= %lu", fax
->Paper_Length
);
1575 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX SLT = %lu", fax
->Scanline_Time
);
1576 if (fax
->Event
== 3) {
1577 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
, "FAX Disc = %lu", fax
->Disc_Reason
);
1580 if ((fax
->Event
== 3) && (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_FAX_STATISTICS
)) {
1581 (*(pC
->pIdiLib
->DivaSTraceGetFaxStatistics
))(pC
->pIdiLib
);
1585 case DIVA_SUPER_TRACE_INTERFACE_CHANGE
:
1586 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_EVENTS
) {
1587 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
,
1588 "Layer 1 -> [%s]", channel
->pInterface
->Layer1
);
1589 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_STAT
,
1590 "Layer 2 -> [%s]", channel
->pInterface
->Layer2
);
1594 case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE
:
1595 if (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_STATISTICS
) {
1599 if (channel
->pInterfaceStat
->inc
.Calls
) {
1600 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1601 "Inc Calls =%lu", channel
->pInterfaceStat
->inc
.Calls
);
1603 if (channel
->pInterfaceStat
->inc
.Connected
) {
1604 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1605 "Inc Connected =%lu", channel
->pInterfaceStat
->inc
.Connected
);
1607 if (channel
->pInterfaceStat
->inc
.User_Busy
) {
1608 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1609 "Inc Busy =%lu", channel
->pInterfaceStat
->inc
.User_Busy
);
1611 if (channel
->pInterfaceStat
->inc
.Call_Rejected
) {
1612 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1613 "Inc Rejected =%lu", channel
->pInterfaceStat
->inc
.Call_Rejected
);
1615 if (channel
->pInterfaceStat
->inc
.Wrong_Number
) {
1616 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1617 "Inc Wrong Nr =%lu", channel
->pInterfaceStat
->inc
.Wrong_Number
);
1619 if (channel
->pInterfaceStat
->inc
.Incompatible_Dst
) {
1620 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1621 "Inc Incomp. Dest =%lu", channel
->pInterfaceStat
->inc
.Incompatible_Dst
);
1623 if (channel
->pInterfaceStat
->inc
.Out_of_Order
) {
1624 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1625 "Inc Out of Order =%lu", channel
->pInterfaceStat
->inc
.Out_of_Order
);
1627 if (channel
->pInterfaceStat
->inc
.Ignored
) {
1628 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1629 "Inc Ignored =%lu", channel
->pInterfaceStat
->inc
.Ignored
);
1635 if (channel
->pInterfaceStat
->outg
.Calls
) {
1636 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1637 "Outg Calls =%lu", channel
->pInterfaceStat
->outg
.Calls
);
1639 if (channel
->pInterfaceStat
->outg
.Connected
) {
1640 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1641 "Outg Connected =%lu", channel
->pInterfaceStat
->outg
.Connected
);
1643 if (channel
->pInterfaceStat
->outg
.User_Busy
) {
1644 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1645 "Outg Busy =%lu", channel
->pInterfaceStat
->outg
.User_Busy
);
1647 if (channel
->pInterfaceStat
->outg
.No_Answer
) {
1648 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1649 "Outg No Answer =%lu", channel
->pInterfaceStat
->outg
.No_Answer
);
1651 if (channel
->pInterfaceStat
->outg
.Wrong_Number
) {
1652 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1653 "Outg Wrong Nr =%lu", channel
->pInterfaceStat
->outg
.Wrong_Number
);
1655 if (channel
->pInterfaceStat
->outg
.Call_Rejected
) {
1656 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1657 "Outg Rejected =%lu", channel
->pInterfaceStat
->outg
.Call_Rejected
);
1659 if (channel
->pInterfaceStat
->outg
.Other_Failures
) {
1660 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1661 "Outg Other Failures =%lu", channel
->pInterfaceStat
->outg
.Other_Failures
);
1666 case DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE
:
1667 if (channel
->pInterfaceStat
->mdm
.Disc_Normal
) {
1668 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1669 "MDM Disc Normal = %lu", channel
->pInterfaceStat
->mdm
.Disc_Normal
);
1671 if (channel
->pInterfaceStat
->mdm
.Disc_Unspecified
) {
1672 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1673 "MDM Disc Unsp. = %lu", channel
->pInterfaceStat
->mdm
.Disc_Unspecified
);
1675 if (channel
->pInterfaceStat
->mdm
.Disc_Busy_Tone
) {
1676 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1677 "MDM Disc Busy Tone = %lu", channel
->pInterfaceStat
->mdm
.Disc_Busy_Tone
);
1679 if (channel
->pInterfaceStat
->mdm
.Disc_Congestion
) {
1680 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1681 "MDM Disc Congestion = %lu", channel
->pInterfaceStat
->mdm
.Disc_Congestion
);
1683 if (channel
->pInterfaceStat
->mdm
.Disc_Carr_Wait
) {
1684 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1685 "MDM Disc Carrier Wait = %lu", channel
->pInterfaceStat
->mdm
.Disc_Carr_Wait
);
1687 if (channel
->pInterfaceStat
->mdm
.Disc_Trn_Timeout
) {
1688 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1689 "MDM Disc Trn. T.o. = %lu", channel
->pInterfaceStat
->mdm
.Disc_Trn_Timeout
);
1691 if (channel
->pInterfaceStat
->mdm
.Disc_Incompat
) {
1692 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1693 "MDM Disc Incompatible = %lu", channel
->pInterfaceStat
->mdm
.Disc_Incompat
);
1695 if (channel
->pInterfaceStat
->mdm
.Disc_Frame_Rej
) {
1696 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1697 "MDM Disc Frame Reject = %lu", channel
->pInterfaceStat
->mdm
.Disc_Frame_Rej
);
1699 if (channel
->pInterfaceStat
->mdm
.Disc_V42bis
) {
1700 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1701 "MDM Disc V.42bis = %lu", channel
->pInterfaceStat
->mdm
.Disc_V42bis
);
1705 case DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE
:
1706 if (channel
->pInterfaceStat
->fax
.Disc_Normal
) {
1707 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1708 "FAX Disc Normal = %lu", channel
->pInterfaceStat
->fax
.Disc_Normal
);
1710 if (channel
->pInterfaceStat
->fax
.Disc_Not_Ident
) {
1711 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1712 "FAX Disc Not Ident. = %lu", channel
->pInterfaceStat
->fax
.Disc_Not_Ident
);
1714 if (channel
->pInterfaceStat
->fax
.Disc_No_Response
) {
1715 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1716 "FAX Disc No Response = %lu", channel
->pInterfaceStat
->fax
.Disc_No_Response
);
1718 if (channel
->pInterfaceStat
->fax
.Disc_Retries
) {
1719 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1720 "FAX Disc Max Retries = %lu", channel
->pInterfaceStat
->fax
.Disc_Retries
);
1722 if (channel
->pInterfaceStat
->fax
.Disc_Unexp_Msg
) {
1723 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1724 "FAX Unexp. Msg. = %lu", channel
->pInterfaceStat
->fax
.Disc_Unexp_Msg
);
1726 if (channel
->pInterfaceStat
->fax
.Disc_No_Polling
) {
1727 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1728 "FAX Disc No Polling = %lu", channel
->pInterfaceStat
->fax
.Disc_No_Polling
);
1730 if (channel
->pInterfaceStat
->fax
.Disc_Training
) {
1731 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1732 "FAX Disc Training = %lu", channel
->pInterfaceStat
->fax
.Disc_Training
);
1734 if (channel
->pInterfaceStat
->fax
.Disc_Unexpected
) {
1735 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1736 "FAX Disc Unexpected = %lu", channel
->pInterfaceStat
->fax
.Disc_Unexpected
);
1738 if (channel
->pInterfaceStat
->fax
.Disc_Application
) {
1739 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1740 "FAX Disc Application = %lu", channel
->pInterfaceStat
->fax
.Disc_Application
);
1742 if (channel
->pInterfaceStat
->fax
.Disc_Incompat
) {
1743 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1744 "FAX Disc Incompatible = %lu", channel
->pInterfaceStat
->fax
.Disc_Incompat
);
1746 if (channel
->pInterfaceStat
->fax
.Disc_No_Command
) {
1747 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1748 "FAX Disc No Command = %lu", channel
->pInterfaceStat
->fax
.Disc_No_Command
);
1750 if (channel
->pInterfaceStat
->fax
.Disc_Long_Msg
) {
1751 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1752 "FAX Disc Long Msg. = %lu", channel
->pInterfaceStat
->fax
.Disc_Long_Msg
);
1754 if (channel
->pInterfaceStat
->fax
.Disc_Supervisor
) {
1755 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1756 "FAX Disc Supervisor = %lu", channel
->pInterfaceStat
->fax
.Disc_Supervisor
);
1758 if (channel
->pInterfaceStat
->fax
.Disc_SUB_SEP_PWD
) {
1759 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1760 "FAX Disc SUP SEP PWD = %lu", channel
->pInterfaceStat
->fax
.Disc_SUB_SEP_PWD
);
1762 if (channel
->pInterfaceStat
->fax
.Disc_Invalid_Msg
) {
1763 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1764 "FAX Disc Invalid Msg. = %lu", channel
->pInterfaceStat
->fax
.Disc_Invalid_Msg
);
1766 if (channel
->pInterfaceStat
->fax
.Disc_Page_Coding
) {
1767 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1768 "FAX Disc Page Coding = %lu", channel
->pInterfaceStat
->fax
.Disc_Page_Coding
);
1770 if (channel
->pInterfaceStat
->fax
.Disc_App_Timeout
) {
1771 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1772 "FAX Disc Appl. T.o. = %lu", channel
->pInterfaceStat
->fax
.Disc_App_Timeout
);
1774 if (channel
->pInterfaceStat
->fax
.Disc_Unspecified
) {
1775 diva_mnt_internal_dprintf(pC
->hDbg
->id
, DLI_LOG
,
1776 "FAX Disc Unspec. = %lu", channel
->pInterfaceStat
->fax
.Disc_Unspecified
);
1783 Receive trace information from the Management Interface and store it in the
1784 internal trace buffer with MSG_TYPE_MLOG as is, without any filtering.
1785 Event Filtering and formatting is done in Management Interface self.
1787 static void diva_maint_trace_notify(void *user_context
,
1788 diva_strace_library_interface_t
*hLib
,
1792 diva_maint_client_t
*pC
= (diva_maint_client_t
*)user_context
;
1793 diva_dbg_entry_head_t
*pmsg
;
1796 int ch
= TraceFilterChannel
;
1797 int id
= TraceFilterIdent
;
1802 if ((id
>= 0) && (ch
>= 0) && (id
< ARRAY_SIZE(clients
)) &&
1803 (clients
[id
].Dbg
.id
== (byte
)id
) && (clients
[id
].pIdiLib
== hLib
)) {
1804 const char *p
= NULL
;
1806 MI_XLOG_HDR
*TrcData
= (MI_XLOG_HDR
*)xlog_buffer
;
1808 if (Adapter
!= clients
[id
].logical
) {
1809 return; /* Ignore all trace messages from other adapters */
1812 if (TrcData
->code
== 24) {
1813 p
= (char *)&TrcData
->code
;
1818 All L1 messages start as [dsp,ch], so we can filter this information
1819 and filter out all messages that use different channel
1821 if (p
&& p
[0] == '[') {
1824 ch_value
= *p
- '0';
1825 } else if (p
[3] == ',') {
1827 ch_value
= *p
- '0';
1829 if (ch_value
>= 0) {
1831 ch_value
= ch_value
* 10 + p
[1] - '0';
1833 if (ch_value
!= ch
) {
1834 return; /* Ignore other channels */
1839 } else if (TraceFilter
[0] != 0) {
1840 return; /* Ignore trace if trace filter is activated, but idle */
1843 diva_os_get_time(&sec
, &usec
);
1845 while (!(pmsg
= (diva_dbg_entry_head_t
*)queueAllocMsg(dbg_queue
,
1846 (word
)length
+ sizeof(*pmsg
)))) {
1847 if ((pmsg
= (diva_dbg_entry_head_t
*)queuePeekMsg(dbg_queue
, &size
))) {
1848 queueFreeMsg(dbg_queue
);
1854 memcpy(&pmsg
[1], xlog_buffer
, length
);
1855 pmsg
->sequence
= dbg_sequence
++;
1856 pmsg
->time_sec
= sec
;
1857 pmsg
->time_usec
= usec
;
1858 pmsg
->facility
= MSG_TYPE_MLOG
;
1859 pmsg
->dli
= pC
->logical
;
1860 pmsg
->drv_id
= pC
->hDbg
->id
;
1862 pmsg
->data_length
= length
;
1863 queueCompleteMsg(pmsg
);
1864 if (queueCount(dbg_queue
)) {
1865 diva_maint_wakeup_read();
1872 Convert MAINT trace mask to management interface trace mask/work/facility and
1873 issue command to management interface
1875 static void diva_change_management_debug_mask(diva_maint_client_t
*pC
, dword old_mask
) {
1876 if (pC
->request
&& pC
->hDbg
&& pC
->pIdiLib
) {
1877 dword changed
= pC
->hDbg
->dbgMask
^ old_mask
;
1879 if (changed
& DIVA_MGT_DBG_TRACE
) {
1880 (*(pC
->pIdiLib
->DivaSTraceSetInfo
))(pC
->pIdiLib
,
1881 (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_TRACE
) != 0);
1883 if (changed
& DIVA_MGT_DBG_DCHAN
) {
1884 (*(pC
->pIdiLib
->DivaSTraceSetDChannel
))(pC
->pIdiLib
,
1885 (pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_DCHAN
) != 0);
1887 if (!TraceFilter
[0]) {
1888 if (changed
& DIVA_MGT_DBG_IFC_BCHANNEL
) {
1889 int i
, state
= ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_BCHANNEL
) != 0);
1891 for (i
= 0; i
< pC
->channels
; i
++) {
1892 (*(pC
->pIdiLib
->DivaSTraceSetBChannel
))(pC
->pIdiLib
, i
+ 1, state
);
1895 if (changed
& DIVA_MGT_DBG_IFC_AUDIO
) {
1896 int i
, state
= ((pC
->hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_AUDIO
) != 0);
1898 for (i
= 0; i
< pC
->channels
; i
++) {
1899 (*(pC
->pIdiLib
->DivaSTraceSetAudioTap
))(pC
->pIdiLib
, i
+ 1, state
);
1907 void diva_mnt_internal_dprintf(dword drv_id
, dword type
, char *fmt
, ...) {
1911 DI_format(0, (word
)drv_id
, (int)type
, fmt
, ap
);
1916 Shutdown all adapters before driver removal
1918 int diva_mnt_shutdown_xdi_adapters(void) {
1919 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1924 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
1927 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "unload");
1928 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "unload");
1930 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
) {
1931 if ((*(clients
[i
].pIdiLib
->DivaSTraceLibraryStop
))(clients
[i
].pIdiLib
) == 1) {
1933 Adapter removal complete
1935 if (clients
[i
].pIdiLib
) {
1936 (*(clients
[i
].pIdiLib
->DivaSTraceLibraryFinit
))(clients
[i
].pIdiLib
->hLib
);
1937 clients
[i
].pIdiLib
= NULL
;
1939 pmem
= clients
[i
].pmem
;
1940 clients
[i
].pmem
= NULL
;
1942 clients
[i
].hDbg
= NULL
;
1943 clients
[i
].request_pending
= 0;
1945 if (clients
[i
].dma_handle
>= 0) {
1949 diva_free_dma_descriptor(clients
[i
].request
, clients
[i
].dma_handle
);
1950 clients
[i
].dma_handle
= -1;
1952 clients
[i
].request
= NULL
;
1958 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "unload");
1959 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
&& clients
[i
].request_pending
) {
1960 clients
[i
].request_pending
= 0;
1961 (*(clients
[i
].request
))((ENTITY
*)(*(clients
[i
].pIdiLib
->DivaSTraceGetHandle
))(clients
[i
].pIdiLib
->hLib
));
1962 if (clients
[i
].dma_handle
>= 0) {
1963 diva_free_dma_descriptor(clients
[i
].request
, clients
[i
].dma_handle
);
1964 clients
[i
].dma_handle
= -1;
1967 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "unload");
1970 diva_os_free(0, pmem
);
1978 Set/Read the trace filter used for selective tracing.
1979 Affects B- and Audio Tap trace mask at run time
1981 int diva_set_trace_filter(int filter_length
, const char *filter
) {
1982 diva_os_spin_lock_magic_t old_irql
, old_irql1
;
1983 int i
, ch
, on
, client_b_on
, client_atap_on
;
1985 diva_os_enter_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
1986 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
1988 if (filter_length
<= DIVA_MAX_SELECTIVE_FILTER_LENGTH
) {
1989 memcpy(&TraceFilter
[0], filter
, filter_length
);
1990 if (TraceFilter
[filter_length
]) {
1991 TraceFilter
[filter_length
] = 0;
1993 if (TraceFilter
[0] == '*') {
2000 TraceFilterIdent
= -1;
2001 TraceFilterChannel
= -1;
2003 on
= (TraceFilter
[0] == 0);
2005 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
2006 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
) {
2007 client_b_on
= on
&& ((clients
[i
].hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_BCHANNEL
) != 0);
2008 client_atap_on
= on
&& ((clients
[i
].hDbg
->dbgMask
& DIVA_MGT_DBG_IFC_AUDIO
) != 0);
2009 for (ch
= 0; ch
< clients
[i
].channels
; ch
++) {
2010 (*(clients
[i
].pIdiLib
->DivaSTraceSetBChannel
))(clients
[i
].pIdiLib
->hLib
, ch
+ 1, client_b_on
);
2011 (*(clients
[i
].pIdiLib
->DivaSTraceSetAudioTap
))(clients
[i
].pIdiLib
->hLib
, ch
+ 1, client_atap_on
);
2016 for (i
= 1; i
< ARRAY_SIZE(clients
); i
++) {
2017 if (clients
[i
].hDbg
&& clients
[i
].pIdiLib
&& clients
[i
].request
&& clients
[i
].request_pending
) {
2018 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
2019 clients
[i
].request_pending
= 0;
2020 (*(clients
[i
].request
))((ENTITY
*)(*(clients
[i
].pIdiLib
->DivaSTraceGetHandle
))(clients
[i
].pIdiLib
->hLib
));
2021 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
2025 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "write_filter");
2026 diva_os_leave_spin_lock(&dbg_adapter_lock
, &old_irql1
, "dbg mask");
2028 return (filter_length
);
2031 int diva_get_trace_filter(int max_length
, char *filter
) {
2032 diva_os_spin_lock_magic_t old_irql
;
2035 diva_os_enter_spin_lock(&dbg_q_lock
, &old_irql
, "read_filter");
2036 len
= strlen(&TraceFilter
[0]) + 1;
2037 if (max_length
>= len
) {
2038 memcpy(filter
, &TraceFilter
[0], len
);
2040 diva_os_leave_spin_lock(&dbg_q_lock
, &old_irql
, "read_filter");
2045 static int diva_dbg_cmp_key(const char *ref
, const char *key
) {
2046 while (*key
&& (*ref
++ == *key
++));
2047 return (!*key
&& !*ref
);
2051 In case trace filter starts with "C" character then
2052 all following characters are interpreted as command.
2053 Following commands are available:
2054 - single, trace single call at time, independent from CPN/CiPN
2056 static int diva_mnt_cmp_nmbr(const char *nmbr
) {
2057 const char *ref
= &TraceFilter
[0];
2058 int ref_len
= strlen(&TraceFilter
[0]), nmbr_len
= strlen(nmbr
);
2060 if (ref
[0] == 'C') {
2061 if (diva_dbg_cmp_key(&ref
[1], "single")) {
2067 if (!ref_len
|| (ref_len
> nmbr_len
)) {
2071 nmbr
= nmbr
+ nmbr_len
- 1;
2072 ref
= ref
+ ref_len
- 1;
2075 if (*nmbr
-- != *ref
--) {
2083 static int diva_get_dma_descriptor(IDI_CALL request
, dword
*dma_magic
) {
2085 IDI_SYNC_REQ
*pReq
= (IDI_SYNC_REQ
*)&e
;
2091 pReq
->xdi_dma_descriptor_operation
.Req
= 0;
2092 pReq
->xdi_dma_descriptor_operation
.Rc
= IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION
;
2094 pReq
->xdi_dma_descriptor_operation
.info
.operation
= IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC
;
2095 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
= -1;
2096 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_address
= NULL
;
2097 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
= 0;
2099 (*request
)((ENTITY
*)pReq
);
2101 if (!pReq
->xdi_dma_descriptor_operation
.info
.operation
&&
2102 (pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
>= 0) &&
2103 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
) {
2104 *dma_magic
= pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
;
2105 return (pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
);
2111 static void diva_free_dma_descriptor(IDI_CALL request
, int nr
) {
2113 IDI_SYNC_REQ
*pReq
= (IDI_SYNC_REQ
*)&e
;
2115 if (!request
|| (nr
< 0)) {
2119 pReq
->xdi_dma_descriptor_operation
.Req
= 0;
2120 pReq
->xdi_dma_descriptor_operation
.Rc
= IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION
;
2122 pReq
->xdi_dma_descriptor_operation
.info
.operation
= IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE
;
2123 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_number
= nr
;
2124 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_address
= NULL
;
2125 pReq
->xdi_dma_descriptor_operation
.info
.descriptor_magic
= 0;
2127 (*request
)((ENTITY
*)pReq
);