2 #include <linux/kernel.h>
3 #include <linux/module.h>
4 #include <linux/isdn/capilli.h>
6 #define DBG(format, arg...) do { \
7 printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
10 struct capilib_msgidqueue
{
11 struct capilib_msgidqueue
*next
;
16 struct list_head list
;
21 struct capilib_msgidqueue
*msgidqueue
;
22 struct capilib_msgidqueue
*msgidlast
;
23 struct capilib_msgidqueue
*msgidfree
;
24 struct capilib_msgidqueue msgidpool
[CAPI_MAXDATAWINDOW
];
27 // ---------------------------------------------------------------------------
30 static inline void mq_init(struct capilib_ncci
* np
)
33 np
->msgidqueue
= NULL
;
36 memset(np
->msgidpool
, 0, sizeof(np
->msgidpool
));
37 np
->msgidfree
= &np
->msgidpool
[0];
38 for (i
= 1; i
< np
->winsize
; i
++) {
39 np
->msgidpool
[i
].next
= np
->msgidfree
;
40 np
->msgidfree
= &np
->msgidpool
[i
];
44 static inline int mq_enqueue(struct capilib_ncci
* np
, u16 msgid
)
46 struct capilib_msgidqueue
*mq
;
47 if ((mq
= np
->msgidfree
) == NULL
)
49 np
->msgidfree
= mq
->next
;
53 np
->msgidlast
->next
= mq
;
61 static inline int mq_dequeue(struct capilib_ncci
* np
, u16 msgid
)
63 struct capilib_msgidqueue
**pp
;
64 for (pp
= &np
->msgidqueue
; *pp
; pp
= &(*pp
)->next
) {
65 if ((*pp
)->msgid
== msgid
) {
66 struct capilib_msgidqueue
*mq
= *pp
;
68 if (mq
== np
->msgidlast
)
70 mq
->next
= np
->msgidfree
;
79 void capilib_new_ncci(struct list_head
*head
, u16 applid
, u32 ncci
, u32 winsize
)
81 struct capilib_ncci
*np
;
83 np
= kmalloc(sizeof(*np
), GFP_ATOMIC
);
85 printk(KERN_WARNING
"capilib_new_ncci: no memory.\n");
88 if (winsize
> CAPI_MAXDATAWINDOW
) {
89 printk(KERN_ERR
"capi_new_ncci: winsize %d too big\n",
91 winsize
= CAPI_MAXDATAWINDOW
;
95 np
->winsize
= winsize
;
97 list_add_tail(&np
->list
, head
);
98 DBG("kcapi: appl %d ncci 0x%x up", applid
, ncci
);
101 EXPORT_SYMBOL(capilib_new_ncci
);
103 void capilib_free_ncci(struct list_head
*head
, u16 applid
, u32 ncci
)
106 struct capilib_ncci
*np
;
108 list_for_each(l
, head
) {
109 np
= list_entry(l
, struct capilib_ncci
, list
);
110 if (np
->applid
!= applid
)
112 if (np
->ncci
!= ncci
)
114 printk(KERN_INFO
"kcapi: appl %d ncci 0x%x down\n", applid
, ncci
);
119 printk(KERN_ERR
"capilib_free_ncci: ncci 0x%x not found\n", ncci
);
122 EXPORT_SYMBOL(capilib_free_ncci
);
124 void capilib_release_appl(struct list_head
*head
, u16 applid
)
126 struct list_head
*l
, *n
;
127 struct capilib_ncci
*np
;
129 list_for_each_safe(l
, n
, head
) {
130 np
= list_entry(l
, struct capilib_ncci
, list
);
131 if (np
->applid
!= applid
)
133 printk(KERN_INFO
"kcapi: appl %d ncci 0x%x forced down\n", applid
, np
->ncci
);
139 EXPORT_SYMBOL(capilib_release_appl
);
141 void capilib_release(struct list_head
*head
)
143 struct list_head
*l
, *n
;
144 struct capilib_ncci
*np
;
146 list_for_each_safe(l
, n
, head
) {
147 np
= list_entry(l
, struct capilib_ncci
, list
);
148 printk(KERN_INFO
"kcapi: appl %d ncci 0x%x forced down\n", np
->applid
, np
->ncci
);
154 EXPORT_SYMBOL(capilib_release
);
156 u16
capilib_data_b3_req(struct list_head
*head
, u16 applid
, u32 ncci
, u16 msgid
)
159 struct capilib_ncci
*np
;
161 list_for_each(l
, head
) {
162 np
= list_entry(l
, struct capilib_ncci
, list
);
163 if (np
->applid
!= applid
)
165 if (np
->ncci
!= ncci
)
168 if (mq_enqueue(np
, msgid
) == 0)
169 return CAPI_SENDQUEUEFULL
;
173 printk(KERN_ERR
"capilib_data_b3_req: ncci 0x%x not found\n", ncci
);
177 EXPORT_SYMBOL(capilib_data_b3_req
);
179 void capilib_data_b3_conf(struct list_head
*head
, u16 applid
, u32 ncci
, u16 msgid
)
182 struct capilib_ncci
*np
;
184 list_for_each(l
, head
) {
185 np
= list_entry(l
, struct capilib_ncci
, list
);
186 if (np
->applid
!= applid
)
188 if (np
->ncci
!= ncci
)
191 if (mq_dequeue(np
, msgid
) == 0) {
192 printk(KERN_ERR
"kcapi: msgid %hu ncci 0x%x not on queue\n",
197 printk(KERN_ERR
"capilib_data_b3_conf: ncci 0x%x not found\n", ncci
);
200 EXPORT_SYMBOL(capilib_data_b3_conf
);