13 #define DBG_MAGIC (0x47114711L)
15 static void DI_register(
void *
arg);
20 static void DiProcessEventLog(
unsigned short id,
unsigned long msgID,
va_list ap) { }
22 static void diva_maint_xdi_cb(
ENTITY *
e);
23 static word SuperTraceCreateReadReq(
byte *
P,
const char *
path);
24 static int diva_mnt_cmp_nmbr(
const char *nmbr);
29 static dword MaxDumpSize = 256;
30 static dword MaxXlogSize = 2 + 128;
32 static int TraceFilterIdent = -1;
33 static int TraceFilterChannel = -1;
63 static void diva_maint_state_change_notify(
void *
user_context,
88 #define MSG_INCOMPLETE 0x8000
91 #define queueCompleteMsg(p) do { ((MSG_HEAD *)p - 1)->Size &= ~MSG_INCOMPLETE; } while (0)
92 #define queueCount(q) ((q)->Count)
93 #define MSG_NEED(size) \
94 ((sizeof(MSG_HEAD) + size + sizeof(dword) - 1) & ~(sizeof(dword) - 1))
99 Q->
High = Buffer + sizeBuffer;
124 if (Q->
Tail + need <= Q->High)
goto alloc;
181 return ((
byte *)(Msg + 1));
189 static byte *dbg_base;
190 static int external_dbg_queue;
193 static int dbg_q_busy;
194 static volatile dword dbg_sequence;
195 static dword start_sec;
196 static dword start_usec;
208 if (dbg_queue || (!base) || (length < (4096 * 4))) {
213 TraceFilterIdent = -1;
214 TraceFilterChannel = -1;
221 base +=
sizeof(
dword);
222 length -=
sizeof(
dword);
224 *(
dword *)base = 2048;
225 base +=
sizeof(
dword);
226 length -=
sizeof(
dword);
228 strcpy(base,
"KERNEL MODE BUFFER\n");
233 base +=
sizeof(
dword);
234 length -=
sizeof(
dword);
236 *(
void **)base = (
void *)(base +
sizeof(
void *));
237 base +=
sizeof(
void *);
238 length -=
sizeof(
void *);
242 external_dbg_queue = 0;
245 external_dbg_queue = 1;
249 if (diva_os_initialize_spin_lock(&dbg_q_lock,
"dbg_init")) {
252 external_dbg_queue = 0;
256 if (diva_os_initialize_spin_lock(&dbg_adapter_lock,
"dbg_init")) {
260 external_dbg_queue = 0;
274 void *
ret = (
void *)dbg_base;
285 if (external_dbg_queue) {
288 external_dbg_queue = 0;
291 if (clients[i].pmem) {
292 diva_os_free(0, clients[i].pmem);
304 return (dbg_queue ?
queueCount(dbg_queue) : 0);
316 diva_os_enter_spin_lock(&dbg_q_lock, old_irql,
"read");
318 diva_os_leave_spin_lock(&dbg_q_lock, old_irql,
"read_busy");
325 diva_os_leave_spin_lock(&dbg_q_lock, old_irql,
"read_empty");
341 queueFreeMsg(dbg_queue);
344 diva_os_leave_spin_lock(&dbg_q_lock, old_irql,
"read_ack");
366 if ((format[0] == 0) && ((
unsigned char)format[1] == 255)) {
367 hDbg =
va_arg(ap,
void *);
374 static void DI_register(
void *
arg) {
378 int id, free_id = -1, best_id = 0;
386 if ((hDbg ==
NULL) ||
392 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"register");
394 for (
id = 1;
id <
ARRAY_SIZE(clients);
id++) {
395 if (clients[
id].hDbg == hDbg) {
399 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"register");
402 if (clients[
id].hDbg) {
414 if (!clients[
id].hDbg) {
428 clients[free_id].
hDbg = hDbg;
429 clients[free_id].
sec =
sec;
430 clients[free_id].
usec = usec;
433 clients[free_id].
dbgMask = hDbg->dbgMask;
441 hDbg->id = (
byte)free_id;
442 hDbg->dbg_end = DI_deregister;
443 hDbg->dbg_prt = DI_format_locked;
444 hDbg->dbg_ev = DiProcessEventLog;
445 hDbg->dbg_irq = DI_format_locked;
446 if (hDbg->Version > 0) {
447 hDbg->dbg_old = DI_format_old;
454 len =
sprintf(tmp,
"DIMAINT - drv # %d = '%s' registered",
455 free_id, hDbg->drvName);
458 (
word)(len + 1 +
sizeof(*pmsg))))) {
460 queueFreeMsg(dbg_queue);
476 memcpy(&pmsg[1], tmp, len + 1);
482 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"register");
494 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1,
"read");
495 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"read");
498 if (clients[i].hDbg == hDbg) {
515 if (clients[i].pIdiLib) {
519 pmem = clients[
i].
pmem;
526 len =
sprintf(tmp,
"DIMAINT - drv # %d = '%s' de-registered",
530 (
word)(len + 1 +
sizeof(*pmsg))))) {
532 queueFreeMsg(dbg_queue);
548 memcpy(&pmsg[1], tmp, len + 1);
557 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"read_ack");
558 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1,
"read_ack");
561 diva_os_free(0, pmem);
565 static void DI_format_locked(
unsigned short id,
569 DI_format(1,
id, type, format, argument_list);
572 static void DI_format(
int do_lock,
592 ((TraceFilter[0] != 0) && ((TraceFilterIdent < 0) || (TraceFilterChannel < 0)))) {
601 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"format");
609 if (!(length =
va_arg(ap,
unsigned long))) {
612 if (length > MaxDumpSize) {
613 length = MaxDumpSize;
616 (
word)length +
sizeof(*pmsg)))) {
618 queueFreeMsg(dbg_queue);
624 memcpy(&pmsg[1], format, length);
639 data =
va_arg(ap,
char *);
641 length = (
unsigned long)
va_arg(ap,
unsigned int);
643 if (length > MaxXlogSize)
644 length = MaxXlogSize;
647 (
word)length +
sizeof(*pmsg) + 2))) {
649 queueFreeMsg(dbg_queue);
655 p = (
byte *)&pmsg[1];
657 p[1] = (
char)(code >> 8);
658 if (data && length) {
659 memcpy(&p[2], &data[0], length);
692 if ((length = (
unsigned long)
vsprintf(&fmtBuf[0], format, ap)) > 0) {
693 length += (
sizeof(*pmsg) + 1);
698 queueFreeMsg(dbg_queue);
713 memcpy(&pmsg[1], fmtBuf, pmsg->data_length);
726 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"format");
738 if (!data || !
id || (data_length < 17) ||
743 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"driver info");
745 if (clients[
id].hDbg) {
747 *p++ = (
byte)clients[
id].sec;
748 *p++ = (
byte)(clients[
id].sec >> 8);
749 *p++ = (
byte)(clients[
id].sec >> 16);
750 *p++ = (
byte)(clients[
id].sec >> 24);
752 *p++ = (
byte)(clients[
id].usec / 1000);
753 *p++ = (
byte)((clients[
id].usec / 1000) >> 8);
754 *p++ = (
byte)((clients[
id].usec / 1000) >> 16);
755 *p++ = (
byte)((clients[
id].usec / 1000) >> 24);
759 if ((to_copy =
min(
strlen(clients[
id].drvName), (
size_t)(data_length - 1)))) {
760 memcpy(p, clients[
id].drvName, to_copy);
762 data_length -= to_copy;
763 if ((data_length >= 4) && clients[
id].hDbg->drvTag[0]) {
766 if ((to_copy =
min(
strlen(clients[
id].hDbg->drvTag), (
size_t)(data_length - 2)))) {
767 memcpy(p, clients[
id].hDbg->drvTag, to_copy);
769 data_length -= to_copy;
770 if (data_length >= 2) {
780 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"driver info");
789 if (!data || !
id || (
id >=
ARRAY_SIZE(clients))) {
792 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"driver info");
794 if (clients[
id].hDbg) {
802 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"driver info");
816 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1,
"dbg mask");
817 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"dbg mask");
819 if (clients[
id].hDbg) {
825 diva_change_management_debug_mask(&clients[
id], old_mask);
829 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"dbg mask");
831 if (clients[
id].request_pending) {
833 (*(clients[
id].
request))((
ENTITY *)(*(clients[
id].pIdiLib->DivaSTraceGetHandle))(clients[
id].pIdiLib->hLib));
836 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1,
"dbg mask");
846 (*request)((
ENTITY *)&sync_req);
847 *logical = sync_req.xdi_logical_adapter_number.info.logical_adapter_number;
849 sync_req.GetSerial.Req = 0;
851 sync_req.GetSerial.serial = 0;
852 (*request)((
ENTITY *)&sync_req);
853 *
serial = sync_req.GetSerial.serial;
864 int id, free_id = -1;
872 diva_get_idi_adapter_info(d->
request, &serial, &logical);
873 if (serial & 0xff000000) {
874 sprintf(tmp,
"ADAPTER:%d SN:%u-%d",
877 (
byte)(((serial & 0xff000000) >> 24) + 1));
879 sprintf(tmp,
"ADAPTER:%d SN:%u", (
int)logical, serial);
887 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1,
"register");
888 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"register");
890 for (
id = 1;
id <
ARRAY_SIZE(clients);
id++) {
892 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"register");
893 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1,
"register");
894 diva_os_free(0, pmem);
897 if (clients[
id].hDbg) {
903 if (!
strcmp(clients[
id].drvName, tmp)) {
914 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"register");
915 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1,
"register");
916 diva_os_free(0, pmem);
926 strcpy(clients[
id].drvName, tmp);
950 diva_maint_state_change_notify,
951 diva_maint_trace_notify,
957 if ((clients[
id].pIdiLib =
959 if (((*(clients[
id].pIdiLib->DivaSTraceLibraryStart))(clients[
id].pIdiLib->hLib))) {
969 if (!clients[
id].pIdiLib) {
973 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"register");
974 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1,
"register");
975 diva_os_free(0, pmem);
982 len =
sprintf(tmp,
"DIMAINT - drv # %d = '%s' registered",
986 (
word)(len + 1 +
sizeof(*pmsg))))) {
988 queueFreeMsg(dbg_queue);
1004 memcpy(&pmsg[1], tmp, len + 1);
1012 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"register");
1014 if (clients[
id].request_pending) {
1016 (*(clients[
id].
request))((
ENTITY *)(*(clients[
id].pIdiLib->DivaSTraceGetHandle))(clients[
id].pIdiLib->hLib));
1019 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1,
"register");
1036 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1,
"read");
1037 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"read");
1045 if (clients[i].pIdiLib) {
1049 pmem = clients[
i].
pmem;
1067 len =
sprintf(tmp,
"DIMAINT - drv # %d = '%s' de-registered",
1070 memset(&clients[i].Dbg, 0x00,
sizeof(clients[i].Dbg));
1073 (
word)(len + 1 +
sizeof(*pmsg))))) {
1075 queueFreeMsg(dbg_queue);
1091 memcpy(&pmsg[1], tmp, len + 1);
1100 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"read_ack");
1101 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1,
"read_ack");
1104 diva_os_free(0, pmem);
1118 if (clients[i].hDbg && clients[i].
request && (clients[i].logical == AdapterNumber)) {
1119 return (&clients[i]);
1142 length = SuperTraceCreateReadReq(xdata, name);
1143 single_p(xdata, &length, 0);
1159 if (AdapterHandle) {
1176 word assign_data_length = 1;
1191 if ((pC->
dma_handle = diva_get_dma_descriptor(pC->
request, &rx_dma_magic)) >= 0) {
1204 assign_data_length = 11;
1216 e->
X->
PLength = assign_data_length;
1261 length = SuperTraceCreateReadReq(xdata, name);
1262 single_p(xdata, &length, 0);
1287 word length = SuperTraceCreateReadReq((
byte *)pVar,
name);
1290 length += var_length;
1291 pVar->
length += var_length;
1294 single_p((
byte *)pVar, &length, 0);
1319 length = SuperTraceCreateReadReq(xdata, name);
1320 single_p(xdata, &length, 0);
1335 static word SuperTraceCreateReadReq(
byte *
P,
const char *
path) {
1349 memcpy(P, path, var_length);
1351 *plen = var_length + 0x06;
1353 return ((
word)(var_length + 0x08));
1356 static void single_p(
byte *P,
word *PLength,
byte Id) {
1357 P[(*PLength)++] = Id;
1360 static void diva_maint_xdi_cb(
ENTITY *
e) {
1366 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1,
"xdi_cb");
1367 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"xdi_cb");
1384 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"xdi_cb");
1392 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1,
"xdi_cb");
1403 "Trace library error(%d) A(%d) %s %d", error, Adapter, file, line);
1412 for (i = 0; ((i < ie->
length) && (length > 3)); i++) {
1416 if (i < (ie->
length - 1)) {
1425 static void diva_maint_state_change_notify(
void *
user_context,
1429 int notify_subject) {
1439 switch (notify_subject) {
1441 int view = (TraceFilter[0] == 0);
1445 if (channel->
Line[0] ==
'I' && channel->
Line[1] ==
'd' &&
1446 channel->
Line[2] ==
'l' && channel->
Line[3] ==
'e') {
1452 TraceFilterIdent = -1;
1453 TraceFilterChannel = -1;
1456 }
else if (TraceFilter[0] && (TraceFilterIdent < 0) && !(diva_mnt_cmp_nmbr(&channel->
RemoteAddress[0]) &&
1466 TraceFilterIdent = pC->
hDbg->
id;
1469 if (TraceFilterIdent >= 0) {
1490 print_ie(&channel->
call_BC, tmp,
sizeof(tmp));
1492 print_ie(&channel->
call_HLC, tmp,
sizeof(tmp));
1494 print_ie(&channel->
call_LLC, tmp,
sizeof(tmp));
1507 int ch = TraceFilterChannel;
1508 int id = TraceFilterIdent;
1510 if ((
id >= 0) && (ch >= 0) && (
id <
ARRAY_SIZE(clients)) &&
1511 (clients[
id].Dbg.id == (
byte)
id) && (clients[
id].
pIdiLib == hLib)) {
1515 }
else if (TraceFilter[0] != 0) {
1542 if (modem->
Event == 3) {
1554 int ch = TraceFilterChannel;
1555 int id = TraceFilterIdent;
1557 if ((
id >= 0) && (ch >= 0) && (
id <
ARRAY_SIZE(clients)) &&
1558 (clients[
id].Dbg.id == (
byte)
id) && (clients[
id].pIdiLib == hLib)) {
1562 }
else if (TraceFilter[0] != 0) {
1579 if (fax->
Event == 3) {
1790 static void diva_maint_trace_notify(
void *user_context,
1799 int ch = TraceFilterChannel;
1800 int id = TraceFilterIdent;
1805 if ((
id >= 0) && (ch >= 0) && (
id <
ARRAY_SIZE(clients)) &&
1806 (clients[
id].Dbg.id == (
byte)
id) && (clients[
id].pIdiLib == hLib)) {
1807 const char *p =
NULL;
1811 if (Adapter != clients[
id].logical) {
1815 if (TrcData->
code == 24) {
1816 p = (
char *)&TrcData->
code;
1824 if (p && p[0] ==
'[') {
1827 ch_value = *p -
'0';
1828 }
else if (p[3] ==
',') {
1830 ch_value = *p -
'0';
1832 if (ch_value >= 0) {
1834 ch_value = ch_value * 10 + p[1] -
'0';
1836 if (ch_value != ch) {
1842 }
else if (TraceFilter[0] != 0) {
1849 (
word)length +
sizeof(*pmsg)))) {
1851 queueFreeMsg(dbg_queue);
1857 memcpy(&pmsg[1], xlog_buffer, length);
1890 if (!TraceFilter[0]) {
1894 for (i = 0; i < pC->
channels; i++) {
1901 for (i = 0; i < pC->
channels; i++) {
1914 DI_format(0, (
word)drv_id, (
int)type, fmt, ap);
1930 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1,
"unload");
1931 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"unload");
1933 if (clients[i].hDbg && clients[i].pIdiLib && clients[i].
request) {
1934 if ((*(clients[i].pIdiLib->DivaSTraceLibraryStop))(clients[i].
pIdiLib) == 1) {
1938 if (clients[i].pIdiLib) {
1942 pmem = clients[
i].
pmem;
1952 diva_free_dma_descriptor(clients[i].request, clients[i].
dma_handle);
1961 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"unload");
1962 if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {
1964 (*(clients[
i].
request))((
ENTITY *)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));
1966 diva_free_dma_descriptor(clients[i].request, clients[i].
dma_handle);
1970 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1,
"unload");
1973 diva_os_free(0, pmem);
1986 int i, ch, on, client_b_on, client_atap_on;
1988 diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1,
"dbg mask");
1989 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"write_filter");
1992 memcpy(&TraceFilter[0], filter, filter_length);
1993 if (TraceFilter[filter_length]) {
1994 TraceFilter[filter_length] = 0;
1996 if (TraceFilter[0] ==
'*') {
2003 TraceFilterIdent = -1;
2004 TraceFilterChannel = -1;
2006 on = (TraceFilter[0] == 0);
2009 if (clients[i].hDbg && clients[i].pIdiLib && clients[i].
request) {
2012 for (ch = 0; ch < clients[
i].
channels; ch++) {
2020 if (clients[i].hDbg && clients[i].pIdiLib && clients[i].
request && clients[i].request_pending) {
2021 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"write_filter");
2023 (*(clients[
i].
request))((
ENTITY *)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));
2024 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"write_filter");
2028 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"write_filter");
2029 diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1,
"dbg mask");
2031 return (filter_length);
2038 diva_os_enter_spin_lock(&dbg_q_lock, &old_irql,
"read_filter");
2039 len =
strlen(&TraceFilter[0]) + 1;
2040 if (max_length >= len) {
2041 memcpy(filter, &TraceFilter[0], len);
2043 diva_os_leave_spin_lock(&dbg_q_lock, &old_irql,
"read_filter");
2048 static int diva_dbg_cmp_key(
const char *ref,
const char *
key) {
2049 while (*key && (*ref++ == *key++));
2050 return (!*key && !*ref);
2059 static int diva_mnt_cmp_nmbr(
const char *nmbr) {
2060 const char *ref = &TraceFilter[0];
2061 int ref_len =
strlen(&TraceFilter[0]), nmbr_len =
strlen(nmbr);
2063 if (ref[0] ==
'C') {
2064 if (diva_dbg_cmp_key(&ref[1],
"single")) {
2070 if (!ref_len || (ref_len > nmbr_len)) {
2074 nmbr = nmbr + nmbr_len - 1;
2075 ref = ref + ref_len - 1;
2078 if (*nmbr-- != *ref--) {
2102 (*request)((
ENTITY *)pReq);
2114 static void diva_free_dma_descriptor(
IDI_CALL request,
int nr) {
2118 if (!request || (nr < 0)) {
2130 (*request)((
ENTITY *)pReq);