aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/capi/capiutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/capi/capiutil.c')
-rw-r--r--drivers/isdn/capi/capiutil.c254
1 files changed, 208 insertions, 46 deletions
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
653static char *pnames[] = 656static char *pnames[] =
@@ -703,44 +706,77 @@ static char *pnames[] =
703}; 706};
704 707
705 708
706static char buf[8192];
707static char *p = NULL;
708 709
709#include <stdarg.h> 710#include <stdarg.h>
710 711
711/*-------------------------------------------------------*/ 712/*-------------------------------------------------------*/
712static void bufprint(char *fmt,...) 713static _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
721static void printstructlen(u8 * m, unsigned len) 752static _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
741static void printstruct(u8 * m) 776static _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
757static void protocol_message_2_pars(_cmsg * cmsg, int level) 794static _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/*-------------------------------------------------------*/
813char *capi_message2str(u8 * msg) 853
854static _cdebbuf *g_debbuf;
855static u_long g_debbuf_lock;
856static _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;
875init:
876 cdb->buf[0] = 0;
877 cdb->p = cdb->buf;
878 cdb->pos = 0;
879 return cdb;
880}
815 881
816 _cmsg cmsg; 882void 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
837char *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
947int __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
970void __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
980static _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
997void cdebbuf_free(_cdebbuf *cdb)
998{
999}
1000
1001int __init cdebug_init(void)
1002{
1003 return 0;
1004}
1005
1006void __exit cdebug_exit(void)
1007{
1008}
1009
1010#endif
1011
1012EXPORT_SYMBOL(cdebbuf_alloc);
1013EXPORT_SYMBOL(cdebbuf_free);
852EXPORT_SYMBOL(capi_cmsg2message); 1014EXPORT_SYMBOL(capi_cmsg2message);
853EXPORT_SYMBOL(capi_message2cmsg); 1015EXPORT_SYMBOL(capi_message2cmsg);
854EXPORT_SYMBOL(capi_cmsg_header); 1016EXPORT_SYMBOL(capi_cmsg_header);