kcapi.c (ef69bb2ec6036945da1d3d3f07b75253f484f693) | kcapi.c (0ca3a017a7373a4545dd7b345a8a0cecc16bc7e2) |
---|---|
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 --- 47 unchanged lines hidden (view full) --- 56static char driver_serial[CAPI_SERIAL_LEN] = "0004711"; 57static char capi_manufakturer[64] = "AVM Berlin"; 58 59#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f) 60 61LIST_HEAD(capi_drivers); 62DEFINE_MUTEX(capi_drivers_lock); 63 | 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 --- 47 unchanged lines hidden (view full) --- 56static char driver_serial[CAPI_SERIAL_LEN] = "0004711"; 57static char capi_manufakturer[64] = "AVM Berlin"; 58 59#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f) 60 61LIST_HEAD(capi_drivers); 62DEFINE_MUTEX(capi_drivers_lock); 63 |
64struct capi_ctr *capi_controller[CAPI_MAXCONTR]; 65DEFINE_MUTEX(capi_controller_lock); 66 |
|
64static DEFINE_RWLOCK(application_lock); | 67static DEFINE_RWLOCK(application_lock); |
65static DEFINE_MUTEX(controller_mutex); | |
66 67struct capi20_appl *capi_applications[CAPI_MAXAPPL]; | 68 69struct capi20_appl *capi_applications[CAPI_MAXAPPL]; |
68struct capi_ctr *capi_controller[CAPI_MAXCONTR]; | |
69 70static int ncontrollers; 71 72static BLOCKING_NOTIFIER_HEAD(ctr_notifier_list); 73 74/* -------- controller ref counting -------------------------------------- */ 75 76static inline struct capi_ctr * --- 89 unchanged lines hidden (view full) --- 166} 167 168static void notify_up(u32 contr) 169{ 170 struct capi20_appl *ap; 171 struct capi_ctr *ctr; 172 u16 applid; 173 | 70 71static int ncontrollers; 72 73static BLOCKING_NOTIFIER_HEAD(ctr_notifier_list); 74 75/* -------- controller ref counting -------------------------------------- */ 76 77static inline struct capi_ctr * --- 89 unchanged lines hidden (view full) --- 167} 168 169static void notify_up(u32 contr) 170{ 171 struct capi20_appl *ap; 172 struct capi_ctr *ctr; 173 u16 applid; 174 |
175 mutex_lock(&capi_controller_lock); 176 |
|
174 if (showcapimsgs & 1) 175 printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr); 176 177 ctr = get_capi_ctr_by_nr(contr); 178 if (ctr) { 179 if (ctr->state == CAPI_CTR_RUNNING) | 177 if (showcapimsgs & 1) 178 printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr); 179 180 ctr = get_capi_ctr_by_nr(contr); 181 if (ctr) { 182 if (ctr->state == CAPI_CTR_RUNNING) |
180 return; | 183 goto unlock_out; |
181 182 ctr->state = CAPI_CTR_RUNNING; 183 184 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 185 ap = get_capi_appl_by_nr(applid); 186 if (!ap || ap->release_in_progress) 187 continue; 188 register_appl(ctr, applid, &ap->rparam); 189 } | 184 185 ctr->state = CAPI_CTR_RUNNING; 186 187 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 188 ap = get_capi_appl_by_nr(applid); 189 if (!ap || ap->release_in_progress) 190 continue; 191 register_appl(ctr, applid, &ap->rparam); 192 } |
193 194 wake_up_interruptible_all(&ctr->state_wait_queue); |
|
190 } else 191 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr); | 195 } else 196 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr); |
197 198unlock_out: 199 mutex_unlock(&capi_controller_lock); |
|
192} 193 | 200} 201 |
194static void ctr_down(struct capi_ctr *ctr) | 202static void ctr_down(struct capi_ctr *ctr, int new_state) |
195{ 196 struct capi20_appl *ap; 197 u16 applid; 198 | 203{ 204 struct capi20_appl *ap; 205 u16 applid; 206 |
199 if (ctr->state == CAPI_CTR_DETECTED) | 207 if (ctr->state == CAPI_CTR_DETECTED || ctr->state == CAPI_CTR_DETACHED) |
200 return; 201 | 208 return; 209 |
202 ctr->state = CAPI_CTR_DETECTED; | 210 ctr->state = new_state; |
203 204 memset(ctr->manu, 0, sizeof(ctr->manu)); 205 memset(&ctr->version, 0, sizeof(ctr->version)); 206 memset(&ctr->profile, 0, sizeof(ctr->profile)); 207 memset(ctr->serial, 0, sizeof(ctr->serial)); 208 209 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 210 ap = get_capi_appl_by_nr(applid); 211 if (ap && !ap->release_in_progress) 212 capi_ctr_put(ctr); 213 } | 211 212 memset(ctr->manu, 0, sizeof(ctr->manu)); 213 memset(&ctr->version, 0, sizeof(ctr->version)); 214 memset(&ctr->profile, 0, sizeof(ctr->profile)); 215 memset(ctr->serial, 0, sizeof(ctr->serial)); 216 217 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 218 ap = get_capi_appl_by_nr(applid); 219 if (ap && !ap->release_in_progress) 220 capi_ctr_put(ctr); 221 } |
222 223 wake_up_interruptible_all(&ctr->state_wait_queue); |
|
214} 215 216static void notify_down(u32 contr) 217{ 218 struct capi_ctr *ctr; 219 | 224} 225 226static void notify_down(u32 contr) 227{ 228 struct capi_ctr *ctr; 229 |
230 mutex_lock(&capi_controller_lock); 231 |
|
220 if (showcapimsgs & 1) 221 printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr); 222 223 ctr = get_capi_ctr_by_nr(contr); 224 if (ctr) | 232 if (showcapimsgs & 1) 233 printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr); 234 235 ctr = get_capi_ctr_by_nr(contr); 236 if (ctr) |
225 ctr_down(ctr); | 237 ctr_down(ctr, CAPI_CTR_DETECTED); |
226 else 227 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr); | 238 else 239 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr); |
240 241 mutex_unlock(&capi_controller_lock); |
|
228} 229 230static int 231notify_handler(struct notifier_block *nb, unsigned long val, void *v) 232{ 233 u32 contr = (long)v; 234 235 switch (val) { --- 195 unchanged lines hidden (view full) --- 431 432EXPORT_SYMBOL(capi_ctr_down); 433 434/** 435 * capi_ctr_suspend_output() - suspend controller 436 * @ctr: controller descriptor structure. 437 * 438 * Called by hardware driver to stop data flow. | 242} 243 244static int 245notify_handler(struct notifier_block *nb, unsigned long val, void *v) 246{ 247 u32 contr = (long)v; 248 249 switch (val) { --- 195 unchanged lines hidden (view full) --- 445 446EXPORT_SYMBOL(capi_ctr_down); 447 448/** 449 * capi_ctr_suspend_output() - suspend controller 450 * @ctr: controller descriptor structure. 451 * 452 * Called by hardware driver to stop data flow. |
453 * 454 * Note: The caller is responsible for synchronizing concurrent state changes 455 * as well as invocations of capi_ctr_handle_message. |
|
439 */ 440 441void capi_ctr_suspend_output(struct capi_ctr *ctr) 442{ 443 if (!ctr->blocked) { 444 printk(KERN_DEBUG "kcapi: controller [%03d] suspend\n", 445 ctr->cnr); 446 ctr->blocked = 1; 447 } 448} 449 450EXPORT_SYMBOL(capi_ctr_suspend_output); 451 452/** 453 * capi_ctr_resume_output() - resume controller 454 * @ctr: controller descriptor structure. 455 * 456 * Called by hardware driver to resume data flow. | 456 */ 457 458void capi_ctr_suspend_output(struct capi_ctr *ctr) 459{ 460 if (!ctr->blocked) { 461 printk(KERN_DEBUG "kcapi: controller [%03d] suspend\n", 462 ctr->cnr); 463 ctr->blocked = 1; 464 } 465} 466 467EXPORT_SYMBOL(capi_ctr_suspend_output); 468 469/** 470 * capi_ctr_resume_output() - resume controller 471 * @ctr: controller descriptor structure. 472 * 473 * Called by hardware driver to resume data flow. |
474 * 475 * Note: The caller is responsible for synchronizing concurrent state changes 476 * as well as invocations of capi_ctr_handle_message. |
|
457 */ 458 459void capi_ctr_resume_output(struct capi_ctr *ctr) 460{ 461 if (ctr->blocked) { 462 printk(KERN_DEBUG "kcapi: controller [%03d] resumed\n", 463 ctr->cnr); 464 ctr->blocked = 0; --- 11 unchanged lines hidden (view full) --- 476 * Called by hardware driver to register a controller with the CAPI subsystem. 477 * Return value: 0 on success, error code < 0 on error 478 */ 479 480int attach_capi_ctr(struct capi_ctr *ctr) 481{ 482 int i; 483 | 477 */ 478 479void capi_ctr_resume_output(struct capi_ctr *ctr) 480{ 481 if (ctr->blocked) { 482 printk(KERN_DEBUG "kcapi: controller [%03d] resumed\n", 483 ctr->cnr); 484 ctr->blocked = 0; --- 11 unchanged lines hidden (view full) --- 496 * Called by hardware driver to register a controller with the CAPI subsystem. 497 * Return value: 0 on success, error code < 0 on error 498 */ 499 500int attach_capi_ctr(struct capi_ctr *ctr) 501{ 502 int i; 503 |
484 mutex_lock(&controller_mutex); | 504 mutex_lock(&capi_controller_lock); |
485 486 for (i = 0; i < CAPI_MAXCONTR; i++) { 487 if (!capi_controller[i]) 488 break; 489 } 490 if (i == CAPI_MAXCONTR) { | 505 506 for (i = 0; i < CAPI_MAXCONTR; i++) { 507 if (!capi_controller[i]) 508 break; 509 } 510 if (i == CAPI_MAXCONTR) { |
491 mutex_unlock(&controller_mutex); | 511 mutex_unlock(&capi_controller_lock); |
492 printk(KERN_ERR "kcapi: out of controller slots\n"); 493 return -EBUSY; 494 } 495 capi_controller[i] = ctr; 496 | 512 printk(KERN_ERR "kcapi: out of controller slots\n"); 513 return -EBUSY; 514 } 515 capi_controller[i] = ctr; 516 |
497 mutex_unlock(&controller_mutex); 498 | |
499 ctr->nrecvctlpkt = 0; 500 ctr->nrecvdatapkt = 0; 501 ctr->nsentctlpkt = 0; 502 ctr->nsentdatapkt = 0; 503 ctr->cnr = i + 1; 504 ctr->state = CAPI_CTR_DETECTED; 505 ctr->blocked = 0; 506 ctr->traceflag = showcapimsgs; | 517 ctr->nrecvctlpkt = 0; 518 ctr->nrecvdatapkt = 0; 519 ctr->nsentctlpkt = 0; 520 ctr->nsentdatapkt = 0; 521 ctr->cnr = i + 1; 522 ctr->state = CAPI_CTR_DETECTED; 523 ctr->blocked = 0; 524 ctr->traceflag = showcapimsgs; |
525 init_waitqueue_head(&ctr->state_wait_queue); |
|
507 508 sprintf(ctr->procfn, "capi/controllers/%d", ctr->cnr); 509 ctr->procent = proc_create_data(ctr->procfn, 0, NULL, ctr->proc_fops, ctr); 510 511 ncontrollers++; | 526 527 sprintf(ctr->procfn, "capi/controllers/%d", ctr->cnr); 528 ctr->procent = proc_create_data(ctr->procfn, 0, NULL, ctr->proc_fops, ctr); 529 530 ncontrollers++; |
531 532 mutex_unlock(&capi_controller_lock); 533 |
|
512 printk(KERN_NOTICE "kcapi: controller [%03d]: %s attached\n", 513 ctr->cnr, ctr->name); 514 return 0; 515} 516 517EXPORT_SYMBOL(attach_capi_ctr); 518 519/** 520 * detach_capi_ctr() - unregister CAPI controller 521 * @ctr: controller descriptor structure. 522 * 523 * Called by hardware driver to remove the registration of a controller 524 * with the CAPI subsystem. 525 * Return value: 0 on success, error code < 0 on error 526 */ 527 528int detach_capi_ctr(struct capi_ctr *ctr) 529{ | 534 printk(KERN_NOTICE "kcapi: controller [%03d]: %s attached\n", 535 ctr->cnr, ctr->name); 536 return 0; 537} 538 539EXPORT_SYMBOL(attach_capi_ctr); 540 541/** 542 * detach_capi_ctr() - unregister CAPI controller 543 * @ctr: controller descriptor structure. 544 * 545 * Called by hardware driver to remove the registration of a controller 546 * with the CAPI subsystem. 547 * Return value: 0 on success, error code < 0 on error 548 */ 549 550int detach_capi_ctr(struct capi_ctr *ctr) 551{ |
530 ctr_down(ctr); | 552 int err = 0; |
531 | 553 |
532 ncontrollers--; | 554 mutex_lock(&capi_controller_lock); |
533 | 555 |
534 if (ctr->procent) { 535 remove_proc_entry(ctr->procfn, NULL); 536 ctr->procent = NULL; | 556 ctr_down(ctr, CAPI_CTR_DETACHED); 557 558 if (capi_controller[ctr->cnr - 1] != ctr) { 559 err = -EINVAL; 560 goto unlock_out; |
537 } 538 capi_controller[ctr->cnr - 1] = NULL; | 561 } 562 capi_controller[ctr->cnr - 1] = NULL; |
563 ncontrollers--; 564 565 if (ctr->procent) 566 remove_proc_entry(ctr->procfn, NULL); 567 |
|
539 printk(KERN_NOTICE "kcapi: controller [%03d]: %s unregistered\n", 540 ctr->cnr, ctr->name); 541 | 568 printk(KERN_NOTICE "kcapi: controller [%03d]: %s unregistered\n", 569 ctr->cnr, ctr->name); 570 |
542 return 0; | 571unlock_out: 572 mutex_unlock(&capi_controller_lock); 573 574 return err; |
543} 544 545EXPORT_SYMBOL(detach_capi_ctr); 546 547/** 548 * register_capi_driver() - register CAPI driver 549 * @driver: driver descriptor structure. 550 * --- 33 unchanged lines hidden (view full) --- 584 * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED 585 * 586 * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller 587 * is ready for use, CAPI_REGNOTINSTALLED otherwise) 588 */ 589 590u16 capi20_isinstalled(void) 591{ | 575} 576 577EXPORT_SYMBOL(detach_capi_ctr); 578 579/** 580 * register_capi_driver() - register CAPI driver 581 * @driver: driver descriptor structure. 582 * --- 33 unchanged lines hidden (view full) --- 616 * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED 617 * 618 * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller 619 * is ready for use, CAPI_REGNOTINSTALLED otherwise) 620 */ 621 622u16 capi20_isinstalled(void) 623{ |
624 u16 ret = CAPI_REGNOTINSTALLED; |
|
592 int i; | 625 int i; |
593 for (i = 0; i < CAPI_MAXCONTR; i++) { | 626 627 mutex_lock(&capi_controller_lock); 628 629 for (i = 0; i < CAPI_MAXCONTR; i++) |
594 if (capi_controller[i] && | 630 if (capi_controller[i] && |
595 capi_controller[i]->state == CAPI_CTR_RUNNING) 596 return CAPI_NOERROR; 597 } 598 return CAPI_REGNOTINSTALLED; | 631 capi_controller[i]->state == CAPI_CTR_RUNNING) { 632 ret = CAPI_NOERROR; 633 break; 634 } 635 636 mutex_unlock(&capi_controller_lock); 637 638 return ret; |
599} 600 601EXPORT_SYMBOL(capi20_isinstalled); 602 603/** 604 * capi20_register() - CAPI 2.0 operation CAPI_REGISTER 605 * @ap: CAPI application descriptor structure. 606 * --- 36 unchanged lines hidden (view full) --- 643 ap->nsentdatapkt = 0; 644 mutex_init(&ap->recv_mtx); 645 skb_queue_head_init(&ap->recv_queue); 646 INIT_WORK(&ap->recv_work, recv_handler); 647 ap->release_in_progress = 0; 648 649 write_unlock_irqrestore(&application_lock, flags); 650 | 639} 640 641EXPORT_SYMBOL(capi20_isinstalled); 642 643/** 644 * capi20_register() - CAPI 2.0 operation CAPI_REGISTER 645 * @ap: CAPI application descriptor structure. 646 * --- 36 unchanged lines hidden (view full) --- 683 ap->nsentdatapkt = 0; 684 mutex_init(&ap->recv_mtx); 685 skb_queue_head_init(&ap->recv_queue); 686 INIT_WORK(&ap->recv_work, recv_handler); 687 ap->release_in_progress = 0; 688 689 write_unlock_irqrestore(&application_lock, flags); 690 |
651 mutex_lock(&controller_mutex); | 691 mutex_lock(&capi_controller_lock); 692 |
652 for (i = 0; i < CAPI_MAXCONTR; i++) { 653 if (!capi_controller[i] || 654 capi_controller[i]->state != CAPI_CTR_RUNNING) 655 continue; 656 register_appl(capi_controller[i], applid, &ap->rparam); 657 } | 693 for (i = 0; i < CAPI_MAXCONTR; i++) { 694 if (!capi_controller[i] || 695 capi_controller[i]->state != CAPI_CTR_RUNNING) 696 continue; 697 register_appl(capi_controller[i], applid, &ap->rparam); 698 } |
658 mutex_unlock(&controller_mutex); | |
659 | 699 |
700 mutex_unlock(&capi_controller_lock); 701 |
|
660 if (showcapimsgs & 1) { 661 printk(KERN_DEBUG "kcapi: appl %d up\n", applid); 662 } 663 664 return CAPI_NOERROR; 665} 666 667EXPORT_SYMBOL(capi20_register); --- 15 unchanged lines hidden (view full) --- 683 684 DBG("applid %#x", ap->applid); 685 686 write_lock_irqsave(&application_lock, flags); 687 ap->release_in_progress = 1; 688 capi_applications[ap->applid - 1] = NULL; 689 write_unlock_irqrestore(&application_lock, flags); 690 | 702 if (showcapimsgs & 1) { 703 printk(KERN_DEBUG "kcapi: appl %d up\n", applid); 704 } 705 706 return CAPI_NOERROR; 707} 708 709EXPORT_SYMBOL(capi20_register); --- 15 unchanged lines hidden (view full) --- 725 726 DBG("applid %#x", ap->applid); 727 728 write_lock_irqsave(&application_lock, flags); 729 ap->release_in_progress = 1; 730 capi_applications[ap->applid - 1] = NULL; 731 write_unlock_irqrestore(&application_lock, flags); 732 |
691 mutex_lock(&controller_mutex); | 733 mutex_lock(&capi_controller_lock); 734 |
692 for (i = 0; i < CAPI_MAXCONTR; i++) { 693 if (!capi_controller[i] || 694 capi_controller[i]->state != CAPI_CTR_RUNNING) 695 continue; 696 release_appl(capi_controller[i], ap->applid); 697 } | 735 for (i = 0; i < CAPI_MAXCONTR; i++) { 736 if (!capi_controller[i] || 737 capi_controller[i]->state != CAPI_CTR_RUNNING) 738 continue; 739 release_appl(capi_controller[i], ap->applid); 740 } |
698 mutex_unlock(&controller_mutex); | |
699 | 741 |
742 mutex_unlock(&capi_controller_lock); 743 |
|
700 flush_scheduled_work(); 701 skb_queue_purge(&ap->recv_queue); 702 703 if (showcapimsgs & 1) { 704 printk(KERN_DEBUG "kcapi: appl %d down\n", ap->applid); 705 } 706 707 return CAPI_NOERROR; --- 21 unchanged lines hidden (view full) --- 729 if (ncontrollers == 0) 730 return CAPI_REGNOTINSTALLED; 731 if ((ap->applid == 0) || ap->release_in_progress) 732 return CAPI_ILLAPPNR; 733 if (skb->len < 12 734 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) 735 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) 736 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; | 744 flush_scheduled_work(); 745 skb_queue_purge(&ap->recv_queue); 746 747 if (showcapimsgs & 1) { 748 printk(KERN_DEBUG "kcapi: appl %d down\n", ap->applid); 749 } 750 751 return CAPI_NOERROR; --- 21 unchanged lines hidden (view full) --- 773 if (ncontrollers == 0) 774 return CAPI_REGNOTINSTALLED; 775 if ((ap->applid == 0) || ap->release_in_progress) 776 return CAPI_ILLAPPNR; 777 if (skb->len < 12 778 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) 779 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) 780 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; |
781 782 /* 783 * The controller reference is protected by the existence of the 784 * application passed to us. We assume that the caller properly 785 * synchronizes this service with capi20_release. 786 */ |
|
737 ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data)); 738 if (!ctr || ctr->state != CAPI_CTR_RUNNING) { 739 ctr = get_capi_ctr_by_nr(1); /* XXX why? */ 740 if (!ctr || ctr->state != CAPI_CTR_RUNNING) 741 return CAPI_REGNOTINSTALLED; 742 } 743 if (ctr->blocked) 744 return CAPI_SENDQUEUEFULL; --- 48 unchanged lines hidden (view full) --- 793 * Retrieve information about the manufacturer of the specified ISDN controller 794 * or (for @contr == 0) the driver itself. 795 * Return value: CAPI result code 796 */ 797 798u16 capi20_get_manufacturer(u32 contr, u8 *buf) 799{ 800 struct capi_ctr *ctr; | 787 ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data)); 788 if (!ctr || ctr->state != CAPI_CTR_RUNNING) { 789 ctr = get_capi_ctr_by_nr(1); /* XXX why? */ 790 if (!ctr || ctr->state != CAPI_CTR_RUNNING) 791 return CAPI_REGNOTINSTALLED; 792 } 793 if (ctr->blocked) 794 return CAPI_SENDQUEUEFULL; --- 48 unchanged lines hidden (view full) --- 843 * Retrieve information about the manufacturer of the specified ISDN controller 844 * or (for @contr == 0) the driver itself. 845 * Return value: CAPI result code 846 */ 847 848u16 capi20_get_manufacturer(u32 contr, u8 *buf) 849{ 850 struct capi_ctr *ctr; |
851 u16 ret; |
|
801 802 if (contr == 0) { 803 strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); 804 return CAPI_NOERROR; 805 } | 852 853 if (contr == 0) { 854 strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); 855 return CAPI_NOERROR; 856 } |
857 858 mutex_lock(&capi_controller_lock); 859 |
|
806 ctr = get_capi_ctr_by_nr(contr); | 860 ctr = get_capi_ctr_by_nr(contr); |
807 if (!ctr || ctr->state != CAPI_CTR_RUNNING) 808 return CAPI_REGNOTINSTALLED; 809 strlcpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN); 810 return CAPI_NOERROR; | 861 if (ctr && ctr->state == CAPI_CTR_RUNNING) { 862 strlcpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN); 863 ret = CAPI_NOERROR; 864 } else 865 ret = CAPI_REGNOTINSTALLED; 866 867 mutex_unlock(&capi_controller_lock); 868 return ret; |
811} 812 813EXPORT_SYMBOL(capi20_get_manufacturer); 814 815/** 816 * capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION 817 * @contr: controller number. 818 * @verp: result structure. 819 * 820 * Retrieve version information for the specified ISDN controller 821 * or (for @contr == 0) the driver itself. 822 * Return value: CAPI result code 823 */ 824 825u16 capi20_get_version(u32 contr, struct capi_version *verp) 826{ 827 struct capi_ctr *ctr; | 869} 870 871EXPORT_SYMBOL(capi20_get_manufacturer); 872 873/** 874 * capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION 875 * @contr: controller number. 876 * @verp: result structure. 877 * 878 * Retrieve version information for the specified ISDN controller 879 * or (for @contr == 0) the driver itself. 880 * Return value: CAPI result code 881 */ 882 883u16 capi20_get_version(u32 contr, struct capi_version *verp) 884{ 885 struct capi_ctr *ctr; |
886 u16 ret; |
|
828 829 if (contr == 0) { 830 *verp = driver_version; 831 return CAPI_NOERROR; 832 } | 887 888 if (contr == 0) { 889 *verp = driver_version; 890 return CAPI_NOERROR; 891 } |
892 893 mutex_lock(&capi_controller_lock); 894 |
|
833 ctr = get_capi_ctr_by_nr(contr); | 895 ctr = get_capi_ctr_by_nr(contr); |
834 if (!ctr || ctr->state != CAPI_CTR_RUNNING) 835 return CAPI_REGNOTINSTALLED; | 896 if (ctr && ctr->state == CAPI_CTR_RUNNING) { 897 memcpy(verp, &ctr->version, sizeof(capi_version)); 898 ret = CAPI_NOERROR; 899 } else 900 ret = CAPI_REGNOTINSTALLED; |
836 | 901 |
837 memcpy(verp, &ctr->version, sizeof(capi_version)); 838 return CAPI_NOERROR; | 902 mutex_unlock(&capi_controller_lock); 903 return ret; |
839} 840 841EXPORT_SYMBOL(capi20_get_version); 842 843/** 844 * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER 845 * @contr: controller number. 846 * @serial: result buffer (8 bytes). 847 * 848 * Retrieve the serial number of the specified ISDN controller 849 * or (for @contr == 0) the driver itself. 850 * Return value: CAPI result code 851 */ 852 853u16 capi20_get_serial(u32 contr, u8 *serial) 854{ 855 struct capi_ctr *ctr; | 904} 905 906EXPORT_SYMBOL(capi20_get_version); 907 908/** 909 * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER 910 * @contr: controller number. 911 * @serial: result buffer (8 bytes). 912 * 913 * Retrieve the serial number of the specified ISDN controller 914 * or (for @contr == 0) the driver itself. 915 * Return value: CAPI result code 916 */ 917 918u16 capi20_get_serial(u32 contr, u8 *serial) 919{ 920 struct capi_ctr *ctr; |
921 u16 ret; |
|
856 857 if (contr == 0) { 858 strlcpy(serial, driver_serial, CAPI_SERIAL_LEN); 859 return CAPI_NOERROR; 860 } | 922 923 if (contr == 0) { 924 strlcpy(serial, driver_serial, CAPI_SERIAL_LEN); 925 return CAPI_NOERROR; 926 } |
927 928 mutex_lock(&capi_controller_lock); 929 |
|
861 ctr = get_capi_ctr_by_nr(contr); | 930 ctr = get_capi_ctr_by_nr(contr); |
862 if (!ctr || ctr->state != CAPI_CTR_RUNNING) 863 return CAPI_REGNOTINSTALLED; | 931 if (ctr && ctr->state == CAPI_CTR_RUNNING) { 932 strlcpy(serial, ctr->serial, CAPI_SERIAL_LEN); 933 ret = CAPI_NOERROR; 934 } else 935 ret = CAPI_REGNOTINSTALLED; |
864 | 936 |
865 strlcpy(serial, ctr->serial, CAPI_SERIAL_LEN); 866 return CAPI_NOERROR; | 937 mutex_unlock(&capi_controller_lock); 938 return ret; |
867} 868 869EXPORT_SYMBOL(capi20_get_serial); 870 871/** 872 * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE 873 * @contr: controller number. 874 * @profp: result structure. 875 * 876 * Retrieve capability information for the specified ISDN controller 877 * or (for @contr == 0) the number of installed controllers. 878 * Return value: CAPI result code 879 */ 880 881u16 capi20_get_profile(u32 contr, struct capi_profile *profp) 882{ 883 struct capi_ctr *ctr; | 939} 940 941EXPORT_SYMBOL(capi20_get_serial); 942 943/** 944 * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE 945 * @contr: controller number. 946 * @profp: result structure. 947 * 948 * Retrieve capability information for the specified ISDN controller 949 * or (for @contr == 0) the number of installed controllers. 950 * Return value: CAPI result code 951 */ 952 953u16 capi20_get_profile(u32 contr, struct capi_profile *profp) 954{ 955 struct capi_ctr *ctr; |
956 u16 ret; |
|
884 885 if (contr == 0) { 886 profp->ncontroller = ncontrollers; 887 return CAPI_NOERROR; 888 } | 957 958 if (contr == 0) { 959 profp->ncontroller = ncontrollers; 960 return CAPI_NOERROR; 961 } |
962 963 mutex_lock(&capi_controller_lock); 964 |
|
889 ctr = get_capi_ctr_by_nr(contr); | 965 ctr = get_capi_ctr_by_nr(contr); |
890 if (!ctr || ctr->state != CAPI_CTR_RUNNING) 891 return CAPI_REGNOTINSTALLED; | 966 if (ctr && ctr->state == CAPI_CTR_RUNNING) { 967 memcpy(profp, &ctr->profile, sizeof(struct capi_profile)); 968 ret = CAPI_NOERROR; 969 } else 970 ret = CAPI_REGNOTINSTALLED; |
892 | 971 |
893 memcpy(profp, &ctr->profile, sizeof(struct capi_profile)); 894 return CAPI_NOERROR; | 972 mutex_unlock(&capi_controller_lock); 973 return ret; |
895} 896 897EXPORT_SYMBOL(capi20_get_profile); 898 | 974} 975 976EXPORT_SYMBOL(capi20_get_profile); 977 |
978/* Must be called with capi_controller_lock held. */ 979static int wait_on_ctr_state(struct capi_ctr *ctr, unsigned int state) 980{ 981 DEFINE_WAIT(wait); 982 int retval = 0; 983 984 ctr = capi_ctr_get(ctr); 985 if (!ctr) 986 return -ESRCH; 987 988 for (;;) { 989 prepare_to_wait(&ctr->state_wait_queue, &wait, 990 TASK_INTERRUPTIBLE); 991 992 if (ctr->state == state) 993 break; 994 if (ctr->state == CAPI_CTR_DETACHED) { 995 retval = -ESRCH; 996 break; 997 } 998 if (signal_pending(current)) { 999 retval = -EINTR; 1000 break; 1001 } 1002 1003 mutex_unlock(&capi_controller_lock); 1004 schedule(); 1005 mutex_lock(&capi_controller_lock); 1006 } 1007 finish_wait(&ctr->state_wait_queue, &wait); 1008 1009 capi_ctr_put(ctr); 1010 1011 return retval; 1012} 1013 |
|
899#ifdef AVMB1_COMPAT 900static int old_capi_manufacturer(unsigned int cmd, void __user *data) 901{ 902 avmb1_loadandconfigdef ldef; 903 avmb1_extcarddef cdef; 904 avmb1_resetdef rdef; 905 capicardparams cparams; 906 struct capi_ctr *ctr; --- 61 unchanged lines hidden (view full) --- 968 return -EFAULT; 969 ldef.t4config.len = 0; 970 ldef.t4config.data = NULL; 971 } else { 972 if (copy_from_user(&ldef, data, 973 sizeof(avmb1_loadandconfigdef))) 974 return -EFAULT; 975 } | 1014#ifdef AVMB1_COMPAT 1015static int old_capi_manufacturer(unsigned int cmd, void __user *data) 1016{ 1017 avmb1_loadandconfigdef ldef; 1018 avmb1_extcarddef cdef; 1019 avmb1_resetdef rdef; 1020 capicardparams cparams; 1021 struct capi_ctr *ctr; --- 61 unchanged lines hidden (view full) --- 1083 return -EFAULT; 1084 ldef.t4config.len = 0; 1085 ldef.t4config.data = NULL; 1086 } else { 1087 if (copy_from_user(&ldef, data, 1088 sizeof(avmb1_loadandconfigdef))) 1089 return -EFAULT; 1090 } |
1091 1092 mutex_lock(&capi_controller_lock); 1093 |
|
976 ctr = get_capi_ctr_by_nr(ldef.contr); | 1094 ctr = get_capi_ctr_by_nr(ldef.contr); |
977 if (!ctr) 978 return -EINVAL; 979 ctr = capi_ctr_get(ctr); 980 if (!ctr) 981 return -ESRCH; | 1095 if (!ctr) { 1096 retval = -EINVAL; 1097 goto load_unlock_out; 1098 } 1099 |
982 if (ctr->load_firmware == NULL) { 983 printk(KERN_DEBUG "kcapi: load: no load function\n"); | 1100 if (ctr->load_firmware == NULL) { 1101 printk(KERN_DEBUG "kcapi: load: no load function\n"); |
984 capi_ctr_put(ctr); 985 return -ESRCH; | 1102 retval = -ESRCH; 1103 goto load_unlock_out; |
986 } 987 988 if (ldef.t4file.len <= 0) { 989 printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len); | 1104 } 1105 1106 if (ldef.t4file.len <= 0) { 1107 printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len); |
990 capi_ctr_put(ctr); 991 return -EINVAL; | 1108 retval = -EINVAL; 1109 goto load_unlock_out; |
992 } 993 if (ldef.t4file.data == NULL) { 994 printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n"); | 1110 } 1111 if (ldef.t4file.data == NULL) { 1112 printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n"); |
995 capi_ctr_put(ctr); 996 return -EINVAL; | 1113 retval = -EINVAL; 1114 goto load_unlock_out; |
997 } 998 999 ldata.firmware.user = 1; 1000 ldata.firmware.data = ldef.t4file.data; 1001 ldata.firmware.len = ldef.t4file.len; 1002 ldata.configuration.user = 1; 1003 ldata.configuration.data = ldef.t4config.data; 1004 ldata.configuration.len = ldef.t4config.len; 1005 1006 if (ctr->state != CAPI_CTR_DETECTED) { 1007 printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr); | 1115 } 1116 1117 ldata.firmware.user = 1; 1118 ldata.firmware.data = ldef.t4file.data; 1119 ldata.firmware.len = ldef.t4file.len; 1120 ldata.configuration.user = 1; 1121 ldata.configuration.data = ldef.t4config.data; 1122 ldata.configuration.len = ldef.t4config.len; 1123 1124 if (ctr->state != CAPI_CTR_DETECTED) { 1125 printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr); |
1008 capi_ctr_put(ctr); 1009 return -EBUSY; | 1126 retval = -EBUSY; 1127 goto load_unlock_out; |
1010 } 1011 ctr->state = CAPI_CTR_LOADING; 1012 1013 retval = ctr->load_firmware(ctr, &ldata); | 1128 } 1129 ctr->state = CAPI_CTR_LOADING; 1130 1131 retval = ctr->load_firmware(ctr, &ldata); |
1014 | |
1015 if (retval) { 1016 ctr->state = CAPI_CTR_DETECTED; | 1132 if (retval) { 1133 ctr->state = CAPI_CTR_DETECTED; |
1017 capi_ctr_put(ctr); 1018 return retval; | 1134 goto load_unlock_out; |
1019 } 1020 | 1135 } 1136 |
1021 while (ctr->state != CAPI_CTR_RUNNING) { | 1137 retval = wait_on_ctr_state(ctr, CAPI_CTR_RUNNING); |
1022 | 1138 |
1023 msleep_interruptible(100); /* 0.1 sec */ | 1139load_unlock_out: 1140 mutex_unlock(&capi_controller_lock); 1141 return retval; |
1024 | 1142 |
1025 if (signal_pending(current)) { 1026 capi_ctr_put(ctr); 1027 return -EINTR; 1028 } 1029 } 1030 capi_ctr_put(ctr); 1031 return 0; 1032 | |
1033 case AVMB1_RESETCARD: 1034 if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef))) 1035 return -EFAULT; | 1143 case AVMB1_RESETCARD: 1144 if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef))) 1145 return -EFAULT; |
1146 1147 retval = 0; 1148 1149 mutex_lock(&capi_controller_lock); 1150 |
|
1036 ctr = get_capi_ctr_by_nr(rdef.contr); | 1151 ctr = get_capi_ctr_by_nr(rdef.contr); |
1037 if (!ctr) 1038 return -ESRCH; | 1152 if (!ctr) { 1153 retval = -ESRCH; 1154 goto reset_unlock_out; 1155 } |
1039 1040 if (ctr->state == CAPI_CTR_DETECTED) | 1156 1157 if (ctr->state == CAPI_CTR_DETECTED) |
1041 return 0; | 1158 goto reset_unlock_out; |
1042 1043 ctr->reset_ctr(ctr); 1044 | 1159 1160 ctr->reset_ctr(ctr); 1161 |
1045 while (ctr->state > CAPI_CTR_DETECTED) { | 1162 retval = wait_on_ctr_state(ctr, CAPI_CTR_DETECTED); |
1046 | 1163 |
1047 msleep_interruptible(100); /* 0.1 sec */ 1048 1049 if (signal_pending(current)) 1050 return -EINTR; 1051 } 1052 return 0; 1053 | 1164reset_unlock_out: 1165 mutex_unlock(&capi_controller_lock); 1166 return retval; |
1054 } 1055 return -EINVAL; 1056} 1057#endif 1058 1059/** 1060 * capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER 1061 * @cmd: command. 1062 * @data: parameter. 1063 * 1064 * Perform manufacturer specific command. 1065 * Return value: CAPI result code 1066 */ 1067 1068int capi20_manufacturer(unsigned int cmd, void __user *data) 1069{ 1070 struct capi_ctr *ctr; | 1167 } 1168 return -EINVAL; 1169} 1170#endif 1171 1172/** 1173 * capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER 1174 * @cmd: command. 1175 * @data: parameter. 1176 * 1177 * Perform manufacturer specific command. 1178 * Return value: CAPI result code 1179 */ 1180 1181int capi20_manufacturer(unsigned int cmd, void __user *data) 1182{ 1183 struct capi_ctr *ctr; |
1184 int retval; |
|
1071 1072 switch (cmd) { 1073#ifdef AVMB1_COMPAT 1074 case AVMB1_LOAD: 1075 case AVMB1_LOAD_AND_CONFIG: 1076 case AVMB1_RESETCARD: 1077 case AVMB1_GET_CARDINFO: 1078 case AVMB1_REMOVECARD: 1079 return old_capi_manufacturer(cmd, data); 1080#endif 1081 case KCAPI_CMD_TRACE: 1082 { 1083 kcapi_flagdef fdef; 1084 1085 if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef))) 1086 return -EFAULT; 1087 | 1185 1186 switch (cmd) { 1187#ifdef AVMB1_COMPAT 1188 case AVMB1_LOAD: 1189 case AVMB1_LOAD_AND_CONFIG: 1190 case AVMB1_RESETCARD: 1191 case AVMB1_GET_CARDINFO: 1192 case AVMB1_REMOVECARD: 1193 return old_capi_manufacturer(cmd, data); 1194#endif 1195 case KCAPI_CMD_TRACE: 1196 { 1197 kcapi_flagdef fdef; 1198 1199 if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef))) 1200 return -EFAULT; 1201 |
1202 mutex_lock(&capi_controller_lock); 1203 |
|
1088 ctr = get_capi_ctr_by_nr(fdef.contr); | 1204 ctr = get_capi_ctr_by_nr(fdef.contr); |
1089 if (!ctr) 1090 return -ESRCH; | 1205 if (ctr) { 1206 ctr->traceflag = fdef.flag; 1207 printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n", 1208 ctr->cnr, ctr->traceflag); 1209 retval = 0; 1210 } else 1211 retval = -ESRCH; |
1091 | 1212 |
1092 ctr->traceflag = fdef.flag; 1093 printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n", 1094 ctr->cnr, ctr->traceflag); 1095 return 0; | 1213 mutex_unlock(&capi_controller_lock); 1214 1215 return retval; |
1096 } 1097 case KCAPI_CMD_ADDCARD: 1098 { 1099 struct list_head *l; 1100 struct capi_driver *driver = NULL; 1101 capicardparams cparams; 1102 kcapi_carddef cdef; | 1216 } 1217 case KCAPI_CMD_ADDCARD: 1218 { 1219 struct list_head *l; 1220 struct capi_driver *driver = NULL; 1221 capicardparams cparams; 1222 kcapi_carddef cdef; |
1103 int retval; | |
1104 1105 if ((retval = copy_from_user(&cdef, data, sizeof(cdef)))) 1106 return retval; 1107 1108 cparams.port = cdef.port; 1109 cparams.irq = cdef.irq; 1110 cparams.membase = cdef.membase; 1111 cparams.cardnr = cdef.cardnr; --- 71 unchanged lines hidden --- | 1223 1224 if ((retval = copy_from_user(&cdef, data, sizeof(cdef)))) 1225 return retval; 1226 1227 cparams.port = cdef.port; 1228 cparams.irq = cdef.irq; 1229 cparams.membase = cdef.membase; 1230 cparams.cardnr = cdef.cardnr; --- 71 unchanged lines hidden --- |