diff options
-rw-r--r-- | drivers/isdn/capi/Kconfig | 16 | ||||
-rw-r--r-- | drivers/isdn/capi/capidrv.c | 28 | ||||
-rw-r--r-- | drivers/isdn/capi/capiutil.c | 254 | ||||
-rw-r--r-- | drivers/isdn/capi/kcapi.c | 77 | ||||
-rw-r--r-- | include/linux/isdn/capiutil.h | 21 |
5 files changed, 318 insertions, 78 deletions
diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig index 8b6c9a431ffa..c921d6c522f5 100644 --- a/drivers/isdn/capi/Kconfig +++ b/drivers/isdn/capi/Kconfig | |||
@@ -2,13 +2,25 @@ | |||
2 | # Config.in for the CAPI subsystem | 2 | # Config.in for the CAPI subsystem |
3 | # | 3 | # |
4 | config ISDN_DRV_AVMB1_VERBOSE_REASON | 4 | config ISDN_DRV_AVMB1_VERBOSE_REASON |
5 | bool "Verbose reason code reporting (kernel size +=7K)" | 5 | bool "Verbose reason code reporting" |
6 | depends on ISDN_CAPI | 6 | depends on ISDN_CAPI |
7 | default y | ||
7 | help | 8 | help |
8 | If you say Y here, the AVM B1 driver will give verbose reasons for | 9 | If you say Y here, the CAPI drivers will give verbose reasons for |
9 | disconnecting. This will increase the size of the kernel by 7 KB. If | 10 | disconnecting. This will increase the size of the kernel by 7 KB. If |
10 | unsure, say Y. | 11 | unsure, say Y. |
11 | 12 | ||
13 | config CAPI_TRACE | ||
14 | bool "CAPI trace support" | ||
15 | depends on ISDN_CAPI | ||
16 | default y | ||
17 | help | ||
18 | If you say Y here, the kernelcapi driver can make verbose traces | ||
19 | of CAPI messages. This feature can be enabled/disabled via IOCTL for | ||
20 | every controler (default disabled). | ||
21 | This will increase the size of the kernelcapi module by 20 KB. | ||
22 | If unsure, say Y. | ||
23 | |||
12 | config ISDN_CAPI_MIDDLEWARE | 24 | config ISDN_CAPI_MIDDLEWARE |
13 | bool "CAPI2.0 Middleware support (EXPERIMENTAL)" | 25 | bool "CAPI2.0 Middleware support (EXPERIMENTAL)" |
14 | depends on ISDN_CAPI && EXPERIMENTAL | 26 | depends on ISDN_CAPI && EXPERIMENTAL |
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index 2a49cea0a223..23b6f7bc16b7 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c | |||
@@ -990,6 +990,7 @@ static void handle_plci(_cmsg * cmsg) | |||
990 | capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f); | 990 | capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f); |
991 | capidrv_plci *plcip; | 991 | capidrv_plci *plcip; |
992 | isdn_ctrl cmd; | 992 | isdn_ctrl cmd; |
993 | _cdebbuf *cdb; | ||
993 | 994 | ||
994 | if (!card) { | 995 | if (!card) { |
995 | printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n", | 996 | printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n", |
@@ -1122,8 +1123,15 @@ static void handle_plci(_cmsg * cmsg) | |||
1122 | break; | 1123 | break; |
1123 | } | 1124 | } |
1124 | } | 1125 | } |
1125 | printk(KERN_ERR "capidrv-%d: %s\n", | 1126 | cdb = capi_cmsg2str(cmsg); |
1126 | card->contrnr, capi_cmsg2str(cmsg)); | 1127 | if (cdb) { |
1128 | printk(KERN_WARNING "capidrv-%d: %s\n", | ||
1129 | card->contrnr, cdb->buf); | ||
1130 | cdebbuf_free(cdb); | ||
1131 | } else | ||
1132 | printk(KERN_WARNING "capidrv-%d: CAPI_INFO_IND InfoNumber %x not handled\n", | ||
1133 | card->contrnr, cmsg->InfoNumber); | ||
1134 | |||
1127 | break; | 1135 | break; |
1128 | 1136 | ||
1129 | case CAPI_CONNECT_ACTIVE_CONF: /* plci */ | 1137 | case CAPI_CONNECT_ACTIVE_CONF: /* plci */ |
@@ -1371,10 +1379,18 @@ static _cmsg s_cmsg; | |||
1371 | static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb) | 1379 | static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb) |
1372 | { | 1380 | { |
1373 | capi_message2cmsg(&s_cmsg, skb->data); | 1381 | capi_message2cmsg(&s_cmsg, skb->data); |
1374 | if (debugmode > 3) | 1382 | if (debugmode > 3) { |
1375 | printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n", | 1383 | _cdebbuf *cdb = capi_cmsg2str(&s_cmsg); |
1376 | ap->applid, capi_cmsg2str(&s_cmsg)); | 1384 | |
1377 | 1385 | if (cdb) { | |
1386 | printk(KERN_DEBUG "%s: applid=%d %s\n", __FUNCTION__, | ||
1387 | ap->applid, cdb->buf); | ||
1388 | cdebbuf_free(cdb); | ||
1389 | } else | ||
1390 | printk(KERN_DEBUG "%s: applid=%d %s not traced\n", | ||
1391 | __FUNCTION__, ap->applid, | ||
1392 | capi_cmd2str(s_cmsg.Command, s_cmsg.Subcommand)); | ||
1393 | } | ||
1378 | if (s_cmsg.Command == CAPI_DATA_B3 | 1394 | if (s_cmsg.Command == CAPI_DATA_B3 |
1379 | && s_cmsg.Subcommand == CAPI_IND) { | 1395 | && s_cmsg.Subcommand == CAPI_IND) { |
1380 | handle_data(&s_cmsg, skb); | 1396 | handle_data(&s_cmsg, skb); |
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c index c1b21552fc03..ad1e2702c2d1 100644 --- a/drivers/isdn/capi/capiutil.c +++ b/drivers/isdn/capi/capiutil.c | |||
@@ -648,6 +648,9 @@ char *capi_cmd2str(u8 cmd, u8 subcmd) | |||
648 | 648 | ||
649 | 649 | ||
650 | /*-------------------------------------------------------*/ | 650 | /*-------------------------------------------------------*/ |
651 | |||
652 | #ifdef CONFIG_CAPI_TRACE | ||
653 | |||
651 | /*-------------------------------------------------------*/ | 654 | /*-------------------------------------------------------*/ |
652 | 655 | ||
653 | static char *pnames[] = | 656 | static char *pnames[] = |
@@ -703,44 +706,77 @@ static char *pnames[] = | |||
703 | }; | 706 | }; |
704 | 707 | ||
705 | 708 | ||
706 | static char buf[8192]; | ||
707 | static char *p = NULL; | ||
708 | 709 | ||
709 | #include <stdarg.h> | 710 | #include <stdarg.h> |
710 | 711 | ||
711 | /*-------------------------------------------------------*/ | 712 | /*-------------------------------------------------------*/ |
712 | static void bufprint(char *fmt,...) | 713 | static _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt,...) |
713 | { | 714 | { |
714 | va_list f; | 715 | va_list f; |
716 | size_t n,r; | ||
717 | |||
718 | if (!cdb) | ||
719 | return NULL; | ||
715 | va_start(f, fmt); | 720 | va_start(f, fmt); |
716 | vsprintf(p, fmt, f); | 721 | r = cdb->size - cdb->pos; |
722 | n = vsnprintf(cdb->p, r, fmt, f); | ||
717 | va_end(f); | 723 | va_end(f); |
718 | p += strlen(p); | 724 | if (n >= r) { |
725 | /* truncated, need bigger buffer */ | ||
726 | size_t ns = 2 * cdb->size; | ||
727 | u_char *nb; | ||
728 | |||
729 | while ((ns - cdb->pos) <= n) | ||
730 | ns *= 2; | ||
731 | nb = kmalloc(ns, GFP_ATOMIC); | ||
732 | if (!nb) { | ||
733 | cdebbuf_free(cdb); | ||
734 | return NULL; | ||
735 | } | ||
736 | memcpy(nb, cdb->buf, cdb->pos); | ||
737 | kfree(cdb->buf); | ||
738 | nb[cdb->pos] = 0; | ||
739 | cdb->buf = nb; | ||
740 | cdb->p = cdb->buf + cdb->pos; | ||
741 | cdb->size = ns; | ||
742 | va_start(f, fmt); | ||
743 | r = cdb->size - cdb->pos; | ||
744 | n = vsnprintf(cdb->p, r, fmt, f); | ||
745 | va_end(f); | ||
746 | } | ||
747 | cdb->p += n; | ||
748 | cdb->pos += n; | ||
749 | return cdb; | ||
719 | } | 750 | } |
720 | 751 | ||
721 | static void printstructlen(u8 * m, unsigned len) | 752 | static _cdebbuf *printstructlen(_cdebbuf *cdb, u8 * m, unsigned len) |
722 | { | 753 | { |
723 | unsigned hex = 0; | 754 | unsigned hex = 0; |
755 | |||
756 | if (!cdb) | ||
757 | return NULL; | ||
724 | for (; len; len--, m++) | 758 | for (; len; len--, m++) |
725 | if (isalnum(*m) || *m == ' ') { | 759 | if (isalnum(*m) || *m == ' ') { |
726 | if (hex) | 760 | if (hex) |
727 | bufprint(">"); | 761 | cdb = bufprint(cdb, ">"); |
728 | bufprint("%c", *m); | 762 | cdb = bufprint(cdb, "%c", *m); |
729 | hex = 0; | 763 | hex = 0; |
730 | } else { | 764 | } else { |
731 | if (!hex) | 765 | if (!hex) |
732 | bufprint("<%02x", *m); | 766 | cdb = bufprint(cdb, "<%02x", *m); |
733 | else | 767 | else |
734 | bufprint(" %02x", *m); | 768 | cdb = bufprint(cdb, " %02x", *m); |
735 | hex = 1; | 769 | hex = 1; |
736 | } | 770 | } |
737 | if (hex) | 771 | if (hex) |
738 | bufprint(">"); | 772 | cdb = bufprint(cdb, ">"); |
773 | return cdb; | ||
739 | } | 774 | } |
740 | 775 | ||
741 | static void printstruct(u8 * m) | 776 | static _cdebbuf *printstruct(_cdebbuf *cdb, u8 * m) |
742 | { | 777 | { |
743 | unsigned len; | 778 | unsigned len; |
779 | |||
744 | if (m[0] != 0xff) { | 780 | if (m[0] != 0xff) { |
745 | len = m[0]; | 781 | len = m[0]; |
746 | m += 1; | 782 | m += 1; |
@@ -748,42 +784,45 @@ static void printstruct(u8 * m) | |||
748 | len = ((u16 *) (m + 1))[0]; | 784 | len = ((u16 *) (m + 1))[0]; |
749 | m += 3; | 785 | m += 3; |
750 | } | 786 | } |
751 | printstructlen(m, len); | 787 | cdb = printstructlen(cdb, m, len); |
788 | return cdb; | ||
752 | } | 789 | } |
753 | 790 | ||
754 | /*-------------------------------------------------------*/ | 791 | /*-------------------------------------------------------*/ |
755 | #define NAME (pnames[cmsg->par[cmsg->p]]) | 792 | #define NAME (pnames[cmsg->par[cmsg->p]]) |
756 | 793 | ||
757 | static void protocol_message_2_pars(_cmsg * cmsg, int level) | 794 | static _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level) |
758 | { | 795 | { |
759 | for (; TYP != _CEND; cmsg->p++) { | 796 | for (; TYP != _CEND; cmsg->p++) { |
760 | int slen = 29 + 3 - level; | 797 | int slen = 29 + 3 - level; |
761 | int i; | 798 | int i; |
762 | 799 | ||
763 | bufprint(" "); | 800 | if (!cdb) |
801 | return NULL; | ||
802 | cdb = bufprint(cdb, " "); | ||
764 | for (i = 0; i < level - 1; i++) | 803 | for (i = 0; i < level - 1; i++) |
765 | bufprint(" "); | 804 | cdb = bufprint(cdb, " "); |
766 | 805 | ||
767 | switch (TYP) { | 806 | switch (TYP) { |
768 | case _CBYTE: | 807 | case _CBYTE: |
769 | bufprint("%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l)); | 808 | cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l)); |
770 | cmsg->l++; | 809 | cmsg->l++; |
771 | break; | 810 | break; |
772 | case _CWORD: | 811 | case _CWORD: |
773 | bufprint("%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l)); | 812 | cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l)); |
774 | cmsg->l += 2; | 813 | cmsg->l += 2; |
775 | break; | 814 | break; |
776 | case _CDWORD: | 815 | case _CDWORD: |
777 | bufprint("%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l)); | 816 | cdb = bufprint(cdb, "%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l)); |
778 | cmsg->l += 4; | 817 | cmsg->l += 4; |
779 | break; | 818 | break; |
780 | case _CSTRUCT: | 819 | case _CSTRUCT: |
781 | bufprint("%-*s = ", slen, NAME); | 820 | cdb = bufprint(cdb, "%-*s = ", slen, NAME); |
782 | if (cmsg->m[cmsg->l] == '\0') | 821 | if (cmsg->m[cmsg->l] == '\0') |
783 | bufprint("default"); | 822 | cdb = bufprint(cdb, "default"); |
784 | else | 823 | else |
785 | printstruct(cmsg->m + cmsg->l); | 824 | cdb = printstruct(cdb, cmsg->m + cmsg->l); |
786 | bufprint("\n"); | 825 | cdb = bufprint(cdb, "\n"); |
787 | if (cmsg->m[cmsg->l] != 0xff) | 826 | if (cmsg->m[cmsg->l] != 0xff) |
788 | cmsg->l += 1 + cmsg->m[cmsg->l]; | 827 | cmsg->l += 1 + cmsg->m[cmsg->l]; |
789 | else | 828 | else |
@@ -794,61 +833,184 @@ static void protocol_message_2_pars(_cmsg * cmsg, int level) | |||
794 | case _CMSTRUCT: | 833 | case _CMSTRUCT: |
795 | /*----- Metastruktur 0 -----*/ | 834 | /*----- Metastruktur 0 -----*/ |
796 | if (cmsg->m[cmsg->l] == '\0') { | 835 | if (cmsg->m[cmsg->l] == '\0') { |
797 | bufprint("%-*s = default\n", slen, NAME); | 836 | cdb = bufprint(cdb, "%-*s = default\n", slen, NAME); |
798 | cmsg->l++; | 837 | cmsg->l++; |
799 | jumpcstruct(cmsg); | 838 | jumpcstruct(cmsg); |
800 | } else { | 839 | } else { |
801 | char *name = NAME; | 840 | char *name = NAME; |
802 | unsigned _l = cmsg->l; | 841 | unsigned _l = cmsg->l; |
803 | bufprint("%-*s\n", slen, name); | 842 | cdb = bufprint(cdb, "%-*s\n", slen, name); |
804 | cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1; | 843 | cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1; |
805 | cmsg->p++; | 844 | cmsg->p++; |
806 | protocol_message_2_pars(cmsg, level + 1); | 845 | cdb = protocol_message_2_pars(cdb, cmsg, level + 1); |
807 | } | 846 | } |
808 | break; | 847 | break; |
809 | } | 848 | } |
810 | } | 849 | } |
850 | return cdb; | ||
811 | } | 851 | } |
812 | /*-------------------------------------------------------*/ | 852 | /*-------------------------------------------------------*/ |
813 | char *capi_message2str(u8 * msg) | 853 | |
854 | static _cdebbuf *g_debbuf; | ||
855 | static u_long g_debbuf_lock; | ||
856 | static _cmsg *g_cmsg; | ||
857 | |||
858 | _cdebbuf *cdebbuf_alloc(void) | ||
814 | { | 859 | { |
860 | _cdebbuf *cdb; | ||
861 | |||
862 | if (likely(!test_and_set_bit(1, &g_debbuf_lock))) { | ||
863 | cdb = g_debbuf; | ||
864 | goto init; | ||
865 | } else | ||
866 | cdb = kmalloc(sizeof(_cdebbuf), GFP_ATOMIC); | ||
867 | if (!cdb) | ||
868 | return NULL; | ||
869 | cdb->buf = kmalloc(CDEBUG_SIZE, GFP_ATOMIC); | ||
870 | if (!cdb->buf) { | ||
871 | kfree(cdb); | ||
872 | return NULL; | ||
873 | } | ||
874 | cdb->size = CDEBUG_SIZE; | ||
875 | init: | ||
876 | cdb->buf[0] = 0; | ||
877 | cdb->p = cdb->buf; | ||
878 | cdb->pos = 0; | ||
879 | return cdb; | ||
880 | } | ||
815 | 881 | ||
816 | _cmsg cmsg; | 882 | void cdebbuf_free(_cdebbuf *cdb) |
817 | p = buf; | 883 | { |
818 | p[0] = 0; | 884 | if (likely(cdb == g_debbuf)) { |
885 | test_and_clear_bit(1, &g_debbuf_lock); | ||
886 | return; | ||
887 | } | ||
888 | if (likely(cdb)) | ||
889 | kfree(cdb->buf); | ||
890 | kfree(cdb); | ||
891 | } | ||
819 | 892 | ||
820 | cmsg.m = msg; | ||
821 | cmsg.l = 8; | ||
822 | cmsg.p = 0; | ||
823 | byteTRcpy(cmsg.m + 4, &cmsg.Command); | ||
824 | byteTRcpy(cmsg.m + 5, &cmsg.Subcommand); | ||
825 | cmsg.par = cpars[command_2_index(cmsg.Command, cmsg.Subcommand)]; | ||
826 | 893 | ||
827 | bufprint("%-26s ID=%03d #0x%04x LEN=%04d\n", | 894 | _cdebbuf *capi_message2str(u8 * msg) |
828 | mnames[command_2_index(cmsg.Command, cmsg.Subcommand)], | 895 | { |
896 | _cdebbuf *cdb; | ||
897 | _cmsg *cmsg; | ||
898 | |||
899 | cdb = cdebbuf_alloc(); | ||
900 | if (unlikely(!cdb)) | ||
901 | return NULL; | ||
902 | if (likely(cdb == g_debbuf)) | ||
903 | cmsg = g_cmsg; | ||
904 | else | ||
905 | cmsg = kmalloc(sizeof(_cmsg), GFP_ATOMIC); | ||
906 | if (unlikely(!cmsg)) { | ||
907 | cdebbuf_free(cdb); | ||
908 | return NULL; | ||
909 | } | ||
910 | cmsg->m = msg; | ||
911 | cmsg->l = 8; | ||
912 | cmsg->p = 0; | ||
913 | byteTRcpy(cmsg->m + 4, &cmsg->Command); | ||
914 | byteTRcpy(cmsg->m + 5, &cmsg->Subcommand); | ||
915 | cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)]; | ||
916 | |||
917 | cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n", | ||
918 | mnames[command_2_index(cmsg->Command, cmsg->Subcommand)], | ||
829 | ((unsigned short *) msg)[1], | 919 | ((unsigned short *) msg)[1], |
830 | ((unsigned short *) msg)[3], | 920 | ((unsigned short *) msg)[3], |
831 | ((unsigned short *) msg)[0]); | 921 | ((unsigned short *) msg)[0]); |
832 | 922 | ||
833 | protocol_message_2_pars(&cmsg, 1); | 923 | cdb = protocol_message_2_pars(cdb, cmsg, 1); |
834 | return buf; | 924 | if (unlikely(cmsg != g_cmsg)) |
925 | kfree(cmsg); | ||
926 | return cdb; | ||
835 | } | 927 | } |
836 | 928 | ||
837 | char *capi_cmsg2str(_cmsg * cmsg) | 929 | _cdebbuf *capi_cmsg2str(_cmsg * cmsg) |
838 | { | 930 | { |
839 | p = buf; | 931 | _cdebbuf *cdb; |
840 | p[0] = 0; | 932 | |
933 | cdb = cdebbuf_alloc(); | ||
934 | if (!cdb) | ||
935 | return NULL; | ||
841 | cmsg->l = 8; | 936 | cmsg->l = 8; |
842 | cmsg->p = 0; | 937 | cmsg->p = 0; |
843 | bufprint("%s ID=%03d #0x%04x LEN=%04d\n", | 938 | cdb = bufprint(cdb, "%s ID=%03d #0x%04x LEN=%04d\n", |
844 | mnames[command_2_index(cmsg->Command, cmsg->Subcommand)], | 939 | mnames[command_2_index(cmsg->Command, cmsg->Subcommand)], |
845 | ((u16 *) cmsg->m)[1], | 940 | ((u16 *) cmsg->m)[1], |
846 | ((u16 *) cmsg->m)[3], | 941 | ((u16 *) cmsg->m)[3], |
847 | ((u16 *) cmsg->m)[0]); | 942 | ((u16 *) cmsg->m)[0]); |
848 | protocol_message_2_pars(cmsg, 1); | 943 | cdb = protocol_message_2_pars(cdb, cmsg, 1); |
849 | return buf; | 944 | return cdb; |
850 | } | 945 | } |
851 | 946 | ||
947 | int __init cdebug_init(void) | ||
948 | { | ||
949 | g_cmsg= kmalloc(sizeof(_cmsg), GFP_KERNEL); | ||
950 | if (!g_cmsg) | ||
951 | return ENOMEM; | ||
952 | g_debbuf = kmalloc(sizeof(_cdebbuf), GFP_KERNEL); | ||
953 | if (!g_debbuf) { | ||
954 | kfree(g_cmsg); | ||
955 | return ENOMEM; | ||
956 | } | ||
957 | g_debbuf->buf = kmalloc(CDEBUG_GSIZE, GFP_KERNEL); | ||
958 | if (!g_debbuf->buf) { | ||
959 | kfree(g_cmsg); | ||
960 | kfree(g_debbuf); | ||
961 | return ENOMEM;; | ||
962 | } | ||
963 | g_debbuf->size = CDEBUG_GSIZE; | ||
964 | g_debbuf->buf[0] = 0; | ||
965 | g_debbuf->p = g_debbuf->buf; | ||
966 | g_debbuf->pos = 0; | ||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | void __exit cdebug_exit(void) | ||
971 | { | ||
972 | if (g_debbuf) | ||
973 | kfree(g_debbuf->buf); | ||
974 | kfree(g_debbuf); | ||
975 | kfree(g_cmsg); | ||
976 | } | ||
977 | |||
978 | #else /* !CONFIG_CAPI_TRACE */ | ||
979 | |||
980 | static _cdebbuf g_debbuf = {"CONFIG_CAPI_TRACE not enabled", NULL, 0, 0}; | ||
981 | |||
982 | _cdebbuf *capi_message2str(u8 * msg) | ||
983 | { | ||
984 | return &g_debbuf; | ||
985 | } | ||
986 | |||
987 | _cdebbuf *capi_cmsg2str(_cmsg * cmsg) | ||
988 | { | ||
989 | return &g_debbuf; | ||
990 | } | ||
991 | |||
992 | _cdebbuf *cdebbuf_alloc(void) | ||
993 | { | ||
994 | return &g_debbuf; | ||
995 | } | ||
996 | |||
997 | void cdebbuf_free(_cdebbuf *cdb) | ||
998 | { | ||
999 | } | ||
1000 | |||
1001 | int __init cdebug_init(void) | ||
1002 | { | ||
1003 | return 0; | ||
1004 | } | ||
1005 | |||
1006 | void __exit cdebug_exit(void) | ||
1007 | { | ||
1008 | } | ||
1009 | |||
1010 | #endif | ||
1011 | |||
1012 | EXPORT_SYMBOL(cdebbuf_alloc); | ||
1013 | EXPORT_SYMBOL(cdebbuf_free); | ||
852 | EXPORT_SYMBOL(capi_cmsg2message); | 1014 | EXPORT_SYMBOL(capi_cmsg2message); |
853 | EXPORT_SYMBOL(capi_message2cmsg); | 1015 | EXPORT_SYMBOL(capi_message2cmsg); |
854 | EXPORT_SYMBOL(capi_cmsg_header); | 1016 | EXPORT_SYMBOL(capi_cmsg_header); |
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index 783a25526315..3ed34f7a1c4f 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c | |||
@@ -276,10 +276,17 @@ void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *s | |||
276 | int showctl = 0; | 276 | int showctl = 0; |
277 | u8 cmd, subcmd; | 277 | u8 cmd, subcmd; |
278 | unsigned long flags; | 278 | unsigned long flags; |
279 | _cdebbuf *cdb; | ||
279 | 280 | ||
280 | if (card->cardstate != CARD_RUNNING) { | 281 | if (card->cardstate != CARD_RUNNING) { |
281 | printk(KERN_INFO "kcapi: controller %d not active, got: %s", | 282 | cdb = capi_message2str(skb->data); |
282 | card->cnr, capi_message2str(skb->data)); | 283 | if (cdb) { |
284 | printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s", | ||
285 | card->cnr, cdb->buf); | ||
286 | cdebbuf_free(cdb); | ||
287 | } else | ||
288 | printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n", | ||
289 | card->cnr); | ||
283 | goto error; | 290 | goto error; |
284 | } | 291 | } |
285 | 292 | ||
@@ -295,15 +302,21 @@ void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *s | |||
295 | showctl |= (card->traceflag & 1); | 302 | showctl |= (card->traceflag & 1); |
296 | if (showctl & 2) { | 303 | if (showctl & 2) { |
297 | if (showctl & 1) { | 304 | if (showctl & 1) { |
298 | printk(KERN_DEBUG "kcapi: got [0x%lx] id#%d %s len=%u\n", | 305 | printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n", |
299 | (unsigned long) card->cnr, | 306 | card->cnr, CAPIMSG_APPID(skb->data), |
300 | CAPIMSG_APPID(skb->data), | ||
301 | capi_cmd2str(cmd, subcmd), | 307 | capi_cmd2str(cmd, subcmd), |
302 | CAPIMSG_LEN(skb->data)); | 308 | CAPIMSG_LEN(skb->data)); |
303 | } else { | 309 | } else { |
304 | printk(KERN_DEBUG "kcapi: got [0x%lx] %s\n", | 310 | cdb = capi_message2str(skb->data); |
305 | (unsigned long) card->cnr, | 311 | if (cdb) { |
306 | capi_message2str(skb->data)); | 312 | printk(KERN_DEBUG "kcapi: got [%03d] %s\n", |
313 | card->cnr, cdb->buf); | ||
314 | cdebbuf_free(cdb); | ||
315 | } else | ||
316 | printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n", | ||
317 | card->cnr, CAPIMSG_APPID(skb->data), | ||
318 | capi_cmd2str(cmd, subcmd), | ||
319 | CAPIMSG_LEN(skb->data)); | ||
307 | } | 320 | } |
308 | 321 | ||
309 | } | 322 | } |
@@ -312,8 +325,15 @@ void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *s | |||
312 | ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data)); | 325 | ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data)); |
313 | if ((!ap) || (ap->release_in_progress)) { | 326 | if ((!ap) || (ap->release_in_progress)) { |
314 | read_unlock_irqrestore(&application_lock, flags); | 327 | read_unlock_irqrestore(&application_lock, flags); |
315 | printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n", | 328 | cdb = capi_message2str(skb->data); |
316 | CAPIMSG_APPID(skb->data), capi_message2str(skb->data)); | 329 | if (cdb) { |
330 | printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n", | ||
331 | CAPIMSG_APPID(skb->data), cdb->buf); | ||
332 | cdebbuf_free(cdb); | ||
333 | } else | ||
334 | printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n", | ||
335 | CAPIMSG_APPID(skb->data), | ||
336 | capi_cmd2str(cmd, subcmd)); | ||
317 | goto error; | 337 | goto error; |
318 | } | 338 | } |
319 | skb_queue_tail(&ap->recv_queue, skb); | 339 | skb_queue_tail(&ap->recv_queue, skb); |
@@ -332,7 +352,7 @@ void capi_ctr_ready(struct capi_ctr * card) | |||
332 | { | 352 | { |
333 | card->cardstate = CARD_RUNNING; | 353 | card->cardstate = CARD_RUNNING; |
334 | 354 | ||
335 | printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", | 355 | printk(KERN_NOTICE "kcapi: card [%03d] \"%s\" ready.\n", |
336 | card->cnr, card->name); | 356 | card->cnr, card->name); |
337 | 357 | ||
338 | notify_push(KCI_CONTRUP, card->cnr, 0, 0); | 358 | notify_push(KCI_CONTRUP, card->cnr, 0, 0); |
@@ -364,7 +384,7 @@ void capi_ctr_reseted(struct capi_ctr * card) | |||
364 | capi_ctr_put(card); | 384 | capi_ctr_put(card); |
365 | } | 385 | } |
366 | 386 | ||
367 | printk(KERN_NOTICE "kcapi: card %d down.\n", card->cnr); | 387 | printk(KERN_NOTICE "kcapi: card [%03d] down.\n", card->cnr); |
368 | 388 | ||
369 | notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); | 389 | notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); |
370 | } | 390 | } |
@@ -374,7 +394,7 @@ EXPORT_SYMBOL(capi_ctr_reseted); | |||
374 | void capi_ctr_suspend_output(struct capi_ctr *card) | 394 | void capi_ctr_suspend_output(struct capi_ctr *card) |
375 | { | 395 | { |
376 | if (!card->blocked) { | 396 | if (!card->blocked) { |
377 | printk(KERN_DEBUG "kcapi: card %d suspend\n", card->cnr); | 397 | printk(KERN_DEBUG "kcapi: card [%03d] suspend\n", card->cnr); |
378 | card->blocked = 1; | 398 | card->blocked = 1; |
379 | } | 399 | } |
380 | } | 400 | } |
@@ -384,7 +404,7 @@ EXPORT_SYMBOL(capi_ctr_suspend_output); | |||
384 | void capi_ctr_resume_output(struct capi_ctr *card) | 404 | void capi_ctr_resume_output(struct capi_ctr *card) |
385 | { | 405 | { |
386 | if (card->blocked) { | 406 | if (card->blocked) { |
387 | printk(KERN_DEBUG "kcapi: card %d resume\n", card->cnr); | 407 | printk(KERN_DEBUG "kcapi: card [%03d] resume\n", card->cnr); |
388 | card->blocked = 0; | 408 | card->blocked = 0; |
389 | } | 409 | } |
390 | } | 410 | } |
@@ -432,7 +452,7 @@ attach_capi_ctr(struct capi_ctr *card) | |||
432 | } | 452 | } |
433 | 453 | ||
434 | ncards++; | 454 | ncards++; |
435 | printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n", | 455 | printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n", |
436 | card->cnr, card->name); | 456 | card->cnr, card->name); |
437 | return 0; | 457 | return 0; |
438 | } | 458 | } |
@@ -451,7 +471,7 @@ int detach_capi_ctr(struct capi_ctr *card) | |||
451 | card->procent = NULL; | 471 | card->procent = NULL; |
452 | } | 472 | } |
453 | capi_cards[card->cnr - 1] = NULL; | 473 | capi_cards[card->cnr - 1] = NULL; |
454 | printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n", | 474 | printk(KERN_NOTICE "kcapi: Controller [%03d]: %s unregistered\n", |
455 | card->cnr, card->name); | 475 | card->cnr, card->name); |
456 | 476 | ||
457 | return 0; | 477 | return 0; |
@@ -623,17 +643,25 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb) | |||
623 | showctl |= (card->traceflag & 1); | 643 | showctl |= (card->traceflag & 1); |
624 | if (showctl & 2) { | 644 | if (showctl & 2) { |
625 | if (showctl & 1) { | 645 | if (showctl & 1) { |
626 | printk(KERN_DEBUG "kcapi: put [%#x] id#%d %s len=%u\n", | 646 | printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n", |
627 | CAPIMSG_CONTROLLER(skb->data), | 647 | CAPIMSG_CONTROLLER(skb->data), |
628 | CAPIMSG_APPID(skb->data), | 648 | CAPIMSG_APPID(skb->data), |
629 | capi_cmd2str(cmd, subcmd), | 649 | capi_cmd2str(cmd, subcmd), |
630 | CAPIMSG_LEN(skb->data)); | 650 | CAPIMSG_LEN(skb->data)); |
631 | } else { | 651 | } else { |
632 | printk(KERN_DEBUG "kcapi: put [%#x] %s\n", | 652 | _cdebbuf *cdb = capi_message2str(skb->data); |
633 | CAPIMSG_CONTROLLER(skb->data), | 653 | if (cdb) { |
634 | capi_message2str(skb->data)); | 654 | printk(KERN_DEBUG "kcapi: put [%03d] %s\n", |
655 | CAPIMSG_CONTROLLER(skb->data), | ||
656 | cdb->buf); | ||
657 | cdebbuf_free(cdb); | ||
658 | } else | ||
659 | printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u cannot trace\n", | ||
660 | CAPIMSG_CONTROLLER(skb->data), | ||
661 | CAPIMSG_APPID(skb->data), | ||
662 | capi_cmd2str(cmd, subcmd), | ||
663 | CAPIMSG_LEN(skb->data)); | ||
635 | } | 664 | } |
636 | |||
637 | } | 665 | } |
638 | return card->send_message(card, skb); | 666 | return card->send_message(card, skb); |
639 | } | 667 | } |
@@ -894,7 +922,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data) | |||
894 | return -ESRCH; | 922 | return -ESRCH; |
895 | 923 | ||
896 | card->traceflag = fdef.flag; | 924 | card->traceflag = fdef.flag; |
897 | printk(KERN_INFO "kcapi: contr %d set trace=%d\n", | 925 | printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n", |
898 | card->cnr, card->traceflag); | 926 | card->cnr, card->traceflag); |
899 | return 0; | 927 | return 0; |
900 | } | 928 | } |
@@ -967,7 +995,11 @@ static int __init kcapi_init(void) | |||
967 | { | 995 | { |
968 | char *p; | 996 | char *p; |
969 | char rev[32]; | 997 | char rev[32]; |
998 | int ret; | ||
970 | 999 | ||
1000 | ret = cdebug_init(); | ||
1001 | if (ret) | ||
1002 | return ret; | ||
971 | kcapi_proc_init(); | 1003 | kcapi_proc_init(); |
972 | 1004 | ||
973 | if ((p = strchr(revision, ':')) != 0 && p[1]) { | 1005 | if ((p = strchr(revision, ':')) != 0 && p[1]) { |
@@ -988,6 +1020,7 @@ static void __exit kcapi_exit(void) | |||
988 | 1020 | ||
989 | /* make sure all notifiers are finished */ | 1021 | /* make sure all notifiers are finished */ |
990 | flush_scheduled_work(); | 1022 | flush_scheduled_work(); |
1023 | cdebug_exit(); | ||
991 | } | 1024 | } |
992 | 1025 | ||
993 | module_init(kcapi_init); | 1026 | module_init(kcapi_init); |
diff --git a/include/linux/isdn/capiutil.h b/include/linux/isdn/capiutil.h index 2e79f816703b..63bd9cf821a7 100644 --- a/include/linux/isdn/capiutil.h +++ b/include/linux/isdn/capiutil.h | |||
@@ -174,9 +174,26 @@ char *capi_info2str(__u16 reason); | |||
174 | /* | 174 | /* |
175 | * Debugging / Tracing functions | 175 | * Debugging / Tracing functions |
176 | */ | 176 | */ |
177 | |||
177 | char *capi_cmd2str(__u8 cmd, __u8 subcmd); | 178 | char *capi_cmd2str(__u8 cmd, __u8 subcmd); |
178 | char *capi_cmsg2str(_cmsg * cmsg); | 179 | |
179 | char *capi_message2str(__u8 * msg); | 180 | typedef struct { |
181 | u_char *buf; | ||
182 | u_char *p; | ||
183 | size_t size; | ||
184 | size_t pos; | ||
185 | } _cdebbuf; | ||
186 | |||
187 | #define CDEBUG_SIZE 1024 | ||
188 | #define CDEBUG_GSIZE 4096 | ||
189 | |||
190 | _cdebbuf *cdebbuf_alloc(void); | ||
191 | void cdebbuf_free(_cdebbuf *cdb); | ||
192 | int cdebug_init(void); | ||
193 | void cdebug_exit(void); | ||
194 | |||
195 | _cdebbuf *capi_cmsg2str(_cmsg *cmsg); | ||
196 | _cdebbuf *capi_message2str(__u8 *msg); | ||
180 | 197 | ||
181 | /*-----------------------------------------------------------------------*/ | 198 | /*-----------------------------------------------------------------------*/ |
182 | 199 | ||