2 #include <linux/slab.h>
3 #include <linux/kernel.h>
4 #include <linux/module.h>
5 #include <linux/isdn/capilli.h>
7 #define DBG(format, arg...) do { \
8 printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
11 struct capilib_msgidqueue
{
12 struct capilib_msgidqueue
*next
;
17 struct list_head list
;
22 struct capilib_msgidqueue
*msgidqueue
;
23 struct capilib_msgidqueue
*msgidlast
;
24 struct capilib_msgidqueue
*msgidfree
;
25 struct capilib_msgidqueue msgidpool
[CAPI_MAXDATAWINDOW
];
28 // ---------------------------------------------------------------------------
31 static inline void mq_init(struct capilib_ncci
*np
)
34 np
->msgidqueue
= NULL
;
37 memset(np
->msgidpool
, 0, sizeof(np
->msgidpool
));
38 np
->msgidfree
= &np
->msgidpool
[0];
39 for (i
= 1; i
< np
->winsize
; i
++) {
40 np
->msgidpool
[i
].next
= np
->msgidfree
;
41 np
->msgidfree
= &np
->msgidpool
[i
];
45 static inline int mq_enqueue(struct capilib_ncci
*np
, u16 msgid
)
47 struct capilib_msgidqueue
*mq
;
48 if ((mq
= np
->msgidfree
) == NULL
)
50 np
->msgidfree
= mq
->next
;
54 np
->msgidlast
->next
= mq
;
62 static inline int mq_dequeue(struct capilib_ncci
*np
, u16 msgid
)
64 struct capilib_msgidqueue
**pp
;
65 for (pp
= &np
->msgidqueue
; *pp
; pp
= &(*pp
)->next
) {
66 if ((*pp
)->msgid
== msgid
) {
67 struct capilib_msgidqueue
*mq
= *pp
;
69 if (mq
== np
->msgidlast
)
71 mq
->next
= np
->msgidfree
;
80 void capilib_new_ncci(struct list_head
*head
, u16 applid
, u32 ncci
, u32 winsize
)
82 struct capilib_ncci
*np
;
84 np
= kmalloc(sizeof(*np
), GFP_ATOMIC
);
86 printk(KERN_WARNING
"capilib_new_ncci: no memory.\n");
89 if (winsize
> CAPI_MAXDATAWINDOW
) {
90 printk(KERN_ERR
"capi_new_ncci: winsize %d too big\n",
92 winsize
= CAPI_MAXDATAWINDOW
;
96 np
->winsize
= winsize
;
98 list_add_tail(&np
->list
, head
);
99 DBG("kcapi: appl %d ncci 0x%x up", applid
, ncci
);
102 EXPORT_SYMBOL(capilib_new_ncci
);
104 void capilib_free_ncci(struct list_head
*head
, u16 applid
, u32 ncci
)
107 struct capilib_ncci
*np
;
109 list_for_each(l
, head
) {
110 np
= list_entry(l
, struct capilib_ncci
, list
);
111 if (np
->applid
!= applid
)
113 if (np
->ncci
!= ncci
)
115 printk(KERN_INFO
"kcapi: appl %d ncci 0x%x down\n", applid
, ncci
);
120 printk(KERN_ERR
"capilib_free_ncci: ncci 0x%x not found\n", ncci
);
123 EXPORT_SYMBOL(capilib_free_ncci
);
125 void capilib_release_appl(struct list_head
*head
, u16 applid
)
127 struct list_head
*l
, *n
;
128 struct capilib_ncci
*np
;
130 list_for_each_safe(l
, n
, head
) {
131 np
= list_entry(l
, struct capilib_ncci
, list
);
132 if (np
->applid
!= applid
)
134 printk(KERN_INFO
"kcapi: appl %d ncci 0x%x forced down\n", applid
, np
->ncci
);
140 EXPORT_SYMBOL(capilib_release_appl
);
142 void capilib_release(struct list_head
*head
)
144 struct list_head
*l
, *n
;
145 struct capilib_ncci
*np
;
147 list_for_each_safe(l
, n
, head
) {
148 np
= list_entry(l
, struct capilib_ncci
, list
);
149 printk(KERN_INFO
"kcapi: appl %d ncci 0x%x forced down\n", np
->applid
, np
->ncci
);
155 EXPORT_SYMBOL(capilib_release
);
157 u16
capilib_data_b3_req(struct list_head
*head
, u16 applid
, u32 ncci
, u16 msgid
)
160 struct capilib_ncci
*np
;
162 list_for_each(l
, head
) {
163 np
= list_entry(l
, struct capilib_ncci
, list
);
164 if (np
->applid
!= applid
)
166 if (np
->ncci
!= ncci
)
169 if (mq_enqueue(np
, msgid
) == 0)
170 return CAPI_SENDQUEUEFULL
;
174 printk(KERN_ERR
"capilib_data_b3_req: ncci 0x%x not found\n", ncci
);
178 EXPORT_SYMBOL(capilib_data_b3_req
);
180 void capilib_data_b3_conf(struct list_head
*head
, u16 applid
, u32 ncci
, u16 msgid
)
183 struct capilib_ncci
*np
;
185 list_for_each(l
, head
) {
186 np
= list_entry(l
, struct capilib_ncci
, list
);
187 if (np
->applid
!= applid
)
189 if (np
->ncci
!= ncci
)
192 if (mq_dequeue(np
, msgid
) == 0) {
193 printk(KERN_ERR
"kcapi: msgid %hu ncci 0x%x not on queue\n",
198 printk(KERN_ERR
"capilib_data_b3_conf: ncci 0x%x not found\n", ncci
);
201 EXPORT_SYMBOL(capilib_data_b3_conf
);