1 /* $Id: kcapi.c,v 1.1.2.8 2004/03/26 19:57:20 armin Exp $ 2 * 3 * Kernel CAPI 2.0 Module 4 * 5 * Copyright 1999 by Carsten Paeth <calle@calle.de> 6 * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name> 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 */ 12 13 #define CONFIG_AVMB1_COMPAT 14 15 #include "kcapi.h" 16 #include <linux/module.h> 17 #include <linux/mm.h> 18 #include <linux/interrupt.h> 19 #include <linux/ioport.h> 20 #include <linux/proc_fs.h> 21 #include <linux/seq_file.h> 22 #include <linux/skbuff.h> 23 #include <linux/workqueue.h> 24 #include <linux/capi.h> 25 #include <linux/kernelcapi.h> 26 #include <linux/init.h> 27 #include <linux/moduleparam.h> 28 #include <linux/delay.h> 29 #include <asm/uaccess.h> 30 #include <linux/isdn/capicmd.h> 31 #include <linux/isdn/capiutil.h> 32 #ifdef CONFIG_AVMB1_COMPAT 33 #include <linux/b1lli.h> 34 #endif 35 #include <linux/mutex.h> 36 37 static char *revision = "$Revision: 1.1.2.8 $"; 38 39 /* ------------------------------------------------------------- */ 40 41 static int showcapimsgs = 0; 42 43 MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer"); 44 MODULE_AUTHOR("Carsten Paeth"); 45 MODULE_LICENSE("GPL"); 46 module_param(showcapimsgs, uint, 0); 47 48 /* ------------------------------------------------------------- */ 49 50 struct capi_notifier { 51 struct work_struct work; 52 unsigned int cmd; 53 u32 controller; 54 u16 applid; 55 u32 ncci; 56 }; 57 58 /* ------------------------------------------------------------- */ 59 60 static struct capi_version driver_version = {2, 0, 1, 1<<4}; 61 static char driver_serial[CAPI_SERIAL_LEN] = "0004711"; 62 static char capi_manufakturer[64] = "AVM Berlin"; 63 64 #define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f) 65 66 LIST_HEAD(capi_drivers); 67 DEFINE_RWLOCK(capi_drivers_list_lock); 68 69 static DEFINE_RWLOCK(application_lock); 70 static DEFINE_MUTEX(controller_mutex); 71 72 struct capi20_appl *capi_applications[CAPI_MAXAPPL]; 73 struct capi_ctr *capi_cards[CAPI_MAXCONTR]; 74 75 static int ncards; 76 77 /* -------- controller ref counting -------------------------------------- */ 78 79 static inline struct capi_ctr * 80 capi_ctr_get(struct capi_ctr *card) 81 { 82 if (!try_module_get(card->owner)) 83 return NULL; 84 return card; 85 } 86 87 static inline void 88 capi_ctr_put(struct capi_ctr *card) 89 { 90 module_put(card->owner); 91 } 92 93 /* ------------------------------------------------------------- */ 94 95 static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) 96 { 97 if (contr - 1 >= CAPI_MAXCONTR) 98 return NULL; 99 100 return capi_cards[contr - 1]; 101 } 102 103 static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) 104 { 105 if (applid - 1 >= CAPI_MAXAPPL) 106 return NULL; 107 108 return capi_applications[applid - 1]; 109 } 110 111 /* -------- util functions ------------------------------------ */ 112 113 static inline int capi_cmd_valid(u8 cmd) 114 { 115 switch (cmd) { 116 case CAPI_ALERT: 117 case CAPI_CONNECT: 118 case CAPI_CONNECT_ACTIVE: 119 case CAPI_CONNECT_B3_ACTIVE: 120 case CAPI_CONNECT_B3: 121 case CAPI_CONNECT_B3_T90_ACTIVE: 122 case CAPI_DATA_B3: 123 case CAPI_DISCONNECT_B3: 124 case CAPI_DISCONNECT: 125 case CAPI_FACILITY: 126 case CAPI_INFO: 127 case CAPI_LISTEN: 128 case CAPI_MANUFACTURER: 129 case CAPI_RESET_B3: 130 case CAPI_SELECT_B_PROTOCOL: 131 return 1; 132 } 133 return 0; 134 } 135 136 static inline int capi_subcmd_valid(u8 subcmd) 137 { 138 switch (subcmd) { 139 case CAPI_REQ: 140 case CAPI_CONF: 141 case CAPI_IND: 142 case CAPI_RESP: 143 return 1; 144 } 145 return 0; 146 } 147 148 /* ------------------------------------------------------------ */ 149 150 static void register_appl(struct capi_ctr *card, u16 applid, capi_register_params *rparam) 151 { 152 card = capi_ctr_get(card); 153 154 if (card) 155 card->register_appl(card, applid, rparam); 156 else 157 printk(KERN_WARNING "%s: cannot get card resources\n", __FUNCTION__); 158 } 159 160 161 static void release_appl(struct capi_ctr *card, u16 applid) 162 { 163 DBG("applid %#x", applid); 164 165 card->release_appl(card, applid); 166 capi_ctr_put(card); 167 } 168 169 /* -------- KCI_CONTRUP --------------------------------------- */ 170 171 static void notify_up(u32 contr) 172 { 173 struct capi_ctr *card = get_capi_ctr_by_nr(contr); 174 struct capi20_appl *ap; 175 u16 applid; 176 177 if (showcapimsgs & 1) { 178 printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr); 179 } 180 if (!card) { 181 printk(KERN_WARNING "%s: invalid contr %d\n", __FUNCTION__, contr); 182 return; 183 } 184 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 185 ap = get_capi_appl_by_nr(applid); 186 if (!ap || ap->release_in_progress) continue; 187 register_appl(card, applid, &ap->rparam); 188 if (ap->callback && !ap->release_in_progress) 189 ap->callback(KCI_CONTRUP, contr, &card->profile); 190 } 191 } 192 193 /* -------- KCI_CONTRDOWN ------------------------------------- */ 194 195 static void notify_down(u32 contr) 196 { 197 struct capi20_appl *ap; 198 u16 applid; 199 200 if (showcapimsgs & 1) { 201 printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr); 202 } 203 204 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 205 ap = get_capi_appl_by_nr(applid); 206 if (ap && ap->callback && !ap->release_in_progress) 207 ap->callback(KCI_CONTRDOWN, contr, NULL); 208 } 209 } 210 211 static void notify_handler(void *data) 212 { 213 struct capi_notifier *np = data; 214 215 switch (np->cmd) { 216 case KCI_CONTRUP: 217 notify_up(np->controller); 218 break; 219 case KCI_CONTRDOWN: 220 notify_down(np->controller); 221 break; 222 } 223 224 kfree(np); 225 } 226 227 /* 228 * The notifier will result in adding/deleteing of devices. Devices can 229 * only removed in user process, not in bh. 230 */ 231 static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci) 232 { 233 struct capi_notifier *np = kmalloc(sizeof(*np), GFP_ATOMIC); 234 235 if (!np) 236 return -ENOMEM; 237 238 INIT_WORK(&np->work, notify_handler, np); 239 np->cmd = cmd; 240 np->controller = controller; 241 np->applid = applid; 242 np->ncci = ncci; 243 244 schedule_work(&np->work); 245 return 0; 246 } 247 248 249 /* -------- Receiver ------------------------------------------ */ 250 251 static void recv_handler(void *_ap) 252 { 253 struct sk_buff *skb; 254 struct capi20_appl *ap = (struct capi20_appl *) _ap; 255 256 if ((!ap) || (ap->release_in_progress)) 257 return; 258 259 down(&ap->recv_sem); 260 while ((skb = skb_dequeue(&ap->recv_queue))) { 261 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_IND) 262 ap->nrecvdatapkt++; 263 else 264 ap->nrecvctlpkt++; 265 266 ap->recv_message(ap, skb); 267 } 268 up(&ap->recv_sem); 269 } 270 271 void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb) 272 { 273 struct capi20_appl *ap; 274 int showctl = 0; 275 u8 cmd, subcmd; 276 unsigned long flags; 277 278 if (card->cardstate != CARD_RUNNING) { 279 printk(KERN_INFO "kcapi: controller %d not active, got: %s", 280 card->cnr, capi_message2str(skb->data)); 281 goto error; 282 } 283 284 cmd = CAPIMSG_COMMAND(skb->data); 285 subcmd = CAPIMSG_SUBCOMMAND(skb->data); 286 if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) { 287 card->nrecvdatapkt++; 288 if (card->traceflag > 2) showctl |= 2; 289 } else { 290 card->nrecvctlpkt++; 291 if (card->traceflag) showctl |= 2; 292 } 293 showctl |= (card->traceflag & 1); 294 if (showctl & 2) { 295 if (showctl & 1) { 296 printk(KERN_DEBUG "kcapi: got [0x%lx] id#%d %s len=%u\n", 297 (unsigned long) card->cnr, 298 CAPIMSG_APPID(skb->data), 299 capi_cmd2str(cmd, subcmd), 300 CAPIMSG_LEN(skb->data)); 301 } else { 302 printk(KERN_DEBUG "kcapi: got [0x%lx] %s\n", 303 (unsigned long) card->cnr, 304 capi_message2str(skb->data)); 305 } 306 307 } 308 309 read_lock_irqsave(&application_lock, flags); 310 ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data)); 311 if ((!ap) || (ap->release_in_progress)) { 312 read_unlock_irqrestore(&application_lock, flags); 313 printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n", 314 CAPIMSG_APPID(skb->data), capi_message2str(skb->data)); 315 goto error; 316 } 317 skb_queue_tail(&ap->recv_queue, skb); 318 schedule_work(&ap->recv_work); 319 read_unlock_irqrestore(&application_lock, flags); 320 321 return; 322 323 error: 324 kfree_skb(skb); 325 } 326 327 EXPORT_SYMBOL(capi_ctr_handle_message); 328 329 void capi_ctr_ready(struct capi_ctr * card) 330 { 331 card->cardstate = CARD_RUNNING; 332 333 printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", 334 card->cnr, card->name); 335 336 notify_push(KCI_CONTRUP, card->cnr, 0, 0); 337 } 338 339 EXPORT_SYMBOL(capi_ctr_ready); 340 341 void capi_ctr_reseted(struct capi_ctr * card) 342 { 343 u16 appl; 344 345 DBG(""); 346 347 if (card->cardstate == CARD_DETECTED) 348 return; 349 350 card->cardstate = CARD_DETECTED; 351 352 memset(card->manu, 0, sizeof(card->manu)); 353 memset(&card->version, 0, sizeof(card->version)); 354 memset(&card->profile, 0, sizeof(card->profile)); 355 memset(card->serial, 0, sizeof(card->serial)); 356 357 for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { 358 struct capi20_appl *ap = get_capi_appl_by_nr(appl); 359 if (!ap || ap->release_in_progress) 360 continue; 361 362 capi_ctr_put(card); 363 } 364 365 printk(KERN_NOTICE "kcapi: card %d down.\n", card->cnr); 366 367 notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); 368 } 369 370 EXPORT_SYMBOL(capi_ctr_reseted); 371 372 void capi_ctr_suspend_output(struct capi_ctr *card) 373 { 374 if (!card->blocked) { 375 printk(KERN_DEBUG "kcapi: card %d suspend\n", card->cnr); 376 card->blocked = 1; 377 } 378 } 379 380 EXPORT_SYMBOL(capi_ctr_suspend_output); 381 382 void capi_ctr_resume_output(struct capi_ctr *card) 383 { 384 if (card->blocked) { 385 printk(KERN_DEBUG "kcapi: card %d resume\n", card->cnr); 386 card->blocked = 0; 387 } 388 } 389 390 EXPORT_SYMBOL(capi_ctr_resume_output); 391 392 /* ------------------------------------------------------------- */ 393 394 int 395 attach_capi_ctr(struct capi_ctr *card) 396 { 397 int i; 398 399 mutex_lock(&controller_mutex); 400 401 for (i = 0; i < CAPI_MAXCONTR; i++) { 402 if (capi_cards[i] == NULL) 403 break; 404 } 405 if (i == CAPI_MAXCONTR) { 406 mutex_unlock(&controller_mutex); 407 printk(KERN_ERR "kcapi: out of controller slots\n"); 408 return -EBUSY; 409 } 410 capi_cards[i] = card; 411 412 mutex_unlock(&controller_mutex); 413 414 card->nrecvctlpkt = 0; 415 card->nrecvdatapkt = 0; 416 card->nsentctlpkt = 0; 417 card->nsentdatapkt = 0; 418 card->cnr = i + 1; 419 card->cardstate = CARD_DETECTED; 420 card->blocked = 0; 421 card->traceflag = showcapimsgs; 422 423 sprintf(card->procfn, "capi/controllers/%d", card->cnr); 424 card->procent = create_proc_entry(card->procfn, 0, NULL); 425 if (card->procent) { 426 card->procent->read_proc = 427 (int (*)(char *,char **,off_t,int,int *,void *)) 428 card->ctr_read_proc; 429 card->procent->data = card; 430 } 431 432 ncards++; 433 printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n", 434 card->cnr, card->name); 435 return 0; 436 } 437 438 EXPORT_SYMBOL(attach_capi_ctr); 439 440 int detach_capi_ctr(struct capi_ctr *card) 441 { 442 if (card->cardstate != CARD_DETECTED) 443 capi_ctr_reseted(card); 444 445 ncards--; 446 447 if (card->procent) { 448 remove_proc_entry(card->procfn, NULL); 449 card->procent = NULL; 450 } 451 capi_cards[card->cnr - 1] = NULL; 452 printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n", 453 card->cnr, card->name); 454 455 return 0; 456 } 457 458 EXPORT_SYMBOL(detach_capi_ctr); 459 460 void register_capi_driver(struct capi_driver *driver) 461 { 462 unsigned long flags; 463 464 write_lock_irqsave(&capi_drivers_list_lock, flags); 465 list_add_tail(&driver->list, &capi_drivers); 466 write_unlock_irqrestore(&capi_drivers_list_lock, flags); 467 } 468 469 EXPORT_SYMBOL(register_capi_driver); 470 471 void unregister_capi_driver(struct capi_driver *driver) 472 { 473 unsigned long flags; 474 475 write_lock_irqsave(&capi_drivers_list_lock, flags); 476 list_del(&driver->list); 477 write_unlock_irqrestore(&capi_drivers_list_lock, flags); 478 } 479 480 EXPORT_SYMBOL(unregister_capi_driver); 481 482 /* ------------------------------------------------------------- */ 483 /* -------- CAPI2.0 Interface ---------------------------------- */ 484 /* ------------------------------------------------------------- */ 485 486 u16 capi20_isinstalled(void) 487 { 488 int i; 489 for (i = 0; i < CAPI_MAXCONTR; i++) { 490 if (capi_cards[i] && capi_cards[i]->cardstate == CARD_RUNNING) 491 return CAPI_NOERROR; 492 } 493 return CAPI_REGNOTINSTALLED; 494 } 495 496 EXPORT_SYMBOL(capi20_isinstalled); 497 498 u16 capi20_register(struct capi20_appl *ap) 499 { 500 int i; 501 u16 applid; 502 unsigned long flags; 503 504 DBG(""); 505 506 if (ap->rparam.datablklen < 128) 507 return CAPI_LOGBLKSIZETOSMALL; 508 509 write_lock_irqsave(&application_lock, flags); 510 511 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 512 if (capi_applications[applid - 1] == NULL) 513 break; 514 } 515 if (applid > CAPI_MAXAPPL) { 516 write_unlock_irqrestore(&application_lock, flags); 517 return CAPI_TOOMANYAPPLS; 518 } 519 520 ap->applid = applid; 521 capi_applications[applid - 1] = ap; 522 523 ap->nrecvctlpkt = 0; 524 ap->nrecvdatapkt = 0; 525 ap->nsentctlpkt = 0; 526 ap->nsentdatapkt = 0; 527 ap->callback = NULL; 528 init_MUTEX(&ap->recv_sem); 529 skb_queue_head_init(&ap->recv_queue); 530 INIT_WORK(&ap->recv_work, recv_handler, (void *)ap); 531 ap->release_in_progress = 0; 532 533 write_unlock_irqrestore(&application_lock, flags); 534 535 mutex_lock(&controller_mutex); 536 for (i = 0; i < CAPI_MAXCONTR; i++) { 537 if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING) 538 continue; 539 register_appl(capi_cards[i], applid, &ap->rparam); 540 } 541 mutex_unlock(&controller_mutex); 542 543 if (showcapimsgs & 1) { 544 printk(KERN_DEBUG "kcapi: appl %d up\n", applid); 545 } 546 547 return CAPI_NOERROR; 548 } 549 550 EXPORT_SYMBOL(capi20_register); 551 552 u16 capi20_release(struct capi20_appl *ap) 553 { 554 int i; 555 unsigned long flags; 556 557 DBG("applid %#x", ap->applid); 558 559 write_lock_irqsave(&application_lock, flags); 560 ap->release_in_progress = 1; 561 capi_applications[ap->applid - 1] = NULL; 562 write_unlock_irqrestore(&application_lock, flags); 563 564 mutex_lock(&controller_mutex); 565 for (i = 0; i < CAPI_MAXCONTR; i++) { 566 if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING) 567 continue; 568 release_appl(capi_cards[i], ap->applid); 569 } 570 mutex_unlock(&controller_mutex); 571 572 flush_scheduled_work(); 573 skb_queue_purge(&ap->recv_queue); 574 575 if (showcapimsgs & 1) { 576 printk(KERN_DEBUG "kcapi: appl %d down\n", ap->applid); 577 } 578 579 return CAPI_NOERROR; 580 } 581 582 EXPORT_SYMBOL(capi20_release); 583 584 u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb) 585 { 586 struct capi_ctr *card; 587 int showctl = 0; 588 u8 cmd, subcmd; 589 590 DBG("applid %#x", ap->applid); 591 592 if (ncards == 0) 593 return CAPI_REGNOTINSTALLED; 594 if ((ap->applid == 0) || ap->release_in_progress) 595 return CAPI_ILLAPPNR; 596 if (skb->len < 12 597 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) 598 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) 599 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; 600 card = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data)); 601 if (!card || card->cardstate != CARD_RUNNING) { 602 card = get_capi_ctr_by_nr(1); // XXX why? 603 if (!card || card->cardstate != CARD_RUNNING) 604 return CAPI_REGNOTINSTALLED; 605 } 606 if (card->blocked) 607 return CAPI_SENDQUEUEFULL; 608 609 cmd = CAPIMSG_COMMAND(skb->data); 610 subcmd = CAPIMSG_SUBCOMMAND(skb->data); 611 612 if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) { 613 card->nsentdatapkt++; 614 ap->nsentdatapkt++; 615 if (card->traceflag > 2) showctl |= 2; 616 } else { 617 card->nsentctlpkt++; 618 ap->nsentctlpkt++; 619 if (card->traceflag) showctl |= 2; 620 } 621 showctl |= (card->traceflag & 1); 622 if (showctl & 2) { 623 if (showctl & 1) { 624 printk(KERN_DEBUG "kcapi: put [%#x] id#%d %s len=%u\n", 625 CAPIMSG_CONTROLLER(skb->data), 626 CAPIMSG_APPID(skb->data), 627 capi_cmd2str(cmd, subcmd), 628 CAPIMSG_LEN(skb->data)); 629 } else { 630 printk(KERN_DEBUG "kcapi: put [%#x] %s\n", 631 CAPIMSG_CONTROLLER(skb->data), 632 capi_message2str(skb->data)); 633 } 634 635 } 636 return card->send_message(card, skb); 637 } 638 639 EXPORT_SYMBOL(capi20_put_message); 640 641 u16 capi20_get_manufacturer(u32 contr, u8 *buf) 642 { 643 struct capi_ctr *card; 644 645 if (contr == 0) { 646 strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); 647 return CAPI_NOERROR; 648 } 649 card = get_capi_ctr_by_nr(contr); 650 if (!card || card->cardstate != CARD_RUNNING) 651 return CAPI_REGNOTINSTALLED; 652 strlcpy(buf, card->manu, CAPI_MANUFACTURER_LEN); 653 return CAPI_NOERROR; 654 } 655 656 EXPORT_SYMBOL(capi20_get_manufacturer); 657 658 u16 capi20_get_version(u32 contr, struct capi_version *verp) 659 { 660 struct capi_ctr *card; 661 662 if (contr == 0) { 663 *verp = driver_version; 664 return CAPI_NOERROR; 665 } 666 card = get_capi_ctr_by_nr(contr); 667 if (!card || card->cardstate != CARD_RUNNING) 668 return CAPI_REGNOTINSTALLED; 669 670 memcpy((void *) verp, &card->version, sizeof(capi_version)); 671 return CAPI_NOERROR; 672 } 673 674 EXPORT_SYMBOL(capi20_get_version); 675 676 u16 capi20_get_serial(u32 contr, u8 *serial) 677 { 678 struct capi_ctr *card; 679 680 if (contr == 0) { 681 strlcpy(serial, driver_serial, CAPI_SERIAL_LEN); 682 return CAPI_NOERROR; 683 } 684 card = get_capi_ctr_by_nr(contr); 685 if (!card || card->cardstate != CARD_RUNNING) 686 return CAPI_REGNOTINSTALLED; 687 688 strlcpy((void *) serial, card->serial, CAPI_SERIAL_LEN); 689 return CAPI_NOERROR; 690 } 691 692 EXPORT_SYMBOL(capi20_get_serial); 693 694 u16 capi20_get_profile(u32 contr, struct capi_profile *profp) 695 { 696 struct capi_ctr *card; 697 698 if (contr == 0) { 699 profp->ncontroller = ncards; 700 return CAPI_NOERROR; 701 } 702 card = get_capi_ctr_by_nr(contr); 703 if (!card || card->cardstate != CARD_RUNNING) 704 return CAPI_REGNOTINSTALLED; 705 706 memcpy((void *) profp, &card->profile, 707 sizeof(struct capi_profile)); 708 return CAPI_NOERROR; 709 } 710 711 EXPORT_SYMBOL(capi20_get_profile); 712 713 #ifdef CONFIG_AVMB1_COMPAT 714 static int old_capi_manufacturer(unsigned int cmd, void __user *data) 715 { 716 avmb1_loadandconfigdef ldef; 717 avmb1_extcarddef cdef; 718 avmb1_resetdef rdef; 719 capicardparams cparams; 720 struct capi_ctr *card; 721 struct capi_driver *driver = NULL; 722 capiloaddata ldata; 723 struct list_head *l; 724 unsigned long flags; 725 int retval; 726 727 switch (cmd) { 728 case AVMB1_ADDCARD: 729 case AVMB1_ADDCARD_WITH_TYPE: 730 if (cmd == AVMB1_ADDCARD) { 731 if ((retval = copy_from_user(&cdef, data, 732 sizeof(avmb1_carddef)))) 733 return retval; 734 cdef.cardtype = AVM_CARDTYPE_B1; 735 } else { 736 if ((retval = copy_from_user(&cdef, data, 737 sizeof(avmb1_extcarddef)))) 738 return retval; 739 } 740 cparams.port = cdef.port; 741 cparams.irq = cdef.irq; 742 cparams.cardnr = cdef.cardnr; 743 744 read_lock_irqsave(&capi_drivers_list_lock, flags); 745 switch (cdef.cardtype) { 746 case AVM_CARDTYPE_B1: 747 list_for_each(l, &capi_drivers) { 748 driver = list_entry(l, struct capi_driver, list); 749 if (strcmp(driver->name, "b1isa") == 0) 750 break; 751 } 752 break; 753 case AVM_CARDTYPE_T1: 754 list_for_each(l, &capi_drivers) { 755 driver = list_entry(l, struct capi_driver, list); 756 if (strcmp(driver->name, "t1isa") == 0) 757 break; 758 } 759 break; 760 default: 761 driver = NULL; 762 break; 763 } 764 if (!driver) { 765 read_unlock_irqrestore(&capi_drivers_list_lock, flags); 766 printk(KERN_ERR "kcapi: driver not loaded.\n"); 767 return -EIO; 768 } 769 if (!driver->add_card) { 770 read_unlock_irqrestore(&capi_drivers_list_lock, flags); 771 printk(KERN_ERR "kcapi: driver has no add card function.\n"); 772 return -EIO; 773 } 774 775 retval = driver->add_card(driver, &cparams); 776 read_unlock_irqrestore(&capi_drivers_list_lock, flags); 777 return retval; 778 779 case AVMB1_LOAD: 780 case AVMB1_LOAD_AND_CONFIG: 781 782 if (cmd == AVMB1_LOAD) { 783 if (copy_from_user(&ldef, data, 784 sizeof(avmb1_loaddef))) 785 return -EFAULT; 786 ldef.t4config.len = 0; 787 ldef.t4config.data = NULL; 788 } else { 789 if (copy_from_user(&ldef, data, 790 sizeof(avmb1_loadandconfigdef))) 791 return -EFAULT; 792 } 793 card = get_capi_ctr_by_nr(ldef.contr); 794 card = capi_ctr_get(card); 795 if (!card) 796 return -ESRCH; 797 if (card->load_firmware == 0) { 798 printk(KERN_DEBUG "kcapi: load: no load function\n"); 799 return -ESRCH; 800 } 801 802 if (ldef.t4file.len <= 0) { 803 printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len); 804 return -EINVAL; 805 } 806 if (ldef.t4file.data == 0) { 807 printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n"); 808 return -EINVAL; 809 } 810 811 ldata.firmware.user = 1; 812 ldata.firmware.data = ldef.t4file.data; 813 ldata.firmware.len = ldef.t4file.len; 814 ldata.configuration.user = 1; 815 ldata.configuration.data = ldef.t4config.data; 816 ldata.configuration.len = ldef.t4config.len; 817 818 if (card->cardstate != CARD_DETECTED) { 819 printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr); 820 return -EBUSY; 821 } 822 card->cardstate = CARD_LOADING; 823 824 retval = card->load_firmware(card, &ldata); 825 826 if (retval) { 827 card->cardstate = CARD_DETECTED; 828 capi_ctr_put(card); 829 return retval; 830 } 831 832 while (card->cardstate != CARD_RUNNING) { 833 834 msleep_interruptible(100); /* 0.1 sec */ 835 836 if (signal_pending(current)) { 837 capi_ctr_put(card); 838 return -EINTR; 839 } 840 } 841 capi_ctr_put(card); 842 return 0; 843 844 case AVMB1_RESETCARD: 845 if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef))) 846 return -EFAULT; 847 card = get_capi_ctr_by_nr(rdef.contr); 848 if (!card) 849 return -ESRCH; 850 851 if (card->cardstate == CARD_DETECTED) 852 return 0; 853 854 card->reset_ctr(card); 855 856 while (card->cardstate > CARD_DETECTED) { 857 858 msleep_interruptible(100); /* 0.1 sec */ 859 860 if (signal_pending(current)) 861 return -EINTR; 862 } 863 return 0; 864 865 } 866 return -EINVAL; 867 } 868 #endif 869 870 int capi20_manufacturer(unsigned int cmd, void __user *data) 871 { 872 struct capi_ctr *card; 873 874 switch (cmd) { 875 #ifdef CONFIG_AVMB1_COMPAT 876 case AVMB1_LOAD: 877 case AVMB1_LOAD_AND_CONFIG: 878 case AVMB1_RESETCARD: 879 case AVMB1_GET_CARDINFO: 880 case AVMB1_REMOVECARD: 881 return old_capi_manufacturer(cmd, data); 882 #endif 883 case KCAPI_CMD_TRACE: 884 { 885 kcapi_flagdef fdef; 886 887 if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef))) 888 return -EFAULT; 889 890 card = get_capi_ctr_by_nr(fdef.contr); 891 if (!card) 892 return -ESRCH; 893 894 card->traceflag = fdef.flag; 895 printk(KERN_INFO "kcapi: contr %d set trace=%d\n", 896 card->cnr, card->traceflag); 897 return 0; 898 } 899 case KCAPI_CMD_ADDCARD: 900 { 901 struct list_head *l; 902 struct capi_driver *driver = NULL; 903 capicardparams cparams; 904 kcapi_carddef cdef; 905 int retval; 906 907 if ((retval = copy_from_user(&cdef, data, sizeof(cdef)))) 908 return retval; 909 910 cparams.port = cdef.port; 911 cparams.irq = cdef.irq; 912 cparams.membase = cdef.membase; 913 cparams.cardnr = cdef.cardnr; 914 cparams.cardtype = 0; 915 cdef.driver[sizeof(cdef.driver)-1] = 0; 916 917 list_for_each(l, &capi_drivers) { 918 driver = list_entry(l, struct capi_driver, list); 919 if (strcmp(driver->name, cdef.driver) == 0) 920 break; 921 } 922 if (driver == 0) { 923 printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n", 924 cdef.driver); 925 return -ESRCH; 926 } 927 928 if (!driver->add_card) { 929 printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver); 930 return -EIO; 931 } 932 933 return driver->add_card(driver, &cparams); 934 } 935 936 default: 937 printk(KERN_ERR "kcapi: manufacturer command %d unknown.\n", 938 cmd); 939 break; 940 941 } 942 return -EINVAL; 943 } 944 945 EXPORT_SYMBOL(capi20_manufacturer); 946 947 /* temporary hack */ 948 void capi20_set_callback(struct capi20_appl *ap, 949 void (*callback) (unsigned int cmd, __u32 contr, void *data)) 950 { 951 ap->callback = callback; 952 } 953 954 EXPORT_SYMBOL(capi20_set_callback); 955 956 /* ------------------------------------------------------------- */ 957 /* -------- Init & Cleanup ------------------------------------- */ 958 /* ------------------------------------------------------------- */ 959 960 /* 961 * init / exit functions 962 */ 963 964 static int __init kcapi_init(void) 965 { 966 char *p; 967 char rev[32]; 968 969 kcapi_proc_init(); 970 971 if ((p = strchr(revision, ':')) != 0 && p[1]) { 972 strlcpy(rev, p + 2, sizeof(rev)); 973 if ((p = strchr(rev, '$')) != 0 && p > rev) 974 *(p-1) = 0; 975 } else 976 strcpy(rev, "1.0"); 977 978 printk(KERN_NOTICE "CAPI Subsystem Rev %s\n", rev); 979 980 return 0; 981 } 982 983 static void __exit kcapi_exit(void) 984 { 985 kcapi_proc_exit(); 986 987 /* make sure all notifiers are finished */ 988 flush_scheduled_work(); 989 } 990 991 module_init(kcapi_init); 992 module_exit(kcapi_exit); 993