Path: blob/master/drivers/isdn/hardware/eicon/debug.c
15115 views
#include "platform.h"1#include "pc.h"2#include "di_defs.h"3#include "debug_if.h"4#include "divasync.h"5#include "kst_ifc.h"6#include "maintidi.h"7#include "man_defs.h"89/*10LOCALS11*/12#define DBG_MAGIC (0x47114711L)1314static void DI_register (void *arg);15static void DI_deregister (pDbgHandle hDbg);16static void DI_format (int do_lock, word id, int type, char *format, va_list argument_list);17static void DI_format_locked (word id, int type, char *format, va_list argument_list);18static void DI_format_old (word id, char *format, va_list ap) { }19static void DiProcessEventLog (unsigned short id, unsigned long msgID, va_list ap) { }20static void single_p (byte * P, word * PLength, byte Id);21static void diva_maint_xdi_cb (ENTITY* e);22static word SuperTraceCreateReadReq (byte* P, const char* path);23static int diva_mnt_cmp_nmbr (const char* nmbr);24static void diva_free_dma_descriptor (IDI_CALL request, int nr);25static int diva_get_dma_descriptor (IDI_CALL request, dword *dma_magic);26void diva_mnt_internal_dprintf (dword drv_id, dword type, char* p, ...);2728static dword MaxDumpSize = 256 ;29static dword MaxXlogSize = 2 + 128 ;30static char TraceFilter[DIVA_MAX_SELECTIVE_FILTER_LENGTH+1];31static int TraceFilterIdent = -1;32static int TraceFilterChannel = -1;3334typedef struct _diva_maint_client {35dword sec;36dword usec;37pDbgHandle hDbg;38char drvName[128];39dword dbgMask;40dword last_dbgMask;41IDI_CALL request;42_DbgHandle_ Dbg;43int logical;44int channels;45diva_strace_library_interface_t* pIdiLib;46BUFFERS XData;47char xbuffer[2048+512];48byte* pmem;49int request_pending;50int dma_handle;51} diva_maint_client_t;52static diva_maint_client_t clients[MAX_DESCRIPTORS];5354static void diva_change_management_debug_mask (diva_maint_client_t* pC, dword old_mask);5556static void diva_maint_error (void* user_context,57diva_strace_library_interface_t* hLib,58int Adapter,59int error,60const char* file,61int line);62static void diva_maint_state_change_notify (void* user_context,63diva_strace_library_interface_t* hLib,64int Adapter,65diva_trace_line_state_t* channel,66int notify_subject);67static void diva_maint_trace_notify (void* user_context,68diva_strace_library_interface_t* hLib,69int Adapter,70void* xlog_buffer,71int length);72737475typedef struct MSG_QUEUE {76dword Size; /* total size of queue (constant) */77byte *Base; /* lowest address (constant) */78byte *High; /* Base + Size (constant) */79byte *Head; /* first message in queue (if any) */80byte *Tail; /* first free position */81byte *Wrap; /* current wraparound position */82dword Count; /* current no of bytes in queue */83} MSG_QUEUE;8485typedef struct MSG_HEAD {86volatile dword Size; /* size of data following MSG_HEAD */87#define MSG_INCOMPLETE 0x8000 /* ored to Size until queueCompleteMsg */88} MSG_HEAD;8990#define queueCompleteMsg(p) do{ ((MSG_HEAD *)p - 1)->Size &= ~MSG_INCOMPLETE; }while(0)91#define queueCount(q) ((q)->Count)92#define MSG_NEED(size) \93( (sizeof(MSG_HEAD) + size + sizeof(dword) - 1) & ~(sizeof(dword) - 1) )9495static void queueInit (MSG_QUEUE *Q, byte *Buffer, dword sizeBuffer) {96Q->Size = sizeBuffer;97Q->Base = Q->Head = Q->Tail = Buffer;98Q->High = Buffer + sizeBuffer;99Q->Wrap = NULL;100Q->Count= 0;101}102103static byte *queueAllocMsg (MSG_QUEUE *Q, word size) {104/* Allocate 'size' bytes at tail of queue which will be filled later105* directly with callers own message header info and/or message.106* An 'alloced' message is marked incomplete by oring the 'Size' field107* with MSG_INCOMPLETE.108* This must be reset via queueCompleteMsg() after the message is filled.109* As long as a message is marked incomplete queuePeekMsg() will return110* a 'queue empty' condition when it reaches such a message. */111112MSG_HEAD *Msg;113word need = MSG_NEED(size);114115if (Q->Tail == Q->Head) {116if (Q->Wrap || need > Q->Size) {117return NULL; /* full */118}119goto alloc; /* empty */120}121122if (Q->Tail > Q->Head) {123if (Q->Tail + need <= Q->High) goto alloc; /* append */124if (Q->Base + need > Q->Head) {125return NULL; /* too much */126}127/* wraparound the queue (but not the message) */128Q->Wrap = Q->Tail;129Q->Tail = Q->Base;130goto alloc;131}132133if (Q->Tail + need > Q->Head) {134return NULL; /* too much */135}136137alloc:138Msg = (MSG_HEAD *)Q->Tail;139140Msg->Size = size | MSG_INCOMPLETE;141142Q->Tail += need;143Q->Count += size;144145146147return ((byte*)(Msg + 1));148}149150static void queueFreeMsg (MSG_QUEUE *Q) {151/* Free the message at head of queue */152153word size = ((MSG_HEAD *)Q->Head)->Size & ~MSG_INCOMPLETE;154155Q->Head += MSG_NEED(size);156Q->Count -= size;157158if (Q->Wrap) {159if (Q->Head >= Q->Wrap) {160Q->Head = Q->Base;161Q->Wrap = NULL;162}163} else if (Q->Head >= Q->Tail) {164Q->Head = Q->Tail = Q->Base;165}166}167168static byte *queuePeekMsg (MSG_QUEUE *Q, word *size) {169/* Show the first valid message in queue BUT DON'T free the message.170* After looking on the message contents it can be freed queueFreeMsg()171* or simply remain in message queue. */172173MSG_HEAD *Msg = (MSG_HEAD *)Q->Head;174175if (((byte *)Msg == Q->Tail && !Q->Wrap) ||176(Msg->Size & MSG_INCOMPLETE)) {177return NULL;178} else {179*size = Msg->Size;180return ((byte *)(Msg + 1));181}182}183184/*185Message queue header186*/187static MSG_QUEUE* dbg_queue;188static byte* dbg_base;189static int external_dbg_queue;190static diva_os_spin_lock_t dbg_q_lock;191static diva_os_spin_lock_t dbg_adapter_lock;192static int dbg_q_busy;193static volatile dword dbg_sequence;194static dword start_sec;195static dword start_usec;196197/*198INTERFACE:199Initialize run time queue structures.200base: base of the message queue201length: length of the message queue202do_init: perfor queue reset203204return: zero on success, -1 on error205*/206int diva_maint_init (byte* base, unsigned long length, int do_init) {207if (dbg_queue || (!base) || (length < (4096*4))) {208return (-1);209}210211TraceFilter[0] = 0;212TraceFilterIdent = -1;213TraceFilterChannel = -1;214215dbg_base = base;216217diva_os_get_time (&start_sec, &start_usec);218219*(dword*)base = (dword)DBG_MAGIC; /* Store Magic */220base += sizeof(dword);221length -= sizeof(dword);222223*(dword*)base = 2048; /* Extension Field Length */224base += sizeof(dword);225length -= sizeof(dword);226227strcpy (base, "KERNEL MODE BUFFER\n");228base += 2048;229length -= 2048;230231*(dword*)base = 0; /* Terminate extension */232base += sizeof(dword);233length -= sizeof(dword);234235*(void**)base = (void*)(base+sizeof(void*)); /* Store Base */236base += sizeof(void*);237length -= sizeof(void*);238239dbg_queue = (MSG_QUEUE*)base;240queueInit (dbg_queue, base + sizeof(MSG_QUEUE), length - sizeof(MSG_QUEUE) - 512);241external_dbg_queue = 0;242243if (!do_init) {244external_dbg_queue = 1; /* memory was located on the external device */245}246247248if (diva_os_initialize_spin_lock (&dbg_q_lock, "dbg_init")) {249dbg_queue = NULL;250dbg_base = NULL;251external_dbg_queue = 0;252return (-1);253}254255if (diva_os_initialize_spin_lock (&dbg_adapter_lock, "dbg_init")) {256diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_init");257dbg_queue = NULL;258dbg_base = NULL;259external_dbg_queue = 0;260return (-1);261}262263return (0);264}265266/*267INTERFACE:268Finit at unload time269return address of internal queue or zero if queue270was external271*/272void* diva_maint_finit (void) {273void* ret = (void*)dbg_base;274int i;275276dbg_queue = NULL;277dbg_base = NULL;278279if (ret) {280diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_finit");281diva_os_destroy_spin_lock(&dbg_adapter_lock, "dbg_finit");282}283284if (external_dbg_queue) {285ret = NULL;286}287external_dbg_queue = 0;288289for (i = 1; i < ARRAY_SIZE(clients); i++) {290if (clients[i].pmem) {291diva_os_free (0, clients[i].pmem);292}293}294295return (ret);296}297298/*299INTERFACE:300Return amount of messages in debug queue301*/302dword diva_dbg_q_length (void) {303return (dbg_queue ? queueCount(dbg_queue) : 0);304}305306/*307INTERFACE:308Lock message queue and return the pointer to the first309entry.310*/311diva_dbg_entry_head_t* diva_maint_get_message (word* size,312diva_os_spin_lock_magic_t* old_irql) {313diva_dbg_entry_head_t* pmsg = NULL;314315diva_os_enter_spin_lock (&dbg_q_lock, old_irql, "read");316if (dbg_q_busy) {317diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_busy");318return NULL;319}320dbg_q_busy = 1;321322if (!(pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, size))) {323dbg_q_busy = 0;324diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_empty");325}326327return (pmsg);328}329330/*331INTERFACE:332acknowledge last message and unlock queue333*/334void diva_maint_ack_message (int do_release,335diva_os_spin_lock_magic_t* old_irql) {336if (!dbg_q_busy) {337return;338}339if (do_release) {340queueFreeMsg (dbg_queue);341}342dbg_q_busy = 0;343diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_ack");344}345346347/*348INTERFACE:349PRT COMP function used to register350with MAINT adapter or log in compatibility351mode in case older driver version is connected too352*/353void diva_maint_prtComp (char *format, ...) {354void *hDbg;355va_list ap;356357if (!format)358return;359360va_start(ap, format);361362/*363register to new log driver functions364*/365if ((format[0] == 0) && ((unsigned char)format[1] == 255)) {366hDbg = va_arg(ap, void *); /* ptr to DbgHandle */367DI_register (hDbg);368}369370va_end (ap);371}372373static void DI_register (void *arg) {374diva_os_spin_lock_magic_t old_irql;375dword sec, usec;376pDbgHandle hDbg ;377int id, free_id = -1, best_id = 0;378379diva_os_get_time (&sec, &usec);380381hDbg = (pDbgHandle)arg ;382/*383Check for bad args, specially for the old obsolete debug handle384*/385if ((hDbg == NULL) ||386((hDbg->id == 0) && (((_OldDbgHandle_ *)hDbg)->id == -1)) ||387(hDbg->Registered != 0)) {388return ;389}390391diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "register");392393for (id = 1; id < ARRAY_SIZE(clients); id++) {394if (clients[id].hDbg == hDbg) {395/*396driver already registered397*/398diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");399return;400}401if (clients[id].hDbg) { /* slot is busy */402continue;403}404free_id = id;405if (!strcmp (clients[id].drvName, hDbg->drvName)) {406/*407This driver was already registered with this name408and slot is still free - reuse it409*/410best_id = 1;411break;412}413if (!clients[id].hDbg) { /* slot is busy */414break;415}416}417418if (free_id != -1) {419diva_dbg_entry_head_t* pmsg = NULL;420int len;421char tmp[256];422word size;423424/*425Register new driver with id == free_id426*/427clients[free_id].hDbg = hDbg;428clients[free_id].sec = sec;429clients[free_id].usec = usec;430strcpy (clients[free_id].drvName, hDbg->drvName);431432clients[free_id].dbgMask = hDbg->dbgMask;433if (best_id) {434hDbg->dbgMask |= clients[free_id].last_dbgMask;435} else {436clients[free_id].last_dbgMask = 0;437}438439hDbg->Registered = DBG_HANDLE_REG_NEW ;440hDbg->id = (byte)free_id;441hDbg->dbg_end = DI_deregister;442hDbg->dbg_prt = DI_format_locked;443hDbg->dbg_ev = DiProcessEventLog;444hDbg->dbg_irq = DI_format_locked;445if (hDbg->Version > 0) {446hDbg->dbg_old = DI_format_old;447}448hDbg->next = (pDbgHandle)DBG_MAGIC;449450/*451Log driver register, MAINT driver ID is '0'452*/453len = sprintf (tmp, "DIMAINT - drv # %d = '%s' registered",454free_id, hDbg->drvName);455456while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,457(word)(len+1+sizeof(*pmsg))))) {458if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {459queueFreeMsg (dbg_queue);460} else {461break;462}463}464465if (pmsg) {466pmsg->sequence = dbg_sequence++;467pmsg->time_sec = sec;468pmsg->time_usec = usec;469pmsg->facility = MSG_TYPE_STRING;470pmsg->dli = DLI_REG;471pmsg->drv_id = 0; /* id 0 - DIMAINT */472pmsg->di_cpu = 0;473pmsg->data_length = len+1;474475memcpy (&pmsg[1], tmp, len+1);476queueCompleteMsg (pmsg);477diva_maint_wakeup_read();478}479}480481diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");482}483484static void DI_deregister (pDbgHandle hDbg) {485diva_os_spin_lock_magic_t old_irql, old_irql1;486dword sec, usec;487int i;488word size;489byte* pmem = NULL;490491diva_os_get_time (&sec, &usec);492493diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "read");494diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "read");495496for (i = 1; i < ARRAY_SIZE(clients); i++) {497if (clients[i].hDbg == hDbg) {498diva_dbg_entry_head_t* pmsg;499char tmp[256];500int len;501502clients[i].hDbg = NULL;503504hDbg->id = -1;505hDbg->dbgMask = 0;506hDbg->dbg_end = NULL;507hDbg->dbg_prt = NULL;508hDbg->dbg_irq = NULL;509if (hDbg->Version > 0)510hDbg->dbg_old = NULL;511hDbg->Registered = 0;512hDbg->next = NULL;513514if (clients[i].pIdiLib) {515(*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);516clients[i].pIdiLib = NULL;517518pmem = clients[i].pmem;519clients[i].pmem = NULL;520}521522/*523Log driver register, MAINT driver ID is '0'524*/525len = sprintf (tmp, "DIMAINT - drv # %d = '%s' de-registered",526i, hDbg->drvName);527528while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,529(word)(len+1+sizeof(*pmsg))))) {530if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {531queueFreeMsg (dbg_queue);532} else {533break;534}535}536537if (pmsg) {538pmsg->sequence = dbg_sequence++;539pmsg->time_sec = sec;540pmsg->time_usec = usec;541pmsg->facility = MSG_TYPE_STRING;542pmsg->dli = DLI_REG;543pmsg->drv_id = 0; /* id 0 - DIMAINT */544pmsg->di_cpu = 0;545pmsg->data_length = len+1;546547memcpy (&pmsg[1], tmp, len+1);548queueCompleteMsg (pmsg);549diva_maint_wakeup_read();550}551552break;553}554}555556diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "read_ack");557diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "read_ack");558559if (pmem) {560diva_os_free (0, pmem);561}562}563564static void DI_format_locked (unsigned short id,565int type,566char *format,567va_list argument_list) {568DI_format (1, id, type, format, argument_list);569}570571static void DI_format (int do_lock,572unsigned short id,573int type,574char *format,575va_list ap) {576diva_os_spin_lock_magic_t old_irql;577dword sec, usec;578diva_dbg_entry_head_t* pmsg = NULL;579dword length;580word size;581static char fmtBuf[MSG_FRAME_MAX_SIZE+sizeof(*pmsg)+1];582char *data;583unsigned short code;584585if (diva_os_in_irq()) {586dbg_sequence++;587return;588}589590if ((!format) ||591((TraceFilter[0] != 0) && ((TraceFilterIdent < 0) || (TraceFilterChannel < 0)))) {592return;593}594595596597diva_os_get_time (&sec, &usec);598599if (do_lock) {600diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "format");601}602603switch (type) {604case DLI_MXLOG :605case DLI_BLK :606case DLI_SEND:607case DLI_RECV:608if (!(length = va_arg(ap, unsigned long))) {609break;610}611if (length > MaxDumpSize) {612length = MaxDumpSize;613}614while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,615(word)length+sizeof(*pmsg)))) {616if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {617queueFreeMsg (dbg_queue);618} else {619break;620}621}622if (pmsg) {623memcpy (&pmsg[1], format, length);624pmsg->sequence = dbg_sequence++;625pmsg->time_sec = sec;626pmsg->time_usec = usec;627pmsg->facility = MSG_TYPE_BINARY ;628pmsg->dli = type; /* DLI_XXX */629pmsg->drv_id = id; /* driver MAINT id */630pmsg->di_cpu = 0;631pmsg->data_length = length;632queueCompleteMsg (pmsg);633}634break;635636case DLI_XLOG: {637byte* p;638data = va_arg(ap, char*);639code = (unsigned short)va_arg(ap, unsigned int);640length = (unsigned long) va_arg(ap, unsigned int);641642if (length > MaxXlogSize)643length = MaxXlogSize;644645while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,646(word)length+sizeof(*pmsg)+2))) {647if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {648queueFreeMsg (dbg_queue);649} else {650break;651}652}653if (pmsg) {654p = (byte*)&pmsg[1];655p[0] = (char)(code) ;656p[1] = (char)(code >> 8) ;657if (data && length) {658memcpy (&p[2], &data[0], length) ;659}660length += 2 ;661662pmsg->sequence = dbg_sequence++;663pmsg->time_sec = sec;664pmsg->time_usec = usec;665pmsg->facility = MSG_TYPE_BINARY ;666pmsg->dli = type; /* DLI_XXX */667pmsg->drv_id = id; /* driver MAINT id */668pmsg->di_cpu = 0;669pmsg->data_length = length;670queueCompleteMsg (pmsg);671}672} break;673674case DLI_LOG :675case DLI_FTL :676case DLI_ERR :677case DLI_TRC :678case DLI_REG :679case DLI_MEM :680case DLI_SPL :681case DLI_IRP :682case DLI_TIM :683case DLI_TAPI:684case DLI_NDIS:685case DLI_CONN:686case DLI_STAT:687case DLI_PRV0:688case DLI_PRV1:689case DLI_PRV2:690case DLI_PRV3:691if ((length = (unsigned long)vsprintf (&fmtBuf[0], format, ap)) > 0) {692length += (sizeof(*pmsg)+1);693694while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,695(word)length))) {696if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {697queueFreeMsg (dbg_queue);698} else {699break;700}701}702703pmsg->sequence = dbg_sequence++;704pmsg->time_sec = sec;705pmsg->time_usec = usec;706pmsg->facility = MSG_TYPE_STRING;707pmsg->dli = type; /* DLI_XXX */708pmsg->drv_id = id; /* driver MAINT id */709pmsg->di_cpu = 0;710pmsg->data_length = length - sizeof(*pmsg);711712memcpy (&pmsg[1], fmtBuf, pmsg->data_length);713queueCompleteMsg (pmsg);714}715break;716717} /* switch type */718719720if (queueCount(dbg_queue)) {721diva_maint_wakeup_read();722}723724if (do_lock) {725diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "format");726}727}728729/*730Write driver ID and driver revision to callers buffer731*/732int diva_get_driver_info (dword id, byte* data, int data_length) {733diva_os_spin_lock_magic_t old_irql;734byte* p = data;735int to_copy;736737if (!data || !id || (data_length < 17) ||738(id >= ARRAY_SIZE(clients))) {739return (-1);740}741742diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "driver info");743744if (clients[id].hDbg) {745*p++ = 1;746*p++ = (byte)clients[id].sec; /* save seconds */747*p++ = (byte)(clients[id].sec >> 8);748*p++ = (byte)(clients[id].sec >> 16);749*p++ = (byte)(clients[id].sec >> 24);750751*p++ = (byte)(clients[id].usec/1000); /* save mseconds */752*p++ = (byte)((clients[id].usec/1000) >> 8);753*p++ = (byte)((clients[id].usec/1000) >> 16);754*p++ = (byte)((clients[id].usec/1000) >> 24);755756data_length -= 9;757758if ((to_copy = min(strlen(clients[id].drvName), (size_t)(data_length-1)))) {759memcpy (p, clients[id].drvName, to_copy);760p += to_copy;761data_length -= to_copy;762if ((data_length >= 4) && clients[id].hDbg->drvTag[0]) {763*p++ = '(';764data_length -= 1;765if ((to_copy = min(strlen(clients[id].hDbg->drvTag), (size_t)(data_length-2)))) {766memcpy (p, clients[id].hDbg->drvTag, to_copy);767p += to_copy;768data_length -= to_copy;769if (data_length >= 2) {770*p++ = ')';771data_length--;772}773}774}775}776}777*p++ = 0;778779diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "driver info");780781return (p - data);782}783784int diva_get_driver_dbg_mask (dword id, byte* data) {785diva_os_spin_lock_magic_t old_irql;786int ret = -1;787788if (!data || !id || (id >= ARRAY_SIZE(clients))) {789return (-1);790}791diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "driver info");792793if (clients[id].hDbg) {794ret = 4;795*data++= (byte)(clients[id].hDbg->dbgMask);796*data++= (byte)(clients[id].hDbg->dbgMask >> 8);797*data++= (byte)(clients[id].hDbg->dbgMask >> 16);798*data++= (byte)(clients[id].hDbg->dbgMask >> 24);799}800801diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "driver info");802803return (ret);804}805806int diva_set_driver_dbg_mask (dword id, dword mask) {807diva_os_spin_lock_magic_t old_irql, old_irql1;808int ret = -1;809810811if (!id || (id >= ARRAY_SIZE(clients))) {812return (-1);813}814815diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask");816diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "dbg mask");817818if (clients[id].hDbg) {819dword old_mask = clients[id].hDbg->dbgMask;820mask &= 0x7fffffff;821clients[id].hDbg->dbgMask = mask;822clients[id].last_dbgMask = (clients[id].hDbg->dbgMask | clients[id].dbgMask);823ret = 4;824diva_change_management_debug_mask (&clients[id], old_mask);825}826827828diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "dbg mask");829830if (clients[id].request_pending) {831clients[id].request_pending = 0;832(*(clients[id].request))((ENTITY*)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib));833}834835diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask");836837return (ret);838}839840static int diva_get_idi_adapter_info (IDI_CALL request, dword* serial, dword* logical) {841IDI_SYNC_REQ sync_req;842843sync_req.xdi_logical_adapter_number.Req = 0;844sync_req.xdi_logical_adapter_number.Rc = IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER;845(*request)((ENTITY *)&sync_req);846*logical = sync_req.xdi_logical_adapter_number.info.logical_adapter_number;847848sync_req.GetSerial.Req = 0;849sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL;850sync_req.GetSerial.serial = 0;851(*request)((ENTITY *)&sync_req);852*serial = sync_req.GetSerial.serial;853854return (0);855}856857/*858Register XDI adapter as MAINT compatible driver859*/860void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) {861diva_os_spin_lock_magic_t old_irql, old_irql1;862dword sec, usec, logical, serial, org_mask;863int id, free_id = -1;864char tmp[128];865diva_dbg_entry_head_t* pmsg = NULL;866int len;867word size;868byte* pmem;869870diva_os_get_time (&sec, &usec);871diva_get_idi_adapter_info (d->request, &serial, &logical);872if (serial & 0xff000000) {873sprintf (tmp, "ADAPTER:%d SN:%u-%d",874(int)logical,875serial & 0x00ffffff,876(byte)(((serial & 0xff000000) >> 24) + 1));877} else {878sprintf (tmp, "ADAPTER:%d SN:%u", (int)logical, serial);879}880881if (!(pmem = diva_os_malloc (0, DivaSTraceGetMemotyRequirement (d->channels)))) {882return;883}884memset (pmem, 0x00, DivaSTraceGetMemotyRequirement (d->channels));885886diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "register");887diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "register");888889for (id = 1; id < ARRAY_SIZE(clients); id++) {890if (clients[id].hDbg && (clients[id].request == d->request)) {891diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");892diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register");893diva_os_free(0, pmem);894return;895}896if (clients[id].hDbg) { /* slot is busy */897continue;898}899if (free_id < 0) {900free_id = id;901}902if (!strcmp (clients[id].drvName, tmp)) {903/*904This driver was already registered with this name905and slot is still free - reuse it906*/907free_id = id;908break;909}910}911912if (free_id < 0) {913diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");914diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register");915diva_os_free (0, pmem);916return;917}918919id = free_id;920clients[id].request = d->request;921clients[id].request_pending = 0;922clients[id].hDbg = &clients[id].Dbg;923clients[id].sec = sec;924clients[id].usec = usec;925strcpy (clients[id].drvName, tmp);926strcpy (clients[id].Dbg.drvName, tmp);927clients[id].Dbg.drvTag[0] = 0;928clients[id].logical = (int)logical;929clients[id].channels = (int)d->channels;930clients[id].dma_handle = -1;931932clients[id].Dbg.dbgMask = 0;933clients[id].dbgMask = clients[id].Dbg.dbgMask;934if (id) {935clients[id].Dbg.dbgMask |= clients[free_id].last_dbgMask;936} else {937clients[id].last_dbgMask = 0;938}939clients[id].Dbg.Registered = DBG_HANDLE_REG_NEW;940clients[id].Dbg.id = (byte)id;941clients[id].Dbg.dbg_end = DI_deregister;942clients[id].Dbg.dbg_prt = DI_format_locked;943clients[id].Dbg.dbg_ev = DiProcessEventLog;944clients[id].Dbg.dbg_irq = DI_format_locked;945clients[id].Dbg.next = (pDbgHandle)DBG_MAGIC;946947{948diva_trace_library_user_interface_t diva_maint_user_ifc = { &clients[id],949diva_maint_state_change_notify,950diva_maint_trace_notify,951diva_maint_error };952953/*954Attach to adapter management interface955*/956if ((clients[id].pIdiLib =957DivaSTraceLibraryCreateInstance ((int)logical, &diva_maint_user_ifc, pmem))) {958if (((*(clients[id].pIdiLib->DivaSTraceLibraryStart))(clients[id].pIdiLib->hLib))) {959diva_mnt_internal_dprintf (0, DLI_ERR, "Adapter(%d) Start failed", (int)logical);960(*(clients[id].pIdiLib->DivaSTraceLibraryFinit))(clients[id].pIdiLib->hLib);961clients[id].pIdiLib = NULL;962}963} else {964diva_mnt_internal_dprintf (0, DLI_ERR, "A(%d) management init failed", (int)logical);965}966}967968if (!clients[id].pIdiLib) {969clients[id].request = NULL;970clients[id].request_pending = 0;971clients[id].hDbg = NULL;972diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");973diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register");974diva_os_free (0, pmem);975return;976}977978/*979Log driver register, MAINT driver ID is '0'980*/981len = sprintf (tmp, "DIMAINT - drv # %d = '%s' registered",982id, clients[id].Dbg.drvName);983984while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,985(word)(len+1+sizeof(*pmsg))))) {986if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {987queueFreeMsg (dbg_queue);988} else {989break;990}991}992993if (pmsg) {994pmsg->sequence = dbg_sequence++;995pmsg->time_sec = sec;996pmsg->time_usec = usec;997pmsg->facility = MSG_TYPE_STRING;998pmsg->dli = DLI_REG;999pmsg->drv_id = 0; /* id 0 - DIMAINT */1000pmsg->di_cpu = 0;1001pmsg->data_length = len+1;10021003memcpy (&pmsg[1], tmp, len+1);1004queueCompleteMsg (pmsg);1005diva_maint_wakeup_read();1006}10071008org_mask = clients[id].Dbg.dbgMask;1009clients[id].Dbg.dbgMask = 0;10101011diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");10121013if (clients[id].request_pending) {1014clients[id].request_pending = 0;1015(*(clients[id].request))((ENTITY*)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib));1016}10171018diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register");10191020diva_set_driver_dbg_mask (id, org_mask);1021}10221023/*1024De-Register XDI adapter1025*/1026void diva_mnt_remove_xdi_adapter (const DESCRIPTOR* d) {1027diva_os_spin_lock_magic_t old_irql, old_irql1;1028dword sec, usec;1029int i;1030word size;1031byte* pmem = NULL;10321033diva_os_get_time (&sec, &usec);10341035diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "read");1036diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "read");10371038for (i = 1; i < ARRAY_SIZE(clients); i++) {1039if (clients[i].hDbg && (clients[i].request == d->request)) {1040diva_dbg_entry_head_t* pmsg;1041char tmp[256];1042int len;10431044if (clients[i].pIdiLib) {1045(*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);1046clients[i].pIdiLib = NULL;10471048pmem = clients[i].pmem;1049clients[i].pmem = NULL;1050}10511052clients[i].hDbg = NULL;1053clients[i].request_pending = 0;1054if (clients[i].dma_handle >= 0) {1055/*1056Free DMA handle1057*/1058diva_free_dma_descriptor (clients[i].request, clients[i].dma_handle);1059clients[i].dma_handle = -1;1060}1061clients[i].request = NULL;10621063/*1064Log driver register, MAINT driver ID is '0'1065*/1066len = sprintf (tmp, "DIMAINT - drv # %d = '%s' de-registered",1067i, clients[i].Dbg.drvName);10681069memset (&clients[i].Dbg, 0x00, sizeof(clients[i].Dbg));10701071while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,1072(word)(len+1+sizeof(*pmsg))))) {1073if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {1074queueFreeMsg (dbg_queue);1075} else {1076break;1077}1078}10791080if (pmsg) {1081pmsg->sequence = dbg_sequence++;1082pmsg->time_sec = sec;1083pmsg->time_usec = usec;1084pmsg->facility = MSG_TYPE_STRING;1085pmsg->dli = DLI_REG;1086pmsg->drv_id = 0; /* id 0 - DIMAINT */1087pmsg->di_cpu = 0;1088pmsg->data_length = len+1;10891090memcpy (&pmsg[1], tmp, len+1);1091queueCompleteMsg (pmsg);1092diva_maint_wakeup_read();1093}10941095break;1096}1097}10981099diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "read_ack");1100diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "read_ack");11011102if (pmem) {1103diva_os_free (0, pmem);1104}1105}11061107/* ----------------------------------------------------------------1108Low level interface for management interface client1109---------------------------------------------------------------- */1110/*1111Return handle to client structure1112*/1113void* SuperTraceOpenAdapter (int AdapterNumber) {1114int i;11151116for (i = 1; i < ARRAY_SIZE(clients); i++) {1117if (clients[i].hDbg && clients[i].request && (clients[i].logical == AdapterNumber)) {1118return (&clients[i]);1119}1120}11211122return NULL;1123}11241125int SuperTraceCloseAdapter (void* AdapterHandle) {1126return (0);1127}11281129int SuperTraceReadRequest (void* AdapterHandle, const char* name, byte* data) {1130diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;11311132if (pC && pC->pIdiLib && pC->request) {1133ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);1134byte* xdata = (byte*)&pC->xbuffer[0];1135char tmp = 0;1136word length;11371138if (!strcmp(name, "\\")) { /* Read ROOT */1139name = &tmp;1140}1141length = SuperTraceCreateReadReq (xdata, name);1142single_p (xdata, &length, 0); /* End Of Message */11431144e->Req = MAN_READ;1145e->ReqCh = 0;1146e->X->PLength = length;1147e->X->P = (byte*)xdata;11481149pC->request_pending = 1;11501151return (0);1152}11531154return (-1);1155}11561157int SuperTraceGetNumberOfChannels (void* AdapterHandle) {1158if (AdapterHandle) {1159diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;11601161return (pC->channels);1162}11631164return (0);1165}11661167int SuperTraceASSIGN (void* AdapterHandle, byte* data) {1168diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;11691170if (pC && pC->pIdiLib && pC->request) {1171ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);1172IDI_SYNC_REQ* preq;1173char buffer[((sizeof(preq->xdi_extended_features)+4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features)+4) : sizeof(ENTITY)];1174char features[4];1175word assign_data_length = 1;11761177features[0] = 0;1178pC->xbuffer[0] = 0;1179preq = (IDI_SYNC_REQ*)&buffer[0];1180preq->xdi_extended_features.Req = 0;1181preq->xdi_extended_features.Rc = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES;1182preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features);1183preq->xdi_extended_features.info.features = &features[0];11841185(*(pC->request))((ENTITY*)preq);11861187if ((features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) &&1188(features[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA)) {1189dword uninitialized_var(rx_dma_magic);1190if ((pC->dma_handle = diva_get_dma_descriptor (pC->request, &rx_dma_magic)) >= 0) {1191pC->xbuffer[0] = LLI;1192pC->xbuffer[1] = 8;1193pC->xbuffer[2] = 0x40;1194pC->xbuffer[3] = (byte)pC->dma_handle;1195pC->xbuffer[4] = (byte)rx_dma_magic;1196pC->xbuffer[5] = (byte)(rx_dma_magic >> 8);1197pC->xbuffer[6] = (byte)(rx_dma_magic >> 16);1198pC->xbuffer[7] = (byte)(rx_dma_magic >> 24);1199pC->xbuffer[8] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE & 0xFF);1200pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8);1201pC->xbuffer[10] = 0;12021203assign_data_length = 11;1204}1205} else {1206pC->dma_handle = -1;1207}12081209e->Id = MAN_ID;1210e->callback = diva_maint_xdi_cb;1211e->XNum = 1;1212e->X = &pC->XData;1213e->Req = ASSIGN;1214e->ReqCh = 0;1215e->X->PLength = assign_data_length;1216e->X->P = (byte*)&pC->xbuffer[0];12171218pC->request_pending = 1;12191220return (0);1221}12221223return (-1);1224}12251226int SuperTraceREMOVE (void* AdapterHandle) {1227diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;12281229if (pC && pC->pIdiLib && pC->request) {1230ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);12311232e->XNum = 1;1233e->X = &pC->XData;1234e->Req = REMOVE;1235e->ReqCh = 0;1236e->X->PLength = 1;1237e->X->P = (byte*)&pC->xbuffer[0];1238pC->xbuffer[0] = 0;12391240pC->request_pending = 1;12411242return (0);1243}12441245return (-1);1246}12471248int SuperTraceTraceOnRequest(void* hAdapter, const char* name, byte* data) {1249diva_maint_client_t* pC = (diva_maint_client_t*)hAdapter;12501251if (pC && pC->pIdiLib && pC->request) {1252ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);1253byte* xdata = (byte*)&pC->xbuffer[0];1254char tmp = 0;1255word length;12561257if (!strcmp(name, "\\")) { /* Read ROOT */1258name = &tmp;1259}1260length = SuperTraceCreateReadReq (xdata, name);1261single_p (xdata, &length, 0); /* End Of Message */1262e->Req = MAN_EVENT_ON;1263e->ReqCh = 0;1264e->X->PLength = length;1265e->X->P = (byte*)xdata;12661267pC->request_pending = 1;12681269return (0);1270}12711272return (-1);1273}12741275int SuperTraceWriteVar (void* AdapterHandle,1276byte* data,1277const char* name,1278void* var,1279byte type,1280byte var_length) {1281diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;12821283if (pC && pC->pIdiLib && pC->request) {1284ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);1285diva_man_var_header_t* pVar = (diva_man_var_header_t*)&pC->xbuffer[0];1286word length = SuperTraceCreateReadReq ((byte*)pVar, name);12871288memcpy (&pC->xbuffer[length], var, var_length);1289length += var_length;1290pVar->length += var_length;1291pVar->value_length = var_length;1292pVar->type = type;1293single_p ((byte*)pVar, &length, 0); /* End Of Message */12941295e->Req = MAN_WRITE;1296e->ReqCh = 0;1297e->X->PLength = length;1298e->X->P = (byte*)pVar;12991300pC->request_pending = 1;13011302return (0);1303}13041305return (-1);1306}13071308int SuperTraceExecuteRequest (void* AdapterHandle,1309const char* name,1310byte* data) {1311diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;13121313if (pC && pC->pIdiLib && pC->request) {1314ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);1315byte* xdata = (byte*)&pC->xbuffer[0];1316word length;13171318length = SuperTraceCreateReadReq (xdata, name);1319single_p (xdata, &length, 0); /* End Of Message */13201321e->Req = MAN_EXECUTE;1322e->ReqCh = 0;1323e->X->PLength = length;1324e->X->P = (byte*)xdata;13251326pC->request_pending = 1;13271328return (0);1329}13301331return (-1);1332}13331334static word SuperTraceCreateReadReq (byte* P, const char* path) {1335byte var_length;1336byte* plen;13371338var_length = (byte)strlen (path);13391340*P++ = ESC;1341plen = P++;1342*P++ = 0x80; /* MAN_IE */1343*P++ = 0x00; /* Type */1344*P++ = 0x00; /* Attribute */1345*P++ = 0x00; /* Status */1346*P++ = 0x00; /* Variable Length */1347*P++ = var_length;1348memcpy (P, path, var_length);1349P += var_length;1350*plen = var_length + 0x06;13511352return ((word)(var_length + 0x08));1353}13541355static void single_p (byte * P, word * PLength, byte Id) {1356P[(*PLength)++] = Id;1357}13581359static void diva_maint_xdi_cb (ENTITY* e) {1360diva_strace_context_t* pLib = DIVAS_CONTAINING_RECORD(e,diva_strace_context_t,e);1361diva_maint_client_t* pC;1362diva_os_spin_lock_magic_t old_irql, old_irql1;136313641365diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "xdi_cb");1366diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "xdi_cb");13671368pC = (diva_maint_client_t*)pLib->hAdapter;13691370if ((e->complete == 255) || (pC->dma_handle < 0)) {1371if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) {1372diva_mnt_internal_dprintf (0, DLI_ERR, "Trace internal library error");1373}1374} else {1375/*1376Process combined management interface indication1377*/1378if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) {1379diva_mnt_internal_dprintf (0, DLI_ERR, "Trace internal library error (DMA mode)");1380}1381}13821383diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "xdi_cb");138413851386if (pC->request_pending) {1387pC->request_pending = 0;1388(*(pC->request))(e);1389}13901391diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "xdi_cb");1392}139313941395static void diva_maint_error (void* user_context,1396diva_strace_library_interface_t* hLib,1397int Adapter,1398int error,1399const char* file,1400int line) {1401diva_mnt_internal_dprintf (0, DLI_ERR,1402"Trace library error(%d) A(%d) %s %d", error, Adapter, file, line);1403}14041405static void print_ie (diva_trace_ie_t* ie, char* buffer, int length) {1406int i;14071408buffer[0] = 0;14091410if (length > 32) {1411for (i = 0; ((i < ie->length) && (length > 3)); i++) {1412sprintf (buffer, "%02x", ie->data[i]);1413buffer += 2;1414length -= 2;1415if (i < (ie->length-1)) {1416strcpy (buffer, " ");1417buffer++;1418length--;1419}1420}1421}1422}14231424static void diva_maint_state_change_notify (void* user_context,1425diva_strace_library_interface_t* hLib,1426int Adapter,1427diva_trace_line_state_t* channel,1428int notify_subject) {1429diva_maint_client_t* pC = (diva_maint_client_t*)user_context;1430diva_trace_fax_state_t* fax = &channel->fax;1431diva_trace_modem_state_t* modem = &channel->modem;1432char tmp[256];14331434if (!pC->hDbg) {1435return;1436}14371438switch (notify_subject) {1439case DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE: {1440int view = (TraceFilter[0] == 0);1441/*1442Process selective Trace1443*/1444if (channel->Line[0] == 'I' && channel->Line[1] == 'd' &&1445channel->Line[2] == 'l' && channel->Line[3] == 'e') {1446if ((TraceFilterIdent == pC->hDbg->id) && (TraceFilterChannel == (int)channel->ChannelNumber)) {1447(*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 0);1448(*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 0);1449diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, "Selective Trace OFF for Ch=%d",1450(int)channel->ChannelNumber);1451TraceFilterIdent = -1;1452TraceFilterChannel = -1;1453view = 1;1454}1455} else if (TraceFilter[0] && (TraceFilterIdent < 0) && !(diva_mnt_cmp_nmbr (&channel->RemoteAddress[0]) &&1456diva_mnt_cmp_nmbr (&channel->LocalAddress[0]))) {14571458if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0) { /* Activate B-channel trace */1459(*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 1);1460}1461if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0) { /* Activate AudioTap Trace */1462(*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 1);1463}14641465TraceFilterIdent = pC->hDbg->id;1466TraceFilterChannel = (int)channel->ChannelNumber;14671468if (TraceFilterIdent >= 0) {1469diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, "Selective Trace ON for Ch=%d",1470(int)channel->ChannelNumber);1471view = 1;1472}1473}1474if (view && (pC->hDbg->dbgMask & DIVA_MGT_DBG_LINE_EVENTS)) {1475diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Ch = %d",1476(int)channel->ChannelNumber);1477diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Status = <%s>", &channel->Line[0]);1478diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Layer1 = <%s>", &channel->Framing[0]);1479diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Layer2 = <%s>", &channel->Layer2[0]);1480diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Layer3 = <%s>", &channel->Layer3[0]);1481diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L RAddr = <%s>",1482&channel->RemoteAddress[0]);1483diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L RSAddr = <%s>",1484&channel->RemoteSubAddress[0]);1485diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L LAddr = <%s>",1486&channel->LocalAddress[0]);1487diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L LSAddr = <%s>",1488&channel->LocalSubAddress[0]);1489print_ie(&channel->call_BC, tmp, sizeof(tmp));1490diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L BC = <%s>", tmp);1491print_ie(&channel->call_HLC, tmp, sizeof(tmp));1492diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L HLC = <%s>", tmp);1493print_ie(&channel->call_LLC, tmp, sizeof(tmp));1494diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L LLC = <%s>", tmp);1495diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L CR = 0x%x", channel->CallReference);1496diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Disc = 0x%x",1497channel->LastDisconnecCause);1498diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Owner = <%s>", &channel->UserID[0]);1499}15001501} break;15021503case DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE:1504if (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_PROGRESS) {1505{1506int ch = TraceFilterChannel;1507int id = TraceFilterIdent;15081509if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&1510(clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {1511if (ch != (int)modem->ChannelNumber) {1512break;1513}1514} else if (TraceFilter[0] != 0) {1515break;1516}1517}151815191520diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Ch = %lu",1521(int)modem->ChannelNumber);1522diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Event = %lu", modem->Event);1523diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Norm = %lu", modem->Norm);1524diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Opts. = 0x%08x", modem->Options);1525diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Tx = %lu Bps", modem->TxSpeed);1526diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rx = %lu Bps", modem->RxSpeed);1527diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RT = %lu mSec",1528modem->RoundtripMsec);1529diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Sr = %lu", modem->SymbolRate);1530diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rxl = %d dBm", modem->RxLeveldBm);1531diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM El = %d dBm", modem->EchoLeveldBm);1532diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM SNR = %lu dB", modem->SNRdb);1533diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM MAE = %lu", modem->MAE);1534diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRet = %lu",1535modem->LocalRetrains);1536diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRet = %lu",1537modem->RemoteRetrains);1538diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRes = %lu", modem->LocalResyncs);1539diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRes = %lu",1540modem->RemoteResyncs);1541if (modem->Event == 3) {1542diva_mnt_internal_dprintf(pC->hDbg->id,DLI_STAT,"MDM Disc = %lu", modem->DiscReason);1543}1544}1545if ((modem->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_STATISTICS)) {1546(*(pC->pIdiLib->DivaSTraceGetModemStatistics))(pC->pIdiLib);1547}1548break;15491550case DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE:1551if (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_PROGRESS) {1552{1553int ch = TraceFilterChannel;1554int id = TraceFilterIdent;15551556if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&1557(clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {1558if (ch != (int)fax->ChannelNumber) {1559break;1560}1561} else if (TraceFilter[0] != 0) {1562break;1563}1564}15651566diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Ch = %lu",(int)fax->ChannelNumber);1567diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Event = %lu", fax->Event);1568diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pages = %lu", fax->Page_Counter);1569diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Feat. = 0x%08x", fax->Features);1570diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX ID = <%s>", &fax->Station_ID[0]);1571diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Saddr = <%s>", &fax->Subaddress[0]);1572diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pwd = <%s>", &fax->Password[0]);1573diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Speed = %lu", fax->Speed);1574diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Res. = 0x%08x", fax->Resolution);1575diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Width = %lu", fax->Paper_Width);1576diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Length= %lu", fax->Paper_Length);1577diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX SLT = %lu", fax->Scanline_Time);1578if (fax->Event == 3) {1579diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Disc = %lu", fax->Disc_Reason);1580}1581}1582if ((fax->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_STATISTICS)) {1583(*(pC->pIdiLib->DivaSTraceGetFaxStatistics))(pC->pIdiLib);1584}1585break;15861587case DIVA_SUPER_TRACE_INTERFACE_CHANGE:1588if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_EVENTS) {1589diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT,1590"Layer 1 -> [%s]", channel->pInterface->Layer1);1591diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT,1592"Layer 2 -> [%s]", channel->pInterface->Layer2);1593}1594break;15951596case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE:1597if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_STATISTICS) {1598/*1599Incoming Statistics1600*/1601if (channel->pInterfaceStat->inc.Calls) {1602diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1603"Inc Calls =%lu", channel->pInterfaceStat->inc.Calls);1604}1605if (channel->pInterfaceStat->inc.Connected) {1606diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1607"Inc Connected =%lu", channel->pInterfaceStat->inc.Connected);1608}1609if (channel->pInterfaceStat->inc.User_Busy) {1610diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1611"Inc Busy =%lu", channel->pInterfaceStat->inc.User_Busy);1612}1613if (channel->pInterfaceStat->inc.Call_Rejected) {1614diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1615"Inc Rejected =%lu", channel->pInterfaceStat->inc.Call_Rejected);1616}1617if (channel->pInterfaceStat->inc.Wrong_Number) {1618diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1619"Inc Wrong Nr =%lu", channel->pInterfaceStat->inc.Wrong_Number);1620}1621if (channel->pInterfaceStat->inc.Incompatible_Dst) {1622diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1623"Inc Incomp. Dest =%lu", channel->pInterfaceStat->inc.Incompatible_Dst);1624}1625if (channel->pInterfaceStat->inc.Out_of_Order) {1626diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1627"Inc Out of Order =%lu", channel->pInterfaceStat->inc.Out_of_Order);1628}1629if (channel->pInterfaceStat->inc.Ignored) {1630diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1631"Inc Ignored =%lu", channel->pInterfaceStat->inc.Ignored);1632}16331634/*1635Outgoing Statistics1636*/1637if (channel->pInterfaceStat->outg.Calls) {1638diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1639"Outg Calls =%lu", channel->pInterfaceStat->outg.Calls);1640}1641if (channel->pInterfaceStat->outg.Connected) {1642diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1643"Outg Connected =%lu", channel->pInterfaceStat->outg.Connected);1644}1645if (channel->pInterfaceStat->outg.User_Busy) {1646diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1647"Outg Busy =%lu", channel->pInterfaceStat->outg.User_Busy);1648}1649if (channel->pInterfaceStat->outg.No_Answer) {1650diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1651"Outg No Answer =%lu", channel->pInterfaceStat->outg.No_Answer);1652}1653if (channel->pInterfaceStat->outg.Wrong_Number) {1654diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1655"Outg Wrong Nr =%lu", channel->pInterfaceStat->outg.Wrong_Number);1656}1657if (channel->pInterfaceStat->outg.Call_Rejected) {1658diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1659"Outg Rejected =%lu", channel->pInterfaceStat->outg.Call_Rejected);1660}1661if (channel->pInterfaceStat->outg.Other_Failures) {1662diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1663"Outg Other Failures =%lu", channel->pInterfaceStat->outg.Other_Failures);1664}1665}1666break;16671668case DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE:1669if (channel->pInterfaceStat->mdm.Disc_Normal) {1670diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1671"MDM Disc Normal = %lu", channel->pInterfaceStat->mdm.Disc_Normal);1672}1673if (channel->pInterfaceStat->mdm.Disc_Unspecified) {1674diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1675"MDM Disc Unsp. = %lu", channel->pInterfaceStat->mdm.Disc_Unspecified);1676}1677if (channel->pInterfaceStat->mdm.Disc_Busy_Tone) {1678diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1679"MDM Disc Busy Tone = %lu", channel->pInterfaceStat->mdm.Disc_Busy_Tone);1680}1681if (channel->pInterfaceStat->mdm.Disc_Congestion) {1682diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1683"MDM Disc Congestion = %lu", channel->pInterfaceStat->mdm.Disc_Congestion);1684}1685if (channel->pInterfaceStat->mdm.Disc_Carr_Wait) {1686diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1687"MDM Disc Carrier Wait = %lu", channel->pInterfaceStat->mdm.Disc_Carr_Wait);1688}1689if (channel->pInterfaceStat->mdm.Disc_Trn_Timeout) {1690diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1691"MDM Disc Trn. T.o. = %lu", channel->pInterfaceStat->mdm.Disc_Trn_Timeout);1692}1693if (channel->pInterfaceStat->mdm.Disc_Incompat) {1694diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1695"MDM Disc Incompatible = %lu", channel->pInterfaceStat->mdm.Disc_Incompat);1696}1697if (channel->pInterfaceStat->mdm.Disc_Frame_Rej) {1698diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1699"MDM Disc Frame Reject = %lu", channel->pInterfaceStat->mdm.Disc_Frame_Rej);1700}1701if (channel->pInterfaceStat->mdm.Disc_V42bis) {1702diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1703"MDM Disc V.42bis = %lu", channel->pInterfaceStat->mdm.Disc_V42bis);1704}1705break;17061707case DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE:1708if (channel->pInterfaceStat->fax.Disc_Normal) {1709diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1710"FAX Disc Normal = %lu", channel->pInterfaceStat->fax.Disc_Normal);1711}1712if (channel->pInterfaceStat->fax.Disc_Not_Ident) {1713diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1714"FAX Disc Not Ident. = %lu", channel->pInterfaceStat->fax.Disc_Not_Ident);1715}1716if (channel->pInterfaceStat->fax.Disc_No_Response) {1717diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1718"FAX Disc No Response = %lu", channel->pInterfaceStat->fax.Disc_No_Response);1719}1720if (channel->pInterfaceStat->fax.Disc_Retries) {1721diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1722"FAX Disc Max Retries = %lu", channel->pInterfaceStat->fax.Disc_Retries);1723}1724if (channel->pInterfaceStat->fax.Disc_Unexp_Msg) {1725diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1726"FAX Unexp. Msg. = %lu", channel->pInterfaceStat->fax.Disc_Unexp_Msg);1727}1728if (channel->pInterfaceStat->fax.Disc_No_Polling) {1729diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1730"FAX Disc No Polling = %lu", channel->pInterfaceStat->fax.Disc_No_Polling);1731}1732if (channel->pInterfaceStat->fax.Disc_Training) {1733diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1734"FAX Disc Training = %lu", channel->pInterfaceStat->fax.Disc_Training);1735}1736if (channel->pInterfaceStat->fax.Disc_Unexpected) {1737diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1738"FAX Disc Unexpected = %lu", channel->pInterfaceStat->fax.Disc_Unexpected);1739}1740if (channel->pInterfaceStat->fax.Disc_Application) {1741diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1742"FAX Disc Application = %lu", channel->pInterfaceStat->fax.Disc_Application);1743}1744if (channel->pInterfaceStat->fax.Disc_Incompat) {1745diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1746"FAX Disc Incompatible = %lu", channel->pInterfaceStat->fax.Disc_Incompat);1747}1748if (channel->pInterfaceStat->fax.Disc_No_Command) {1749diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1750"FAX Disc No Command = %lu", channel->pInterfaceStat->fax.Disc_No_Command);1751}1752if (channel->pInterfaceStat->fax.Disc_Long_Msg) {1753diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1754"FAX Disc Long Msg. = %lu", channel->pInterfaceStat->fax.Disc_Long_Msg);1755}1756if (channel->pInterfaceStat->fax.Disc_Supervisor) {1757diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1758"FAX Disc Supervisor = %lu", channel->pInterfaceStat->fax.Disc_Supervisor);1759}1760if (channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD) {1761diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1762"FAX Disc SUP SEP PWD = %lu", channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD);1763}1764if (channel->pInterfaceStat->fax.Disc_Invalid_Msg) {1765diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1766"FAX Disc Invalid Msg. = %lu", channel->pInterfaceStat->fax.Disc_Invalid_Msg);1767}1768if (channel->pInterfaceStat->fax.Disc_Page_Coding) {1769diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1770"FAX Disc Page Coding = %lu", channel->pInterfaceStat->fax.Disc_Page_Coding);1771}1772if (channel->pInterfaceStat->fax.Disc_App_Timeout) {1773diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1774"FAX Disc Appl. T.o. = %lu", channel->pInterfaceStat->fax.Disc_App_Timeout);1775}1776if (channel->pInterfaceStat->fax.Disc_Unspecified) {1777diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,1778"FAX Disc Unspec. = %lu", channel->pInterfaceStat->fax.Disc_Unspecified);1779}1780break;1781}1782}17831784/*1785Receive trace information from the Management Interface and store it in the1786internal trace buffer with MSG_TYPE_MLOG as is, without any filtering.1787Event Filtering and formatting is done in Management Interface self.1788*/1789static void diva_maint_trace_notify (void* user_context,1790diva_strace_library_interface_t* hLib,1791int Adapter,1792void* xlog_buffer,1793int length) {1794diva_maint_client_t* pC = (diva_maint_client_t*)user_context;1795diva_dbg_entry_head_t* pmsg;1796word size;1797dword sec, usec;1798int ch = TraceFilterChannel;1799int id = TraceFilterIdent;18001801/*1802Selective trace1803*/1804if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&1805(clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {1806const char* p = NULL;1807int ch_value = -1;1808MI_XLOG_HDR *TrcData = (MI_XLOG_HDR *)xlog_buffer;18091810if (Adapter != clients[id].logical) {1811return; /* Ignore all trace messages from other adapters */1812}18131814if (TrcData->code == 24) {1815p = (char*)&TrcData->code;1816p += 2;1817}18181819/*1820All L1 messages start as [dsp,ch], so we can filter this information1821and filter out all messages that use different channel1822*/1823if (p && p[0] == '[') {1824if (p[2] == ',') {1825p += 3;1826ch_value = *p - '0';1827} else if (p[3] == ',') {1828p += 4;1829ch_value = *p - '0';1830}1831if (ch_value >= 0) {1832if (p[2] == ']') {1833ch_value = ch_value * 10 + p[1] - '0';1834}1835if (ch_value != ch) {1836return; /* Ignore other channels */1837}1838}1839}18401841} else if (TraceFilter[0] != 0) {1842return; /* Ignore trace if trace filter is activated, but idle */1843}18441845diva_os_get_time (&sec, &usec);18461847while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,1848(word)length+sizeof(*pmsg)))) {1849if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {1850queueFreeMsg (dbg_queue);1851} else {1852break;1853}1854}1855if (pmsg) {1856memcpy (&pmsg[1], xlog_buffer, length);1857pmsg->sequence = dbg_sequence++;1858pmsg->time_sec = sec;1859pmsg->time_usec = usec;1860pmsg->facility = MSG_TYPE_MLOG;1861pmsg->dli = pC->logical;1862pmsg->drv_id = pC->hDbg->id;1863pmsg->di_cpu = 0;1864pmsg->data_length = length;1865queueCompleteMsg (pmsg);1866if (queueCount(dbg_queue)) {1867diva_maint_wakeup_read();1868}1869}1870}187118721873/*1874Convert MAINT trace mask to management interface trace mask/work/facility and1875issue command to management interface1876*/1877static void diva_change_management_debug_mask (diva_maint_client_t* pC, dword old_mask) {1878if (pC->request && pC->hDbg && pC->pIdiLib) {1879dword changed = pC->hDbg->dbgMask ^ old_mask;18801881if (changed & DIVA_MGT_DBG_TRACE) {1882(*(pC->pIdiLib->DivaSTraceSetInfo))(pC->pIdiLib,1883(pC->hDbg->dbgMask & DIVA_MGT_DBG_TRACE) != 0);1884}1885if (changed & DIVA_MGT_DBG_DCHAN) {1886(*(pC->pIdiLib->DivaSTraceSetDChannel))(pC->pIdiLib,1887(pC->hDbg->dbgMask & DIVA_MGT_DBG_DCHAN) != 0);1888}1889if (!TraceFilter[0]) {1890if (changed & DIVA_MGT_DBG_IFC_BCHANNEL) {1891int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0);18921893for (i = 0; i < pC->channels; i++) {1894(*(pC->pIdiLib->DivaSTraceSetBChannel))(pC->pIdiLib, i+1, state);1895}1896}1897if (changed & DIVA_MGT_DBG_IFC_AUDIO) {1898int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0);18991900for (i = 0; i < pC->channels; i++) {1901(*(pC->pIdiLib->DivaSTraceSetAudioTap))(pC->pIdiLib, i+1, state);1902}1903}1904}1905}1906}190719081909void diva_mnt_internal_dprintf (dword drv_id, dword type, char* fmt, ...) {1910va_list ap;19111912va_start(ap, fmt);1913DI_format (0, (word)drv_id, (int)type, fmt, ap);1914va_end(ap);1915}19161917/*1918Shutdown all adapters before driver removal1919*/1920int diva_mnt_shutdown_xdi_adapters (void) {1921diva_os_spin_lock_magic_t old_irql, old_irql1;1922int i, fret = 0;1923byte * pmem;192419251926for (i = 1; i < ARRAY_SIZE(clients); i++) {1927pmem = NULL;19281929diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "unload");1930diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "unload");19311932if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) {1933if ((*(clients[i].pIdiLib->DivaSTraceLibraryStop))(clients[i].pIdiLib) == 1) {1934/*1935Adapter removal complete1936*/1937if (clients[i].pIdiLib) {1938(*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);1939clients[i].pIdiLib = NULL;19401941pmem = clients[i].pmem;1942clients[i].pmem = NULL;1943}1944clients[i].hDbg = NULL;1945clients[i].request_pending = 0;19461947if (clients[i].dma_handle >= 0) {1948/*1949Free DMA handle1950*/1951diva_free_dma_descriptor (clients[i].request, clients[i].dma_handle);1952clients[i].dma_handle = -1;1953}1954clients[i].request = NULL;1955} else {1956fret = -1;1957}1958}19591960diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "unload");1961if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {1962clients[i].request_pending = 0;1963(*(clients[i].request))((ENTITY*)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));1964if (clients[i].dma_handle >= 0) {1965diva_free_dma_descriptor (clients[i].request, clients[i].dma_handle);1966clients[i].dma_handle = -1;1967}1968}1969diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "unload");19701971if (pmem) {1972diva_os_free (0, pmem);1973}1974}19751976return (fret);1977}19781979/*1980Set/Read the trace filter used for selective tracing.1981Affects B- and Audio Tap trace mask at run time1982*/1983int diva_set_trace_filter (int filter_length, const char* filter) {1984diva_os_spin_lock_magic_t old_irql, old_irql1;1985int i, ch, on, client_b_on, client_atap_on;19861987diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask");1988diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "write_filter");19891990if (filter_length <= DIVA_MAX_SELECTIVE_FILTER_LENGTH) {1991memcpy (&TraceFilter[0], filter, filter_length);1992if (TraceFilter[filter_length]) {1993TraceFilter[filter_length] = 0;1994}1995if (TraceFilter[0] == '*') {1996TraceFilter[0] = 0;1997}1998} else {1999filter_length = -1;2000}20012002TraceFilterIdent = -1;2003TraceFilterChannel = -1;20042005on = (TraceFilter[0] == 0);20062007for (i = 1; i < ARRAY_SIZE(clients); i++) {2008if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) {2009client_b_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0);2010client_atap_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0);2011for (ch = 0; ch < clients[i].channels; ch++) {2012(*(clients[i].pIdiLib->DivaSTraceSetBChannel))(clients[i].pIdiLib->hLib, ch+1, client_b_on);2013(*(clients[i].pIdiLib->DivaSTraceSetAudioTap))(clients[i].pIdiLib->hLib, ch+1, client_atap_on);2014}2015}2016}20172018for (i = 1; i < ARRAY_SIZE(clients); i++) {2019if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {2020diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "write_filter");2021clients[i].request_pending = 0;2022(*(clients[i].request))((ENTITY*)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));2023diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "write_filter");2024}2025}20262027diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "write_filter");2028diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask");20292030return (filter_length);2031}20322033int diva_get_trace_filter (int max_length, char* filter) {2034diva_os_spin_lock_magic_t old_irql;2035int len;20362037diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "read_filter");2038len = strlen (&TraceFilter[0]) + 1;2039if (max_length >= len) {2040memcpy (filter, &TraceFilter[0], len);2041}2042diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "read_filter");20432044return (len);2045}20462047static int diva_dbg_cmp_key (const char* ref, const char* key) {2048while (*key && (*ref++ == *key++));2049return (!*key && !*ref);2050}20512052/*2053In case trace filter starts with "C" character then2054all following characters are interpreted as command.2055Followings commands are available:2056- single, trace single call at time, independent from CPN/CiPN2057*/2058static int diva_mnt_cmp_nmbr (const char* nmbr) {2059const char* ref = &TraceFilter[0];2060int ref_len = strlen(&TraceFilter[0]), nmbr_len = strlen(nmbr);20612062if (ref[0] == 'C') {2063if (diva_dbg_cmp_key (&ref[1], "single")) {2064return (0);2065}2066return (-1);2067}20682069if (!ref_len || (ref_len > nmbr_len)) {2070return (-1);2071}20722073nmbr = nmbr + nmbr_len - 1;2074ref = ref + ref_len - 1;20752076while (ref_len--) {2077if (*nmbr-- != *ref--) {2078return (-1);2079}2080}20812082return (0);2083}20842085static int diva_get_dma_descriptor (IDI_CALL request, dword *dma_magic) {2086ENTITY e;2087IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e;20882089if (!request) {2090return (-1);2091}20922093pReq->xdi_dma_descriptor_operation.Req = 0;2094pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;20952096pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC;2097pReq->xdi_dma_descriptor_operation.info.descriptor_number = -1;2098pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;2099pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0;21002101(*request)((ENTITY*)pReq);21022103if (!pReq->xdi_dma_descriptor_operation.info.operation &&2104(pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) &&2105pReq->xdi_dma_descriptor_operation.info.descriptor_magic) {2106*dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic;2107return (pReq->xdi_dma_descriptor_operation.info.descriptor_number);2108} else {2109return (-1);2110}2111}21122113static void diva_free_dma_descriptor (IDI_CALL request, int nr) {2114ENTITY e;2115IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e;21162117if (!request || (nr < 0)) {2118return;2119}21202121pReq->xdi_dma_descriptor_operation.Req = 0;2122pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;21232124pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE;2125pReq->xdi_dma_descriptor_operation.info.descriptor_number = nr;2126pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;2127pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0;21282129(*request)((ENTITY*)pReq);2130}2131213221332134