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