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