aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/capi/kcapi.c
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@web.de>2010-02-08 05:12:12 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-16 19:01:21 -0500
commit3efecf7a49cde47e5f2deb1d5504951ff4bede53 (patch)
tree0080a12e211ea9be33b076f4a824ece6cb3df390 /drivers/isdn/capi/kcapi.c
parent9717fb8b64ed41be9dd074bc8010bafd33046f1a (diff)
CAPI: Rework capi_ctr_ready/down
This step prepares the application of proper controller locking: Push all state changing work into the notify handler that are called by capi_ctr_ready and capi_ctr_down, switch detach_capi_ctr to issue a synchronous ctr_down. Also ensure that we do not go through any action if the state did not change. Signed-off-by: Jan Kiszka <jan.kiszka@web.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn/capi/kcapi.c')
-rw-r--r--drivers/isdn/capi/kcapi.c95
1 files changed, 50 insertions, 45 deletions
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index c46964fc17c7..9362a7a66aa1 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -169,44 +169,74 @@ static void release_appl(struct capi_ctr *ctr, u16 applid)
169 169
170static void notify_up(u32 contr) 170static void notify_up(u32 contr)
171{ 171{
172 struct capi_ctr *ctr = get_capi_ctr_by_nr(contr);
173 struct capi20_appl *ap; 172 struct capi20_appl *ap;
173 struct capi_ctr *ctr;
174 u16 applid; 174 u16 applid;
175 175
176 if (showcapimsgs & 1) { 176 if (showcapimsgs & 1)
177 printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr); 177 printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
178 } 178
179 if (!ctr) { 179 ctr = get_capi_ctr_by_nr(contr);
180 if (ctr) {
181 if (ctr->state == CAPI_CTR_RUNNING)
182 return;
183
184 ctr->state = CAPI_CTR_RUNNING;
185
186 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
187 ap = get_capi_appl_by_nr(applid);
188 if (!ap || ap->release_in_progress)
189 continue;
190 register_appl(ctr, applid, &ap->rparam);
191 if (ap->callback && !ap->release_in_progress)
192 ap->callback(KCI_CONTRUP, contr,
193 &ctr->profile);
194 }
195 } else
180 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr); 196 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
181 return;
182 }
183 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
184 ap = get_capi_appl_by_nr(applid);
185 if (!ap || ap->release_in_progress) continue;
186 register_appl(ctr, applid, &ap->rparam);
187 if (ap->callback && !ap->release_in_progress)
188 ap->callback(KCI_CONTRUP, contr, &ctr->profile);
189 }
190} 197}
191 198
192/* -------- KCI_CONTRDOWN ------------------------------------- */ 199/* -------- KCI_CONTRDOWN ------------------------------------- */
193 200
194static void notify_down(u32 contr) 201static void ctr_down(struct capi_ctr *ctr)
195{ 202{
196 struct capi20_appl *ap; 203 struct capi20_appl *ap;
197 u16 applid; 204 u16 applid;
198 205
199 if (showcapimsgs & 1) { 206 if (ctr->state == CAPI_CTR_DETECTED)
200 printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr); 207 return;
201 } 208
209 ctr->state = CAPI_CTR_DETECTED;
210
211 memset(ctr->manu, 0, sizeof(ctr->manu));
212 memset(&ctr->version, 0, sizeof(ctr->version));
213 memset(&ctr->profile, 0, sizeof(ctr->profile));
214 memset(ctr->serial, 0, sizeof(ctr->serial));
202 215
203 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 216 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
204 ap = get_capi_appl_by_nr(applid); 217 ap = get_capi_appl_by_nr(applid);
205 if (ap && ap->callback && !ap->release_in_progress) 218 if (ap && !ap->release_in_progress) {
206 ap->callback(KCI_CONTRDOWN, contr, NULL); 219 if (ap->callback)
220 ap->callback(KCI_CONTRDOWN, ctr->cnr, NULL);
221 capi_ctr_put(ctr);
222 }
207 } 223 }
208} 224}
209 225
226static void notify_down(u32 contr)
227{
228 struct capi_ctr *ctr;
229
230 if (showcapimsgs & 1)
231 printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
232
233 ctr = get_capi_ctr_by_nr(contr);
234 if (ctr)
235 ctr_down(ctr);
236 else
237 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
238}
239
210static void notify_handler(struct work_struct *work) 240static void notify_handler(struct work_struct *work)
211{ 241{
212 struct capi_notifier *np = 242 struct capi_notifier *np =
@@ -368,8 +398,6 @@ EXPORT_SYMBOL(capi_ctr_handle_message);
368 398
369void capi_ctr_ready(struct capi_ctr *ctr) 399void capi_ctr_ready(struct capi_ctr *ctr)
370{ 400{
371 ctr->state = CAPI_CTR_RUNNING;
372
373 printk(KERN_NOTICE "kcapi: controller [%03d] \"%s\" ready.\n", 401 printk(KERN_NOTICE "kcapi: controller [%03d] \"%s\" ready.\n",
374 ctr->cnr, ctr->name); 402 ctr->cnr, ctr->name);
375 403
@@ -388,28 +416,6 @@ EXPORT_SYMBOL(capi_ctr_ready);
388 416
389void capi_ctr_down(struct capi_ctr *ctr) 417void capi_ctr_down(struct capi_ctr *ctr)
390{ 418{
391 u16 appl;
392
393 DBG("");
394
395 if (ctr->state == CAPI_CTR_DETECTED)
396 return;
397
398 ctr->state = CAPI_CTR_DETECTED;
399
400 memset(ctr->manu, 0, sizeof(ctr->manu));
401 memset(&ctr->version, 0, sizeof(ctr->version));
402 memset(&ctr->profile, 0, sizeof(ctr->profile));
403 memset(ctr->serial, 0, sizeof(ctr->serial));
404
405 for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
406 struct capi20_appl *ap = get_capi_appl_by_nr(appl);
407 if (!ap || ap->release_in_progress)
408 continue;
409
410 capi_ctr_put(ctr);
411 }
412
413 printk(KERN_NOTICE "kcapi: controller [%03d] down.\n", ctr->cnr); 419 printk(KERN_NOTICE "kcapi: controller [%03d] down.\n", ctr->cnr);
414 420
415 notify_push(KCI_CONTRDOWN, ctr->cnr, 0, 0); 421 notify_push(KCI_CONTRDOWN, ctr->cnr, 0, 0);
@@ -513,8 +519,7 @@ EXPORT_SYMBOL(attach_capi_ctr);
513 519
514int detach_capi_ctr(struct capi_ctr *ctr) 520int detach_capi_ctr(struct capi_ctr *ctr)
515{ 521{
516 if (ctr->state != CAPI_CTR_DETECTED) 522 ctr_down(ctr);
517 capi_ctr_down(ctr);
518 523
519 ncontrollers--; 524 ncontrollers--;
520 525