upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / isdn / act2000 / capi.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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