void avmb1_handle_new_ncci(avmb1_card * card, __u16 appl, __u32 ncci, __u32 winsize) { avmb1_ncci *np; if (!VALID_APPLID(appl)) { printk(KERN_ERR "avmb1_handle_new_ncci: illegal appl %d\n", appl); return; } if ((np = (avmb1_ncci *) kmalloc(sizeof(avmb1_ncci), GFP_ATOMIC)) == 0) { printk(KERN_ERR "avmb1_handle_new_ncci: alloc failed ncci 0x%x\n", ncci); return; } if (winsize > CAPI_MAXDATAWINDOW) { printk(KERN_ERR "avmb1_handle_new_ncci: winsize %d too big, set to %d\n", winsize, CAPI_MAXDATAWINDOW); winsize = CAPI_MAXDATAWINDOW; } np->applid = appl; np->ncci = ncci; np->winsize = winsize; mq_init(np); np->next = APPL(appl)->nccilist; APPL(appl)->nccilist = np; printk(KERN_INFO "b1capi: appl %d ncci 0x%x up\n", appl, ncci); }
static __u16 capi_register(capi_register_params * rparam, __u16 * applidp) { int appl; int i; if (rparam->datablklen < 128) return CAPI_LOGBLKSIZETOSMALL; for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { if (APPL_IS_FREE(appl)) break; } if (appl > CAPI_MAXAPPL) return CAPI_TOOMANYAPPLS; APPL_MARK_USED(appl); skb_queue_head_init(&APPL(appl)->recv_queue); APPL(appl)->nncci = 0; memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params)); for (i = 0; i < CAPI_MAXCONTR; i++) { if (cards[i].cardstate != CARD_RUNNING) continue; cards[i].driver->register_appl(&cards[i], appl, &APPL(appl)->rparam); } *applidp = appl; printk(KERN_INFO "kcapi: appl %d up\n", appl); return CAPI_NOERROR; }
static void controllercb_new_ncci(struct capi_ctr * card, __u16 appl, __u32 ncci, __u32 winsize) { struct capi_ncci *np; if (!VALID_APPLID(appl)) { printk(KERN_ERR "avmb1_handle_new_ncci: illegal appl %d\n", appl); return; } if ((np = (struct capi_ncci *) kmalloc(sizeof(struct capi_ncci), GFP_ATOMIC)) == 0) { printk(KERN_ERR "capi_new_ncci: alloc failed ncci 0x%x\n", ncci); return; } if (winsize > CAPI_MAXDATAWINDOW) { printk(KERN_ERR "capi_new_ncci: winsize %d too big, set to %d\n", winsize, CAPI_MAXDATAWINDOW); winsize = CAPI_MAXDATAWINDOW; } np->applid = appl; np->ncci = ncci; np->winsize = winsize; mq_init(np); np->next = APPL(appl)->nccilist; APPL(appl)->nccilist = np; APPL(appl)->nncci++; printk(KERN_INFO "kcapi: appl %d ncci 0x%x up\n", appl, ncci); notify_push(KCI_NCCIUP, CARDNR(card), appl, ncci); }
static __u16 capi_release(__u16 applid) { struct sk_buff *skb; int i; if (ncards == 0) return CAPI_REGNOTINSTALLED; if (!VALID_APPLID(applid) || APPL(applid)->releasing) return CAPI_ILLAPPNR; while ((skb = skb_dequeue(&APPL(applid)->recv_queue)) != 0) kfree_skb(skb); for (i = 0; i < CAPI_MAXCONTR; i++) { if (cards[i].cardstate != CARD_RUNNING) { continue; } APPL(applid)->releasing++; B1_send_release(cards[i].port, applid); } if (APPL(applid)->releasing == 0) { APPL(applid)->signal = 0; APPL_MARK_FREE(applid); printk(KERN_INFO "b1capi: appl %d down\n", applid); } return CAPI_NOERROR; }
void avmb1_card_ready(avmb1_card * card) { __u16 appl; card->cversion.majorversion = 2; card->cversion.minorversion = 0; card->cversion.majormanuversion = (card->version[VER_DRIVER][0] - '0') << 4; card->cversion.majormanuversion |= (card->version[VER_DRIVER][2] - '0'); card->cversion.minormanuversion = (card->version[VER_DRIVER][3] - '0') << 4; card->cversion.minormanuversion |= (card->version[VER_DRIVER][5] - '0') * 10; card->cversion.minormanuversion |= (card->version[VER_DRIVER][6] - '0'); card->cardstate = CARD_RUNNING; for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { if (VALID_APPLID(appl) && !APPL(appl)->releasing) { B1_send_register(card->port, appl, 1024 * (APPL(appl)->rparam.level3cnt+1), APPL(appl)->rparam.level3cnt, APPL(appl)->rparam.datablkcnt, APPL(appl)->rparam.datablklen); } } set_bit(CARDNR(card), ¬ify_up_set); queue_task(&tq_state_notify, &tq_scheduler); printk(KERN_NOTICE "b1capi: card %d ready.\n", CARDNR(card)); }
static __u16 capi_put_message(__u16 applid, struct sk_buff *skb) { struct capi_ncci *np; __u32 contr; int showctl = 0; __u8 cmd, subcmd; if (ncards == 0) return CAPI_REGNOTINSTALLED; if (!VALID_APPLID(applid)) return CAPI_ILLAPPNR; if (skb->len < 12 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; contr = CAPIMSG_CONTROLLER(skb->data); if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) { contr = 1; if (CARD(contr)->cardstate != CARD_RUNNING) return CAPI_REGNOTINSTALLED; } if (CARD(contr)->blocked) return CAPI_SENDQUEUEFULL; cmd = CAPIMSG_COMMAND(skb->data); subcmd = CAPIMSG_SUBCOMMAND(skb->data); if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) { if ((np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0 && mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0) return CAPI_SENDQUEUEFULL; CARD(contr)->nsentdatapkt++; APPL(applid)->nsentdatapkt++; if (CARD(contr)->traceflag > 2) showctl |= 2; } else { CARD(contr)->nsentctlpkt++; APPL(applid)->nsentctlpkt++; if (CARD(contr)->traceflag) showctl |= 2; } showctl |= (CARD(contr)->traceflag & 1); if (showctl & 2) { if (showctl & 1) { printk(KERN_DEBUG "kcapi: put [0x%lx] id#%d %s len=%u\n", (unsigned long) contr, CAPIMSG_APPID(skb->data), capi_cmd2str(cmd, subcmd), CAPIMSG_LEN(skb->data)); } else { printk(KERN_DEBUG "kcapi: put [0x%lx] %s\n", (unsigned long) contr, capi_message2str(skb->data)); } } CARD(contr)->driver->send_message(CARD(contr), skb); return CAPI_NOERROR; }
static __u16 capi_set_signal(__u16 applid, void (*signal) (__u16 applid, void *param), void *param) { if (!VALID_APPLID(applid)) return CAPI_ILLAPPNR; APPL(applid)->signal = signal; APPL(applid)->param = param; return CAPI_NOERROR; }
static __u16 capi_put_message(__u16 applid, struct sk_buff *skb) { avmb1_ncci *np; int contr; if (ncards == 0) return CAPI_REGNOTINSTALLED; if (!VALID_APPLID(applid)) return CAPI_ILLAPPNR; if (skb->len < 12 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; contr = CAPIMSG_CONTROLLER(skb->data); if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) { contr = 1; if (CARD(contr)->cardstate != CARD_RUNNING) return CAPI_REGNOTINSTALLED; } if (CARD(contr)->blocked) return CAPI_SENDQUEUEFULL; if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3 && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_REQ && (np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0 && mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0) return CAPI_SENDQUEUEFULL; B1_send_message(CARD(contr)->port, skb); return CAPI_NOERROR; }
static void controllercb_ready(struct capi_ctr * card) { __u16 appl; card->cardstate = CARD_RUNNING; for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { if (!VALID_APPLID(appl)) continue; if (APPL(appl)->releasing) continue; card->driver->register_appl(card, appl, &APPL(appl)->rparam); } printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", CARDNR(card), card->name); notify_push(KCI_CONTRUP, CARDNR(card), 0, 0); }
static void controllercb_appl_released(struct capi_ctr * card, __u16 appl) { struct capi_ncci **pp, **nextpp; for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) { if (NCCI2CTRL((*pp)->ncci) == card->cnr) { struct capi_ncci *np = *pp; *pp = np->next; printk(KERN_INFO "kcapi: appl %d ncci 0x%x down!\n", appl, np->ncci); kfree(np); APPL(appl)->nncci--; nextpp = pp; } else { nextpp = &(*pp)->next; } } if (APPL(appl)->releasing) { /* only release if the application was marked for release */ printk(KERN_DEBUG "kcapi: appl %d releasing(%d)\n", appl, APPL(appl)->releasing); APPL(appl)->releasing--; if (APPL(appl)->releasing <= 0) { APPL(appl)->signal = 0; APPL_MARK_FREE(appl); printk(KERN_INFO "kcapi: appl %d down\n", appl); } } else printk(KERN_WARNING "kcapi: appl %d card%d released without request\n", appl, card->cnr); }
static void notify_up(__u32 contr) { struct capi_interface_user *p; __u16 appl; for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { if (!VALID_APPLID(appl)) continue; if (APPL(appl)->releasing) continue; CARD(contr)->driver->register_appl(CARD(contr), appl, &APPL(appl)->rparam); } printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr); spin_lock(&capi_users_lock); for (p = capi_users; p; p = p->next) { if (!p->callback) continue; (*p->callback) (KCI_CONTRUP, contr, &CARD(contr)->profile); } spin_unlock(&capi_users_lock); }
static __u16 capi_get_message(__u16 applid, struct sk_buff **msgp) { struct sk_buff *skb; if (!VALID_APPLID(applid)) return CAPI_ILLAPPNR; if ((skb = skb_dequeue(&APPL(applid)->recv_queue)) == 0) return CAPI_RECEIVEQUEUEEMPTY; *msgp = skb; return CAPI_NOERROR; }
static void controllercb_free_ncci(struct capi_ctr * card, __u16 appl, __u32 ncci) { struct capi_ncci **pp; if (!VALID_APPLID(appl)) { printk(KERN_ERR "free_ncci: illegal appl %d\n", appl); return; } for (pp = &APPL(appl)->nccilist; *pp; pp = &(*pp)->next) { if ((*pp)->ncci == ncci) { struct capi_ncci *np = *pp; *pp = np->next; kfree(np); APPL(appl)->nncci--; printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", appl, ncci); notify_push(KCI_NCCIDOWN, CARDNR(card), appl, ncci); return; } } printk(KERN_ERR "free_ncci: ncci 0x%x not found\n", ncci); }
void avmb1_handle_free_ncci(avmb1_card * card, __u16 appl, __u32 ncci) { if (!VALID_APPLID(appl)) { printk(KERN_ERR "avmb1_handle_free_ncci: illegal appl %d\n", appl); return; } if (ncci != 0xffffffff) { avmb1_ncci **pp; for (pp = &APPL(appl)->nccilist; *pp; pp = &(*pp)->next) { if ((*pp)->ncci == ncci) { avmb1_ncci *np = *pp; *pp = np->next; kfree(np); printk(KERN_INFO "b1capi: appl %d ncci 0x%x down\n", appl, ncci); return; } } printk(KERN_ERR "avmb1_handle_free_ncci: ncci 0x%x not found\n", ncci); } else { avmb1_ncci **pp, **nextpp; for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) { if (NCCI2CTRL((*pp)->ncci) == card->cnr) { avmb1_ncci *np = *pp; *pp = np->next; printk(KERN_INFO "b1capi: appl %d ncci 0x%x down!\n", appl, np->ncci); kfree(np); nextpp = pp; } else { nextpp = &(*pp)->next; } } APPL(appl)->releasing--; if (APPL(appl)->releasing == 0) { APPL(appl)->signal = 0; APPL_MARK_FREE(appl); printk(KERN_INFO "b1capi: appl %d down\n", appl); } } }
static __u16 capi_register(capi_register_params * rparam, __u16 * applidp) { int i; int appl; if (rparam->datablklen < 128) return CAPI_LOGBLKSIZETOSMALL; for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { if (APPL_IS_FREE(appl)) break; } if (appl > CAPI_MAXAPPL) return CAPI_TOOMANYAPPLS; APPL_MARK_USED(appl); skb_queue_head_init(&APPL(appl)->recv_queue); memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params)); for (i = 0; i < ncards; i++) { if (cards[i].cardstate != CARD_RUNNING) continue; B1_send_register(cards[i].port, appl, 1024 * (APPL(appl)->rparam.level3cnt + 1), APPL(appl)->rparam.level3cnt, APPL(appl)->rparam.datablkcnt, APPL(appl)->rparam.datablklen); } *applidp = appl; printk(KERN_INFO "b1capi: appl %d up\n", appl); return CAPI_NOERROR; }
static void recv_handler(void *dummy) { struct sk_buff *skb; while ((skb = skb_dequeue(&recv_queue)) != 0) { __u16 appl = CAPIMSG_APPID(skb->data); struct avmb1_ncci *np; if (!VALID_APPLID(appl)) { printk(KERN_ERR "b1capi: recv_handler: applid %d ? (%s)\n", appl, capi_message2str(skb->data)); kfree_skb(skb); continue; } if (APPL(appl)->signal == 0) { printk(KERN_ERR "b1capi: recv_handler: applid %d has no signal function\n", appl); kfree_skb(skb); continue; } if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3 && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF && (np = find_ncci(APPL(appl), CAPIMSG_NCCI(skb->data))) != 0 && mq_dequeue(np, CAPIMSG_MSGID(skb->data)) == 0) { printk(KERN_ERR "b1capi: msgid %hu ncci 0x%x not on queue\n", CAPIMSG_MSGID(skb->data), np->ncci); } skb_queue_tail(&APPL(appl)->recv_queue, skb); (APPL(appl)->signal) (APPL(appl)->applid, APPL(appl)->param); } }
static void controllercb_appl_released(struct capi_ctr * card, __u16 appl) { struct capi_ncci **pp, **nextpp; for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) { if (NCCI2CTRL((*pp)->ncci) == card->cnr) { struct capi_ncci *np = *pp; *pp = np->next; printk(KERN_INFO "kcapi: appl %d ncci 0x%x down!\n", appl, np->ncci); kfree(np); APPL(appl)->nncci--; nextpp = pp; } else { nextpp = &(*pp)->next; } } APPL(appl)->releasing--; if (APPL(appl)->releasing <= 0) { APPL(appl)->signal = 0; APPL_MARK_FREE(appl); printk(KERN_INFO "kcapi: appl %d down\n", appl); } }
static __u16 capi_release(__u16 applid) { int i; if (!VALID_APPLID(applid) || APPL(applid)->releasing) return CAPI_ILLAPPNR; APPL(applid)->releasing++; skb_queue_purge(&APPL(applid)->recv_queue); for (i = 0; i < CAPI_MAXCONTR; i++) { if (cards[i].cardstate != CARD_RUNNING) continue; APPL(applid)->releasing++; cards[i].driver->release_appl(&cards[i], applid); } APPL(applid)->releasing--; if (APPL(applid)->releasing <= 0) { APPL(applid)->signal = 0; APPL_MARK_FREE(applid); printk(KERN_INFO "kcapi: appl %d down\n", applid); } return CAPI_NOERROR; }
static void controllercb_reseted(struct capi_ctr * card) { __u16 appl; if (card->cardstate == CARD_FREE) return; if (card->cardstate == CARD_DETECTED) return; card->cardstate = CARD_DETECTED; memset(card->manu, 0, sizeof(card->manu)); memset(&card->version, 0, sizeof(card->version)); memset(&card->profile, 0, sizeof(card->profile)); memset(card->serial, 0, sizeof(card->serial)); for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { struct capi_ncci **pp, **nextpp; for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) { if (NCCI2CTRL((*pp)->ncci) == card->cnr) { struct capi_ncci *np = *pp; *pp = np->next; printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down!\n", appl, np->ncci); notify_push(KCI_NCCIDOWN, CARDNR(card), appl, np->ncci); kfree(np); nextpp = pp; } else { nextpp = &(*pp)->next; } } } printk(KERN_NOTICE "kcapi: card %d down.\n", CARDNR(card)); notify_push(KCI_CONTRDOWN, CARDNR(card), 0, 0); }
static void avmb1_card_down(avmb1_card * card, int notify) { __u16 appl; card->cardstate = CARD_DETECTED; for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { avmb1_ncci **pp, **nextpp; for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) { if (NCCI2CTRL((*pp)->ncci) == card->cnr) { avmb1_ncci *np = *pp; *pp = np->next; printk(KERN_INFO "b1capi: appl %d ncci 0x%x forced down!\n", appl, np->ncci); kfree(np); nextpp = pp; } else { nextpp = &(*pp)->next; } } } set_bit(CARDNR(card), ¬ify_down_set); queue_task(&tq_state_notify, &tq_scheduler); printk(KERN_NOTICE "b1capi: card %d down.\n", CARDNR(card)); }
static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *), void *arg, size_t size) { ACL_FIBER *fiber; sigset_t zero; union cc_arg carg; ACL_RING *head; fiber_check(); #define APPL ACL_RING_TO_APPL /* try to reuse the fiber memory in dead queue */ head = acl_ring_pop_head(&__thread_fiber->dead); if (head == NULL) { fiber = (ACL_FIBER *) acl_mycalloc(1, sizeof(ACL_FIBER)); fiber->buff = (char *) acl_mymalloc(size); } else if ((fiber = APPL(head, ACL_FIBER, me))->size < size) fiber->buff = (char *) acl_myrealloc(fiber->buff, size); else size = fiber->size; fiber->errnum = 0; fiber->fn = fn; fiber->arg = arg; fiber->size = size; fiber->id = ++__thread_fiber->idgen; fiber->flag = 0; fiber->status = FIBER_STATUS_READY; carg.p = fiber; if (fiber->context == NULL) fiber->context = (ucontext_t *) acl_mymalloc(sizeof(ucontext_t)); sigemptyset(&zero); sigprocmask(SIG_BLOCK, &zero, &fiber->context->uc_sigmask); if (getcontext(fiber->context) < 0) acl_msg_fatal("%s(%d), %s: getcontext error: %s", __FILE__, __LINE__, __FUNCTION__, acl_last_serror()); fiber->context->uc_stack.ss_sp = fiber->buff + 8; fiber->context->uc_stack.ss_size = fiber->size - 64; #ifdef USE_JMP fiber->context->uc_link = NULL; #else fiber->context->uc_link = __thread_fiber->original.context; #endif #ifdef USE_VALGRIND /* avoding the valgrind's warning */ fiber->vid = VALGRIND_STACK_REGISTER(fiber->context->uc_stack.ss_sp, fiber->context->uc_stack.ss_sp + fiber->context->uc_stack.ss_size); #endif makecontext(fiber->context, (void(*)(void)) fiber_start, 2, carg.i[0], carg.i[1]); return fiber; }
void avmb1_card_ready(avmb1_card * card) { struct capi_profile *profp = (struct capi_profile *)card->version[VER_PROFILE]; char *dversion = card->version[VER_DRIVER]; __u16 appl; char *cardname, cname[20]; __u32 flag; card->cversion.majorversion = 2; card->cversion.minorversion = 0; card->cversion.majormanuversion = (((dversion[0] - '0') & 0xf) << 4); card->cversion.majormanuversion |= ((dversion[2] - '0') & 0xf); card->cversion.minormanuversion = (dversion[3] - '0') << 4; card->cversion.minormanuversion |= (dversion[5] - '0') * 10 + ((dversion[6] - '0') & 0xf); card->cardstate = CARD_RUNNING; for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { if (VALID_APPLID(appl) && !APPL(appl)->releasing) { B1_send_register(card->port, appl, 1024 * (APPL(appl)->rparam.level3cnt+1), APPL(appl)->rparam.level3cnt, APPL(appl)->rparam.datablkcnt, APPL(appl)->rparam.datablklen); } } set_bit(CARDNR(card), ¬ify_up_set); queue_task(&tq_state_notify, &tq_scheduler); flag = ((__u8 *)(profp->manu))[1]; switch (flag) { case 0: cardname = cardtype2str(card->cardtype); break; case 3: cardname = "PCMCIA B"; break; case 4: cardname = "PCMCIA M1"; break; case 5: cardname = "PCMCIA M2"; break; case 6: cardname = "B1 V3.0"; break; case 7: cardname = "B1 PCI"; break; default: cardname = cname; break; sprintf(cname, "AVM?%u", (unsigned int)flag); break; } printk(KERN_NOTICE "b1capi: card %d \"%s\" ready.\n", CARDNR(card), cardname); flag = ((__u8 *)(profp->manu))[3]; if (flag) printk(KERN_NOTICE "b1capi: card %d Protocol:%s%s%s%s%s%s%s\n", CARDNR(card), (flag & 0x01) ? " DSS1" : "", (flag & 0x02) ? " CT1" : "", (flag & 0x04) ? " VN3" : "", (flag & 0x08) ? " NI1" : "", (flag & 0x10) ? " AUSTEL" : "", (flag & 0x20) ? " ESS" : "", (flag & 0x40) ? " 1TR6" : "" ); flag = ((__u8 *)(profp->manu))[5]; if (flag) printk(KERN_NOTICE "b1capi: card %d Linetype:%s%s%s%s\n", CARDNR(card), (flag & 0x01) ? " point to point" : "", (flag & 0x02) ? " point to multipoint" : "", (flag & 0x08) ? " leased line without D-channel" : "", (flag & 0x04) ? " leased line with D-channel" : "" ); }