aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorTilman Schmidt <tilman@imap.cc>2009-10-06 08:18:10 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-07 01:20:53 -0400
commite48470217d1822e3566b657002c6f79bd7a77345 (patch)
tree200e267a4149e63806afda52809590a7bacf34b7 /drivers/isdn
parent812d73473af23dd738afa83ab77cd6c733b3721f (diff)
isdn: avoid races in capidrv
In several places, capidrv sends a CAPI message to the ISDN device and then updates its internal state accordingly. If the response message from the device arrives before the state is updated, it may be rejected or processed incorrectly. Avoid these races by updating the state before emitting the message. Impact: bugfix Signed-off-by: Tilman Schmidt <tilman@imap.cc> Acked-by: Karsten Keil <keil@b1-systems.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/capi/capidrv.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 650120261abf..4921eae71acb 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -671,8 +671,8 @@ static void n0(capidrv_contr * card, capidrv_ncci * ncci)
671 NULL, /* Useruserdata */ /* $$$$ */ 671 NULL, /* Useruserdata */ /* $$$$ */
672 NULL /* Facilitydataarray */ 672 NULL /* Facilitydataarray */
673 ); 673 );
674 send_message(card, &cmsg);
675 plci_change_state(card, ncci->plcip, EV_PLCI_DISCONNECT_REQ); 674 plci_change_state(card, ncci->plcip, EV_PLCI_DISCONNECT_REQ);
675 send_message(card, &cmsg);
676 676
677 cmd.command = ISDN_STAT_BHUP; 677 cmd.command = ISDN_STAT_BHUP;
678 cmd.driver = card->myid; 678 cmd.driver = card->myid;
@@ -924,8 +924,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
924 */ 924 */
925 capi_cmsg_answer(cmsg); 925 capi_cmsg_answer(cmsg);
926 cmsg->Reject = 1; /* ignore */ 926 cmsg->Reject = 1; /* ignore */
927 send_message(card, cmsg);
928 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT); 927 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
928 send_message(card, cmsg);
929 printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s ignored\n", 929 printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s ignored\n",
930 card->contrnr, 930 card->contrnr,
931 cmd.parm.setup.phone, 931 cmd.parm.setup.phone,
@@ -974,8 +974,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
974 case 2: /* Call will be rejected. */ 974 case 2: /* Call will be rejected. */
975 capi_cmsg_answer(cmsg); 975 capi_cmsg_answer(cmsg);
976 cmsg->Reject = 2; /* reject call, normal call clearing */ 976 cmsg->Reject = 2; /* reject call, normal call clearing */
977 send_message(card, cmsg);
978 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT); 977 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
978 send_message(card, cmsg);
979 break; 979 break;
980 980
981 default: 981 default:
@@ -983,8 +983,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
983 capi_cmsg_answer(cmsg); 983 capi_cmsg_answer(cmsg);
984 cmsg->Reject = 8; /* reject call, 984 cmsg->Reject = 8; /* reject call,
985 destination out of order */ 985 destination out of order */
986 send_message(card, cmsg);
987 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT); 986 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
987 send_message(card, cmsg);
988 break; 988 break;
989 } 989 }
990 return; 990 return;
@@ -1020,8 +1020,8 @@ static void handle_plci(_cmsg * cmsg)
1020 card->bchans[plcip->chan].disconnecting = 1; 1020 card->bchans[plcip->chan].disconnecting = 1;
1021 plci_change_state(card, plcip, EV_PLCI_DISCONNECT_IND); 1021 plci_change_state(card, plcip, EV_PLCI_DISCONNECT_IND);
1022 capi_cmsg_answer(cmsg); 1022 capi_cmsg_answer(cmsg);
1023 send_message(card, cmsg);
1024 plci_change_state(card, plcip, EV_PLCI_DISCONNECT_RESP); 1023 plci_change_state(card, plcip, EV_PLCI_DISCONNECT_RESP);
1024 send_message(card, cmsg);
1025 break; 1025 break;
1026 1026
1027 case CAPI_DISCONNECT_CONF: /* plci */ 1027 case CAPI_DISCONNECT_CONF: /* plci */
@@ -1078,8 +1078,8 @@ static void handle_plci(_cmsg * cmsg)
1078 1078
1079 if (card->bchans[plcip->chan].incoming) { 1079 if (card->bchans[plcip->chan].incoming) {
1080 capi_cmsg_answer(cmsg); 1080 capi_cmsg_answer(cmsg);
1081 send_message(card, cmsg);
1082 plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND); 1081 plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND);
1082 send_message(card, cmsg);
1083 } else { 1083 } else {
1084 capidrv_ncci *nccip; 1084 capidrv_ncci *nccip;
1085 capi_cmsg_answer(cmsg); 1085 capi_cmsg_answer(cmsg);
@@ -1098,13 +1098,14 @@ static void handle_plci(_cmsg * cmsg)
1098 NULL /* NCPI */ 1098 NULL /* NCPI */
1099 ); 1099 );
1100 nccip->msgid = cmsg->Messagenumber; 1100 nccip->msgid = cmsg->Messagenumber;
1101 plci_change_state(card, plcip,
1102 EV_PLCI_CONNECT_ACTIVE_IND);
1103 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ);
1101 send_message(card, cmsg); 1104 send_message(card, cmsg);
1102 cmd.command = ISDN_STAT_DCONN; 1105 cmd.command = ISDN_STAT_DCONN;
1103 cmd.driver = card->myid; 1106 cmd.driver = card->myid;
1104 cmd.arg = plcip->chan; 1107 cmd.arg = plcip->chan;
1105 card->interface.statcallb(&cmd); 1108 card->interface.statcallb(&cmd);
1106 plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND);
1107 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ);
1108 } 1109 }
1109 break; 1110 break;
1110 1111
@@ -1193,8 +1194,8 @@ static void handle_ncci(_cmsg * cmsg)
1193 goto notfound; 1194 goto notfound;
1194 1195
1195 capi_cmsg_answer(cmsg); 1196 capi_cmsg_answer(cmsg);
1196 send_message(card, cmsg);
1197 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_ACTIVE_IND); 1197 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_ACTIVE_IND);
1198 send_message(card, cmsg);
1198 1199
1199 cmd.command = ISDN_STAT_BCONN; 1200 cmd.command = ISDN_STAT_BCONN;
1200 cmd.driver = card->myid; 1201 cmd.driver = card->myid;
@@ -1222,8 +1223,8 @@ static void handle_ncci(_cmsg * cmsg)
1222 0, /* Reject */ 1223 0, /* Reject */
1223 NULL /* NCPI */ 1224 NULL /* NCPI */
1224 ); 1225 );
1225 send_message(card, cmsg);
1226 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_RESP); 1226 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_RESP);
1227 send_message(card, cmsg);
1227 break; 1228 break;
1228 } 1229 }
1229 printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n", card->contrnr); 1230 printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n", card->contrnr);
@@ -1299,8 +1300,8 @@ static void handle_ncci(_cmsg * cmsg)
1299 card->bchans[nccip->chan].disconnecting = 1; 1300 card->bchans[nccip->chan].disconnecting = 1;
1300 ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_IND); 1301 ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_IND);
1301 capi_cmsg_answer(cmsg); 1302 capi_cmsg_answer(cmsg);
1302 send_message(card, cmsg);
1303 ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_RESP); 1303 ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_RESP);
1304 send_message(card, cmsg);
1304 break; 1305 break;
1305 1306
1306 case CAPI_DISCONNECT_B3_CONF: /* ncci */ 1307 case CAPI_DISCONNECT_B3_CONF: /* ncci */
@@ -2014,8 +2015,8 @@ static void send_listen(capidrv_contr *card)
2014 card->cipmask, 2015 card->cipmask,
2015 card->cipmask2, 2016 card->cipmask2,
2016 NULL, NULL); 2017 NULL, NULL);
2017 send_message(card, &cmdcmsg);
2018 listen_change_state(card, EV_LISTEN_REQ); 2018 listen_change_state(card, EV_LISTEN_REQ);
2019 send_message(card, &cmdcmsg);
2019} 2020}
2020 2021
2021static void listentimerfunc(unsigned long x) 2022static void listentimerfunc(unsigned long x)