#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;
static dword               start_sec;
static dword               start_usec;

/*
	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;

  diva_os_get_time (&start_sec, &start_usec);

  *(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, best_id = 0, 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;
      best_id = 1;
      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.
  Followings 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);
}

