capi.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:47k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: capi.c,v 1.1.4.2 2001/12/09 18:45:13 kai Exp $
  2.  *
  3.  * CAPI 2.0 Interface for Linux
  4.  *
  5.  * Copyright 1996 by Carsten Paeth <calle@calle.de>
  6.  *
  7.  * This software may be used and distributed according to the terms
  8.  * of the GNU General Public License, incorporated herein by reference.
  9.  *
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/module.h>
  13. #include <linux/errno.h>
  14. #include <linux/kernel.h>
  15. #include <linux/major.h>
  16. #include <linux/sched.h>
  17. #include <linux/slab.h>
  18. #include <linux/fcntl.h>
  19. #include <linux/fs.h>
  20. #include <linux/signal.h>
  21. #include <linux/mm.h>
  22. #include <linux/smp_lock.h>
  23. #include <linux/timer.h>
  24. #include <linux/wait.h>
  25. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  26. #include <linux/tty.h>
  27. #ifdef CONFIG_PPP
  28. #include <linux/netdevice.h>
  29. #include <linux/ppp_defs.h>
  30. #include <linux/if_ppp.h>
  31. #undef CAPI_PPP_ON_RAW_DEVICE
  32. #endif /* CONFIG_PPP */
  33. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  34. #include <linux/skbuff.h>
  35. #include <linux/proc_fs.h>
  36. #include <linux/poll.h>
  37. #include <linux/capi.h>
  38. #include <linux/kernelcapi.h>
  39. #include <linux/init.h>
  40. #include <linux/devfs_fs_kernel.h>
  41. #include "capiutil.h"
  42. #include "capicmd.h"
  43. #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
  44. #include "capifs.h"
  45. #endif
  46. static char *revision = "$Revision: 1.1.4.2 $";
  47. MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
  48. MODULE_AUTHOR("Carsten Paeth");
  49. MODULE_LICENSE("GPL");
  50. #undef _DEBUG_REFCOUNT /* alloc/free and open/close debug */
  51. #undef _DEBUG_TTYFUNCS /* call to tty_driver */
  52. #undef _DEBUG_DATAFLOW /* data flow */
  53. /* -------- driver information -------------------------------------- */
  54. int capi_major = 68; /* allocated */
  55. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  56. int capi_rawmajor = 190;
  57. int capi_ttymajor = 191;
  58. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  59. MODULE_PARM(capi_major, "i");
  60. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  61. MODULE_PARM(capi_rawmajor, "i");
  62. MODULE_PARM(capi_ttymajor, "i");
  63. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  64. /* -------- defines ------------------------------------------------- */
  65. #define CAPINC_MAX_RECVQUEUE 10
  66. #define CAPINC_MAX_SENDQUEUE 10
  67. #define CAPI_MAX_BLKSIZE 2048
  68. /* -------- data structures ----------------------------------------- */
  69. struct capidev;
  70. struct capincci;
  71. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  72. struct capiminor;
  73. struct capiminor {
  74. struct capiminor *next;
  75. struct capincci  *nccip;
  76. unsigned int      minor;
  77. u16    applid;
  78. u32  ncci;
  79. u16  datahandle;
  80. u16  msgid;
  81. struct file      *file;
  82. struct tty_struct *tty;
  83. int                ttyinstop;
  84. int                ttyoutstop;
  85. struct sk_buff    *ttyskb;
  86. atomic_t           ttyopencount;
  87. struct sk_buff_head inqueue;
  88. int                 inbytes;
  89. struct sk_buff_head outqueue;
  90. int                 outbytes;
  91. /* for raw device */
  92. struct sk_buff_head recvqueue;
  93. wait_queue_head_t recvwait;
  94. wait_queue_head_t sendwait;
  95. /* transmit path */
  96. struct datahandle_queue {
  97.     struct datahandle_queue *next;
  98.     u16                      datahandle;
  99. } *ackqueue;
  100. int nack;
  101. };
  102. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  103. struct capincci {
  104. struct capincci *next;
  105. u32  ncci;
  106. struct capidev *cdev;
  107. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  108. struct capiminor *minorp;
  109. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  110. };
  111. struct capidev {
  112. struct capidev *next;
  113. struct file    *file;
  114. u16 applid;
  115. u16 errcode;
  116. unsigned int    minor;
  117. unsigned        userflags;
  118. struct sk_buff_head recvqueue;
  119. wait_queue_head_t recvwait;
  120. /* Statistic */
  121. unsigned long nrecvctlpkt;
  122. unsigned long nrecvdatapkt;
  123. unsigned long nsentctlpkt;
  124. unsigned long nsentdatapkt;
  125. struct capincci *nccis;
  126. };
  127. /* -------- global variables ---------------------------------------- */
  128. static struct capi_interface *capifuncs = 0;
  129. static struct capidev *capidev_openlist = 0;
  130. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  131. static struct capiminor *minors = 0;
  132. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  133. static kmem_cache_t *capidev_cachep = 0;
  134. static kmem_cache_t *capincci_cachep = 0;
  135. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  136. static kmem_cache_t *capiminor_cachep = 0;
  137. static kmem_cache_t *capidh_cachep = 0;
  138. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  139. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  140. /* -------- datahandles --------------------------------------------- */
  141. static int capincci_add_ack(struct capiminor *mp, u16 datahandle)
  142. {
  143. struct datahandle_queue *n, **pp;
  144. n = (struct datahandle_queue *)
  145. kmem_cache_alloc(capidh_cachep, GFP_ATOMIC);
  146. if (!n) {
  147.    printk(KERN_ERR "capi: alloc datahandle failedn");
  148.    return -1;
  149. }
  150. n->next = 0;
  151. n->datahandle = datahandle;
  152. for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) ;
  153. *pp = n;
  154. mp->nack++;
  155. return 0;
  156. }
  157. static int capiminor_del_ack(struct capiminor *mp, u16 datahandle)
  158. {
  159. struct datahandle_queue **pp, *p;
  160. for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) {
  161.   if ((*pp)->datahandle == datahandle) {
  162. p = *pp;
  163. *pp = (*pp)->next;
  164. kmem_cache_free(capidh_cachep, p);
  165. mp->nack--;
  166. return 0;
  167. }
  168. }
  169. return -1;
  170. }
  171. static void capiminor_del_all_ack(struct capiminor *mp)
  172. {
  173. struct datahandle_queue **pp, *p;
  174. pp = &mp->ackqueue;
  175. while (*pp) {
  176. p = *pp;
  177. *pp = (*pp)->next;
  178. kmem_cache_free(capidh_cachep, p);
  179. mp->nack--;
  180. }
  181. }
  182. /* -------- struct capiminor ---------------------------------------- */
  183. static struct capiminor *capiminor_alloc(u16 applid, u32 ncci)
  184. {
  185. struct capiminor *mp, **pp;
  186.         unsigned int minor = 0;
  187. MOD_INC_USE_COUNT;
  188. mp = (struct capiminor *)kmem_cache_alloc(capiminor_cachep, GFP_ATOMIC);
  189. if (!mp) {
  190. MOD_DEC_USE_COUNT;
  191. printk(KERN_ERR "capi: can't alloc capiminorn");
  192. return 0;
  193. }
  194. #ifdef _DEBUG_REFCOUNT
  195. printk(KERN_DEBUG "capiminor_alloc %dn", GET_USE_COUNT(THIS_MODULE));
  196. #endif
  197. memset(mp, 0, sizeof(struct capiminor));
  198. mp->applid = applid;
  199. mp->ncci = ncci;
  200. mp->msgid = 0;
  201. atomic_set(&mp->ttyopencount,0);
  202. skb_queue_head_init(&mp->inqueue);
  203. skb_queue_head_init(&mp->outqueue);
  204. skb_queue_head_init(&mp->recvqueue);
  205. init_waitqueue_head(&mp->recvwait);
  206. init_waitqueue_head(&mp->sendwait);
  207. for (pp = &minors; *pp; pp = &(*pp)->next) {
  208. if ((*pp)->minor < minor)
  209. continue;
  210. if ((*pp)->minor > minor)
  211. break;
  212. minor++;
  213. }
  214. mp->minor = minor;
  215. mp->next = *pp;
  216. *pp = mp;
  217. return mp;
  218. }
  219. static void capiminor_free(struct capiminor *mp)
  220. {
  221. struct capiminor **pp;
  222. pp = &minors;
  223. while (*pp) {
  224. if (*pp == mp) {
  225. *pp = (*pp)->next;
  226. if (mp->ttyskb) kfree_skb(mp->ttyskb);
  227. mp->ttyskb = 0;
  228. skb_queue_purge(&mp->recvqueue);
  229. skb_queue_purge(&mp->inqueue);
  230. skb_queue_purge(&mp->outqueue);
  231. capiminor_del_all_ack(mp);
  232. kmem_cache_free(capiminor_cachep, mp);
  233. MOD_DEC_USE_COUNT;
  234. #ifdef _DEBUG_REFCOUNT
  235. printk(KERN_DEBUG "capiminor_free %dn", GET_USE_COUNT(THIS_MODULE));
  236. #endif
  237. return;
  238. } else {
  239. pp = &(*pp)->next;
  240. }
  241. }
  242. }
  243. static struct capiminor *capiminor_find(unsigned int minor)
  244. {
  245. struct capiminor *p;
  246. for (p = minors; p && p->minor != minor; p = p->next)
  247. ;
  248. return p;
  249. }
  250. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  251. /* -------- struct capincci ----------------------------------------- */
  252. static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci)
  253. {
  254. struct capincci *np, **pp;
  255. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  256. struct capiminor *mp = 0;
  257. kdev_t kdev;
  258. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  259. np = (struct capincci *)kmem_cache_alloc(capincci_cachep, GFP_ATOMIC);
  260. if (!np)
  261. return 0;
  262. memset(np, 0, sizeof(struct capincci));
  263. np->ncci = ncci;
  264. np->cdev = cdev;
  265. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  266. mp = 0;
  267. if (cdev->userflags & CAPIFLAG_HIGHJACKING)
  268. mp = np->minorp = capiminor_alloc(cdev->applid, ncci);
  269. if (mp) {
  270. mp->nccip = np;
  271. #ifdef _DEBUG_REFCOUNT
  272. printk(KERN_DEBUG "set mp->nccipn");
  273. #endif
  274. #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
  275. kdev = MKDEV(capi_rawmajor, mp->minor);
  276. capifs_new_ncci('r', mp->minor, kdev);
  277. kdev = MKDEV(capi_ttymajor, mp->minor);
  278. capifs_new_ncci(0, mp->minor, kdev);
  279. #endif
  280. }
  281. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  282. for (pp=&cdev->nccis; *pp; pp = &(*pp)->next)
  283. ;
  284. *pp = np;
  285.         return np;
  286. }
  287. static void capincci_free(struct capidev *cdev, u32 ncci)
  288. {
  289. struct capincci *np, **pp;
  290. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  291. struct capiminor *mp;
  292. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  293. pp=&cdev->nccis;
  294. while (*pp) {
  295. np = *pp;
  296. if (ncci == 0xffffffff || np->ncci == ncci) {
  297. *pp = (*pp)->next;
  298. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  299. if ((mp = np->minorp) != 0) {
  300. #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
  301. capifs_free_ncci('r', mp->minor);
  302. capifs_free_ncci(0, mp->minor);
  303. #endif
  304. if (mp->tty) {
  305. mp->nccip = 0;
  306. #ifdef _DEBUG_REFCOUNT
  307. printk(KERN_DEBUG "reset mp->nccipn");
  308. #endif
  309. tty_hangup(mp->tty);
  310. } else if (mp->file) {
  311. mp->nccip = 0;
  312. #ifdef _DEBUG_REFCOUNT
  313. printk(KERN_DEBUG "reset mp->nccipn");
  314. #endif
  315. wake_up_interruptible(&mp->recvwait);
  316. wake_up_interruptible(&mp->sendwait);
  317. } else {
  318. capiminor_free(mp);
  319. }
  320. }
  321. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  322. kmem_cache_free(capincci_cachep, np);
  323. if (*pp == 0) return;
  324. } else {
  325. pp = &(*pp)->next;
  326. }
  327. }
  328. }
  329. static struct capincci *capincci_find(struct capidev *cdev, u32 ncci)
  330. {
  331. struct capincci *p;
  332. for (p=cdev->nccis; p ; p = p->next) {
  333. if (p->ncci == ncci)
  334. break;
  335. }
  336. return p;
  337. }
  338. /* -------- struct capidev ------------------------------------------ */
  339. static struct capidev *capidev_alloc(struct file *file)
  340. {
  341. struct capidev *cdev;
  342. struct capidev **pp;
  343. cdev = (struct capidev *)kmem_cache_alloc(capidev_cachep, GFP_KERNEL);
  344. if (!cdev)
  345. return 0;
  346. memset(cdev, 0, sizeof(struct capidev));
  347. cdev->file = file;
  348. cdev->minor = MINOR(file->f_dentry->d_inode->i_rdev);
  349. skb_queue_head_init(&cdev->recvqueue);
  350. init_waitqueue_head(&cdev->recvwait);
  351. pp=&capidev_openlist;
  352. while (*pp) pp = &(*pp)->next;
  353. *pp = cdev;
  354.         return cdev;
  355. }
  356. static void capidev_free(struct capidev *cdev)
  357. {
  358. struct capidev **pp;
  359. if (cdev->applid)
  360. (*capifuncs->capi_release) (cdev->applid);
  361. cdev->applid = 0;
  362. skb_queue_purge(&cdev->recvqueue);
  363. pp=&capidev_openlist;
  364. while (*pp && *pp != cdev) pp = &(*pp)->next;
  365. if (*pp)
  366. *pp = cdev->next;
  367. kmem_cache_free(capidev_cachep, cdev);
  368. }
  369. static struct capidev *capidev_find(u16 applid)
  370. {
  371. struct capidev *p;
  372. for (p=capidev_openlist; p; p = p->next) {
  373. if (p->applid == applid)
  374. break;
  375. }
  376. return p;
  377. }
  378. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  379. /* -------- handle data queue --------------------------------------- */
  380. static struct sk_buff *
  381. gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
  382. {
  383. struct sk_buff *nskb;
  384. nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_ATOMIC);
  385. if (nskb) {
  386. u16 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4+4+2);
  387. unsigned char *s = skb_put(nskb, CAPI_DATA_B3_RESP_LEN);
  388. capimsg_setu16(s, 0, CAPI_DATA_B3_RESP_LEN);
  389. capimsg_setu16(s, 2, mp->applid);
  390. capimsg_setu8 (s, 4, CAPI_DATA_B3);
  391. capimsg_setu8 (s, 5, CAPI_RESP);
  392. capimsg_setu16(s, 6, mp->msgid++);
  393. capimsg_setu32(s, 8, mp->ncci);
  394. capimsg_setu16(s, 12, datahandle);
  395. }
  396. return nskb;
  397. }
  398. static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
  399. {
  400. struct sk_buff *nskb;
  401. unsigned int datalen;
  402. u16 errcode, datahandle;
  403. datalen = skb->len - CAPIMSG_LEN(skb->data);
  404. if (mp->tty) {
  405. if (mp->tty->ldisc.receive_buf == 0) {
  406. printk(KERN_ERR "capi: ldisc has no receive_buf functionn");
  407. return -1;
  408. }
  409. if (mp->ttyinstop) {
  410. #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
  411. printk(KERN_DEBUG "capi: recv tty throttledn");
  412. #endif
  413. return -1;
  414. }
  415. if (mp->tty->ldisc.receive_room &&
  416.     mp->tty->ldisc.receive_room(mp->tty) < datalen) {
  417. #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
  418. printk(KERN_DEBUG "capi: no room in ttyn");
  419. #endif
  420. return -1;
  421. }
  422. if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) {
  423. printk(KERN_ERR "capi: gen_data_b3_resp failedn");
  424. return -1;
  425. }
  426. datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
  427. errcode = (*capifuncs->capi_put_message)(mp->applid, nskb);
  428. if (errcode != CAPI_NOERROR) {
  429. printk(KERN_ERR "capi: send DATA_B3_RESP failed=%xn",
  430. errcode);
  431. kfree_skb(nskb);
  432. return -1;
  433. }
  434. (void)skb_pull(skb, CAPIMSG_LEN(skb->data));
  435. #ifdef _DEBUG_DATAFLOW
  436. printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldiscn",
  437. datahandle, skb->len);
  438. #endif
  439. mp->tty->ldisc.receive_buf(mp->tty, skb->data, 0, skb->len);
  440. kfree_skb(skb);
  441. return 0;
  442. } else if (mp->file) {
  443. if (skb_queue_len(&mp->recvqueue) > CAPINC_MAX_RECVQUEUE) {
  444. #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
  445. printk(KERN_DEBUG "capi: no room in raw queuen");
  446. #endif
  447. return -1;
  448. }
  449. if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) {
  450. printk(KERN_ERR "capi: gen_data_b3_resp failedn");
  451. return -1;
  452. }
  453. datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
  454. errcode = (*capifuncs->capi_put_message)(mp->applid, nskb);
  455. if (errcode != CAPI_NOERROR) {
  456. printk(KERN_ERR "capi: send DATA_B3_RESP failed=%xn",
  457. errcode);
  458. kfree_skb(nskb);
  459. return -1;
  460. }
  461. (void)skb_pull(skb, CAPIMSG_LEN(skb->data));
  462. #ifdef _DEBUG_DATAFLOW
  463. printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => rawn",
  464. datahandle, skb->len);
  465. #endif
  466. skb_queue_tail(&mp->recvqueue, skb);
  467. wake_up_interruptible(&mp->recvwait);
  468. return 0;
  469. }
  470. #ifdef _DEBUG_DATAFLOW
  471. printk(KERN_DEBUG "capi: currently no receivern");
  472. #endif
  473. return -1;
  474. }
  475. static void handle_minor_recv(struct capiminor *mp)
  476. {
  477. struct sk_buff *skb;
  478. while ((skb = skb_dequeue(&mp->inqueue)) != 0) {
  479. unsigned int len = skb->len;
  480. mp->inbytes -= len;
  481. if (handle_recv_skb(mp, skb) < 0) {
  482. skb_queue_head(&mp->inqueue, skb);
  483. mp->inbytes += len;
  484. return;
  485. }
  486. }
  487. }
  488. static int handle_minor_send(struct capiminor *mp)
  489. {
  490. struct sk_buff *skb;
  491. u16 len;
  492. int count = 0;
  493. u16 errcode;
  494. u16 datahandle;
  495. if (mp->tty && mp->ttyoutstop) {
  496. #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
  497. printk(KERN_DEBUG "capi: send: tty stoppedn");
  498. #endif
  499. return 0;
  500. }
  501. while ((skb = skb_dequeue(&mp->outqueue)) != 0) {
  502. datahandle = mp->datahandle;
  503. len = (u16)skb->len;
  504. skb_push(skb, CAPI_DATA_B3_REQ_LEN);
  505. memset(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
  506. capimsg_setu16(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
  507. capimsg_setu16(skb->data, 2, mp->applid);
  508. capimsg_setu8 (skb->data, 4, CAPI_DATA_B3);
  509. capimsg_setu8 (skb->data, 5, CAPI_REQ);
  510. capimsg_setu16(skb->data, 6, mp->msgid++);
  511. capimsg_setu32(skb->data, 8, mp->ncci); /* NCCI */
  512. capimsg_setu32(skb->data, 12, (u32) skb->data); /* Data32 */
  513. capimsg_setu16(skb->data, 16, len); /* Data length */
  514. capimsg_setu16(skb->data, 18, datahandle);
  515. capimsg_setu16(skb->data, 20, 0); /* Flags */
  516. if (capincci_add_ack(mp, datahandle) < 0) {
  517. skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
  518. skb_queue_head(&mp->outqueue, skb);
  519. return count;
  520. }
  521. errcode = (*capifuncs->capi_put_message) (mp->applid, skb);
  522. if (errcode == CAPI_NOERROR) {
  523. mp->datahandle++;
  524. count++;
  525. mp->outbytes -= len;
  526. #ifdef _DEBUG_DATAFLOW
  527. printk(KERN_DEBUG "capi: DATA_B3_REQ %u len=%un",
  528. datahandle, len);
  529. #endif
  530. continue;
  531. }
  532. capiminor_del_ack(mp, datahandle);
  533. if (errcode == CAPI_SENDQUEUEFULL) {
  534. skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
  535. skb_queue_head(&mp->outqueue, skb);
  536. break;
  537. }
  538. /* ups, drop packet */
  539. printk(KERN_ERR "capi: put_message = %xn", errcode);
  540. mp->outbytes -= len;
  541. kfree_skb(skb);
  542. }
  543. if (count)
  544. wake_up_interruptible(&mp->sendwait);
  545. return count;
  546. }
  547. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  548. /* -------- function called by lower level -------------------------- */
  549. static void capi_signal(u16 applid, void *param)
  550. {
  551. struct capidev *cdev = (struct capidev *)param;
  552. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  553. struct capiminor *mp;
  554. u16 datahandle;
  555. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  556. struct capincci *np;
  557. struct sk_buff *skb = 0;
  558. u32 ncci;
  559. (void) (*capifuncs->capi_get_message) (applid, &skb);
  560. if (!skb) {
  561. printk(KERN_ERR "BUG: capi_signal: no skbn");
  562. return;
  563. }
  564. if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
  565. skb_queue_tail(&cdev->recvqueue, skb);
  566. wake_up_interruptible(&cdev->recvwait);
  567. return;
  568. }
  569. ncci = CAPIMSG_CONTROL(skb->data);
  570. for (np = cdev->nccis; np && np->ncci != ncci; np = np->next)
  571. ;
  572. if (!np) {
  573. printk(KERN_ERR "BUG: capi_signal: ncci not foundn");
  574. skb_queue_tail(&cdev->recvqueue, skb);
  575. wake_up_interruptible(&cdev->recvwait);
  576. return;
  577. }
  578. #ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
  579. skb_queue_tail(&cdev->recvqueue, skb);
  580. wake_up_interruptible(&cdev->recvwait);
  581. #else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  582. mp = np->minorp;
  583. if (!mp) {
  584. skb_queue_tail(&cdev->recvqueue, skb);
  585. wake_up_interruptible(&cdev->recvwait);
  586. return;
  587. }
  588. if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
  589. datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
  590. #ifdef _DEBUG_DATAFLOW
  591. printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%dn",
  592. datahandle, skb->len-CAPIMSG_LEN(skb->data));
  593. #endif
  594. skb_queue_tail(&mp->inqueue, skb);
  595. mp->inbytes += skb->len;
  596. handle_minor_recv(mp);
  597. } else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) {
  598. datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4);
  599. #ifdef _DEBUG_DATAFLOW
  600. printk(KERN_DEBUG "capi_signal: DATA_B3_CONF %u 0x%xn",
  601. datahandle,
  602. CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
  603. #endif
  604. kfree_skb(skb);
  605. (void)capiminor_del_ack(mp, datahandle);
  606. if (mp->tty) {
  607. if (mp->tty->ldisc.write_wakeup)
  608. mp->tty->ldisc.write_wakeup(mp->tty);
  609. } else {
  610. wake_up_interruptible(&mp->sendwait);
  611. }
  612. (void)handle_minor_send(mp);
  613. } else {
  614. /* ups, let capi application handle it :-) */
  615. skb_queue_tail(&cdev->recvqueue, skb);
  616. wake_up_interruptible(&cdev->recvwait);
  617. }
  618. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  619. }
  620. /* -------- file_operations for capidev ----------------------------- */
  621. static ssize_t
  622. capi_read(struct file *file, char *buf, size_t count, loff_t *ppos)
  623. {
  624. struct capidev *cdev = (struct capidev *)file->private_data;
  625. struct sk_buff *skb;
  626. int retval;
  627. size_t copied;
  628. if (ppos != &file->f_pos)
  629. return -ESPIPE;
  630. if (!cdev->applid)
  631. return -ENODEV;
  632. if ((skb = skb_dequeue(&cdev->recvqueue)) == 0) {
  633. if (file->f_flags & O_NONBLOCK)
  634. return -EAGAIN;
  635. for (;;) {
  636. interruptible_sleep_on(&cdev->recvwait);
  637. if ((skb = skb_dequeue(&cdev->recvqueue)) != 0)
  638. break;
  639. if (signal_pending(current))
  640. break;
  641. }
  642. if (skb == 0)
  643. return -ERESTARTNOHAND;
  644. }
  645. if (skb->len > count) {
  646. skb_queue_head(&cdev->recvqueue, skb);
  647. return -EMSGSIZE;
  648. }
  649. retval = copy_to_user(buf, skb->data, skb->len);
  650. if (retval) {
  651. skb_queue_head(&cdev->recvqueue, skb);
  652. return retval;
  653. }
  654. copied = skb->len;
  655. if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_IND) {
  656. cdev->nrecvdatapkt++;
  657. } else {
  658. cdev->nrecvctlpkt++;
  659. }
  660. kfree_skb(skb);
  661. return copied;
  662. }
  663. static ssize_t
  664. capi_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
  665. {
  666. struct capidev *cdev = (struct capidev *)file->private_data;
  667. struct sk_buff *skb;
  668. int retval;
  669. u16 mlen;
  670.         if (ppos != &file->f_pos)
  671. return -ESPIPE;
  672. if (!cdev->applid)
  673. return -ENODEV;
  674. skb = alloc_skb(count, GFP_USER);
  675. if (!skb)
  676. return -ENOMEM;
  677. if ((retval = copy_from_user(skb_put(skb, count), buf, count))) {
  678. kfree_skb(skb);
  679. return -EFAULT;
  680. }
  681. mlen = CAPIMSG_LEN(skb->data);
  682. if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
  683. if (mlen + CAPIMSG_DATALEN(skb->data) != count) {
  684. kfree_skb(skb);
  685. return -EINVAL;
  686. }
  687. } else {
  688. if (mlen != count) {
  689. kfree_skb(skb);
  690. return -EINVAL;
  691. }
  692. }
  693. CAPIMSG_SETAPPID(skb->data, cdev->applid);
  694. cdev->errcode = (*capifuncs->capi_put_message) (cdev->applid, skb);
  695. if (cdev->errcode) {
  696. kfree_skb(skb);
  697. return -EIO;
  698. }
  699. if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
  700. cdev->nsentdatapkt++;
  701. } else {
  702. cdev->nsentctlpkt++;
  703. }
  704. return count;
  705. }
  706. static unsigned int
  707. capi_poll(struct file *file, poll_table * wait)
  708. {
  709. struct capidev *cdev = (struct capidev *)file->private_data;
  710. unsigned int mask = 0;
  711. if (!cdev->applid)
  712. return POLLERR;
  713. poll_wait(file, &(cdev->recvwait), wait);
  714. mask = POLLOUT | POLLWRNORM;
  715. if (!skb_queue_empty(&cdev->recvqueue))
  716. mask |= POLLIN | POLLRDNORM;
  717. return mask;
  718. }
  719. static int
  720. capi_ioctl(struct inode *inode, struct file *file,
  721.       unsigned int cmd, unsigned long arg)
  722. {
  723. struct capidev *cdev = (struct capidev *)file->private_data;
  724. capi_ioctl_struct data;
  725. int retval = -EINVAL;
  726. switch (cmd) {
  727. case CAPI_REGISTER:
  728. {
  729. retval = copy_from_user((void *) &data.rparams,
  730. (void *) arg, sizeof(struct capi_register_params));
  731. if (retval)
  732. return -EFAULT;
  733. if (cdev->applid)
  734. return -EEXIST;
  735. cdev->errcode = (*capifuncs->capi_register) (&data.rparams,
  736.   &cdev->applid);
  737. if (cdev->errcode) {
  738. cdev->applid = 0;
  739. return -EIO;
  740. }
  741. (void) (*capifuncs->capi_set_signal) (cdev->applid, capi_signal, cdev);
  742. }
  743. return (int)cdev->applid;
  744. case CAPI_GET_VERSION:
  745. {
  746. retval = copy_from_user((void *) &data.contr,
  747. (void *) arg,
  748. sizeof(data.contr));
  749. if (retval)
  750. return -EFAULT;
  751.         cdev->errcode = (*capifuncs->capi_get_version) (data.contr, &data.version);
  752. if (cdev->errcode)
  753. return -EIO;
  754. retval = copy_to_user((void *) arg,
  755.       (void *) &data.version,
  756.       sizeof(data.version));
  757. if (retval)
  758. return -EFAULT;
  759. }
  760. return 0;
  761. case CAPI_GET_SERIAL:
  762. {
  763. retval = copy_from_user((void *) &data.contr,
  764. (void *) arg,
  765. sizeof(data.contr));
  766. if (retval)
  767. return -EFAULT;
  768. cdev->errcode = (*capifuncs->capi_get_serial) (data.contr, data.serial);
  769. if (cdev->errcode)
  770. return -EIO;
  771. retval = copy_to_user((void *) arg,
  772.       (void *) data.serial,
  773.       sizeof(data.serial));
  774. if (retval)
  775. return -EFAULT;
  776. }
  777. return 0;
  778. case CAPI_GET_PROFILE:
  779. {
  780. retval = copy_from_user((void *) &data.contr,
  781. (void *) arg,
  782. sizeof(data.contr));
  783. if (retval)
  784. return -EFAULT;
  785. if (data.contr == 0) {
  786. cdev->errcode = (*capifuncs->capi_get_profile) (data.contr, &data.profile);
  787. if (cdev->errcode)
  788. return -EIO;
  789. retval = copy_to_user((void *) arg,
  790.       (void *) &data.profile.ncontroller,
  791.        sizeof(data.profile.ncontroller));
  792. } else {
  793. cdev->errcode = (*capifuncs->capi_get_profile) (data.contr, &data.profile);
  794. if (cdev->errcode)
  795. return -EIO;
  796. retval = copy_to_user((void *) arg,
  797.   (void *) &data.profile,
  798.    sizeof(data.profile));
  799. }
  800. if (retval)
  801. return -EFAULT;
  802. }
  803. return 0;
  804. case CAPI_GET_MANUFACTURER:
  805. {
  806. retval = copy_from_user((void *) &data.contr,
  807. (void *) arg,
  808. sizeof(data.contr));
  809. if (retval)
  810. return -EFAULT;
  811. cdev->errcode = (*capifuncs->capi_get_manufacturer) (data.contr, data.manufacturer);
  812. if (cdev->errcode)
  813. return -EIO;
  814. retval = copy_to_user((void *) arg, (void *) data.manufacturer,
  815.       sizeof(data.manufacturer));
  816. if (retval)
  817. return -EFAULT;
  818. }
  819. return 0;
  820. case CAPI_GET_ERRCODE:
  821. data.errcode = cdev->errcode;
  822. cdev->errcode = CAPI_NOERROR;
  823. if (arg) {
  824. retval = copy_to_user((void *) arg,
  825.       (void *) &data.errcode,
  826.       sizeof(data.errcode));
  827. if (retval)
  828. return -EFAULT;
  829. }
  830. return data.errcode;
  831. case CAPI_INSTALLED:
  832. if ((*capifuncs->capi_isinstalled)() == CAPI_NOERROR)
  833. return 0;
  834. return -ENXIO;
  835. case CAPI_MANUFACTURER_CMD:
  836. {
  837. struct capi_manufacturer_cmd mcmd;
  838. if (!capable(CAP_SYS_ADMIN))
  839. return -EPERM;
  840. retval = copy_from_user((void *) &mcmd, (void *) arg,
  841. sizeof(mcmd));
  842. if (retval)
  843. return -EFAULT;
  844. return (*capifuncs->capi_manufacturer) (mcmd.cmd, mcmd.data);
  845. }
  846. return 0;
  847. case CAPI_SET_FLAGS:
  848. case CAPI_CLR_FLAGS:
  849. {
  850. unsigned userflags;
  851. retval = copy_from_user((void *) &userflags,
  852. (void *) arg,
  853. sizeof(userflags));
  854. if (retval)
  855. return -EFAULT;
  856. if (cmd == CAPI_SET_FLAGS)
  857. cdev->userflags |= userflags;
  858. else
  859. cdev->userflags &= ~userflags;
  860. }
  861. return 0;
  862. case CAPI_GET_FLAGS:
  863. {
  864. retval = copy_to_user((void *) arg,
  865.       (void *) &cdev->userflags,
  866.       sizeof(cdev->userflags));
  867. if (retval)
  868. return -EFAULT;
  869. }
  870. return 0;
  871. case CAPI_NCCI_OPENCOUNT:
  872. {
  873. struct capincci *nccip;
  874. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  875. struct capiminor *mp;
  876. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  877. unsigned ncci;
  878. int count = 0;
  879. retval = copy_from_user((void *) &ncci,
  880. (void *) arg,
  881. sizeof(ncci));
  882. if (retval)
  883. return -EFAULT;
  884. nccip = capincci_find(cdev, (u32) ncci);
  885. if (!nccip)
  886. return 0;
  887. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  888. if ((mp = nccip->minorp) != 0) {
  889. count += atomic_read(&mp->ttyopencount);
  890. if (mp->file)
  891. count++;
  892. }
  893. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  894. return count;
  895. }
  896. return 0;
  897. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  898. case CAPI_NCCI_GETUNIT:
  899. {
  900. struct capincci *nccip;
  901. struct capiminor *mp;
  902. unsigned ncci;
  903. retval = copy_from_user((void *) &ncci,
  904. (void *) arg,
  905. sizeof(ncci));
  906. if (retval)
  907. return -EFAULT;
  908. nccip = capincci_find(cdev, (u32) ncci);
  909. if (!nccip || (mp = nccip->minorp) == 0)
  910. return -ESRCH;
  911. return mp->minor;
  912. }
  913. return 0;
  914. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  915. }
  916. return -EINVAL;
  917. }
  918. static int
  919. capi_open(struct inode *inode, struct file *file)
  920. {
  921. if (file->private_data)
  922. return -EEXIST;
  923. if ((file->private_data = capidev_alloc(file)) == 0)
  924. return -ENOMEM;
  925. MOD_INC_USE_COUNT;
  926. #ifdef _DEBUG_REFCOUNT
  927. printk(KERN_DEBUG "capi_open %dn", GET_USE_COUNT(THIS_MODULE));
  928. #endif
  929. return 0;
  930. }
  931. static int
  932. capi_release(struct inode *inode, struct file *file)
  933. {
  934. struct capidev *cdev = (struct capidev *)file->private_data;
  935. lock_kernel();
  936. capincci_free(cdev, 0xffffffff);
  937. capidev_free(cdev);
  938. file->private_data = NULL;
  939. MOD_DEC_USE_COUNT;
  940. #ifdef _DEBUG_REFCOUNT
  941. printk(KERN_DEBUG "capi_release %dn", GET_USE_COUNT(THIS_MODULE));
  942. #endif
  943. unlock_kernel();
  944. return 0;
  945. }
  946. static struct file_operations capi_fops =
  947. {
  948. owner: THIS_MODULE,
  949. llseek: no_llseek,
  950. read: capi_read,
  951. write: capi_write,
  952. poll: capi_poll,
  953. ioctl: capi_ioctl,
  954. open: capi_open,
  955. release: capi_release,
  956. };
  957. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  958. /* -------- file_operations for capincci ---------------------------- */
  959. static int
  960. capinc_raw_open(struct inode *inode, struct file *file)
  961. {
  962. struct capiminor *mp;
  963. if (file->private_data)
  964. return -EEXIST;
  965. if ((mp = capiminor_find(MINOR(file->f_dentry->d_inode->i_rdev))) == 0)
  966. return -ENXIO;
  967. if (mp->nccip == 0)
  968. return -ENXIO;
  969. if (mp->file)
  970. return -EBUSY;
  971. #ifdef _DEBUG_REFCOUNT
  972. printk(KERN_DEBUG "capi_raw_open %dn", GET_USE_COUNT(THIS_MODULE));
  973. #endif
  974. mp->datahandle = 0;
  975. mp->file = file;
  976. file->private_data = (void *)mp;
  977. handle_minor_recv(mp);
  978. return 0;
  979. }
  980. static ssize_t
  981. capinc_raw_read(struct file *file, char *buf, size_t count, loff_t *ppos)
  982. {
  983. struct capiminor *mp = (struct capiminor *)file->private_data;
  984. struct sk_buff *skb;
  985. int retval;
  986. size_t copied = 0;
  987.         if (ppos != &file->f_pos)
  988. return -ESPIPE;
  989. if (!mp || !mp->nccip)
  990. return -EINVAL;
  991. if ((skb = skb_dequeue(&mp->recvqueue)) == 0) {
  992. if (file->f_flags & O_NONBLOCK)
  993. return -EAGAIN;
  994. for (;;) {
  995. interruptible_sleep_on(&mp->recvwait);
  996. if (mp->nccip == 0)
  997. return 0;
  998. if ((skb = skb_dequeue(&mp->recvqueue)) != 0)
  999. break;
  1000. if (signal_pending(current))
  1001. break;
  1002. }
  1003. if (skb == 0)
  1004. return -ERESTARTNOHAND;
  1005. }
  1006. do {
  1007. if (count < skb->len) {
  1008. retval = copy_to_user(buf, skb->data, count);
  1009. if (retval) {
  1010. skb_queue_head(&mp->recvqueue, skb);
  1011. return retval;
  1012. }
  1013. skb_pull(skb, count);
  1014. skb_queue_head(&mp->recvqueue, skb);
  1015. copied += count;
  1016. return copied;
  1017. } else {
  1018. retval = copy_to_user(buf, skb->data, skb->len);
  1019. if (retval) {
  1020. skb_queue_head(&mp->recvqueue, skb);
  1021. return copied;
  1022. }
  1023. copied += skb->len;
  1024. count -= skb->len;
  1025. buf += skb->len;
  1026. kfree_skb(skb);
  1027. }
  1028. } while ((skb = skb_dequeue(&mp->recvqueue)) != 0);
  1029. return copied;
  1030. }
  1031. static ssize_t
  1032. capinc_raw_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
  1033. {
  1034. struct capiminor *mp = (struct capiminor *)file->private_data;
  1035. struct sk_buff *skb;
  1036. int retval;
  1037.         if (ppos != &file->f_pos)
  1038. return -ESPIPE;
  1039. if (!mp || !mp->nccip)
  1040. return -EINVAL;
  1041. skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+count, GFP_USER);
  1042. if (!skb)
  1043. return -ENOMEM;
  1044. skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
  1045. if ((retval = copy_from_user(skb_put(skb, count), buf, count))) {
  1046. kfree_skb(skb);
  1047. return -EFAULT;
  1048. }
  1049. while (skb_queue_len(&mp->outqueue) > CAPINC_MAX_SENDQUEUE) {
  1050. if (file->f_flags & O_NONBLOCK)
  1051. return -EAGAIN;
  1052. interruptible_sleep_on(&mp->sendwait);
  1053. if (mp->nccip == 0) {
  1054. kfree_skb(skb);
  1055. return -EIO;
  1056. }
  1057. if (signal_pending(current))
  1058. return -ERESTARTNOHAND;
  1059. }
  1060. skb_queue_tail(&mp->outqueue, skb);
  1061. mp->outbytes += skb->len;
  1062. (void)handle_minor_send(mp);
  1063. return count;
  1064. }
  1065. static unsigned int
  1066. capinc_raw_poll(struct file *file, poll_table * wait)
  1067. {
  1068. struct capiminor *mp = (struct capiminor *)file->private_data;
  1069. unsigned int mask = 0;
  1070. if (!mp || !mp->nccip)
  1071. return POLLERR|POLLHUP;
  1072. poll_wait(file, &(mp->recvwait), wait);
  1073. if (!skb_queue_empty(&mp->recvqueue))
  1074. mask |= POLLIN | POLLRDNORM;
  1075. poll_wait(file, &(mp->sendwait), wait);
  1076. if (skb_queue_len(&mp->outqueue) > CAPINC_MAX_SENDQUEUE)
  1077. mask = POLLOUT | POLLWRNORM;
  1078. return mask;
  1079. }
  1080. static int
  1081. capinc_raw_ioctl(struct inode *inode, struct file *file,
  1082.       unsigned int cmd, unsigned long arg)
  1083. {
  1084. struct capiminor *mp = (struct capiminor *)file->private_data;
  1085. if (!mp || !mp->nccip)
  1086. return -EINVAL;
  1087. switch (cmd) {
  1088. }
  1089. return -EINVAL;
  1090. }
  1091. static int
  1092. capinc_raw_release(struct inode *inode, struct file *file)
  1093. {
  1094. struct capiminor *mp = (struct capiminor *)file->private_data;
  1095. if (mp) {
  1096. lock_kernel();
  1097. mp->file = 0;
  1098. if (mp->nccip == 0) {
  1099. capiminor_free(mp);
  1100. file->private_data = NULL;
  1101. }
  1102. unlock_kernel();
  1103. }
  1104. #ifdef _DEBUG_REFCOUNT
  1105. printk(KERN_DEBUG "capinc_raw_release %dn", GET_USE_COUNT(THIS_MODULE));
  1106. #endif
  1107. return 0;
  1108. }
  1109. static struct file_operations capinc_raw_fops =
  1110. {
  1111. owner: THIS_MODULE,
  1112. llseek: no_llseek,
  1113. read: capinc_raw_read,
  1114. write: capinc_raw_write,
  1115. poll: capinc_raw_poll,
  1116. ioctl: capinc_raw_ioctl,
  1117. open: capinc_raw_open,
  1118. release: capinc_raw_release,
  1119. };
  1120. /* -------- tty_operations for capincci ----------------------------- */
  1121. static int capinc_tty_open(struct tty_struct * tty, struct file * file)
  1122. {
  1123. struct capiminor *mp;
  1124. if ((mp = capiminor_find(MINOR(file->f_dentry->d_inode->i_rdev))) == 0)
  1125. return -ENXIO;
  1126. if (mp->nccip == 0)
  1127. return -ENXIO;
  1128. if (mp->file)
  1129. return -EBUSY;
  1130. skb_queue_head_init(&mp->recvqueue);
  1131. init_waitqueue_head(&mp->recvwait);
  1132. init_waitqueue_head(&mp->sendwait);
  1133. tty->driver_data = (void *)mp;
  1134. #ifdef _DEBUG_REFCOUNT
  1135. printk(KERN_DEBUG "capi_tty_open %dn", GET_USE_COUNT(THIS_MODULE));
  1136. #endif
  1137. if (atomic_read(&mp->ttyopencount) == 0)
  1138. mp->tty = tty;
  1139. atomic_inc(&mp->ttyopencount);
  1140. #ifdef _DEBUG_REFCOUNT
  1141. printk(KERN_DEBUG "capinc_tty_open ocount=%dn", atomic_read(&mp->ttyopencount));
  1142. #endif
  1143. handle_minor_recv(mp);
  1144. return 0;
  1145. }
  1146. static void capinc_tty_close(struct tty_struct * tty, struct file * file)
  1147. {
  1148. struct capiminor *mp;
  1149. mp = (struct capiminor *)tty->driver_data;
  1150. if (mp) {
  1151. if (atomic_dec_and_test(&mp->ttyopencount)) {
  1152. #ifdef _DEBUG_REFCOUNT
  1153. printk(KERN_DEBUG "capinc_tty_close lastclosen");
  1154. #endif
  1155. tty->driver_data = (void *)0;
  1156. mp->tty = 0;
  1157. }
  1158. #ifdef _DEBUG_REFCOUNT
  1159. printk(KERN_DEBUG "capinc_tty_close ocount=%dn", atomic_read(&mp->ttyopencount));
  1160. #endif
  1161. if (mp->nccip == 0)
  1162. capiminor_free(mp);
  1163. }
  1164. #ifdef _DEBUG_REFCOUNT
  1165. printk(KERN_DEBUG "capinc_tty_closen");
  1166. #endif
  1167. }
  1168. static int capinc_tty_write(struct tty_struct * tty, int from_user,
  1169.     const unsigned char *buf, int count)
  1170. {
  1171. struct capiminor *mp = (struct capiminor *)tty->driver_data;
  1172. struct sk_buff *skb;
  1173. int retval;
  1174. #ifdef _DEBUG_TTYFUNCS
  1175. printk(KERN_DEBUG "capinc_tty_write(from_user=%d,count=%d)n",
  1176. from_user, count);
  1177. #endif
  1178. if (!mp || !mp->nccip) {
  1179. #ifdef _DEBUG_TTYFUNCS
  1180. printk(KERN_DEBUG "capinc_tty_write: mp or mp->ncci NULLn");
  1181. #endif
  1182. return 0;
  1183. }
  1184. skb = mp->ttyskb;
  1185. if (skb) {
  1186. mp->ttyskb = 0;
  1187. skb_queue_tail(&mp->outqueue, skb);
  1188. mp->outbytes += skb->len;
  1189. }
  1190. skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+count, GFP_ATOMIC);
  1191. if (!skb) {
  1192. printk(KERN_ERR "capinc_tty_write: alloc_skb failedn");
  1193. return -ENOMEM;
  1194. }
  1195. skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
  1196. if (from_user) {
  1197. if ((retval = copy_from_user(skb_put(skb, count), buf, count))) {
  1198. kfree_skb(skb);
  1199. #ifdef _DEBUG_TTYFUNCS
  1200. printk(KERN_DEBUG "capinc_tty_write: copy_from_user=%dn", retval);
  1201. #endif
  1202. return -EFAULT;
  1203. }
  1204. } else {
  1205. memcpy(skb_put(skb, count), buf, count);
  1206. }
  1207. skb_queue_tail(&mp->outqueue, skb);
  1208. mp->outbytes += skb->len;
  1209. (void)handle_minor_send(mp);
  1210. (void)handle_minor_recv(mp);
  1211. return count;
  1212. }
  1213. static void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
  1214. {
  1215. struct capiminor *mp = (struct capiminor *)tty->driver_data;
  1216. struct sk_buff *skb;
  1217. #ifdef _DEBUG_TTYFUNCS
  1218. printk(KERN_DEBUG "capinc_put_char(%u)n", ch);
  1219. #endif
  1220. if (!mp || !mp->nccip) {
  1221. #ifdef _DEBUG_TTYFUNCS
  1222. printk(KERN_DEBUG "capinc_tty_put_char: mp or mp->ncci NULLn");
  1223. #endif
  1224. return;
  1225. }
  1226. skb = mp->ttyskb;
  1227. if (skb) {
  1228. if (skb_tailroom(skb) > 0) {
  1229. *(skb_put(skb, 1)) = ch;
  1230. return;
  1231. }
  1232. mp->ttyskb = 0;
  1233. skb_queue_tail(&mp->outqueue, skb);
  1234. mp->outbytes += skb->len;
  1235. (void)handle_minor_send(mp);
  1236. }
  1237. skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+CAPI_MAX_BLKSIZE, GFP_ATOMIC);
  1238. if (skb) {
  1239. skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
  1240. *(skb_put(skb, 1)) = ch;
  1241. mp->ttyskb = skb;
  1242. } else {
  1243. printk(KERN_ERR "capinc_put_char: char %u lostn", ch);
  1244. }
  1245. }
  1246. static void capinc_tty_flush_chars(struct tty_struct *tty)
  1247. {
  1248. struct capiminor *mp = (struct capiminor *)tty->driver_data;
  1249. struct sk_buff *skb;
  1250. #ifdef _DEBUG_TTYFUNCS
  1251. printk(KERN_DEBUG "capinc_tty_flush_charsn");
  1252. #endif
  1253. if (!mp || !mp->nccip) {
  1254. #ifdef _DEBUG_TTYFUNCS
  1255. printk(KERN_DEBUG "capinc_tty_flush_chars: mp or mp->ncci NULLn");
  1256. #endif
  1257. return;
  1258. }
  1259. skb = mp->ttyskb;
  1260. if (skb) {
  1261. mp->ttyskb = 0;
  1262. skb_queue_tail(&mp->outqueue, skb);
  1263. mp->outbytes += skb->len;
  1264. (void)handle_minor_send(mp);
  1265. }
  1266. (void)handle_minor_recv(mp);
  1267. }
  1268. static int capinc_tty_write_room(struct tty_struct *tty)
  1269. {
  1270. struct capiminor *mp = (struct capiminor *)tty->driver_data;
  1271. int room;
  1272. if (!mp || !mp->nccip) {
  1273. #ifdef _DEBUG_TTYFUNCS
  1274. printk(KERN_DEBUG "capinc_tty_write_room: mp or mp->ncci NULLn");
  1275. #endif
  1276. return 0;
  1277. }
  1278. room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue);
  1279. room *= CAPI_MAX_BLKSIZE;
  1280. #ifdef _DEBUG_TTYFUNCS
  1281. printk(KERN_DEBUG "capinc_tty_write_room = %dn", room);
  1282. #endif
  1283. return room;
  1284. }
  1285. static int capinc_tty_chars_in_buffer(struct tty_struct *tty)
  1286. {
  1287. struct capiminor *mp = (struct capiminor *)tty->driver_data;
  1288. if (!mp || !mp->nccip) {
  1289. #ifdef _DEBUG_TTYFUNCS
  1290. printk(KERN_DEBUG "capinc_tty_chars_in_buffer: mp or mp->ncci NULLn");
  1291. #endif
  1292. return 0;
  1293. }
  1294. #ifdef _DEBUG_TTYFUNCS
  1295. printk(KERN_DEBUG "capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%dn",
  1296. mp->outbytes, mp->nack,
  1297. skb_queue_len(&mp->outqueue),
  1298. skb_queue_len(&mp->inqueue));
  1299. #endif
  1300. return mp->outbytes;
  1301. }
  1302. static int capinc_tty_ioctl(struct tty_struct *tty, struct file * file,
  1303.     unsigned int cmd, unsigned long arg)
  1304. {
  1305. int error = 0;
  1306. switch (cmd) {
  1307. default:
  1308. error = n_tty_ioctl (tty, file, cmd, arg);
  1309. break;
  1310. }
  1311. return error;
  1312. }
  1313. static void capinc_tty_set_termios(struct tty_struct *tty, struct termios * old)
  1314. {
  1315. #ifdef _DEBUG_TTYFUNCS
  1316. printk(KERN_DEBUG "capinc_tty_set_termiosn");
  1317. #endif
  1318. }
  1319. static void capinc_tty_throttle(struct tty_struct * tty)
  1320. {
  1321. struct capiminor *mp = (struct capiminor *)tty->driver_data;
  1322. #ifdef _DEBUG_TTYFUNCS
  1323. printk(KERN_DEBUG "capinc_tty_throttlen");
  1324. #endif
  1325. if (mp)
  1326. mp->ttyinstop = 1;
  1327. }
  1328. static void capinc_tty_unthrottle(struct tty_struct * tty)
  1329. {
  1330. struct capiminor *mp = (struct capiminor *)tty->driver_data;
  1331. #ifdef _DEBUG_TTYFUNCS
  1332. printk(KERN_DEBUG "capinc_tty_unthrottlen");
  1333. #endif
  1334. if (mp) {
  1335. mp->ttyinstop = 0;
  1336. handle_minor_recv(mp);
  1337. }
  1338. }
  1339. static void capinc_tty_stop(struct tty_struct *tty)
  1340. {
  1341. struct capiminor *mp = (struct capiminor *)tty->driver_data;
  1342. #ifdef _DEBUG_TTYFUNCS
  1343. printk(KERN_DEBUG "capinc_tty_stopn");
  1344. #endif
  1345. if (mp) {
  1346. mp->ttyoutstop = 1;
  1347. }
  1348. }
  1349. static void capinc_tty_start(struct tty_struct *tty)
  1350. {
  1351. struct capiminor *mp = (struct capiminor *)tty->driver_data;
  1352. #ifdef _DEBUG_TTYFUNCS
  1353. printk(KERN_DEBUG "capinc_tty_startn");
  1354. #endif
  1355. if (mp) {
  1356. mp->ttyoutstop = 0;
  1357. (void)handle_minor_send(mp);
  1358. }
  1359. }
  1360. static void capinc_tty_hangup(struct tty_struct *tty)
  1361. {
  1362. #ifdef _DEBUG_TTYFUNCS
  1363. printk(KERN_DEBUG "capinc_tty_hangupn");
  1364. #endif
  1365. }
  1366. static void capinc_tty_break_ctl(struct tty_struct *tty, int state)
  1367. {
  1368. #ifdef _DEBUG_TTYFUNCS
  1369. printk(KERN_DEBUG "capinc_tty_break_ctl(%d)n", state);
  1370. #endif
  1371. }
  1372. static void capinc_tty_flush_buffer(struct tty_struct *tty)
  1373. {
  1374. #ifdef _DEBUG_TTYFUNCS
  1375. printk(KERN_DEBUG "capinc_tty_flush_buffern");
  1376. #endif
  1377. }
  1378. static void capinc_tty_set_ldisc(struct tty_struct *tty)
  1379. {
  1380. #ifdef _DEBUG_TTYFUNCS
  1381. printk(KERN_DEBUG "capinc_tty_set_ldiscn");
  1382. #endif
  1383. }
  1384. static void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
  1385. {
  1386. #ifdef _DEBUG_TTYFUNCS
  1387. printk(KERN_DEBUG "capinc_tty_send_xchar(%d)n", ch);
  1388. #endif
  1389. }
  1390. static int capinc_tty_read_proc(char *page, char **start, off_t off,
  1391. int count, int *eof, void *data)
  1392. {
  1393. return 0;
  1394. }
  1395. #define CAPINC_NR_PORTS 256
  1396. static struct tty_driver capinc_tty_driver;
  1397. static int capinc_tty_refcount;
  1398. static struct tty_struct *capinc_tty_table[CAPINC_NR_PORTS];
  1399. static struct termios *capinc_tty_termios[CAPINC_NR_PORTS];
  1400. static struct termios *capinc_tty_termios_locked[CAPINC_NR_PORTS];
  1401. static int capinc_tty_init(void)
  1402. {
  1403. struct tty_driver *drv = &capinc_tty_driver;
  1404. /* Initialize the tty_driver structure */
  1405. memset(drv, 0, sizeof(struct tty_driver));
  1406. drv->magic = TTY_DRIVER_MAGIC;
  1407. #if (LINUX_VERSION_CODE > 0x20100)
  1408. drv->driver_name = "capi_nc";
  1409. #endif
  1410. drv->name = "capi/%d";
  1411. drv->major = capi_ttymajor;
  1412. drv->minor_start = 0;
  1413. drv->num = CAPINC_NR_PORTS;
  1414. drv->type = TTY_DRIVER_TYPE_SERIAL;
  1415. drv->subtype = SERIAL_TYPE_NORMAL;
  1416. drv->init_termios = tty_std_termios;
  1417. drv->init_termios.c_iflag = ICRNL;
  1418. drv->init_termios.c_oflag = OPOST | ONLCR;
  1419. drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
  1420. drv->init_termios.c_lflag = 0;
  1421. drv->flags = TTY_DRIVER_REAL_RAW|TTY_DRIVER_RESET_TERMIOS;
  1422. drv->refcount = &capinc_tty_refcount;
  1423. drv->table = capinc_tty_table;
  1424. drv->termios = capinc_tty_termios;
  1425. drv->termios_locked = capinc_tty_termios_locked;
  1426. drv->open = capinc_tty_open;
  1427. drv->close = capinc_tty_close;
  1428. drv->write = capinc_tty_write;
  1429. drv->put_char = capinc_tty_put_char;
  1430. drv->flush_chars = capinc_tty_flush_chars;
  1431. drv->write_room = capinc_tty_write_room;
  1432. drv->chars_in_buffer = capinc_tty_chars_in_buffer;
  1433. drv->ioctl = capinc_tty_ioctl;
  1434. drv->set_termios = capinc_tty_set_termios;
  1435. drv->throttle = capinc_tty_throttle;
  1436. drv->unthrottle = capinc_tty_unthrottle;
  1437. drv->stop = capinc_tty_stop;
  1438. drv->start = capinc_tty_start;
  1439. drv->hangup = capinc_tty_hangup;
  1440. #if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
  1441. drv->break_ctl = capinc_tty_break_ctl;
  1442. #endif
  1443. drv->flush_buffer = capinc_tty_flush_buffer;
  1444. drv->set_ldisc = capinc_tty_set_ldisc;
  1445. #if (LINUX_VERSION_CODE >= 131343)
  1446. drv->send_xchar = capinc_tty_send_xchar;
  1447. drv->read_proc = capinc_tty_read_proc;
  1448. #endif
  1449. if (tty_register_driver(drv)) {
  1450. printk(KERN_ERR "Couldn't register capi_nc drivern");
  1451. return -1;
  1452. }
  1453. return 0;
  1454. }
  1455. static void capinc_tty_exit(void)
  1456. {
  1457. struct tty_driver *drv = &capinc_tty_driver;
  1458. int retval;
  1459. if ((retval = tty_unregister_driver(drv)))
  1460. printk(KERN_ERR "capi: failed to unregister capi_nc driver (%d)n", retval);
  1461. }
  1462. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  1463. /* -------- /proc functions ----------------------------------------- */
  1464. /*
  1465.  * /proc/capi/capi20:
  1466.  *  minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
  1467.  */
  1468. static int proc_capidev_read_proc(char *page, char **start, off_t off,
  1469.                                        int count, int *eof, void *data)
  1470. {
  1471.         struct capidev *cdev;
  1472. int len = 0;
  1473. for (cdev=capidev_openlist; cdev; cdev = cdev->next) {
  1474. len += sprintf(page+len, "%d %d %lu %lu %lu %lun",
  1475. cdev->minor,
  1476. cdev->applid,
  1477. cdev->nrecvctlpkt,
  1478. cdev->nrecvdatapkt,
  1479. cdev->nsentctlpkt,
  1480. cdev->nsentdatapkt);
  1481. if (len <= off) {
  1482. off -= len;
  1483. len = 0;
  1484. } else {
  1485. if (len-off > count)
  1486. goto endloop;
  1487. }
  1488. }
  1489. endloop:
  1490. if (len < count)
  1491. *eof = 1;
  1492. if (len>count) len = count;
  1493. if (len<0) len = 0;
  1494. return len;
  1495. }
  1496. /*
  1497.  * /proc/capi/capi20ncci:
  1498.  *  applid ncci
  1499.  */
  1500. static int proc_capincci_read_proc(char *page, char **start, off_t off,
  1501.                                        int count, int *eof, void *data)
  1502. {
  1503.         struct capidev *cdev;
  1504.         struct capincci *np;
  1505. int len = 0;
  1506. for (cdev=capidev_openlist; cdev; cdev = cdev->next) {
  1507. for (np=cdev->nccis; np; np = np->next) {
  1508. len += sprintf(page+len, "%d 0x%x%sn",
  1509. cdev->applid,
  1510. np->ncci,
  1511. #ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
  1512. "");
  1513. #else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  1514. np->minorp && np->minorp->file ? " open" : "");
  1515. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  1516. if (len <= off) {
  1517. off -= len;
  1518. len = 0;
  1519. } else {
  1520. if (len-off > count)
  1521. goto endloop;
  1522. }
  1523. }
  1524. }
  1525. endloop:
  1526. *start = page+off;
  1527. if (len < count)
  1528. *eof = 1;
  1529. if (len>count) len = count;
  1530. if (len<0) len = 0;
  1531. return len;
  1532. }
  1533. static struct procfsentries {
  1534.   char *name;
  1535.   mode_t mode;
  1536.   int (*read_proc)(char *page, char **start, off_t off,
  1537.                                        int count, int *eof, void *data);
  1538.   struct proc_dir_entry *procent;
  1539. } procfsentries[] = {
  1540.    /* { "capi",   S_IFDIR, 0 }, */
  1541.    { "capi/capi20",    0  , proc_capidev_read_proc },
  1542.    { "capi/capi20ncci",   0  , proc_capincci_read_proc },
  1543. };
  1544. static void __init proc_init(void)
  1545. {
  1546.     int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
  1547.     int i;
  1548.     for (i=0; i < nelem; i++) {
  1549.         struct procfsentries *p = procfsentries + i;
  1550. p->procent = create_proc_entry(p->name, p->mode, 0);
  1551. if (p->procent) p->procent->read_proc = p->read_proc;
  1552.     }
  1553. }
  1554. static void __exit proc_exit(void)
  1555. {
  1556.     int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
  1557.     int i;
  1558.     for (i=nelem-1; i >= 0; i--) {
  1559.         struct procfsentries *p = procfsentries + i;
  1560. if (p->procent) {
  1561.    remove_proc_entry(p->name, 0);
  1562.    p->procent = 0;
  1563. }
  1564.     }
  1565. }
  1566. /* -------- init function and module interface ---------------------- */
  1567. static void alloc_exit(void)
  1568. {
  1569. if (capidev_cachep) {
  1570. (void)kmem_cache_destroy(capidev_cachep);
  1571. capidev_cachep = 0;
  1572. }
  1573. if (capincci_cachep) {
  1574. (void)kmem_cache_destroy(capincci_cachep);
  1575. capincci_cachep = 0;
  1576. }
  1577. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  1578. if (capidh_cachep) {
  1579. (void)kmem_cache_destroy(capidh_cachep);
  1580. capidh_cachep = 0;
  1581. }
  1582. if (capiminor_cachep) {
  1583. (void)kmem_cache_destroy(capiminor_cachep);
  1584. capiminor_cachep = 0;
  1585. }
  1586. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  1587. }
  1588. static int __init alloc_init(void)
  1589. {
  1590. capidev_cachep = kmem_cache_create("capi20_dev",
  1591.  sizeof(struct capidev),
  1592.  0,
  1593.  SLAB_HWCACHE_ALIGN,
  1594.  NULL, NULL);
  1595. if (!capidev_cachep) {
  1596. alloc_exit();
  1597. return -ENOMEM;
  1598. }
  1599. capincci_cachep = kmem_cache_create("capi20_ncci",
  1600.  sizeof(struct capincci),
  1601.  0,
  1602.  SLAB_HWCACHE_ALIGN,
  1603.  NULL, NULL);
  1604. if (!capincci_cachep) {
  1605. alloc_exit();
  1606. return -ENOMEM;
  1607. }
  1608. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  1609. capidh_cachep = kmem_cache_create("capi20_dh",
  1610.  sizeof(struct datahandle_queue),
  1611.  0,
  1612.  SLAB_HWCACHE_ALIGN,
  1613.  NULL, NULL);
  1614. if (!capidh_cachep) {
  1615. alloc_exit();
  1616. return -ENOMEM;
  1617. }
  1618. capiminor_cachep = kmem_cache_create("capi20_minor",
  1619.  sizeof(struct capiminor),
  1620.  0,
  1621.  SLAB_HWCACHE_ALIGN,
  1622.  NULL, NULL);
  1623. if (!capiminor_cachep) {
  1624. alloc_exit();
  1625. return -ENOMEM;
  1626. }
  1627. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  1628. return 0;
  1629. }
  1630. static void lower_callback(unsigned int cmd, u32 contr, void *data)
  1631. {
  1632. struct capi_ncciinfo *np;
  1633. struct capidev *cdev;
  1634. switch (cmd) {
  1635. case KCI_CONTRUP:
  1636. printk(KERN_INFO "capi: controller %hu upn", contr);
  1637. break;
  1638. case KCI_CONTRDOWN:
  1639. printk(KERN_INFO "capi: controller %hu downn", contr);
  1640. break;
  1641. case KCI_NCCIUP:
  1642. np = (struct capi_ncciinfo *)data;
  1643. if ((cdev = capidev_find(np->applid)) == 0)
  1644. return;
  1645. (void)capincci_alloc(cdev, np->ncci);
  1646. break;
  1647. case KCI_NCCIDOWN:
  1648. np = (struct capi_ncciinfo *)data;
  1649. if ((cdev = capidev_find(np->applid)) == 0)
  1650. return;
  1651. (void)capincci_free(cdev, np->ncci);
  1652. break;
  1653. }
  1654. }
  1655. static struct capi_interface_user cuser = {
  1656. name: "capi20",
  1657. callback: lower_callback,
  1658. };
  1659. static char rev[32];
  1660. static int __init capi_init(void)
  1661. {
  1662. char *p;
  1663. char *compileinfo;
  1664. MOD_INC_USE_COUNT;
  1665. if ((p = strchr(revision, ':')) != 0 && p[1]) {
  1666. strncpy(rev, p + 2, sizeof(rev));
  1667. rev[sizeof(rev)-1] = 0;
  1668. if ((p = strchr(rev, '$')) != 0 && p > rev)
  1669.    *(p-1) = 0;
  1670. } else
  1671. strcpy(rev, "1.0");
  1672. if (devfs_register_chrdev(capi_major, "capi20", &capi_fops)) {
  1673. printk(KERN_ERR "capi20: unable to get major %dn", capi_major);
  1674. MOD_DEC_USE_COUNT;
  1675. return -EIO;
  1676. }
  1677. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  1678. if (devfs_register_chrdev(capi_rawmajor, "capi/r%d", &capinc_raw_fops)) {
  1679. devfs_unregister_chrdev(capi_major, "capi20");
  1680. printk(KERN_ERR "capi20: unable to get major %dn", capi_rawmajor);
  1681. MOD_DEC_USE_COUNT;
  1682. return -EIO;
  1683. }
  1684.         devfs_register_series (NULL, "capi/r%u", CAPINC_NR_PORTS,
  1685.       DEVFS_FL_DEFAULT,
  1686.                               capi_rawmajor, 0,
  1687.                               S_IFCHR | S_IRUSR | S_IWUSR,
  1688.                               &capinc_raw_fops, NULL);
  1689. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  1690. devfs_register (NULL, "isdn/capi20", DEVFS_FL_DEFAULT,
  1691. capi_major, 0, S_IFCHR | S_IRUSR | S_IWUSR,
  1692. &capi_fops, NULL);
  1693. printk(KERN_NOTICE "capi20: started up with major %dn", capi_major);
  1694. if ((capifuncs = attach_capi_interface(&cuser)) == 0) {
  1695. MOD_DEC_USE_COUNT;
  1696. devfs_unregister_chrdev(capi_major, "capi20");
  1697. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  1698. devfs_unregister_chrdev(capi_rawmajor, "capi/r%d");
  1699. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  1700. devfs_unregister(devfs_find_handle(NULL, "capi20",
  1701.    capi_major, 0,
  1702.    DEVFS_SPECIAL_CHR, 0));
  1703. return -EIO;
  1704. }
  1705. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  1706. if (capinc_tty_init() < 0) {
  1707. (void) detach_capi_interface(&cuser);
  1708. devfs_unregister_chrdev(capi_major, "capi20");
  1709. devfs_unregister_chrdev(capi_rawmajor, "capi/r%d");
  1710. MOD_DEC_USE_COUNT;
  1711. return -ENOMEM;
  1712. }
  1713. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  1714. if (alloc_init() < 0) {
  1715. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  1716. unsigned int j;
  1717. devfs_unregister_chrdev(capi_rawmajor, "capi/r%d");
  1718. for (j = 0; j < CAPINC_NR_PORTS; j++) {
  1719. char devname[32];
  1720. sprintf(devname, "capi/r%u", j);
  1721. devfs_unregister(devfs_find_handle(NULL, devname, capi_rawmajor, j, DEVFS_SPECIAL_CHR, 0));
  1722. }
  1723. capinc_tty_exit();
  1724. #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  1725. (void) detach_capi_interface(&cuser);
  1726. devfs_unregister_chrdev(capi_major, "capi20");
  1727. devfs_unregister(devfs_find_handle(NULL, "capi20",
  1728.    capi_major, 0,
  1729.    DEVFS_SPECIAL_CHR, 0));
  1730. MOD_DEC_USE_COUNT;
  1731. return -ENOMEM;
  1732. }
  1733. (void)proc_init();
  1734. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  1735. #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
  1736.         compileinfo = " (middleware+capifs)";
  1737. #else
  1738.         compileinfo = " (no capifs)";
  1739. #endif
  1740. #else
  1741.         compileinfo = " (no middleware)";
  1742. #endif
  1743. printk(KERN_NOTICE "capi20: Rev %s: started up with major %d%sn",
  1744. rev, capi_major, compileinfo);
  1745. MOD_DEC_USE_COUNT;
  1746. return 0;
  1747. }
  1748. static void __exit capi_exit(void)
  1749. {
  1750. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  1751. unsigned int j;
  1752. #endif
  1753. alloc_exit();
  1754. (void)proc_exit();
  1755. devfs_unregister_chrdev(capi_major, "capi20");
  1756. devfs_unregister(devfs_find_handle(NULL, "isdn/capi20", capi_major, 0, DEVFS_SPECIAL_CHR, 0));
  1757. #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  1758. capinc_tty_exit();
  1759. devfs_unregister_chrdev(capi_rawmajor, "capi/r%d");
  1760. for (j = 0; j < CAPINC_NR_PORTS; j++) {
  1761. char devname[32];
  1762. sprintf(devname, "capi/r%u", j);
  1763. devfs_unregister(devfs_find_handle(NULL, devname, capi_rawmajor, j, DEVFS_SPECIAL_CHR, 0));
  1764. }
  1765. #endif
  1766. (void) detach_capi_interface(&cuser);
  1767. printk(KERN_NOTICE "capi: Rev %s: unloadedn", rev);
  1768. }
  1769. module_init(capi_init);
  1770. module_exit(capi_exit);