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(struct work_struct *work) 212 { 213 struct capi_notifier *np = 214 container_of(work, struct capi_notifier, work); 215 216 switch (np->cmd) { 217 case KCI_CONTRUP: 218 notify_up(np->controller); 219 break; 220 case KCI_CONTRDOWN: 221 notify_down(np->controller); 222 break; 223 } 224 225 kfree(np); 226 } 227 228 /* 229 * The notifier will result in adding/deleteing of devices. Devices can 230 * only removed in user process, not in bh. 231 */ 232 static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci) 233 { 234 struct capi_notifier *np = kmalloc(sizeof(*np), GFP_ATOMIC); 235 236 if (!np) 237 return -ENOMEM; 238 239 INIT_WORK(&np->work, notify_handler); 240 np->cmd = cmd; 241 np->controller = controller; 242 np->applid = applid; 243 np->ncci = ncci; 244 245 schedule_work(&np->work); 246 return 0; 247 } 248 249 250 /* -------- Receiver ------------------------------------------ */ 251 252 static void recv_handler(struct work_struct *work) 253 { 254 struct sk_buff *skb; 255 struct capi20_appl *ap = 256 container_of(work, struct capi20_appl, recv_work); 257 258 if ((!ap) || (ap->release_in_progress)) 259 return; 260 261 down(&ap->recv_sem); 262 while ((skb = skb_dequeue(&ap->recv_queue))) { 263 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_IND) 264 ap->nrecvdatapkt++; 265 else 266 ap->nrecvctlpkt++; 267 268 ap->recv_message(ap, skb); 269 } 270 up(&ap->recv_sem); 271 } 272 273 void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb) 274 { 275 struct capi20_appl *ap; 276 int showctl = 0; 277 u8 cmd, subcmd; 278 unsigned long flags; 279 _cdebbuf *cdb; 280 281 if (card->cardstate != CARD_RUNNING) { 282 cdb = capi_message2str(skb->data); 283 if (cdb) { 284 printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s", 285 card->cnr, cdb->buf); 286 cdebbuf_free(cdb); 287 } else 288 printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n", 289 card->cnr); 290 goto error; 291 } 292 293 cmd = CAPIMSG_COMMAND(skb->data); 294 subcmd = CAPIMSG_SUBCOMMAND(skb->data); 295 if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) { 296 card->nrecvdatapkt++; 297 if (card->traceflag > 2) showctl |= 2; 298 } else { 299 card->nrecvctlpkt++; 300 if (card->traceflag) showctl |= 2; 301 } 302 showctl |= (card->traceflag & 1); 303 if (showctl & 2) { 304 if (showctl & 1) { 305 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n", 306 card->cnr, CAPIMSG_APPID(skb->data), 307 capi_cmd2str(cmd, subcmd), 308 CAPIMSG_LEN(skb->data)); 309 } else { 310 cdb = capi_message2str(skb->data); 311 if (cdb) { 312 printk(KERN_DEBUG "kcapi: got [%03d] %s\n", 313 card->cnr, cdb->buf); 314 cdebbuf_free(cdb); 315 } else 316 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n", 317 card->cnr, CAPIMSG_APPID(skb->data), 318 capi_cmd2str(cmd, subcmd), 319 CAPIMSG_LEN(skb->data)); 320 } 321 322 } 323 324 read_lock_irqsave(&application_lock, flags); 325 ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data)); 326 if ((!ap) || (ap->release_in_progress)) { 327 read_unlock_irqrestore(&application_lock, flags); 328 cdb = capi_message2str(skb->data); 329 if (cdb) { 330 printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n", 331 CAPIMSG_APPID(skb->data), cdb->buf); 332 cdebbuf_free(cdb); 333 } else 334 printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n", 335 CAPIMSG_APPID(skb->data), 336 capi_cmd2str(cmd, subcmd)); 337 goto error; 338 } 339 skb_queue_tail(&ap->recv_queue, skb); 340 schedule_work(&ap->recv_work); 341 read_unlock_irqrestore(&application_lock, flags); 342 343 return; 344 345 error: 346 kfree_skb(skb); 347 } 348 349 EXPORT_SYMBOL(capi_ctr_handle_message); 350 351 void capi_ctr_ready(struct capi_ctr * card) 352 { 353 card->cardstate = CARD_RUNNING; 354 355 printk(KERN_NOTICE "kcapi: card [%03d] \"%s\" ready.\n", 356 card->cnr, card->name); 357 358 notify_push(KCI_CONTRUP, card->cnr, 0, 0); 359 } 360 361 EXPORT_SYMBOL(capi_ctr_ready); 362 363 void capi_ctr_reseted(struct capi_ctr * card) 364 { 365 u16 appl; 366 367 DBG(""); 368 369 if (card->cardstate == CARD_DETECTED) 370 return; 371 372 card->cardstate = CARD_DETECTED; 373 374 memset(card->manu, 0, sizeof(card->manu)); 375 memset(&card->version, 0, sizeof(card->version)); 376 memset(&card->profile, 0, sizeof(card->profile)); 377 memset(card->serial, 0, sizeof(card->serial)); 378 379 for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { 380 struct capi20_appl *ap = get_capi_appl_by_nr(appl); 381 if (!ap || ap->release_in_progress) 382 continue; 383 384 capi_ctr_put(card); 385 } 386 387 printk(KERN_NOTICE "kcapi: card [%03d] down.\n", card->cnr); 388 389 notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); 390 } 391 392 EXPORT_SYMBOL(capi_ctr_reseted); 393 394 void capi_ctr_suspend_output(struct capi_ctr *card) 395 { 396 if (!card->blocked) { 397 printk(KERN_DEBUG "kcapi: card [%03d] suspend\n", card->cnr); 398 card->blocked = 1; 399 } 400 } 401 402 EXPORT_SYMBOL(capi_ctr_suspend_output); 403 404 void capi_ctr_resume_output(struct capi_ctr *card) 405 { 406 if (card->blocked) { 407 printk(KERN_DEBUG "kcapi: card [%03d] resume\n", card->cnr); 408 card->blocked = 0; 409 } 410 } 411 412 EXPORT_SYMBOL(capi_ctr_resume_output); 413 414 /* ------------------------------------------------------------- */ 415 416 int 417 attach_capi_ctr(struct capi_ctr *card) 418 { 419 int i; 420 421 mutex_lock(&controller_mutex); 422 423 for (i = 0; i < CAPI_MAXCONTR; i++) { 424 if (capi_cards[i] == NULL) 425 break; 426 } 427 if (i == CAPI_MAXCONTR) { 428 mutex_unlock(&controller_mutex); 429 printk(KERN_ERR "kcapi: out of controller slots\n"); 430 return -EBUSY; 431 } 432 capi_cards[i] = card; 433 434 mutex_unlock(&controller_mutex); 435 436 card->nrecvctlpkt = 0; 437 card->nrecvdatapkt = 0; 438 card->nsentctlpkt = 0; 439 card->nsentdatapkt = 0; 440 card->cnr = i + 1; 441 card->cardstate = CARD_DETECTED; 442 card->blocked = 0; 443 card->traceflag = showcapimsgs; 444 445 sprintf(card->procfn, "capi/controllers/%d", card->cnr); 446 card->procent = create_proc_entry(card->procfn, 0, NULL); 447 if (card->procent) { 448 card->procent->read_proc = 449 (int (*)(char *,char **,off_t,int,int *,void *)) 450 card->ctr_read_proc; 451 card->procent->data = card; 452 } 453 454 ncards++; 455 printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n", 456 card->cnr, card->name); 457 return 0; 458 } 459 460 EXPORT_SYMBOL(attach_capi_ctr); 461 462 int detach_capi_ctr(struct capi_ctr *card) 463 { 464 if (card->cardstate != CARD_DETECTED) 465 capi_ctr_reseted(card); 466 467 ncards--; 468 469 if (card->procent) { 470 remove_proc_entry(card->procfn, NULL); 471 card->procent = NULL; 472 } 473 capi_cards[card->cnr - 1] = NULL; 474 printk(KERN_NOTICE "kcapi: Controller [%03d]: %s unregistered\n", 475 card->cnr, card->name); 476 477 return 0; 478 } 479 480 EXPORT_SYMBOL(detach_capi_ctr); 481 482 void register_capi_driver(struct capi_driver *driver) 483 { 484 unsigned long flags; 485 486 write_lock_irqsave(&capi_drivers_list_lock, flags); 487 list_add_tail(&driver->list, &capi_drivers); 488 write_unlock_irqrestore(&capi_drivers_list_lock, flags); 489 } 490 491 EXPORT_SYMBOL(register_capi_driver); 492 493 void unregister_capi_driver(struct capi_driver *driver) 494 { 495 unsigned long flags; 496 497 write_lock_irqsave(&capi_drivers_list_lock, flags); 498 list_del(&driver->list); 499 write_unlock_irqrestore(&capi_drivers_list_lock, flags); 500 } 501 502 EXPORT_SYMBOL(unregister_capi_driver); 503 504 /* ------------------------------------------------------------- */ 505 /* -------- CAPI2.0 Interface ---------------------------------- */ 506 /* ------------------------------------------------------------- */ 507 508 u16 capi20_isinstalled(void) 509 { 510 int i; 511 for (i = 0; i < CAPI_MAXCONTR; i++) { 512 if (capi_cards[i] && capi_cards[i]->cardstate == CARD_RUNNING) 513 return CAPI_NOERROR; 514 } 515 return CAPI_REGNOTINSTALLED; 516 } 517 518 EXPORT_SYMBOL(capi20_isinstalled); 519 520 u16 capi20_register(struct capi20_appl *ap) 521 { 522 int i; 523 u16 applid; 524 unsigned long flags; 525 526 DBG(""); 527 528 if (ap->rparam.datablklen < 128) 529 return CAPI_LOGBLKSIZETOSMALL; 530 531 write_lock_irqsave(&application_lock, flags); 532 533 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 534 if (capi_applications[applid - 1] == NULL) 535 break; 536 } 537 if (applid > CAPI_MAXAPPL) { 538 write_unlock_irqrestore(&application_lock, flags); 539 return CAPI_TOOMANYAPPLS; 540 } 541 542 ap->applid = applid; 543 capi_applications[applid - 1] = ap; 544 545 ap->nrecvctlpkt = 0; 546 ap->nrecvdatapkt = 0; 547 ap->nsentctlpkt = 0; 548 ap->nsentdatapkt = 0; 549 ap->callback = NULL; 550 init_MUTEX(&ap->recv_sem); 551 skb_queue_head_init(&ap->recv_queue); 552 INIT_WORK(&ap->recv_work, recv_handler); 553 ap->release_in_progress = 0; 554 555 write_unlock_irqrestore(&application_lock, flags); 556 557 mutex_lock(&controller_mutex); 558 for (i = 0; i < CAPI_MAXCONTR; i++) { 559 if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING) 560 continue; 561 register_appl(capi_cards[i], applid, &ap->rparam); 562 } 563 mutex_unlock(&controller_mutex); 564 565 if (showcapimsgs & 1) { 566 printk(KERN_DEBUG "kcapi: appl %d up\n", applid); 567 } 568 569 return CAPI_NOERROR; 570 } 571 572 EXPORT_SYMBOL(capi20_register); 573 574 u16 capi20_release(struct capi20_appl *ap) 575 { 576 int i; 577 unsigned long flags; 578 579 DBG("applid %#x", ap->applid); 580 581 write_lock_irqsave(&application_lock, flags); 582 ap->release_in_progress = 1; 583 capi_applications[ap->applid - 1] = NULL; 584 write_unlock_irqrestore(&application_lock, flags); 585 586 mutex_lock(&controller_mutex); 587 for (i = 0; i < CAPI_MAXCONTR; i++) { 588 if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING) 589 continue; 590 release_appl(capi_cards[i], ap->applid); 591 } 592 mutex_unlock(&controller_mutex); 593 594 flush_scheduled_work(); 595 skb_queue_purge(&ap->recv_queue); 596 597 if (showcapimsgs & 1) { 598 printk(KERN_DEBUG "kcapi: appl %d down\n", ap->applid); 599 } 600 601 return CAPI_NOERROR; 602 } 603 604 EXPORT_SYMBOL(capi20_release); 605 606 u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb) 607 { 608 struct capi_ctr *card; 609 int showctl = 0; 610 u8 cmd, subcmd; 611 612 DBG("applid %#x", ap->applid); 613 614 if (ncards == 0) 615 return CAPI_REGNOTINSTALLED; 616 if ((ap->applid == 0) || ap->release_in_progress) 617 return CAPI_ILLAPPNR; 618 if (skb->len < 12 619 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) 620 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) 621 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; 622 card = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data)); 623 if (!card || card->cardstate != CARD_RUNNING) { 624 card = get_capi_ctr_by_nr(1); // XXX why? 625 if (!card || card->cardstate != CARD_RUNNING) 626 return CAPI_REGNOTINSTALLED; 627 } 628 if (card->blocked) 629 return CAPI_SENDQUEUEFULL; 630 631 cmd = CAPIMSG_COMMAND(skb->data); 632 subcmd = CAPIMSG_SUBCOMMAND(skb->data); 633 634 if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) { 635 card->nsentdatapkt++; 636 ap->nsentdatapkt++; 637 if (card->traceflag > 2) showctl |= 2; 638 } else { 639 card->nsentctlpkt++; 640 ap->nsentctlpkt++; 641 if (card->traceflag) showctl |= 2; 642 } 643 showctl |= (card->traceflag & 1); 644 if (showctl & 2) { 645 if (showctl & 1) { 646 printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n", 647 CAPIMSG_CONTROLLER(skb->data), 648 CAPIMSG_APPID(skb->data), 649 capi_cmd2str(cmd, subcmd), 650 CAPIMSG_LEN(skb->data)); 651 } else { 652 _cdebbuf *cdb = capi_message2str(skb->data); 653 if (cdb) { 654 printk(KERN_DEBUG "kcapi: put [%03d] %s\n", 655 CAPIMSG_CONTROLLER(skb->data), 656 cdb->buf); 657 cdebbuf_free(cdb); 658 } else 659 printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u cannot trace\n", 660 CAPIMSG_CONTROLLER(skb->data), 661 CAPIMSG_APPID(skb->data), 662 capi_cmd2str(cmd, subcmd), 663 CAPIMSG_LEN(skb->data)); 664 } 665 } 666 return card->send_message(card, skb); 667 } 668 669 EXPORT_SYMBOL(capi20_put_message); 670 671 u16 capi20_get_manufacturer(u32 contr, u8 *buf) 672 { 673 struct capi_ctr *card; 674 675 if (contr == 0) { 676 strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); 677 return CAPI_NOERROR; 678 } 679 card = get_capi_ctr_by_nr(contr); 680 if (!card || card->cardstate != CARD_RUNNING) 681 return CAPI_REGNOTINSTALLED; 682 strlcpy(buf, card->manu, CAPI_MANUFACTURER_LEN); 683 return CAPI_NOERROR; 684 } 685 686 EXPORT_SYMBOL(capi20_get_manufacturer); 687 688 u16 capi20_get_version(u32 contr, struct capi_version *verp) 689 { 690 struct capi_ctr *card; 691 692 if (contr == 0) { 693 *verp = driver_version; 694 return CAPI_NOERROR; 695 } 696 card = get_capi_ctr_by_nr(contr); 697 if (!card || card->cardstate != CARD_RUNNING) 698 return CAPI_REGNOTINSTALLED; 699 700 memcpy((void *) verp, &card->version, sizeof(capi_version)); 701 return CAPI_NOERROR; 702 } 703 704 EXPORT_SYMBOL(capi20_get_version); 705 706 u16 capi20_get_serial(u32 contr, u8 *serial) 707 { 708 struct capi_ctr *card; 709 710 if (contr == 0) { 711 strlcpy(serial, driver_serial, CAPI_SERIAL_LEN); 712 return CAPI_NOERROR; 713 } 714 card = get_capi_ctr_by_nr(contr); 715 if (!card || card->cardstate != CARD_RUNNING) 716 return CAPI_REGNOTINSTALLED; 717 718 strlcpy((void *) serial, card->serial, CAPI_SERIAL_LEN); 719 return CAPI_NOERROR; 720 } 721 722 EXPORT_SYMBOL(capi20_get_serial); 723 724 u16 capi20_get_profile(u32 contr, struct capi_profile *profp) 725 { 726 struct capi_ctr *card; 727 728 if (contr == 0) { 729 profp->ncontroller = ncards; 730 return CAPI_NOERROR; 731 } 732 card = get_capi_ctr_by_nr(contr); 733 if (!card || card->cardstate != CARD_RUNNING) 734 return CAPI_REGNOTINSTALLED; 735 736 memcpy((void *) profp, &card->profile, 737 sizeof(struct capi_profile)); 738 return CAPI_NOERROR; 739 } 740 741 EXPORT_SYMBOL(capi20_get_profile); 742 743 #ifdef CONFIG_AVMB1_COMPAT 744 static int old_capi_manufacturer(unsigned int cmd, void __user *data) 745 { 746 avmb1_loadandconfigdef ldef; 747 avmb1_extcarddef cdef; 748 avmb1_resetdef rdef; 749 capicardparams cparams; 750 struct capi_ctr *card; 751 struct capi_driver *driver = NULL; 752 capiloaddata ldata; 753 struct list_head *l; 754 unsigned long flags; 755 int retval; 756 757 switch (cmd) { 758 case AVMB1_ADDCARD: 759 case AVMB1_ADDCARD_WITH_TYPE: 760 if (cmd == AVMB1_ADDCARD) { 761 if ((retval = copy_from_user(&cdef, data, 762 sizeof(avmb1_carddef)))) 763 return retval; 764 cdef.cardtype = AVM_CARDTYPE_B1; 765 } else { 766 if ((retval = copy_from_user(&cdef, data, 767 sizeof(avmb1_extcarddef)))) 768 return retval; 769 } 770 cparams.port = cdef.port; 771 cparams.irq = cdef.irq; 772 cparams.cardnr = cdef.cardnr; 773 774 read_lock_irqsave(&capi_drivers_list_lock, flags); 775 switch (cdef.cardtype) { 776 case AVM_CARDTYPE_B1: 777 list_for_each(l, &capi_drivers) { 778 driver = list_entry(l, struct capi_driver, list); 779 if (strcmp(driver->name, "b1isa") == 0) 780 break; 781 } 782 break; 783 case AVM_CARDTYPE_T1: 784 list_for_each(l, &capi_drivers) { 785 driver = list_entry(l, struct capi_driver, list); 786 if (strcmp(driver->name, "t1isa") == 0) 787 break; 788 } 789 break; 790 default: 791 driver = NULL; 792 break; 793 } 794 if (!driver) { 795 read_unlock_irqrestore(&capi_drivers_list_lock, flags); 796 printk(KERN_ERR "kcapi: driver not loaded.\n"); 797 return -EIO; 798 } 799 if (!driver->add_card) { 800 read_unlock_irqrestore(&capi_drivers_list_lock, flags); 801 printk(KERN_ERR "kcapi: driver has no add card function.\n"); 802 return -EIO; 803 } 804 805 retval = driver->add_card(driver, &cparams); 806 read_unlock_irqrestore(&capi_drivers_list_lock, flags); 807 return retval; 808 809 case AVMB1_LOAD: 810 case AVMB1_LOAD_AND_CONFIG: 811 812 if (cmd == AVMB1_LOAD) { 813 if (copy_from_user(&ldef, data, 814 sizeof(avmb1_loaddef))) 815 return -EFAULT; 816 ldef.t4config.len = 0; 817 ldef.t4config.data = NULL; 818 } else { 819 if (copy_from_user(&ldef, data, 820 sizeof(avmb1_loadandconfigdef))) 821 return -EFAULT; 822 } 823 card = get_capi_ctr_by_nr(ldef.contr); 824 card = capi_ctr_get(card); 825 if (!card) 826 return -ESRCH; 827 if (card->load_firmware == 0) { 828 printk(KERN_DEBUG "kcapi: load: no load function\n"); 829 return -ESRCH; 830 } 831 832 if (ldef.t4file.len <= 0) { 833 printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len); 834 return -EINVAL; 835 } 836 if (ldef.t4file.data == 0) { 837 printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n"); 838 return -EINVAL; 839 } 840 841 ldata.firmware.user = 1; 842 ldata.firmware.data = ldef.t4file.data; 843 ldata.firmware.len = ldef.t4file.len; 844 ldata.configuration.user = 1; 845 ldata.configuration.data = ldef.t4config.data; 846 ldata.configuration.len = ldef.t4config.len; 847 848 if (card->cardstate != CARD_DETECTED) { 849 printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr); 850 return -EBUSY; 851 } 852 card->cardstate = CARD_LOADING; 853 854 retval = card->load_firmware(card, &ldata); 855 856 if (retval) { 857 card->cardstate = CARD_DETECTED; 858 capi_ctr_put(card); 859 return retval; 860 } 861 862 while (card->cardstate != CARD_RUNNING) { 863 864 msleep_interruptible(100); /* 0.1 sec */ 865 866 if (signal_pending(current)) { 867 capi_ctr_put(card); 868 return -EINTR; 869 } 870 } 871 capi_ctr_put(card); 872 return 0; 873 874 case AVMB1_RESETCARD: 875 if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef))) 876 return -EFAULT; 877 card = get_capi_ctr_by_nr(rdef.contr); 878 if (!card) 879 return -ESRCH; 880 881 if (card->cardstate == CARD_DETECTED) 882 return 0; 883 884 card->reset_ctr(card); 885 886 while (card->cardstate > CARD_DETECTED) { 887 888 msleep_interruptible(100); /* 0.1 sec */ 889 890 if (signal_pending(current)) 891 return -EINTR; 892 } 893 return 0; 894 895 } 896 return -EINVAL; 897 } 898 #endif 899 900 int capi20_manufacturer(unsigned int cmd, void __user *data) 901 { 902 struct capi_ctr *card; 903 904 switch (cmd) { 905 #ifdef CONFIG_AVMB1_COMPAT 906 case AVMB1_LOAD: 907 case AVMB1_LOAD_AND_CONFIG: 908 case AVMB1_RESETCARD: 909 case AVMB1_GET_CARDINFO: 910 case AVMB1_REMOVECARD: 911 return old_capi_manufacturer(cmd, data); 912 #endif 913 case KCAPI_CMD_TRACE: 914 { 915 kcapi_flagdef fdef; 916 917 if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef))) 918 return -EFAULT; 919 920 card = get_capi_ctr_by_nr(fdef.contr); 921 if (!card) 922 return -ESRCH; 923 924 card->traceflag = fdef.flag; 925 printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n", 926 card->cnr, card->traceflag); 927 return 0; 928 } 929 case KCAPI_CMD_ADDCARD: 930 { 931 struct list_head *l; 932 struct capi_driver *driver = NULL; 933 capicardparams cparams; 934 kcapi_carddef cdef; 935 int retval; 936 937 if ((retval = copy_from_user(&cdef, data, sizeof(cdef)))) 938 return retval; 939 940 cparams.port = cdef.port; 941 cparams.irq = cdef.irq; 942 cparams.membase = cdef.membase; 943 cparams.cardnr = cdef.cardnr; 944 cparams.cardtype = 0; 945 cdef.driver[sizeof(cdef.driver)-1] = 0; 946 947 list_for_each(l, &capi_drivers) { 948 driver = list_entry(l, struct capi_driver, list); 949 if (strcmp(driver->name, cdef.driver) == 0) 950 break; 951 } 952 if (driver == 0) { 953 printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n", 954 cdef.driver); 955 return -ESRCH; 956 } 957 958 if (!driver->add_card) { 959 printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver); 960 return -EIO; 961 } 962 963 return driver->add_card(driver, &cparams); 964 } 965 966 default: 967 printk(KERN_ERR "kcapi: manufacturer command %d unknown.\n", 968 cmd); 969 break; 970 971 } 972 return -EINVAL; 973 } 974 975 EXPORT_SYMBOL(capi20_manufacturer); 976 977 /* temporary hack */ 978 void capi20_set_callback(struct capi20_appl *ap, 979 void (*callback) (unsigned int cmd, __u32 contr, void *data)) 980 { 981 ap->callback = callback; 982 } 983 984 EXPORT_SYMBOL(capi20_set_callback); 985 986 /* ------------------------------------------------------------- */ 987 /* -------- Init & Cleanup ------------------------------------- */ 988 /* ------------------------------------------------------------- */ 989 990 /* 991 * init / exit functions 992 */ 993 994 static int __init kcapi_init(void) 995 { 996 char *p; 997 char rev[32]; 998 int ret; 999 1000 ret = cdebug_init(); 1001 if (ret) 1002 return ret; 1003 kcapi_proc_init(); 1004 1005 if ((p = strchr(revision, ':')) != 0 && p[1]) { 1006 strlcpy(rev, p + 2, sizeof(rev)); 1007 if ((p = strchr(rev, '$')) != 0 && p > rev) 1008 *(p-1) = 0; 1009 } else 1010 strcpy(rev, "1.0"); 1011 1012 printk(KERN_NOTICE "CAPI Subsystem Rev %s\n", rev); 1013 1014 return 0; 1015 } 1016 1017 static void __exit kcapi_exit(void) 1018 { 1019 kcapi_proc_exit(); 1020 1021 /* make sure all notifiers are finished */ 1022 flush_scheduled_work(); 1023 cdebug_exit(); 1024 } 1025 1026 module_init(kcapi_init); 1027 module_exit(kcapi_exit); 1028