root/drivers/isdn/capi/kcapi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. capi_ctr_get
  2. capi_ctr_put
  3. get_capi_ctr_by_nr
  4. __get_capi_appl_by_nr
  5. get_capi_appl_by_nr
  6. capi_cmd_valid
  7. capi_subcmd_valid
  8. register_appl
  9. release_appl
  10. notify_up
  11. ctr_down
  12. notify_down
  13. notify_handler
  14. do_notify_work
  15. notify_push
  16. register_capictr_notifier
  17. unregister_capictr_notifier
  18. recv_handler
  19. capi_ctr_handle_message
  20. capi_ctr_ready
  21. capi_ctr_down
  22. capi_ctr_suspend_output
  23. capi_ctr_resume_output
  24. attach_capi_ctr
  25. detach_capi_ctr
  26. register_capi_driver
  27. unregister_capi_driver
  28. capi20_isinstalled
  29. capi20_register
  30. capi20_release
  31. capi20_put_message
  32. capi20_get_manufacturer
  33. capi20_get_version
  34. capi20_get_serial
  35. capi20_get_profile
  36. wait_on_ctr_state
  37. old_capi_manufacturer
  38. capi20_manufacturer
  39. kcapi_init
  40. kcapi_exit

   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 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/sched/signal.h>
  22 #include <linux/seq_file.h>
  23 #include <linux/skbuff.h>
  24 #include <linux/workqueue.h>
  25 #include <linux/capi.h>
  26 #include <linux/kernelcapi.h>
  27 #include <linux/init.h>
  28 #include <linux/moduleparam.h>
  29 #include <linux/delay.h>
  30 #include <linux/slab.h>
  31 #include <linux/uaccess.h>
  32 #include <linux/isdn/capicmd.h>
  33 #include <linux/isdn/capiutil.h>
  34 #ifdef AVMB1_COMPAT
  35 #include <linux/b1lli.h>
  36 #endif
  37 #include <linux/mutex.h>
  38 #include <linux/rcupdate.h>
  39 
  40 static int showcapimsgs = 0;
  41 static struct workqueue_struct *kcapi_wq;
  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 capictr_event {
  51         struct work_struct work;
  52         unsigned int type;
  53         u32 controller;
  54 };
  55 
  56 /* ------------------------------------------------------------- */
  57 
  58 static const struct capi_version driver_version = {2, 0, 1, 1 << 4};
  59 static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
  60 static char capi_manufakturer[64] = "AVM Berlin";
  61 
  62 #define NCCI2CTRL(ncci)    (((ncci) >> 24) & 0x7f)
  63 
  64 LIST_HEAD(capi_drivers);
  65 DEFINE_MUTEX(capi_drivers_lock);
  66 
  67 struct capi_ctr *capi_controller[CAPI_MAXCONTR];
  68 DEFINE_MUTEX(capi_controller_lock);
  69 
  70 struct capi20_appl *capi_applications[CAPI_MAXAPPL];
  71 
  72 static int ncontrollers;
  73 
  74 static BLOCKING_NOTIFIER_HEAD(ctr_notifier_list);
  75 
  76 /* -------- controller ref counting -------------------------------------- */
  77 
  78 static inline struct capi_ctr *
  79 capi_ctr_get(struct capi_ctr *ctr)
  80 {
  81         if (!try_module_get(ctr->owner))
  82                 return NULL;
  83         return ctr;
  84 }
  85 
  86 static inline void
  87 capi_ctr_put(struct capi_ctr *ctr)
  88 {
  89         module_put(ctr->owner);
  90 }
  91 
  92 /* ------------------------------------------------------------- */
  93 
  94 static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
  95 {
  96         if (contr < 1 || contr - 1 >= CAPI_MAXCONTR)
  97                 return NULL;
  98 
  99         return capi_controller[contr - 1];
 100 }
 101 
 102 static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
 103 {
 104         lockdep_assert_held(&capi_controller_lock);
 105 
 106         if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
 107                 return NULL;
 108 
 109         return capi_applications[applid - 1];
 110 }
 111 
 112 static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
 113 {
 114         if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
 115                 return NULL;
 116 
 117         return rcu_dereference(capi_applications[applid - 1]);
 118 }
 119 
 120 /* -------- util functions ------------------------------------ */
 121 
 122 static inline int capi_cmd_valid(u8 cmd)
 123 {
 124         switch (cmd) {
 125         case CAPI_ALERT:
 126         case CAPI_CONNECT:
 127         case CAPI_CONNECT_ACTIVE:
 128         case CAPI_CONNECT_B3_ACTIVE:
 129         case CAPI_CONNECT_B3:
 130         case CAPI_CONNECT_B3_T90_ACTIVE:
 131         case CAPI_DATA_B3:
 132         case CAPI_DISCONNECT_B3:
 133         case CAPI_DISCONNECT:
 134         case CAPI_FACILITY:
 135         case CAPI_INFO:
 136         case CAPI_LISTEN:
 137         case CAPI_MANUFACTURER:
 138         case CAPI_RESET_B3:
 139         case CAPI_SELECT_B_PROTOCOL:
 140                 return 1;
 141         }
 142         return 0;
 143 }
 144 
 145 static inline int capi_subcmd_valid(u8 subcmd)
 146 {
 147         switch (subcmd) {
 148         case CAPI_REQ:
 149         case CAPI_CONF:
 150         case CAPI_IND:
 151         case CAPI_RESP:
 152                 return 1;
 153         }
 154         return 0;
 155 }
 156 
 157 /* ------------------------------------------------------------ */
 158 
 159 static void
 160 register_appl(struct capi_ctr *ctr, u16 applid, capi_register_params *rparam)
 161 {
 162         ctr = capi_ctr_get(ctr);
 163 
 164         if (ctr)
 165                 ctr->register_appl(ctr, applid, rparam);
 166         else
 167                 printk(KERN_WARNING "%s: cannot get controller resources\n",
 168                        __func__);
 169 }
 170 
 171 
 172 static void release_appl(struct capi_ctr *ctr, u16 applid)
 173 {
 174         DBG("applid %#x", applid);
 175 
 176         ctr->release_appl(ctr, applid);
 177         capi_ctr_put(ctr);
 178 }
 179 
 180 static void notify_up(u32 contr)
 181 {
 182         struct capi20_appl *ap;
 183         struct capi_ctr *ctr;
 184         u16 applid;
 185 
 186         mutex_lock(&capi_controller_lock);
 187 
 188         if (showcapimsgs & 1)
 189                 printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
 190 
 191         ctr = get_capi_ctr_by_nr(contr);
 192         if (ctr) {
 193                 if (ctr->state == CAPI_CTR_RUNNING)
 194                         goto unlock_out;
 195 
 196                 ctr->state = CAPI_CTR_RUNNING;
 197 
 198                 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
 199                         ap = __get_capi_appl_by_nr(applid);
 200                         if (ap)
 201                                 register_appl(ctr, applid, &ap->rparam);
 202                 }
 203 
 204                 wake_up_interruptible_all(&ctr->state_wait_queue);
 205         } else
 206                 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
 207 
 208 unlock_out:
 209         mutex_unlock(&capi_controller_lock);
 210 }
 211 
 212 static void ctr_down(struct capi_ctr *ctr, int new_state)
 213 {
 214         struct capi20_appl *ap;
 215         u16 applid;
 216 
 217         if (ctr->state == CAPI_CTR_DETECTED || ctr->state == CAPI_CTR_DETACHED)
 218                 return;
 219 
 220         ctr->state = new_state;
 221 
 222         memset(ctr->manu, 0, sizeof(ctr->manu));
 223         memset(&ctr->version, 0, sizeof(ctr->version));
 224         memset(&ctr->profile, 0, sizeof(ctr->profile));
 225         memset(ctr->serial, 0, sizeof(ctr->serial));
 226 
 227         for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
 228                 ap = __get_capi_appl_by_nr(applid);
 229                 if (ap)
 230                         capi_ctr_put(ctr);
 231         }
 232 
 233         wake_up_interruptible_all(&ctr->state_wait_queue);
 234 }
 235 
 236 static void notify_down(u32 contr)
 237 {
 238         struct capi_ctr *ctr;
 239 
 240         mutex_lock(&capi_controller_lock);
 241 
 242         if (showcapimsgs & 1)
 243                 printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
 244 
 245         ctr = get_capi_ctr_by_nr(contr);
 246         if (ctr)
 247                 ctr_down(ctr, CAPI_CTR_DETECTED);
 248         else
 249                 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
 250 
 251         mutex_unlock(&capi_controller_lock);
 252 }
 253 
 254 static int
 255 notify_handler(struct notifier_block *nb, unsigned long val, void *v)
 256 {
 257         u32 contr = (long)v;
 258 
 259         switch (val) {
 260         case CAPICTR_UP:
 261                 notify_up(contr);
 262                 break;
 263         case CAPICTR_DOWN:
 264                 notify_down(contr);
 265                 break;
 266         }
 267         return NOTIFY_OK;
 268 }
 269 
 270 static void do_notify_work(struct work_struct *work)
 271 {
 272         struct capictr_event *event =
 273                 container_of(work, struct capictr_event, work);
 274 
 275         blocking_notifier_call_chain(&ctr_notifier_list, event->type,
 276                                      (void *)(long)event->controller);
 277         kfree(event);
 278 }
 279 
 280 /*
 281  * The notifier will result in adding/deleteing of devices. Devices can
 282  * only removed in user process, not in bh.
 283  */
 284 static int notify_push(unsigned int event_type, u32 controller)
 285 {
 286         struct capictr_event *event = kmalloc(sizeof(*event), GFP_ATOMIC);
 287 
 288         if (!event)
 289                 return -ENOMEM;
 290 
 291         INIT_WORK(&event->work, do_notify_work);
 292         event->type = event_type;
 293         event->controller = controller;
 294 
 295         queue_work(kcapi_wq, &event->work);
 296         return 0;
 297 }
 298 
 299 int register_capictr_notifier(struct notifier_block *nb)
 300 {
 301         return blocking_notifier_chain_register(&ctr_notifier_list, nb);
 302 }
 303 EXPORT_SYMBOL_GPL(register_capictr_notifier);
 304 
 305 int unregister_capictr_notifier(struct notifier_block *nb)
 306 {
 307         return blocking_notifier_chain_unregister(&ctr_notifier_list, nb);
 308 }
 309 EXPORT_SYMBOL_GPL(unregister_capictr_notifier);
 310 
 311 /* -------- Receiver ------------------------------------------ */
 312 
 313 static void recv_handler(struct work_struct *work)
 314 {
 315         struct sk_buff *skb;
 316         struct capi20_appl *ap =
 317                 container_of(work, struct capi20_appl, recv_work);
 318 
 319         if ((!ap) || (ap->release_in_progress))
 320                 return;
 321 
 322         mutex_lock(&ap->recv_mtx);
 323         while ((skb = skb_dequeue(&ap->recv_queue))) {
 324                 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_IND)
 325                         ap->nrecvdatapkt++;
 326                 else
 327                         ap->nrecvctlpkt++;
 328 
 329                 ap->recv_message(ap, skb);
 330         }
 331         mutex_unlock(&ap->recv_mtx);
 332 }
 333 
 334 /**
 335  * capi_ctr_handle_message() - handle incoming CAPI message
 336  * @ctr:        controller descriptor structure.
 337  * @appl:       application ID.
 338  * @skb:        message.
 339  *
 340  * Called by hardware driver to pass a CAPI message to the application.
 341  */
 342 
 343 void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
 344                              struct sk_buff *skb)
 345 {
 346         struct capi20_appl *ap;
 347         int showctl = 0;
 348         u8 cmd, subcmd;
 349         _cdebbuf *cdb;
 350 
 351         if (ctr->state != CAPI_CTR_RUNNING) {
 352                 cdb = capi_message2str(skb->data);
 353                 if (cdb) {
 354                         printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
 355                                ctr->cnr, cdb->buf);
 356                         cdebbuf_free(cdb);
 357                 } else
 358                         printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
 359                                ctr->cnr);
 360                 goto error;
 361         }
 362 
 363         cmd = CAPIMSG_COMMAND(skb->data);
 364         subcmd = CAPIMSG_SUBCOMMAND(skb->data);
 365         if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
 366                 ctr->nrecvdatapkt++;
 367                 if (ctr->traceflag > 2)
 368                         showctl |= 2;
 369         } else {
 370                 ctr->nrecvctlpkt++;
 371                 if (ctr->traceflag)
 372                         showctl |= 2;
 373         }
 374         showctl |= (ctr->traceflag & 1);
 375         if (showctl & 2) {
 376                 if (showctl & 1) {
 377                         printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n",
 378                                ctr->cnr, CAPIMSG_APPID(skb->data),
 379                                capi_cmd2str(cmd, subcmd),
 380                                CAPIMSG_LEN(skb->data));
 381                 } else {
 382                         cdb = capi_message2str(skb->data);
 383                         if (cdb) {
 384                                 printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
 385                                        ctr->cnr, cdb->buf);
 386                                 cdebbuf_free(cdb);
 387                         } else
 388                                 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
 389                                        ctr->cnr, CAPIMSG_APPID(skb->data),
 390                                        capi_cmd2str(cmd, subcmd),
 391                                        CAPIMSG_LEN(skb->data));
 392                 }
 393 
 394         }
 395 
 396         rcu_read_lock();
 397         ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
 398         if (!ap) {
 399                 rcu_read_unlock();
 400                 cdb = capi_message2str(skb->data);
 401                 if (cdb) {
 402                         printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
 403                                CAPIMSG_APPID(skb->data), cdb->buf);
 404                         cdebbuf_free(cdb);
 405                 } else
 406                         printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n",
 407                                CAPIMSG_APPID(skb->data),
 408                                capi_cmd2str(cmd, subcmd));
 409                 goto error;
 410         }
 411         skb_queue_tail(&ap->recv_queue, skb);
 412         queue_work(kcapi_wq, &ap->recv_work);
 413         rcu_read_unlock();
 414 
 415         return;
 416 
 417 error:
 418         kfree_skb(skb);
 419 }
 420 
 421 EXPORT_SYMBOL(capi_ctr_handle_message);
 422 
 423 /**
 424  * capi_ctr_ready() - signal CAPI controller ready
 425  * @ctr:        controller descriptor structure.
 426  *
 427  * Called by hardware driver to signal that the controller is up and running.
 428  */
 429 
 430 void capi_ctr_ready(struct capi_ctr *ctr)
 431 {
 432         printk(KERN_NOTICE "kcapi: controller [%03d] \"%s\" ready.\n",
 433                ctr->cnr, ctr->name);
 434 
 435         notify_push(CAPICTR_UP, ctr->cnr);
 436 }
 437 
 438 EXPORT_SYMBOL(capi_ctr_ready);
 439 
 440 /**
 441  * capi_ctr_down() - signal CAPI controller not ready
 442  * @ctr:        controller descriptor structure.
 443  *
 444  * Called by hardware driver to signal that the controller is down and
 445  * unavailable for use.
 446  */
 447 
 448 void capi_ctr_down(struct capi_ctr *ctr)
 449 {
 450         printk(KERN_NOTICE "kcapi: controller [%03d] down.\n", ctr->cnr);
 451 
 452         notify_push(CAPICTR_DOWN, ctr->cnr);
 453 }
 454 
 455 EXPORT_SYMBOL(capi_ctr_down);
 456 
 457 /**
 458  * capi_ctr_suspend_output() - suspend controller
 459  * @ctr:        controller descriptor structure.
 460  *
 461  * Called by hardware driver to stop data flow.
 462  *
 463  * Note: The caller is responsible for synchronizing concurrent state changes
 464  * as well as invocations of capi_ctr_handle_message.
 465  */
 466 
 467 void capi_ctr_suspend_output(struct capi_ctr *ctr)
 468 {
 469         if (!ctr->blocked) {
 470                 printk(KERN_DEBUG "kcapi: controller [%03d] suspend\n",
 471                        ctr->cnr);
 472                 ctr->blocked = 1;
 473         }
 474 }
 475 
 476 EXPORT_SYMBOL(capi_ctr_suspend_output);
 477 
 478 /**
 479  * capi_ctr_resume_output() - resume controller
 480  * @ctr:        controller descriptor structure.
 481  *
 482  * Called by hardware driver to resume data flow.
 483  *
 484  * Note: The caller is responsible for synchronizing concurrent state changes
 485  * as well as invocations of capi_ctr_handle_message.
 486  */
 487 
 488 void capi_ctr_resume_output(struct capi_ctr *ctr)
 489 {
 490         if (ctr->blocked) {
 491                 printk(KERN_DEBUG "kcapi: controller [%03d] resumed\n",
 492                        ctr->cnr);
 493                 ctr->blocked = 0;
 494         }
 495 }
 496 
 497 EXPORT_SYMBOL(capi_ctr_resume_output);
 498 
 499 /* ------------------------------------------------------------- */
 500 
 501 /**
 502  * attach_capi_ctr() - register CAPI controller
 503  * @ctr:        controller descriptor structure.
 504  *
 505  * Called by hardware driver to register a controller with the CAPI subsystem.
 506  * Return value: 0 on success, error code < 0 on error
 507  */
 508 
 509 int attach_capi_ctr(struct capi_ctr *ctr)
 510 {
 511         int i;
 512 
 513         mutex_lock(&capi_controller_lock);
 514 
 515         for (i = 0; i < CAPI_MAXCONTR; i++) {
 516                 if (!capi_controller[i])
 517                         break;
 518         }
 519         if (i == CAPI_MAXCONTR) {
 520                 mutex_unlock(&capi_controller_lock);
 521                 printk(KERN_ERR "kcapi: out of controller slots\n");
 522                 return -EBUSY;
 523         }
 524         capi_controller[i] = ctr;
 525 
 526         ctr->nrecvctlpkt = 0;
 527         ctr->nrecvdatapkt = 0;
 528         ctr->nsentctlpkt = 0;
 529         ctr->nsentdatapkt = 0;
 530         ctr->cnr = i + 1;
 531         ctr->state = CAPI_CTR_DETECTED;
 532         ctr->blocked = 0;
 533         ctr->traceflag = showcapimsgs;
 534         init_waitqueue_head(&ctr->state_wait_queue);
 535 
 536         sprintf(ctr->procfn, "capi/controllers/%d", ctr->cnr);
 537         ctr->procent = proc_create_single_data(ctr->procfn, 0, NULL,
 538                         ctr->proc_show, ctr);
 539 
 540         ncontrollers++;
 541 
 542         mutex_unlock(&capi_controller_lock);
 543 
 544         printk(KERN_NOTICE "kcapi: controller [%03d]: %s attached\n",
 545                ctr->cnr, ctr->name);
 546         return 0;
 547 }
 548 
 549 EXPORT_SYMBOL(attach_capi_ctr);
 550 
 551 /**
 552  * detach_capi_ctr() - unregister CAPI controller
 553  * @ctr:        controller descriptor structure.
 554  *
 555  * Called by hardware driver to remove the registration of a controller
 556  * with the CAPI subsystem.
 557  * Return value: 0 on success, error code < 0 on error
 558  */
 559 
 560 int detach_capi_ctr(struct capi_ctr *ctr)
 561 {
 562         int err = 0;
 563 
 564         mutex_lock(&capi_controller_lock);
 565 
 566         ctr_down(ctr, CAPI_CTR_DETACHED);
 567 
 568         if (capi_controller[ctr->cnr - 1] != ctr) {
 569                 err = -EINVAL;
 570                 goto unlock_out;
 571         }
 572         capi_controller[ctr->cnr - 1] = NULL;
 573         ncontrollers--;
 574 
 575         if (ctr->procent)
 576                 remove_proc_entry(ctr->procfn, NULL);
 577 
 578         printk(KERN_NOTICE "kcapi: controller [%03d]: %s unregistered\n",
 579                ctr->cnr, ctr->name);
 580 
 581 unlock_out:
 582         mutex_unlock(&capi_controller_lock);
 583 
 584         return err;
 585 }
 586 
 587 EXPORT_SYMBOL(detach_capi_ctr);
 588 
 589 /**
 590  * register_capi_driver() - register CAPI driver
 591  * @driver:     driver descriptor structure.
 592  *
 593  * Called by hardware driver to register itself with the CAPI subsystem.
 594  */
 595 
 596 void register_capi_driver(struct capi_driver *driver)
 597 {
 598         mutex_lock(&capi_drivers_lock);
 599         list_add_tail(&driver->list, &capi_drivers);
 600         mutex_unlock(&capi_drivers_lock);
 601 }
 602 
 603 EXPORT_SYMBOL(register_capi_driver);
 604 
 605 /**
 606  * unregister_capi_driver() - unregister CAPI driver
 607  * @driver:     driver descriptor structure.
 608  *
 609  * Called by hardware driver to unregister itself from the CAPI subsystem.
 610  */
 611 
 612 void unregister_capi_driver(struct capi_driver *driver)
 613 {
 614         mutex_lock(&capi_drivers_lock);
 615         list_del(&driver->list);
 616         mutex_unlock(&capi_drivers_lock);
 617 }
 618 
 619 EXPORT_SYMBOL(unregister_capi_driver);
 620 
 621 /* ------------------------------------------------------------- */
 622 /* -------- CAPI2.0 Interface ---------------------------------- */
 623 /* ------------------------------------------------------------- */
 624 
 625 /**
 626  * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED
 627  *
 628  * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller
 629  *      is ready for use, CAPI_REGNOTINSTALLED otherwise)
 630  */
 631 
 632 u16 capi20_isinstalled(void)
 633 {
 634         u16 ret = CAPI_REGNOTINSTALLED;
 635         int i;
 636 
 637         mutex_lock(&capi_controller_lock);
 638 
 639         for (i = 0; i < CAPI_MAXCONTR; i++)
 640                 if (capi_controller[i] &&
 641                     capi_controller[i]->state == CAPI_CTR_RUNNING) {
 642                         ret = CAPI_NOERROR;
 643                         break;
 644                 }
 645 
 646         mutex_unlock(&capi_controller_lock);
 647 
 648         return ret;
 649 }
 650 
 651 EXPORT_SYMBOL(capi20_isinstalled);
 652 
 653 /**
 654  * capi20_register() - CAPI 2.0 operation CAPI_REGISTER
 655  * @ap:         CAPI application descriptor structure.
 656  *
 657  * Register an application's presence with CAPI.
 658  * A unique application ID is assigned and stored in @ap->applid.
 659  * After this function returns successfully, the message receive
 660  * callback function @ap->recv_message() may be called at any time
 661  * until capi20_release() has been called for the same @ap.
 662  * Return value: CAPI result code
 663  */
 664 
 665 u16 capi20_register(struct capi20_appl *ap)
 666 {
 667         int i;
 668         u16 applid;
 669 
 670         DBG("");
 671 
 672         if (ap->rparam.datablklen < 128)
 673                 return CAPI_LOGBLKSIZETOSMALL;
 674 
 675         ap->nrecvctlpkt = 0;
 676         ap->nrecvdatapkt = 0;
 677         ap->nsentctlpkt = 0;
 678         ap->nsentdatapkt = 0;
 679         mutex_init(&ap->recv_mtx);
 680         skb_queue_head_init(&ap->recv_queue);
 681         INIT_WORK(&ap->recv_work, recv_handler);
 682         ap->release_in_progress = 0;
 683 
 684         mutex_lock(&capi_controller_lock);
 685 
 686         for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
 687                 if (capi_applications[applid - 1] == NULL)
 688                         break;
 689         }
 690         if (applid > CAPI_MAXAPPL) {
 691                 mutex_unlock(&capi_controller_lock);
 692                 return CAPI_TOOMANYAPPLS;
 693         }
 694 
 695         ap->applid = applid;
 696         capi_applications[applid - 1] = ap;
 697 
 698         for (i = 0; i < CAPI_MAXCONTR; i++) {
 699                 if (!capi_controller[i] ||
 700                     capi_controller[i]->state != CAPI_CTR_RUNNING)
 701                         continue;
 702                 register_appl(capi_controller[i], applid, &ap->rparam);
 703         }
 704 
 705         mutex_unlock(&capi_controller_lock);
 706 
 707         if (showcapimsgs & 1) {
 708                 printk(KERN_DEBUG "kcapi: appl %d up\n", applid);
 709         }
 710 
 711         return CAPI_NOERROR;
 712 }
 713 
 714 EXPORT_SYMBOL(capi20_register);
 715 
 716 /**
 717  * capi20_release() - CAPI 2.0 operation CAPI_RELEASE
 718  * @ap:         CAPI application descriptor structure.
 719  *
 720  * Terminate an application's registration with CAPI.
 721  * After this function returns successfully, the message receive
 722  * callback function @ap->recv_message() will no longer be called.
 723  * Return value: CAPI result code
 724  */
 725 
 726 u16 capi20_release(struct capi20_appl *ap)
 727 {
 728         int i;
 729 
 730         DBG("applid %#x", ap->applid);
 731 
 732         mutex_lock(&capi_controller_lock);
 733 
 734         ap->release_in_progress = 1;
 735         capi_applications[ap->applid - 1] = NULL;
 736 
 737         synchronize_rcu();
 738 
 739         for (i = 0; i < CAPI_MAXCONTR; i++) {
 740                 if (!capi_controller[i] ||
 741                     capi_controller[i]->state != CAPI_CTR_RUNNING)
 742                         continue;
 743                 release_appl(capi_controller[i], ap->applid);
 744         }
 745 
 746         mutex_unlock(&capi_controller_lock);
 747 
 748         flush_workqueue(kcapi_wq);
 749         skb_queue_purge(&ap->recv_queue);
 750 
 751         if (showcapimsgs & 1) {
 752                 printk(KERN_DEBUG "kcapi: appl %d down\n", ap->applid);
 753         }
 754 
 755         return CAPI_NOERROR;
 756 }
 757 
 758 EXPORT_SYMBOL(capi20_release);
 759 
 760 /**
 761  * capi20_put_message() - CAPI 2.0 operation CAPI_PUT_MESSAGE
 762  * @ap:         CAPI application descriptor structure.
 763  * @skb:        CAPI message.
 764  *
 765  * Transfer a single message to CAPI.
 766  * Return value: CAPI result code
 767  */
 768 
 769 u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
 770 {
 771         struct capi_ctr *ctr;
 772         int showctl = 0;
 773         u8 cmd, subcmd;
 774 
 775         DBG("applid %#x", ap->applid);
 776 
 777         if (ncontrollers == 0)
 778                 return CAPI_REGNOTINSTALLED;
 779         if ((ap->applid == 0) || ap->release_in_progress)
 780                 return CAPI_ILLAPPNR;
 781         if (skb->len < 12
 782             || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
 783             || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
 784                 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
 785 
 786         /*
 787          * The controller reference is protected by the existence of the
 788          * application passed to us. We assume that the caller properly
 789          * synchronizes this service with capi20_release.
 790          */
 791         ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
 792         if (!ctr || ctr->state != CAPI_CTR_RUNNING)
 793                 return CAPI_REGNOTINSTALLED;
 794         if (ctr->blocked)
 795                 return CAPI_SENDQUEUEFULL;
 796 
 797         cmd = CAPIMSG_COMMAND(skb->data);
 798         subcmd = CAPIMSG_SUBCOMMAND(skb->data);
 799 
 800         if (cmd == CAPI_DATA_B3 && subcmd == CAPI_REQ) {
 801                 ctr->nsentdatapkt++;
 802                 ap->nsentdatapkt++;
 803                 if (ctr->traceflag > 2)
 804                         showctl |= 2;
 805         } else {
 806                 ctr->nsentctlpkt++;
 807                 ap->nsentctlpkt++;
 808                 if (ctr->traceflag)
 809                         showctl |= 2;
 810         }
 811         showctl |= (ctr->traceflag & 1);
 812         if (showctl & 2) {
 813                 if (showctl & 1) {
 814                         printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n",
 815                                CAPIMSG_CONTROLLER(skb->data),
 816                                CAPIMSG_APPID(skb->data),
 817                                capi_cmd2str(cmd, subcmd),
 818                                CAPIMSG_LEN(skb->data));
 819                 } else {
 820                         _cdebbuf *cdb = capi_message2str(skb->data);
 821                         if (cdb) {
 822                                 printk(KERN_DEBUG "kcapi: put [%03d] %s\n",
 823                                        CAPIMSG_CONTROLLER(skb->data),
 824                                        cdb->buf);
 825                                 cdebbuf_free(cdb);
 826                         } else
 827                                 printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u cannot trace\n",
 828                                        CAPIMSG_CONTROLLER(skb->data),
 829                                        CAPIMSG_APPID(skb->data),
 830                                        capi_cmd2str(cmd, subcmd),
 831                                        CAPIMSG_LEN(skb->data));
 832                 }
 833         }
 834         return ctr->send_message(ctr, skb);
 835 }
 836 
 837 EXPORT_SYMBOL(capi20_put_message);
 838 
 839 /**
 840  * capi20_get_manufacturer() - CAPI 2.0 operation CAPI_GET_MANUFACTURER
 841  * @contr:      controller number.
 842  * @buf:        result buffer (64 bytes).
 843  *
 844  * Retrieve information about the manufacturer of the specified ISDN controller
 845  * or (for @contr == 0) the driver itself.
 846  * Return value: CAPI result code
 847  */
 848 
 849 u16 capi20_get_manufacturer(u32 contr, u8 *buf)
 850 {
 851         struct capi_ctr *ctr;
 852         u16 ret;
 853 
 854         if (contr == 0) {
 855                 strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
 856                 return CAPI_NOERROR;
 857         }
 858 
 859         mutex_lock(&capi_controller_lock);
 860 
 861         ctr = get_capi_ctr_by_nr(contr);
 862         if (ctr && ctr->state == CAPI_CTR_RUNNING) {
 863                 strncpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN);
 864                 ret = CAPI_NOERROR;
 865         } else
 866                 ret = CAPI_REGNOTINSTALLED;
 867 
 868         mutex_unlock(&capi_controller_lock);
 869         return ret;
 870 }
 871 
 872 EXPORT_SYMBOL(capi20_get_manufacturer);
 873 
 874 /**
 875  * capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION
 876  * @contr:      controller number.
 877  * @verp:       result structure.
 878  *
 879  * Retrieve version information for the specified ISDN controller
 880  * or (for @contr == 0) the driver itself.
 881  * Return value: CAPI result code
 882  */
 883 
 884 u16 capi20_get_version(u32 contr, struct capi_version *verp)
 885 {
 886         struct capi_ctr *ctr;
 887         u16 ret;
 888 
 889         if (contr == 0) {
 890                 *verp = driver_version;
 891                 return CAPI_NOERROR;
 892         }
 893 
 894         mutex_lock(&capi_controller_lock);
 895 
 896         ctr = get_capi_ctr_by_nr(contr);
 897         if (ctr && ctr->state == CAPI_CTR_RUNNING) {
 898                 memcpy(verp, &ctr->version, sizeof(capi_version));
 899                 ret = CAPI_NOERROR;
 900         } else
 901                 ret = CAPI_REGNOTINSTALLED;
 902 
 903         mutex_unlock(&capi_controller_lock);
 904         return ret;
 905 }
 906 
 907 EXPORT_SYMBOL(capi20_get_version);
 908 
 909 /**
 910  * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER
 911  * @contr:      controller number.
 912  * @serial:     result buffer (8 bytes).
 913  *
 914  * Retrieve the serial number of the specified ISDN controller
 915  * or (for @contr == 0) the driver itself.
 916  * Return value: CAPI result code
 917  */
 918 
 919 u16 capi20_get_serial(u32 contr, u8 *serial)
 920 {
 921         struct capi_ctr *ctr;
 922         u16 ret;
 923 
 924         if (contr == 0) {
 925                 strlcpy(serial, driver_serial, CAPI_SERIAL_LEN);
 926                 return CAPI_NOERROR;
 927         }
 928 
 929         mutex_lock(&capi_controller_lock);
 930 
 931         ctr = get_capi_ctr_by_nr(contr);
 932         if (ctr && ctr->state == CAPI_CTR_RUNNING) {
 933                 strlcpy(serial, ctr->serial, CAPI_SERIAL_LEN);
 934                 ret = CAPI_NOERROR;
 935         } else
 936                 ret = CAPI_REGNOTINSTALLED;
 937 
 938         mutex_unlock(&capi_controller_lock);
 939         return ret;
 940 }
 941 
 942 EXPORT_SYMBOL(capi20_get_serial);
 943 
 944 /**
 945  * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE
 946  * @contr:      controller number.
 947  * @profp:      result structure.
 948  *
 949  * Retrieve capability information for the specified ISDN controller
 950  * or (for @contr == 0) the number of installed controllers.
 951  * Return value: CAPI result code
 952  */
 953 
 954 u16 capi20_get_profile(u32 contr, struct capi_profile *profp)
 955 {
 956         struct capi_ctr *ctr;
 957         u16 ret;
 958 
 959         if (contr == 0) {
 960                 profp->ncontroller = ncontrollers;
 961                 return CAPI_NOERROR;
 962         }
 963 
 964         mutex_lock(&capi_controller_lock);
 965 
 966         ctr = get_capi_ctr_by_nr(contr);
 967         if (ctr && ctr->state == CAPI_CTR_RUNNING) {
 968                 memcpy(profp, &ctr->profile, sizeof(struct capi_profile));
 969                 ret = CAPI_NOERROR;
 970         } else
 971                 ret = CAPI_REGNOTINSTALLED;
 972 
 973         mutex_unlock(&capi_controller_lock);
 974         return ret;
 975 }
 976 
 977 EXPORT_SYMBOL(capi20_get_profile);
 978 
 979 /* Must be called with capi_controller_lock held. */
 980 static int wait_on_ctr_state(struct capi_ctr *ctr, unsigned int state)
 981 {
 982         DEFINE_WAIT(wait);
 983         int retval = 0;
 984 
 985         ctr = capi_ctr_get(ctr);
 986         if (!ctr)
 987                 return -ESRCH;
 988 
 989         for (;;) {
 990                 prepare_to_wait(&ctr->state_wait_queue, &wait,
 991                                 TASK_INTERRUPTIBLE);
 992 
 993                 if (ctr->state == state)
 994                         break;
 995                 if (ctr->state == CAPI_CTR_DETACHED) {
 996                         retval = -ESRCH;
 997                         break;
 998                 }
 999                 if (signal_pending(current)) {
1000                         retval = -EINTR;
1001                         break;
1002                 }
1003 
1004                 mutex_unlock(&capi_controller_lock);
1005                 schedule();
1006                 mutex_lock(&capi_controller_lock);
1007         }
1008         finish_wait(&ctr->state_wait_queue, &wait);
1009 
1010         capi_ctr_put(ctr);
1011 
1012         return retval;
1013 }
1014 
1015 #ifdef AVMB1_COMPAT
1016 static int old_capi_manufacturer(unsigned int cmd, void __user *data)
1017 {
1018         avmb1_loadandconfigdef ldef;
1019         avmb1_extcarddef cdef;
1020         avmb1_resetdef rdef;
1021         capicardparams cparams;
1022         struct capi_ctr *ctr;
1023         struct capi_driver *driver = NULL;
1024         capiloaddata ldata;
1025         struct list_head *l;
1026         int retval;
1027 
1028         switch (cmd) {
1029         case AVMB1_ADDCARD:
1030         case AVMB1_ADDCARD_WITH_TYPE:
1031                 if (cmd == AVMB1_ADDCARD) {
1032                         if ((retval = copy_from_user(&cdef, data,
1033                                                      sizeof(avmb1_carddef))))
1034                                 return -EFAULT;
1035                         cdef.cardtype = AVM_CARDTYPE_B1;
1036                         cdef.cardnr = 0;
1037                 } else {
1038                         if ((retval = copy_from_user(&cdef, data,
1039                                                      sizeof(avmb1_extcarddef))))
1040                                 return -EFAULT;
1041                 }
1042                 cparams.port = cdef.port;
1043                 cparams.irq = cdef.irq;
1044                 cparams.cardnr = cdef.cardnr;
1045 
1046                 mutex_lock(&capi_drivers_lock);
1047 
1048                 switch (cdef.cardtype) {
1049                 case AVM_CARDTYPE_B1:
1050                         list_for_each(l, &capi_drivers) {
1051                                 driver = list_entry(l, struct capi_driver, list);
1052                                 if (strcmp(driver->name, "b1isa") == 0)
1053                                         break;
1054                         }
1055                         break;
1056                 case AVM_CARDTYPE_T1:
1057                         list_for_each(l, &capi_drivers) {
1058                                 driver = list_entry(l, struct capi_driver, list);
1059                                 if (strcmp(driver->name, "t1isa") == 0)
1060                                         break;
1061                         }
1062                         break;
1063                 default:
1064                         driver = NULL;
1065                         break;
1066                 }
1067                 if (!driver) {
1068                         printk(KERN_ERR "kcapi: driver not loaded.\n");
1069                         retval = -EIO;
1070                 } else if (!driver->add_card) {
1071                         printk(KERN_ERR "kcapi: driver has no add card function.\n");
1072                         retval = -EIO;
1073                 } else
1074                         retval = driver->add_card(driver, &cparams);
1075 
1076                 mutex_unlock(&capi_drivers_lock);
1077                 return retval;
1078 
1079         case AVMB1_LOAD:
1080         case AVMB1_LOAD_AND_CONFIG:
1081 
1082                 if (cmd == AVMB1_LOAD) {
1083                         if (copy_from_user(&ldef, data,
1084                                            sizeof(avmb1_loaddef)))
1085                                 return -EFAULT;
1086                         ldef.t4config.len = 0;
1087                         ldef.t4config.data = NULL;
1088                 } else {
1089                         if (copy_from_user(&ldef, data,
1090                                            sizeof(avmb1_loadandconfigdef)))
1091                                 return -EFAULT;
1092                 }
1093 
1094                 mutex_lock(&capi_controller_lock);
1095 
1096                 ctr = get_capi_ctr_by_nr(ldef.contr);
1097                 if (!ctr) {
1098                         retval = -EINVAL;
1099                         goto load_unlock_out;
1100                 }
1101 
1102                 if (ctr->load_firmware == NULL) {
1103                         printk(KERN_DEBUG "kcapi: load: no load function\n");
1104                         retval = -ESRCH;
1105                         goto load_unlock_out;
1106                 }
1107 
1108                 if (ldef.t4file.len <= 0) {
1109                         printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);
1110                         retval = -EINVAL;
1111                         goto load_unlock_out;
1112                 }
1113                 if (ldef.t4file.data == NULL) {
1114                         printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n");
1115                         retval = -EINVAL;
1116                         goto load_unlock_out;
1117                 }
1118 
1119                 ldata.firmware.user = 1;
1120                 ldata.firmware.data = ldef.t4file.data;
1121                 ldata.firmware.len = ldef.t4file.len;
1122                 ldata.configuration.user = 1;
1123                 ldata.configuration.data = ldef.t4config.data;
1124                 ldata.configuration.len = ldef.t4config.len;
1125 
1126                 if (ctr->state != CAPI_CTR_DETECTED) {
1127                         printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr);
1128                         retval = -EBUSY;
1129                         goto load_unlock_out;
1130                 }
1131                 ctr->state = CAPI_CTR_LOADING;
1132 
1133                 retval = ctr->load_firmware(ctr, &ldata);
1134                 if (retval) {
1135                         ctr->state = CAPI_CTR_DETECTED;
1136                         goto load_unlock_out;
1137                 }
1138 
1139                 retval = wait_on_ctr_state(ctr, CAPI_CTR_RUNNING);
1140 
1141         load_unlock_out:
1142                 mutex_unlock(&capi_controller_lock);
1143                 return retval;
1144 
1145         case AVMB1_RESETCARD:
1146                 if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef)))
1147                         return -EFAULT;
1148 
1149                 retval = 0;
1150 
1151                 mutex_lock(&capi_controller_lock);
1152 
1153                 ctr = get_capi_ctr_by_nr(rdef.contr);
1154                 if (!ctr) {
1155                         retval = -ESRCH;
1156                         goto reset_unlock_out;
1157                 }
1158 
1159                 if (ctr->state == CAPI_CTR_DETECTED)
1160                         goto reset_unlock_out;
1161 
1162                 if (ctr->reset_ctr == NULL) {
1163                         printk(KERN_DEBUG "kcapi: reset: no reset function\n");
1164                         retval = -ESRCH;
1165                         goto reset_unlock_out;
1166                 }
1167 
1168                 ctr->reset_ctr(ctr);
1169 
1170                 retval = wait_on_ctr_state(ctr, CAPI_CTR_DETECTED);
1171 
1172         reset_unlock_out:
1173                 mutex_unlock(&capi_controller_lock);
1174                 return retval;
1175         }
1176         return -EINVAL;
1177 }
1178 #endif
1179 
1180 /**
1181  * capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER
1182  * @cmd:        command.
1183  * @data:       parameter.
1184  *
1185  * Perform manufacturer specific command.
1186  * Return value: CAPI result code
1187  */
1188 
1189 int capi20_manufacturer(unsigned long cmd, void __user *data)
1190 {
1191         struct capi_ctr *ctr;
1192         int retval;
1193 
1194         switch (cmd) {
1195 #ifdef AVMB1_COMPAT
1196         case AVMB1_LOAD:
1197         case AVMB1_LOAD_AND_CONFIG:
1198         case AVMB1_RESETCARD:
1199         case AVMB1_GET_CARDINFO:
1200         case AVMB1_REMOVECARD:
1201                 return old_capi_manufacturer(cmd, data);
1202 #endif
1203         case KCAPI_CMD_TRACE:
1204         {
1205                 kcapi_flagdef fdef;
1206 
1207                 if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef)))
1208                         return -EFAULT;
1209 
1210                 mutex_lock(&capi_controller_lock);
1211 
1212                 ctr = get_capi_ctr_by_nr(fdef.contr);
1213                 if (ctr) {
1214                         ctr->traceflag = fdef.flag;
1215                         printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
1216                                ctr->cnr, ctr->traceflag);
1217                         retval = 0;
1218                 } else
1219                         retval = -ESRCH;
1220 
1221                 mutex_unlock(&capi_controller_lock);
1222 
1223                 return retval;
1224         }
1225         case KCAPI_CMD_ADDCARD:
1226         {
1227                 struct list_head *l;
1228                 struct capi_driver *driver = NULL;
1229                 capicardparams cparams;
1230                 kcapi_carddef cdef;
1231 
1232                 if ((retval = copy_from_user(&cdef, data, sizeof(cdef))))
1233                         return -EFAULT;
1234 
1235                 cparams.port = cdef.port;
1236                 cparams.irq = cdef.irq;
1237                 cparams.membase = cdef.membase;
1238                 cparams.cardnr = cdef.cardnr;
1239                 cparams.cardtype = 0;
1240                 cdef.driver[sizeof(cdef.driver) - 1] = 0;
1241 
1242                 mutex_lock(&capi_drivers_lock);
1243 
1244                 list_for_each(l, &capi_drivers) {
1245                         driver = list_entry(l, struct capi_driver, list);
1246                         if (strcmp(driver->name, cdef.driver) == 0)
1247                                 break;
1248                 }
1249                 if (driver == NULL) {
1250                         printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",
1251                                cdef.driver);
1252                         retval = -ESRCH;
1253                 } else if (!driver->add_card) {
1254                         printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);
1255                         retval = -EIO;
1256                 } else
1257                         retval = driver->add_card(driver, &cparams);
1258 
1259                 mutex_unlock(&capi_drivers_lock);
1260                 return retval;
1261         }
1262 
1263         default:
1264                 printk(KERN_ERR "kcapi: manufacturer command %lu unknown.\n",
1265                        cmd);
1266                 break;
1267 
1268         }
1269         return -EINVAL;
1270 }
1271 
1272 EXPORT_SYMBOL(capi20_manufacturer);
1273 
1274 /* ------------------------------------------------------------- */
1275 /* -------- Init & Cleanup ------------------------------------- */
1276 /* ------------------------------------------------------------- */
1277 
1278 /*
1279  * init / exit functions
1280  */
1281 
1282 static struct notifier_block capictr_nb = {
1283         .notifier_call = notify_handler,
1284         .priority = INT_MAX,
1285 };
1286 
1287 static int __init kcapi_init(void)
1288 {
1289         int err;
1290 
1291         kcapi_wq = alloc_workqueue("kcapi", 0, 0);
1292         if (!kcapi_wq)
1293                 return -ENOMEM;
1294 
1295         register_capictr_notifier(&capictr_nb);
1296 
1297         err = cdebug_init();
1298         if (err) {
1299                 unregister_capictr_notifier(&capictr_nb);
1300                 destroy_workqueue(kcapi_wq);
1301                 return err;
1302         }
1303 
1304         kcapi_proc_init();
1305         return 0;
1306 }
1307 
1308 static void __exit kcapi_exit(void)
1309 {
1310         kcapi_proc_exit();
1311 
1312         unregister_capictr_notifier(&capictr_nb);
1313         cdebug_exit();
1314         destroy_workqueue(kcapi_wq);
1315 }
1316 
1317 module_init(kcapi_init);
1318 module_exit(kcapi_exit);

/* [<][>][^][v][top][bottom][index][help] */