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