kcapi.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  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 <[email protected]>
  6. * Copyright 2002 by Kai Germaschewski <[email protected]>
  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. #include "kcapi.h"
  13. #include <linux/module.h>
  14. #include <linux/mm.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/ioport.h>
  17. #include <linux/proc_fs.h>
  18. #include <linux/sched/signal.h>
  19. #include <linux/seq_file.h>
  20. #include <linux/skbuff.h>
  21. #include <linux/workqueue.h>
  22. #include <linux/capi.h>
  23. #include <linux/kernelcapi.h>
  24. #include <linux/init.h>
  25. #include <linux/moduleparam.h>
  26. #include <linux/delay.h>
  27. #include <linux/slab.h>
  28. #include <linux/uaccess.h>
  29. #include <linux/isdn/capicmd.h>
  30. #include <linux/isdn/capiutil.h>
  31. #include <linux/mutex.h>
  32. #include <linux/rcupdate.h>
  33. static int showcapimsgs;
  34. static struct workqueue_struct *kcapi_wq;
  35. module_param(showcapimsgs, uint, 0);
  36. /* ------------------------------------------------------------- */
  37. struct capictr_event {
  38. struct work_struct work;
  39. unsigned int type;
  40. u32 controller;
  41. };
  42. /* ------------------------------------------------------------- */
  43. static const struct capi_version driver_version = {2, 0, 1, 1 << 4};
  44. static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
  45. static char capi_manufakturer[64] = "AVM Berlin";
  46. #define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
  47. struct capi_ctr *capi_controller[CAPI_MAXCONTR];
  48. DEFINE_MUTEX(capi_controller_lock);
  49. struct capi20_appl *capi_applications[CAPI_MAXAPPL];
  50. static int ncontrollers;
  51. /* -------- controller ref counting -------------------------------------- */
  52. static inline struct capi_ctr *
  53. capi_ctr_get(struct capi_ctr *ctr)
  54. {
  55. if (!try_module_get(ctr->owner))
  56. return NULL;
  57. return ctr;
  58. }
  59. static inline void
  60. capi_ctr_put(struct capi_ctr *ctr)
  61. {
  62. module_put(ctr->owner);
  63. }
  64. /* ------------------------------------------------------------- */
  65. static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
  66. {
  67. if (contr < 1 || contr - 1 >= CAPI_MAXCONTR)
  68. return NULL;
  69. return capi_controller[contr - 1];
  70. }
  71. static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
  72. {
  73. lockdep_assert_held(&capi_controller_lock);
  74. if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
  75. return NULL;
  76. return capi_applications[applid - 1];
  77. }
  78. static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
  79. {
  80. if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
  81. return NULL;
  82. return rcu_dereference(capi_applications[applid - 1]);
  83. }
  84. /* -------- util functions ------------------------------------ */
  85. static inline int capi_cmd_valid(u8 cmd)
  86. {
  87. switch (cmd) {
  88. case CAPI_ALERT:
  89. case CAPI_CONNECT:
  90. case CAPI_CONNECT_ACTIVE:
  91. case CAPI_CONNECT_B3_ACTIVE:
  92. case CAPI_CONNECT_B3:
  93. case CAPI_CONNECT_B3_T90_ACTIVE:
  94. case CAPI_DATA_B3:
  95. case CAPI_DISCONNECT_B3:
  96. case CAPI_DISCONNECT:
  97. case CAPI_FACILITY:
  98. case CAPI_INFO:
  99. case CAPI_LISTEN:
  100. case CAPI_MANUFACTURER:
  101. case CAPI_RESET_B3:
  102. case CAPI_SELECT_B_PROTOCOL:
  103. return 1;
  104. }
  105. return 0;
  106. }
  107. static inline int capi_subcmd_valid(u8 subcmd)
  108. {
  109. switch (subcmd) {
  110. case CAPI_REQ:
  111. case CAPI_CONF:
  112. case CAPI_IND:
  113. case CAPI_RESP:
  114. return 1;
  115. }
  116. return 0;
  117. }
  118. /* ------------------------------------------------------------ */
  119. static void
  120. register_appl(struct capi_ctr *ctr, u16 applid, capi_register_params *rparam)
  121. {
  122. ctr = capi_ctr_get(ctr);
  123. if (ctr)
  124. ctr->register_appl(ctr, applid, rparam);
  125. else
  126. printk(KERN_WARNING "%s: cannot get controller resources\n",
  127. __func__);
  128. }
  129. static void release_appl(struct capi_ctr *ctr, u16 applid)
  130. {
  131. DBG("applid %#x", applid);
  132. ctr->release_appl(ctr, applid);
  133. capi_ctr_put(ctr);
  134. }
  135. static void notify_up(u32 contr)
  136. {
  137. struct capi20_appl *ap;
  138. struct capi_ctr *ctr;
  139. u16 applid;
  140. mutex_lock(&capi_controller_lock);
  141. if (showcapimsgs & 1)
  142. printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
  143. ctr = get_capi_ctr_by_nr(contr);
  144. if (ctr) {
  145. if (ctr->state == CAPI_CTR_RUNNING)
  146. goto unlock_out;
  147. ctr->state = CAPI_CTR_RUNNING;
  148. for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
  149. ap = __get_capi_appl_by_nr(applid);
  150. if (ap)
  151. register_appl(ctr, applid, &ap->rparam);
  152. }
  153. } else
  154. printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
  155. unlock_out:
  156. mutex_unlock(&capi_controller_lock);
  157. }
  158. static void ctr_down(struct capi_ctr *ctr, int new_state)
  159. {
  160. struct capi20_appl *ap;
  161. u16 applid;
  162. if (ctr->state == CAPI_CTR_DETECTED || ctr->state == CAPI_CTR_DETACHED)
  163. return;
  164. ctr->state = new_state;
  165. memset(ctr->manu, 0, sizeof(ctr->manu));
  166. memset(&ctr->version, 0, sizeof(ctr->version));
  167. memset(&ctr->profile, 0, sizeof(ctr->profile));
  168. memset(ctr->serial, 0, sizeof(ctr->serial));
  169. for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
  170. ap = __get_capi_appl_by_nr(applid);
  171. if (ap)
  172. capi_ctr_put(ctr);
  173. }
  174. }
  175. static void notify_down(u32 contr)
  176. {
  177. struct capi_ctr *ctr;
  178. mutex_lock(&capi_controller_lock);
  179. if (showcapimsgs & 1)
  180. printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
  181. ctr = get_capi_ctr_by_nr(contr);
  182. if (ctr)
  183. ctr_down(ctr, CAPI_CTR_DETECTED);
  184. else
  185. printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
  186. mutex_unlock(&capi_controller_lock);
  187. }
  188. static void do_notify_work(struct work_struct *work)
  189. {
  190. struct capictr_event *event =
  191. container_of(work, struct capictr_event, work);
  192. switch (event->type) {
  193. case CAPICTR_UP:
  194. notify_up(event->controller);
  195. break;
  196. case CAPICTR_DOWN:
  197. notify_down(event->controller);
  198. break;
  199. }
  200. kfree(event);
  201. }
  202. static int notify_push(unsigned int event_type, u32 controller)
  203. {
  204. struct capictr_event *event = kmalloc(sizeof(*event), GFP_ATOMIC);
  205. if (!event)
  206. return -ENOMEM;
  207. INIT_WORK(&event->work, do_notify_work);
  208. event->type = event_type;
  209. event->controller = controller;
  210. queue_work(kcapi_wq, &event->work);
  211. return 0;
  212. }
  213. /* -------- Receiver ------------------------------------------ */
  214. static void recv_handler(struct work_struct *work)
  215. {
  216. struct sk_buff *skb;
  217. struct capi20_appl *ap =
  218. container_of(work, struct capi20_appl, recv_work);
  219. if ((!ap) || (ap->release_in_progress))
  220. return;
  221. mutex_lock(&ap->recv_mtx);
  222. while ((skb = skb_dequeue(&ap->recv_queue))) {
  223. if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_IND)
  224. ap->nrecvdatapkt++;
  225. else
  226. ap->nrecvctlpkt++;
  227. ap->recv_message(ap, skb);
  228. }
  229. mutex_unlock(&ap->recv_mtx);
  230. }
  231. /**
  232. * capi_ctr_handle_message() - handle incoming CAPI message
  233. * @ctr: controller descriptor structure.
  234. * @appl: application ID.
  235. * @skb: message.
  236. *
  237. * Called by hardware driver to pass a CAPI message to the application.
  238. */
  239. void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
  240. struct sk_buff *skb)
  241. {
  242. struct capi20_appl *ap;
  243. int showctl = 0;
  244. u8 cmd, subcmd;
  245. _cdebbuf *cdb;
  246. if (ctr->state != CAPI_CTR_RUNNING) {
  247. cdb = capi_message2str(skb->data);
  248. if (cdb) {
  249. printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
  250. ctr->cnr, cdb->buf);
  251. cdebbuf_free(cdb);
  252. } else
  253. printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
  254. ctr->cnr);
  255. goto error;
  256. }
  257. cmd = CAPIMSG_COMMAND(skb->data);
  258. subcmd = CAPIMSG_SUBCOMMAND(skb->data);
  259. if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
  260. ctr->nrecvdatapkt++;
  261. if (ctr->traceflag > 2)
  262. showctl |= 2;
  263. } else {
  264. ctr->nrecvctlpkt++;
  265. if (ctr->traceflag)
  266. showctl |= 2;
  267. }
  268. showctl |= (ctr->traceflag & 1);
  269. if (showctl & 2) {
  270. if (showctl & 1) {
  271. printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n",
  272. ctr->cnr, CAPIMSG_APPID(skb->data),
  273. capi_cmd2str(cmd, subcmd),
  274. CAPIMSG_LEN(skb->data));
  275. } else {
  276. cdb = capi_message2str(skb->data);
  277. if (cdb) {
  278. printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
  279. ctr->cnr, cdb->buf);
  280. cdebbuf_free(cdb);
  281. } else
  282. printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
  283. ctr->cnr, CAPIMSG_APPID(skb->data),
  284. capi_cmd2str(cmd, subcmd),
  285. CAPIMSG_LEN(skb->data));
  286. }
  287. }
  288. rcu_read_lock();
  289. ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
  290. if (!ap) {
  291. rcu_read_unlock();
  292. cdb = capi_message2str(skb->data);
  293. if (cdb) {
  294. printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
  295. CAPIMSG_APPID(skb->data), cdb->buf);
  296. cdebbuf_free(cdb);
  297. } else
  298. printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n",
  299. CAPIMSG_APPID(skb->data),
  300. capi_cmd2str(cmd, subcmd));
  301. goto error;
  302. }
  303. skb_queue_tail(&ap->recv_queue, skb);
  304. queue_work(kcapi_wq, &ap->recv_work);
  305. rcu_read_unlock();
  306. return;
  307. error:
  308. kfree_skb(skb);
  309. }
  310. EXPORT_SYMBOL(capi_ctr_handle_message);
  311. /**
  312. * capi_ctr_ready() - signal CAPI controller ready
  313. * @ctr: controller descriptor structure.
  314. *
  315. * Called by hardware driver to signal that the controller is up and running.
  316. */
  317. void capi_ctr_ready(struct capi_ctr *ctr)
  318. {
  319. printk(KERN_NOTICE "kcapi: controller [%03d] \"%s\" ready.\n",
  320. ctr->cnr, ctr->name);
  321. notify_push(CAPICTR_UP, ctr->cnr);
  322. }
  323. EXPORT_SYMBOL(capi_ctr_ready);
  324. /**
  325. * capi_ctr_down() - signal CAPI controller not ready
  326. * @ctr: controller descriptor structure.
  327. *
  328. * Called by hardware driver to signal that the controller is down and
  329. * unavailable for use.
  330. */
  331. void capi_ctr_down(struct capi_ctr *ctr)
  332. {
  333. printk(KERN_NOTICE "kcapi: controller [%03d] down.\n", ctr->cnr);
  334. notify_push(CAPICTR_DOWN, ctr->cnr);
  335. }
  336. EXPORT_SYMBOL(capi_ctr_down);
  337. /* ------------------------------------------------------------- */
  338. /**
  339. * attach_capi_ctr() - register CAPI controller
  340. * @ctr: controller descriptor structure.
  341. *
  342. * Called by hardware driver to register a controller with the CAPI subsystem.
  343. * Return value: 0 on success, error code < 0 on error
  344. */
  345. int attach_capi_ctr(struct capi_ctr *ctr)
  346. {
  347. int i;
  348. mutex_lock(&capi_controller_lock);
  349. for (i = 0; i < CAPI_MAXCONTR; i++) {
  350. if (!capi_controller[i])
  351. break;
  352. }
  353. if (i == CAPI_MAXCONTR) {
  354. mutex_unlock(&capi_controller_lock);
  355. printk(KERN_ERR "kcapi: out of controller slots\n");
  356. return -EBUSY;
  357. }
  358. capi_controller[i] = ctr;
  359. ctr->nrecvctlpkt = 0;
  360. ctr->nrecvdatapkt = 0;
  361. ctr->nsentctlpkt = 0;
  362. ctr->nsentdatapkt = 0;
  363. ctr->cnr = i + 1;
  364. ctr->state = CAPI_CTR_DETECTED;
  365. ctr->blocked = 0;
  366. ctr->traceflag = showcapimsgs;
  367. sprintf(ctr->procfn, "capi/controllers/%d", ctr->cnr);
  368. ctr->procent = proc_create_single_data(ctr->procfn, 0, NULL,
  369. ctr->proc_show, ctr);
  370. ncontrollers++;
  371. mutex_unlock(&capi_controller_lock);
  372. printk(KERN_NOTICE "kcapi: controller [%03d]: %s attached\n",
  373. ctr->cnr, ctr->name);
  374. return 0;
  375. }
  376. EXPORT_SYMBOL(attach_capi_ctr);
  377. /**
  378. * detach_capi_ctr() - unregister CAPI controller
  379. * @ctr: controller descriptor structure.
  380. *
  381. * Called by hardware driver to remove the registration of a controller
  382. * with the CAPI subsystem.
  383. * Return value: 0 on success, error code < 0 on error
  384. */
  385. int detach_capi_ctr(struct capi_ctr *ctr)
  386. {
  387. int err = 0;
  388. mutex_lock(&capi_controller_lock);
  389. ctr_down(ctr, CAPI_CTR_DETACHED);
  390. if (ctr->cnr < 1 || ctr->cnr - 1 >= CAPI_MAXCONTR) {
  391. err = -EINVAL;
  392. goto unlock_out;
  393. }
  394. if (capi_controller[ctr->cnr - 1] != ctr) {
  395. err = -EINVAL;
  396. goto unlock_out;
  397. }
  398. capi_controller[ctr->cnr - 1] = NULL;
  399. ncontrollers--;
  400. if (ctr->procent)
  401. remove_proc_entry(ctr->procfn, NULL);
  402. printk(KERN_NOTICE "kcapi: controller [%03d]: %s unregistered\n",
  403. ctr->cnr, ctr->name);
  404. unlock_out:
  405. mutex_unlock(&capi_controller_lock);
  406. return err;
  407. }
  408. EXPORT_SYMBOL(detach_capi_ctr);
  409. /* ------------------------------------------------------------- */
  410. /* -------- CAPI2.0 Interface ---------------------------------- */
  411. /* ------------------------------------------------------------- */
  412. /**
  413. * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED
  414. *
  415. * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller
  416. * is ready for use, CAPI_REGNOTINSTALLED otherwise)
  417. */
  418. u16 capi20_isinstalled(void)
  419. {
  420. u16 ret = CAPI_REGNOTINSTALLED;
  421. int i;
  422. mutex_lock(&capi_controller_lock);
  423. for (i = 0; i < CAPI_MAXCONTR; i++)
  424. if (capi_controller[i] &&
  425. capi_controller[i]->state == CAPI_CTR_RUNNING) {
  426. ret = CAPI_NOERROR;
  427. break;
  428. }
  429. mutex_unlock(&capi_controller_lock);
  430. return ret;
  431. }
  432. /**
  433. * capi20_register() - CAPI 2.0 operation CAPI_REGISTER
  434. * @ap: CAPI application descriptor structure.
  435. *
  436. * Register an application's presence with CAPI.
  437. * A unique application ID is assigned and stored in @ap->applid.
  438. * After this function returns successfully, the message receive
  439. * callback function @ap->recv_message() may be called at any time
  440. * until capi20_release() has been called for the same @ap.
  441. * Return value: CAPI result code
  442. */
  443. u16 capi20_register(struct capi20_appl *ap)
  444. {
  445. int i;
  446. u16 applid;
  447. DBG("");
  448. if (ap->rparam.datablklen < 128)
  449. return CAPI_LOGBLKSIZETOSMALL;
  450. ap->nrecvctlpkt = 0;
  451. ap->nrecvdatapkt = 0;
  452. ap->nsentctlpkt = 0;
  453. ap->nsentdatapkt = 0;
  454. mutex_init(&ap->recv_mtx);
  455. skb_queue_head_init(&ap->recv_queue);
  456. INIT_WORK(&ap->recv_work, recv_handler);
  457. ap->release_in_progress = 0;
  458. mutex_lock(&capi_controller_lock);
  459. for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
  460. if (capi_applications[applid - 1] == NULL)
  461. break;
  462. }
  463. if (applid > CAPI_MAXAPPL) {
  464. mutex_unlock(&capi_controller_lock);
  465. return CAPI_TOOMANYAPPLS;
  466. }
  467. ap->applid = applid;
  468. capi_applications[applid - 1] = ap;
  469. for (i = 0; i < CAPI_MAXCONTR; i++) {
  470. if (!capi_controller[i] ||
  471. capi_controller[i]->state != CAPI_CTR_RUNNING)
  472. continue;
  473. register_appl(capi_controller[i], applid, &ap->rparam);
  474. }
  475. mutex_unlock(&capi_controller_lock);
  476. if (showcapimsgs & 1) {
  477. printk(KERN_DEBUG "kcapi: appl %d up\n", applid);
  478. }
  479. return CAPI_NOERROR;
  480. }
  481. /**
  482. * capi20_release() - CAPI 2.0 operation CAPI_RELEASE
  483. * @ap: CAPI application descriptor structure.
  484. *
  485. * Terminate an application's registration with CAPI.
  486. * After this function returns successfully, the message receive
  487. * callback function @ap->recv_message() will no longer be called.
  488. * Return value: CAPI result code
  489. */
  490. u16 capi20_release(struct capi20_appl *ap)
  491. {
  492. int i;
  493. DBG("applid %#x", ap->applid);
  494. mutex_lock(&capi_controller_lock);
  495. ap->release_in_progress = 1;
  496. capi_applications[ap->applid - 1] = NULL;
  497. synchronize_rcu();
  498. for (i = 0; i < CAPI_MAXCONTR; i++) {
  499. if (!capi_controller[i] ||
  500. capi_controller[i]->state != CAPI_CTR_RUNNING)
  501. continue;
  502. release_appl(capi_controller[i], ap->applid);
  503. }
  504. mutex_unlock(&capi_controller_lock);
  505. flush_workqueue(kcapi_wq);
  506. skb_queue_purge(&ap->recv_queue);
  507. if (showcapimsgs & 1) {
  508. printk(KERN_DEBUG "kcapi: appl %d down\n", ap->applid);
  509. }
  510. return CAPI_NOERROR;
  511. }
  512. /**
  513. * capi20_put_message() - CAPI 2.0 operation CAPI_PUT_MESSAGE
  514. * @ap: CAPI application descriptor structure.
  515. * @skb: CAPI message.
  516. *
  517. * Transfer a single message to CAPI.
  518. * Return value: CAPI result code
  519. */
  520. u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
  521. {
  522. struct capi_ctr *ctr;
  523. int showctl = 0;
  524. u8 cmd, subcmd;
  525. DBG("applid %#x", ap->applid);
  526. if (ncontrollers == 0)
  527. return CAPI_REGNOTINSTALLED;
  528. if ((ap->applid == 0) || ap->release_in_progress)
  529. return CAPI_ILLAPPNR;
  530. if (skb->len < 12
  531. || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
  532. || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
  533. return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
  534. /*
  535. * The controller reference is protected by the existence of the
  536. * application passed to us. We assume that the caller properly
  537. * synchronizes this service with capi20_release.
  538. */
  539. ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
  540. if (!ctr || ctr->state != CAPI_CTR_RUNNING)
  541. return CAPI_REGNOTINSTALLED;
  542. if (ctr->blocked)
  543. return CAPI_SENDQUEUEFULL;
  544. cmd = CAPIMSG_COMMAND(skb->data);
  545. subcmd = CAPIMSG_SUBCOMMAND(skb->data);
  546. if (cmd == CAPI_DATA_B3 && subcmd == CAPI_REQ) {
  547. ctr->nsentdatapkt++;
  548. ap->nsentdatapkt++;
  549. if (ctr->traceflag > 2)
  550. showctl |= 2;
  551. } else {
  552. ctr->nsentctlpkt++;
  553. ap->nsentctlpkt++;
  554. if (ctr->traceflag)
  555. showctl |= 2;
  556. }
  557. showctl |= (ctr->traceflag & 1);
  558. if (showctl & 2) {
  559. if (showctl & 1) {
  560. printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n",
  561. CAPIMSG_CONTROLLER(skb->data),
  562. CAPIMSG_APPID(skb->data),
  563. capi_cmd2str(cmd, subcmd),
  564. CAPIMSG_LEN(skb->data));
  565. } else {
  566. _cdebbuf *cdb = capi_message2str(skb->data);
  567. if (cdb) {
  568. printk(KERN_DEBUG "kcapi: put [%03d] %s\n",
  569. CAPIMSG_CONTROLLER(skb->data),
  570. cdb->buf);
  571. cdebbuf_free(cdb);
  572. } else
  573. printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u cannot trace\n",
  574. CAPIMSG_CONTROLLER(skb->data),
  575. CAPIMSG_APPID(skb->data),
  576. capi_cmd2str(cmd, subcmd),
  577. CAPIMSG_LEN(skb->data));
  578. }
  579. }
  580. return ctr->send_message(ctr, skb);
  581. }
  582. /**
  583. * capi20_get_manufacturer() - CAPI 2.0 operation CAPI_GET_MANUFACTURER
  584. * @contr: controller number.
  585. * @buf: result buffer (64 bytes).
  586. *
  587. * Retrieve information about the manufacturer of the specified ISDN controller
  588. * or (for @contr == 0) the driver itself.
  589. * Return value: CAPI result code
  590. */
  591. u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN])
  592. {
  593. struct capi_ctr *ctr;
  594. u16 ret;
  595. if (contr == 0) {
  596. strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
  597. return CAPI_NOERROR;
  598. }
  599. mutex_lock(&capi_controller_lock);
  600. ctr = get_capi_ctr_by_nr(contr);
  601. if (ctr && ctr->state == CAPI_CTR_RUNNING) {
  602. strncpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN);
  603. ret = CAPI_NOERROR;
  604. } else
  605. ret = CAPI_REGNOTINSTALLED;
  606. mutex_unlock(&capi_controller_lock);
  607. return ret;
  608. }
  609. /**
  610. * capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION
  611. * @contr: controller number.
  612. * @verp: result structure.
  613. *
  614. * Retrieve version information for the specified ISDN controller
  615. * or (for @contr == 0) the driver itself.
  616. * Return value: CAPI result code
  617. */
  618. u16 capi20_get_version(u32 contr, struct capi_version *verp)
  619. {
  620. struct capi_ctr *ctr;
  621. u16 ret;
  622. if (contr == 0) {
  623. *verp = driver_version;
  624. return CAPI_NOERROR;
  625. }
  626. mutex_lock(&capi_controller_lock);
  627. ctr = get_capi_ctr_by_nr(contr);
  628. if (ctr && ctr->state == CAPI_CTR_RUNNING) {
  629. memcpy(verp, &ctr->version, sizeof(capi_version));
  630. ret = CAPI_NOERROR;
  631. } else
  632. ret = CAPI_REGNOTINSTALLED;
  633. mutex_unlock(&capi_controller_lock);
  634. return ret;
  635. }
  636. /**
  637. * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER
  638. * @contr: controller number.
  639. * @serial: result buffer (8 bytes).
  640. *
  641. * Retrieve the serial number of the specified ISDN controller
  642. * or (for @contr == 0) the driver itself.
  643. * Return value: CAPI result code
  644. */
  645. u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN])
  646. {
  647. struct capi_ctr *ctr;
  648. u16 ret;
  649. if (contr == 0) {
  650. strscpy(serial, driver_serial, CAPI_SERIAL_LEN);
  651. return CAPI_NOERROR;
  652. }
  653. mutex_lock(&capi_controller_lock);
  654. ctr = get_capi_ctr_by_nr(contr);
  655. if (ctr && ctr->state == CAPI_CTR_RUNNING) {
  656. strscpy(serial, ctr->serial, CAPI_SERIAL_LEN);
  657. ret = CAPI_NOERROR;
  658. } else
  659. ret = CAPI_REGNOTINSTALLED;
  660. mutex_unlock(&capi_controller_lock);
  661. return ret;
  662. }
  663. /**
  664. * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE
  665. * @contr: controller number.
  666. * @profp: result structure.
  667. *
  668. * Retrieve capability information for the specified ISDN controller
  669. * or (for @contr == 0) the number of installed controllers.
  670. * Return value: CAPI result code
  671. */
  672. u16 capi20_get_profile(u32 contr, struct capi_profile *profp)
  673. {
  674. struct capi_ctr *ctr;
  675. u16 ret;
  676. if (contr == 0) {
  677. profp->ncontroller = ncontrollers;
  678. return CAPI_NOERROR;
  679. }
  680. mutex_lock(&capi_controller_lock);
  681. ctr = get_capi_ctr_by_nr(contr);
  682. if (ctr && ctr->state == CAPI_CTR_RUNNING) {
  683. memcpy(profp, &ctr->profile, sizeof(struct capi_profile));
  684. ret = CAPI_NOERROR;
  685. } else
  686. ret = CAPI_REGNOTINSTALLED;
  687. mutex_unlock(&capi_controller_lock);
  688. return ret;
  689. }
  690. /**
  691. * capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER
  692. * @cmd: command.
  693. * @data: parameter.
  694. *
  695. * Perform manufacturer specific command.
  696. * Return value: CAPI result code
  697. */
  698. int capi20_manufacturer(unsigned long cmd, void __user *data)
  699. {
  700. struct capi_ctr *ctr;
  701. int retval;
  702. switch (cmd) {
  703. case KCAPI_CMD_TRACE:
  704. {
  705. kcapi_flagdef fdef;
  706. if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef)))
  707. return -EFAULT;
  708. mutex_lock(&capi_controller_lock);
  709. ctr = get_capi_ctr_by_nr(fdef.contr);
  710. if (ctr) {
  711. ctr->traceflag = fdef.flag;
  712. printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
  713. ctr->cnr, ctr->traceflag);
  714. retval = 0;
  715. } else
  716. retval = -ESRCH;
  717. mutex_unlock(&capi_controller_lock);
  718. return retval;
  719. }
  720. default:
  721. printk(KERN_ERR "kcapi: manufacturer command %lu unknown.\n",
  722. cmd);
  723. break;
  724. }
  725. return -EINVAL;
  726. }
  727. /* ------------------------------------------------------------- */
  728. /* -------- Init & Cleanup ------------------------------------- */
  729. /* ------------------------------------------------------------- */
  730. /*
  731. * init / exit functions
  732. */
  733. int __init kcapi_init(void)
  734. {
  735. int err;
  736. kcapi_wq = alloc_workqueue("kcapi", 0, 0);
  737. if (!kcapi_wq)
  738. return -ENOMEM;
  739. err = cdebug_init();
  740. if (err) {
  741. destroy_workqueue(kcapi_wq);
  742. return err;
  743. }
  744. kcapi_proc_init();
  745. return 0;
  746. }
  747. void kcapi_exit(void)
  748. {
  749. kcapi_proc_exit();
  750. cdebug_exit();
  751. destroy_workqueue(kcapi_wq);
  752. }