diff options
Diffstat (limited to 'drivers/isdn/hisax/config.c')
-rw-r--r-- | drivers/isdn/hisax/config.c | 233 |
1 files changed, 140 insertions, 93 deletions
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index a43162c2ef1..5f7907e5709 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c | |||
@@ -847,95 +847,10 @@ static int init_card(struct IsdnCardState *cs) | |||
847 | return 3; | 847 | return 3; |
848 | } | 848 | } |
849 | 849 | ||
850 | static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockowner) | 850 | static int hisax_cs_setup_card(struct IsdnCard *card) |
851 | { | 851 | { |
852 | int ret = 0; | 852 | int ret; |
853 | struct IsdnCard *card = cards + cardnr; | ||
854 | struct IsdnCardState *cs; | ||
855 | 853 | ||
856 | cs = kzalloc(sizeof(struct IsdnCardState), GFP_ATOMIC); | ||
857 | if (!cs) { | ||
858 | printk(KERN_WARNING | ||
859 | "HiSax: No memory for IsdnCardState(card %d)\n", | ||
860 | cardnr + 1); | ||
861 | goto out; | ||
862 | } | ||
863 | card->cs = cs; | ||
864 | spin_lock_init(&cs->statlock); | ||
865 | spin_lock_init(&cs->lock); | ||
866 | cs->chanlimit = 2; /* maximum B-channel number */ | ||
867 | cs->logecho = 0; /* No echo logging */ | ||
868 | cs->cardnr = cardnr; | ||
869 | cs->debug = L1_DEB_WARN; | ||
870 | cs->HW_Flags = 0; | ||
871 | cs->busy_flag = busy_flag; | ||
872 | cs->irq_flags = I4L_IRQ_FLAG; | ||
873 | #if TEI_PER_CARD | ||
874 | if (card->protocol == ISDN_PTYPE_NI1) | ||
875 | test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); | ||
876 | #else | ||
877 | test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); | ||
878 | #endif | ||
879 | cs->protocol = card->protocol; | ||
880 | |||
881 | if (card->typ <= 0 || card->typ > ISDN_CTYPE_COUNT) { | ||
882 | printk(KERN_WARNING | ||
883 | "HiSax: Card Type %d out of range\n", card->typ); | ||
884 | goto outf_cs; | ||
885 | } | ||
886 | if (!(cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC))) { | ||
887 | printk(KERN_WARNING | ||
888 | "HiSax: No memory for dlog(card %d)\n", cardnr + 1); | ||
889 | goto outf_cs; | ||
890 | } | ||
891 | if (!(cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) { | ||
892 | printk(KERN_WARNING | ||
893 | "HiSax: No memory for status_buf(card %d)\n", | ||
894 | cardnr + 1); | ||
895 | goto outf_dlog; | ||
896 | } | ||
897 | cs->stlist = NULL; | ||
898 | cs->status_read = cs->status_buf; | ||
899 | cs->status_write = cs->status_buf; | ||
900 | cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1; | ||
901 | cs->typ = card->typ; | ||
902 | #ifdef MODULE | ||
903 | cs->iif.owner = lockowner; | ||
904 | #endif | ||
905 | strcpy(cs->iif.id, id); | ||
906 | cs->iif.channels = 2; | ||
907 | cs->iif.maxbufsize = MAX_DATA_SIZE; | ||
908 | cs->iif.hl_hdrlen = MAX_HEADER_LEN; | ||
909 | cs->iif.features = | ||
910 | ISDN_FEATURE_L2_X75I | | ||
911 | ISDN_FEATURE_L2_HDLC | | ||
912 | ISDN_FEATURE_L2_HDLC_56K | | ||
913 | ISDN_FEATURE_L2_TRANS | | ||
914 | ISDN_FEATURE_L3_TRANS | | ||
915 | #ifdef CONFIG_HISAX_1TR6 | ||
916 | ISDN_FEATURE_P_1TR6 | | ||
917 | #endif | ||
918 | #ifdef CONFIG_HISAX_EURO | ||
919 | ISDN_FEATURE_P_EURO | | ||
920 | #endif | ||
921 | #ifdef CONFIG_HISAX_NI1 | ||
922 | ISDN_FEATURE_P_NI1 | | ||
923 | #endif | ||
924 | 0; | ||
925 | |||
926 | cs->iif.command = HiSax_command; | ||
927 | cs->iif.writecmd = NULL; | ||
928 | cs->iif.writebuf_skb = HiSax_writebuf_skb; | ||
929 | cs->iif.readstat = HiSax_readstatus; | ||
930 | register_isdn(&cs->iif); | ||
931 | cs->myid = cs->iif.channels; | ||
932 | printk(KERN_INFO | ||
933 | "HiSax: Card %d Protocol %s Id=%s (%d)\n", cardnr + 1, | ||
934 | (card->protocol == ISDN_PTYPE_1TR6) ? "1TR6" : | ||
935 | (card->protocol == ISDN_PTYPE_EURO) ? "EDSS1" : | ||
936 | (card->protocol == ISDN_PTYPE_LEASED) ? "LEASED" : | ||
937 | (card->protocol == ISDN_PTYPE_NI1) ? "NI1" : | ||
938 | "NONE", cs->iif.id, cs->myid); | ||
939 | switch (card->typ) { | 854 | switch (card->typ) { |
940 | #if CARD_TELES0 | 855 | #if CARD_TELES0 |
941 | case ISDN_CTYPE_16_0: | 856 | case ISDN_CTYPE_16_0: |
@@ -1094,13 +1009,115 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow | |||
1094 | printk(KERN_WARNING | 1009 | printk(KERN_WARNING |
1095 | "HiSax: Support for %s Card not selected\n", | 1010 | "HiSax: Support for %s Card not selected\n", |
1096 | CardType[card->typ]); | 1011 | CardType[card->typ]); |
1097 | ll_unload(cs); | 1012 | ret = 0; |
1013 | break; | ||
1014 | } | ||
1015 | |||
1016 | return ret; | ||
1017 | } | ||
1018 | |||
1019 | static int hisax_cs_new(int cardnr, char *id, struct IsdnCard *card, | ||
1020 | struct IsdnCardState **cs_out, int *busy_flag, | ||
1021 | struct module *lockowner) | ||
1022 | { | ||
1023 | struct IsdnCardState *cs; | ||
1024 | |||
1025 | *cs_out = NULL; | ||
1026 | |||
1027 | cs = kzalloc(sizeof(struct IsdnCardState), GFP_ATOMIC); | ||
1028 | if (!cs) { | ||
1029 | printk(KERN_WARNING | ||
1030 | "HiSax: No memory for IsdnCardState(card %d)\n", | ||
1031 | cardnr + 1); | ||
1032 | goto out; | ||
1033 | } | ||
1034 | card->cs = cs; | ||
1035 | spin_lock_init(&cs->statlock); | ||
1036 | spin_lock_init(&cs->lock); | ||
1037 | cs->chanlimit = 2; /* maximum B-channel number */ | ||
1038 | cs->logecho = 0; /* No echo logging */ | ||
1039 | cs->cardnr = cardnr; | ||
1040 | cs->debug = L1_DEB_WARN; | ||
1041 | cs->HW_Flags = 0; | ||
1042 | cs->busy_flag = busy_flag; | ||
1043 | cs->irq_flags = I4L_IRQ_FLAG; | ||
1044 | #if TEI_PER_CARD | ||
1045 | if (card->protocol == ISDN_PTYPE_NI1) | ||
1046 | test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); | ||
1047 | #else | ||
1048 | test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); | ||
1049 | #endif | ||
1050 | cs->protocol = card->protocol; | ||
1051 | |||
1052 | if (card->typ <= 0 || card->typ > ISDN_CTYPE_COUNT) { | ||
1053 | printk(KERN_WARNING | ||
1054 | "HiSax: Card Type %d out of range\n", card->typ); | ||
1098 | goto outf_cs; | 1055 | goto outf_cs; |
1099 | } | 1056 | } |
1100 | if (!ret) { | 1057 | if (!(cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC))) { |
1101 | ll_unload(cs); | 1058 | printk(KERN_WARNING |
1059 | "HiSax: No memory for dlog(card %d)\n", cardnr + 1); | ||
1102 | goto outf_cs; | 1060 | goto outf_cs; |
1103 | } | 1061 | } |
1062 | if (!(cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) { | ||
1063 | printk(KERN_WARNING | ||
1064 | "HiSax: No memory for status_buf(card %d)\n", | ||
1065 | cardnr + 1); | ||
1066 | goto outf_dlog; | ||
1067 | } | ||
1068 | cs->stlist = NULL; | ||
1069 | cs->status_read = cs->status_buf; | ||
1070 | cs->status_write = cs->status_buf; | ||
1071 | cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1; | ||
1072 | cs->typ = card->typ; | ||
1073 | #ifdef MODULE | ||
1074 | cs->iif.owner = lockowner; | ||
1075 | #endif | ||
1076 | strcpy(cs->iif.id, id); | ||
1077 | cs->iif.channels = 2; | ||
1078 | cs->iif.maxbufsize = MAX_DATA_SIZE; | ||
1079 | cs->iif.hl_hdrlen = MAX_HEADER_LEN; | ||
1080 | cs->iif.features = | ||
1081 | ISDN_FEATURE_L2_X75I | | ||
1082 | ISDN_FEATURE_L2_HDLC | | ||
1083 | ISDN_FEATURE_L2_HDLC_56K | | ||
1084 | ISDN_FEATURE_L2_TRANS | | ||
1085 | ISDN_FEATURE_L3_TRANS | | ||
1086 | #ifdef CONFIG_HISAX_1TR6 | ||
1087 | ISDN_FEATURE_P_1TR6 | | ||
1088 | #endif | ||
1089 | #ifdef CONFIG_HISAX_EURO | ||
1090 | ISDN_FEATURE_P_EURO | | ||
1091 | #endif | ||
1092 | #ifdef CONFIG_HISAX_NI1 | ||
1093 | ISDN_FEATURE_P_NI1 | | ||
1094 | #endif | ||
1095 | 0; | ||
1096 | |||
1097 | cs->iif.command = HiSax_command; | ||
1098 | cs->iif.writecmd = NULL; | ||
1099 | cs->iif.writebuf_skb = HiSax_writebuf_skb; | ||
1100 | cs->iif.readstat = HiSax_readstatus; | ||
1101 | register_isdn(&cs->iif); | ||
1102 | cs->myid = cs->iif.channels; | ||
1103 | |||
1104 | *cs_out = cs; | ||
1105 | return 1; /* success */ | ||
1106 | |||
1107 | outf_dlog: | ||
1108 | kfree(cs->dlog); | ||
1109 | outf_cs: | ||
1110 | kfree(cs); | ||
1111 | card->cs = NULL; | ||
1112 | out: | ||
1113 | return 0; /* error */ | ||
1114 | } | ||
1115 | |||
1116 | static int hisax_cs_setup(int cardnr, struct IsdnCard *card, | ||
1117 | struct IsdnCardState *cs) | ||
1118 | { | ||
1119 | int ret; | ||
1120 | |||
1104 | if (!(cs->rcvbuf = kmalloc(MAX_DFRAME_LEN_L1, GFP_ATOMIC))) { | 1121 | if (!(cs->rcvbuf = kmalloc(MAX_DFRAME_LEN_L1, GFP_ATOMIC))) { |
1105 | printk(KERN_WARNING "HiSax: No memory for isac rcvbuf\n"); | 1122 | printk(KERN_WARNING "HiSax: No memory for isac rcvbuf\n"); |
1106 | ll_unload(cs); | 1123 | ll_unload(cs); |
@@ -1143,11 +1160,41 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow | |||
1143 | if (!test_bit(HW_ISAR, &cs->HW_Flags)) | 1160 | if (!test_bit(HW_ISAR, &cs->HW_Flags)) |
1144 | ll_run(cs, 0); | 1161 | ll_run(cs, 0); |
1145 | 1162 | ||
1146 | ret = 1; | 1163 | return 1; |
1164 | |||
1165 | outf_cs: | ||
1166 | kfree(cs); | ||
1167 | card->cs = NULL; | ||
1168 | return ret; | ||
1169 | } | ||
1170 | |||
1171 | static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockowner) | ||
1172 | { | ||
1173 | int ret; | ||
1174 | struct IsdnCard *card = cards + cardnr; | ||
1175 | struct IsdnCardState *cs; | ||
1176 | |||
1177 | ret = hisax_cs_new(cardnr, id, card, &cs, busy_flag, lockowner); | ||
1178 | if (!ret) | ||
1179 | return 0; | ||
1180 | |||
1181 | printk(KERN_INFO | ||
1182 | "HiSax: Card %d Protocol %s Id=%s (%d)\n", cardnr + 1, | ||
1183 | (card->protocol == ISDN_PTYPE_1TR6) ? "1TR6" : | ||
1184 | (card->protocol == ISDN_PTYPE_EURO) ? "EDSS1" : | ||
1185 | (card->protocol == ISDN_PTYPE_LEASED) ? "LEASED" : | ||
1186 | (card->protocol == ISDN_PTYPE_NI1) ? "NI1" : | ||
1187 | "NONE", cs->iif.id, cs->myid); | ||
1188 | |||
1189 | ret = hisax_cs_setup_card(card); | ||
1190 | if (!ret) { | ||
1191 | ll_unload(cs); | ||
1192 | goto outf_cs; | ||
1193 | } | ||
1194 | |||
1195 | ret = hisax_cs_setup(cardnr, card, cs); | ||
1147 | goto out; | 1196 | goto out; |
1148 | 1197 | ||
1149 | outf_dlog: | ||
1150 | kfree(cs->dlog); | ||
1151 | outf_cs: | 1198 | outf_cs: |
1152 | kfree(cs); | 1199 | kfree(cs); |
1153 | card->cs = NULL; | 1200 | card->cs = NULL; |