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