1/* $Id: icn.c,v 1.65.6.8 2001/09/23 22:24:55 kai Exp $ 2 * 3 * ISDN low-level module for the ICN active ISDN-Card. 4 * 5 * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de) 6 * 7 * This software may be used and distributed according to the terms 8 * of the GNU General Public License, incorporated herein by reference. 9 * 10 */ 11 12#include "icn.h" 13#include <linux/module.h> 14#include <linux/init.h> 15#include <linux/slab.h> 16#include <linux/sched.h> 17 18static int portbase = ICN_BASEADDR; 19static unsigned long membase = ICN_MEMADDR; 20static char *icn_id = "\0"; 21static char *icn_id2 = "\0"; 22 23MODULE_DESCRIPTION("ISDN4Linux: Driver for ICN active ISDN card"); 24MODULE_AUTHOR("Fritz Elfert"); 25MODULE_LICENSE("GPL"); 26module_param(portbase, int, 0); 27MODULE_PARM_DESC(portbase, "Port address of first card"); 28module_param(membase, ulong, 0); 29MODULE_PARM_DESC(membase, "Shared memory address of all cards"); 30module_param(icn_id, charp, 0); 31MODULE_PARM_DESC(icn_id, "ID-String of first card"); 32module_param(icn_id2, charp, 0); 33MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)"); 34 35/* 36 * Verbose bootcode- and protocol-downloading. 37 */ 38#undef BOOT_DEBUG 39 40/* 41 * Verbose Shmem-Mapping. 42 */ 43#undef MAP_DEBUG 44 45static char 46*revision = "$Revision: 1.65.6.8 $"; 47 48static int icn_addcard(int, char *, char *); 49 50/* 51 * Free send-queue completely. 52 * Parameter: 53 * card = pointer to card struct 54 * channel = channel number 55 */ 56static void 57icn_free_queue(icn_card *card, int channel) 58{ 59 struct sk_buff_head *queue = &card->spqueue[channel]; 60 struct sk_buff *skb; 61 62 skb_queue_purge(queue); 63 card->xlen[channel] = 0; 64 card->sndcount[channel] = 0; 65 if ((skb = card->xskb[channel])) { 66 card->xskb[channel] = NULL; 67 dev_kfree_skb(skb); 68 } 69} 70 71/* Put a value into a shift-register, highest bit first. 72 * Parameters: 73 * port = port for output (bit 0 is significant) 74 * val = value to be output 75 * firstbit = Bit-Number of highest bit 76 * bitcount = Number of bits to output 77 */ 78static inline void 79icn_shiftout(unsigned short port, 80 unsigned long val, 81 int firstbit, 82 int bitcount) 83{ 84 85 register u_char s; 86 register u_char c; 87 88 for (s = firstbit, c = bitcount; c > 0; s--, c--) 89 OUTB_P((u_char) ((val >> s) & 1) ? 0xff : 0, port); 90} 91 92/* 93 * disable a cards shared memory 94 */ 95static inline void 96icn_disable_ram(icn_card *card) 97{ 98 OUTB_P(0, ICN_MAPRAM); 99} 100 101/* 102 * enable a cards shared memory 103 */ 104static inline void 105icn_enable_ram(icn_card *card) 106{ 107 OUTB_P(0xff, ICN_MAPRAM); 108} 109 110/* 111 * Map a cards channel0 (Bank0/Bank8) or channel1 (Bank4/Bank12) 112 * 113 * must called with holding the devlock 114 */ 115static inline void 116icn_map_channel(icn_card *card, int channel) 117{ 118#ifdef MAP_DEBUG 119 printk(KERN_DEBUG "icn_map_channel %d %d\n", dev.channel, channel); 120#endif 121 if ((channel == dev.channel) && (card == dev.mcard)) 122 return; 123 if (dev.mcard) 124 icn_disable_ram(dev.mcard); 125 icn_shiftout(ICN_BANK, chan2bank[channel], 3, 4); /* Select Bank */ 126 icn_enable_ram(card); 127 dev.mcard = card; 128 dev.channel = channel; 129#ifdef MAP_DEBUG 130 printk(KERN_DEBUG "icn_map_channel done\n"); 131#endif 132} 133 134/* 135 * Lock a cards channel. 136 * Return 0 if requested card/channel is unmapped (failure). 137 * Return 1 on success. 138 * 139 * must called with holding the devlock 140 */ 141static inline int 142icn_lock_channel(icn_card *card, int channel) 143{ 144 register int retval; 145 146#ifdef MAP_DEBUG 147 printk(KERN_DEBUG "icn_lock_channel %d\n", channel); 148#endif 149 if ((dev.channel == channel) && (card == dev.mcard)) { 150 dev.chanlock++; 151 retval = 1; 152#ifdef MAP_DEBUG 153 printk(KERN_DEBUG "icn_lock_channel %d OK\n", channel); 154#endif 155 } else { 156 retval = 0; 157#ifdef MAP_DEBUG 158 printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev.channel); 159#endif 160 } 161 return retval; 162} 163 164/* 165 * Release current card/channel lock 166 * 167 * must called with holding the devlock 168 */ 169static inline void 170__icn_release_channel(void) 171{ 172#ifdef MAP_DEBUG 173 printk(KERN_DEBUG "icn_release_channel l=%d\n", dev.chanlock); 174#endif 175 if (dev.chanlock > 0) 176 dev.chanlock--; 177} 178 179/* 180 * Release current card/channel lock 181 */ 182static inline void 183icn_release_channel(void) 184{ 185 ulong flags; 186 187 spin_lock_irqsave(&dev.devlock, flags); 188 __icn_release_channel(); 189 spin_unlock_irqrestore(&dev.devlock, flags); 190} 191 192/* 193 * Try to map and lock a cards channel. 194 * Return 1 on success, 0 on failure. 195 */ 196static inline int 197icn_trymaplock_channel(icn_card *card, int channel) 198{ 199 ulong flags; 200 201#ifdef MAP_DEBUG 202 printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev.channel, 203 dev.chanlock); 204#endif 205 spin_lock_irqsave(&dev.devlock, flags); 206 if ((!dev.chanlock) || 207 ((dev.channel == channel) && (dev.mcard == card))) { 208 dev.chanlock++; 209 icn_map_channel(card, channel); 210 spin_unlock_irqrestore(&dev.devlock, flags); 211#ifdef MAP_DEBUG 212 printk(KERN_DEBUG "trymaplock %d OK\n", channel); 213#endif 214 return 1; 215 } 216 spin_unlock_irqrestore(&dev.devlock, flags); 217#ifdef MAP_DEBUG 218 printk(KERN_DEBUG "trymaplock %d FAILED\n", channel); 219#endif 220 return 0; 221} 222 223/* 224 * Release current card/channel lock, 225 * then map same or other channel without locking. 226 */ 227static inline void 228icn_maprelease_channel(icn_card *card, int channel) 229{ 230 ulong flags; 231 232#ifdef MAP_DEBUG 233 printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev.chanlock); 234#endif 235 spin_lock_irqsave(&dev.devlock, flags); 236 if (dev.chanlock > 0) 237 dev.chanlock--; 238 if (!dev.chanlock) 239 icn_map_channel(card, channel); 240 spin_unlock_irqrestore(&dev.devlock, flags); 241} 242 243/* Get Data from the B-Channel, assemble fragmented packets and put them 244 * into receive-queue. Wake up any B-Channel-reading processes. 245 * This routine is called via timer-callback from icn_pollbchan(). 246 */ 247 248static void 249icn_pollbchan_receive(int channel, icn_card *card) 250{ 251 int mch = channel + ((card->secondhalf) ? 2 : 0); 252 int eflag; 253 int cnt; 254 struct sk_buff *skb; 255 256 if (icn_trymaplock_channel(card, mch)) { 257 while (rbavl) { 258 cnt = readb(&rbuf_l); 259 if ((card->rcvidx[channel] + cnt) > 4000) { 260 printk(KERN_WARNING 261 "icn: (%s) bogus packet on ch%d, dropping.\n", 262 CID, 263 channel + 1); 264 card->rcvidx[channel] = 0; 265 eflag = 0; 266 } else { 267 memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]], 268 &rbuf_d, cnt); 269 card->rcvidx[channel] += cnt; 270 eflag = readb(&rbuf_f); 271 } 272 rbnext; 273 icn_maprelease_channel(card, mch & 2); 274 if (!eflag) { 275 if ((cnt = card->rcvidx[channel])) { 276 if (!(skb = dev_alloc_skb(cnt))) { 277 printk(KERN_WARNING "icn: receive out of memory\n"); 278 break; 279 } 280 memcpy(skb_put(skb, cnt), card->rcvbuf[channel], cnt); 281 card->rcvidx[channel] = 0; 282 card->interface.rcvcallb_skb(card->myid, channel, skb); 283 } 284 } 285 if (!icn_trymaplock_channel(card, mch)) 286 break; 287 } 288 icn_maprelease_channel(card, mch & 2); 289 } 290} 291 292/* Send data-packet to B-Channel, split it up into fragments of 293 * ICN_FRAGSIZE length. If last fragment is sent out, signal 294 * success to upper layers via statcallb with ISDN_STAT_BSENT argument. 295 * This routine is called via timer-callback from icn_pollbchan() or 296 * directly from icn_sendbuf(). 297 */ 298 299static void 300icn_pollbchan_send(int channel, icn_card *card) 301{ 302 int mch = channel + ((card->secondhalf) ? 2 : 0); 303 int cnt; 304 unsigned long flags; 305 struct sk_buff *skb; 306 isdn_ctrl cmd; 307 308 if (!(card->sndcount[channel] || card->xskb[channel] || 309 !skb_queue_empty(&card->spqueue[channel]))) 310 return; 311 if (icn_trymaplock_channel(card, mch)) { 312 while (sbfree && 313 (card->sndcount[channel] || 314 !skb_queue_empty(&card->spqueue[channel]) || 315 card->xskb[channel])) { 316 spin_lock_irqsave(&card->lock, flags); 317 if (card->xmit_lock[channel]) { 318 spin_unlock_irqrestore(&card->lock, flags); 319 break; 320 } 321 card->xmit_lock[channel]++; 322 spin_unlock_irqrestore(&card->lock, flags); 323 skb = card->xskb[channel]; 324 if (!skb) { 325 skb = skb_dequeue(&card->spqueue[channel]); 326 if (skb) { 327 /* Pop ACK-flag off skb. 328 * Store length to xlen. 329 */ 330 if (*(skb_pull(skb, 1))) 331 card->xlen[channel] = skb->len; 332 else 333 card->xlen[channel] = 0; 334 } 335 } 336 if (!skb) 337 break; 338 if (skb->len > ICN_FRAGSIZE) { 339 writeb(0xff, &sbuf_f); 340 cnt = ICN_FRAGSIZE; 341 } else { 342 writeb(0x0, &sbuf_f); 343 cnt = skb->len; 344 } 345 writeb(cnt, &sbuf_l); 346 memcpy_toio(&sbuf_d, skb->data, cnt); 347 skb_pull(skb, cnt); 348 sbnext; /* switch to next buffer */ 349 icn_maprelease_channel(card, mch & 2); 350 spin_lock_irqsave(&card->lock, flags); 351 card->sndcount[channel] -= cnt; 352 if (!skb->len) { 353 if (card->xskb[channel]) 354 card->xskb[channel] = NULL; 355 card->xmit_lock[channel] = 0; 356 spin_unlock_irqrestore(&card->lock, flags); 357 dev_kfree_skb(skb); 358 if (card->xlen[channel]) { 359 cmd.command = ISDN_STAT_BSENT; 360 cmd.driver = card->myid; 361 cmd.arg = channel; 362 cmd.parm.length = card->xlen[channel]; 363 card->interface.statcallb(&cmd); 364 } 365 } else { 366 card->xskb[channel] = skb; 367 card->xmit_lock[channel] = 0; 368 spin_unlock_irqrestore(&card->lock, flags); 369 } 370 if (!icn_trymaplock_channel(card, mch)) 371 break; 372 } 373 icn_maprelease_channel(card, mch & 2); 374 } 375} 376 377/* Send/Receive Data to/from the B-Channel. 378 * This routine is called via timer-callback. 379 * It schedules itself while any B-Channel is open. 380 */ 381 382static void 383icn_pollbchan(unsigned long data) 384{ 385 icn_card *card = (icn_card *) data; 386 unsigned long flags; 387 388 if (card->flags & ICN_FLAGS_B1ACTIVE) { 389 icn_pollbchan_receive(0, card); 390 icn_pollbchan_send(0, card); 391 } 392 if (card->flags & ICN_FLAGS_B2ACTIVE) { 393 icn_pollbchan_receive(1, card); 394 icn_pollbchan_send(1, card); 395 } 396 if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) { 397 /* schedule b-channel polling again */ 398 spin_lock_irqsave(&card->lock, flags); 399 mod_timer(&card->rb_timer, jiffies + ICN_TIMER_BCREAD); 400 card->flags |= ICN_FLAGS_RBTIMER; 401 spin_unlock_irqrestore(&card->lock, flags); 402 } else 403 card->flags &= ~ICN_FLAGS_RBTIMER; 404} 405 406typedef struct icn_stat { 407 char *statstr; 408 int command; 409 int action; 410} icn_stat; 411/* *INDENT-OFF* */ 412static icn_stat icn_stat_table[] = 413{ 414 {"BCON_", ISDN_STAT_BCONN, 1}, /* B-Channel connected */ 415 {"BDIS_", ISDN_STAT_BHUP, 2}, /* B-Channel disconnected */ 416 /* 417 ** add d-channel connect and disconnect support to link-level 418 */ 419 {"DCON_", ISDN_STAT_DCONN, 10}, /* D-Channel connected */ 420 {"DDIS_", ISDN_STAT_DHUP, 11}, /* D-Channel disconnected */ 421 {"DCAL_I", ISDN_STAT_ICALL, 3}, /* Incoming call dialup-line */ 422 {"DSCA_I", ISDN_STAT_ICALL, 3}, /* Incoming call 1TR6-SPV */ 423 {"FCALL", ISDN_STAT_ICALL, 4}, /* Leased line connection up */ 424 {"CIF", ISDN_STAT_CINF, 5}, /* Charge-info, 1TR6-type */ 425 {"AOC", ISDN_STAT_CINF, 6}, /* Charge-info, DSS1-type */ 426 {"CAU", ISDN_STAT_CAUSE, 7}, /* Cause code */ 427 {"TEI OK", ISDN_STAT_RUN, 0}, /* Card connected to wallplug */ 428 {"E_L1: ACT FAIL", ISDN_STAT_BHUP, 8}, /* Layer-1 activation failed */ 429 {"E_L2: DATA LIN", ISDN_STAT_BHUP, 8}, /* Layer-2 data link lost */ 430 {"E_L1: ACTIVATION FAILED", 431 ISDN_STAT_BHUP, 8}, /* Layer-1 activation failed */ 432 {NULL, 0, -1} 433}; 434/* *INDENT-ON* */ 435 436 437/* 438 * Check Statusqueue-Pointer from isdn-cards. 439 * If there are new status-replies from the interface, check 440 * them against B-Channel-connects/disconnects and set flags accordingly. 441 * Wake-Up any processes, who are reading the status-device. 442 * If there are B-Channels open, initiate a timer-callback to 443 * icn_pollbchan(). 444 * This routine is called periodically via timer. 445 */ 446 447static void 448icn_parse_status(u_char *status, int channel, icn_card *card) 449{ 450 icn_stat *s = icn_stat_table; 451 int action = -1; 452 unsigned long flags; 453 isdn_ctrl cmd; 454 455 while (s->statstr) { 456 if (!strncmp(status, s->statstr, strlen(s->statstr))) { 457 cmd.command = s->command; 458 action = s->action; 459 break; 460 } 461 s++; 462 } 463 if (action == -1) 464 return; 465 cmd.driver = card->myid; 466 cmd.arg = channel; 467 switch (action) { 468 case 11: 469 spin_lock_irqsave(&card->lock, flags); 470 icn_free_queue(card, channel); 471 card->rcvidx[channel] = 0; 472 473 if (card->flags & 474 ((channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE)) { 475 476 isdn_ctrl ncmd; 477 478 card->flags &= ~((channel) ? 479 ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE); 480 481 memset(&ncmd, 0, sizeof(ncmd)); 482 483 ncmd.driver = card->myid; 484 ncmd.arg = channel; 485 ncmd.command = ISDN_STAT_BHUP; 486 spin_unlock_irqrestore(&card->lock, flags); 487 card->interface.statcallb(&cmd); 488 } else 489 spin_unlock_irqrestore(&card->lock, flags); 490 break; 491 case 1: 492 spin_lock_irqsave(&card->lock, flags); 493 icn_free_queue(card, channel); 494 card->flags |= (channel) ? 495 ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE; 496 spin_unlock_irqrestore(&card->lock, flags); 497 break; 498 case 2: 499 spin_lock_irqsave(&card->lock, flags); 500 card->flags &= ~((channel) ? 501 ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE); 502 icn_free_queue(card, channel); 503 card->rcvidx[channel] = 0; 504 spin_unlock_irqrestore(&card->lock, flags); 505 break; 506 case 3: 507 { 508 char *t = status + 6; 509 char *s = strchr(t, ','); 510 511 *s++ = '\0'; 512 strlcpy(cmd.parm.setup.phone, t, 513 sizeof(cmd.parm.setup.phone)); 514 s = strchr(t = s, ','); 515 *s++ = '\0'; 516 if (!strlen(t)) 517 cmd.parm.setup.si1 = 0; 518 else 519 cmd.parm.setup.si1 = 520 simple_strtoul(t, NULL, 10); 521 s = strchr(t = s, ','); 522 *s++ = '\0'; 523 if (!strlen(t)) 524 cmd.parm.setup.si2 = 0; 525 else 526 cmd.parm.setup.si2 = 527 simple_strtoul(t, NULL, 10); 528 strlcpy(cmd.parm.setup.eazmsn, s, 529 sizeof(cmd.parm.setup.eazmsn)); 530 } 531 cmd.parm.setup.plan = 0; 532 cmd.parm.setup.screen = 0; 533 break; 534 case 4: 535 sprintf(cmd.parm.setup.phone, "LEASED%d", card->myid); 536 sprintf(cmd.parm.setup.eazmsn, "%d", channel + 1); 537 cmd.parm.setup.si1 = 7; 538 cmd.parm.setup.si2 = 0; 539 cmd.parm.setup.plan = 0; 540 cmd.parm.setup.screen = 0; 541 break; 542 case 5: 543 strlcpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num)); 544 break; 545 case 6: 546 snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%d", 547 (int) simple_strtoul(status + 7, NULL, 16)); 548 break; 549 case 7: 550 status += 3; 551 if (strlen(status) == 4) 552 snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%s%c%c", 553 status + 2, *status, *(status + 1)); 554 else 555 strlcpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num)); 556 break; 557 case 8: 558 spin_lock_irqsave(&card->lock, flags); 559 card->flags &= ~ICN_FLAGS_B1ACTIVE; 560 icn_free_queue(card, 0); 561 card->rcvidx[0] = 0; 562 spin_unlock_irqrestore(&card->lock, flags); 563 cmd.arg = 0; 564 cmd.driver = card->myid; 565 card->interface.statcallb(&cmd); 566 cmd.command = ISDN_STAT_DHUP; 567 cmd.arg = 0; 568 cmd.driver = card->myid; 569 card->interface.statcallb(&cmd); 570 cmd.command = ISDN_STAT_BHUP; 571 spin_lock_irqsave(&card->lock, flags); 572 card->flags &= ~ICN_FLAGS_B2ACTIVE; 573 icn_free_queue(card, 1); 574 card->rcvidx[1] = 0; 575 spin_unlock_irqrestore(&card->lock, flags); 576 cmd.arg = 1; 577 cmd.driver = card->myid; 578 card->interface.statcallb(&cmd); 579 cmd.command = ISDN_STAT_DHUP; 580 cmd.arg = 1; 581 cmd.driver = card->myid; 582 break; 583 } 584 card->interface.statcallb(&cmd); 585 return; 586} 587 588static void 589icn_putmsg(icn_card *card, unsigned char c) 590{ 591 ulong flags; 592 593 spin_lock_irqsave(&card->lock, flags); 594 *card->msg_buf_write++ = (c == 0xff) ? '\n' : c; 595 if (card->msg_buf_write == card->msg_buf_read) { 596 if (++card->msg_buf_read > card->msg_buf_end) 597 card->msg_buf_read = card->msg_buf; 598 } 599 if (card->msg_buf_write > card->msg_buf_end) 600 card->msg_buf_write = card->msg_buf; 601 spin_unlock_irqrestore(&card->lock, flags); 602} 603 604static void 605icn_polldchan(unsigned long data) 606{ 607 icn_card *card = (icn_card *) data; 608 int mch = card->secondhalf ? 2 : 0; 609 int avail = 0; 610 int left; 611 u_char c; 612 int ch; 613 unsigned long flags; 614 int i; 615 u_char *p; 616 isdn_ctrl cmd; 617 618 if (icn_trymaplock_channel(card, mch)) { 619 avail = msg_avail; 620 for (left = avail, i = readb(&msg_o); left > 0; i++, left--) { 621 c = readb(&dev.shmem->comm_buffers.iopc_buf[i & 0xff]); 622 icn_putmsg(card, c); 623 if (c == 0xff) { 624 card->imsg[card->iptr] = 0; 625 card->iptr = 0; 626 if (card->imsg[0] == '0' && card->imsg[1] >= '0' && 627 card->imsg[1] <= '2' && card->imsg[2] == ';') { 628 ch = (card->imsg[1] - '0') - 1; 629 p = &card->imsg[3]; 630 icn_parse_status(p, ch, card); 631 } else { 632 p = card->imsg; 633 if (!strncmp(p, "DRV1.", 5)) { 634 u_char vstr[10]; 635 u_char *q = vstr; 636 637 printk(KERN_INFO "icn: (%s) %s\n", CID, p); 638 if (!strncmp(p + 7, "TC", 2)) { 639 card->ptype = ISDN_PTYPE_1TR6; 640 card->interface.features |= ISDN_FEATURE_P_1TR6; 641 printk(KERN_INFO 642 "icn: (%s) 1TR6-Protocol loaded and running\n", CID); 643 } 644 if (!strncmp(p + 7, "EC", 2)) { 645 card->ptype = ISDN_PTYPE_EURO; 646 card->interface.features |= ISDN_FEATURE_P_EURO; 647 printk(KERN_INFO 648 "icn: (%s) Euro-Protocol loaded and running\n", CID); 649 } 650 p = strstr(card->imsg, "BRV") + 3; 651 while (*p) { 652 if (*p >= '0' && *p <= '9') 653 *q++ = *p; 654 p++; 655 } 656 *q = '\0'; 657 strcat(vstr, "000"); 658 vstr[3] = '\0'; 659 card->fw_rev = (int) simple_strtoul(vstr, NULL, 10); 660 continue; 661 662 } 663 } 664 } else { 665 card->imsg[card->iptr] = c; 666 if (card->iptr < 59) 667 card->iptr++; 668 } 669 } 670 writeb((readb(&msg_o) + avail) & 0xff, &msg_o); 671 icn_release_channel(); 672 } 673 if (avail) { 674 cmd.command = ISDN_STAT_STAVAIL; 675 cmd.driver = card->myid; 676 cmd.arg = avail; 677 card->interface.statcallb(&cmd); 678 } 679 spin_lock_irqsave(&card->lock, flags); 680 if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) 681 if (!(card->flags & ICN_FLAGS_RBTIMER)) { 682 /* schedule b-channel polling */ 683 card->flags |= ICN_FLAGS_RBTIMER; 684 del_timer(&card->rb_timer); 685 card->rb_timer.function = icn_pollbchan; 686 card->rb_timer.data = (unsigned long) card; 687 card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD; 688 add_timer(&card->rb_timer); 689 } 690 /* schedule again */ 691 mod_timer(&card->st_timer, jiffies + ICN_TIMER_DCREAD); 692 spin_unlock_irqrestore(&card->lock, flags); 693} 694 695/* Append a packet to the transmit buffer-queue. 696 * Parameters: 697 * channel = Number of B-channel 698 * skb = pointer to sk_buff 699 * card = pointer to card-struct 700 * Return: 701 * Number of bytes transferred, -E??? on error 702 */ 703 704static int 705icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card *card) 706{ 707 int len = skb->len; 708 unsigned long flags; 709 struct sk_buff *nskb; 710 711 if (len > 4000) { 712 printk(KERN_WARNING 713 "icn: Send packet too large\n"); 714 return -EINVAL; 715 } 716 if (len) { 717 if (!(card->flags & (channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE)) 718 return 0; 719 if (card->sndcount[channel] > ICN_MAX_SQUEUE) 720 return 0; 721#warning TODO test headroom or use skb->nb to flag ACK 722 nskb = skb_clone(skb, GFP_ATOMIC); 723 if (nskb) { 724 /* Push ACK flag as one 725 * byte in front of data. 726 */ 727 *(skb_push(nskb, 1)) = ack ? 1 : 0; 728 skb_queue_tail(&card->spqueue[channel], nskb); 729 dev_kfree_skb(skb); 730 } else 731 len = 0; 732 spin_lock_irqsave(&card->lock, flags); 733 card->sndcount[channel] += len; 734 spin_unlock_irqrestore(&card->lock, flags); 735 } 736 return len; 737} 738 739/* 740 * Check card's status after starting the bootstrap loader. 741 * On entry, the card's shared memory has already to be mapped. 742 * Return: 743 * 0 on success (Boot loader ready) 744 * -EIO on failure (timeout) 745 */ 746static int 747icn_check_loader(int cardnumber) 748{ 749 int timer = 0; 750 751 while (1) { 752#ifdef BOOT_DEBUG 753 printk(KERN_DEBUG "Loader %d ?\n", cardnumber); 754#endif 755 if (readb(&dev.shmem->data_control.scns) || 756 readb(&dev.shmem->data_control.scnr)) { 757 if (timer++ > 5) { 758 printk(KERN_WARNING 759 "icn: Boot-Loader %d timed out.\n", 760 cardnumber); 761 icn_release_channel(); 762 return -EIO; 763 } 764#ifdef BOOT_DEBUG 765 printk(KERN_DEBUG "Loader %d TO?\n", cardnumber); 766#endif 767 msleep_interruptible(ICN_BOOT_TIMEOUT1); 768 } else { 769#ifdef BOOT_DEBUG 770 printk(KERN_DEBUG "Loader %d OK\n", cardnumber); 771#endif 772 icn_release_channel(); 773 return 0; 774 } 775 } 776} 777 778/* Load the boot-code into the interface-card's memory and start it. 779 * Always called from user-process. 780 * 781 * Parameters: 782 * buffer = pointer to packet 783 * Return: 784 * 0 if successfully loaded 785 */ 786 787#ifdef BOOT_DEBUG 788#define SLEEP(sec) { \ 789 int slsec = sec; \ 790 printk(KERN_DEBUG "SLEEP(%d)\n", slsec); \ 791 while (slsec) { \ 792 msleep_interruptible(1000); \ 793 slsec--; \ 794 } \ 795 } 796#else 797#define SLEEP(sec) 798#endif 799 800static int 801icn_loadboot(u_char __user *buffer, icn_card *card) 802{ 803 int ret; 804 u_char *codebuf; 805 unsigned long flags; 806 807#ifdef BOOT_DEBUG 808 printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong) buffer); 809#endif 810 if (!(codebuf = kmalloc(ICN_CODE_STAGE1, GFP_KERNEL))) { 811 printk(KERN_WARNING "icn: Could not allocate code buffer\n"); 812 ret = -ENOMEM; 813 goto out; 814 } 815 if (copy_from_user(codebuf, buffer, ICN_CODE_STAGE1)) { 816 ret = -EFAULT; 817 goto out_kfree; 818 } 819 if (!card->rvalid) { 820 if (!request_region(card->port, ICN_PORTLEN, card->regname)) { 821 printk(KERN_WARNING 822 "icn: (%s) ports 0x%03x-0x%03x in use.\n", 823 CID, 824 card->port, 825 card->port + ICN_PORTLEN); 826 ret = -EBUSY; 827 goto out_kfree; 828 } 829 card->rvalid = 1; 830 if (card->doubleS0) 831 card->other->rvalid = 1; 832 } 833 if (!dev.mvalid) { 834 if (!request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)")) { 835 printk(KERN_WARNING 836 "icn: memory at 0x%08lx in use.\n", dev.memaddr); 837 ret = -EBUSY; 838 goto out_kfree; 839 } 840 dev.shmem = ioremap(dev.memaddr, 0x4000); 841 dev.mvalid = 1; 842 } 843 OUTB_P(0, ICN_RUN); /* Reset Controller */ 844 OUTB_P(0, ICN_MAPRAM); /* Disable RAM */ 845 icn_shiftout(ICN_CFG, 0x0f, 3, 4); /* Windowsize= 16k */ 846 icn_shiftout(ICN_CFG, dev.memaddr, 23, 10); /* Set RAM-Addr. */ 847#ifdef BOOT_DEBUG 848 printk(KERN_DEBUG "shmem=%08lx\n", dev.memaddr); 849#endif 850 SLEEP(1); 851#ifdef BOOT_DEBUG 852 printk(KERN_DEBUG "Map Bank 0\n"); 853#endif 854 spin_lock_irqsave(&dev.devlock, flags); 855 icn_map_channel(card, 0); /* Select Bank 0 */ 856 icn_lock_channel(card, 0); /* Lock Bank 0 */ 857 spin_unlock_irqrestore(&dev.devlock, flags); 858 SLEEP(1); 859 memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */ 860#ifdef BOOT_DEBUG 861 printk(KERN_DEBUG "Bootloader transferred\n"); 862#endif 863 if (card->doubleS0) { 864 SLEEP(1); 865#ifdef BOOT_DEBUG 866 printk(KERN_DEBUG "Map Bank 8\n"); 867#endif 868 spin_lock_irqsave(&dev.devlock, flags); 869 __icn_release_channel(); 870 icn_map_channel(card, 2); /* Select Bank 8 */ 871 icn_lock_channel(card, 2); /* Lock Bank 8 */ 872 spin_unlock_irqrestore(&dev.devlock, flags); 873 SLEEP(1); 874 memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */ 875#ifdef BOOT_DEBUG 876 printk(KERN_DEBUG "Bootloader transferred\n"); 877#endif 878 } 879 SLEEP(1); 880 OUTB_P(0xff, ICN_RUN); /* Start Boot-Code */ 881 if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1))) { 882 goto out_kfree; 883 } 884 if (!card->doubleS0) { 885 ret = 0; 886 goto out_kfree; 887 } 888 /* reached only, if we have a Double-S0-Card */ 889#ifdef BOOT_DEBUG 890 printk(KERN_DEBUG "Map Bank 0\n"); 891#endif 892 spin_lock_irqsave(&dev.devlock, flags); 893 icn_map_channel(card, 0); /* Select Bank 0 */ 894 icn_lock_channel(card, 0); /* Lock Bank 0 */ 895 spin_unlock_irqrestore(&dev.devlock, flags); 896 SLEEP(1); 897 ret = (icn_check_loader(1)); 898 899out_kfree: 900 kfree(codebuf); 901out: 902 return ret; 903} 904 905static int 906icn_loadproto(u_char __user *buffer, icn_card *card) 907{ 908 register u_char __user *p = buffer; 909 u_char codebuf[256]; 910 uint left = ICN_CODE_STAGE2; 911 uint cnt; 912 int timer; 913 unsigned long flags; 914 915#ifdef BOOT_DEBUG 916 printk(KERN_DEBUG "icn_loadproto called\n"); 917#endif 918 if (!access_ok(VERIFY_READ, buffer, ICN_CODE_STAGE2)) 919 return -EFAULT; 920 timer = 0; 921 spin_lock_irqsave(&dev.devlock, flags); 922 if (card->secondhalf) { 923 icn_map_channel(card, 2); 924 icn_lock_channel(card, 2); 925 } else { 926 icn_map_channel(card, 0); 927 icn_lock_channel(card, 0); 928 } 929 spin_unlock_irqrestore(&dev.devlock, flags); 930 while (left) { 931 if (sbfree) { /* If there is a free buffer... */ 932 cnt = left; 933 if (cnt > 256) 934 cnt = 256; 935 if (copy_from_user(codebuf, p, cnt)) { 936 icn_maprelease_channel(card, 0); 937 return -EFAULT; 938 } 939 memcpy_toio(&sbuf_l, codebuf, cnt); /* copy data */ 940 sbnext; /* switch to next buffer */ 941 p += cnt; 942 left -= cnt; 943 timer = 0; 944 } else { 945#ifdef BOOT_DEBUG 946 printk(KERN_DEBUG "boot 2 !sbfree\n"); 947#endif 948 if (timer++ > 5) { 949 icn_maprelease_channel(card, 0); 950 return -EIO; 951 } 952 schedule_timeout_interruptible(10); 953 } 954 } 955 writeb(0x20, &sbuf_n); 956 timer = 0; 957 while (1) { 958 if (readb(&cmd_o) || readb(&cmd_i)) { 959#ifdef BOOT_DEBUG 960 printk(KERN_DEBUG "Proto?\n"); 961#endif 962 if (timer++ > 5) { 963 printk(KERN_WARNING 964 "icn: (%s) Protocol timed out.\n", 965 CID); 966#ifdef BOOT_DEBUG 967 printk(KERN_DEBUG "Proto TO!\n"); 968#endif 969 icn_maprelease_channel(card, 0); 970 return -EIO; 971 } 972#ifdef BOOT_DEBUG 973 printk(KERN_DEBUG "Proto TO?\n"); 974#endif 975 msleep_interruptible(ICN_BOOT_TIMEOUT1); 976 } else { 977 if ((card->secondhalf) || (!card->doubleS0)) { 978#ifdef BOOT_DEBUG 979 printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n", 980 card->secondhalf); 981#endif 982 spin_lock_irqsave(&card->lock, flags); 983 init_timer(&card->st_timer); 984 card->st_timer.expires = jiffies + ICN_TIMER_DCREAD; 985 card->st_timer.function = icn_polldchan; 986 card->st_timer.data = (unsigned long) card; 987 add_timer(&card->st_timer); 988 card->flags |= ICN_FLAGS_RUNNING; 989 if (card->doubleS0) { 990 init_timer(&card->other->st_timer); 991 card->other->st_timer.expires = jiffies + ICN_TIMER_DCREAD; 992 card->other->st_timer.function = icn_polldchan; 993 card->other->st_timer.data = (unsigned long) card->other; 994 add_timer(&card->other->st_timer); 995 card->other->flags |= ICN_FLAGS_RUNNING; 996 } 997 spin_unlock_irqrestore(&card->lock, flags); 998 } 999 icn_maprelease_channel(card, 0); 1000 return 0; 1001 } 1002 } 1003} 1004 1005/* Read the Status-replies from the Interface */ 1006static int 1007icn_readstatus(u_char __user *buf, int len, icn_card *card) 1008{ 1009 int count; 1010 u_char __user *p; 1011 1012 for (p = buf, count = 0; count < len; p++, count++) { 1013 if (card->msg_buf_read == card->msg_buf_write) 1014 return count; 1015 if (put_user(*card->msg_buf_read++, p)) 1016 return -EFAULT; 1017 if (card->msg_buf_read > card->msg_buf_end) 1018 card->msg_buf_read = card->msg_buf; 1019 } 1020 return count; 1021} 1022 1023/* Put command-strings into the command-queue of the Interface */ 1024static int 1025icn_writecmd(const u_char *buf, int len, int user, icn_card *card) 1026{ 1027 int mch = card->secondhalf ? 2 : 0; 1028 int pp; 1029 int i; 1030 int count; 1031 int xcount; 1032 int ocount; 1033 int loop; 1034 unsigned long flags; 1035 int lastmap_channel; 1036 struct icn_card *lastmap_card; 1037 u_char *p; 1038 isdn_ctrl cmd; 1039 u_char msg[0x100]; 1040 1041 ocount = 1; 1042 xcount = loop = 0; 1043 while (len) { 1044 count = cmd_free; 1045 if (count > len) 1046 count = len; 1047 if (user) { 1048 if (copy_from_user(msg, buf, count)) 1049 return -EFAULT; 1050 } else 1051 memcpy(msg, buf, count); 1052 1053 spin_lock_irqsave(&dev.devlock, flags); 1054 lastmap_card = dev.mcard; 1055 lastmap_channel = dev.channel; 1056 icn_map_channel(card, mch); 1057 1058 icn_putmsg(card, '>'); 1059 for (p = msg, pp = readb(&cmd_i), i = count; i > 0; i--, p++, pp 1060 ++) { 1061 writeb((*p == '\n') ? 0xff : *p, 1062 &dev.shmem->comm_buffers.pcio_buf[pp & 0xff]); 1063 len--; 1064 xcount++; 1065 icn_putmsg(card, *p); 1066 if ((*p == '\n') && (i > 1)) { 1067 icn_putmsg(card, '>'); 1068 ocount++; 1069 } 1070 ocount++; 1071 } 1072 writeb((readb(&cmd_i) + count) & 0xff, &cmd_i); 1073 if (lastmap_card) 1074 icn_map_channel(lastmap_card, lastmap_channel); 1075 spin_unlock_irqrestore(&dev.devlock, flags); 1076 if (len) { 1077 mdelay(1); 1078 if (loop++ > 20) 1079 break; 1080 } else 1081 break; 1082 } 1083 if (len && (!user)) 1084 printk(KERN_WARNING "icn: writemsg incomplete!\n"); 1085 cmd.command = ISDN_STAT_STAVAIL; 1086 cmd.driver = card->myid; 1087 cmd.arg = ocount; 1088 card->interface.statcallb(&cmd); 1089 return xcount; 1090} 1091 1092/* 1093 * Delete card's pending timers, send STOP to linklevel 1094 */ 1095static void 1096icn_stopcard(icn_card *card) 1097{ 1098 unsigned long flags; 1099 isdn_ctrl cmd; 1100 1101 spin_lock_irqsave(&card->lock, flags); 1102 if (card->flags & ICN_FLAGS_RUNNING) { 1103 card->flags &= ~ICN_FLAGS_RUNNING; 1104 del_timer(&card->st_timer); 1105 del_timer(&card->rb_timer); 1106 spin_unlock_irqrestore(&card->lock, flags); 1107 cmd.command = ISDN_STAT_STOP; 1108 cmd.driver = card->myid; 1109 card->interface.statcallb(&cmd); 1110 if (card->doubleS0) 1111 icn_stopcard(card->other); 1112 } else 1113 spin_unlock_irqrestore(&card->lock, flags); 1114} 1115 1116static void 1117icn_stopallcards(void) 1118{ 1119 icn_card *p = cards; 1120 1121 while (p) { 1122 icn_stopcard(p); 1123 p = p->next; 1124 } 1125} 1126 1127/* 1128 * Unmap all cards, because some of them may be mapped accidetly during 1129 * autoprobing of some network drivers (SMC-driver?) 1130 */ 1131static void 1132icn_disable_cards(void) 1133{ 1134 icn_card *card = cards; 1135 1136 while (card) { 1137 if (!request_region(card->port, ICN_PORTLEN, "icn-isdn")) { 1138 printk(KERN_WARNING 1139 "icn: (%s) ports 0x%03x-0x%03x in use.\n", 1140 CID, 1141 card->port, 1142 card->port + ICN_PORTLEN); 1143 } else { 1144 OUTB_P(0, ICN_RUN); /* Reset Controller */ 1145 OUTB_P(0, ICN_MAPRAM); /* Disable RAM */ 1146 release_region(card->port, ICN_PORTLEN); 1147 } 1148 card = card->next; 1149 } 1150} 1151 1152static int 1153icn_command(isdn_ctrl *c, icn_card *card) 1154{ 1155 ulong a; 1156 ulong flags; 1157 int i; 1158 char cbuf[80]; 1159 isdn_ctrl cmd; 1160 icn_cdef cdef; 1161 char __user *arg; 1162 1163 switch (c->command) { 1164 case ISDN_CMD_IOCTL: 1165 memcpy(&a, c->parm.num, sizeof(ulong)); 1166 arg = (char __user *)a; 1167 switch (c->arg) { 1168 case ICN_IOCTL_SETMMIO: 1169 if (dev.memaddr != (a & 0x0ffc000)) { 1170 if (!request_mem_region(a & 0x0ffc000, 0x4000, "icn-isdn (all cards)")) { 1171 printk(KERN_WARNING 1172 "icn: memory at 0x%08lx in use.\n", 1173 a & 0x0ffc000); 1174 return -EINVAL; 1175 } 1176 release_mem_region(a & 0x0ffc000, 0x4000); 1177 icn_stopallcards(); 1178 spin_lock_irqsave(&card->lock, flags); 1179 if (dev.mvalid) { 1180 iounmap(dev.shmem); 1181 release_mem_region(dev.memaddr, 0x4000); 1182 } 1183 dev.mvalid = 0; 1184 dev.memaddr = a & 0x0ffc000; 1185 spin_unlock_irqrestore(&card->lock, flags); 1186 printk(KERN_INFO 1187 "icn: (%s) mmio set to 0x%08lx\n", 1188 CID, 1189 dev.memaddr); 1190 } 1191 break; 1192 case ICN_IOCTL_GETMMIO: 1193 return (long) dev.memaddr; 1194 case ICN_IOCTL_SETPORT: 1195 if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330 1196 || a == 0x340 || a == 0x350 || a == 0x360 || 1197 a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338 1198 || a == 0x348 || a == 0x358 || a == 0x368) { 1199 if (card->port != (unsigned short) a) { 1200 if (!request_region((unsigned short) a, ICN_PORTLEN, "icn-isdn")) { 1201 printk(KERN_WARNING 1202 "icn: (%s) ports 0x%03x-0x%03x in use.\n", 1203 CID, (int) a, (int) a + ICN_PORTLEN); 1204 return -EINVAL; 1205 } 1206 release_region((unsigned short) a, ICN_PORTLEN); 1207 icn_stopcard(card); 1208 spin_lock_irqsave(&card->lock, flags); 1209 if (card->rvalid) 1210 release_region(card->port, ICN_PORTLEN); 1211 card->port = (unsigned short) a; 1212 card->rvalid = 0; 1213 if (card->doubleS0) { 1214 card->other->port = (unsigned short) a; 1215 card->other->rvalid = 0; 1216 } 1217 spin_unlock_irqrestore(&card->lock, flags); 1218 printk(KERN_INFO 1219 "icn: (%s) port set to 0x%03x\n", 1220 CID, card->port); 1221 } 1222 } else 1223 return -EINVAL; 1224 break; 1225 case ICN_IOCTL_GETPORT: 1226 return (int) card->port; 1227 case ICN_IOCTL_GETDOUBLE: 1228 return (int) card->doubleS0; 1229 case ICN_IOCTL_DEBUGVAR: 1230 if (copy_to_user(arg, 1231 &card, 1232 sizeof(ulong))) 1233 return -EFAULT; 1234 a += sizeof(ulong); 1235 { 1236 ulong l = (ulong)&dev; 1237 if (copy_to_user(arg, 1238 &l, 1239 sizeof(ulong))) 1240 return -EFAULT; 1241 } 1242 return 0; 1243 case ICN_IOCTL_LOADBOOT: 1244 if (dev.firstload) { 1245 icn_disable_cards(); 1246 dev.firstload = 0; 1247 } 1248 icn_stopcard(card); 1249 return (icn_loadboot(arg, card)); 1250 case ICN_IOCTL_LOADPROTO: 1251 icn_stopcard(card); 1252 if ((i = (icn_loadproto(arg, card)))) 1253 return i; 1254 if (card->doubleS0) 1255 i = icn_loadproto(arg + ICN_CODE_STAGE2, card->other); 1256 return i; 1257 break; 1258 case ICN_IOCTL_ADDCARD: 1259 if (!dev.firstload) 1260 return -EBUSY; 1261 if (copy_from_user(&cdef, 1262 arg, 1263 sizeof(cdef))) 1264 return -EFAULT; 1265 return (icn_addcard(cdef.port, cdef.id1, cdef.id2)); 1266 break; 1267 case ICN_IOCTL_LEASEDCFG: 1268 if (a) { 1269 if (!card->leased) { 1270 card->leased = 1; 1271 while (card->ptype == ISDN_PTYPE_UNKNOWN) { 1272 msleep_interruptible(ICN_BOOT_TIMEOUT1); 1273 } 1274 msleep_interruptible(ICN_BOOT_TIMEOUT1); 1275 sprintf(cbuf, "00;FV2ON\n01;EAZ%c\n02;EAZ%c\n", 1276 (a & 1) ? '1' : 'C', (a & 2) ? '2' : 'C'); 1277 i = icn_writecmd(cbuf, strlen(cbuf), 0, card); 1278 printk(KERN_INFO 1279 "icn: (%s) Leased-line mode enabled\n", 1280 CID); 1281 cmd.command = ISDN_STAT_RUN; 1282 cmd.driver = card->myid; 1283 cmd.arg = 0; 1284 card->interface.statcallb(&cmd); 1285 } 1286 } else { 1287 if (card->leased) { 1288 card->leased = 0; 1289 sprintf(cbuf, "00;FV2OFF\n"); 1290 i = icn_writecmd(cbuf, strlen(cbuf), 0, card); 1291 printk(KERN_INFO 1292 "icn: (%s) Leased-line mode disabled\n", 1293 CID); 1294 cmd.command = ISDN_STAT_RUN; 1295 cmd.driver = card->myid; 1296 cmd.arg = 0; 1297 card->interface.statcallb(&cmd); 1298 } 1299 } 1300 return 0; 1301 default: 1302 return -EINVAL; 1303 } 1304 break; 1305 case ISDN_CMD_DIAL: 1306 if (!(card->flags & ICN_FLAGS_RUNNING)) 1307 return -ENODEV; 1308 if (card->leased) 1309 break; 1310 if ((c->arg & 255) < ICN_BCH) { 1311 char *p; 1312 char dcode[4]; 1313 1314 a = c->arg; 1315 p = c->parm.setup.phone; 1316 if (*p == 's' || *p == 'S') { 1317 /* Dial for SPV */ 1318 p++; 1319 strcpy(dcode, "SCA"); 1320 } else 1321 /* Normal Dial */ 1322 strcpy(dcode, "CAL"); 1323 snprintf(cbuf, sizeof(cbuf), 1324 "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), 1325 dcode, p, c->parm.setup.si1, 1326 c->parm.setup.si2, c->parm.setup.eazmsn); 1327 i = icn_writecmd(cbuf, strlen(cbuf), 0, card); 1328 } 1329 break; 1330 case ISDN_CMD_ACCEPTD: 1331 if (!(card->flags & ICN_FLAGS_RUNNING)) 1332 return -ENODEV; 1333 if (c->arg < ICN_BCH) { 1334 a = c->arg + 1; 1335 if (card->fw_rev >= 300) { 1336 switch (card->l2_proto[a - 1]) { 1337 case ISDN_PROTO_L2_X75I: 1338 sprintf(cbuf, "%02d;BX75\n", (int) a); 1339 break; 1340 case ISDN_PROTO_L2_HDLC: 1341 sprintf(cbuf, "%02d;BTRA\n", (int) a); 1342 break; 1343 } 1344 i = icn_writecmd(cbuf, strlen(cbuf), 0, card); 1345 } 1346 sprintf(cbuf, "%02d;DCON_R\n", (int) a); 1347 i = icn_writecmd(cbuf, strlen(cbuf), 0, card); 1348 } 1349 break; 1350 case ISDN_CMD_ACCEPTB: 1351 if (!(card->flags & ICN_FLAGS_RUNNING)) 1352 return -ENODEV; 1353 if (c->arg < ICN_BCH) { 1354 a = c->arg + 1; 1355 if (card->fw_rev >= 300) 1356 switch (card->l2_proto[a - 1]) { 1357 case ISDN_PROTO_L2_X75I: 1358 sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a); 1359 break; 1360 case ISDN_PROTO_L2_HDLC: 1361 sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a); 1362 break; 1363 } else 1364 sprintf(cbuf, "%02d;BCON_R\n", (int) a); 1365 i = icn_writecmd(cbuf, strlen(cbuf), 0, card); 1366 } 1367 break; 1368 case ISDN_CMD_HANGUP: 1369 if (!(card->flags & ICN_FLAGS_RUNNING)) 1370 return -ENODEV; 1371 if (c->arg < ICN_BCH) { 1372 a = c->arg + 1; 1373 sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a); 1374 i = icn_writecmd(cbuf, strlen(cbuf), 0, card); 1375 } 1376 break; 1377 case ISDN_CMD_SETEAZ: 1378 if (!(card->flags & ICN_FLAGS_RUNNING)) 1379 return -ENODEV; 1380 if (card->leased) 1381 break; 1382 if (c->arg < ICN_BCH) { 1383 a = c->arg + 1; 1384 if (card->ptype == ISDN_PTYPE_EURO) { 1385 sprintf(cbuf, "%02d;MS%s%s\n", (int) a, 1386 c->parm.num[0] ? "N" : "ALL", c->parm.num); 1387 } else 1388 sprintf(cbuf, "%02d;EAZ%s\n", (int) a, 1389 c->parm.num[0] ? (char *)(c->parm.num) : "0123456789"); 1390 i = icn_writecmd(cbuf, strlen(cbuf), 0, card); 1391 } 1392 break; 1393 case ISDN_CMD_CLREAZ: 1394 if (!(card->flags & ICN_FLAGS_RUNNING)) 1395 return -ENODEV; 1396 if (card->leased) 1397 break; 1398 if (c->arg < ICN_BCH) { 1399 a = c->arg + 1; 1400 if (card->ptype == ISDN_PTYPE_EURO) 1401 sprintf(cbuf, "%02d;MSNC\n", (int) a); 1402 else 1403 sprintf(cbuf, "%02d;EAZC\n", (int) a); 1404 i = icn_writecmd(cbuf, strlen(cbuf), 0, card); 1405 } 1406 break; 1407 case ISDN_CMD_SETL2: 1408 if (!(card->flags & ICN_FLAGS_RUNNING)) 1409 return -ENODEV; 1410 if ((c->arg & 255) < ICN_BCH) { 1411 a = c->arg; 1412 switch (a >> 8) { 1413 case ISDN_PROTO_L2_X75I: 1414 sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1); 1415 break; 1416 case ISDN_PROTO_L2_HDLC: 1417 sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1); 1418 break; 1419 default: 1420 return -EINVAL; 1421 } 1422 i = icn_writecmd(cbuf, strlen(cbuf), 0, card); 1423 card->l2_proto[a & 255] = (a >> 8); 1424 } 1425 break; 1426 case ISDN_CMD_SETL3: 1427 if (!(card->flags & ICN_FLAGS_RUNNING)) 1428 return -ENODEV; 1429 return 0; 1430 default: 1431 return -EINVAL; 1432 } 1433 return 0; 1434} 1435 1436/* 1437 * Find card with given driverId 1438 */ 1439static inline icn_card * 1440icn_findcard(int driverid) 1441{ 1442 icn_card *p = cards; 1443 1444 while (p) { 1445 if (p->myid == driverid) 1446 return p; 1447 p = p->next; 1448 } 1449 return (icn_card *) 0; 1450} 1451 1452/* 1453 * Wrapper functions for interface to linklevel 1454 */ 1455static int 1456if_command(isdn_ctrl *c) 1457{ 1458 icn_card *card = icn_findcard(c->driver); 1459 1460 if (card) 1461 return (icn_command(c, card)); 1462 printk(KERN_ERR 1463 "icn: if_command %d called with invalid driverId %d!\n", 1464 c->command, c->driver); 1465 return -ENODEV; 1466} 1467 1468static int 1469if_writecmd(const u_char __user *buf, int len, int id, int channel) 1470{ 1471 icn_card *card = icn_findcard(id); 1472 1473 if (card) { 1474 if (!(card->flags & ICN_FLAGS_RUNNING)) 1475 return -ENODEV; 1476 return (icn_writecmd(buf, len, 1, card)); 1477 } 1478 printk(KERN_ERR 1479 "icn: if_writecmd called with invalid driverId!\n"); 1480 return -ENODEV; 1481} 1482 1483static int 1484if_readstatus(u_char __user *buf, int len, int id, int channel) 1485{ 1486 icn_card *card = icn_findcard(id); 1487 1488 if (card) { 1489 if (!(card->flags & ICN_FLAGS_RUNNING)) 1490 return -ENODEV; 1491 return (icn_readstatus(buf, len, card)); 1492 } 1493 printk(KERN_ERR 1494 "icn: if_readstatus called with invalid driverId!\n"); 1495 return -ENODEV; 1496} 1497 1498static int 1499if_sendbuf(int id, int channel, int ack, struct sk_buff *skb) 1500{ 1501 icn_card *card = icn_findcard(id); 1502 1503 if (card) { 1504 if (!(card->flags & ICN_FLAGS_RUNNING)) 1505 return -ENODEV; 1506 return (icn_sendbuf(channel, ack, skb, card)); 1507 } 1508 printk(KERN_ERR 1509 "icn: if_sendbuf called with invalid driverId!\n"); 1510 return -ENODEV; 1511} 1512 1513/* 1514 * Allocate a new card-struct, initialize it 1515 * link it into cards-list and register it at linklevel. 1516 */ 1517static icn_card * 1518icn_initcard(int port, char *id) 1519{ 1520 icn_card *card; 1521 int i; 1522 1523 if (!(card = kzalloc(sizeof(icn_card), GFP_KERNEL))) { 1524 printk(KERN_WARNING 1525 "icn: (%s) Could not allocate card-struct.\n", id); 1526 return (icn_card *) 0; 1527 } 1528 spin_lock_init(&card->lock); 1529 card->port = port; 1530 card->interface.owner = THIS_MODULE; 1531 card->interface.hl_hdrlen = 1; 1532 card->interface.channels = ICN_BCH; 1533 card->interface.maxbufsize = 4000; 1534 card->interface.command = if_command; 1535 card->interface.writebuf_skb = if_sendbuf; 1536 card->interface.writecmd = if_writecmd; 1537 card->interface.readstat = if_readstatus; 1538 card->interface.features = ISDN_FEATURE_L2_X75I | 1539 ISDN_FEATURE_L2_HDLC | 1540 ISDN_FEATURE_L3_TRANS | 1541 ISDN_FEATURE_P_UNKNOWN; 1542 card->ptype = ISDN_PTYPE_UNKNOWN; 1543 strlcpy(card->interface.id, id, sizeof(card->interface.id)); 1544 card->msg_buf_write = card->msg_buf; 1545 card->msg_buf_read = card->msg_buf; 1546 card->msg_buf_end = &card->msg_buf[sizeof(card->msg_buf) - 1]; 1547 for (i = 0; i < ICN_BCH; i++) { 1548 card->l2_proto[i] = ISDN_PROTO_L2_X75I; 1549 skb_queue_head_init(&card->spqueue[i]); 1550 } 1551 card->next = cards; 1552 cards = card; 1553 if (!register_isdn(&card->interface)) { 1554 cards = cards->next; 1555 printk(KERN_WARNING 1556 "icn: Unable to register %s\n", id); 1557 kfree(card); 1558 return (icn_card *) 0; 1559 } 1560 card->myid = card->interface.channels; 1561 sprintf(card->regname, "icn-isdn (%s)", card->interface.id); 1562 return card; 1563} 1564 1565static int 1566icn_addcard(int port, char *id1, char *id2) 1567{ 1568 icn_card *card; 1569 icn_card *card2; 1570 1571 if (!(card = icn_initcard(port, id1))) { 1572 return -EIO; 1573 } 1574 if (!strlen(id2)) { 1575 printk(KERN_INFO 1576 "icn: (%s) ICN-2B, port 0x%x added\n", 1577 card->interface.id, port); 1578 return 0; 1579 } 1580 if (!(card2 = icn_initcard(port, id2))) { 1581 printk(KERN_INFO 1582 "icn: (%s) half ICN-4B, port 0x%x added\n", id2, port); 1583 return 0; 1584 } 1585 card->doubleS0 = 1; 1586 card->secondhalf = 0; 1587 card->other = card2; 1588 card2->doubleS0 = 1; 1589 card2->secondhalf = 1; 1590 card2->other = card; 1591 printk(KERN_INFO 1592 "icn: (%s and %s) ICN-4B, port 0x%x added\n", 1593 card->interface.id, card2->interface.id, port); 1594 return 0; 1595} 1596 1597#ifndef MODULE 1598static int __init 1599icn_setup(char *line) 1600{ 1601 char *p, *str; 1602 int ints[3]; 1603 static char sid[20]; 1604 static char sid2[20]; 1605 1606 str = get_options(line, 2, ints); 1607 if (ints[0]) 1608 portbase = ints[1]; 1609 if (ints[0] > 1) 1610 membase = (unsigned long)ints[2]; 1611 if (str && *str) { 1612 strlcpy(sid, str, sizeof(sid)); 1613 icn_id = sid; 1614 if ((p = strchr(sid, ','))) { 1615 *p++ = 0; 1616 strcpy(sid2, p); 1617 icn_id2 = sid2; 1618 } 1619 } 1620 return (1); 1621} 1622__setup("icn=", icn_setup); 1623#endif /* MODULE */ 1624 1625static int __init icn_init(void) 1626{ 1627 char *p; 1628 char rev[21]; 1629 1630 memset(&dev, 0, sizeof(icn_dev)); 1631 dev.memaddr = (membase & 0x0ffc000); 1632 dev.channel = -1; 1633 dev.mcard = NULL; 1634 dev.firstload = 1; 1635 spin_lock_init(&dev.devlock); 1636 1637 if ((p = strchr(revision, ':'))) { 1638 strncpy(rev, p + 1, 20); 1639 rev[20] = '\0'; 1640 p = strchr(rev, '$'); 1641 if (p) 1642 *p = 0; 1643 } else 1644 strcpy(rev, " ??? "); 1645 printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev, 1646 dev.memaddr); 1647 return (icn_addcard(portbase, icn_id, icn_id2)); 1648} 1649 1650static void __exit icn_exit(void) 1651{ 1652 isdn_ctrl cmd; 1653 icn_card *card = cards; 1654 icn_card *last, *tmpcard; 1655 int i; 1656 unsigned long flags; 1657 1658 icn_stopallcards(); 1659 while (card) { 1660 cmd.command = ISDN_STAT_UNLOAD; 1661 cmd.driver = card->myid; 1662 card->interface.statcallb(&cmd); 1663 spin_lock_irqsave(&card->lock, flags); 1664 if (card->rvalid) { 1665 OUTB_P(0, ICN_RUN); /* Reset Controller */ 1666 OUTB_P(0, ICN_MAPRAM); /* Disable RAM */ 1667 if (card->secondhalf || (!card->doubleS0)) { 1668 release_region(card->port, ICN_PORTLEN); 1669 card->rvalid = 0; 1670 } 1671 for (i = 0; i < ICN_BCH; i++) 1672 icn_free_queue(card, i); 1673 } 1674 tmpcard = card->next; 1675 spin_unlock_irqrestore(&card->lock, flags); 1676 card = tmpcard; 1677 } 1678 card = cards; 1679 cards = NULL; 1680 while (card) { 1681 last = card; 1682 card = card->next; 1683 kfree(last); 1684 } 1685 if (dev.mvalid) { 1686 iounmap(dev.shmem); 1687 release_mem_region(dev.memaddr, 0x4000); 1688 } 1689 printk(KERN_NOTICE "ICN-ISDN-driver unloaded\n"); 1690} 1691 1692module_init(icn_init); 1693module_exit(icn_exit); 1694