示例#1
0
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);

}
示例#2
0
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;
}
示例#3
0
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);
}
示例#4
0
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;
}
示例#5
0
文件: b1capi.c 项目: rohsaini/mkunity
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), &notify_up_set);
        queue_task(&tq_state_notify, &tq_scheduler);
        printk(KERN_NOTICE "b1capi: card %d ready.\n", CARDNR(card));
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
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;
}
示例#9
0
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);
}
示例#10
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);
}
示例#11
0
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);
}
示例#12
0
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;
}
示例#13
0
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);
}
示例#14
0
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);
		}
	}
}
示例#15
0
文件: b1capi.c 项目: rohsaini/mkunity
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;
}
示例#16
0
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);
	}
}
示例#17
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;
		}
	}
	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);
	}
}
示例#18
0
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;
}
示例#19
0
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);
}
示例#20
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), &notify_down_set);
	queue_task(&tq_state_notify, &tq_scheduler);
	printk(KERN_NOTICE "b1capi: card %d down.\n", CARDNR(card));
}
示例#21
0
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;
}
示例#22
0
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), &notify_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" : ""
			);
}