// SPDX-License-Identifier: GPL-2.0
#include "platform.h"
#include "pc.h"
#include "di_defs.h"
#include "debug_if.h"
#include "divasync.h"
#include "kst_ifc.h"
#include "maintidi.h"
#include "man_defs.h"

/*
  LOCALS
*/
#define DBG_MAGIC (0x47114711L)

static void DI_register(void *arg);
static void DI_deregister(pDbgHandle hDbg);
static void DI_format(int do_lock, word id, int type, char *format, va_list argument_list);
static void DI_format_locked(word id, int type, char *format, va_list argument_list);
static void DI_format_old(word id, char *format, va_list ap) { }
static void DiProcessEventLog(unsigned short id, unsigned long msgID, va_list ap) { }
static void single_p(byte *P, word *PLength, byte Id);
static void diva_maint_xdi_cb(ENTITY *e);
static word SuperTraceCreateReadReq(byte *P, const char *path);
static int diva_mnt_cmp_nmbr(const char *nmbr);
static void diva_free_dma_descriptor(IDI_CALL request, int nr);
static int diva_get_dma_descriptor(IDI_CALL request, dword *dma_magic);
void diva_mnt_internal_dprintf(dword drv_id, dword type, char *p, ...);

static dword MaxDumpSize = 256;
static dword MaxXlogSize = 2 + 128;
static char  TraceFilter[DIVA_MAX_SELECTIVE_FILTER_LENGTH + 1];
static int TraceFilterIdent   = -1;
static int TraceFilterChannel = -1;

typedef struct _diva_maint_client {
	dword       sec;
	dword       usec;
	pDbgHandle  hDbg;
	char        drvName[128];
	dword       dbgMask;
	dword       last_dbgMask;
	IDI_CALL    request;
	_DbgHandle_ Dbg;
	int         logical;
	int         channels;
	diva_strace_library_interface_t *pIdiLib;
	BUFFERS     XData;
	char        xbuffer[2048 + 512];
	byte        *pmem;
	int         request_pending;
	int         dma_handle;
} diva_maint_client_t;
static diva_maint_client_t clients[MAX_DESCRIPTORS];

static void diva_change_management_debug_mask(diva_maint_client_t *pC, dword old_mask);

static void diva_maint_error(void *user_context,
			     diva_strace_library_interface_t *hLib,
			     int Adapter,
			     int error,
			     const char *file,
			     int line);
static void diva_maint_state_change_notify(void *user_context,
					   diva_strace_library_interface_t *hLib,
					   int Adapter,
					   diva_trace_line_state_t *channel,
					   int notify_subject);
static void diva_maint_trace_notify(void *user_context,
				    diva_strace_library_interface_t *hLib,
				    int Adapter,
				    void *xlog_buffer,
				    int length);



typedef struct MSG_QUEUE {
	dword	Size;		/* total size of queue (constant)	*/
	byte	*Base;		/* lowest address (constant)		*/
	byte	*High;		/* Base + Size (constant)		*/
	byte	*Head;		/* first message in queue (if any)	*/
	byte	*Tail;		/* first free position			*/
	byte	*Wrap;		/* current wraparound position		*/
	dword	Count;		/* current no of bytes in queue		*/
} MSG_QUEUE;

typedef struct MSG_HEAD {
	volatile dword	Size;		/* size of data following MSG_HEAD	*/
#define	MSG_INCOMPLETE	0x8000	/* ored to Size until queueCompleteMsg	*/
} MSG_HEAD;

#define queueCompleteMsg(p) do { ((MSG_HEAD *)p - 1)->Size &= ~MSG_INCOMPLETE; } while (0)
#define queueCount(q)	((q)->Count)
#define MSG_NEED(size)							\
	((sizeof(MSG_HEAD) + size + sizeof(dword) - 1) & ~(sizeof(dword) - 1))

static void queueInit(MSG_QUEUE *Q, byte *Buffer, dword sizeBuffer) {
	Q->Size = sizeBuffer;
	Q->Base = Q->Head = Q->Tail = Buffer;
	Q->High = Buffer + sizeBuffer;
	Q->Wrap = NULL;
	Q->Count = 0;
}

static byte *queueAllocMsg(MSG_QUEUE *Q, word size) {
	/* Allocate 'size' bytes at tail of queue which will be filled later
	 * directly with callers own message header info and/or message.
	 * An 'alloced' message is marked incomplete by oring the 'Size' field
	 * with MSG_INCOMPLETE.
	 * This must be reset via queueCompleteMsg() after the message is filled.
	 * As long as a message is marked incomplete queuePeekMsg() will return
	 * a 'queue empty' condition when it reaches such a message.  */

	MSG_HEAD *Msg;
	word need = MSG_NEED(size);

	if (Q->Tail == Q->Head) {
		if (Q->Wrap || need > Q->Size) {
			return NULL; /* full */
		}
		goto alloc; /* empty */
	}

	if (Q->Tail > Q->Head) {
		if (Q->Tail + need <= Q->High) goto alloc; /* append */
		if (Q->Base + need > Q->Head) {
			return NULL; /* too much */
		}
		/* wraparound the queue (but not the message) */
		Q->Wrap = Q->Tail;
		Q->Tail = Q->Base;
		goto alloc;
	}

	if (Q->Tail + need > Q->Head) {
		return NULL; /* too much */
	}

alloc:
	Msg = (MSG_HEAD *)Q->Tail;

	Msg->Size = size | MSG_INCOMPLETE;

	Q->Tail	 += need;
	Q->Count += size;



	return ((byte *)(Msg + 1));
}

static void queueFreeMsg(MSG_QUEUE *Q) {
/* Free the message at head of queue */

	word size = ((MSG_HEAD *)Q->Head)->Size & ~MSG_INCOMPLETE;

	Q->Head  += MSG_NEED(size);
	Q->Count -= size;

	if (Q->Wrap) {
		if (Q->Head >= Q->Wrap) {
			Q->Head = Q->Base;
			Q->Wrap = NULL;
		}
	} else if (Q->Head >= Q->Tail) {
		Q->Head = Q->Tail = Q->Base;
	}
}

static byte *queuePeekMsg(MSG_QUEUE *Q, word *size) {
	/* Show the first valid message in queue BUT DON'T free the message.
	 * After looking on the message contents it can be freed queueFreeMsg()
	 * or simply remain in message queue.  */

	MSG_HEAD *Msg = (MSG_HEAD *)Q->Head;

	if (((byte *)Msg == Q->Tail && !Q->Wrap) ||
	    (Msg->Size & MSG_INCOMPLETE)) {
		return NULL;
	} else {
		*size = Msg->Size;
		return ((byte *)(Msg + 1));
	}
}

/*
  Message queue header
*/
static MSG_QUEUE *dbg_queue;
static byte *dbg_base;
static int                 external_dbg_queue;
static diva_os_spin_lock_t dbg_q_lock;
static diva_os_spin_lock_t dbg_adapter_lock;
static int                 dbg_q_busy;
static volatile dword      dbg_sequence;

/*
  INTERFACE:
  Initialize run time queue structures.
  base:    base of the message queue
  length:  length of the message queue
  do_init: perfor queue reset

  return:  zero on success, -1 on error
*/
int diva_maint_init(byte *base, unsigned long length, int do_init) {
	if (dbg_queue || (!base) || (length < (4096 * 4))) {
		return (-1);
	}

	TraceFilter[0]     =  0;
	TraceFilterIdent   = -1;
	TraceFilterChannel = -1;

	dbg_base = base;

	*(dword *)base  = (dword)DBG_MAGIC; /* Store Magic */
	base   += sizeof(dword);
	length -= sizeof(dword);

	*(dword *)base = 2048; /* Extension Field Length */
	base   += sizeof(dword);
	length -= sizeof(dword);

	strcpy(base, "KERNEL MODE BUFFER\n");
	base   += 2048;
	length -= 2048;

	*(dword *)base = 0; /* Terminate extension */
	base   += sizeof(dword);
	length -= sizeof(dword);

	*(void **)base  =  (void *)(base + sizeof(void *)); /* Store Base  */
	base   += sizeof(void *);
	length -= sizeof(void *);

	dbg_queue = (MSG_QUEUE *)base;
	queueInit(dbg_queue, base + sizeof(MSG_QUEUE), length - sizeof(MSG_QUEUE) - 512);
	external_dbg_queue = 0;

	if (!do_init) {
		external_dbg_queue = 1; /* memory was located on the external device */
	}


	if (diva_os_initialize_spin_lock(&dbg_q_lock, "dbg_init")) {
		dbg_queue = NULL;
		dbg_base = NULL;
		external_dbg_queue = 0;
		return (-1);
	}

	if (diva_os_initialize_spin_lock(&dbg_adapter_lock, "dbg_init")) {
		diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_init");
		dbg_queue = NULL;
		dbg_base = NULL;
		external_dbg_queue = 0;
		return (-1);
	}

	return (0);
}

/*
  INTERFACE:
  Finit at unload time
  return address of internal queue or zero if queue
  was external
*/
void *diva_maint_finit(void) {
	void *ret = (void *)dbg_base;
	int i;

	dbg_queue = NULL;
	dbg_base  = NULL;

	if (ret) {
		diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_finit");
		diva_os_destroy_spin_lock(&dbg_adapter_lock, "dbg_finit");
	}

	if (external_dbg_queue) {
		ret = NULL;
	}
	external_dbg_queue = 0;

	for (i = 1; i < ARRAY_SIZE(clients); i++) {
		if (clients[i].pmem) {
			diva_os_free(0, clients[i].pmem);
		}
	}

	return (ret);
}

/*
  INTERFACE:
  Return amount of messages in debug queue
*/
dword diva_dbg_q_length(void) {
	return (dbg_queue ? queueCount(dbg_queue)	: 0);
}

/*
  INTERFACE:
  Lock message queue and return the pointer to the first
  entry.
*/
diva_dbg_entry_head_t *diva_maint_get_message(word *size,
					      diva_os_spin_lock_magic_t *old_irql) {
	diva_dbg_entry_head_t *pmsg = NULL;

	diva_os_enter_spin_lock(&dbg_q_lock, old_irql, "read");
	if (dbg_q_busy) {
		diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_busy");
		return NULL;
	}
	dbg_q_busy = 1;

	if (!(pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, size))) {
		dbg_q_busy = 0;
		diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_empty");
	}

	return (pmsg);
}

/*
  INTERFACE:
  acknowledge last message and unlock queue
*/
void diva_maint_ack_message(int do_release,
			    diva_os_spin_lock_magic_t *old_irql) {
	if (!dbg_q_busy) {
		return;
	}
	if (do_release) {
		queueFreeMsg(dbg_queue);
	}
	dbg_q_busy = 0;
	diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_ack");
}


/*
  INTERFACE:
  PRT COMP function used to register
  with MAINT adapter or log in compatibility
  mode in case older driver version is connected too
*/
void diva_maint_prtComp(char *format, ...) {
	void    *hDbg;
	va_list ap;

	if (!format)
		return;

	va_start(ap, format);

	/*
	  register to new log driver functions
	*/
	if ((format[0] == 0) && ((unsigned char)format[1] == 255)) {
		hDbg = va_arg(ap, void *); /* ptr to DbgHandle */
		DI_register(hDbg);
	}

	va_end(ap);
}

static void DI_register(void *arg) {
	diva_os_spin_lock_magic_t old_irql;
	dword sec, usec;
	pDbgHandle	hDbg;
	int id, free_id = -1, best_id = 0;

	diva_os_get_time(&sec, &usec);

	hDbg = (pDbgHandle)arg;
	/*
	  Check for bad args, specially for the old obsolete debug handle
	*/
	if ((hDbg == NULL) ||
	    ((hDbg->id == 0) && (((_OldDbgHandle_ *)hDbg)->id == -1)) ||
	    (hDbg->Registered != 0)) {
		return;
	}

	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "register");

	for (id = 1; id < ARRAY_SIZE(clients); id++) {
		if (clients[id].hDbg == hDbg) {
			/*
			  driver already registered
			*/
			diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
			return;
		}
		if (clients[id].hDbg) { /* slot is busy */
			continue;
		}
		free_id = id;
		if (!strcmp(clients[id].drvName, hDbg->drvName)) {
			/*
			  This driver was already registered with this name
			  and slot is still free - reuse it
			*/
			best_id = 1;
			break;
		}
		if (!clients[id].hDbg) { /* slot is busy */
			break;
		}
	}

	if (free_id != -1) {
		diva_dbg_entry_head_t *pmsg = NULL;
		int len;
		char tmp[256];
		word size;

		/*
		  Register new driver with id == free_id
		*/
		clients[free_id].hDbg = hDbg;
		clients[free_id].sec  = sec;
		clients[free_id].usec = usec;
		strcpy(clients[free_id].drvName, hDbg->drvName);

		clients[free_id].dbgMask = hDbg->dbgMask;
		if (best_id) {
			hDbg->dbgMask |= clients[free_id].last_dbgMask;
		} else {
			clients[free_id].last_dbgMask = 0;
		}

		hDbg->Registered = DBG_HANDLE_REG_NEW;
		hDbg->id         = (byte)free_id;
		hDbg->dbg_end    = DI_deregister;
		hDbg->dbg_prt    = DI_format_locked;
		hDbg->dbg_ev     = DiProcessEventLog;
		hDbg->dbg_irq    = DI_format_locked;
		if (hDbg->Version > 0) {
			hDbg->dbg_old  = DI_format_old;
		}
		hDbg->next       = (pDbgHandle)DBG_MAGIC;

		/*
		  Log driver register, MAINT driver ID is '0'
		*/
		len = sprintf(tmp, "DIMAINT - drv # %d = '%s' registered",
			      free_id, hDbg->drvName);

		while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
								       (word)(len + 1 + sizeof(*pmsg))))) {
			if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
				queueFreeMsg(dbg_queue);
			} else {
				break;
			}
		}

		if (pmsg) {
			pmsg->sequence    = dbg_sequence++;
			pmsg->time_sec    = sec;
			pmsg->time_usec   = usec;
			pmsg->facility    = MSG_TYPE_STRING;
			pmsg->dli         = DLI_REG;
			pmsg->drv_id      = 0; /* id 0 - DIMAINT */
			pmsg->di_cpu      = 0;
			pmsg->data_length = len + 1;

			memcpy(&pmsg[1], tmp, len + 1);
			queueCompleteMsg(pmsg);
			diva_maint_wakeup_read();
		}
	}

	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
}

static void DI_deregister(pDbgHandle hDbg) {
	diva_os_spin_lock_magic_t old_irql, old_irql1;
	dword sec, usec;
	int i;
	word size;
	byte *pmem = NULL;

	diva_os_get_time(&sec, &usec);

	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "read");
	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read");

	for (i = 1; i < ARRAY_SIZE(clients); i++) {
		if (clients[i].hDbg == hDbg) {
			diva_dbg_entry_head_t *pmsg;
			char tmp[256];
			int len;

			clients[i].hDbg = NULL;

			hDbg->id       = -1;
			hDbg->dbgMask  = 0;
			hDbg->dbg_end  = NULL;
			hDbg->dbg_prt  = NULL;
			hDbg->dbg_irq  = NULL;
			if (hDbg->Version > 0)
				hDbg->dbg_old = NULL;
			hDbg->Registered = 0;
			hDbg->next     = NULL;

			if (clients[i].pIdiLib) {
				(*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
				clients[i].pIdiLib = NULL;

				pmem = clients[i].pmem;
				clients[i].pmem = NULL;
			}

			/*
			  Log driver register, MAINT driver ID is '0'
			*/
			len = sprintf(tmp, "DIMAINT - drv # %d = '%s' de-registered",
				      i, hDbg->drvName);

			while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
									      (word)(len + 1 + sizeof(*pmsg))))) {
				if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
					queueFreeMsg(dbg_queue);
				} else {
					break;
				}
			}

			if (pmsg) {
				pmsg->sequence    = dbg_sequence++;
				pmsg->time_sec    = sec;
				pmsg->time_usec   = usec;
				pmsg->facility    = MSG_TYPE_STRING;
				pmsg->dli         = DLI_REG;
				pmsg->drv_id      = 0; /* id 0 - DIMAINT */
				pmsg->di_cpu      = 0;
				pmsg->data_length = len + 1;

				memcpy(&pmsg[1], tmp, len + 1);
				queueCompleteMsg(pmsg);
				diva_maint_wakeup_read();
			}

			break;
		}
	}

	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_ack");
	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "read_ack");

	if (pmem) {
		diva_os_free(0, pmem);
	}
}

static void DI_format_locked(unsigned short id,
			     int type,
			     char *format,
			     va_list argument_list) {
	DI_format(1, id, type, format, argument_list);
}

static void DI_format(int do_lock,
		      unsigned short id,
		      int type,
		      char *format,
		      va_list ap) {
	diva_os_spin_lock_magic_t old_irql;
	dword sec, usec;
	diva_dbg_entry_head_t *pmsg = NULL;
	dword length;
	word size;
	static char fmtBuf[MSG_FRAME_MAX_SIZE + sizeof(*pmsg) + 1];
	char          *data;
	unsigned short code;

	if (diva_os_in_irq()) {
		dbg_sequence++;
		return;
	}

	if ((!format) ||
	    ((TraceFilter[0] != 0) && ((TraceFilterIdent < 0) || (TraceFilterChannel < 0)))) {
		return;
	}



	diva_os_get_time(&sec, &usec);

	if (do_lock) {
		diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "format");
	}

	switch (type) {
	case DLI_MXLOG:
	case DLI_BLK:
	case DLI_SEND:
	case DLI_RECV:
		if (!(length = va_arg(ap, unsigned long))) {
			break;
		}
		if (length > MaxDumpSize) {
			length = MaxDumpSize;
		}
		while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
								       (word)length + sizeof(*pmsg)))) {
			if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
				queueFreeMsg(dbg_queue);
			} else {
				break;
			}
		}
		if (pmsg) {
			memcpy(&pmsg[1], format, length);
			pmsg->sequence    = dbg_sequence++;
			pmsg->time_sec    = sec;
			pmsg->time_usec   = usec;
			pmsg->facility    = MSG_TYPE_BINARY;
			pmsg->dli         = type; /* DLI_XXX */
			pmsg->drv_id      = id;   /* driver MAINT id */
			pmsg->di_cpu      = 0;
			pmsg->data_length = length;
			queueCompleteMsg(pmsg);
		}
		break;

	case DLI_XLOG: {
		byte *p;
		data    = va_arg(ap, char *);
		code    = (unsigned short)va_arg(ap, unsigned int);
		length	= (unsigned long)va_arg(ap, unsigned int);

		if (length > MaxXlogSize)
			length = MaxXlogSize;

		while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
								      (word)length + sizeof(*pmsg) + 2))) {
			if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
				queueFreeMsg(dbg_queue);
			} else {
				break;
			}
		}
		if (pmsg) {
			p = (byte *)&pmsg[1];
			p[0] = (char)(code);
			p[1] = (char)(code >> 8);
			if (data && length) {
				memcpy(&p[2], &data[0], length);
			}
			length += 2;

			pmsg->sequence    = dbg_sequence++;
			pmsg->time_sec    = sec;
			pmsg->time_usec   = usec;
			pmsg->facility    = MSG_TYPE_BINARY;
			pmsg->dli         = type; /* DLI_XXX */
			pmsg->drv_id      = id;   /* driver MAINT id */
			pmsg->di_cpu      = 0;
			pmsg->data_length = length;
			queueCompleteMsg(pmsg);
		}
	} break;

	case DLI_LOG:
	case DLI_FTL:
	case DLI_ERR:
	case DLI_TRC:
	case DLI_REG:
	case DLI_MEM:
	case DLI_SPL:
	case DLI_IRP:
	case DLI_TIM:
	case DLI_TAPI:
	case DLI_NDIS:
	case DLI_CONN:
	case DLI_STAT:
	case DLI_PRV0:
	case DLI_PRV1:
	case DLI_PRV2:
	case DLI_PRV3:
		if ((length = (unsigned long)vsprintf(&fmtBuf[0], format, ap)) > 0) {
			length += (sizeof(*pmsg) + 1);

			while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
									       (word)length))) {
				if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
					queueFreeMsg(dbg_queue);
				} else {
					break;
				}
			}

			pmsg->sequence    = dbg_sequence++;
			pmsg->time_sec    = sec;
			pmsg->time_usec   = usec;
			pmsg->facility    = MSG_TYPE_STRING;
			pmsg->dli         = type; /* DLI_XXX */
			pmsg->drv_id      = id;   /* driver MAINT id */
			pmsg->di_cpu      = 0;
			pmsg->data_length = length - sizeof(*pmsg);

			memcpy(&pmsg[1], fmtBuf, pmsg->data_length);
			queueCompleteMsg(pmsg);
		}
		break;

	} /* switch type */


	if (queueCount(dbg_queue)) {
		diva_maint_wakeup_read();
	}

	if (do_lock) {
		diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "format");
	}
}

/*
  Write driver ID and driver revision to callers buffer
*/
int diva_get_driver_info(dword id, byte *data, int data_length) {
	diva_os_spin_lock_magic_t old_irql;
	byte *p = data;
	int to_copy;

	if (!data || !id || (data_length < 17) ||
	    (id >= ARRAY_SIZE(clients))) {
		return (-1);
	}

	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "driver info");

	if (clients[id].hDbg) {
		*p++ = 1;
		*p++ = (byte)clients[id].sec; /* save seconds */
		*p++ = (byte)(clients[id].sec >>  8);
		*p++ = (byte)(clients[id].sec >> 16);
		*p++ = (byte)(clients[id].sec >> 24);

		*p++ = (byte)(clients[id].usec / 1000); /* save mseconds */
		*p++ = (byte)((clients[id].usec / 1000) >>  8);
		*p++ = (byte)((clients[id].usec / 1000) >> 16);
		*p++ = (byte)((clients[id].usec / 1000) >> 24);

		data_length -= 9;

		if ((to_copy = min(strlen(clients[id].drvName), (size_t)(data_length - 1)))) {
			memcpy(p, clients[id].drvName, to_copy);
			p += to_copy;
			data_length -= to_copy;
			if ((data_length >= 4) && clients[id].hDbg->drvTag[0]) {
				*p++ = '(';
				data_length -= 1;
				if ((to_copy = min(strlen(clients[id].hDbg->drvTag), (size_t)(data_length - 2)))) {
					memcpy(p, clients[id].hDbg->drvTag, to_copy);
					p += to_copy;
					data_length -= to_copy;
					if (data_length >= 2) {
						*p++ = ')';
						data_length--;
					}
				}
			}
		}
	}
	*p++ = 0;

	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "driver info");

	return (p - data);
}

int diva_get_driver_dbg_mask(dword id, byte *data) {
	diva_os_spin_lock_magic_t old_irql;
	int ret = -1;

	if (!data || !id || (id >= ARRAY_SIZE(clients))) {
		return (-1);
	}
	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "driver info");

	if (clients[id].hDbg) {
		ret = 4;
		*data++ = (byte)(clients[id].hDbg->dbgMask);
		*data++ = (byte)(clients[id].hDbg->dbgMask >>  8);
		*data++ = (byte)(clients[id].hDbg->dbgMask >> 16);
		*data++ = (byte)(clients[id].hDbg->dbgMask >> 24);
	}

	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "driver info");

	return (ret);
}

int diva_set_driver_dbg_mask(dword id, dword mask) {
	diva_os_spin_lock_magic_t old_irql, old_irql1;
	int ret = -1;


	if (!id || (id >= ARRAY_SIZE(clients))) {
		return (-1);
	}

	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");
	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "dbg mask");

	if (clients[id].hDbg) {
		dword old_mask = clients[id].hDbg->dbgMask;
		mask &= 0x7fffffff;
		clients[id].hDbg->dbgMask = mask;
		clients[id].last_dbgMask = (clients[id].hDbg->dbgMask | clients[id].dbgMask);
		ret = 4;
		diva_change_management_debug_mask(&clients[id], old_mask);
	}


	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "dbg mask");

	if (clients[id].request_pending) {
		clients[id].request_pending = 0;
		(*(clients[id].request))((ENTITY *)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib));
	}

	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");

	return (ret);
}

static int diva_get_idi_adapter_info(IDI_CALL request, dword *serial, dword *logical) {
	IDI_SYNC_REQ sync_req;

	sync_req.xdi_logical_adapter_number.Req = 0;
	sync_req.xdi_logical_adapter_number.Rc = IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER;
	(*request)((ENTITY *)&sync_req);
	*logical = sync_req.xdi_logical_adapter_number.info.logical_adapter_number;

	sync_req.GetSerial.Req = 0;
	sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL;
	sync_req.GetSerial.serial = 0;
	(*request)((ENTITY *)&sync_req);
	*serial = sync_req.GetSerial.serial;

	return (0);
}

/*
  Register XDI adapter as MAINT compatible driver
*/
void diva_mnt_add_xdi_adapter(const DESCRIPTOR *d) {
	diva_os_spin_lock_magic_t old_irql, old_irql1;
	dword sec, usec, logical, serial, org_mask;
	int id, free_id = -1;
	char tmp[128];
	diva_dbg_entry_head_t *pmsg = NULL;
	int len;
	word size;
	byte *pmem;

	diva_os_get_time(&sec, &usec);
	diva_get_idi_adapter_info(d->request, &serial, &logical);
	if (serial & 0xff000000) {
		sprintf(tmp, "ADAPTER:%d SN:%u-%d",
			(int)logical,
			serial & 0x00ffffff,
			(byte)(((serial & 0xff000000) >> 24) + 1));
	} else {
		sprintf(tmp, "ADAPTER:%d SN:%u", (int)logical, serial);
	}

	if (!(pmem = diva_os_malloc(0, DivaSTraceGetMemotyRequirement(d->channels)))) {
		return;
	}
	memset(pmem, 0x00, DivaSTraceGetMemotyRequirement(d->channels));

	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "register");

	for (id = 1; id < ARRAY_SIZE(clients); id++) {
		if (clients[id].hDbg && (clients[id].request == d->request)) {
			diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
			diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
			diva_os_free(0, pmem);
			return;
		}
		if (clients[id].hDbg) { /* slot is busy */
			continue;
		}
		if (free_id < 0) {
			free_id = id;
		}
		if (!strcmp(clients[id].drvName, tmp)) {
			/*
			  This driver was already registered with this name
			  and slot is still free - reuse it
			*/
			free_id = id;
			break;
		}
	}

	if (free_id < 0) {
		diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
		diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
		diva_os_free(0, pmem);
		return;
	}

	id = free_id;
	clients[id].request  = d->request;
	clients[id].request_pending = 0;
	clients[id].hDbg     = &clients[id].Dbg;
	clients[id].sec      = sec;
	clients[id].usec     = usec;
	strcpy(clients[id].drvName,     tmp);
	strcpy(clients[id].Dbg.drvName, tmp);
	clients[id].Dbg.drvTag[0] = 0;
	clients[id].logical  = (int)logical;
	clients[id].channels = (int)d->channels;
	clients[id].dma_handle = -1;

	clients[id].Dbg.dbgMask    = 0;
	clients[id].dbgMask        = clients[id].Dbg.dbgMask;
	if (id) {
		clients[id].Dbg.dbgMask |= clients[free_id].last_dbgMask;
	} else {
		clients[id].last_dbgMask = 0;
	}
	clients[id].Dbg.Registered = DBG_HANDLE_REG_NEW;
	clients[id].Dbg.id         = (byte)id;
	clients[id].Dbg.dbg_end    = DI_deregister;
	clients[id].Dbg.dbg_prt    = DI_format_locked;
	clients[id].Dbg.dbg_ev     = DiProcessEventLog;
	clients[id].Dbg.dbg_irq    = DI_format_locked;
	clients[id].Dbg.next       = (pDbgHandle)DBG_MAGIC;

	{
		diva_trace_library_user_interface_t diva_maint_user_ifc = { &clients[id],
									    diva_maint_state_change_notify,
									    diva_maint_trace_notify,
									    diva_maint_error };

		/*
		  Attach to adapter management interface
		*/
		if ((clients[id].pIdiLib =
		     DivaSTraceLibraryCreateInstance((int)logical, &diva_maint_user_ifc, pmem))) {
			if (((*(clients[id].pIdiLib->DivaSTraceLibraryStart))(clients[id].pIdiLib->hLib))) {
				diva_mnt_internal_dprintf(0, DLI_ERR, "Adapter(%d) Start failed", (int)logical);
				(*(clients[id].pIdiLib->DivaSTraceLibraryFinit))(clients[id].pIdiLib->hLib);
				clients[id].pIdiLib = NULL;
			}
		} else {
			diva_mnt_internal_dprintf(0, DLI_ERR, "A(%d) management init failed", (int)logical);
		}
	}

	if (!clients[id].pIdiLib) {
		clients[id].request = NULL;
		clients[id].request_pending = 0;
		clients[id].hDbg    = NULL;
		diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
		diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
		diva_os_free(0, pmem);
		return;
	}

	/*
	  Log driver register, MAINT driver ID is '0'
	*/
	len = sprintf(tmp, "DIMAINT - drv # %d = '%s' registered",
		      id, clients[id].Dbg.drvName);

	while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
							       (word)(len + 1 + sizeof(*pmsg))))) {
		if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
			queueFreeMsg(dbg_queue);
		} else {
			break;
		}
	}

	if (pmsg) {
		pmsg->sequence    = dbg_sequence++;
		pmsg->time_sec    = sec;
		pmsg->time_usec   = usec;
		pmsg->facility    = MSG_TYPE_STRING;
		pmsg->dli         = DLI_REG;
		pmsg->drv_id      = 0; /* id 0 - DIMAINT */
		pmsg->di_cpu      = 0;
		pmsg->data_length = len + 1;

		memcpy(&pmsg[1], tmp, len + 1);
		queueCompleteMsg(pmsg);
		diva_maint_wakeup_read();
	}

	org_mask = clients[id].Dbg.dbgMask;
	clients[id].Dbg.dbgMask = 0;

	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");

	if (clients[id].request_pending) {
		clients[id].request_pending = 0;
		(*(clients[id].request))((ENTITY *)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib));
	}

	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");

	diva_set_driver_dbg_mask(id, org_mask);
}

/*
  De-Register XDI adapter
*/
void diva_mnt_remove_xdi_adapter(const DESCRIPTOR *d) {
	diva_os_spin_lock_magic_t old_irql, old_irql1;
	dword sec, usec;
	int i;
	word size;
	byte *pmem = NULL;

	diva_os_get_time(&sec, &usec);

	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "read");
	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read");

	for (i = 1; i < ARRAY_SIZE(clients); i++) {
		if (clients[i].hDbg && (clients[i].request == d->request)) {
			diva_dbg_entry_head_t *pmsg;
			char tmp[256];
			int len;

			if (clients[i].pIdiLib) {
				(*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
				clients[i].pIdiLib = NULL;

				pmem = clients[i].pmem;
				clients[i].pmem = NULL;
			}

			clients[i].hDbg    = NULL;
			clients[i].request_pending = 0;
			if (clients[i].dma_handle >= 0) {
				/*
				  Free DMA handle
				*/
				diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle);
				clients[i].dma_handle = -1;
			}
			clients[i].request = NULL;

			/*
			  Log driver register, MAINT driver ID is '0'
			*/
			len = sprintf(tmp, "DIMAINT - drv # %d = '%s' de-registered",
				      i, clients[i].Dbg.drvName);

			memset(&clients[i].Dbg, 0x00, sizeof(clients[i].Dbg));

			while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
									       (word)(len + 1 + sizeof(*pmsg))))) {
				if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
					queueFreeMsg(dbg_queue);
				} else {
					break;
				}
			}

			if (pmsg) {
				pmsg->sequence    = dbg_sequence++;
				pmsg->time_sec    = sec;
				pmsg->time_usec   = usec;
				pmsg->facility    = MSG_TYPE_STRING;
				pmsg->dli         = DLI_REG;
				pmsg->drv_id      = 0; /* id 0 - DIMAINT */
				pmsg->di_cpu      = 0;
				pmsg->data_length = len + 1;

				memcpy(&pmsg[1], tmp, len + 1);
				queueCompleteMsg(pmsg);
				diva_maint_wakeup_read();
			}

			break;
		}
	}

	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_ack");
	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "read_ack");

	if (pmem) {
		diva_os_free(0, pmem);
	}
}

/* ----------------------------------------------------------------
   Low level interface for management interface client
   ---------------------------------------------------------------- */
/*
  Return handle to client structure
*/
void *SuperTraceOpenAdapter(int AdapterNumber) {
	int i;

	for (i = 1; i < ARRAY_SIZE(clients); i++) {
		if (clients[i].hDbg && clients[i].request && (clients[i].logical == AdapterNumber)) {
			return (&clients[i]);
		}
	}

	return NULL;
}

int SuperTraceCloseAdapter(void *AdapterHandle) {
	return (0);
}

int SuperTraceReadRequest(void *AdapterHandle, const char *name, byte *data) {
	diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;

	if (pC && pC->pIdiLib && pC->request) {
		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
		byte *xdata = (byte *)&pC->xbuffer[0];
		char tmp = 0;
		word length;

		if (!strcmp(name, "\\")) { /* Read ROOT */
			name = &tmp;
		}
		length = SuperTraceCreateReadReq(xdata, name);
		single_p(xdata, &length, 0); /* End Of Message */

		e->Req        = MAN_READ;
		e->ReqCh      = 0;
		e->X->PLength = length;
		e->X->P	= (byte *)xdata;

		pC->request_pending = 1;

		return (0);
	}

	return (-1);
}

int SuperTraceGetNumberOfChannels(void *AdapterHandle) {
	if (AdapterHandle) {
		diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;

		return (pC->channels);
	}

	return (0);
}

int SuperTraceASSIGN(void *AdapterHandle, byte *data) {
	diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;

	if (pC && pC->pIdiLib && pC->request) {
		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
		IDI_SYNC_REQ *preq;
		char buffer[((sizeof(preq->xdi_extended_features) + 4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features) + 4) : sizeof(ENTITY)];
		char features[4];
		word assign_data_length = 1;

		features[0] = 0;
		pC->xbuffer[0] = 0;
		preq = (IDI_SYNC_REQ *)&buffer[0];
		preq->xdi_extended_features.Req = 0;
		preq->xdi_extended_features.Rc  = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES;
		preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features);
		preq->xdi_extended_features.info.features = &features[0];

		(*(pC->request))((ENTITY *)preq);

		if ((features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) &&
		    (features[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA)) {
			dword uninitialized_var(rx_dma_magic);
			if ((pC->dma_handle = diva_get_dma_descriptor(pC->request, &rx_dma_magic)) >= 0) {
				pC->xbuffer[0] = LLI;
				pC->xbuffer[1] = 8;
				pC->xbuffer[2] = 0x40;
				pC->xbuffer[3] = (byte)pC->dma_handle;
				pC->xbuffer[4] = (byte)rx_dma_magic;
				pC->xbuffer[5] = (byte)(rx_dma_magic >>  8);
				pC->xbuffer[6] = (byte)(rx_dma_magic >> 16);
				pC->xbuffer[7] = (byte)(rx_dma_magic >> 24);
				pC->xbuffer[8] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE & 0xFF);
				pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8);
				pC->xbuffer[10] = 0;

				assign_data_length = 11;
			}
		} else {
			pC->dma_handle = -1;
		}

		e->Id          = MAN_ID;
		e->callback    = diva_maint_xdi_cb;
		e->XNum        = 1;
		e->X           = &pC->XData;
		e->Req         = ASSIGN;
		e->ReqCh       = 0;
		e->X->PLength  = assign_data_length;
		e->X->P        = (byte *)&pC->xbuffer[0];

		pC->request_pending = 1;

		return (0);
	}

	return (-1);
}

int SuperTraceREMOVE(void *AdapterHandle) {
	diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;

	if (pC && pC->pIdiLib && pC->request) {
		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);

		e->XNum        = 1;
		e->X           = &pC->XData;
		e->Req         = REMOVE;
		e->ReqCh       = 0;
		e->X->PLength  = 1;
		e->X->P        = (byte *)&pC->xbuffer[0];
		pC->xbuffer[0] = 0;

		pC->request_pending = 1;

		return (0);
	}

	return (-1);
}

int SuperTraceTraceOnRequest(void *hAdapter, const char *name, byte *data) {
	diva_maint_client_t *pC = (diva_maint_client_t *)hAdapter;

	if (pC && pC->pIdiLib && pC->request) {
		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
		byte *xdata = (byte *)&pC->xbuffer[0];
		char tmp = 0;
		word length;

		if (!strcmp(name, "\\")) { /* Read ROOT */
			name = &tmp;
		}
		length = SuperTraceCreateReadReq(xdata, name);
		single_p(xdata, &length, 0); /* End Of Message */
		e->Req          = MAN_EVENT_ON;
		e->ReqCh        = 0;
		e->X->PLength   = length;
		e->X->P = (byte *)xdata;

		pC->request_pending = 1;

		return (0);
	}

	return (-1);
}

int SuperTraceWriteVar(void *AdapterHandle,
		       byte *data,
		       const char *name,
		       void *var,
		       byte type,
		       byte var_length) {
	diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;

	if (pC && pC->pIdiLib && pC->request) {
		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
		diva_man_var_header_t *pVar = (diva_man_var_header_t *)&pC->xbuffer[0];
		word length = SuperTraceCreateReadReq((byte *)pVar, name);

		memcpy(&pC->xbuffer[length], var, var_length);
		length += var_length;
		pVar->length += var_length;
		pVar->value_length = var_length;
		pVar->type = type;
		single_p((byte *)pVar, &length, 0); /* End Of Message */

		e->Req = MAN_WRITE;
		e->ReqCh = 0;
		e->X->PLength   = length;
		e->X->P = (byte *)pVar;

		pC->request_pending = 1;

		return (0);
	}

	return (-1);
}

int SuperTraceExecuteRequest(void *AdapterHandle,
			     const char *name,
			     byte *data) {
	diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;

	if (pC && pC->pIdiLib && pC->request) {
		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
		byte *xdata = (byte *)&pC->xbuffer[0];
		word length;

		length = SuperTraceCreateReadReq(xdata, name);
		single_p(xdata, &length, 0); /* End Of Message */

		e->Req = MAN_EXECUTE;
		e->ReqCh = 0;
		e->X->PLength = length;
		e->X->P = (byte *)xdata;

		pC->request_pending = 1;

		return (0);
	}

	return (-1);
}

static word SuperTraceCreateReadReq(byte *P, const char *path) {
	byte var_length;
	byte *plen;

	var_length = (byte)strlen(path);

	*P++ = ESC;
	plen = P++;
	*P++ = 0x80; /* MAN_IE */
	*P++ = 0x00; /* Type */
	*P++ = 0x00; /* Attribute */
	*P++ = 0x00; /* Status */
	*P++ = 0x00; /* Variable Length */
	*P++ = var_length;
	memcpy(P, path, var_length);
	P += var_length;
	*plen = var_length + 0x06;

	return ((word)(var_length + 0x08));
}

static void single_p(byte *P, word *PLength, byte Id) {
	P[(*PLength)++] = Id;
}

static void diva_maint_xdi_cb(ENTITY *e) {
	diva_strace_context_t *pLib = DIVAS_CONTAINING_RECORD(e, diva_strace_context_t, e);
	diva_maint_client_t *pC;
	diva_os_spin_lock_magic_t old_irql, old_irql1;


	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "xdi_cb");
	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "xdi_cb");

	pC = (diva_maint_client_t *)pLib->hAdapter;

	if ((e->complete == 255) || (pC->dma_handle < 0)) {
		if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) {
			diva_mnt_internal_dprintf(0, DLI_ERR, "Trace internal library error");
		}
	} else {
		/*
		  Process combined management interface indication
		*/
		if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) {
			diva_mnt_internal_dprintf(0, DLI_ERR, "Trace internal library error (DMA mode)");
		}
	}

	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "xdi_cb");


	if (pC->request_pending) {
		pC->request_pending = 0;
		(*(pC->request))(e);
	}

	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "xdi_cb");
}


static void diva_maint_error(void *user_context,
			     diva_strace_library_interface_t *hLib,
			     int Adapter,
			     int error,
			     const char *file,
			     int line) {
	diva_mnt_internal_dprintf(0, DLI_ERR,
				  "Trace library error(%d) A(%d) %s %d", error, Adapter, file, line);
}

static void print_ie(diva_trace_ie_t *ie, char *buffer, int length) {
	int i;

	buffer[0] = 0;

	if (length > 32) {
		for (i = 0; ((i < ie->length) && (length > 3)); i++) {
			sprintf(buffer, "%02x", ie->data[i]);
			buffer += 2;
			length -= 2;
			if (i < (ie->length - 1)) {
				strcpy(buffer, " ");
				buffer++;
				length--;
			}
		}
	}
}

static void diva_maint_state_change_notify(void *user_context,
					   diva_strace_library_interface_t *hLib,
					   int Adapter,
					   diva_trace_line_state_t *channel,
					   int notify_subject) {
	diva_maint_client_t *pC = (diva_maint_client_t *)user_context;
	diva_trace_fax_state_t *fax = &channel->fax;
	diva_trace_modem_state_t *modem = &channel->modem;
	char tmp[256];

	if (!pC->hDbg) {
		return;
	}

	switch (notify_subject) {
	case DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE: {
		int view = (TraceFilter[0] == 0);
		/*
		  Process selective Trace
		*/
		if (channel->Line[0] == 'I' && channel->Line[1] == 'd' &&
		    channel->Line[2] == 'l' && channel->Line[3] == 'e') {
			if ((TraceFilterIdent == pC->hDbg->id) && (TraceFilterChannel == (int)channel->ChannelNumber)) {
				(*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 0);
				(*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 0);
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, "Selective Trace OFF for Ch=%d",
							  (int)channel->ChannelNumber);
				TraceFilterIdent   = -1;
				TraceFilterChannel = -1;
				view = 1;
			}
		} else if (TraceFilter[0] && (TraceFilterIdent < 0) && !(diva_mnt_cmp_nmbr(&channel->RemoteAddress[0]) &&
									 diva_mnt_cmp_nmbr(&channel->LocalAddress[0]))) {

			if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0) { /* Activate B-channel trace */
				(*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 1);
			}
			if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0) { /* Activate AudioTap Trace */
				(*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 1);
			}

			TraceFilterIdent   = pC->hDbg->id;
			TraceFilterChannel = (int)channel->ChannelNumber;

			if (TraceFilterIdent >= 0) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, "Selective Trace ON for Ch=%d",
							  (int)channel->ChannelNumber);
				view = 1;
			}
		}
		if (view && (pC->hDbg->dbgMask & DIVA_MGT_DBG_LINE_EVENTS)) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Ch     = %d",
						  (int)channel->ChannelNumber);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Status = <%s>", &channel->Line[0]);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer1 = <%s>", &channel->Framing[0]);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer2 = <%s>", &channel->Layer2[0]);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer3 = <%s>", &channel->Layer3[0]);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L RAddr  = <%s>",
						  &channel->RemoteAddress[0]);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L RSAddr = <%s>",
						  &channel->RemoteSubAddress[0]);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LAddr  = <%s>",
						  &channel->LocalAddress[0]);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LSAddr = <%s>",
						  &channel->LocalSubAddress[0]);
			print_ie(&channel->call_BC, tmp, sizeof(tmp));
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L BC     = <%s>", tmp);
			print_ie(&channel->call_HLC, tmp, sizeof(tmp));
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L HLC    = <%s>", tmp);
			print_ie(&channel->call_LLC, tmp, sizeof(tmp));
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LLC    = <%s>", tmp);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L CR     = 0x%x", channel->CallReference);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Disc   = 0x%x",
						  channel->LastDisconnecCause);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Owner  = <%s>", &channel->UserID[0]);
		}

	} break;

	case DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE:
		if (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_PROGRESS) {
			{
				int ch = TraceFilterChannel;
				int id = TraceFilterIdent;

				if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
				    (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
					if (ch != (int)modem->ChannelNumber) {
						break;
					}
				} else if (TraceFilter[0] != 0) {
					break;
				}
			}


			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Ch    = %lu",
						  (int)modem->ChannelNumber);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Event = %lu", modem->Event);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Norm  = %lu", modem->Norm);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Opts. = 0x%08x", modem->Options);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Tx    = %lu Bps", modem->TxSpeed);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rx    = %lu Bps", modem->RxSpeed);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RT    = %lu mSec",
						  modem->RoundtripMsec);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Sr    = %lu", modem->SymbolRate);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rxl   = %d dBm", modem->RxLeveldBm);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM El    = %d dBm", modem->EchoLeveldBm);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM SNR   = %lu dB", modem->SNRdb);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM MAE   = %lu", modem->MAE);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRet  = %lu",
						  modem->LocalRetrains);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRet  = %lu",
						  modem->RemoteRetrains);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRes  = %lu", modem->LocalResyncs);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRes  = %lu",
						  modem->RemoteResyncs);
			if (modem->Event == 3) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Disc  =  %lu", modem->DiscReason);
			}
		}
		if ((modem->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_STATISTICS)) {
			(*(pC->pIdiLib->DivaSTraceGetModemStatistics))(pC->pIdiLib);
		}
		break;

	case DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE:
		if (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_PROGRESS) {
			{
				int ch = TraceFilterChannel;
				int id = TraceFilterIdent;

				if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
				    (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
					if (ch != (int)fax->ChannelNumber) {
						break;
					}
				} else if (TraceFilter[0] != 0) {
					break;
				}
			}

			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Ch    = %lu", (int)fax->ChannelNumber);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Event = %lu",     fax->Event);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pages = %lu",     fax->Page_Counter);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Feat. = 0x%08x",  fax->Features);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX ID    = <%s>",    &fax->Station_ID[0]);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Saddr = <%s>",    &fax->Subaddress[0]);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pwd   = <%s>",    &fax->Password[0]);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Speed = %lu",     fax->Speed);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Res.  = 0x%08x",  fax->Resolution);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Width = %lu",     fax->Paper_Width);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Length= %lu",     fax->Paper_Length);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX SLT   = %lu",     fax->Scanline_Time);
			if (fax->Event == 3) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Disc  = %lu",     fax->Disc_Reason);
			}
		}
		if ((fax->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_STATISTICS)) {
			(*(pC->pIdiLib->DivaSTraceGetFaxStatistics))(pC->pIdiLib);
		}
		break;

	case DIVA_SUPER_TRACE_INTERFACE_CHANGE:
		if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_EVENTS) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT,
						  "Layer 1 -> [%s]", channel->pInterface->Layer1);
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT,
						  "Layer 2 -> [%s]", channel->pInterface->Layer2);
		}
		break;

	case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE:
		if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_STATISTICS) {
			/*
			  Incoming Statistics
			*/
			if (channel->pInterfaceStat->inc.Calls) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Inc Calls                     =%lu", channel->pInterfaceStat->inc.Calls);
			}
			if (channel->pInterfaceStat->inc.Connected) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Inc Connected                 =%lu", channel->pInterfaceStat->inc.Connected);
			}
			if (channel->pInterfaceStat->inc.User_Busy) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Inc Busy                      =%lu", channel->pInterfaceStat->inc.User_Busy);
			}
			if (channel->pInterfaceStat->inc.Call_Rejected) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Inc Rejected                  =%lu", channel->pInterfaceStat->inc.Call_Rejected);
			}
			if (channel->pInterfaceStat->inc.Wrong_Number) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Inc Wrong Nr                  =%lu", channel->pInterfaceStat->inc.Wrong_Number);
			}
			if (channel->pInterfaceStat->inc.Incompatible_Dst) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Inc Incomp. Dest              =%lu", channel->pInterfaceStat->inc.Incompatible_Dst);
			}
			if (channel->pInterfaceStat->inc.Out_of_Order) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Inc Out of Order              =%lu", channel->pInterfaceStat->inc.Out_of_Order);
			}
			if (channel->pInterfaceStat->inc.Ignored) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Inc Ignored                   =%lu", channel->pInterfaceStat->inc.Ignored);
			}

			/*
			  Outgoing Statistics
			*/
			if (channel->pInterfaceStat->outg.Calls) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Outg Calls                    =%lu", channel->pInterfaceStat->outg.Calls);
			}
			if (channel->pInterfaceStat->outg.Connected) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Outg Connected                =%lu", channel->pInterfaceStat->outg.Connected);
			}
			if (channel->pInterfaceStat->outg.User_Busy) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Outg Busy                     =%lu", channel->pInterfaceStat->outg.User_Busy);
			}
			if (channel->pInterfaceStat->outg.No_Answer) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Outg No Answer                =%lu", channel->pInterfaceStat->outg.No_Answer);
			}
			if (channel->pInterfaceStat->outg.Wrong_Number) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Outg Wrong Nr                 =%lu", channel->pInterfaceStat->outg.Wrong_Number);
			}
			if (channel->pInterfaceStat->outg.Call_Rejected) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Outg Rejected                 =%lu", channel->pInterfaceStat->outg.Call_Rejected);
			}
			if (channel->pInterfaceStat->outg.Other_Failures) {
				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
							  "Outg Other Failures           =%lu", channel->pInterfaceStat->outg.Other_Failures);
			}
		}
		break;

	case DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE:
		if (channel->pInterfaceStat->mdm.Disc_Normal) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "MDM Disc Normal        = %lu", channel->pInterfaceStat->mdm.Disc_Normal);
		}
		if (channel->pInterfaceStat->mdm.Disc_Unspecified) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "MDM Disc Unsp.         = %lu", channel->pInterfaceStat->mdm.Disc_Unspecified);
		}
		if (channel->pInterfaceStat->mdm.Disc_Busy_Tone) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "MDM Disc Busy Tone     = %lu", channel->pInterfaceStat->mdm.Disc_Busy_Tone);
		}
		if (channel->pInterfaceStat->mdm.Disc_Congestion) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "MDM Disc Congestion    = %lu", channel->pInterfaceStat->mdm.Disc_Congestion);
		}
		if (channel->pInterfaceStat->mdm.Disc_Carr_Wait) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "MDM Disc Carrier Wait  = %lu", channel->pInterfaceStat->mdm.Disc_Carr_Wait);
		}
		if (channel->pInterfaceStat->mdm.Disc_Trn_Timeout) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "MDM Disc Trn. T.o.     = %lu", channel->pInterfaceStat->mdm.Disc_Trn_Timeout);
		}
		if (channel->pInterfaceStat->mdm.Disc_Incompat) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "MDM Disc Incompatible  = %lu", channel->pInterfaceStat->mdm.Disc_Incompat);
		}
		if (channel->pInterfaceStat->mdm.Disc_Frame_Rej) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "MDM Disc Frame Reject  = %lu", channel->pInterfaceStat->mdm.Disc_Frame_Rej);
		}
		if (channel->pInterfaceStat->mdm.Disc_V42bis) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "MDM Disc V.42bis       = %lu", channel->pInterfaceStat->mdm.Disc_V42bis);
		}
		break;

	case DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE:
		if (channel->pInterfaceStat->fax.Disc_Normal) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Normal        = %lu", channel->pInterfaceStat->fax.Disc_Normal);
		}
		if (channel->pInterfaceStat->fax.Disc_Not_Ident) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Not Ident.    = %lu", channel->pInterfaceStat->fax.Disc_Not_Ident);
		}
		if (channel->pInterfaceStat->fax.Disc_No_Response) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc No Response   = %lu", channel->pInterfaceStat->fax.Disc_No_Response);
		}
		if (channel->pInterfaceStat->fax.Disc_Retries) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Max Retries   = %lu", channel->pInterfaceStat->fax.Disc_Retries);
		}
		if (channel->pInterfaceStat->fax.Disc_Unexp_Msg) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Unexp. Msg.        = %lu", channel->pInterfaceStat->fax.Disc_Unexp_Msg);
		}
		if (channel->pInterfaceStat->fax.Disc_No_Polling) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc No Polling    = %lu", channel->pInterfaceStat->fax.Disc_No_Polling);
		}
		if (channel->pInterfaceStat->fax.Disc_Training) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Training      = %lu", channel->pInterfaceStat->fax.Disc_Training);
		}
		if (channel->pInterfaceStat->fax.Disc_Unexpected) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Unexpected    = %lu", channel->pInterfaceStat->fax.Disc_Unexpected);
		}
		if (channel->pInterfaceStat->fax.Disc_Application) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Application   = %lu", channel->pInterfaceStat->fax.Disc_Application);
		}
		if (channel->pInterfaceStat->fax.Disc_Incompat) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Incompatible  = %lu", channel->pInterfaceStat->fax.Disc_Incompat);
		}
		if (channel->pInterfaceStat->fax.Disc_No_Command) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc No Command    = %lu", channel->pInterfaceStat->fax.Disc_No_Command);
		}
		if (channel->pInterfaceStat->fax.Disc_Long_Msg) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Long Msg.     = %lu", channel->pInterfaceStat->fax.Disc_Long_Msg);
		}
		if (channel->pInterfaceStat->fax.Disc_Supervisor) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Supervisor    = %lu", channel->pInterfaceStat->fax.Disc_Supervisor);
		}
		if (channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc SUP SEP PWD   = %lu", channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD);
		}
		if (channel->pInterfaceStat->fax.Disc_Invalid_Msg) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Invalid Msg.  = %lu", channel->pInterfaceStat->fax.Disc_Invalid_Msg);
		}
		if (channel->pInterfaceStat->fax.Disc_Page_Coding) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Page Coding   = %lu", channel->pInterfaceStat->fax.Disc_Page_Coding);
		}
		if (channel->pInterfaceStat->fax.Disc_App_Timeout) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Appl. T.o.    = %lu", channel->pInterfaceStat->fax.Disc_App_Timeout);
		}
		if (channel->pInterfaceStat->fax.Disc_Unspecified) {
			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
						  "FAX Disc Unspec.       = %lu", channel->pInterfaceStat->fax.Disc_Unspecified);
		}
		break;
	}
}

/*
  Receive trace information from the Management Interface and store it in the
  internal trace buffer with MSG_TYPE_MLOG as is, without any filtering.
  Event Filtering and formatting is done in  Management Interface self.
*/
static void diva_maint_trace_notify(void *user_context,
				    diva_strace_library_interface_t *hLib,
				    int Adapter,
				    void *xlog_buffer,
				    int length) {
	diva_maint_client_t *pC = (diva_maint_client_t *)user_context;
	diva_dbg_entry_head_t *pmsg;
	word size;
	dword sec, usec;
	int ch = TraceFilterChannel;
	int id = TraceFilterIdent;

	/*
	  Selective trace
	*/
	if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
	    (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
		const char *p = NULL;
		int ch_value = -1;
		MI_XLOG_HDR *TrcData = (MI_XLOG_HDR *)xlog_buffer;

		if (Adapter != clients[id].logical) {
			return; /* Ignore all trace messages from other adapters */
		}

		if (TrcData->code == 24) {
			p = (char *)&TrcData->code;
			p += 2;
		}

		/*
		  All L1 messages start as [dsp,ch], so we can filter this information
		  and filter out all messages that use different channel
		*/
		if (p && p[0] == '[') {
			if (p[2] == ',') {
				p += 3;
				ch_value = *p - '0';
			} else if (p[3] == ',') {
				p += 4;
				ch_value = *p - '0';
			}
			if (ch_value >= 0) {
				if (p[2] == ']') {
					ch_value = ch_value * 10 + p[1] - '0';
				}
				if (ch_value != ch) {
					return; /* Ignore other channels */
				}
			}
		}

	} else if (TraceFilter[0] != 0) {
		return; /* Ignore trace if trace filter is activated, but idle */
	}

	diva_os_get_time(&sec, &usec);

	while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
							       (word)length + sizeof(*pmsg)))) {
		if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
			queueFreeMsg(dbg_queue);
		} else {
			break;
		}
	}
	if (pmsg) {
		memcpy(&pmsg[1], xlog_buffer, length);
		pmsg->sequence    = dbg_sequence++;
		pmsg->time_sec    = sec;
		pmsg->time_usec   = usec;
		pmsg->facility    = MSG_TYPE_MLOG;
		pmsg->dli         = pC->logical;
		pmsg->drv_id      = pC->hDbg->id;
		pmsg->di_cpu      = 0;
		pmsg->data_length = length;
		queueCompleteMsg(pmsg);
		if (queueCount(dbg_queue)) {
			diva_maint_wakeup_read();
		}
	}
}


/*
  Convert MAINT trace mask to management interface trace mask/work/facility and
  issue command to management interface
*/
static void diva_change_management_debug_mask(diva_maint_client_t *pC, dword old_mask) {
	if (pC->request && pC->hDbg && pC->pIdiLib) {
		dword changed = pC->hDbg->dbgMask ^ old_mask;

		if (changed & DIVA_MGT_DBG_TRACE) {
			(*(pC->pIdiLib->DivaSTraceSetInfo))(pC->pIdiLib,
							    (pC->hDbg->dbgMask & DIVA_MGT_DBG_TRACE) != 0);
		}
		if (changed & DIVA_MGT_DBG_DCHAN) {
			(*(pC->pIdiLib->DivaSTraceSetDChannel))(pC->pIdiLib,
								(pC->hDbg->dbgMask & DIVA_MGT_DBG_DCHAN) != 0);
		}
		if (!TraceFilter[0]) {
			if (changed & DIVA_MGT_DBG_IFC_BCHANNEL) {
				int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0);

				for (i = 0; i < pC->channels; i++) {
					(*(pC->pIdiLib->DivaSTraceSetBChannel))(pC->pIdiLib, i + 1, state);
				}
			}
			if (changed & DIVA_MGT_DBG_IFC_AUDIO) {
				int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0);

				for (i = 0; i < pC->channels; i++) {
					(*(pC->pIdiLib->DivaSTraceSetAudioTap))(pC->pIdiLib, i + 1, state);
				}
			}
		}
	}
}


void diva_mnt_internal_dprintf(dword drv_id, dword type, char *fmt, ...) {
	va_list ap;

	va_start(ap, fmt);
	DI_format(0, (word)drv_id, (int)type, fmt, ap);
	va_end(ap);
}

/*
  Shutdown all adapters before driver removal
*/
int diva_mnt_shutdown_xdi_adapters(void) {
	diva_os_spin_lock_magic_t old_irql, old_irql1;
	int i, fret = 0;
	byte *pmem;


	for (i = 1; i < ARRAY_SIZE(clients); i++) {
		pmem = NULL;

		diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "unload");
		diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "unload");

		if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) {
			if ((*(clients[i].pIdiLib->DivaSTraceLibraryStop))(clients[i].pIdiLib) == 1) {
				/*
				  Adapter removal complete
				*/
				if (clients[i].pIdiLib) {
					(*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
					clients[i].pIdiLib = NULL;

					pmem = clients[i].pmem;
					clients[i].pmem = NULL;
				}
				clients[i].hDbg    = NULL;
				clients[i].request_pending = 0;

				if (clients[i].dma_handle >= 0) {
					/*
					  Free DMA handle
					*/
					diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle);
					clients[i].dma_handle = -1;
				}
				clients[i].request = NULL;
			} else {
				fret = -1;
			}
		}

		diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "unload");
		if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {
			clients[i].request_pending = 0;
			(*(clients[i].request))((ENTITY *)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));
			if (clients[i].dma_handle >= 0) {
				diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle);
				clients[i].dma_handle = -1;
			}
		}
		diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "unload");

		if (pmem) {
			diva_os_free(0, pmem);
		}
	}

	return (fret);
}

/*
  Set/Read the trace filter used for selective tracing.
  Affects B- and Audio Tap trace mask at run time
*/
int diva_set_trace_filter(int filter_length, const char *filter) {
	diva_os_spin_lock_magic_t old_irql, old_irql1;
	int i, ch, on, client_b_on, client_atap_on;

	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");
	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "write_filter");

	if (filter_length <= DIVA_MAX_SELECTIVE_FILTER_LENGTH) {
		memcpy(&TraceFilter[0], filter, filter_length);
		if (TraceFilter[filter_length]) {
			TraceFilter[filter_length] = 0;
		}
		if (TraceFilter[0] == '*') {
			TraceFilter[0] = 0;
		}
	} else {
		filter_length = -1;
	}

	TraceFilterIdent   = -1;
	TraceFilterChannel = -1;

	on = (TraceFilter[0] == 0);

	for (i = 1; i < ARRAY_SIZE(clients); i++) {
		if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) {
			client_b_on    = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0);
			client_atap_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO)    != 0);
			for (ch = 0; ch < clients[i].channels; ch++) {
				(*(clients[i].pIdiLib->DivaSTraceSetBChannel))(clients[i].pIdiLib->hLib, ch + 1, client_b_on);
				(*(clients[i].pIdiLib->DivaSTraceSetAudioTap))(clients[i].pIdiLib->hLib, ch + 1, client_atap_on);
			}
		}
	}

	for (i = 1; i < ARRAY_SIZE(clients); i++) {
		if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {
			diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "write_filter");
			clients[i].request_pending = 0;
			(*(clients[i].request))((ENTITY *)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));
			diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "write_filter");
		}
	}

	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "write_filter");
	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");

	return (filter_length);
}

int diva_get_trace_filter(int max_length, char *filter) {
	diva_os_spin_lock_magic_t old_irql;
	int len;

	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read_filter");
	len = strlen(&TraceFilter[0]) + 1;
	if (max_length >= len) {
		memcpy(filter, &TraceFilter[0], len);
	}
	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_filter");

	return (len);
}

static int diva_dbg_cmp_key(const char *ref, const char *key) {
	while (*key && (*ref++ == *key++));
	return (!*key && !*ref);
}

/*
  In case trace filter starts with "C" character then
  all following characters are interpreted as command.
  Following commands are available:
  - single, trace single call at time, independent from CPN/CiPN
*/
static int diva_mnt_cmp_nmbr(const char *nmbr) {
	const char *ref = &TraceFilter[0];
	int ref_len = strlen(&TraceFilter[0]), nmbr_len = strlen(nmbr);

	if (ref[0] == 'C') {
		if (diva_dbg_cmp_key(&ref[1], "single")) {
			return (0);
		}
		return (-1);
	}

	if (!ref_len || (ref_len > nmbr_len)) {
		return (-1);
	}

	nmbr = nmbr + nmbr_len - 1;
	ref  = ref  + ref_len  - 1;

	while (ref_len--) {
		if (*nmbr-- != *ref--) {
			return (-1);
		}
	}

	return (0);
}

static int diva_get_dma_descriptor(IDI_CALL request, dword *dma_magic) {
	ENTITY e;
	IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;

	if (!request) {
		return (-1);
	}

	pReq->xdi_dma_descriptor_operation.Req = 0;
	pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;

	pReq->xdi_dma_descriptor_operation.info.operation =     IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC;
	pReq->xdi_dma_descriptor_operation.info.descriptor_number  = -1;
	pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
	pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;

	(*request)((ENTITY *)pReq);

	if (!pReq->xdi_dma_descriptor_operation.info.operation &&
	    (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) &&
	    pReq->xdi_dma_descriptor_operation.info.descriptor_magic) {
		*dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic;
		return (pReq->xdi_dma_descriptor_operation.info.descriptor_number);
	} else {
		return (-1);
	}
}

static void diva_free_dma_descriptor(IDI_CALL request, int nr) {
	ENTITY e;
	IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;

	if (!request || (nr < 0)) {
		return;
	}

	pReq->xdi_dma_descriptor_operation.Req = 0;
	pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;

	pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE;
	pReq->xdi_dma_descriptor_operation.info.descriptor_number  = nr;
	pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
	pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;

	(*request)((ENTITY *)pReq);
}
