at v2.6.13 808 lines 22 kB view raw
1/* $Id: module.c,v 1.14.6.4 2001/09/23 22:24:32 kai Exp $ 2 * 3 * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. 4 * 5 * Author Fritz Elfert 6 * Copyright by Fritz Elfert <fritz@isdn4linux.de> 7 * 8 * This software may be used and distributed according to the terms 9 * of the GNU General Public License, incorporated herein by reference. 10 * 11 * Thanks to Friedemann Baitinger and IBM Germany 12 * 13 */ 14 15#include "act2000.h" 16#include "act2000_isa.h" 17#include "capi.h" 18#include <linux/module.h> 19#include <linux/init.h> 20 21static unsigned short act2000_isa_ports[] = 22{ 23 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380, 24 0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60, 25}; 26#define ISA_NRPORTS (sizeof(act2000_isa_ports)/sizeof(unsigned short)) 27 28static act2000_card *cards = (act2000_card *) NULL; 29 30/* Parameters to be set by insmod */ 31static int act_bus = 0; 32static int act_port = -1; /* -1 = Autoprobe */ 33static int act_irq = -1; 34static char *act_id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 35 36MODULE_DESCRIPTION( "ISDN4Linux: Driver for IBM Active 2000 ISDN card"); 37MODULE_AUTHOR( "Fritz Elfert"); 38MODULE_LICENSE( "GPL"); 39MODULE_PARM_DESC(act_bus, "BusType of first card, 1=ISA, 2=MCA, 3=PCMCIA, currently only ISA"); 40MODULE_PARM_DESC(membase, "Base port address of first card"); 41MODULE_PARM_DESC(act_irq, "IRQ of first card"); 42MODULE_PARM_DESC(act_id, "ID-String of first card"); 43module_param(act_bus, int, 0); 44module_param(act_port, int, 0); 45module_param(act_irq, int, 0); 46module_param(act_id, charp, 0); 47 48static int act2000_addcard(int, int, int, char *); 49 50static act2000_chan * 51find_channel(act2000_card *card, int channel) 52{ 53 if ((channel >= 0) && (channel < ACT2000_BCH)) 54 return &(card->bch[channel]); 55 printk(KERN_WARNING "act2000: Invalid channel %d\n", channel); 56 return NULL; 57} 58 59/* 60 * Free MSN list 61 */ 62static void 63act2000_clear_msn(act2000_card *card) 64{ 65 struct msn_entry *p = card->msn_list; 66 struct msn_entry *q; 67 unsigned long flags; 68 69 spin_lock_irqsave(&card->lock, flags); 70 card->msn_list = NULL; 71 spin_unlock_irqrestore(&card->lock, flags); 72 while (p) { 73 q = p->next; 74 kfree(p); 75 p = q; 76 } 77} 78 79/* 80 * Find an MSN entry in the list. 81 * If ia5 != 0, return IA5-encoded EAZ, else 82 * return a bitmask with corresponding bit set. 83 */ 84static __u16 85act2000_find_msn(act2000_card *card, char *msn, int ia5) 86{ 87 struct msn_entry *p = card->msn_list; 88 __u8 eaz = '0'; 89 90 while (p) { 91 if (!strcmp(p->msn, msn)) { 92 eaz = p->eaz; 93 break; 94 } 95 p = p->next; 96 } 97 if (!ia5) 98 return (1 << (eaz - '0')); 99 else 100 return eaz; 101} 102 103/* 104 * Find an EAZ entry in the list. 105 * return a string with corresponding msn. 106 */ 107char * 108act2000_find_eaz(act2000_card *card, char eaz) 109{ 110 struct msn_entry *p = card->msn_list; 111 112 while (p) { 113 if (p->eaz == eaz) 114 return(p->msn); 115 p = p->next; 116 } 117 return("\0"); 118} 119 120/* 121 * Add or delete an MSN to the MSN list 122 * 123 * First character of msneaz is EAZ, rest is MSN. 124 * If length of eazmsn is 1, delete that entry. 125 */ 126static int 127act2000_set_msn(act2000_card *card, char *eazmsn) 128{ 129 struct msn_entry *p = card->msn_list; 130 struct msn_entry *q = NULL; 131 unsigned long flags; 132 int i; 133 134 if (!strlen(eazmsn)) 135 return 0; 136 if (strlen(eazmsn) > 16) 137 return -EINVAL; 138 for (i = 0; i < strlen(eazmsn); i++) 139 if (!isdigit(eazmsn[i])) 140 return -EINVAL; 141 if (strlen(eazmsn) == 1) { 142 /* Delete a single MSN */ 143 while (p) { 144 if (p->eaz == eazmsn[0]) { 145 spin_lock_irqsave(&card->lock, flags); 146 if (q) 147 q->next = p->next; 148 else 149 card->msn_list = p->next; 150 spin_unlock_irqrestore(&card->lock, flags); 151 kfree(p); 152 printk(KERN_DEBUG 153 "Mapping for EAZ %c deleted\n", 154 eazmsn[0]); 155 return 0; 156 } 157 q = p; 158 p = p->next; 159 } 160 return 0; 161 } 162 /* Add a single MSN */ 163 while (p) { 164 /* Found in list, replace MSN */ 165 if (p->eaz == eazmsn[0]) { 166 spin_lock_irqsave(&card->lock, flags); 167 strcpy(p->msn, &eazmsn[1]); 168 spin_unlock_irqrestore(&card->lock, flags); 169 printk(KERN_DEBUG 170 "Mapping for EAZ %c changed to %s\n", 171 eazmsn[0], 172 &eazmsn[1]); 173 return 0; 174 } 175 p = p->next; 176 } 177 /* Not found in list, add new entry */ 178 p = kmalloc(sizeof(msn_entry), GFP_KERNEL); 179 if (!p) 180 return -ENOMEM; 181 p->eaz = eazmsn[0]; 182 strcpy(p->msn, &eazmsn[1]); 183 p->next = card->msn_list; 184 spin_lock_irqsave(&card->lock, flags); 185 card->msn_list = p; 186 spin_unlock_irqrestore(&card->lock, flags); 187 printk(KERN_DEBUG 188 "Mapping %c -> %s added\n", 189 eazmsn[0], 190 &eazmsn[1]); 191 return 0; 192} 193 194static void 195act2000_transmit(struct act2000_card *card) 196{ 197 switch (card->bus) { 198 case ACT2000_BUS_ISA: 199 act2000_isa_send(card); 200 break; 201 case ACT2000_BUS_PCMCIA: 202 case ACT2000_BUS_MCA: 203 default: 204 printk(KERN_WARNING 205 "act2000_transmit: Illegal bustype %d\n", card->bus); 206 } 207} 208 209static void 210act2000_receive(struct act2000_card *card) 211{ 212 switch (card->bus) { 213 case ACT2000_BUS_ISA: 214 act2000_isa_receive(card); 215 break; 216 case ACT2000_BUS_PCMCIA: 217 case ACT2000_BUS_MCA: 218 default: 219 printk(KERN_WARNING 220 "act2000_receive: Illegal bustype %d\n", card->bus); 221 } 222} 223 224static void 225act2000_poll(unsigned long data) 226{ 227 act2000_card * card = (act2000_card *)data; 228 unsigned long flags; 229 230 act2000_receive(card); 231 spin_lock_irqsave(&card->lock, flags); 232 mod_timer(&card->ptimer, jiffies+3); 233 spin_unlock_irqrestore(&card->lock, flags); 234} 235 236static int 237act2000_command(act2000_card * card, isdn_ctrl * c) 238{ 239 ulong a; 240 act2000_chan *chan; 241 act2000_cdef cdef; 242 isdn_ctrl cmd; 243 char tmp[17]; 244 int ret; 245 unsigned long flags; 246 void __user *arg; 247 248 switch (c->command) { 249 case ISDN_CMD_IOCTL: 250 memcpy(&a, c->parm.num, sizeof(ulong)); 251 arg = (void __user *)a; 252 switch (c->arg) { 253 case ACT2000_IOCTL_LOADBOOT: 254 switch (card->bus) { 255 case ACT2000_BUS_ISA: 256 ret = act2000_isa_download(card, 257 arg); 258 if (!ret) { 259 card->flags |= ACT2000_FLAGS_LOADED; 260 if (!(card->flags & ACT2000_FLAGS_IVALID)) { 261 card->ptimer.expires = jiffies + 3; 262 card->ptimer.function = act2000_poll; 263 card->ptimer.data = (unsigned long)card; 264 add_timer(&card->ptimer); 265 } 266 actcapi_manufacturer_req_errh(card); 267 } 268 break; 269 default: 270 printk(KERN_WARNING 271 "act2000: Illegal BUS type %d\n", 272 card->bus); 273 ret = -EIO; 274 } 275 return ret; 276 case ACT2000_IOCTL_SETPROTO: 277 card->ptype = a?ISDN_PTYPE_EURO:ISDN_PTYPE_1TR6; 278 if (!(card->flags & ACT2000_FLAGS_RUNNING)) 279 return 0; 280 actcapi_manufacturer_req_net(card); 281 return 0; 282 case ACT2000_IOCTL_SETMSN: 283 if (copy_from_user(tmp, arg, 284 sizeof(tmp))) 285 return -EFAULT; 286 if ((ret = act2000_set_msn(card, tmp))) 287 return ret; 288 if (card->flags & ACT2000_FLAGS_RUNNING) 289 return(actcapi_manufacturer_req_msn(card)); 290 return 0; 291 case ACT2000_IOCTL_ADDCARD: 292 if (copy_from_user(&cdef, arg, 293 sizeof(cdef))) 294 return -EFAULT; 295 if (act2000_addcard(cdef.bus, cdef.port, cdef.irq, cdef.id)) 296 return -EIO; 297 return 0; 298 case ACT2000_IOCTL_TEST: 299 if (!(card->flags & ACT2000_FLAGS_RUNNING)) 300 return -ENODEV; 301 return 0; 302 default: 303 return -EINVAL; 304 } 305 break; 306 case ISDN_CMD_DIAL: 307 if (!card->flags & ACT2000_FLAGS_RUNNING) 308 return -ENODEV; 309 if (!(chan = find_channel(card, c->arg & 0x0f))) 310 break; 311 spin_lock_irqsave(&card->lock, flags); 312 if (chan->fsm_state != ACT2000_STATE_NULL) { 313 spin_unlock_irqrestore(&card->lock, flags); 314 printk(KERN_WARNING "Dial on channel with state %d\n", 315 chan->fsm_state); 316 return -EBUSY; 317 } 318 if (card->ptype == ISDN_PTYPE_EURO) 319 tmp[0] = act2000_find_msn(card, c->parm.setup.eazmsn, 1); 320 else 321 tmp[0] = c->parm.setup.eazmsn[0]; 322 chan->fsm_state = ACT2000_STATE_OCALL; 323 chan->callref = 0xffff; 324 spin_unlock_irqrestore(&card->lock, flags); 325 ret = actcapi_connect_req(card, chan, c->parm.setup.phone, 326 tmp[0], c->parm.setup.si1, 327 c->parm.setup.si2); 328 if (ret) { 329 cmd.driver = card->myid; 330 cmd.command = ISDN_STAT_DHUP; 331 cmd.arg &= 0x0f; 332 card->interface.statcallb(&cmd); 333 } 334 return ret; 335 case ISDN_CMD_ACCEPTD: 336 if (!card->flags & ACT2000_FLAGS_RUNNING) 337 return -ENODEV; 338 if (!(chan = find_channel(card, c->arg & 0x0f))) 339 break; 340 if (chan->fsm_state == ACT2000_STATE_ICALL) 341 actcapi_select_b2_protocol_req(card, chan); 342 return 0; 343 case ISDN_CMD_ACCEPTB: 344 if (!card->flags & ACT2000_FLAGS_RUNNING) 345 return -ENODEV; 346 return 0; 347 case ISDN_CMD_HANGUP: 348 if (!card->flags & ACT2000_FLAGS_RUNNING) 349 return -ENODEV; 350 if (!(chan = find_channel(card, c->arg & 0x0f))) 351 break; 352 switch (chan->fsm_state) { 353 case ACT2000_STATE_ICALL: 354 case ACT2000_STATE_BSETUP: 355 actcapi_connect_resp(card, chan, 0x15); 356 break; 357 case ACT2000_STATE_ACTIVE: 358 actcapi_disconnect_b3_req(card, chan); 359 break; 360 } 361 return 0; 362 case ISDN_CMD_SETEAZ: 363 if (!card->flags & ACT2000_FLAGS_RUNNING) 364 return -ENODEV; 365 if (!(chan = find_channel(card, c->arg & 0x0f))) 366 break; 367 if (strlen(c->parm.num)) { 368 if (card->ptype == ISDN_PTYPE_EURO) { 369 chan->eazmask = act2000_find_msn(card, c->parm.num, 0); 370 } 371 if (card->ptype == ISDN_PTYPE_1TR6) { 372 int i; 373 chan->eazmask = 0; 374 for (i = 0; i < strlen(c->parm.num); i++) 375 if (isdigit(c->parm.num[i])) 376 chan->eazmask |= (1 << (c->parm.num[i] - '0')); 377 } 378 } else 379 chan->eazmask = 0x3ff; 380 actcapi_listen_req(card); 381 return 0; 382 case ISDN_CMD_CLREAZ: 383 if (!card->flags & ACT2000_FLAGS_RUNNING) 384 return -ENODEV; 385 if (!(chan = find_channel(card, c->arg & 0x0f))) 386 break; 387 chan->eazmask = 0; 388 actcapi_listen_req(card); 389 return 0; 390 case ISDN_CMD_SETL2: 391 if (!card->flags & ACT2000_FLAGS_RUNNING) 392 return -ENODEV; 393 if (!(chan = find_channel(card, c->arg & 0x0f))) 394 break; 395 chan->l2prot = (c->arg >> 8); 396 return 0; 397 case ISDN_CMD_SETL3: 398 if (!card->flags & ACT2000_FLAGS_RUNNING) 399 return -ENODEV; 400 if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) { 401 printk(KERN_WARNING "L3 protocol unknown\n"); 402 return -1; 403 } 404 if (!(chan = find_channel(card, c->arg & 0x0f))) 405 break; 406 chan->l3prot = (c->arg >> 8); 407 return 0; 408 } 409 410 return -EINVAL; 411} 412 413static int 414act2000_sendbuf(act2000_card *card, int channel, int ack, struct sk_buff *skb) 415{ 416 struct sk_buff *xmit_skb; 417 int len; 418 act2000_chan *chan; 419 actcapi_msg *msg; 420 421 if (!(chan = find_channel(card, channel))) 422 return -1; 423 if (chan->fsm_state != ACT2000_STATE_ACTIVE) 424 return -1; 425 len = skb->len; 426 if ((chan->queued + len) >= ACT2000_MAX_QUEUED) 427 return 0; 428 if (!len) 429 return 0; 430 if (skb_headroom(skb) < 19) { 431 printk(KERN_WARNING "act2000_sendbuf: Headroom only %d\n", 432 skb_headroom(skb)); 433 xmit_skb = alloc_skb(len + 19, GFP_ATOMIC); 434 if (!xmit_skb) { 435 printk(KERN_WARNING "act2000_sendbuf: Out of memory\n"); 436 return 0; 437 } 438 skb_reserve(xmit_skb, 19); 439 memcpy(skb_put(xmit_skb, len), skb->data, len); 440 } else { 441 xmit_skb = skb_clone(skb, GFP_ATOMIC); 442 if (!xmit_skb) { 443 printk(KERN_WARNING "act2000_sendbuf: Out of memory\n"); 444 return 0; 445 } 446 } 447 dev_kfree_skb(skb); 448 msg = (actcapi_msg *)skb_push(xmit_skb, 19); 449 msg->hdr.len = 19 + len; 450 msg->hdr.applicationID = 1; 451 msg->hdr.cmd.cmd = 0x86; 452 msg->hdr.cmd.subcmd = 0x00; 453 msg->hdr.msgnum = actcapi_nextsmsg(card); 454 msg->msg.data_b3_req.datalen = len; 455 msg->msg.data_b3_req.blocknr = (msg->hdr.msgnum & 0xff); 456 msg->msg.data_b3_req.fakencci = MAKE_NCCI(chan->plci, 0, chan->ncci); 457 msg->msg.data_b3_req.flags = ack; /* Will be set to 0 on actual sending */ 458 actcapi_debug_msg(xmit_skb, 1); 459 chan->queued += len; 460 skb_queue_tail(&card->sndq, xmit_skb); 461 act2000_schedule_tx(card); 462 return len; 463} 464 465 466/* Read the Status-replies from the Interface */ 467static int 468act2000_readstatus(u_char __user * buf, int len, act2000_card * card) 469{ 470 int count; 471 u_char __user *p; 472 473 for (p = buf, count = 0; count < len; p++, count++) { 474 if (card->status_buf_read == card->status_buf_write) 475 return count; 476 put_user(*card->status_buf_read++, p); 477 if (card->status_buf_read > card->status_buf_end) 478 card->status_buf_read = card->status_buf; 479 } 480 return count; 481} 482 483/* 484 * Find card with given driverId 485 */ 486static inline act2000_card * 487act2000_findcard(int driverid) 488{ 489 act2000_card *p = cards; 490 491 while (p) { 492 if (p->myid == driverid) 493 return p; 494 p = p->next; 495 } 496 return (act2000_card *) 0; 497} 498 499/* 500 * Wrapper functions for interface to linklevel 501 */ 502static int 503if_command(isdn_ctrl * c) 504{ 505 act2000_card *card = act2000_findcard(c->driver); 506 507 if (card) 508 return (act2000_command(card, c)); 509 printk(KERN_ERR 510 "act2000: if_command %d called with invalid driverId %d!\n", 511 c->command, c->driver); 512 return -ENODEV; 513} 514 515static int 516if_writecmd(const u_char __user *buf, int len, int id, int channel) 517{ 518 act2000_card *card = act2000_findcard(id); 519 520 if (card) { 521 if (!card->flags & ACT2000_FLAGS_RUNNING) 522 return -ENODEV; 523 return (len); 524 } 525 printk(KERN_ERR 526 "act2000: if_writecmd called with invalid driverId!\n"); 527 return -ENODEV; 528} 529 530static int 531if_readstatus(u_char __user * buf, int len, int id, int channel) 532{ 533 act2000_card *card = act2000_findcard(id); 534 535 if (card) { 536 if (!card->flags & ACT2000_FLAGS_RUNNING) 537 return -ENODEV; 538 return (act2000_readstatus(buf, len, card)); 539 } 540 printk(KERN_ERR 541 "act2000: if_readstatus called with invalid driverId!\n"); 542 return -ENODEV; 543} 544 545static int 546if_sendbuf(int id, int channel, int ack, struct sk_buff *skb) 547{ 548 act2000_card *card = act2000_findcard(id); 549 550 if (card) { 551 if (!card->flags & ACT2000_FLAGS_RUNNING) 552 return -ENODEV; 553 return (act2000_sendbuf(card, channel, ack, skb)); 554 } 555 printk(KERN_ERR 556 "act2000: if_sendbuf called with invalid driverId!\n"); 557 return -ENODEV; 558} 559 560 561/* 562 * Allocate a new card-struct, initialize it 563 * link it into cards-list. 564 */ 565static void 566act2000_alloccard(int bus, int port, int irq, char *id) 567{ 568 int i; 569 act2000_card *card; 570 if (!(card = (act2000_card *) kmalloc(sizeof(act2000_card), GFP_KERNEL))) { 571 printk(KERN_WARNING 572 "act2000: (%s) Could not allocate card-struct.\n", id); 573 return; 574 } 575 memset((char *) card, 0, sizeof(act2000_card)); 576 spin_lock_init(&card->lock); 577 spin_lock_init(&card->mnlock); 578 skb_queue_head_init(&card->sndq); 579 skb_queue_head_init(&card->rcvq); 580 skb_queue_head_init(&card->ackq); 581 INIT_WORK(&card->snd_tq, (void *) (void *) act2000_transmit, card); 582 INIT_WORK(&card->rcv_tq, (void *) (void *) actcapi_dispatch, card); 583 INIT_WORK(&card->poll_tq, (void *) (void *) act2000_receive, card); 584 init_timer(&card->ptimer); 585 card->interface.owner = THIS_MODULE; 586 card->interface.channels = ACT2000_BCH; 587 card->interface.maxbufsize = 4000; 588 card->interface.command = if_command; 589 card->interface.writebuf_skb = if_sendbuf; 590 card->interface.writecmd = if_writecmd; 591 card->interface.readstat = if_readstatus; 592 card->interface.features = 593 ISDN_FEATURE_L2_X75I | 594 ISDN_FEATURE_L2_HDLC | 595 ISDN_FEATURE_L3_TRANS | 596 ISDN_FEATURE_P_UNKNOWN; 597 card->interface.hl_hdrlen = 20; 598 card->ptype = ISDN_PTYPE_EURO; 599 strlcpy(card->interface.id, id, sizeof(card->interface.id)); 600 for (i=0; i<ACT2000_BCH; i++) { 601 card->bch[i].plci = 0x8000; 602 card->bch[i].ncci = 0x8000; 603 card->bch[i].l2prot = ISDN_PROTO_L2_X75I; 604 card->bch[i].l3prot = ISDN_PROTO_L3_TRANS; 605 } 606 card->myid = -1; 607 card->bus = bus; 608 card->port = port; 609 card->irq = irq; 610 card->next = cards; 611 cards = card; 612} 613 614/* 615 * register card at linklevel 616 */ 617static int 618act2000_registercard(act2000_card * card) 619{ 620 switch (card->bus) { 621 case ACT2000_BUS_ISA: 622 break; 623 case ACT2000_BUS_MCA: 624 case ACT2000_BUS_PCMCIA: 625 default: 626 printk(KERN_WARNING 627 "act2000: Illegal BUS type %d\n", 628 card->bus); 629 return -1; 630 } 631 if (!register_isdn(&card->interface)) { 632 printk(KERN_WARNING 633 "act2000: Unable to register %s\n", 634 card->interface.id); 635 return -1; 636 } 637 card->myid = card->interface.channels; 638 sprintf(card->regname, "act2000-isdn (%s)", card->interface.id); 639 return 0; 640} 641 642static void 643unregister_card(act2000_card * card) 644{ 645 isdn_ctrl cmd; 646 647 cmd.command = ISDN_STAT_UNLOAD; 648 cmd.driver = card->myid; 649 card->interface.statcallb(&cmd); 650 switch (card->bus) { 651 case ACT2000_BUS_ISA: 652 act2000_isa_release(card); 653 break; 654 case ACT2000_BUS_MCA: 655 case ACT2000_BUS_PCMCIA: 656 default: 657 printk(KERN_WARNING 658 "act2000: Invalid BUS type %d\n", 659 card->bus); 660 break; 661 } 662} 663 664static int 665act2000_addcard(int bus, int port, int irq, char *id) 666{ 667 act2000_card *p; 668 act2000_card *q = NULL; 669 int initialized; 670 int added = 0; 671 int failed = 0; 672 int i; 673 674 if (!bus) 675 bus = ACT2000_BUS_ISA; 676 if (port != -1) { 677 /* Port defined, do fixed setup */ 678 act2000_alloccard(bus, port, irq, id); 679 } else { 680 /* No port defined, perform autoprobing. 681 * This may result in more than one card detected. 682 */ 683 switch (bus) { 684 case ACT2000_BUS_ISA: 685 for (i = 0; i < ISA_NRPORTS; i++) 686 if (act2000_isa_detect(act2000_isa_ports[i])) { 687 printk(KERN_INFO 688 "act2000: Detected ISA card at port 0x%x\n", 689 act2000_isa_ports[i]); 690 act2000_alloccard(bus, act2000_isa_ports[i], irq, id); 691 } 692 break; 693 case ACT2000_BUS_MCA: 694 case ACT2000_BUS_PCMCIA: 695 default: 696 printk(KERN_WARNING 697 "act2000: addcard: Invalid BUS type %d\n", 698 bus); 699 } 700 } 701 if (!cards) 702 return 1; 703 p = cards; 704 while (p) { 705 initialized = 0; 706 if (!p->interface.statcallb) { 707 /* Not yet registered. 708 * Try to register and activate it. 709 */ 710 added++; 711 switch (p->bus) { 712 case ACT2000_BUS_ISA: 713 if (act2000_isa_detect(p->port)) { 714 if (act2000_registercard(p)) 715 break; 716 if (act2000_isa_config_port(p, p->port)) { 717 printk(KERN_WARNING 718 "act2000: Could not request port 0x%04x\n", 719 p->port); 720 unregister_card(p); 721 p->interface.statcallb = NULL; 722 break; 723 } 724 if (act2000_isa_config_irq(p, p->irq)) { 725 printk(KERN_INFO 726 "act2000: No IRQ available, fallback to polling\n"); 727 /* Fall back to polled operation */ 728 p->irq = 0; 729 } 730 printk(KERN_INFO 731 "act2000: ISA" 732 "-type card at port " 733 "0x%04x ", 734 p->port); 735 if (p->irq) 736 printk("irq %d\n", p->irq); 737 else 738 printk("polled\n"); 739 initialized = 1; 740 } 741 break; 742 case ACT2000_BUS_MCA: 743 case ACT2000_BUS_PCMCIA: 744 default: 745 printk(KERN_WARNING 746 "act2000: addcard: Invalid BUS type %d\n", 747 p->bus); 748 } 749 } else 750 /* Card already initialized */ 751 initialized = 1; 752 if (initialized) { 753 /* Init OK, next card ... */ 754 q = p; 755 p = p->next; 756 } else { 757 /* Init failed, remove card from list, free memory */ 758 printk(KERN_WARNING 759 "act2000: Initialization of %s failed\n", 760 p->interface.id); 761 if (q) { 762 q->next = p->next; 763 kfree(p); 764 p = q->next; 765 } else { 766 cards = p->next; 767 kfree(p); 768 p = cards; 769 } 770 failed++; 771 } 772 } 773 return (added - failed); 774} 775 776#define DRIVERNAME "IBM Active 2000 ISDN driver" 777 778static int __init act2000_init(void) 779{ 780 printk(KERN_INFO "%s\n", DRIVERNAME); 781 if (!cards) 782 act2000_addcard(act_bus, act_port, act_irq, act_id); 783 if (!cards) 784 printk(KERN_INFO "act2000: No cards defined yet\n"); 785 return 0; 786} 787 788static void __exit act2000_exit(void) 789{ 790 act2000_card *card = cards; 791 act2000_card *last; 792 while (card) { 793 unregister_card(card); 794 del_timer(&card->ptimer); 795 card = card->next; 796 } 797 card = cards; 798 while (card) { 799 last = card; 800 card = card->next; 801 act2000_clear_msn(last); 802 kfree(last); 803 } 804 printk(KERN_INFO "%s unloaded\n", DRIVERNAME); 805} 806 807module_init(act2000_init); 808module_exit(act2000_exit);