summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/digi/pcimac/trc_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/ndis/digi/pcimac/trc_core.c')
-rw-r--r--private/ntos/ndis/digi/pcimac/trc_core.c357
1 files changed, 357 insertions, 0 deletions
diff --git a/private/ntos/ndis/digi/pcimac/trc_core.c b/private/ntos/ndis/digi/pcimac/trc_core.c
new file mode 100644
index 000000000..4c802ec8c
--- /dev/null
+++ b/private/ntos/ndis/digi/pcimac/trc_core.c
@@ -0,0 +1,357 @@
+/*
+ * TRC_CORE.C - trace core module
+ */
+
+#include <ndis.h>
+#include <ndiswan.h>
+#include <mydefs.h>
+#include <mytypes.h>
+#include <util.h>
+#include <opcodes.h>
+#include <adapter.h>
+#include <idd.h>
+#include <mtl.h>
+#include <cm.h>
+#include <trc.h>
+#include <disp.h>
+
+/* local trace context table (NULL=free) */
+
+#define CheckNULLTrace(Trace) \
+ { \
+ if (Trace == NULL) \
+ break; \
+ }
+
+
+/* register an available idd */
+INT
+trc_register_idd(VOID *idd)
+{
+ IDD_MSG msg;
+
+ D_LOG(D_ENTRY, ("trc_register_idd: entry, idd: 0x%lx", idd));
+
+ /* add handle to idd command receiver */
+ if ( idd_attach(idd, IDD_PORT_CMD_RX, (VOID*)trc__cmd_handler, idd) != IDD_E_SUCC )
+ return(TRC_E_IDD);
+
+ /* issue idd command to stop trace */
+ NdisZeroMemory(&msg, sizeof(msg));
+ msg.opcode = CMD_TRC_OFF;
+ if ( idd_send_msg(idd, &msg, IDD_PORT_CMD_TX, NULL, NULL) != IDD_E_SUCC )
+ return(TRC_E_IDD);
+
+ return(TRC_E_SUCC);
+}
+
+/* deregister an available idd */
+INT
+trc_deregister_idd(VOID *idd)
+{
+ IDD_MSG msg;
+
+ D_LOG(D_ENTRY, ("trc_deregister_idd: entry, idd: 0x%lx", idd));
+
+ /* issue idd command to stop trace */
+ NdisZeroMemory(&msg, sizeof(msg));
+ msg.opcode = CMD_TRC_OFF;
+ if ( idd_send_msg(idd, &msg, IDD_PORT_CMD_TX, NULL, NULL) != IDD_E_SUCC )
+ return(TRC_E_IDD);
+
+ /* remove handle from idd command receiver */
+ if ( idd_detach(idd, IDD_PORT_CMD_RX, (VOID*)trc__cmd_handler, idd) != IDD_E_SUCC )
+ return(TRC_E_IDD);
+ else
+ return(TRC_E_SUCC);
+}
+
+/* create a trace object */
+INT
+trc_create(VOID **trc_1, ULONG depth)
+{
+ TRC **ret_trc = (TRC**)trc_1;
+ NDIS_PHYSICAL_ADDRESS pa = NDIS_PHYSICAL_ADDRESS_CONST(0xffffffff, 0xffffffff);
+ TRC *trc;
+
+ D_LOG(D_ENTRY, ("trc_create: entry, ret_trc: 0x%lx, depth: %ld", ret_trc, depth));
+
+ /* allocate memory object */
+ NdisAllocateMemory((PVOID*)&trc, sizeof(*trc), 0, pa);
+ if ( !trc )
+ {
+ mem_alloc_failed:
+ D_LOG(D_ALWAYS, ("trc_create: memory allocate failed!"));
+ return(TRC_E_NOMEM);
+ }
+ D_LOG(D_ALWAYS, ("trc_create: trc: 0x%lx", trc));
+ NdisZeroMemory(trc, sizeof(*trc));
+
+ /* allocate buffer memory */
+ NdisAllocateMemory((PVOID*)&trc->ent_tbl, sizeof(TRC_ENTRY) * depth,
+ 0, pa);
+ if ( !trc->ent_tbl )
+ goto mem_alloc_failed;
+ D_LOG(D_ALWAYS, ("trc_create: trc->ent_tbl: 0x%lx", trc->ent_tbl));
+ NdisZeroMemory(trc->ent_tbl, sizeof(TRC_ENTRY) * depth);
+
+ /* setup initial field values */
+ trc->stat.state = TRC_ST_STOP;
+ trc->stat.filter = TRC_FT_NONE;
+ trc->stat.depth = depth;
+
+ /* return succ */
+ *ret_trc = trc;
+ return(TRC_E_SUCC);
+}
+
+/* delte a trace object */
+INT
+trc_destroy(VOID *trc_1)
+{
+ TRC *trc = (TRC*)trc_1;
+
+ D_LOG(D_ENTRY, ("trc_destroy: entry, trc: 0x%lx", trc));
+
+ /* free memory */
+ NdisFreeMemory(trc->ent_tbl, sizeof(TRC_ENTRY) * trc->stat.depth, 0);
+ NdisFreeMemory(trc, sizeof(*trc), 0);
+
+ return(TRC_E_SUCC);
+}
+
+/* perform a trace control function */
+INT
+trc_control(VOID *idd, ULONG op, ULONG arg)
+{
+ IDD_MSG msg;
+ TRC *trc;
+ INT ret;
+
+
+ trc = idd_get_trc(idd);
+
+ D_LOG(D_ENTRY, ("trc_control: idd: 0x%lx trc: 0x%lx, op: 0x%x, arg: 0x%x", idd, trc, op, arg));
+
+ /* branch on opcode */
+ switch ( op )
+ {
+ case TRC_OP_CREATE:
+ D_LOG(D_ENTRY, ("trc_control: CreateTrace"));
+ // if no trace object for this idd yet
+ if (trc == NULL)
+ {
+ //create trace object
+ if ((ret = trc_create(&trc, arg)) != TRC_E_SUCC)
+ return(TRC_E_IDD);
+
+ // register trace for this idd
+ if ((ret = trc_register_idd (idd)) != TRC_E_SUCC)
+ {
+ trc_destroy(trc);
+ return(TRC_E_IDD);
+ }
+
+ idd_set_trc (idd, trc);
+
+ // set ref count
+ trc->create_ref = 0;
+
+ // set backpointer
+ trc->idd = idd;
+ }
+ // inc ref count
+ trc->create_ref++;
+ break;
+
+ case TRC_OP_DESTROY:
+ D_LOG(D_ENTRY, ("trc_control: DestroyTrace"));
+
+ // if trc == NULL break;
+ CheckNULLTrace (trc);
+
+ // dec ref count
+ if (--trc->create_ref)
+ break;
+
+ trc_deregister_idd(idd);
+ trc_destroy(trc);
+ idd_set_trc(idd, NULL);
+ break;
+
+ case TRC_OP_RESET :
+ D_LOG(D_ENTRY, ("trc_control: ResetTrace"));
+ // if trc == NULL break;
+ CheckNULLTrace (trc);
+
+ trc->stat.state = TRC_ST_STOP;
+ trc->stat.entries = trc->stat.seq_1st = 0;
+ trc->ent_put = trc->ent_get = trc->ent_num = trc->ent_seq = 0;
+ break;
+
+ case TRC_OP_STOP :
+ D_LOG(D_ENTRY, ("trc_control: StopTrace"));
+ // if trc == NULL break;
+ CheckNULLTrace (trc);
+
+ // check start flag
+ if (--trc->start_ref)
+ break;
+
+ trc->stat.state = TRC_ST_STOP;
+
+ /* issue idd command to stop trace */
+ NdisZeroMemory(&msg, sizeof(msg));
+ msg.opcode = CMD_TRC_OFF;
+ if ( idd_send_msg((VOID*)arg, &msg, IDD_PORT_CMD_TX, NULL, NULL) != IDD_E_SUCC )
+ return(TRC_E_IDD);
+ break;
+
+ case TRC_OP_START :
+ D_LOG(D_ENTRY, ("trc_control: StartTrace"));
+ // if trc == NULL break;
+ CheckNULLTrace (trc);
+
+ trc->stat.state = TRC_ST_RUN;
+
+ // check start flag
+ if (trc->start_ref++)
+ break;
+
+
+ /* issue idd command to start trace */
+ NdisZeroMemory(&msg, sizeof(msg));
+ msg.opcode = CMD_TRC_ON;
+ if ( idd_send_msg((VOID*)arg, &msg, IDD_PORT_CMD_TX, NULL, NULL) != IDD_E_SUCC )
+ return(TRC_E_IDD);
+ break;
+
+ case TRC_OP_SET_FILTER :
+ D_LOG(D_ENTRY, ("trc_control: SetTraceFilter"));
+ // if trc == NULL break;
+ CheckNULLTrace (trc);
+
+ trc->stat.filter = arg;
+ break;
+
+ default :
+ return(TRC_E_PARAM);
+ }
+
+ /* if here, was successful */
+ return(TRC_E_SUCC);
+}
+
+/* get status of a trace context */
+INT
+trc_get_status(VOID *trc_1, TRC_STATUS *stat)
+{
+ TRC *trc = (TRC*)trc_1;
+
+ D_LOG(D_ENTRY, ("trc_get_status: entry, trc: 0x%lx, stat: 0x%lx", trc, stat));
+
+ // if no obect exit
+ if (trc == NULL)
+ return (TRC_E_NOSUCH);
+
+ *stat = trc->stat;
+ stat->entries = trc->ent_num;
+ stat->seq_1st = trc->ent_seq;
+
+ return(TRC_E_SUCC);
+}
+
+/* get an entry by sequence number */
+INT
+trc_get_entry(VOID *trc_1, ULONG seq, TRC_ENTRY *ent)
+{
+ TRC *trc = (TRC*)trc_1;
+ ULONG n, index;
+
+ D_LOG(D_ENTRY, ("trc_get_entry: entry, trc: 0x%lx, seq: %ld, ent: 0x%lx", \
+ trc, seq, ent));
+
+ // if no obect exit
+ if (trc == NULL)
+ return(TRC_E_NOSUCH);
+
+ /* find requested sequence number, temp!!!, using search! */
+ for ( n = 0 ; n < trc->ent_num ; n++ )
+ {
+ index = (trc->ent_get + n) % trc->stat.depth;
+ if ( trc->ent_tbl[index].seq == seq )
+ {
+ /* found */
+ *ent = trc->ent_tbl[index];
+ return(TRC_E_SUCC);
+ }
+ }
+ /* if here not found */
+ return(TRC_E_NOSUCH);
+}
+
+/* handler for trace and dump area data packets */
+VOID
+trc__cmd_handler(VOID *idd_1, USHORT chan, ULONG Reserved, IDD_MSG *msg)
+{
+ TRC *trc;
+ TRC_ENTRY *ent;
+ IDD *idd = (IDD*)idd_1;
+
+
+ D_LOG(D_ENTRY, ("trc__cmd_handler: idd: %lx, chan: %d, msg: %lx", \
+ idd, chan, msg));
+ D_LOG(D_ENTRY, ("trc__cmd_handler: opcode: 0x%x, buflen: 0x%x, bufptr: %lx", \
+ msg->opcode, msg->buflen, msg->bufptr));
+ D_LOG(D_ENTRY, ("trc__cmd_handler: bufid: %lx, param: 0x%x", \
+ msg->bufid, msg->param));
+
+
+ // Get the trace object for this idd
+ trc = idd_get_trc(idd);
+
+ // if no obect exit
+ if (trc == NULL || msg->bufid >= 2)
+ return;
+
+ /* if here it is a trace frame. param is rx/tx attribute */
+ /* establish entry to insert into & update vars */
+
+ /* check if trace enabled */
+ if ( trc->stat.state == TRC_ST_STOP )
+ return;
+
+ D_LOG(D_ALWAYS, ("trc__cmd_handler: trc: %lx", trc));
+ /* check if frame filters in */
+ if ( !trc__filter(trc->stat.filter, msg->bufptr, msg->buflen) )
+ return;
+
+ /* frames needs to be buffered, establish entry pointer */
+ ent = trc->ent_tbl + trc->ent_put;
+ trc->ent_put = (trc->ent_put + 1) % trc->stat.depth;
+ if ( trc->ent_num < trc->stat.depth )
+ trc->ent_num++;
+
+ /* fill up entry */
+ ent->seq = trc->ent_seq++;
+ KeQuerySystemTime(&ent->time_stamp);
+ ent->attr = msg->bufid;
+ ent->org_len = msg->buflen;
+ ent->len = MIN(msg->buflen, sizeof(ent->data));
+ IddGetDataFromAdapter(idd,
+ (PUCHAR)ent->data,
+ (PUCHAR)msg->bufptr,
+ (USHORT)ent->len);
+// NdisMoveMemory (ent->data, msg->bufptr, ent->len);
+}
+
+/* filter trace frame */
+INT
+trc__filter(ULONG filter, CHAR *buf, ULONG len)
+{
+ D_LOG(D_ENTRY, ("trc__filter: entry, filter: %ld, buf: 0x%lx, len: %ld",\
+ filter, buf, len));
+
+ /* not implemented, all frames filter in */
+ return(1);
+}