aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/mISDN
diff options
context:
space:
mode:
authorKarsten Keil <isdn@linux-pingi.de>2012-05-04 00:15:31 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-04 11:53:59 -0400
commit7ed80fe45d42678fb234bf9d18de6a98cfa9830d (patch)
tree0967e3bf027d4c90c41c7f841d520f978fca82a0 /drivers/isdn/mISDN
parent82107b73eae812d8c089832b14b24ffe20a5c241 (diff)
mISDN: Fix refcounting bug
Under some configs it was still not possible to unload the driver, because the module use count was srewed up. Signed-off-by: Karsten Keil <keil@b1-systems.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn/mISDN')
-rw-r--r--drivers/isdn/mISDN/tei.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index 969766f5f82b..109276a0d1a0 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -790,18 +790,23 @@ tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len)
790static struct layer2 * 790static struct layer2 *
791create_new_tei(struct manager *mgr, int tei, int sapi) 791create_new_tei(struct manager *mgr, int tei, int sapi)
792{ 792{
793 u_long opt = 0; 793 unsigned long opt = 0;
794 u_long flags; 794 unsigned long flags;
795 int id; 795 int id;
796 struct layer2 *l2; 796 struct layer2 *l2;
797 struct channel_req rq;
797 798
798 if (!mgr->up) 799 if (!mgr->up)
799 return NULL; 800 return NULL;
800 if ((tei >= 0) && (tei < 64)) 801 if ((tei >= 0) && (tei < 64))
801 test_and_set_bit(OPTION_L2_FIXEDTEI, &opt); 802 test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
802 if (mgr->ch.st->dev->Dprotocols 803 if (mgr->ch.st->dev->Dprotocols & ((1 << ISDN_P_TE_E1) |
803 & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1))) 804 (1 << ISDN_P_NT_E1))) {
804 test_and_set_bit(OPTION_L2_PMX, &opt); 805 test_and_set_bit(OPTION_L2_PMX, &opt);
806 rq.protocol = ISDN_P_NT_E1;
807 } else {
808 rq.protocol = ISDN_P_NT_S0;
809 }
805 l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi); 810 l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi);
806 if (!l2) { 811 if (!l2) {
807 printk(KERN_WARNING "%s:no memory for layer2\n", __func__); 812 printk(KERN_WARNING "%s:no memory for layer2\n", __func__);
@@ -836,6 +841,14 @@ create_new_tei(struct manager *mgr, int tei, int sapi)
836 l2->ch.recv = mgr->ch.recv; 841 l2->ch.recv = mgr->ch.recv;
837 l2->ch.peer = mgr->ch.peer; 842 l2->ch.peer = mgr->ch.peer;
838 l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL); 843 l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL);
844 /* We need open here L1 for the manager as well (refcounting) */
845 rq.adr.dev = mgr->ch.st->dev->id;
846 id = mgr->ch.st->own.ctrl(&mgr->ch.st->own, OPEN_CHANNEL, &rq);
847 if (id < 0) {
848 printk(KERN_WARNING "%s: cannot open L1\n", __func__);
849 l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
850 l2 = NULL;
851 }
839 } 852 }
840 return l2; 853 return l2;
841} 854}
@@ -978,10 +991,11 @@ TEIrelease(struct layer2 *l2)
978static int 991static int
979create_teimgr(struct manager *mgr, struct channel_req *crq) 992create_teimgr(struct manager *mgr, struct channel_req *crq)
980{ 993{
981 struct layer2 *l2; 994 struct layer2 *l2;
982 u_long opt = 0; 995 unsigned long opt = 0;
983 u_long flags; 996 unsigned long flags;
984 int id; 997 int id;
998 struct channel_req l1rq;
985 999
986 if (*debug & DEBUG_L2_TEI) 1000 if (*debug & DEBUG_L2_TEI)
987 printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n", 1001 printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
@@ -1016,6 +1030,7 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
1016 if (crq->protocol == ISDN_P_LAPD_TE) 1030 if (crq->protocol == ISDN_P_LAPD_TE)
1017 test_and_set_bit(MGR_OPT_USER, &mgr->options); 1031 test_and_set_bit(MGR_OPT_USER, &mgr->options);
1018 } 1032 }
1033 l1rq.adr = crq->adr;
1019 if (mgr->ch.st->dev->Dprotocols 1034 if (mgr->ch.st->dev->Dprotocols
1020 & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1))) 1035 & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
1021 test_and_set_bit(OPTION_L2_PMX, &opt); 1036 test_and_set_bit(OPTION_L2_PMX, &opt);
@@ -1055,24 +1070,34 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
1055 l2->tm->tei_m.fsm = &teifsmu; 1070 l2->tm->tei_m.fsm = &teifsmu;
1056 l2->tm->tei_m.state = ST_TEI_NOP; 1071 l2->tm->tei_m.state = ST_TEI_NOP;
1057 l2->tm->tval = 1000; /* T201 1 sec */ 1072 l2->tm->tval = 1000; /* T201 1 sec */
1073 if (test_bit(OPTION_L2_PMX, &opt))
1074 l1rq.protocol = ISDN_P_TE_E1;
1075 else
1076 l1rq.protocol = ISDN_P_TE_S0;
1058 } else { 1077 } else {
1059 l2->tm->tei_m.fsm = &teifsmn; 1078 l2->tm->tei_m.fsm = &teifsmn;
1060 l2->tm->tei_m.state = ST_TEI_NOP; 1079 l2->tm->tei_m.state = ST_TEI_NOP;
1061 l2->tm->tval = 2000; /* T202 2 sec */ 1080 l2->tm->tval = 2000; /* T202 2 sec */
1081 if (test_bit(OPTION_L2_PMX, &opt))
1082 l1rq.protocol = ISDN_P_NT_E1;
1083 else
1084 l1rq.protocol = ISDN_P_NT_S0;
1062 } 1085 }
1063 mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer); 1086 mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer);
1064 write_lock_irqsave(&mgr->lock, flags); 1087 write_lock_irqsave(&mgr->lock, flags);
1065 id = get_free_id(mgr); 1088 id = get_free_id(mgr);
1066 list_add_tail(&l2->list, &mgr->layer2); 1089 list_add_tail(&l2->list, &mgr->layer2);
1067 write_unlock_irqrestore(&mgr->lock, flags); 1090 write_unlock_irqrestore(&mgr->lock, flags);
1068 if (id < 0) { 1091 if (id >= 0) {
1069 l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
1070 } else {
1071 l2->ch.nr = id; 1092 l2->ch.nr = id;
1072 l2->up->nr = id; 1093 l2->up->nr = id;
1073 crq->ch = &l2->ch; 1094 crq->ch = &l2->ch;
1074 id = 0; 1095 /* We need open here L1 for the manager as well (refcounting) */
1096 id = mgr->ch.st->own.ctrl(&mgr->ch.st->own, OPEN_CHANNEL,
1097 &l1rq);
1075 } 1098 }
1099 if (id < 0)
1100 l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
1076 return id; 1101 return id;
1077} 1102}
1078 1103