diff options
author | Jan Kiszka <jan.kiszka@web.de> | 2010-02-08 05:12:12 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-16 19:01:21 -0500 |
commit | 3efecf7a49cde47e5f2deb1d5504951ff4bede53 (patch) | |
tree | 0080a12e211ea9be33b076f4a824ece6cb3df390 /drivers/isdn/capi/kcapi.c | |
parent | 9717fb8b64ed41be9dd074bc8010bafd33046f1a (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.c | 95 |
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 | ||
170 | static void notify_up(u32 contr) | 170 | static 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 | ||
194 | static void notify_down(u32 contr) | 201 | static 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 | ||
226 | static 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 | |||
210 | static void notify_handler(struct work_struct *work) | 240 | static 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 | ||
369 | void capi_ctr_ready(struct capi_ctr *ctr) | 399 | void 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 | ||
389 | void capi_ctr_down(struct capi_ctr *ctr) | 417 | void 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 | ||
514 | int detach_capi_ctr(struct capi_ctr *ctr) | 520 | int 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 | ||