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