File: /usr/src/linux/drivers/isdn/act2000/capi.c

1     /* $Id: capi.c,v 1.9.6.1 2001/02/16 16:43:23 kai Exp $
2      *
3      * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
4      *        CAPI encoder/decoder
5      *
6      * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
7      * Thanks to Friedemann Baitinger and IBM Germany
8      *
9      * This program is free software; you can redistribute it and/or modify
10      * it under the terms of the GNU General Public License as published by
11      * the Free Software Foundation; either version 2, or (at your option)
12      * any later version.
13      *
14      * This program is distributed in the hope that it will be useful,
15      * but WITHOUT ANY WARRANTY; without even the implied warranty of
16      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17      * GNU General Public License for more details.
18      *
19      * You should have received a copy of the GNU General Public License
20      * along with this program; if not, write to the Free Software
21      * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
22      *
23      */
24     
25     #define __NO_VERSION__
26     #include "act2000.h"
27     #include "capi.h"
28     
29     static actcapi_msgdsc valid_msg[] = {
30     	{{ 0x86, 0x02}, "DATA_B3_IND"},       /* DATA_B3_IND/CONF must be first because of speed!!! */
31     	{{ 0x86, 0x01}, "DATA_B3_CONF"},
32     	{{ 0x02, 0x01}, "CONNECT_CONF"},
33     	{{ 0x02, 0x02}, "CONNECT_IND"},
34     	{{ 0x09, 0x01}, "CONNECT_INFO_CONF"},
35     	{{ 0x03, 0x02}, "CONNECT_ACTIVE_IND"},
36     	{{ 0x04, 0x01}, "DISCONNECT_CONF"},
37     	{{ 0x04, 0x02}, "DISCONNECT_IND"},
38     	{{ 0x05, 0x01}, "LISTEN_CONF"},
39     	{{ 0x06, 0x01}, "GET_PARAMS_CONF"},
40     	{{ 0x07, 0x01}, "INFO_CONF"},
41     	{{ 0x07, 0x02}, "INFO_IND"},
42     	{{ 0x08, 0x01}, "DATA_CONF"},
43     	{{ 0x08, 0x02}, "DATA_IND"},
44     	{{ 0x40, 0x01}, "SELECT_B2_PROTOCOL_CONF"},
45     	{{ 0x80, 0x01}, "SELECT_B3_PROTOCOL_CONF"},
46     	{{ 0x81, 0x01}, "LISTEN_B3_CONF"},
47     	{{ 0x82, 0x01}, "CONNECT_B3_CONF"},
48     	{{ 0x82, 0x02}, "CONNECT_B3_IND"},
49     	{{ 0x83, 0x02}, "CONNECT_B3_ACTIVE_IND"},
50     	{{ 0x84, 0x01}, "DISCONNECT_B3_CONF"},
51     	{{ 0x84, 0x02}, "DISCONNECT_B3_IND"},
52     	{{ 0x85, 0x01}, "GET_B3_PARAMS_CONF"},
53     	{{ 0x01, 0x01}, "RESET_B3_CONF"},
54     	{{ 0x01, 0x02}, "RESET_B3_IND"},
55     	/* {{ 0x87, 0x02, "HANDSET_IND"}, not implemented */
56     	{{ 0xff, 0x01}, "MANUFACTURER_CONF"},
57     	{{ 0xff, 0x02}, "MANUFACTURER_IND"},
58     #ifdef DEBUG_MSG
59     	/* Requests */
60     	{{ 0x01, 0x00}, "RESET_B3_REQ"},
61     	{{ 0x02, 0x00}, "CONNECT_REQ"},
62     	{{ 0x04, 0x00}, "DISCONNECT_REQ"},
63     	{{ 0x05, 0x00}, "LISTEN_REQ"},
64     	{{ 0x06, 0x00}, "GET_PARAMS_REQ"},
65     	{{ 0x07, 0x00}, "INFO_REQ"},
66     	{{ 0x08, 0x00}, "DATA_REQ"},
67     	{{ 0x09, 0x00}, "CONNECT_INFO_REQ"},
68     	{{ 0x40, 0x00}, "SELECT_B2_PROTOCOL_REQ"},
69     	{{ 0x80, 0x00}, "SELECT_B3_PROTOCOL_REQ"},
70     	{{ 0x81, 0x00}, "LISTEN_B3_REQ"},
71     	{{ 0x82, 0x00}, "CONNECT_B3_REQ"},
72     	{{ 0x84, 0x00}, "DISCONNECT_B3_REQ"},
73     	{{ 0x85, 0x00}, "GET_B3_PARAMS_REQ"},
74     	{{ 0x86, 0x00}, "DATA_B3_REQ"},
75     	{{ 0xff, 0x00}, "MANUFACTURER_REQ"},
76     	/* Responses */
77     	{{ 0x01, 0x03}, "RESET_B3_RESP"},	
78     	{{ 0x02, 0x03}, "CONNECT_RESP"},	
79     	{{ 0x03, 0x03}, "CONNECT_ACTIVE_RESP"},	
80     	{{ 0x04, 0x03}, "DISCONNECT_RESP"},	
81     	{{ 0x07, 0x03}, "INFO_RESP"},	
82     	{{ 0x08, 0x03}, "DATA_RESP"},	
83     	{{ 0x82, 0x03}, "CONNECT_B3_RESP"},	
84     	{{ 0x83, 0x03}, "CONNECT_B3_ACTIVE_RESP"},	
85     	{{ 0x84, 0x03}, "DISCONNECT_B3_RESP"},
86     	{{ 0x86, 0x03}, "DATA_B3_RESP"},
87     	{{ 0xff, 0x03}, "MANUFACTURER_RESP"},
88     #endif
89     	{{ 0x00, 0x00}, NULL},
90     };
91     #define num_valid_msg (sizeof(valid_msg)/sizeof(actcapi_msgdsc))
92     #define num_valid_imsg 27 /* MANUFACTURER_IND */
93     
94     /*
95      * Check for a valid incoming CAPI message.
96      * Return:
97      *   0 = Invalid message
98      *   1 = Valid message, no B-Channel-data
99      *   2 = Valid message, B-Channel-data
100      */
101     int
102     actcapi_chkhdr(act2000_card * card, actcapi_msghdr *hdr)
103     {
104     	int i;
105     
106     	if (hdr->applicationID != 1)
107     		return 0;
108     	if (hdr->len < 9)
109     		return 0;
110     	for (i = 0; i < num_valid_imsg; i++)
111     		if ((hdr->cmd.cmd == valid_msg[i].cmd.cmd) &&
112     		    (hdr->cmd.subcmd == valid_msg[i].cmd.subcmd)) {
113     			return (i?1:2);
114     		}
115     	return 0;
116     }
117     
118     #define ACTCAPI_MKHDR(l, c, s) { \
119     	skb = alloc_skb(l + 8, GFP_ATOMIC); \
120     	if (skb) { \
121     	        m = (actcapi_msg *)skb_put(skb, l + 8); \
122     		m->hdr.len = l + 8; \
123     		m->hdr.applicationID = 1; \
124     	        m->hdr.cmd.cmd = c; \
125     	        m->hdr.cmd.subcmd = s; \
126     	        m->hdr.msgnum = actcapi_nextsmsg(card); \
127     	} else m = NULL;\
128     }
129     
130     #define ACTCAPI_CHKSKB if (!skb) { \
131     	printk(KERN_WARNING "actcapi: alloc_skb failed\n"); \
132     	return; \
133     }
134     
135     #define ACTCAPI_QUEUE_TX { \
136     	actcapi_debug_msg(skb, 1); \
137     	skb_queue_tail(&card->sndq, skb); \
138     	act2000_schedule_tx(card); \
139     }
140     
141     int
142     actcapi_listen_req(act2000_card *card)
143     {
144     	__u16 eazmask = 0;
145     	int i;
146     	actcapi_msg *m;
147     	struct sk_buff *skb;
148     
149     	for (i = 0; i < ACT2000_BCH; i++)
150     		eazmask |= card->bch[i].eazmask;
151     	ACTCAPI_MKHDR(9, 0x05, 0x00);
152             if (!skb) {
153                     printk(KERN_WARNING "actcapi: alloc_skb failed\n");
154                     return -ENOMEM;
155             }
156     	m->msg.listen_req.controller = 0;
157     	m->msg.listen_req.infomask = 0x3f; /* All information */
158     	m->msg.listen_req.eazmask = eazmask;
159     	m->msg.listen_req.simask = (eazmask)?0x86:0; /* All SI's  */
160     	ACTCAPI_QUEUE_TX;
161             return 0;
162     }
163     
164     int
165     actcapi_connect_req(act2000_card *card, act2000_chan *chan, char *phone,
166     		    char eaz, int si1, int si2)
167     {
168     	actcapi_msg *m;
169     	struct sk_buff *skb;
170     
171     	ACTCAPI_MKHDR((11 + strlen(phone)), 0x02, 0x00);
172     	if (!skb) {
173                     printk(KERN_WARNING "actcapi: alloc_skb failed\n");
174     		chan->fsm_state = ACT2000_STATE_NULL;
175     		return -ENOMEM;
176     	}
177     	m->msg.connect_req.controller = 0;
178     	m->msg.connect_req.bchan = 0x83;
179     	m->msg.connect_req.infomask = 0x3f;
180     	m->msg.connect_req.si1 = si1;
181     	m->msg.connect_req.si2 = si2;
182     	m->msg.connect_req.eaz = eaz?eaz:'0';
183     	m->msg.connect_req.addr.len = strlen(phone) + 1;
184     	m->msg.connect_req.addr.tnp = 0x81;
185     	memcpy(m->msg.connect_req.addr.num, phone, strlen(phone));
186     	chan->callref = m->hdr.msgnum;
187     	ACTCAPI_QUEUE_TX;
188     	return 0;
189     }
190     
191     static void
192     actcapi_connect_b3_req(act2000_card *card, act2000_chan *chan)
193     {
194     	actcapi_msg *m;
195     	struct sk_buff *skb;
196     
197     	ACTCAPI_MKHDR(17, 0x82, 0x00);
198     	ACTCAPI_CHKSKB;
199     	m->msg.connect_b3_req.plci = chan->plci;
200     	memset(&m->msg.connect_b3_req.ncpi, 0,
201     	       sizeof(m->msg.connect_b3_req.ncpi));
202     	m->msg.connect_b3_req.ncpi.len = 13;
203     	m->msg.connect_b3_req.ncpi.modulo = 8;
204     	ACTCAPI_QUEUE_TX;
205     }
206     
207     /*
208      * Set net type (1TR6) or (EDSS1)
209      */
210     int
211     actcapi_manufacturer_req_net(act2000_card *card)
212     {
213     	actcapi_msg *m;
214     	struct sk_buff *skb;
215     
216     	ACTCAPI_MKHDR(5, 0xff, 0x00);
217             if (!skb) {
218                     printk(KERN_WARNING "actcapi: alloc_skb failed\n");
219                     return -ENOMEM;
220             }
221     	m->msg.manufacturer_req_net.manuf_msg = 0x11;
222     	m->msg.manufacturer_req_net.controller = 1;
223     	m->msg.manufacturer_req_net.nettype = (card->ptype == ISDN_PTYPE_EURO)?1:0;
224     	ACTCAPI_QUEUE_TX;
225     	printk(KERN_INFO "act2000 %s: D-channel protocol now %s\n",
226     	       card->interface.id, (card->ptype == ISDN_PTYPE_EURO)?"euro":"1tr6");
227     	card->interface.features &=
228     		~(ISDN_FEATURE_P_UNKNOWN | ISDN_FEATURE_P_EURO | ISDN_FEATURE_P_1TR6);
229     	card->interface.features |=
230     		((card->ptype == ISDN_PTYPE_EURO)?ISDN_FEATURE_P_EURO:ISDN_FEATURE_P_1TR6);
231             return 0;
232     }
233     
234     /*
235      * Switch V.42 on or off
236      */
237     int
238     actcapi_manufacturer_req_v42(act2000_card *card, ulong arg)
239     {
240     	actcapi_msg *m;
241     	struct sk_buff *skb;
242     
243     	ACTCAPI_MKHDR(8, 0xff, 0x00);
244             if (!skb) {
245     
246                     printk(KERN_WARNING "actcapi: alloc_skb failed\n");
247                     return -ENOMEM;
248             }
249     	m->msg.manufacturer_req_v42.manuf_msg = 0x10;
250     	m->msg.manufacturer_req_v42.controller = 0;
251     	m->msg.manufacturer_req_v42.v42control = (arg?1:0);
252     	ACTCAPI_QUEUE_TX;
253             return 0;
254     }
255     
256     /*
257      * Set error-handler
258      */
259     int
260     actcapi_manufacturer_req_errh(act2000_card *card)
261     {
262     	actcapi_msg *m;
263     	struct sk_buff *skb;
264     
265     	ACTCAPI_MKHDR(4, 0xff, 0x00);
266             if (!skb) {
267     
268                     printk(KERN_WARNING "actcapi: alloc_skb failed\n");
269                     return -ENOMEM;
270             }
271     	m->msg.manufacturer_req_err.manuf_msg = 0x03;
272     	m->msg.manufacturer_req_err.controller = 0;
273     	ACTCAPI_QUEUE_TX;
274             return 0;
275     }
276     
277     /*
278      * Set MSN-Mapping.
279      */
280     int
281     actcapi_manufacturer_req_msn(act2000_card *card)
282     {
283     	msn_entry *p = card->msn_list;
284     	actcapi_msg *m;
285     	struct sk_buff *skb;
286     	int len;
287     
288     	while (p) {
289     		int i;
290     
291     		len = strlen(p->msn);
292     		for (i = 0; i < 2; i++) {
293     			ACTCAPI_MKHDR(6 + len, 0xff, 0x00);
294     			if (!skb) {
295     				printk(KERN_WARNING "actcapi: alloc_skb failed\n");
296     				return -ENOMEM;
297     			}
298     			m->msg.manufacturer_req_msn.manuf_msg = 0x13 + i;
299     			m->msg.manufacturer_req_msn.controller = 0;
300     			m->msg.manufacturer_req_msn.msnmap.eaz = p->eaz;
301     			m->msg.manufacturer_req_msn.msnmap.len = len;
302     			memcpy(m->msg.manufacturer_req_msn.msnmap.msn, p->msn, len);
303     			ACTCAPI_QUEUE_TX;
304     		}
305     		p = p->next;
306     	}
307             return 0;
308     }
309     
310     void
311     actcapi_select_b2_protocol_req(act2000_card *card, act2000_chan *chan)
312     {
313     	actcapi_msg *m;
314     	struct sk_buff *skb;
315     
316     	ACTCAPI_MKHDR(10, 0x40, 0x00);
317     	ACTCAPI_CHKSKB;
318     	m->msg.select_b2_protocol_req.plci = chan->plci;
319     	memset(&m->msg.select_b2_protocol_req.dlpd, 0,
320     	       sizeof(m->msg.select_b2_protocol_req.dlpd));
321     	m->msg.select_b2_protocol_req.dlpd.len = 6;
322     	switch (chan->l2prot) {
323     		case ISDN_PROTO_L2_TRANS:
324     			m->msg.select_b2_protocol_req.protocol = 0x03;
325     			m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
326     			break;
327     		case ISDN_PROTO_L2_HDLC:
328     			m->msg.select_b2_protocol_req.protocol = 0x02;
329     			m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
330     			break;
331     		case ISDN_PROTO_L2_X75I:
332     		case ISDN_PROTO_L2_X75UI:
333     		case ISDN_PROTO_L2_X75BUI:
334     			m->msg.select_b2_protocol_req.protocol = 0x01;
335     			m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
336     			m->msg.select_b2_protocol_req.dlpd.laa = 3;
337     			m->msg.select_b2_protocol_req.dlpd.lab = 1;
338     			m->msg.select_b2_protocol_req.dlpd.win = 7;
339     			m->msg.select_b2_protocol_req.dlpd.modulo = 8;
340     			break;
341     	}
342     	ACTCAPI_QUEUE_TX;
343     }
344     
345     static void
346     actcapi_select_b3_protocol_req(act2000_card *card, act2000_chan *chan)
347     {
348     	actcapi_msg *m;
349     	struct sk_buff *skb;
350     
351     	ACTCAPI_MKHDR(17, 0x80, 0x00);
352     	ACTCAPI_CHKSKB;
353     	m->msg.select_b3_protocol_req.plci = chan->plci;
354     	memset(&m->msg.select_b3_protocol_req.ncpd, 0,
355     	       sizeof(m->msg.select_b3_protocol_req.ncpd));
356     	switch (chan->l3prot) {
357     		case ISDN_PROTO_L3_TRANS:
358     			m->msg.select_b3_protocol_req.protocol = 0x04;
359     			m->msg.select_b3_protocol_req.ncpd.len = 13;
360     			m->msg.select_b3_protocol_req.ncpd.modulo = 8;
361     			break;
362     	}
363     	ACTCAPI_QUEUE_TX;
364     }
365     
366     static void
367     actcapi_listen_b3_req(act2000_card *card, act2000_chan *chan)
368     {
369     	actcapi_msg *m;
370     	struct sk_buff *skb;
371     
372     	ACTCAPI_MKHDR(2, 0x81, 0x00);
373     	ACTCAPI_CHKSKB;
374     	m->msg.listen_b3_req.plci = chan->plci;
375     	ACTCAPI_QUEUE_TX;
376     }
377     
378     static void
379     actcapi_disconnect_req(act2000_card *card, act2000_chan *chan)
380     {
381     	actcapi_msg *m;
382     	struct sk_buff *skb;
383     
384     	ACTCAPI_MKHDR(3, 0x04, 0x00);
385     	ACTCAPI_CHKSKB;
386     	m->msg.disconnect_req.plci = chan->plci;
387     	m->msg.disconnect_req.cause = 0;
388     	ACTCAPI_QUEUE_TX;
389     }
390     
391     void
392     actcapi_disconnect_b3_req(act2000_card *card, act2000_chan *chan)
393     {
394     	actcapi_msg *m;
395     	struct sk_buff *skb;
396     
397     	ACTCAPI_MKHDR(17, 0x84, 0x00);
398     	ACTCAPI_CHKSKB;
399     	m->msg.disconnect_b3_req.ncci = chan->ncci;
400     	memset(&m->msg.disconnect_b3_req.ncpi, 0,
401     	       sizeof(m->msg.disconnect_b3_req.ncpi));
402     	m->msg.disconnect_b3_req.ncpi.len = 13;
403     	m->msg.disconnect_b3_req.ncpi.modulo = 8;
404     	chan->fsm_state = ACT2000_STATE_BHWAIT;
405     	ACTCAPI_QUEUE_TX;
406     }
407     
408     void
409     actcapi_connect_resp(act2000_card *card, act2000_chan *chan, __u8 cause)
410     {
411     	actcapi_msg *m;
412     	struct sk_buff *skb;
413     
414     	ACTCAPI_MKHDR(3, 0x02, 0x03);
415     	ACTCAPI_CHKSKB;
416     	m->msg.connect_resp.plci = chan->plci;
417     	m->msg.connect_resp.rejectcause = cause;
418     	if (cause) {
419     		chan->fsm_state = ACT2000_STATE_NULL;
420     		chan->plci = 0x8000;
421     	} else
422     		chan->fsm_state = ACT2000_STATE_IWAIT;
423     	ACTCAPI_QUEUE_TX;
424     }
425     
426     static void
427     actcapi_connect_active_resp(act2000_card *card, act2000_chan *chan)
428     {
429     	actcapi_msg *m;
430     	struct sk_buff *skb;
431     
432     	ACTCAPI_MKHDR(2, 0x03, 0x03);
433     	ACTCAPI_CHKSKB;
434     	m->msg.connect_resp.plci = chan->plci;
435     	if (chan->fsm_state == ACT2000_STATE_IWAIT)
436     		chan->fsm_state = ACT2000_STATE_IBWAIT;
437     	ACTCAPI_QUEUE_TX;
438     }
439     
440     static void
441     actcapi_connect_b3_resp(act2000_card *card, act2000_chan *chan, __u8 rejectcause)
442     {
443     	actcapi_msg *m;
444     	struct sk_buff *skb;
445     
446     	ACTCAPI_MKHDR((rejectcause?3:17), 0x82, 0x03);
447     	ACTCAPI_CHKSKB;
448     	m->msg.connect_b3_resp.ncci = chan->ncci;
449     	m->msg.connect_b3_resp.rejectcause = rejectcause;
450     	if (!rejectcause) {
451     		memset(&m->msg.connect_b3_resp.ncpi, 0,
452     		       sizeof(m->msg.connect_b3_resp.ncpi));
453     		m->msg.connect_b3_resp.ncpi.len = 13;
454     		m->msg.connect_b3_resp.ncpi.modulo = 8;
455     		chan->fsm_state = ACT2000_STATE_BWAIT;
456     	}
457     	ACTCAPI_QUEUE_TX;
458     }
459     
460     static void
461     actcapi_connect_b3_active_resp(act2000_card *card, act2000_chan *chan)
462     {
463     	actcapi_msg *m;
464     	struct sk_buff *skb;
465     
466     	ACTCAPI_MKHDR(2, 0x83, 0x03);
467     	ACTCAPI_CHKSKB;
468     	m->msg.connect_b3_active_resp.ncci = chan->ncci;
469     	chan->fsm_state = ACT2000_STATE_ACTIVE;
470     	ACTCAPI_QUEUE_TX;
471     }
472     
473     static void
474     actcapi_info_resp(act2000_card *card, act2000_chan *chan)
475     {
476     	actcapi_msg *m;
477     	struct sk_buff *skb;
478     
479     	ACTCAPI_MKHDR(2, 0x07, 0x03);
480     	ACTCAPI_CHKSKB;
481     	m->msg.info_resp.plci = chan->plci;
482     	ACTCAPI_QUEUE_TX;
483     }
484     
485     static void
486     actcapi_disconnect_b3_resp(act2000_card *card, act2000_chan *chan)
487     {
488     	actcapi_msg *m;
489     	struct sk_buff *skb;
490     
491     	ACTCAPI_MKHDR(2, 0x84, 0x03);
492     	ACTCAPI_CHKSKB;
493     	m->msg.disconnect_b3_resp.ncci = chan->ncci;
494     	chan->ncci = 0x8000;
495     	chan->queued = 0;
496     	ACTCAPI_QUEUE_TX;
497     }
498     
499     static void
500     actcapi_disconnect_resp(act2000_card *card, act2000_chan *chan)
501     {
502     	actcapi_msg *m;
503     	struct sk_buff *skb;
504     
505     	ACTCAPI_MKHDR(2, 0x04, 0x03);
506     	ACTCAPI_CHKSKB;
507     	m->msg.disconnect_resp.plci = chan->plci;
508     	chan->plci = 0x8000;
509     	ACTCAPI_QUEUE_TX;
510     }
511     
512     static int
513     new_plci(act2000_card *card, __u16 plci)
514     {
515     	int i;
516     	for (i = 0; i < ACT2000_BCH; i++)
517     		if (card->bch[i].plci == 0x8000) {
518     			card->bch[i].plci = plci;
519     			return i;
520     		}
521     	return -1;
522     }
523     
524     static int
525     find_plci(act2000_card *card, __u16 plci)
526     {
527     	int i;
528     	for (i = 0; i < ACT2000_BCH; i++)
529     		if (card->bch[i].plci == plci)
530     			return i;
531     	return -1;
532     }
533     
534     static int
535     find_ncci(act2000_card *card, __u16 ncci)
536     {
537     	int i;
538     	for (i = 0; i < ACT2000_BCH; i++)
539     		if (card->bch[i].ncci == ncci)
540     			return i;
541     	return -1;
542     }
543     
544     static int
545     find_dialing(act2000_card *card, __u16 callref)
546     {
547     	int i;
548     	for (i = 0; i < ACT2000_BCH; i++)
549     		if ((card->bch[i].callref == callref) &&
550     		    (card->bch[i].fsm_state == ACT2000_STATE_OCALL))
551     			return i;
552     	return -1;
553     }
554     
555     static int
556     actcapi_data_b3_ind(act2000_card *card, struct sk_buff *skb) {
557     	__u16 plci;
558     	__u16 ncci;
559     	__u16 controller;
560     	__u8  blocknr;
561     	int chan;
562     	actcapi_msg *msg = (actcapi_msg *)skb->data;
563     
564     	EVAL_NCCI(msg->msg.data_b3_ind.fakencci, plci, controller, ncci);
565     	chan = find_ncci(card, ncci);
566     	if (chan < 0)
567     		return 0;
568     	if (card->bch[chan].fsm_state != ACT2000_STATE_ACTIVE)
569     		return 0;
570     	if (card->bch[chan].plci != plci)
571     		return 0;
572     	blocknr = msg->msg.data_b3_ind.blocknr;
573     	skb_pull(skb, 19);
574     	card->interface.rcvcallb_skb(card->myid, chan, skb);
575             if (!(skb = alloc_skb(11, GFP_ATOMIC))) {
576                     printk(KERN_WARNING "actcapi: alloc_skb failed\n");
577                     return 1;
578             }
579     	msg = (actcapi_msg *)skb_put(skb, 11);
580     	msg->hdr.len = 11;
581     	msg->hdr.applicationID = 1;
582     	msg->hdr.cmd.cmd = 0x86;
583     	msg->hdr.cmd.subcmd = 0x03;
584     	msg->hdr.msgnum = actcapi_nextsmsg(card);
585     	msg->msg.data_b3_resp.ncci = ncci;
586     	msg->msg.data_b3_resp.blocknr = blocknr;
587     	ACTCAPI_QUEUE_TX;
588     	return 1;
589     }
590     
591     /*
592      * Walk over ackq, unlink DATA_B3_REQ from it, if
593      * ncci and blocknr are matching.
594      * Decrement queued-bytes counter.
595      */
596     static int
597     handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) {
598     	unsigned long flags;
599     	struct sk_buff *skb;
600     	struct sk_buff *tmp;
601     	struct actcapi_msg *m;
602     	int ret = 0;
603     
604     	save_flags(flags);
605     	cli();
606     	skb = skb_peek(&card->ackq);
607     	restore_flags(flags);
608             if (!skb) {
609     		printk(KERN_WARNING "act2000: handle_ack nothing found!\n");
610     		return 0;
611     	}
612             tmp = skb;
613             while (1) {
614                     m = (actcapi_msg *)tmp->data;
615                     if ((((m->msg.data_b3_req.fakencci >> 8) & 0xff) == chan->ncci) &&
616     		    (m->msg.data_b3_req.blocknr == blocknr)) {
617     			/* found corresponding DATA_B3_REQ */
618                             skb_unlink(tmp);
619     			chan->queued -= m->msg.data_b3_req.datalen;
620     			if (m->msg.data_b3_req.flags)
621     				ret = m->msg.data_b3_req.datalen;
622     			dev_kfree_skb(tmp);
623     			if (chan->queued < 0)
624     				chan->queued = 0;
625                             return ret;
626                     }
627     		save_flags(flags);
628     		cli();
629                     tmp = skb_peek((struct sk_buff_head *)tmp);
630     		restore_flags(flags);
631                     if ((tmp == skb) || (tmp == NULL)) {
632     			/* reached end of queue */
633     			printk(KERN_WARNING "act2000: handle_ack nothing found!\n");
634                             return 0;
635     		}
636             }
637     }
638     
639     void
640     actcapi_dispatch(act2000_card *card)
641     {
642     	struct sk_buff *skb;
643     	actcapi_msg *msg;
644     	__u16 ccmd;
645     	int chan;
646     	int len;
647     	act2000_chan *ctmp;
648     	isdn_ctrl cmd;
649     	char tmp[170];
650     
651     	while ((skb = skb_dequeue(&card->rcvq))) {
652     		actcapi_debug_msg(skb, 0);
653     		msg = (actcapi_msg *)skb->data;
654     		ccmd = ((msg->hdr.cmd.cmd << 8) | msg->hdr.cmd.subcmd);
655     		switch (ccmd) {
656     			case 0x8602:
657     				/* DATA_B3_IND */
658     				if (actcapi_data_b3_ind(card, skb))
659     					return;
660     				break;
661     			case 0x8601:
662     				/* DATA_B3_CONF */
663     				chan = find_ncci(card, msg->msg.data_b3_conf.ncci);
664     				if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_ACTIVE)) {
665     					if (msg->msg.data_b3_conf.info != 0)
666     						printk(KERN_WARNING "act2000: DATA_B3_CONF: %04x\n",
667     						       msg->msg.data_b3_conf.info);
668     					len = handle_ack(card, &card->bch[chan],
669     							 msg->msg.data_b3_conf.blocknr);
670     					if (len) {
671     						cmd.driver = card->myid;
672     						cmd.command = ISDN_STAT_BSENT;
673     						cmd.arg = chan;
674     						cmd.parm.length = len;
675     						card->interface.statcallb(&cmd);
676     					}
677     				}
678     				break;
679     			case 0x0201:
680     				/* CONNECT_CONF */
681     				chan = find_dialing(card, msg->hdr.msgnum);
682     				if (chan >= 0) {
683     					if (msg->msg.connect_conf.info) {
684     						card->bch[chan].fsm_state = ACT2000_STATE_NULL;
685     						cmd.driver = card->myid;
686     						cmd.command = ISDN_STAT_DHUP;
687     						cmd.arg = chan;
688     						card->interface.statcallb(&cmd);
689     					} else {
690     						card->bch[chan].fsm_state = ACT2000_STATE_OWAIT;
691     						card->bch[chan].plci = msg->msg.connect_conf.plci;
692     					}
693     				}
694     				break;
695     			case 0x0202:
696     				/* CONNECT_IND */
697     				chan = new_plci(card, msg->msg.connect_ind.plci);
698     				if (chan < 0) {
699     					ctmp = (act2000_chan *)tmp;
700     					ctmp->plci = msg->msg.connect_ind.plci;
701     					actcapi_connect_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
702     				} else {
703     					card->bch[chan].fsm_state = ACT2000_STATE_ICALL;
704     					cmd.driver = card->myid;
705     					cmd.command = ISDN_STAT_ICALL;
706     					cmd.arg = chan;
707     					cmd.parm.setup.si1 = msg->msg.connect_ind.si1;
708     					cmd.parm.setup.si2 = msg->msg.connect_ind.si2;
709     					if (card->ptype == ISDN_PTYPE_EURO)
710     						strcpy(cmd.parm.setup.eazmsn,
711     						       act2000_find_eaz(card, msg->msg.connect_ind.eaz));
712     					else {
713     						cmd.parm.setup.eazmsn[0] = msg->msg.connect_ind.eaz;
714     						cmd.parm.setup.eazmsn[1] = 0;
715     					}
716     					memset(cmd.parm.setup.phone, 0, sizeof(cmd.parm.setup.phone));
717     					memcpy(cmd.parm.setup.phone, msg->msg.connect_ind.addr.num,
718     					       msg->msg.connect_ind.addr.len - 1);
719     					cmd.parm.setup.plan = msg->msg.connect_ind.addr.tnp;
720     					cmd.parm.setup.screen = 0;
721     					if (card->interface.statcallb(&cmd) == 2)
722     						actcapi_connect_resp(card, &card->bch[chan], 0x15); /* Reject Call */
723     				}
724     				break;
725     			case 0x0302:
726     				/* CONNECT_ACTIVE_IND */
727     				chan = find_plci(card, msg->msg.connect_active_ind.plci);
728     				if (chan >= 0)
729     					switch (card->bch[chan].fsm_state) {
730     						case ACT2000_STATE_IWAIT:
731     							actcapi_connect_active_resp(card, &card->bch[chan]);
732     							break;
733     						case ACT2000_STATE_OWAIT:
734     							actcapi_connect_active_resp(card, &card->bch[chan]);
735     							actcapi_select_b2_protocol_req(card, &card->bch[chan]);
736     							break;
737     					}
738     				break;
739     			case 0x8202:
740     				/* CONNECT_B3_IND */
741     				chan = find_plci(card, msg->msg.connect_b3_ind.plci);
742     				if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_IBWAIT)) {
743     					card->bch[chan].ncci = msg->msg.connect_b3_ind.ncci;
744     					actcapi_connect_b3_resp(card, &card->bch[chan], 0);
745     				} else {
746     					ctmp = (act2000_chan *)tmp;
747     					ctmp->ncci = msg->msg.connect_b3_ind.ncci;
748     					actcapi_connect_b3_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
749     				}
750     				break;
751     			case 0x8302:
752     				/* CONNECT_B3_ACTIVE_IND */
753     				chan = find_ncci(card, msg->msg.connect_b3_active_ind.ncci);
754     				if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BWAIT)) {
755     					actcapi_connect_b3_active_resp(card, &card->bch[chan]);
756     					cmd.driver = card->myid;
757     					cmd.command = ISDN_STAT_BCONN;
758     					cmd.arg = chan;
759     					card->interface.statcallb(&cmd);
760     				}
761     				break;
762     			case 0x8402:
763     				/* DISCONNECT_B3_IND */
764     				chan = find_ncci(card, msg->msg.disconnect_b3_ind.ncci);
765     				if (chan >= 0) {
766     					ctmp = &card->bch[chan];
767     					actcapi_disconnect_b3_resp(card, ctmp);
768     					switch (ctmp->fsm_state) {
769     						case ACT2000_STATE_ACTIVE:
770     							ctmp->fsm_state = ACT2000_STATE_DHWAIT2;
771     							cmd.driver = card->myid;
772     							cmd.command = ISDN_STAT_BHUP;
773     							cmd.arg = chan;
774     							card->interface.statcallb(&cmd);
775     							break;
776     						case ACT2000_STATE_BHWAIT2:
777     							actcapi_disconnect_req(card, ctmp);
778     							ctmp->fsm_state = ACT2000_STATE_DHWAIT;
779     							cmd.driver = card->myid;
780     							cmd.command = ISDN_STAT_BHUP;
781     							cmd.arg = chan;
782     							card->interface.statcallb(&cmd);
783     							break;
784     					}
785     				}
786     				break;
787     			case 0x0402:
788     				/* DISCONNECT_IND */
789     				chan = find_plci(card, msg->msg.disconnect_ind.plci);
790     				if (chan >= 0) {
791     					ctmp = &card->bch[chan];
792     					actcapi_disconnect_resp(card, ctmp);
793     					ctmp->fsm_state = ACT2000_STATE_NULL;
794     					cmd.driver = card->myid;
795     					cmd.command = ISDN_STAT_DHUP;
796     					cmd.arg = chan;
797     					card->interface.statcallb(&cmd);
798     				} else {
799     					ctmp = (act2000_chan *)tmp;
800     					ctmp->plci = msg->msg.disconnect_ind.plci;
801     					actcapi_disconnect_resp(card, ctmp);
802     				}
803     				break;
804     			case 0x4001:
805     				/* SELECT_B2_PROTOCOL_CONF */
806     				chan = find_plci(card, msg->msg.select_b2_protocol_conf.plci);
807     				if (chan >= 0)
808     					switch (card->bch[chan].fsm_state) {
809     						case ACT2000_STATE_ICALL:
810     						case ACT2000_STATE_OWAIT:
811     							ctmp = &card->bch[chan];
812     							if (msg->msg.select_b2_protocol_conf.info == 0)
813     								actcapi_select_b3_protocol_req(card, ctmp);
814     							else {
815     								ctmp->fsm_state = ACT2000_STATE_NULL;
816     								cmd.driver = card->myid;
817     								cmd.command = ISDN_STAT_DHUP;
818     								cmd.arg = chan;
819     								card->interface.statcallb(&cmd);
820     							}
821     							break;
822     					}
823     				break;
824     			case 0x8001:
825     				/* SELECT_B3_PROTOCOL_CONF */
826     				chan = find_plci(card, msg->msg.select_b3_protocol_conf.plci);
827     				if (chan >= 0)
828     					switch (card->bch[chan].fsm_state) {
829     						case ACT2000_STATE_ICALL:
830     						case ACT2000_STATE_OWAIT:
831     							ctmp = &card->bch[chan];
832     							if (msg->msg.select_b3_protocol_conf.info == 0)
833     								actcapi_listen_b3_req(card, ctmp);
834     							else {
835     								ctmp->fsm_state = ACT2000_STATE_NULL;
836     								cmd.driver = card->myid;
837     								cmd.command = ISDN_STAT_DHUP;
838     								cmd.arg = chan;
839     								card->interface.statcallb(&cmd);
840     							}
841     					}
842     				break;
843     			case 0x8101:
844     				/* LISTEN_B3_CONF */
845     				chan = find_plci(card, msg->msg.listen_b3_conf.plci);
846     				if (chan >= 0)
847     					switch (card->bch[chan].fsm_state) {
848     						case ACT2000_STATE_ICALL:
849     							ctmp = &card->bch[chan];
850     							if (msg->msg.listen_b3_conf.info == 0)
851     								actcapi_connect_resp(card, ctmp, 0);
852     							else {
853     								ctmp->fsm_state = ACT2000_STATE_NULL;
854     								cmd.driver = card->myid;
855     								cmd.command = ISDN_STAT_DHUP;
856     								cmd.arg = chan;
857     								card->interface.statcallb(&cmd);
858     							}
859     							break;
860     						case ACT2000_STATE_OWAIT:
861     							ctmp = &card->bch[chan];
862     							if (msg->msg.listen_b3_conf.info == 0) {
863     								actcapi_connect_b3_req(card, ctmp);
864     								ctmp->fsm_state = ACT2000_STATE_OBWAIT;
865     								cmd.driver = card->myid;
866     								cmd.command = ISDN_STAT_DCONN;
867     								cmd.arg = chan;
868     								card->interface.statcallb(&cmd);
869     							} else {
870     								ctmp->fsm_state = ACT2000_STATE_NULL;
871     								cmd.driver = card->myid;
872     								cmd.command = ISDN_STAT_DHUP;
873     								cmd.arg = chan;
874     								card->interface.statcallb(&cmd);
875     							}
876     							break;
877     					}
878     				break;
879     			case 0x8201:
880     				/* CONNECT_B3_CONF */
881     				chan = find_plci(card, msg->msg.connect_b3_conf.plci);
882     				if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_OBWAIT)) {
883     					ctmp = &card->bch[chan];
884     					if (msg->msg.connect_b3_conf.info) {
885     						ctmp->fsm_state = ACT2000_STATE_NULL;
886     						cmd.driver = card->myid;
887     						cmd.command = ISDN_STAT_DHUP;
888     						cmd.arg = chan;
889     						card->interface.statcallb(&cmd);
890     					} else {
891     						ctmp->ncci = msg->msg.connect_b3_conf.ncci;
892     						ctmp->fsm_state = ACT2000_STATE_BWAIT;
893     					}
894     				}
895     				break;
896     			case 0x8401:
897     				/* DISCONNECT_B3_CONF */
898     				chan = find_ncci(card, msg->msg.disconnect_b3_conf.ncci);
899     				if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BHWAIT))
900     					card->bch[chan].fsm_state = ACT2000_STATE_BHWAIT2;
901     				break;
902     			case 0x0702:
903     				/* INFO_IND */
904     				chan = find_plci(card, msg->msg.info_ind.plci);
905     				if (chan >= 0)
906     					/* TODO: Eval Charging info / cause */
907     					actcapi_info_resp(card, &card->bch[chan]);
908     				break;
909     			case 0x0401:
910     				/* LISTEN_CONF */
911     			case 0x0501:
912     				/* LISTEN_CONF */
913     			case 0xff01:
914     				/* MANUFACTURER_CONF */
915     				break;
916     			case 0xff02:
917     				/* MANUFACTURER_IND */
918     				if (msg->msg.manuf_msg == 3) {
919     					memset(tmp, 0, sizeof(tmp));
920     					strncpy(tmp,
921     						&msg->msg.manufacturer_ind_err.errstring,
922     						msg->hdr.len - 16);
923     					if (msg->msg.manufacturer_ind_err.errcode)
924     						printk(KERN_WARNING "act2000: %s\n", tmp);
925     					else {
926     						printk(KERN_DEBUG "act2000: %s\n", tmp);
927     						if ((!strncmp(tmp, "INFO: Trace buffer con", 22)) ||
928     						    (!strncmp(tmp, "INFO: Compile Date/Tim", 22))) {
929     							card->flags |= ACT2000_FLAGS_RUNNING;
930     							cmd.command = ISDN_STAT_RUN;
931     							cmd.driver = card->myid;
932     							cmd.arg = 0;
933     							actcapi_manufacturer_req_net(card);
934     							actcapi_manufacturer_req_msn(card);
935     							actcapi_listen_req(card);
936     							card->interface.statcallb(&cmd);
937     						}
938     					}
939     				}
940     				break;
941     			default:
942     				printk(KERN_WARNING "act2000: UNHANDLED Message %04x\n", ccmd);
943     				break;
944     		}
945     		dev_kfree_skb(skb);
946     	}
947     }
948     
949     #ifdef DEBUG_MSG
950     static void
951     actcapi_debug_caddr(actcapi_addr *addr)
952     {
953     	char tmp[30];
954     
955     	printk(KERN_DEBUG " Alen  = %d\n", addr->len);
956     	if (addr->len > 0)
957     		printk(KERN_DEBUG " Atnp  = 0x%02x\n", addr->tnp);
958     	if (addr->len > 1) {
959     		memset(tmp, 0, 30);
960     		memcpy(tmp, addr->num, addr->len - 1);
961     		printk(KERN_DEBUG " Anum  = '%s'\n", tmp);
962     	}
963     }
964     
965     static void
966     actcapi_debug_ncpi(actcapi_ncpi *ncpi)
967     {
968     	printk(KERN_DEBUG " ncpi.len = %d\n", ncpi->len);
969     	if (ncpi->len >= 2)
970     		printk(KERN_DEBUG " ncpi.lic = 0x%04x\n", ncpi->lic);
971     	if (ncpi->len >= 4)
972     		printk(KERN_DEBUG " ncpi.hic = 0x%04x\n", ncpi->hic);
973     	if (ncpi->len >= 6)
974     		printk(KERN_DEBUG " ncpi.ltc = 0x%04x\n", ncpi->ltc);
975     	if (ncpi->len >= 8)
976     		printk(KERN_DEBUG " ncpi.htc = 0x%04x\n", ncpi->htc);
977     	if (ncpi->len >= 10)
978     		printk(KERN_DEBUG " ncpi.loc = 0x%04x\n", ncpi->loc);
979     	if (ncpi->len >= 12)
980     		printk(KERN_DEBUG " ncpi.hoc = 0x%04x\n", ncpi->hoc);
981     	if (ncpi->len >= 13)
982     		printk(KERN_DEBUG " ncpi.mod = %d\n", ncpi->modulo);
983     }
984     
985     static void
986     actcapi_debug_dlpd(actcapi_dlpd *dlpd)
987     {
988     	printk(KERN_DEBUG " dlpd.len = %d\n", dlpd->len);
989     	if (dlpd->len >= 2)
990     		printk(KERN_DEBUG " dlpd.dlen   = 0x%04x\n", dlpd->dlen);
991     	if (dlpd->len >= 3)
992     		printk(KERN_DEBUG " dlpd.laa    = 0x%02x\n", dlpd->laa);
993     	if (dlpd->len >= 4)
994     		printk(KERN_DEBUG " dlpd.lab    = 0x%02x\n", dlpd->lab);
995     	if (dlpd->len >= 5)
996     		printk(KERN_DEBUG " dlpd.modulo = %d\n", dlpd->modulo);
997     	if (dlpd->len >= 6)
998     		printk(KERN_DEBUG " dlpd.win    = %d\n", dlpd->win);
999     }
1000     
1001     #ifdef DEBUG_DUMP_SKB
1002     static void dump_skb(struct sk_buff *skb) {
1003     	char tmp[80];
1004     	char *p = skb->data;
1005     	char *t = tmp;
1006     	int i;
1007     
1008     	for (i = 0; i < skb->len; i++) {
1009     		t += sprintf(t, "%02x ", *p++ & 0xff);
1010     		if ((i & 0x0f) == 8) {
1011     			printk(KERN_DEBUG "dump: %s\n", tmp);
1012     			t = tmp;
1013     		}
1014     	}
1015     	if (i & 0x07)
1016     		printk(KERN_DEBUG "dump: %s\n", tmp);
1017     }
1018     #endif
1019     
1020     void
1021     actcapi_debug_msg(struct sk_buff *skb, int direction)
1022     {
1023     	actcapi_msg *msg = (actcapi_msg *)skb->data;
1024     	char *descr;
1025     	int i;
1026     	char tmp[170];
1027     	
1028     #ifndef DEBUG_DATA_MSG
1029     	if (msg->hdr.cmd.cmd == 0x86)
1030     		return;
1031     #endif
1032     	descr = "INVALID";
1033     #ifdef DEBUG_DUMP_SKB
1034     	dump_skb(skb);
1035     #endif
1036     	for (i = 0; i < num_valid_msg; i++)
1037     		if ((msg->hdr.cmd.cmd == valid_msg[i].cmd.cmd) &&
1038     		    (msg->hdr.cmd.subcmd == valid_msg[i].cmd.subcmd)) {
1039     			descr = valid_msg[i].description;
1040     			break;
1041     		}
1042     	printk(KERN_DEBUG "%s %s msg\n", direction?"Outgoing":"Incoming", descr);
1043     	printk(KERN_DEBUG " ApplID = %d\n", msg->hdr.applicationID);
1044     	printk(KERN_DEBUG " Len    = %d\n", msg->hdr.len);
1045     	printk(KERN_DEBUG " MsgNum = 0x%04x\n", msg->hdr.msgnum);
1046     	printk(KERN_DEBUG " Cmd    = 0x%02x\n", msg->hdr.cmd.cmd);
1047     	printk(KERN_DEBUG " SubCmd = 0x%02x\n", msg->hdr.cmd.subcmd);
1048     	switch (i) {
1049     		case 0:
1050     			/* DATA B3 IND */
1051     			printk(KERN_DEBUG " BLOCK = 0x%02x\n",
1052     			       msg->msg.data_b3_ind.blocknr);
1053     			break;
1054     		case 2:
1055     			/* CONNECT CONF */
1056     			printk(KERN_DEBUG " PLCI = 0x%04x\n",
1057     			       msg->msg.connect_conf.plci);
1058     			printk(KERN_DEBUG " Info = 0x%04x\n",
1059     			       msg->msg.connect_conf.info);
1060     			break;
1061     		case 3:
1062     			/* CONNECT IND */
1063     			printk(KERN_DEBUG " PLCI = 0x%04x\n",
1064     			       msg->msg.connect_ind.plci);
1065     			printk(KERN_DEBUG " Contr = %d\n",
1066     			       msg->msg.connect_ind.controller);
1067     			printk(KERN_DEBUG " SI1   = %d\n",
1068     			       msg->msg.connect_ind.si1);
1069     			printk(KERN_DEBUG " SI2   = %d\n",
1070     			       msg->msg.connect_ind.si2);
1071     			printk(KERN_DEBUG " EAZ   = '%c'\n",
1072     			       msg->msg.connect_ind.eaz);
1073     			actcapi_debug_caddr(&msg->msg.connect_ind.addr);
1074     			break;
1075     		case 5:
1076     			/* CONNECT ACTIVE IND */
1077     			printk(KERN_DEBUG " PLCI = 0x%04x\n",
1078     			       msg->msg.connect_active_ind.plci);
1079     			actcapi_debug_caddr(&msg->msg.connect_active_ind.addr);
1080     			break;
1081     		case 8:
1082     			/* LISTEN CONF */
1083     			printk(KERN_DEBUG " Contr = %d\n",
1084     			       msg->msg.listen_conf.controller);
1085     			printk(KERN_DEBUG " Info = 0x%04x\n",
1086     			       msg->msg.listen_conf.info);
1087     			break;
1088     		case 11:
1089     			/* INFO IND */
1090     			printk(KERN_DEBUG " PLCI = 0x%04x\n",
1091     			       msg->msg.info_ind.plci);
1092     			printk(KERN_DEBUG " Imsk = 0x%04x\n",
1093     			       msg->msg.info_ind.nr.mask);
1094     			if (msg->hdr.len > 12) {
1095     				int l = msg->hdr.len - 12;
1096     				int j;
1097     				char *p = tmp;
1098     				for (j = 0; j < l ; j++)
1099     					p += sprintf(p, "%02x ", msg->msg.info_ind.el.display[j]);
1100     				printk(KERN_DEBUG " D = '%s'\n", tmp);
1101     			}
1102     			break;
1103     		case 14:
1104     			/* SELECT B2 PROTOCOL CONF */
1105     			printk(KERN_DEBUG " PLCI = 0x%04x\n",
1106     			       msg->msg.select_b2_protocol_conf.plci);
1107     			printk(KERN_DEBUG " Info = 0x%04x\n",
1108     			       msg->msg.select_b2_protocol_conf.info);
1109     			break;
1110     		case 15:
1111     			/* SELECT B3 PROTOCOL CONF */
1112     			printk(KERN_DEBUG " PLCI = 0x%04x\n",
1113     			       msg->msg.select_b3_protocol_conf.plci);
1114     			printk(KERN_DEBUG " Info = 0x%04x\n",
1115     			       msg->msg.select_b3_protocol_conf.info);
1116     			break;
1117     		case 16:
1118     			/* LISTEN B3 CONF */
1119     			printk(KERN_DEBUG " PLCI = 0x%04x\n",
1120     			       msg->msg.listen_b3_conf.plci);
1121     			printk(KERN_DEBUG " Info = 0x%04x\n",
1122     			       msg->msg.listen_b3_conf.info);
1123     			break;
1124     		case 18:
1125     			/* CONNECT B3 IND */
1126     			printk(KERN_DEBUG " NCCI = 0x%04x\n",
1127     			       msg->msg.connect_b3_ind.ncci);
1128     			printk(KERN_DEBUG " PLCI = 0x%04x\n",
1129     			       msg->msg.connect_b3_ind.plci);
1130     			actcapi_debug_ncpi(&msg->msg.connect_b3_ind.ncpi);
1131     			break;
1132     		case 19:
1133     			/* CONNECT B3 ACTIVE IND */
1134     			printk(KERN_DEBUG " NCCI = 0x%04x\n",
1135     			       msg->msg.connect_b3_active_ind.ncci);
1136     			actcapi_debug_ncpi(&msg->msg.connect_b3_active_ind.ncpi);
1137     			break;
1138     		case 26:
1139     			/* MANUFACTURER IND */
1140     			printk(KERN_DEBUG " Mmsg = 0x%02x\n",
1141     			       msg->msg.manufacturer_ind_err.manuf_msg);
1142     			switch (msg->msg.manufacturer_ind_err.manuf_msg) {
1143     				case 3:
1144     					printk(KERN_DEBUG " Contr = %d\n",
1145     					       msg->msg.manufacturer_ind_err.controller);
1146     					printk(KERN_DEBUG " Code = 0x%08x\n",
1147     					       msg->msg.manufacturer_ind_err.errcode);
1148     					memset(tmp, 0, sizeof(tmp));
1149     					strncpy(tmp, &msg->msg.manufacturer_ind_err.errstring,
1150     						msg->hdr.len - 16);
1151     					printk(KERN_DEBUG " Emsg = '%s'\n", tmp);
1152     					break;
1153     			}
1154     			break;
1155     		case 30:
1156     			/* LISTEN REQ */
1157     			printk(KERN_DEBUG " Imsk = 0x%08x\n",
1158     			       msg->msg.listen_req.infomask);
1159     			printk(KERN_DEBUG " Emsk = 0x%04x\n",
1160     			       msg->msg.listen_req.eazmask);
1161     			printk(KERN_DEBUG " Smsk = 0x%04x\n",
1162     			       msg->msg.listen_req.simask);
1163     			break;
1164     		case 35:
1165     			/* SELECT_B2_PROTOCOL_REQ */
1166     			printk(KERN_DEBUG " PLCI  = 0x%04x\n",
1167     			       msg->msg.select_b2_protocol_req.plci);
1168     			printk(KERN_DEBUG " prot  = 0x%02x\n",
1169     			       msg->msg.select_b2_protocol_req.protocol);
1170     			if (msg->hdr.len >= 11)
1171     				printk(KERN_DEBUG "No dlpd\n");
1172     			else
1173     				actcapi_debug_dlpd(&msg->msg.select_b2_protocol_req.dlpd);
1174     			break;
1175     		case 44:
1176     			/* CONNECT RESP */
1177     			printk(KERN_DEBUG " PLCI  = 0x%04x\n",
1178     			       msg->msg.connect_resp.plci);
1179     			printk(KERN_DEBUG " CAUSE = 0x%02x\n",
1180     			       msg->msg.connect_resp.rejectcause);
1181     			break;
1182     		case 45:
1183     			/* CONNECT ACTIVE RESP */
1184     			printk(KERN_DEBUG " PLCI  = 0x%04x\n",
1185     			       msg->msg.connect_active_resp.plci);
1186     			break;
1187     	}
1188     }
1189     #endif
1190