aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/pcbit
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/pcbit')
-rw-r--r--drivers/isdn/pcbit/Kconfig14
-rw-r--r--drivers/isdn/pcbit/Makefile9
-rw-r--r--drivers/isdn/pcbit/callbacks.c367
-rw-r--r--drivers/isdn/pcbit/callbacks.h49
-rw-r--r--drivers/isdn/pcbit/capi.c663
-rw-r--r--drivers/isdn/pcbit/capi.h88
-rw-r--r--drivers/isdn/pcbit/drv.c1088
-rw-r--r--drivers/isdn/pcbit/edss1.c325
-rw-r--r--drivers/isdn/pcbit/edss1.h99
-rw-r--r--drivers/isdn/pcbit/layer2.c732
-rw-r--r--drivers/isdn/pcbit/layer2.h288
-rw-r--r--drivers/isdn/pcbit/module.c130
-rw-r--r--drivers/isdn/pcbit/pcbit.h169
13 files changed, 4021 insertions, 0 deletions
diff --git a/drivers/isdn/pcbit/Kconfig b/drivers/isdn/pcbit/Kconfig
new file mode 100644
index 000000000000..f06997faef16
--- /dev/null
+++ b/drivers/isdn/pcbit/Kconfig
@@ -0,0 +1,14 @@
1#
2# Config.in for PCBIT ISDN driver
3#
4config ISDN_DRV_PCBIT
5 tristate "PCBIT-D support"
6 depends on ISDN_I4L && ISA && (BROKEN || !PPC)
7 help
8 This enables support for the PCBIT ISDN-card. This card is
9 manufactured in Portugal by Octal. For running this card,
10 additional firmware is necessary, which has to be downloaded into
11 the card using a utility which is distributed separately. See
12 <file:Documentation/isdn/README> and
13 <file:Documentation/isdn/README.pcbit> for more information.
14
diff --git a/drivers/isdn/pcbit/Makefile b/drivers/isdn/pcbit/Makefile
new file mode 100644
index 000000000000..2d026c3242e8
--- /dev/null
+++ b/drivers/isdn/pcbit/Makefile
@@ -0,0 +1,9 @@
1# Makefile for the pcbit ISDN device driver
2
3# Each configuration option enables a list of files.
4
5obj-$(CONFIG_ISDN_DRV_PCBIT) += pcbit.o
6
7# Multipart objects.
8
9pcbit-y := module.o edss1.o drv.o layer2.o capi.o callbacks.o
diff --git a/drivers/isdn/pcbit/callbacks.c b/drivers/isdn/pcbit/callbacks.c
new file mode 100644
index 000000000000..692ec72d1ee8
--- /dev/null
+++ b/drivers/isdn/pcbit/callbacks.c
@@ -0,0 +1,367 @@
1/*
2 * Callbacks for the FSM
3 *
4 * Copyright (C) 1996 Universidade de Lisboa
5 *
6 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
7 *
8 * This software may be used and distributed according to the terms of
9 * the GNU General Public License, incorporated herein by reference.
10 */
11
12/*
13 * Fix: 19981230 - Carlos Morgado <chbm@techie.com>
14 * Port of Nelson Escravana's <nelson.escravana@usa.net> fix to CalledPN
15 * NULL pointer dereference in cb_in_1 (originally fixed in 2.0)
16 */
17
18#include <linux/sched.h>
19#include <linux/string.h>
20#include <linux/kernel.h>
21
22#include <linux/types.h>
23#include <linux/slab.h>
24#include <linux/mm.h>
25#include <linux/skbuff.h>
26
27#include <asm/io.h>
28
29#include <linux/isdnif.h>
30
31#include "pcbit.h"
32#include "layer2.h"
33#include "edss1.h"
34#include "callbacks.h"
35#include "capi.h"
36
37ushort last_ref_num = 1;
38
39/*
40 * send_conn_req
41 *
42 */
43
44void cb_out_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
45 struct callb_data *cbdata)
46{
47 struct sk_buff *skb;
48 int len;
49 ushort refnum;
50
51
52#ifdef DEBUG
53 printk(KERN_DEBUG "Called Party Number: %s\n",
54 cbdata->data.setup.CalledPN);
55#endif
56 /*
57 * hdr - kmalloc in capi_conn_req
58 * - kfree when msg has been sent
59 */
60
61 if ((len = capi_conn_req(cbdata->data.setup.CalledPN, &skb,
62 chan->proto)) < 0)
63 {
64 printk("capi_conn_req failed\n");
65 return;
66 }
67
68
69 refnum = last_ref_num++ & 0x7fffU;
70
71 chan->callref = 0;
72 chan->layer2link = 0;
73 chan->snum = 0;
74 chan->s_refnum = refnum;
75
76 pcbit_l2_write(dev, MSG_CONN_REQ, refnum, skb, len);
77}
78
79/*
80 * rcv CONNECT
81 * will go into ACTIVE state
82 * send CONN_ACTIVE_RESP
83 * send Select protocol request
84 */
85
86void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
87 struct callb_data *data)
88{
89 isdn_ctrl ictl;
90 struct sk_buff *skb;
91 int len;
92 ushort refnum;
93
94 if ((len=capi_conn_active_resp(chan, &skb)) < 0)
95 {
96 printk("capi_conn_active_req failed\n");
97 return;
98 }
99
100 refnum = last_ref_num++ & 0x7fffU;
101 chan->s_refnum = refnum;
102
103 pcbit_l2_write(dev, MSG_CONN_ACTV_RESP, refnum, skb, len);
104
105
106 ictl.command = ISDN_STAT_DCONN;
107 ictl.driver=dev->id;
108 ictl.arg=chan->id;
109 dev->dev_if->statcallb(&ictl);
110
111 /* ACTIVE D-channel */
112
113 /* Select protocol */
114
115 if ((len=capi_select_proto_req(chan, &skb, 1 /*outgoing*/)) < 0) {
116 printk("capi_select_proto_req failed\n");
117 return;
118 }
119
120 refnum = last_ref_num++ & 0x7fffU;
121 chan->s_refnum = refnum;
122
123 pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
124}
125
126
127/*
128 * Disconnect received (actually RELEASE COMPLETE)
129 * This means we were not able to establish connection with remote
130 * Inform the big boss above
131 */
132void cb_out_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
133 struct callb_data *data)
134{
135 isdn_ctrl ictl;
136
137 ictl.command = ISDN_STAT_DHUP;
138 ictl.driver=dev->id;
139 ictl.arg=chan->id;
140 dev->dev_if->statcallb(&ictl);
141}
142
143
144/*
145 * Incoming call received
146 * inform user
147 */
148
149void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
150 struct callb_data *cbdata)
151{
152 isdn_ctrl ictl;
153 unsigned short refnum;
154 struct sk_buff *skb;
155 int len;
156
157
158 ictl.command = ISDN_STAT_ICALL;
159 ictl.driver=dev->id;
160 ictl.arg=chan->id;
161
162 /*
163 * ictl.num >= strlen() + strlen() + 5
164 */
165
166 if (cbdata->data.setup.CallingPN == NULL) {
167 printk(KERN_DEBUG "NULL CallingPN to phone; using 0\n");
168 strcpy(ictl.parm.setup.phone, "0");
169 }
170 else {
171 strcpy(ictl.parm.setup.phone, cbdata->data.setup.CallingPN);
172 }
173 if (cbdata->data.setup.CalledPN == NULL) {
174 printk(KERN_DEBUG "NULL CalledPN to eazmsn; using 0\n");
175 strcpy(ictl.parm.setup.eazmsn, "0");
176 }
177 else {
178 strcpy(ictl.parm.setup.eazmsn, cbdata->data.setup.CalledPN);
179 }
180 ictl.parm.setup.si1 = 7;
181 ictl.parm.setup.si2 = 0;
182 ictl.parm.setup.plan = 0;
183 ictl.parm.setup.screen = 0;
184
185#ifdef DEBUG
186 printk(KERN_DEBUG "statstr: %s\n", ictl.num);
187#endif
188
189 dev->dev_if->statcallb(&ictl);
190
191
192 if ((len=capi_conn_resp(chan, &skb)) < 0) {
193 printk(KERN_DEBUG "capi_conn_resp failed\n");
194 return;
195 }
196
197 refnum = last_ref_num++ & 0x7fffU;
198 chan->s_refnum = refnum;
199
200 pcbit_l2_write(dev, MSG_CONN_RESP, refnum, skb, len);
201}
202
203/*
204 * user has replied
205 * open the channel
206 * send CONNECT message CONNECT_ACTIVE_REQ in CAPI
207 */
208
209void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
210 struct callb_data *data)
211{
212 unsigned short refnum;
213 struct sk_buff *skb;
214 int len;
215
216 if ((len = capi_conn_active_req(chan, &skb)) < 0) {
217 printk(KERN_DEBUG "capi_conn_active_req failed\n");
218 return;
219 }
220
221
222 refnum = last_ref_num++ & 0x7fffU;
223 chan->s_refnum = refnum;
224
225 printk(KERN_DEBUG "sending MSG_CONN_ACTV_REQ\n");
226 pcbit_l2_write(dev, MSG_CONN_ACTV_REQ, refnum, skb, len);
227}
228
229/*
230 * CONN_ACK arrived
231 * start b-proto selection
232 *
233 */
234
235void cb_in_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
236 struct callb_data *data)
237{
238 unsigned short refnum;
239 struct sk_buff *skb;
240 int len;
241
242 if ((len = capi_select_proto_req(chan, &skb, 0 /*incoming*/)) < 0)
243 {
244 printk("capi_select_proto_req failed\n");
245 return;
246 }
247
248 refnum = last_ref_num++ & 0x7fffU;
249 chan->s_refnum = refnum;
250
251 pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
252
253}
254
255
256/*
257 * Received disconnect ind on active state
258 * send disconnect resp
259 * send msg to user
260 */
261void cb_disc_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
262 struct callb_data *data)
263{
264 struct sk_buff *skb;
265 int len;
266 ushort refnum;
267 isdn_ctrl ictl;
268
269 if ((len = capi_disc_resp(chan, &skb)) < 0) {
270 printk("capi_disc_resp failed\n");
271 return;
272 }
273
274 refnum = last_ref_num++ & 0x7fffU;
275 chan->s_refnum = refnum;
276
277 pcbit_l2_write(dev, MSG_DISC_RESP, refnum, skb, len);
278
279 ictl.command = ISDN_STAT_BHUP;
280 ictl.driver=dev->id;
281 ictl.arg=chan->id;
282 dev->dev_if->statcallb(&ictl);
283}
284
285
286/*
287 * User HANGUP on active/call proceeding state
288 * send disc.req
289 */
290void cb_disc_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
291 struct callb_data *data)
292{
293 struct sk_buff *skb;
294 int len;
295 ushort refnum;
296
297 if ((len = capi_disc_req(chan->callref, &skb, CAUSE_NORMAL)) < 0)
298 {
299 printk("capi_disc_req failed\n");
300 return;
301 }
302
303 refnum = last_ref_num++ & 0x7fffU;
304 chan->s_refnum = refnum;
305
306 pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb, len);
307}
308
309/*
310 * Disc confirm received send BHUP
311 * Problem: when the HL driver sends the disc req itself
312 * LL receives BHUP
313 */
314void cb_disc_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
315 struct callb_data *data)
316{
317 isdn_ctrl ictl;
318
319 ictl.command = ISDN_STAT_BHUP;
320 ictl.driver=dev->id;
321 ictl.arg=chan->id;
322 dev->dev_if->statcallb(&ictl);
323}
324
325void cb_notdone(struct pcbit_dev * dev, struct pcbit_chan* chan,
326 struct callb_data *data)
327{
328}
329
330/*
331 * send activate b-chan protocol
332 */
333void cb_selp_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
334 struct callb_data *data)
335{
336 struct sk_buff *skb;
337 int len;
338 ushort refnum;
339
340 if ((len = capi_activate_transp_req(chan, &skb)) < 0)
341 {
342 printk("capi_conn_activate_transp_req failed\n");
343 return;
344 }
345
346 refnum = last_ref_num++ & 0x7fffU;
347 chan->s_refnum = refnum;
348
349 pcbit_l2_write(dev, MSG_ACT_TRANSP_REQ, refnum, skb, len);
350}
351
352/*
353 * Inform User that the B-channel is available
354 */
355void cb_open(struct pcbit_dev * dev, struct pcbit_chan* chan,
356 struct callb_data *data)
357{
358 isdn_ctrl ictl;
359
360 ictl.command = ISDN_STAT_BCONN;
361 ictl.driver=dev->id;
362 ictl.arg=chan->id;
363 dev->dev_if->statcallb(&ictl);
364}
365
366
367
diff --git a/drivers/isdn/pcbit/callbacks.h b/drivers/isdn/pcbit/callbacks.h
new file mode 100644
index 000000000000..f510dc56b57e
--- /dev/null
+++ b/drivers/isdn/pcbit/callbacks.h
@@ -0,0 +1,49 @@
1/*
2 * Callbacks prototypes for FSM
3 *
4 * Copyright (C) 1996 Universidade de Lisboa
5 *
6 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
7 *
8 * This software may be used and distributed according to the terms of
9 * the GNU General Public License, incorporated herein by reference.
10 */
11
12#ifndef CALLBACKS_H
13#define CALLBACKS_H
14
15
16extern void cb_out_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
17 struct callb_data *data);
18
19extern void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
20 struct callb_data *data);
21
22extern void cb_out_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
23 struct callb_data *data);
24
25extern void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
26 struct callb_data *data);
27extern void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
28 struct callb_data *data);
29extern void cb_in_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
30 struct callb_data *data);
31
32extern void cb_disc_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
33 struct callb_data *data);
34extern void cb_disc_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
35 struct callb_data *data);
36extern void cb_disc_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
37 struct callb_data *data);
38
39extern void cb_notdone(struct pcbit_dev * dev, struct pcbit_chan* chan,
40 struct callb_data *data);
41
42extern void cb_selp_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
43 struct callb_data *data);
44extern void cb_open(struct pcbit_dev * dev, struct pcbit_chan* chan,
45 struct callb_data *data);
46
47#endif
48
49
diff --git a/drivers/isdn/pcbit/capi.c b/drivers/isdn/pcbit/capi.c
new file mode 100644
index 000000000000..29eb03a8c29d
--- /dev/null
+++ b/drivers/isdn/pcbit/capi.c
@@ -0,0 +1,663 @@
1/*
2 * CAPI encoder/decoder for
3 * Portugal Telecom CAPI 2.0
4 *
5 * Copyright (C) 1996 Universidade de Lisboa
6 *
7 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
8 *
9 * This software may be used and distributed according to the terms of
10 * the GNU General Public License, incorporated herein by reference.
11 *
12 * Not compatible with the AVM Gmbh. CAPI 2.0
13 *
14 */
15
16/*
17 * Documentation:
18 * - "Common ISDN API - Perfil Português - Versão 2.1",
19 * Telecom Portugal, Fev 1992.
20 * - "Common ISDN API - Especificação de protocolos para
21 * acesso aos canais B", Inesc, Jan 1994.
22 */
23
24/*
25 * TODO: better decoding of Information Elements
26 * for debug purposes mainly
27 * encode our number in CallerPN and ConnectedPN
28 */
29
30#include <linux/sched.h>
31#include <linux/string.h>
32#include <linux/kernel.h>
33
34#include <linux/types.h>
35#include <linux/slab.h>
36#include <linux/mm.h>
37
38#include <linux/skbuff.h>
39
40#include <asm/io.h>
41#include <asm/string.h>
42
43#include <linux/isdnif.h>
44
45#include "pcbit.h"
46#include "edss1.h"
47#include "capi.h"
48
49
50/*
51 * Encoding of CAPI messages
52 *
53 */
54
55int capi_conn_req(const char * calledPN, struct sk_buff **skb, int proto)
56{
57 ushort len;
58
59 /*
60 * length
61 * AppInfoMask - 2
62 * BC0 - 3
63 * BC1 - 1
64 * Chan - 2
65 * Keypad - 1
66 * CPN - 1
67 * CPSA - 1
68 * CalledPN - 2 + strlen
69 * CalledPSA - 1
70 * rest... - 4
71 * ----------------
72 * Total 18 + strlen
73 */
74
75 len = 18 + strlen(calledPN);
76
77 if (proto == ISDN_PROTO_L2_TRANS)
78 len++;
79
80 if ((*skb = dev_alloc_skb(len)) == NULL) {
81
82 printk(KERN_WARNING "capi_conn_req: alloc_skb failed\n");
83 return -1;
84 }
85
86 /* InfoElmMask */
87 *((ushort*) skb_put(*skb, 2)) = AppInfoMask;
88
89 if (proto == ISDN_PROTO_L2_TRANS)
90 {
91 /* Bearer Capability - Mandatory*/
92 *(skb_put(*skb, 1)) = 3; /* BC0.Length */
93 *(skb_put(*skb, 1)) = 0x80; /* Speech */
94 *(skb_put(*skb, 1)) = 0x10; /* Circuit Mode */
95 *(skb_put(*skb, 1)) = 0x23; /* A-law */
96 }
97 else
98 {
99 /* Bearer Capability - Mandatory*/
100 *(skb_put(*skb, 1)) = 2; /* BC0.Length */
101 *(skb_put(*skb, 1)) = 0x88; /* Digital Information */
102 *(skb_put(*skb, 1)) = 0x90; /* BC0.Octect4 */
103 }
104
105 /* Bearer Capability - Optional*/
106 *(skb_put(*skb, 1)) = 0; /* BC1.Length = 0 */
107
108 *(skb_put(*skb, 1)) = 1; /* ChannelID.Length = 1 */
109 *(skb_put(*skb, 1)) = 0x83; /* Basic Interface - Any Channel */
110
111 *(skb_put(*skb, 1)) = 0; /* Keypad.Length = 0 */
112
113
114 *(skb_put(*skb, 1)) = 0; /* CallingPN.Length = 0 */
115 *(skb_put(*skb, 1)) = 0; /* CallingPSA.Length = 0 */
116
117 /* Called Party Number */
118 *(skb_put(*skb, 1)) = strlen(calledPN) + 1;
119 *(skb_put(*skb, 1)) = 0x81;
120 memcpy(skb_put(*skb, strlen(calledPN)), calledPN, strlen(calledPN));
121
122 /* '#' */
123
124 *(skb_put(*skb, 1)) = 0; /* CalledPSA.Length = 0 */
125
126 /* LLC.Length = 0; */
127 /* HLC0.Length = 0; */
128 /* HLC1.Length = 0; */
129 /* UTUS.Length = 0; */
130 memset(skb_put(*skb, 4), 0, 4);
131
132 return len;
133}
134
135int capi_conn_resp(struct pcbit_chan* chan, struct sk_buff **skb)
136{
137
138 if ((*skb = dev_alloc_skb(5)) == NULL) {
139
140 printk(KERN_WARNING "capi_conn_resp: alloc_skb failed\n");
141 return -1;
142 }
143
144 *((ushort*) skb_put(*skb, 2) ) = chan->callref;
145 *(skb_put(*skb, 1)) = 0x01; /* ACCEPT_CALL */
146 *(skb_put(*skb, 1)) = 0;
147 *(skb_put(*skb, 1)) = 0;
148
149 return 5;
150}
151
152int capi_conn_active_req(struct pcbit_chan* chan, struct sk_buff **skb)
153{
154 /*
155 * 8 bytes
156 */
157
158 if ((*skb = dev_alloc_skb(8)) == NULL) {
159
160 printk(KERN_WARNING "capi_conn_active_req: alloc_skb failed\n");
161 return -1;
162 }
163
164 *((ushort*) skb_put(*skb, 2) ) = chan->callref;
165
166#ifdef DEBUG
167 printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref);
168#endif
169
170 *(skb_put(*skb, 1)) = 0; /* BC.Length = 0; */
171 *(skb_put(*skb, 1)) = 0; /* ConnectedPN.Length = 0 */
172 *(skb_put(*skb, 1)) = 0; /* PSA.Length */
173 *(skb_put(*skb, 1)) = 0; /* LLC.Length = 0; */
174 *(skb_put(*skb, 1)) = 0; /* HLC.Length = 0; */
175 *(skb_put(*skb, 1)) = 0; /* UTUS.Length = 0; */
176
177 return 8;
178}
179
180int capi_conn_active_resp(struct pcbit_chan* chan, struct sk_buff **skb)
181{
182 /*
183 * 2 bytes
184 */
185
186 if ((*skb = dev_alloc_skb(2)) == NULL) {
187
188 printk(KERN_WARNING "capi_conn_active_resp: alloc_skb failed\n");
189 return -1;
190 }
191
192 *((ushort*) skb_put(*skb, 2) ) = chan->callref;
193
194 return 2;
195}
196
197
198int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb,
199 int outgoing)
200{
201
202 /*
203 * 18 bytes
204 */
205
206 if ((*skb = dev_alloc_skb(18)) == NULL) {
207
208 printk(KERN_WARNING "capi_select_proto_req: alloc_skb failed\n");
209 return -1;
210 }
211
212 *((ushort*) skb_put(*skb, 2) ) = chan->callref;
213
214 /* Layer2 protocol */
215
216 switch (chan->proto) {
217 case ISDN_PROTO_L2_X75I:
218 *(skb_put(*skb, 1)) = 0x05; /* LAPB */
219 break;
220 case ISDN_PROTO_L2_HDLC:
221 *(skb_put(*skb, 1)) = 0x02;
222 break;
223 case ISDN_PROTO_L2_TRANS:
224 /*
225 * Voice (a-law)
226 */
227 *(skb_put(*skb, 1)) = 0x06;
228 break;
229 default:
230#ifdef DEBUG
231 printk(KERN_DEBUG "Transparent\n");
232#endif
233 *(skb_put(*skb, 1)) = 0x03;
234 break;
235 }
236
237 *(skb_put(*skb, 1)) = (outgoing ? 0x02 : 0x42); /* Don't ask */
238 *(skb_put(*skb, 1)) = 0x00;
239
240 *((ushort *) skb_put(*skb, 2)) = MRU;
241
242
243 *(skb_put(*skb, 1)) = 0x08; /* Modulo */
244 *(skb_put(*skb, 1)) = 0x07; /* Max Window */
245
246 *(skb_put(*skb, 1)) = 0x01; /* No Layer3 Protocol */
247
248 /*
249 * 2 - layer3 MTU [10]
250 * - Modulo [12]
251 * - Window
252 * - layer1 proto [14]
253 * - bitrate
254 * - sub-channel [16]
255 * - layer1dataformat [17]
256 */
257
258 memset(skb_put(*skb, 8), 0, 8);
259
260 return 18;
261}
262
263
264int capi_activate_transp_req(struct pcbit_chan *chan, struct sk_buff **skb)
265{
266
267 if ((*skb = dev_alloc_skb(7)) == NULL) {
268
269 printk(KERN_WARNING "capi_activate_transp_req: alloc_skb failed\n");
270 return -1;
271 }
272
273 *((ushort*) skb_put(*skb, 2) ) = chan->callref;
274
275
276 *(skb_put(*skb, 1)) = chan->layer2link; /* Layer2 id */
277 *(skb_put(*skb, 1)) = 0x00; /* Transmit by default */
278
279 *((ushort *) skb_put(*skb, 2)) = MRU;
280
281 *(skb_put(*skb, 1)) = 0x01; /* Enables reception*/
282
283 return 7;
284}
285
286int capi_tdata_req(struct pcbit_chan* chan, struct sk_buff *skb)
287{
288 ushort data_len;
289
290
291 /*
292 * callref - 2
293 * layer2link - 1
294 * wBlockLength - 2
295 * data - 4
296 * sernum - 1
297 */
298
299 data_len = skb->len;
300
301 if(skb_headroom(skb) < 10)
302 {
303 printk(KERN_CRIT "No headspace (%u) on headroom %p for capi header\n", skb_headroom(skb), skb);
304 }
305 else
306 {
307 skb_push(skb, 10);
308 }
309
310 *((u16 *) (skb->data)) = chan->callref;
311 skb->data[2] = chan->layer2link;
312 *((u16 *) (skb->data + 3)) = data_len;
313
314 chan->s_refnum = (chan->s_refnum + 1) % 8;
315 *((u32 *) (skb->data + 5)) = chan->s_refnum;
316
317 skb->data[9] = 0; /* HDLC frame number */
318
319 return 10;
320}
321
322int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff ** skb)
323
324{
325 if ((*skb = dev_alloc_skb(4)) == NULL) {
326
327 printk(KERN_WARNING "capi_tdata_resp: alloc_skb failed\n");
328 return -1;
329 }
330
331 *((ushort*) skb_put(*skb, 2) ) = chan->callref;
332
333 *(skb_put(*skb, 1)) = chan->layer2link;
334 *(skb_put(*skb, 1)) = chan->r_refnum;
335
336 return (*skb)->len;
337}
338
339int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause)
340{
341
342 if ((*skb = dev_alloc_skb(6)) == NULL) {
343
344 printk(KERN_WARNING "capi_disc_req: alloc_skb failed\n");
345 return -1;
346 }
347
348 *((ushort*) skb_put(*skb, 2) ) = callref;
349
350 *(skb_put(*skb, 1)) = 2; /* Cause.Length = 2; */
351 *(skb_put(*skb, 1)) = 0x80;
352 *(skb_put(*skb, 1)) = 0x80 | cause;
353
354 /*
355 * Change it: we should send 'Sic transit gloria Mundi' here ;-)
356 */
357
358 *(skb_put(*skb, 1)) = 0; /* UTUS.Length = 0; */
359
360 return 6;
361}
362
363int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb)
364{
365 if ((*skb = dev_alloc_skb(2)) == NULL) {
366
367 printk(KERN_WARNING "capi_disc_resp: alloc_skb failed\n");
368 return -1;
369 }
370
371 *((ushort*) skb_put(*skb, 2)) = chan->callref;
372
373 return 2;
374}
375
376
377/*
378 * Decoding of CAPI messages
379 *
380 */
381
382int capi_decode_conn_ind(struct pcbit_chan * chan,
383 struct sk_buff *skb,
384 struct callb_data *info)
385{
386 int CIlen, len;
387
388 /* Call Reference [CAPI] */
389 chan->callref = *((ushort*) skb->data);
390 skb_pull(skb, 2);
391
392#ifdef DEBUG
393 printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref);
394#endif
395
396 /* Channel Identification */
397
398 /* Expect
399 Len = 1
400 Octect 3 = 0100 10CC - [ 7 Basic, 4 , 2-1 chan ]
401 */
402
403 CIlen = skb->data[0];
404#ifdef DEBUG
405 if (CIlen == 1) {
406
407 if ( ((skb->data[1]) & 0xFC) == 0x48 )
408 printk(KERN_DEBUG "decode_conn_ind: chan ok\n");
409 printk(KERN_DEBUG "phyChan = %d\n", skb->data[1] & 0x03);
410 }
411 else
412 printk(KERN_DEBUG "conn_ind: CIlen = %d\n", CIlen);
413#endif
414 skb_pull(skb, CIlen + 1);
415
416 /* Calling Party Number */
417 /* An "additional service" as far as Portugal Telecom is concerned */
418
419 len = skb->data[0];
420
421 if (len > 0) {
422 int count = 1;
423
424#ifdef DEBUG
425 printk(KERN_DEBUG "CPN: Octect 3 %02x\n", skb->data[1]);
426#endif
427 if ((skb->data[1] & 0x80) == 0)
428 count = 2;
429
430 if (!(info->data.setup.CallingPN = kmalloc(len - count + 1, GFP_ATOMIC)))
431 return -1;
432
433 memcpy(info->data.setup.CallingPN, skb->data + count + 1,
434 len - count);
435 info->data.setup.CallingPN[len - count] = 0;
436
437 }
438 else {
439 info->data.setup.CallingPN = NULL;
440 printk(KERN_DEBUG "NULL CallingPN\n");
441 }
442
443 skb_pull(skb, len + 1);
444
445 /* Calling Party Subaddress */
446 skb_pull(skb, skb->data[0] + 1);
447
448 /* Called Party Number */
449
450 len = skb->data[0];
451
452 if (len > 0) {
453 int count = 1;
454
455 if ((skb->data[1] & 0x80) == 0)
456 count = 2;
457
458 if (!(info->data.setup.CalledPN = kmalloc(len - count + 1, GFP_ATOMIC)))
459 return -1;
460
461 memcpy(info->data.setup.CalledPN, skb->data + count + 1,
462 len - count);
463 info->data.setup.CalledPN[len - count] = 0;
464
465 }
466 else {
467 info->data.setup.CalledPN = NULL;
468 printk(KERN_DEBUG "NULL CalledPN\n");
469 }
470
471 skb_pull(skb, len + 1);
472
473 /* Called Party Subaddress */
474 skb_pull(skb, skb->data[0] + 1);
475
476 /* LLC */
477 skb_pull(skb, skb->data[0] + 1);
478
479 /* HLC */
480 skb_pull(skb, skb->data[0] + 1);
481
482 /* U2U */
483 skb_pull(skb, skb->data[0] + 1);
484
485 return 0;
486}
487
488/*
489 * returns errcode
490 */
491
492int capi_decode_conn_conf(struct pcbit_chan * chan, struct sk_buff *skb,
493 int *complete)
494{
495 int errcode;
496
497 chan->callref = *((ushort *) skb->data); /* Update CallReference */
498 skb_pull(skb, 2);
499
500 errcode = *((ushort *) skb->data); /* read errcode */
501 skb_pull(skb, 2);
502
503 *complete = *(skb->data);
504 skb_pull(skb, 1);
505
506 /* FIX ME */
507 /* This is actually a firmware bug */
508 if (!*complete)
509 {
510 printk(KERN_DEBUG "complete=%02x\n", *complete);
511 *complete = 1;
512 }
513
514
515 /* Optional Bearer Capability */
516 skb_pull(skb, *(skb->data) + 1);
517
518 /* Channel Identification */
519 skb_pull(skb, *(skb->data) + 1);
520
521 /* High Layer Compatibility follows */
522 skb_pull(skb, *(skb->data) + 1);
523
524 return errcode;
525}
526
527int capi_decode_conn_actv_ind(struct pcbit_chan * chan, struct sk_buff *skb)
528{
529 ushort len;
530#ifdef DEBUG
531 char str[32];
532#endif
533
534 /* Yet Another Bearer Capability */
535 skb_pull(skb, *(skb->data) + 1);
536
537
538 /* Connected Party Number */
539 len=*(skb->data);
540
541#ifdef DEBUG
542 if (len > 1 && len < 31) {
543 memcpy(str, skb->data + 2, len - 1);
544 str[len] = 0;
545 printk(KERN_DEBUG "Connected Party Number: %s\n", str);
546 }
547 else
548 printk(KERN_DEBUG "actv_ind CPN len = %d\n", len);
549#endif
550
551 skb_pull(skb, len + 1);
552
553 /* Connected Subaddress */
554 skb_pull(skb, *(skb->data) + 1);
555
556 /* Low Layer Capability */
557 skb_pull(skb, *(skb->data) + 1);
558
559 /* High Layer Capability */
560 skb_pull(skb, *(skb->data) + 1);
561
562 return 0;
563}
564
565int capi_decode_conn_actv_conf(struct pcbit_chan * chan, struct sk_buff *skb)
566{
567 ushort errcode;
568
569 errcode = *((ushort*) skb->data);
570 skb_pull(skb, 2);
571
572 /* Channel Identification
573 skb_pull(skb, skb->data[0] + 1);
574 */
575 return errcode;
576}
577
578
579int capi_decode_sel_proto_conf(struct pcbit_chan *chan, struct sk_buff *skb)
580{
581 ushort errcode;
582
583 chan->layer2link = *(skb->data);
584 skb_pull(skb, 1);
585
586 errcode = *((ushort*) skb->data);
587 skb_pull(skb, 2);
588
589 return errcode;
590}
591
592int capi_decode_actv_trans_conf(struct pcbit_chan *chan, struct sk_buff *skb)
593{
594 ushort errcode;
595
596 if (chan->layer2link != *(skb->data) )
597 printk("capi_decode_actv_trans_conf: layer2link doesn't match\n");
598
599 skb_pull(skb, 1);
600
601 errcode = *((ushort*) skb->data);
602 skb_pull(skb, 2);
603
604 return errcode;
605}
606
607int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb)
608{
609 ushort len;
610#ifdef DEBUG
611 int i;
612#endif
613 /* Cause */
614
615 len = *(skb->data);
616 skb_pull(skb, 1);
617
618#ifdef DEBUG
619
620 for (i=0; i<len; i++)
621 printk(KERN_DEBUG "Cause Octect %d: %02x\n", i+3,
622 *(skb->data + i));
623#endif
624
625 skb_pull(skb, len);
626
627 return 0;
628}
629
630int capi_decode_disc_conf(struct pcbit_chan *chan, struct sk_buff *skb)
631{
632 ushort errcode;
633
634 errcode = *((ushort*) skb->data);
635 skb_pull(skb, 2);
636
637 return errcode;
638}
639
640#ifdef DEBUG
641int capi_decode_debug_188(u_char *hdr, ushort hdrlen)
642{
643 char str[64];
644 int len;
645
646 len = hdr[0];
647
648 if (len < 64 && len == hdrlen - 1) {
649 memcpy(str, hdr + 1, hdrlen - 1);
650 str[hdrlen - 1] = 0;
651 printk("%s\n", str);
652 }
653 else
654 printk("debug message incorrect\n");
655
656 return 0;
657}
658#endif
659
660
661
662
663
diff --git a/drivers/isdn/pcbit/capi.h b/drivers/isdn/pcbit/capi.h
new file mode 100644
index 000000000000..18e6aa360a8f
--- /dev/null
+++ b/drivers/isdn/pcbit/capi.h
@@ -0,0 +1,88 @@
1/*
2 * CAPI encode/decode prototypes and defines
3 *
4 * Copyright (C) 1996 Universidade de Lisboa
5 *
6 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
7 *
8 * This software may be used and distributed according to the terms of
9 * the GNU General Public License, incorporated herein by reference.
10 */
11
12#ifndef CAPI_H
13#define CAPI_H
14
15
16#define REQ_CAUSE 0x01
17#define REQ_DISPLAY 0x04
18#define REQ_USER_TO_USER 0x08
19
20#define AppInfoMask REQ_CAUSE|REQ_DISPLAY|REQ_USER_TO_USER
21
22/* Connection Setup */
23extern int capi_conn_req(const char * calledPN, struct sk_buff **buf,
24 int proto);
25extern int capi_decode_conn_conf(struct pcbit_chan * chan, struct sk_buff *skb,
26 int *complete);
27
28extern int capi_decode_conn_ind(struct pcbit_chan * chan, struct sk_buff *skb,
29 struct callb_data *info);
30extern int capi_conn_resp(struct pcbit_chan* chan, struct sk_buff **skb);
31
32extern int capi_conn_active_req(struct pcbit_chan* chan, struct sk_buff **skb);
33extern int capi_decode_conn_actv_conf(struct pcbit_chan * chan,
34 struct sk_buff *skb);
35
36extern int capi_decode_conn_actv_ind(struct pcbit_chan * chan,
37 struct sk_buff *skb);
38extern int capi_conn_active_resp(struct pcbit_chan* chan,
39 struct sk_buff **skb);
40
41/* Data */
42extern int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb,
43 int outgoing);
44extern int capi_decode_sel_proto_conf(struct pcbit_chan *chan,
45 struct sk_buff *skb);
46
47extern int capi_activate_transp_req(struct pcbit_chan *chan,
48 struct sk_buff **skb);
49extern int capi_decode_actv_trans_conf(struct pcbit_chan *chan,
50 struct sk_buff *skb);
51
52extern int capi_tdata_req(struct pcbit_chan* chan, struct sk_buff *skb);
53extern int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff ** skb);
54
55/* Connection Termination */
56extern int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause);
57extern int capi_decode_disc_conf(struct pcbit_chan *chan, struct sk_buff *skb);
58
59extern int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb);
60extern int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb);
61
62#ifdef DEBUG
63extern int capi_decode_debug_188(u_char *hdr, ushort hdrlen);
64#endif
65
66static inline struct pcbit_chan *
67capi_channel(struct pcbit_dev *dev, struct sk_buff *skb)
68{
69 ushort callref;
70
71 callref = *((ushort*) skb->data);
72 skb_pull(skb, 2);
73
74 if (dev->b1->callref == callref)
75 return dev->b1;
76 else if (dev->b2->callref == callref)
77 return dev->b2;
78
79 return NULL;
80}
81
82#endif
83
84
85
86
87
88
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
new file mode 100644
index 000000000000..e98f9c48c184
--- /dev/null
+++ b/drivers/isdn/pcbit/drv.c
@@ -0,0 +1,1088 @@
1/*
2 * PCBIT-D interface with isdn4linux
3 *
4 * Copyright (C) 1996 Universidade de Lisboa
5 *
6 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
7 *
8 * This software may be used and distributed according to the terms of
9 * the GNU General Public License, incorporated herein by reference.
10 */
11
12/*
13 * Fixes:
14 *
15 * Nuno Grilo <l38486@alfa.ist.utl.pt>
16 * fixed msn_list NULL pointer dereference.
17 *
18 */
19
20#include <linux/module.h>
21
22#include <linux/sched.h>
23
24#include <linux/kernel.h>
25
26#include <linux/types.h>
27#include <linux/slab.h>
28#include <linux/mm.h>
29#include <linux/interrupt.h>
30#include <linux/string.h>
31#include <linux/skbuff.h>
32
33#include <linux/isdnif.h>
34#include <asm/string.h>
35#include <asm/io.h>
36#include <linux/ioport.h>
37
38#include "pcbit.h"
39#include "edss1.h"
40#include "layer2.h"
41#include "capi.h"
42
43
44extern ushort last_ref_num;
45
46static int pcbit_ioctl(isdn_ctrl* ctl);
47
48static char* pcbit_devname[MAX_PCBIT_CARDS] = {
49 "pcbit0",
50 "pcbit1",
51 "pcbit2",
52 "pcbit3"
53};
54
55/*
56 * prototypes
57 */
58
59int pcbit_command(isdn_ctrl* ctl);
60int pcbit_stat(u_char __user * buf, int len, int, int);
61int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb);
62int pcbit_writecmd(const u_char __user *, int, int, int);
63
64static int set_protocol_running(struct pcbit_dev * dev);
65
66static void pcbit_clear_msn(struct pcbit_dev *dev);
67static void pcbit_set_msn(struct pcbit_dev *dev, char *list);
68static int pcbit_check_msn(struct pcbit_dev *dev, char *msn);
69
70
71extern void pcbit_deliver(void * data);
72
73int pcbit_init_dev(int board, int mem_base, int irq)
74{
75 struct pcbit_dev *dev;
76 isdn_if *dev_if;
77
78 if ((dev=kmalloc(sizeof(struct pcbit_dev), GFP_KERNEL)) == NULL)
79 {
80 printk("pcbit_init: couldn't malloc pcbit_dev struct\n");
81 return -ENOMEM;
82 }
83
84 dev_pcbit[board] = dev;
85 memset(dev, 0, sizeof(struct pcbit_dev));
86 init_waitqueue_head(&dev->set_running_wq);
87 spin_lock_init(&dev->lock);
88
89 if (mem_base >= 0xA0000 && mem_base <= 0xFFFFF ) {
90 dev->ph_mem = mem_base;
91 if (!request_mem_region(dev->ph_mem, 4096, "PCBIT mem")) {
92 printk(KERN_WARNING
93 "PCBIT: memory region %lx-%lx already in use\n",
94 dev->ph_mem, dev->ph_mem + 4096);
95 kfree(dev);
96 dev_pcbit[board] = NULL;
97 return -EACCES;
98 }
99 dev->sh_mem = ioremap(dev->ph_mem, 4096);
100 }
101 else
102 {
103 printk("memory address invalid");
104 kfree(dev);
105 dev_pcbit[board] = NULL;
106 return -EACCES;
107 }
108
109 dev->b1 = kmalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
110 if (!dev->b1) {
111 printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
112 iounmap(dev->sh_mem);
113 release_mem_region(dev->ph_mem, 4096);
114 kfree(dev);
115 return -ENOMEM;
116 }
117
118 dev->b2 = kmalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
119 if (!dev->b2) {
120 printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
121 kfree(dev->b1);
122 iounmap(dev->sh_mem);
123 release_mem_region(dev->ph_mem, 4096);
124 kfree(dev);
125 return -ENOMEM;
126 }
127
128 memset(dev->b1, 0, sizeof(struct pcbit_chan));
129 memset(dev->b2, 0, sizeof(struct pcbit_chan));
130 dev->b2->id = 1;
131
132 INIT_WORK(&dev->qdelivery, pcbit_deliver, dev);
133
134 /*
135 * interrupts
136 */
137
138 if (request_irq(irq, &pcbit_irq_handler, 0, pcbit_devname[board], dev) != 0)
139 {
140 kfree(dev->b1);
141 kfree(dev->b2);
142 iounmap(dev->sh_mem);
143 release_mem_region(dev->ph_mem, 4096);
144 kfree(dev);
145 dev_pcbit[board] = NULL;
146 return -EIO;
147 }
148
149 dev->irq = irq;
150
151 /* next frame to be received */
152 dev->rcv_seq = 0;
153 dev->send_seq = 0;
154 dev->unack_seq = 0;
155
156 dev->hl_hdrlen = 16;
157
158 dev_if = kmalloc(sizeof(isdn_if), GFP_KERNEL);
159
160 if (!dev_if) {
161 free_irq(irq, dev);
162 kfree(dev->b1);
163 kfree(dev->b2);
164 iounmap(dev->sh_mem);
165 release_mem_region(dev->ph_mem, 4096);
166 kfree(dev);
167 dev_pcbit[board] = NULL;
168 return -EIO;
169 }
170
171 dev->dev_if = dev_if;
172
173 dev_if->owner = THIS_MODULE;
174
175 dev_if->channels = 2;
176
177 dev_if->features = (ISDN_FEATURE_P_EURO | ISDN_FEATURE_L3_TRANS |
178 ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L2_TRANS );
179
180 dev_if->writebuf_skb = pcbit_xmit;
181 dev_if->hl_hdrlen = 16;
182
183 dev_if->maxbufsize = MAXBUFSIZE;
184 dev_if->command = pcbit_command;
185
186 dev_if->writecmd = pcbit_writecmd;
187 dev_if->readstat = pcbit_stat;
188
189
190 strcpy(dev_if->id, pcbit_devname[board]);
191
192 if (!register_isdn(dev_if)) {
193 free_irq(irq, dev);
194 kfree(dev->b1);
195 kfree(dev->b2);
196 iounmap(dev->sh_mem);
197 release_mem_region(dev->ph_mem, 4096);
198 kfree(dev);
199 dev_pcbit[board] = NULL;
200 return -EIO;
201 }
202
203 dev->id = dev_if->channels;
204
205
206 dev->l2_state = L2_DOWN;
207 dev->free = 511;
208
209 /*
210 * set_protocol_running(dev);
211 */
212
213 return 0;
214}
215
216#ifdef MODULE
217void pcbit_terminate(int board)
218{
219 struct pcbit_dev * dev;
220
221 dev = dev_pcbit[board];
222
223 if (dev) {
224 /* unregister_isdn(dev->dev_if); */
225 free_irq(dev->irq, dev);
226 pcbit_clear_msn(dev);
227 kfree(dev->dev_if);
228 if (dev->b1->fsm_timer.function)
229 del_timer(&dev->b1->fsm_timer);
230 if (dev->b2->fsm_timer.function)
231 del_timer(&dev->b2->fsm_timer);
232 kfree(dev->b1);
233 kfree(dev->b2);
234 iounmap(dev->sh_mem);
235 release_mem_region(dev->ph_mem, 4096);
236 kfree(dev);
237 }
238}
239#endif
240
241int pcbit_command(isdn_ctrl* ctl)
242{
243 struct pcbit_dev *dev;
244 struct pcbit_chan *chan;
245 struct callb_data info;
246
247 dev = finddev(ctl->driver);
248
249 if (!dev)
250 {
251 printk("pcbit_command: unknown device\n");
252 return -1;
253 }
254
255 chan = (ctl->arg & 0x0F) ? dev->b2 : dev->b1;
256
257
258 switch(ctl->command) {
259 case ISDN_CMD_IOCTL:
260 return pcbit_ioctl(ctl);
261 break;
262 case ISDN_CMD_DIAL:
263 info.type = EV_USR_SETUP_REQ;
264 info.data.setup.CalledPN = (char *) &ctl->parm.setup.phone;
265 pcbit_fsm_event(dev, chan, EV_USR_SETUP_REQ, &info);
266 break;
267 case ISDN_CMD_ACCEPTD:
268 pcbit_fsm_event(dev, chan, EV_USR_SETUP_RESP, NULL);
269 break;
270 case ISDN_CMD_ACCEPTB:
271 printk("ISDN_CMD_ACCEPTB - not really needed\n");
272 break;
273 case ISDN_CMD_HANGUP:
274 pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);
275 break;
276 case ISDN_CMD_SETL2:
277 chan->proto = (ctl->arg >> 8);
278 break;
279 case ISDN_CMD_CLREAZ:
280 pcbit_clear_msn(dev);
281 break;
282 case ISDN_CMD_SETEAZ:
283 pcbit_set_msn(dev, ctl->parm.num);
284 break;
285 case ISDN_CMD_SETL3:
286 if ((ctl->arg >> 8) != ISDN_PROTO_L3_TRANS)
287 printk(KERN_DEBUG "L3 protocol unknown\n");
288 break;
289 default:
290 printk(KERN_DEBUG "pcbit_command: unknown command\n");
291 break;
292 };
293
294 return 0;
295}
296
297/*
298 * Another Hack :-(
299 * on some conditions the board stops sending TDATA_CONFs
300 * let's see if we can turn around the problem
301 */
302
303#ifdef BLOCK_TIMER
304static void pcbit_block_timer(unsigned long data)
305{
306 struct pcbit_chan *chan;
307 struct pcbit_dev * dev;
308 isdn_ctrl ictl;
309
310 chan = (struct pcbit_chan *) data;
311
312 dev = chan2dev(chan);
313
314 if (dev == NULL) {
315 printk(KERN_DEBUG "pcbit: chan2dev failed\n");
316 return;
317 }
318
319 del_timer(&chan->block_timer);
320 chan->block_timer.function = NULL;
321
322#ifdef DEBUG
323 printk(KERN_DEBUG "pcbit_block_timer\n");
324#endif
325 chan->queued = 0;
326 ictl.driver = dev->id;
327 ictl.command = ISDN_STAT_BSENT;
328 ictl.arg = chan->id;
329 dev->dev_if->statcallb(&ictl);
330}
331#endif
332
333int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
334{
335 ushort hdrlen;
336 int refnum, len;
337 struct pcbit_chan * chan;
338 struct pcbit_dev *dev;
339
340 dev = finddev(driver);
341 if (dev == NULL)
342 {
343 printk("finddev returned NULL");
344 return -1;
345 }
346
347 chan = chnum ? dev->b2 : dev->b1;
348
349
350 if (chan->fsm_state != ST_ACTIVE)
351 return -1;
352
353 if (chan->queued >= MAX_QUEUED )
354 {
355#ifdef DEBUG_QUEUE
356 printk(KERN_DEBUG
357 "pcbit: %d packets already in queue - write fails\n",
358 chan->queued);
359#endif
360 /*
361 * packet stays on the head of the device queue
362 * since dev_start_xmit will fail
363 * see net/core/dev.c
364 */
365#ifdef BLOCK_TIMER
366 if (chan->block_timer.function == NULL) {
367 init_timer(&chan->block_timer);
368 chan->block_timer.function = &pcbit_block_timer;
369 chan->block_timer.data = (long) chan;
370 chan->block_timer.expires = jiffies + 1 * HZ;
371 add_timer(&chan->block_timer);
372 }
373#endif
374 return 0;
375 }
376
377
378 chan->queued++;
379
380 len = skb->len;
381
382 hdrlen = capi_tdata_req(chan, skb);
383
384 refnum = last_ref_num++ & 0x7fffU;
385 chan->s_refnum = refnum;
386
387 pcbit_l2_write(dev, MSG_TDATA_REQ, refnum, skb, hdrlen);
388
389 return len;
390}
391
392int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel)
393{
394 struct pcbit_dev * dev;
395 int i, j;
396 const u_char * loadbuf;
397 u_char * ptr = NULL;
398 u_char *cbuf;
399
400 int errstat;
401
402 dev = finddev(driver);
403
404 if (!dev)
405 {
406 printk("pcbit_writecmd: couldn't find device");
407 return -ENODEV;
408 }
409
410 switch(dev->l2_state) {
411 case L2_LWMODE:
412 /* check (size <= rdp_size); write buf into board */
413 if (len < 0 || len > BANK4 + 1 || len > 1024)
414 {
415 printk("pcbit_writecmd: invalid length %d\n", len);
416 return -EINVAL;
417 }
418
419 cbuf = kmalloc(len, GFP_KERNEL);
420 if (!cbuf)
421 return -ENOMEM;
422
423 if (copy_from_user(cbuf, buf, len)) {
424 kfree(cbuf);
425 return -EFAULT;
426 }
427 memcpy_toio(dev->sh_mem, cbuf, len);
428 kfree(cbuf);
429 return len;
430 case L2_FWMODE:
431 /* this is the hard part */
432 /* dumb board */
433 /* get it into kernel space */
434 if ((ptr = kmalloc(len, GFP_KERNEL))==NULL)
435 return -ENOMEM;
436 if (copy_from_user(ptr, buf, len)) {
437 kfree(ptr);
438 return -EFAULT;
439 }
440 loadbuf = ptr;
441
442 errstat = 0;
443
444 for (i=0; i < len; i++)
445 {
446 for(j=0; j < LOAD_RETRY; j++)
447 if (!(readb(dev->sh_mem + dev->loadptr)))
448 break;
449
450 if (j == LOAD_RETRY)
451 {
452 errstat = -ETIME;
453 printk("TIMEOUT i=%d\n", i);
454 break;
455 }
456 writeb(loadbuf[i], dev->sh_mem + dev->loadptr + 1);
457 writeb(0x01, dev->sh_mem + dev->loadptr);
458
459 dev->loadptr += 2;
460 if (dev->loadptr > LOAD_ZONE_END)
461 dev->loadptr = LOAD_ZONE_START;
462 }
463 kfree(ptr);
464
465 return errstat ? errstat : len;
466 default:
467 return -EBUSY;
468 }
469}
470
471/*
472 * demultiplexing of messages
473 *
474 */
475
476void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
477 struct sk_buff * skb,
478 ushort hdr_len, ushort refnum)
479{
480 struct pcbit_chan *chan;
481 struct sk_buff *skb2;
482 unsigned short len;
483 struct callb_data cbdata;
484 int complete, err;
485 isdn_ctrl ictl;
486
487 switch(msg) {
488
489 case MSG_TDATA_IND:
490 if (!(chan = capi_channel(dev, skb))) {
491 printk(KERN_WARNING
492 "CAPI header: unknown channel id\n");
493 break;
494 }
495 chan->r_refnum = skb->data[7];
496 skb_pull(skb, 8);
497
498 dev->dev_if->rcvcallb_skb(dev->id, chan->id, skb);
499
500 if (capi_tdata_resp(chan, &skb2) > 0)
501 pcbit_l2_write(dev, MSG_TDATA_RESP, refnum,
502 skb2, skb2->len);
503 return;
504 break;
505 case MSG_TDATA_CONF:
506 if (!(chan = capi_channel(dev, skb))) {
507 printk(KERN_WARNING
508 "CAPI header: unknown channel id\n");
509 break;
510 }
511
512#ifdef DEBUG
513 if ( (*((ushort *) (skb->data + 2) )) != 0) {
514 printk(KERN_DEBUG "TDATA_CONF error\n");
515 }
516#endif
517#ifdef BLOCK_TIMER
518 if (chan->queued == MAX_QUEUED) {
519 del_timer(&chan->block_timer);
520 chan->block_timer.function = NULL;
521 }
522
523#endif
524 chan->queued--;
525
526 ictl.driver = dev->id;
527 ictl.command = ISDN_STAT_BSENT;
528 ictl.arg = chan->id;
529 dev->dev_if->statcallb(&ictl);
530 break;
531
532 case MSG_CONN_IND:
533 /*
534 * channel: 1st not used will do
535 * if both are used we're in trouble
536 */
537
538 if (!dev->b1->fsm_state)
539 chan = dev->b1;
540 else if (!dev->b2->fsm_state)
541 chan = dev->b2;
542 else {
543 printk(KERN_INFO
544 "Incoming connection: no channels available");
545
546 if ((len = capi_disc_req(*(ushort*)(skb->data), &skb2, CAUSE_NOCHAN)) > 0)
547 pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb2, len);
548 break;
549 }
550
551 cbdata.data.setup.CalledPN = NULL;
552 cbdata.data.setup.CallingPN = NULL;
553
554 capi_decode_conn_ind(chan, skb, &cbdata);
555 cbdata.type = EV_NET_SETUP;
556
557 pcbit_fsm_event(dev, chan, EV_NET_SETUP, NULL);
558
559 if (pcbit_check_msn(dev, cbdata.data.setup.CallingPN))
560 pcbit_fsm_event(dev, chan, EV_USR_PROCED_REQ, &cbdata);
561 else
562 pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);
563
564 if (cbdata.data.setup.CalledPN)
565 kfree(cbdata.data.setup.CalledPN);
566 if (cbdata.data.setup.CallingPN)
567 kfree(cbdata.data.setup.CallingPN);
568 break;
569
570 case MSG_CONN_CONF:
571 /*
572 * We should be able to find the channel by the message
573 * reference number. The current version of the firmware
574 * doesn't sent the ref number correctly.
575 */
576#ifdef DEBUG
577 printk(KERN_DEBUG "refnum=%04x b1=%04x b2=%04x\n", refnum,
578 dev->b1->s_refnum,
579 dev->b2->s_refnum);
580#endif
581 /* We just try to find a channel in the right state */
582
583 if (dev->b1->fsm_state == ST_CALL_INIT)
584 chan = dev->b1;
585 else {
586 if (dev->b2->s_refnum == ST_CALL_INIT)
587 chan = dev->b2;
588 else {
589 chan = NULL;
590 printk(KERN_WARNING "Connection Confirm - no channel in Call Init state\n");
591 break;
592 }
593 }
594 if (capi_decode_conn_conf(chan, skb, &complete)) {
595 printk(KERN_DEBUG "conn_conf indicates error\n");
596 pcbit_fsm_event(dev, chan, EV_ERROR, NULL);
597 }
598 else
599 if (complete)
600 pcbit_fsm_event(dev, chan, EV_NET_CALL_PROC, NULL);
601 else
602 pcbit_fsm_event(dev, chan, EV_NET_SETUP_ACK, NULL);
603 break;
604 case MSG_CONN_ACTV_IND:
605
606 if (!(chan = capi_channel(dev, skb))) {
607 printk(KERN_WARNING
608 "CAPI header: unknown channel id\n");
609 break;
610 }
611
612 if (capi_decode_conn_actv_ind(chan, skb)) {
613 printk("error in capi_decode_conn_actv_ind\n");
614 /* pcbit_fsm_event(dev, chan, EV_ERROR, NULL); */
615 break;
616 }
617 chan->r_refnum = refnum;
618 pcbit_fsm_event(dev, chan, EV_NET_CONN, NULL);
619 break;
620 case MSG_CONN_ACTV_CONF:
621
622 if (!(chan = capi_channel(dev, skb))) {
623 printk(KERN_WARNING
624 "CAPI header: unknown channel id\n");
625 break;
626 }
627
628 if (capi_decode_conn_actv_conf(chan, skb) == 0)
629 pcbit_fsm_event(dev, chan, EV_NET_CONN_ACK, NULL);
630
631 else
632 printk(KERN_DEBUG "decode_conn_actv_conf failed\n");
633 break;
634
635 case MSG_SELP_CONF:
636
637 if (!(chan = capi_channel(dev, skb))) {
638 printk(KERN_WARNING
639 "CAPI header: unknown channel id\n");
640 break;
641 }
642
643 if (!(err = capi_decode_sel_proto_conf(chan, skb)))
644 pcbit_fsm_event(dev, chan, EV_NET_SELP_RESP, NULL);
645 else {
646 /* Error */
647 printk("error %d - capi_decode_sel_proto_conf\n", err);
648 }
649 break;
650 case MSG_ACT_TRANSP_CONF:
651 if (!(chan = capi_channel(dev, skb))) {
652 printk(KERN_WARNING
653 "CAPI header: unknown channel id\n");
654 break;
655 }
656
657 if (!capi_decode_actv_trans_conf(chan, skb))
658 pcbit_fsm_event(dev, chan, EV_NET_ACTV_RESP, NULL);
659 break;
660
661 case MSG_DISC_IND:
662
663 if (!(chan = capi_channel(dev, skb))) {
664 printk(KERN_WARNING
665 "CAPI header: unknown channel id\n");
666 break;
667 }
668
669 if (!capi_decode_disc_ind(chan, skb))
670 pcbit_fsm_event(dev, chan, EV_NET_DISC, NULL);
671 else
672 printk(KERN_WARNING "capi_decode_disc_ind - error\n");
673 break;
674 case MSG_DISC_CONF:
675 if (!(chan = capi_channel(dev, skb))) {
676 printk(KERN_WARNING
677 "CAPI header: unknown channel id\n");
678 break;
679 }
680
681 if (!capi_decode_disc_ind(chan, skb))
682 pcbit_fsm_event(dev, chan, EV_NET_RELEASE, NULL);
683 else
684 printk(KERN_WARNING "capi_decode_disc_conf - error\n");
685 break;
686 case MSG_INFO_IND:
687#ifdef DEBUG
688 printk(KERN_DEBUG "received Info Indication - discarded\n");
689#endif
690 break;
691#ifdef DEBUG
692 case MSG_DEBUG_188:
693 capi_decode_debug_188(skb->data, skb->len);
694 break;
695
696 default:
697 printk(KERN_DEBUG "pcbit_l3_receive: unknown message %08lx\n",
698 msg);
699 break;
700#endif
701 }
702
703 kfree_skb(skb);
704
705}
706
707/*
708 * Single statbuf
709 * should be a statbuf per device
710 */
711
712static char statbuf[STATBUF_LEN];
713static int stat_st = 0;
714static int stat_end = 0;
715
716int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
717{
718 int stat_count;
719 stat_count = stat_end - stat_st;
720
721 if (stat_count < 0)
722 stat_count = STATBUF_LEN - stat_st + stat_end;
723
724 /* FIXME: should we sleep and wait for more cookies ? */
725 if (len > stat_count)
726 len = stat_count;
727
728 if (stat_st < stat_end)
729 {
730 copy_to_user(buf, statbuf + stat_st, len);
731 stat_st += len;
732 }
733 else
734 {
735 if (len > STATBUF_LEN - stat_st)
736 {
737 copy_to_user(buf, statbuf + stat_st,
738 STATBUF_LEN - stat_st);
739 copy_to_user(buf, statbuf,
740 len - (STATBUF_LEN - stat_st));
741
742 stat_st = len - (STATBUF_LEN - stat_st);
743 }
744 else
745 {
746 copy_to_user(buf, statbuf + stat_st, len);
747
748 stat_st += len;
749
750 if (stat_st == STATBUF_LEN)
751 stat_st = 0;
752 }
753 }
754
755 if (stat_st == stat_end)
756 stat_st = stat_end = 0;
757
758 return len;
759}
760
761static void pcbit_logstat(struct pcbit_dev *dev, char *str)
762{
763 int i;
764 isdn_ctrl ictl;
765
766 for (i=stat_end; i<strlen(str); i++)
767 {
768 statbuf[i]=str[i];
769 stat_end = (stat_end + 1) % STATBUF_LEN;
770 if (stat_end == stat_st)
771 stat_st = (stat_st + 1) % STATBUF_LEN;
772 }
773
774 ictl.command=ISDN_STAT_STAVAIL;
775 ictl.driver=dev->id;
776 ictl.arg=strlen(str);
777 dev->dev_if->statcallb(&ictl);
778}
779
780extern char * isdn_state_table[];
781extern char * strisdnevent(unsigned short);
782
783
784void pcbit_state_change(struct pcbit_dev * dev, struct pcbit_chan * chan,
785 unsigned short i, unsigned short ev, unsigned short f)
786{
787 char buf[256];
788
789 sprintf(buf, "change on device: %d channel:%d\n%s -> %s -> %s\n",
790 dev->id, chan->id,
791 isdn_state_table[i], strisdnevent(ev), isdn_state_table[f]
792 );
793
794#ifdef DEBUG
795 printk("%s", buf);
796#endif
797
798 pcbit_logstat(dev, buf);
799}
800
801static void set_running_timeout(unsigned long ptr)
802{
803 struct pcbit_dev * dev;
804
805#ifdef DEBUG
806 printk(KERN_DEBUG "set_running_timeout\n");
807#endif
808 dev = (struct pcbit_dev *) ptr;
809
810 wake_up_interruptible(&dev->set_running_wq);
811}
812
813static int set_protocol_running(struct pcbit_dev * dev)
814{
815 isdn_ctrl ctl;
816
817 init_timer(&dev->set_running_timer);
818
819 dev->set_running_timer.function = &set_running_timeout;
820 dev->set_running_timer.data = (ulong) dev;
821 dev->set_running_timer.expires = jiffies + SET_RUN_TIMEOUT;
822
823 /* kick it */
824
825 dev->l2_state = L2_STARTING;
826
827 writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)),
828 dev->sh_mem + BANK4);
829
830 add_timer(&dev->set_running_timer);
831
832 interruptible_sleep_on(&dev->set_running_wq);
833
834 del_timer(&dev->set_running_timer);
835
836 if (dev->l2_state == L2_RUNNING)
837 {
838 printk(KERN_DEBUG "pcbit: running\n");
839
840 dev->unack_seq = dev->send_seq;
841
842 dev->writeptr = dev->sh_mem;
843 dev->readptr = dev->sh_mem + BANK2;
844
845 /* tell the good news to the upper layer */
846 ctl.driver = dev->id;
847 ctl.command = ISDN_STAT_RUN;
848
849 dev->dev_if->statcallb(&ctl);
850 }
851 else
852 {
853 printk(KERN_DEBUG "pcbit: initialization failed\n");
854 printk(KERN_DEBUG "pcbit: firmware not loaded\n");
855
856 dev->l2_state = L2_DOWN;
857
858#ifdef DEBUG
859 printk(KERN_DEBUG "Bank3 = %02x\n",
860 readb(dev->sh_mem + BANK3));
861#endif
862 writeb(0x40, dev->sh_mem + BANK4);
863
864 /* warn the upper layer */
865 ctl.driver = dev->id;
866 ctl.command = ISDN_STAT_STOP;
867
868 dev->dev_if->statcallb(&ctl);
869
870 return -EL2HLT; /* Level 2 halted */
871 }
872
873 return 0;
874}
875
876static int pcbit_ioctl(isdn_ctrl* ctl)
877{
878 struct pcbit_dev * dev;
879 struct pcbit_ioctl *cmd;
880
881 dev = finddev(ctl->driver);
882
883 if (!dev)
884 {
885 printk(KERN_DEBUG "pcbit_ioctl: unknown device\n");
886 return -ENODEV;
887 }
888
889 cmd = (struct pcbit_ioctl *) ctl->parm.num;
890
891 switch(ctl->arg) {
892 case PCBIT_IOCTL_GETSTAT:
893 cmd->info.l2_status = dev->l2_state;
894 break;
895
896 case PCBIT_IOCTL_STRLOAD:
897 if (dev->l2_state == L2_RUNNING)
898 return -EBUSY;
899
900 dev->unack_seq = dev->send_seq = dev->rcv_seq = 0;
901
902 dev->writeptr = dev->sh_mem;
903 dev->readptr = dev->sh_mem + BANK2;
904
905 dev->l2_state = L2_LOADING;
906 break;
907
908 case PCBIT_IOCTL_LWMODE:
909 if (dev->l2_state != L2_LOADING)
910 return -EINVAL;
911
912 dev->l2_state = L2_LWMODE;
913 break;
914
915 case PCBIT_IOCTL_FWMODE:
916 if (dev->l2_state == L2_RUNNING)
917 return -EBUSY;
918 dev->loadptr = LOAD_ZONE_START;
919 dev->l2_state = L2_FWMODE;
920
921 break;
922 case PCBIT_IOCTL_ENDLOAD:
923 if (dev->l2_state == L2_RUNNING)
924 return -EBUSY;
925 dev->l2_state = L2_DOWN;
926 break;
927
928 case PCBIT_IOCTL_SETBYTE:
929 if (dev->l2_state == L2_RUNNING)
930 return -EBUSY;
931
932 /* check addr */
933 if (cmd->info.rdp_byte.addr > BANK4)
934 return -EFAULT;
935
936 writeb(cmd->info.rdp_byte.value, dev->sh_mem + cmd->info.rdp_byte.addr);
937 break;
938 case PCBIT_IOCTL_GETBYTE:
939 if (dev->l2_state == L2_RUNNING)
940 return -EBUSY;
941
942 /* check addr */
943
944 if (cmd->info.rdp_byte.addr > BANK4)
945 {
946 printk("getbyte: invalid addr %04x\n", cmd->info.rdp_byte.addr);
947 return -EFAULT;
948 }
949
950 cmd->info.rdp_byte.value = readb(dev->sh_mem + cmd->info.rdp_byte.addr);
951 break;
952 case PCBIT_IOCTL_RUNNING:
953 if (dev->l2_state == L2_RUNNING)
954 return -EBUSY;
955 return set_protocol_running(dev);
956 break;
957 case PCBIT_IOCTL_WATCH188:
958 if (dev->l2_state != L2_LOADING)
959 return -EINVAL;
960 pcbit_l2_write(dev, MSG_WATCH188, 0x0001, NULL, 0);
961 break;
962 case PCBIT_IOCTL_PING188:
963 if (dev->l2_state != L2_LOADING)
964 return -EINVAL;
965 pcbit_l2_write(dev, MSG_PING188_REQ, 0x0001, NULL, 0);
966 break;
967 case PCBIT_IOCTL_APION:
968 if (dev->l2_state != L2_LOADING)
969 return -EINVAL;
970 pcbit_l2_write(dev, MSG_API_ON, 0x0001, NULL, 0);
971 break;
972 case PCBIT_IOCTL_STOP:
973 dev->l2_state = L2_DOWN;
974 writeb(0x40, dev->sh_mem + BANK4);
975 dev->rcv_seq = 0;
976 dev->send_seq = 0;
977 dev->unack_seq = 0;
978 break;
979 default:
980 printk("error: unknown ioctl\n");
981 break;
982 };
983 return 0;
984}
985
986/*
987 * MSN list handling
988 *
989 * if null reject all calls
990 * if first entry has null MSN accept all calls
991 */
992
993static void pcbit_clear_msn(struct pcbit_dev *dev)
994{
995 struct msn_entry *ptr, *back;
996
997 for (ptr=dev->msn_list; ptr; )
998 {
999 back = ptr->next;
1000 kfree(ptr);
1001 ptr = back;
1002 }
1003
1004 dev->msn_list = NULL;
1005}
1006
1007static void pcbit_set_msn(struct pcbit_dev *dev, char *list)
1008{
1009 struct msn_entry *ptr;
1010 struct msn_entry *back = NULL;
1011 char *cp, *sp;
1012 int len;
1013
1014 if (strlen(list) == 0) {
1015 ptr = kmalloc(sizeof(struct msn_entry), GFP_ATOMIC);
1016 if (!ptr) {
1017 printk(KERN_WARNING "kmalloc failed\n");
1018 return;
1019 }
1020
1021 ptr->msn = NULL;
1022
1023 ptr->next = dev->msn_list;
1024 dev->msn_list = ptr;
1025
1026 return;
1027 }
1028
1029 if (dev->msn_list)
1030 for (back=dev->msn_list; back->next; back=back->next);
1031
1032 sp = list;
1033
1034 do {
1035 cp=strchr(sp, ',');
1036 if (cp)
1037 len = cp - sp;
1038 else
1039 len = strlen(sp);
1040
1041 ptr = kmalloc(sizeof(struct msn_entry), GFP_ATOMIC);
1042
1043 if (!ptr) {
1044 printk(KERN_WARNING "kmalloc failed\n");
1045 return;
1046 }
1047 ptr->next = NULL;
1048
1049 ptr->msn = kmalloc(len, GFP_ATOMIC);
1050 if (!ptr->msn) {
1051 printk(KERN_WARNING "kmalloc failed\n");
1052 kfree(ptr);
1053 return;
1054 }
1055
1056 memcpy(ptr->msn, sp, len - 1);
1057 ptr->msn[len] = 0;
1058
1059#ifdef DEBUG
1060 printk(KERN_DEBUG "msn: %s\n", ptr->msn);
1061#endif
1062 if (dev->msn_list == NULL)
1063 dev->msn_list = ptr;
1064 else
1065 back->next = ptr;
1066 back = ptr;
1067 sp += len;
1068 } while(cp);
1069}
1070
1071/*
1072 * check if we do signal or reject an incoming call
1073 */
1074static int pcbit_check_msn(struct pcbit_dev *dev, char *msn)
1075{
1076 struct msn_entry *ptr;
1077
1078 for (ptr=dev->msn_list; ptr; ptr=ptr->next) {
1079
1080 if (ptr->msn == NULL)
1081 return 1;
1082
1083 if (strcmp(ptr->msn, msn) == 0)
1084 return 1;
1085 }
1086
1087 return 0;
1088}
diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c
new file mode 100644
index 000000000000..93ca7de5670b
--- /dev/null
+++ b/drivers/isdn/pcbit/edss1.c
@@ -0,0 +1,325 @@
1/*
2 * DSS.1 Finite State Machine
3 * base: ITU-T Rec Q.931
4 *
5 * Copyright (C) 1996 Universidade de Lisboa
6 *
7 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
8 *
9 * This software may be used and distributed according to the terms of
10 * the GNU General Public License, incorporated herein by reference.
11 */
12
13/*
14 * TODO: complete the FSM
15 * move state/event descriptions to a user space logger
16 */
17
18#include <linux/sched.h>
19#include <linux/string.h>
20#include <linux/kernel.h>
21
22#include <linux/types.h>
23#include <linux/slab.h>
24#include <linux/mm.h>
25#include <linux/skbuff.h>
26
27#include <linux/timer.h>
28#include <asm/io.h>
29
30#include <linux/isdnif.h>
31
32#include "pcbit.h"
33#include "edss1.h"
34#include "layer2.h"
35#include "callbacks.h"
36
37
38extern void pcbit_state_change(struct pcbit_dev *, struct pcbit_chan *,
39 unsigned short i, unsigned short ev,
40 unsigned short f);
41
42extern struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS];
43
44char * isdn_state_table[] = {
45 "Closed",
46 "Call initiated",
47 "Overlap sending",
48 "Outgoing call proceeding",
49 "NOT DEFINED",
50 "Call delivered",
51 "Call present",
52 "Call received",
53 "Connect request",
54 "Incoming call proceeding",
55 "Active",
56 "Disconnect request",
57 "Disconnect indication",
58 "NOT DEFINED",
59 "NOT DEFINED",
60 "Suspend request",
61 "NOT DEFINED",
62 "Resume request",
63 "NOT DEFINED",
64 "Release Request",
65 "NOT DEFINED",
66 "NOT DEFINED",
67 "NOT DEFINED",
68 "NOT DEFINED",
69 "NOT DEFINED",
70 "Overlap receiving",
71 "Select protocol on B-Channel",
72 "Activate B-channel protocol"
73};
74
75#ifdef DEBUG_ERRS
76static
77struct CauseValue {
78 byte nr;
79 char *descr;
80} cvlist[]={
81 {0x01,"Unallocated (unassigned) number"},
82 {0x02,"No route to specified transit network"},
83 {0x03,"No route to destination"},
84 {0x04,"Send special information tone"},
85 {0x05,"Misdialled trunk prefix"},
86 {0x06,"Channel unacceptable"},
87 {0x07,"Channel awarded and being delivered in an established channel"},
88 {0x08,"Preemption"},
89 {0x09,"Preemption - circuit reserved for reuse"},
90 {0x10,"Normal call clearing"},
91 {0x11,"User busy"},
92 {0x12,"No user responding"},
93 {0x13,"No answer from user (user alerted)"},
94 {0x14,"Subscriber absent"},
95 {0x15,"Call rejected"},
96 {0x16,"Number changed"},
97 {0x1a,"non-selected user clearing"},
98 {0x1b,"Destination out of order"},
99 {0x1c,"Invalid number format (address incomplete)"},
100 {0x1d,"Facility rejected"},
101 {0x1e,"Response to Status enquiry"},
102 {0x1f,"Normal, unspecified"},
103 {0x22,"No circuit/channel available"},
104 {0x26,"Network out of order"},
105 {0x27,"Permanent frame mode connection out-of-service"},
106 {0x28,"Permanent frame mode connection operational"},
107 {0x29,"Temporary failure"},
108 {0x2a,"Switching equipment congestion"},
109 {0x2b,"Access information discarded"},
110 {0x2c,"Requested circuit/channel not available"},
111 {0x2e,"Precedence call blocked"},
112 {0x2f,"Resource unavailable, unspecified"},
113 {0x31,"Quality of service unavailable"},
114 {0x32,"Requested facility not subscribed"},
115 {0x35,"Outgoing calls barred within CUG"},
116 {0x37,"Incoming calls barred within CUG"},
117 {0x39,"Bearer capability not authorized"},
118 {0x3a,"Bearer capability not presently available"},
119 {0x3e,"Inconsistency in designated outgoing access information and subscriber class"},
120 {0x3f,"Service or option not available, unspecified"},
121 {0x41,"Bearer capability not implemented"},
122 {0x42,"Channel type not implemented"},
123 {0x43,"Requested facility not implemented"},
124 {0x44,"Only restricted digital information bearer capability is available"},
125 {0x4f,"Service or option not implemented"},
126 {0x51,"Invalid call reference value"},
127 {0x52,"Identified channel does not exist"},
128 {0x53,"A suspended call exists, but this call identity does not"},
129 {0x54,"Call identity in use"},
130 {0x55,"No call suspended"},
131 {0x56,"Call having the requested call identity has been cleared"},
132 {0x57,"User not member of CUG"},
133 {0x58,"Incompatible destination"},
134 {0x5a,"Non-existent CUG"},
135 {0x5b,"Invalid transit network selection"},
136 {0x5f,"Invalid message, unspecified"},
137 {0x60,"Mandatory information element is missing"},
138 {0x61,"Message type non-existent or not implemented"},
139 {0x62,"Message not compatible with call state or message type non-existent or not implemented"},
140 {0x63,"Information element/parameter non-existent or not implemented"},
141 {0x64,"Invalid information element contents"},
142 {0x65,"Message not compatible with call state"},
143 {0x66,"Recovery on timer expiry"},
144 {0x67,"Parameter non-existent or not implemented - passed on"},
145 {0x6e,"Message with unrecognized parameter discarded"},
146 {0x6f,"Protocol error, unspecified"},
147 {0x7f,"Interworking, unspecified"}
148};
149
150#endif
151
152static struct isdn_event_desc {
153 unsigned short ev;
154 char * desc;
155} isdn_event_table [] = {
156 {EV_USR_SETUP_REQ, "CC->L3: Setup Request"},
157 {EV_USR_SETUP_RESP, "CC->L3: Setup Response"},
158 {EV_USR_PROCED_REQ, "CC->L3: Proceeding Request"},
159 {EV_USR_RELEASE_REQ, "CC->L3: Release Request"},
160
161 {EV_NET_SETUP, "NET->TE: setup "},
162 {EV_NET_CALL_PROC, "NET->TE: call proceeding"},
163 {EV_NET_SETUP_ACK, "NET->TE: setup acknowledge (more info needed)"},
164 {EV_NET_CONN, "NET->TE: connect"},
165 {EV_NET_CONN_ACK, "NET->TE: connect acknowledge"},
166 {EV_NET_DISC, "NET->TE: disconnect indication"},
167 {EV_NET_RELEASE, "NET->TE: release"},
168 {EV_NET_RELEASE_COMP, "NET->TE: release complete"},
169 {EV_NET_SELP_RESP, "Board: Select B-channel protocol ack"},
170 {EV_NET_ACTV_RESP, "Board: Activate B-channel protocol ack"},
171 {EV_TIMER, "Timeout"},
172 {0, "NULL"}
173};
174
175char * strisdnevent(ushort ev)
176{
177 struct isdn_event_desc * entry;
178
179 for (entry = isdn_event_table; entry->ev; entry++)
180 if (entry->ev == ev)
181 break;
182
183 return entry->desc;
184}
185
186/*
187 * Euro ISDN finite state machine
188 */
189
190static struct fsm_timer_entry fsm_timers[] = {
191 {ST_CALL_PROC, 10},
192 {ST_DISC_REQ, 2},
193 {ST_ACTIVE_SELP, 5},
194 {ST_ACTIVE_ACTV, 5},
195 {ST_INCM_PROC, 10},
196 {ST_CONN_REQ, 2},
197 {0xff, 0}
198};
199
200static struct fsm_entry fsm_table[] = {
201/* Connect Phase */
202 /* Outgoing */
203 {ST_NULL, ST_CALL_INIT, EV_USR_SETUP_REQ, cb_out_1},
204
205 {ST_CALL_INIT, ST_OVER_SEND, EV_NET_SETUP_ACK, cb_notdone},
206 {ST_CALL_INIT, ST_CALL_PROC, EV_NET_CALL_PROC, NULL},
207 {ST_CALL_INIT, ST_NULL, EV_NET_DISC, cb_out_2},
208
209 {ST_CALL_PROC, ST_ACTIVE_SELP, EV_NET_CONN, cb_out_2},
210 {ST_CALL_PROC, ST_NULL, EV_NET_DISC, cb_disc_1},
211 {ST_CALL_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
212
213 /* Incoming */
214 {ST_NULL, ST_CALL_PRES, EV_NET_SETUP, NULL},
215
216 {ST_CALL_PRES, ST_INCM_PROC, EV_USR_PROCED_REQ, cb_in_1},
217 {ST_CALL_PRES, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
218
219 {ST_INCM_PROC, ST_CONN_REQ, EV_USR_SETUP_RESP, cb_in_2},
220 {ST_INCM_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
221
222 {ST_CONN_REQ, ST_ACTIVE_SELP, EV_NET_CONN_ACK, cb_in_3},
223
224 /* Active */
225 {ST_ACTIVE, ST_NULL, EV_NET_DISC, cb_disc_1},
226 {ST_ACTIVE, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
227 {ST_ACTIVE, ST_NULL, EV_NET_RELEASE, cb_disc_3},
228
229 /* Disconnect */
230
231 {ST_DISC_REQ, ST_NULL, EV_NET_DISC, cb_disc_1},
232 {ST_DISC_REQ, ST_NULL, EV_NET_RELEASE, cb_disc_3},
233
234 /* protocol selection */
235 {ST_ACTIVE_SELP, ST_ACTIVE_ACTV, EV_NET_SELP_RESP, cb_selp_1},
236 {ST_ACTIVE_SELP, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
237
238 {ST_ACTIVE_ACTV, ST_ACTIVE, EV_NET_ACTV_RESP, cb_open},
239 {ST_ACTIVE_ACTV, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
240
241 /* Timers */
242 {ST_CALL_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2},
243 {ST_DISC_REQ, ST_NULL, EV_TIMER, cb_disc_3},
244 {ST_ACTIVE_SELP, ST_DISC_REQ, EV_TIMER, cb_disc_2},
245 {ST_ACTIVE_ACTV, ST_DISC_REQ, EV_TIMER, cb_disc_2},
246 {ST_INCM_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2},
247 {ST_CONN_REQ, ST_CONN_REQ, EV_TIMER, cb_in_2},
248
249 {0xff, 0, 0, NULL}
250};
251
252
253static void pcbit_fsm_timer(unsigned long data)
254{
255 struct pcbit_dev *dev;
256 struct pcbit_chan *chan;
257
258 chan = (struct pcbit_chan *) data;
259
260 del_timer(&chan->fsm_timer);
261 chan->fsm_timer.function = NULL;
262
263 dev = chan2dev(chan);
264
265 if (dev == NULL) {
266 printk(KERN_WARNING "pcbit: timer for unknown device\n");
267 return;
268 }
269
270 pcbit_fsm_event(dev, chan, EV_TIMER, NULL);
271}
272
273
274void pcbit_fsm_event(struct pcbit_dev *dev, struct pcbit_chan *chan,
275 unsigned short event, struct callb_data *data)
276{
277 struct fsm_entry * action;
278 struct fsm_timer_entry *tentry;
279 unsigned long flags;
280
281 spin_lock_irqsave(&dev->lock, flags);
282
283 for (action = fsm_table; action->init != 0xff; action++)
284 if (action->init == chan->fsm_state && action->event == event)
285 break;
286
287 if (action->init == 0xff) {
288
289 spin_unlock_irqrestore(&dev->lock, flags);
290 printk(KERN_DEBUG "fsm error: event %x on state %x\n",
291 event, chan->fsm_state);
292 return;
293 }
294
295 if (chan->fsm_timer.function) {
296 del_timer(&chan->fsm_timer);
297 chan->fsm_timer.function = NULL;
298 }
299
300 chan->fsm_state = action->final;
301
302 pcbit_state_change(dev, chan, action->init, event, action->final);
303
304 for (tentry = fsm_timers; tentry->init != 0xff; tentry++)
305 if (tentry->init == chan->fsm_state)
306 break;
307
308 if (tentry->init != 0xff) {
309 init_timer(&chan->fsm_timer);
310 chan->fsm_timer.function = &pcbit_fsm_timer;
311 chan->fsm_timer.data = (ulong) chan;
312 chan->fsm_timer.expires = jiffies + tentry->timeout * HZ;
313 add_timer(&chan->fsm_timer);
314 }
315
316 spin_unlock_irqrestore(&dev->lock, flags);
317
318 if (action->callb)
319 action->callb(dev, chan, data);
320
321}
322
323
324
325
diff --git a/drivers/isdn/pcbit/edss1.h b/drivers/isdn/pcbit/edss1.h
new file mode 100644
index 000000000000..6bb587005b86
--- /dev/null
+++ b/drivers/isdn/pcbit/edss1.h
@@ -0,0 +1,99 @@
1/*
2 * DSS.1 module definitions
3 *
4 * Copyright (C) 1996 Universidade de Lisboa
5 *
6 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
7 *
8 * This software may be used and distributed according to the terms of
9 * the GNU General Public License, incorporated herein by reference.
10 */
11
12#ifndef EDSS1_H
13#define EDSS1_H
14
15/* ISDN states */
16
17#define ST_NULL 0
18#define ST_CALL_INIT 1 /* Call initiated */
19#define ST_OVER_SEND 2 /* Overlap sending - Requests More Info 4 call */
20#define ST_CALL_PROC 3 /* Call Proceeding */
21#define ST_CALL_DELV 4
22#define ST_CALL_PRES 6 /* Call Present - Received CONN.IND */
23#define ST_CALL_RECV 7 /* Alerting sent */
24#define ST_CONN_REQ 8 /* Answered - waiting 4 CONN.CONF */
25#define ST_INCM_PROC 9
26#define ST_ACTIVE 10
27#define ST_DISC_REQ 11
28#define ST_DISC_IND 12
29#define ST_SUSP_REQ 15
30#define ST_RESM_REQ 17
31#define ST_RELS_REQ 19
32#define ST_OVER_RECV 25
33
34#define ST_ACTIVE_SELP 26 /* Select protocol on B-Channel */
35#define ST_ACTIVE_ACTV 27 /* Activate B-channel protocol */
36
37#define MAX_STATE ST_ACTIVE_ACTV
38
39#define EV_NULL 0
40#define EV_USR_SETUP_REQ 1
41#define EV_USR_SETUP_RESP 2
42#define EV_USR_PROCED_REQ 3
43#define EV_USR_RELEASE_REQ 4
44#define EV_USR_REJECT_REQ 4
45
46#define EV_NET_SETUP 16
47#define EV_NET_CALL_PROC 17
48#define EV_NET_SETUP_ACK 18
49#define EV_NET_CONN 19
50#define EV_NET_CONN_ACK 20
51
52#define EV_NET_SELP_RESP 21
53#define EV_NET_ACTV_RESP 22
54
55#define EV_NET_DISC 23
56#define EV_NET_RELEASE 24
57#define EV_NET_RELEASE_COMP 25
58
59#define EV_TIMER 26
60#define EV_ERROR 32
61
62/*
63 * Cause values
64 * only the ones we use
65 */
66
67#define CAUSE_NORMAL 0x10U
68#define CAUSE_NOCHAN 0x22U
69
70struct callb_data {
71 unsigned short type;
72 union {
73 struct ConnInfo {
74 char *CalledPN;
75 char *CallingPN;
76 } setup;
77 unsigned short cause;
78 } data;
79};
80
81struct fsm_entry {
82 unsigned short init;
83 unsigned short final;
84 unsigned short event;
85 void (*callb)(struct pcbit_dev *, struct pcbit_chan *, struct callb_data*);
86};
87
88struct fsm_timer_entry {
89 unsigned short init;
90 unsigned long timeout; /* in seconds */
91};
92
93
94extern void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *,
95 unsigned short event, struct callb_data *);
96#endif
97
98
99
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c
new file mode 100644
index 000000000000..ba766930f088
--- /dev/null
+++ b/drivers/isdn/pcbit/layer2.c
@@ -0,0 +1,732 @@
1/*
2 * PCBIT-D low-layer interface
3 *
4 * Copyright (C) 1996 Universidade de Lisboa
5 *
6 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
7 *
8 * This software may be used and distributed according to the terms of
9 * the GNU General Public License, incorporated herein by reference.
10 */
11
12/*
13 * 19991203 - Fernando Carvalho - takion@superbofh.org
14 * Hacked to compile with egcs and run with current version of isdn modules
15*/
16
17/*
18 * Based on documentation provided by Inesc:
19 * - "Interface com bus do PC para o PCBIT e PCBIT-D", Inesc, Jan 93
20 */
21
22/*
23 * TODO: better handling of errors
24 * re-write/remove debug printks
25 */
26
27#include <linux/sched.h>
28#include <linux/string.h>
29#include <linux/kernel.h>
30#include <linux/types.h>
31#include <linux/slab.h>
32#include <linux/interrupt.h>
33#include <linux/workqueue.h>
34#include <linux/mm.h>
35#include <linux/skbuff.h>
36
37#include <linux/isdnif.h>
38
39#include <asm/system.h>
40#include <asm/io.h>
41
42
43#include "pcbit.h"
44#include "layer2.h"
45#include "edss1.h"
46
47#undef DEBUG_FRAG
48
49
50
51/*
52 * task queue struct
53 */
54
55
56
57/*
58 * Layer 3 packet demultiplexer
59 * drv.c
60 */
61
62extern void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg,
63 struct sk_buff *skb,
64 ushort hdr_len, ushort refnum);
65
66/*
67 * Prototypes
68 */
69
70void pcbit_deliver(void *data);
71static void pcbit_transmit(struct pcbit_dev *dev);
72
73static void pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack);
74
75static void pcbit_l2_error(struct pcbit_dev *dev);
76static void pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info);
77static void pcbit_l2_err_recover(unsigned long data);
78
79static void pcbit_firmware_bug(struct pcbit_dev *dev);
80
81static __inline__ void
82pcbit_sched_delivery(struct pcbit_dev *dev)
83{
84 schedule_work(&dev->qdelivery);
85}
86
87
88/*
89 * Called from layer3
90 */
91
92int
93pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum,
94 struct sk_buff *skb, unsigned short hdr_len)
95{
96 struct frame_buf *frame,
97 *ptr;
98 unsigned long flags;
99
100 if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) {
101 dev_kfree_skb(skb);
102 return -1;
103 }
104 if ((frame = (struct frame_buf *) kmalloc(sizeof(struct frame_buf),
105 GFP_ATOMIC)) == NULL) {
106 printk(KERN_WARNING "pcbit_2_write: kmalloc failed\n");
107 dev_kfree_skb(skb);
108 return -1;
109 }
110 frame->msg = msg;
111 frame->refnum = refnum;
112 frame->copied = 0;
113 frame->hdr_len = hdr_len;
114
115 if (skb)
116 frame->dt_len = skb->len - hdr_len;
117 else
118 frame->dt_len = 0;
119
120 frame->skb = skb;
121
122 frame->next = NULL;
123
124 spin_lock_irqsave(&dev->lock, flags);
125
126 if (dev->write_queue == NULL) {
127 dev->write_queue = frame;
128 spin_unlock_irqrestore(&dev->lock, flags);
129 pcbit_transmit(dev);
130 } else {
131 for (ptr = dev->write_queue; ptr->next; ptr = ptr->next);
132 ptr->next = frame;
133
134 spin_unlock_irqrestore(&dev->lock, flags);
135 }
136 return 0;
137}
138
139static __inline__ void
140pcbit_tx_update(struct pcbit_dev *dev, ushort len)
141{
142 u_char info;
143
144 dev->send_seq = (dev->send_seq + 1) % 8;
145
146 dev->fsize[dev->send_seq] = len;
147 info = 0;
148 info |= dev->rcv_seq << 3;
149 info |= dev->send_seq;
150
151 writeb(info, dev->sh_mem + BANK4);
152
153}
154
155/*
156 * called by interrupt service routine or by write_2
157 */
158
159static void
160pcbit_transmit(struct pcbit_dev *dev)
161{
162 struct frame_buf *frame = NULL;
163 unsigned char unacked;
164 int flen; /* fragment frame length including all headers */
165 int free;
166 int count,
167 cp_len;
168 unsigned long flags;
169 unsigned short tt;
170
171 if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING)
172 return;
173
174 unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07;
175
176 spin_lock_irqsave(&dev->lock, flags);
177
178 if (dev->free > 16 && dev->write_queue && unacked < 7) {
179
180 if (!dev->w_busy)
181 dev->w_busy = 1;
182 else {
183 spin_unlock_irqrestore(&dev->lock, flags);
184 return;
185 }
186
187
188 frame = dev->write_queue;
189 free = dev->free;
190
191 spin_unlock_irqrestore(&dev->lock, flags);
192
193 if (frame->copied == 0) {
194
195 /* Type 0 frame */
196
197 ulong msg;
198
199 if (frame->skb)
200 flen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
201 else
202 flen = FRAME_HDR_LEN + PREHDR_LEN;
203
204 if (flen > free)
205 flen = free;
206
207 msg = frame->msg;
208
209 /*
210 * Board level 2 header
211 */
212
213 pcbit_writew(dev, flen - FRAME_HDR_LEN);
214
215 pcbit_writeb(dev, GET_MSG_CPU(msg));
216
217 pcbit_writeb(dev, GET_MSG_PROC(msg));
218
219 /* TH */
220 pcbit_writew(dev, frame->hdr_len + PREHDR_LEN);
221
222 /* TD */
223 pcbit_writew(dev, frame->dt_len);
224
225
226 /*
227 * Board level 3 fixed-header
228 */
229
230 /* LEN = TH */
231 pcbit_writew(dev, frame->hdr_len + PREHDR_LEN);
232
233 /* XX */
234 pcbit_writew(dev, 0);
235
236 /* C + S */
237 pcbit_writeb(dev, GET_MSG_CMD(msg));
238 pcbit_writeb(dev, GET_MSG_SCMD(msg));
239
240 /* NUM */
241 pcbit_writew(dev, frame->refnum);
242
243 count = FRAME_HDR_LEN + PREHDR_LEN;
244 } else {
245 /* Type 1 frame */
246
247 flen = 2 + (frame->skb->len - frame->copied);
248
249 if (flen > free)
250 flen = free;
251
252 /* TT */
253 tt = ((ushort) (flen - 2)) | 0x8000U; /* Type 1 */
254 pcbit_writew(dev, tt);
255
256 count = 2;
257 }
258
259 if (frame->skb) {
260 cp_len = frame->skb->len - frame->copied;
261 if (cp_len > flen - count)
262 cp_len = flen - count;
263
264 memcpy_topcbit(dev, frame->skb->data + frame->copied,
265 cp_len);
266 frame->copied += cp_len;
267 }
268 /* bookkeeping */
269 dev->free -= flen;
270 pcbit_tx_update(dev, flen);
271
272 spin_lock_irqsave(&dev->lock, flags);
273
274 if (frame->skb == NULL || frame->copied == frame->skb->len) {
275
276 dev->write_queue = frame->next;
277
278 if (frame->skb != NULL) {
279 /* free frame */
280 dev_kfree_skb(frame->skb);
281 }
282 kfree(frame);
283 }
284 dev->w_busy = 0;
285 spin_unlock_irqrestore(&dev->lock, flags);
286 } else {
287 spin_unlock_irqrestore(&dev->lock, flags);
288#ifdef DEBUG
289 printk(KERN_DEBUG "unacked %d free %d write_queue %s\n",
290 unacked, dev->free, dev->write_queue ? "not empty" :
291 "empty");
292#endif
293 }
294}
295
296
297/*
298 * deliver a queued frame to the upper layer
299 */
300
301void
302pcbit_deliver(void *data)
303{
304 struct frame_buf *frame;
305 unsigned long flags, msg;
306 struct pcbit_dev *dev = (struct pcbit_dev *) data;
307
308 spin_lock_irqsave(&dev->lock, flags);
309
310 while ((frame = dev->read_queue)) {
311 dev->read_queue = frame->next;
312 spin_unlock_irqrestore(&dev->lock, flags);
313
314 SET_MSG_CPU(msg, 0);
315 SET_MSG_PROC(msg, 0);
316 SET_MSG_CMD(msg, frame->skb->data[2]);
317 SET_MSG_SCMD(msg, frame->skb->data[3]);
318
319 frame->refnum = *((ushort *) frame->skb->data + 4);
320 frame->msg = *((ulong *) & msg);
321
322 skb_pull(frame->skb, 6);
323
324 pcbit_l3_receive(dev, frame->msg, frame->skb, frame->hdr_len,
325 frame->refnum);
326
327 kfree(frame);
328
329 spin_lock_irqsave(&dev->lock, flags);
330 }
331
332 spin_unlock_irqrestore(&dev->lock, flags);
333}
334
335/*
336 * Reads BANK 2 & Reassembles
337 */
338
339static void
340pcbit_receive(struct pcbit_dev *dev)
341{
342 unsigned short tt;
343 u_char cpu,
344 proc;
345 struct frame_buf *frame = NULL;
346 unsigned long flags;
347 u_char type1;
348
349 if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING)
350 return;
351
352 tt = pcbit_readw(dev);
353
354 if ((tt & 0x7fffU) > 511) {
355 printk(KERN_INFO "pcbit: invalid frame length -> TT=%04x\n",
356 tt);
357 pcbit_l2_error(dev);
358 return;
359 }
360 if (!(tt & 0x8000U)) { /* Type 0 */
361 type1 = 0;
362
363 if (dev->read_frame) {
364 printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
365 /* discard previous queued frame */
366 if (dev->read_frame->skb)
367 kfree_skb(dev->read_frame->skb);
368 kfree(dev->read_frame);
369 dev->read_frame = NULL;
370 }
371 frame = kmalloc(sizeof(struct frame_buf), GFP_ATOMIC);
372
373 if (frame == NULL) {
374 printk(KERN_WARNING "kmalloc failed\n");
375 return;
376 }
377 memset(frame, 0, sizeof(struct frame_buf));
378
379 cpu = pcbit_readb(dev);
380 proc = pcbit_readb(dev);
381
382
383 if (cpu != 0x06 && cpu != 0x02) {
384 printk(KERN_DEBUG "pcbit: invalid cpu value\n");
385 kfree(frame);
386 pcbit_l2_error(dev);
387 return;
388 }
389 /*
390 * we discard cpu & proc on receiving
391 * but we read it to update the pointer
392 */
393
394 frame->hdr_len = pcbit_readw(dev);
395 frame->dt_len = pcbit_readw(dev);
396
397 /*
398 * 0 sized packet
399 * I don't know if they are an error or not...
400 * But they are very frequent
401 * Not documented
402 */
403
404 if (frame->hdr_len == 0) {
405 kfree(frame);
406#ifdef DEBUG
407 printk(KERN_DEBUG "0 sized frame\n");
408#endif
409 pcbit_firmware_bug(dev);
410 return;
411 }
412 /* sanity check the length values */
413 if (frame->hdr_len > 1024 || frame->dt_len > 2048) {
414#ifdef DEBUG
415 printk(KERN_DEBUG "length problem: ");
416 printk(KERN_DEBUG "TH=%04x TD=%04x\n",
417 frame->hdr_len,
418 frame->dt_len);
419#endif
420 pcbit_l2_error(dev);
421 kfree(frame);
422 return;
423 }
424 /* minimum frame read */
425
426 frame->skb = dev_alloc_skb(frame->hdr_len + frame->dt_len +
427 ((frame->hdr_len + 15) & ~15));
428
429 if (!frame->skb) {
430 printk(KERN_DEBUG "pcbit_receive: out of memory\n");
431 kfree(frame);
432 return;
433 }
434 /* 16 byte alignment for IP */
435 if (frame->dt_len)
436 skb_reserve(frame->skb, (frame->hdr_len + 15) & ~15);
437
438 } else {
439 /* Type 1 */
440 type1 = 1;
441 tt &= 0x7fffU;
442
443 if (!(frame = dev->read_frame)) {
444 printk("Type 1 frame and no frame queued\n");
445 /* usually after an error: toss frame */
446 dev->readptr += tt;
447 if (dev->readptr > dev->sh_mem + BANK2 + BANKLEN)
448 dev->readptr -= BANKLEN;
449 return;
450
451 }
452 }
453
454 memcpy_frompcbit(dev, skb_put(frame->skb, tt), tt);
455
456 frame->copied += tt;
457 spin_lock_irqsave(&dev->lock, flags);
458 if (frame->copied == frame->hdr_len + frame->dt_len) {
459
460 if (type1) {
461 dev->read_frame = NULL;
462 }
463 if (dev->read_queue) {
464 struct frame_buf *ptr;
465 for (ptr = dev->read_queue; ptr->next; ptr = ptr->next);
466 ptr->next = frame;
467 } else
468 dev->read_queue = frame;
469
470 } else {
471 dev->read_frame = frame;
472 }
473 spin_unlock_irqrestore(&dev->lock, flags);
474}
475
476/*
477 * The board sends 0 sized frames
478 * They are TDATA_CONFs that get messed up somehow
479 * gotta send a fake acknowledgment to the upper layer somehow
480 */
481
482static __inline__ void
483pcbit_fake_conf(struct pcbit_dev *dev, struct pcbit_chan *chan)
484{
485 isdn_ctrl ictl;
486
487 if (chan->queued) {
488 chan->queued--;
489
490 ictl.driver = dev->id;
491 ictl.command = ISDN_STAT_BSENT;
492 ictl.arg = chan->id;
493 dev->dev_if->statcallb(&ictl);
494 }
495}
496
497static void
498pcbit_firmware_bug(struct pcbit_dev *dev)
499{
500 struct pcbit_chan *chan;
501
502 chan = dev->b1;
503
504 if (chan->fsm_state == ST_ACTIVE) {
505 pcbit_fake_conf(dev, chan);
506 }
507 chan = dev->b2;
508
509 if (chan->fsm_state == ST_ACTIVE) {
510 pcbit_fake_conf(dev, chan);
511 }
512}
513
514irqreturn_t
515pcbit_irq_handler(int interrupt, void *devptr, struct pt_regs *regs)
516{
517 struct pcbit_dev *dev;
518 u_char info,
519 ack_seq,
520 read_seq;
521
522 dev = (struct pcbit_dev *) devptr;
523
524 if (!dev) {
525 printk(KERN_WARNING "pcbit_irq_handler: wrong device\n");
526 return IRQ_NONE;
527 }
528 if (dev->interrupt) {
529 printk(KERN_DEBUG "pcbit: reentering interrupt hander\n");
530 return IRQ_HANDLED;
531 }
532 dev->interrupt = 1;
533
534 info = readb(dev->sh_mem + BANK3);
535
536 if (dev->l2_state == L2_STARTING || dev->l2_state == L2_ERROR) {
537 pcbit_l2_active_conf(dev, info);
538 dev->interrupt = 0;
539 return IRQ_HANDLED;
540 }
541 if (info & 0x40U) { /* E bit set */
542#ifdef DEBUG
543 printk(KERN_DEBUG "pcbit_irq_handler: E bit on\n");
544#endif
545 pcbit_l2_error(dev);
546 dev->interrupt = 0;
547 return IRQ_HANDLED;
548 }
549 if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) {
550 dev->interrupt = 0;
551 return IRQ_HANDLED;
552 }
553 ack_seq = (info >> 3) & 0x07U;
554 read_seq = (info & 0x07U);
555
556 dev->interrupt = 0;
557
558 if (read_seq != dev->rcv_seq) {
559 while (read_seq != dev->rcv_seq) {
560 pcbit_receive(dev);
561 dev->rcv_seq = (dev->rcv_seq + 1) % 8;
562 }
563 pcbit_sched_delivery(dev);
564 }
565 if (ack_seq != dev->unack_seq) {
566 pcbit_recv_ack(dev, ack_seq);
567 }
568 info = dev->rcv_seq << 3;
569 info |= dev->send_seq;
570
571 writeb(info, dev->sh_mem + BANK4);
572 return IRQ_HANDLED;
573}
574
575
576static void
577pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info)
578{
579 u_char state;
580
581 state = dev->l2_state;
582
583#ifdef DEBUG
584 printk(KERN_DEBUG "layer2_active_confirm\n");
585#endif
586
587
588 if (info & 0x80U) {
589 dev->rcv_seq = info & 0x07U;
590 dev->l2_state = L2_RUNNING;
591 } else
592 dev->l2_state = L2_DOWN;
593
594 if (state == L2_STARTING)
595 wake_up_interruptible(&dev->set_running_wq);
596
597 if (state == L2_ERROR && dev->l2_state == L2_RUNNING) {
598 pcbit_transmit(dev);
599 }
600}
601
602static void
603pcbit_l2_err_recover(unsigned long data)
604{
605
606 struct pcbit_dev *dev;
607 struct frame_buf *frame;
608
609 dev = (struct pcbit_dev *) data;
610
611 del_timer(&dev->error_recover_timer);
612 if (dev->w_busy || dev->r_busy) {
613 init_timer(&dev->error_recover_timer);
614 dev->error_recover_timer.expires = jiffies + ERRTIME;
615 add_timer(&dev->error_recover_timer);
616 return;
617 }
618 dev->w_busy = dev->r_busy = 1;
619
620 if (dev->read_frame) {
621 if (dev->read_frame->skb)
622 kfree_skb(dev->read_frame->skb);
623 kfree(dev->read_frame);
624 dev->read_frame = NULL;
625 }
626 if (dev->write_queue) {
627 frame = dev->write_queue;
628#ifdef FREE_ON_ERROR
629 dev->write_queue = dev->write_queue->next;
630
631 if (frame->skb) {
632 dev_kfree_skb(frame->skb);
633 }
634 kfree(frame);
635#else
636 frame->copied = 0;
637#endif
638 }
639 dev->rcv_seq = dev->send_seq = dev->unack_seq = 0;
640 dev->free = 511;
641 dev->l2_state = L2_ERROR;
642
643 /* this is an hack... */
644 pcbit_firmware_bug(dev);
645
646 dev->writeptr = dev->sh_mem;
647 dev->readptr = dev->sh_mem + BANK2;
648
649 writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)),
650 dev->sh_mem + BANK4);
651 dev->w_busy = dev->r_busy = 0;
652
653}
654
655static void
656pcbit_l2_error(struct pcbit_dev *dev)
657{
658 if (dev->l2_state == L2_RUNNING) {
659
660 printk(KERN_INFO "pcbit: layer 2 error\n");
661
662#ifdef DEBUG
663 log_state(dev);
664#endif
665
666 dev->l2_state = L2_DOWN;
667
668 init_timer(&dev->error_recover_timer);
669 dev->error_recover_timer.function = &pcbit_l2_err_recover;
670 dev->error_recover_timer.data = (ulong) dev;
671 dev->error_recover_timer.expires = jiffies + ERRTIME;
672 add_timer(&dev->error_recover_timer);
673 }
674}
675
676/*
677 * Description:
678 * if board acks frames
679 * update dev->free
680 * call pcbit_transmit to write possible queued frames
681 */
682
683static void
684pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack)
685{
686 int i,
687 count;
688 int unacked;
689
690 unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07;
691
692 /* dev->unack_seq < ack <= dev->send_seq; */
693
694 if (unacked) {
695
696 if (dev->send_seq > dev->unack_seq) {
697 if (ack <= dev->unack_seq || ack > dev->send_seq) {
698 printk(KERN_DEBUG
699 "layer 2 ack unacceptable - dev %d",
700 dev->id);
701
702 pcbit_l2_error(dev);
703 } else if (ack > dev->send_seq && ack <= dev->unack_seq) {
704 printk(KERN_DEBUG
705 "layer 2 ack unacceptable - dev %d",
706 dev->id);
707 pcbit_l2_error(dev);
708 }
709 }
710 /* ack is acceptable */
711
712
713 i = dev->unack_seq;
714
715 do {
716 dev->unack_seq = i = (i + 1) % 8;
717 dev->free += dev->fsize[i];
718 } while (i != ack);
719
720 count = 0;
721 while (count < 7 && dev->write_queue) {
722 u8 lsend_seq = dev->send_seq;
723
724 pcbit_transmit(dev);
725
726 if (dev->send_seq == lsend_seq)
727 break;
728 count++;
729 }
730 } else
731 printk(KERN_DEBUG "recv_ack: unacked = 0\n");
732}
diff --git a/drivers/isdn/pcbit/layer2.h b/drivers/isdn/pcbit/layer2.h
new file mode 100644
index 000000000000..0d99da3a3e2b
--- /dev/null
+++ b/drivers/isdn/pcbit/layer2.h
@@ -0,0 +1,288 @@
1/*
2 * PCBIT-D low-layer interface definitions
3 *
4 * Copyright (C) 1996 Universidade de Lisboa
5 *
6 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
7 *
8 * This software may be used and distributed according to the terms of
9 * the GNU General Public License, incorporated herein by reference.
10 */
11
12/*
13 * 19991203 - Fernando Carvalho - takion@superbofh.org
14 * Hacked to compile with egcs and run with current version of isdn modules
15*/
16
17#ifndef LAYER2_H
18#define LAYER2_H
19
20#include <linux/interrupt.h>
21
22#include <asm/byteorder.h>
23
24#define BANK1 0x0000U /* PC -> Board */
25#define BANK2 0x01ffU /* Board -> PC */
26#define BANK3 0x03feU /* Att Board */
27#define BANK4 0x03ffU /* Att PC */
28
29#define BANKLEN 0x01FFU
30
31#define LOAD_ZONE_START 0x03f8U
32#define LOAD_ZONE_END 0x03fdU
33
34#define LOAD_RETRY 18000000
35
36
37
38/* TAM - XX - C - S - NUM */
39#define PREHDR_LEN 8
40/* TT - M - I - TH - TD */
41#define FRAME_HDR_LEN 8
42
43#define MSG_CONN_REQ 0x08000100
44#define MSG_CONN_CONF 0x00000101
45#define MSG_CONN_IND 0x00000102
46#define MSG_CONN_RESP 0x08000103
47
48#define MSG_CONN_ACTV_REQ 0x08000300
49#define MSG_CONN_ACTV_CONF 0x00000301
50#define MSG_CONN_ACTV_IND 0x00000302
51#define MSG_CONN_ACTV_RESP 0x08000303
52
53#define MSG_DISC_REQ 0x08000400
54#define MSG_DISC_CONF 0x00000401
55#define MSG_DISC_IND 0x00000402
56#define MSG_DISC_RESP 0x08000403
57
58#define MSG_TDATA_REQ 0x0908E200
59#define MSG_TDATA_CONF 0x0000E201
60#define MSG_TDATA_IND 0x0000E202
61#define MSG_TDATA_RESP 0x0908E203
62
63#define MSG_SELP_REQ 0x09004000
64#define MSG_SELP_CONF 0x00004001
65
66#define MSG_ACT_TRANSP_REQ 0x0908E000
67#define MSG_ACT_TRANSP_CONF 0x0000E001
68
69#define MSG_STPROT_REQ 0x09004100
70#define MSG_STPROT_CONF 0x00004101
71
72#define MSG_PING188_REQ 0x09030500
73#define MSG_PING188_CONF 0x000005bc
74
75#define MSG_WATCH188 0x09030400
76
77#define MSG_API_ON 0x08020102
78#define MSG_POOL_PCBIT 0x08020400
79#define MSG_POOL_PCBIT_CONF 0x00000401
80
81#define MSG_INFO_IND 0x00002602
82#define MSG_INFO_RESP 0x08002603
83
84#define MSG_DEBUG_188 0x0000ff00
85
86/*
87
88 long 4 3 2 1
89 Intel 1 2 3 4
90*/
91
92#ifdef __LITTLE_ENDIAN
93#define SET_MSG_SCMD(msg, ch) (msg = (msg & 0xffffff00) | (((ch) & 0xff)))
94#define SET_MSG_CMD(msg, ch) (msg = (msg & 0xffff00ff) | (((ch) & 0xff) << 8))
95#define SET_MSG_PROC(msg, ch) (msg = (msg & 0xff00ffff) | (((ch) & 0xff) << 16))
96#define SET_MSG_CPU(msg, ch) (msg = (msg & 0x00ffffff) | (((ch) & 0xff) << 24))
97
98#define GET_MSG_SCMD(msg) ((msg) & 0xFF)
99#define GET_MSG_CMD(msg) ((msg) >> 8 & 0xFF)
100#define GET_MSG_PROC(msg) ((msg) >> 16 & 0xFF)
101#define GET_MSG_CPU(msg) ((msg) >> 24)
102
103#else
104#error "Non-Intel CPU"
105#endif
106
107#define MAX_QUEUED 7
108
109#define SCHED_READ 0x01
110#define SCHED_WRITE 0x02
111
112#define SET_RUN_TIMEOUT 2*HZ /* 2 seconds */
113
114struct frame_buf {
115 ulong msg;
116 unsigned int refnum;
117 unsigned int dt_len;
118 unsigned int hdr_len;
119 struct sk_buff *skb;
120 unsigned int copied;
121 struct frame_buf * next;
122};
123
124extern int pcbit_l2_write(struct pcbit_dev * dev, ulong msg, ushort refnum,
125 struct sk_buff *skb, unsigned short hdr_len);
126
127extern irqreturn_t pcbit_irq_handler(int interrupt, void *, struct pt_regs *regs);
128
129extern struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS];
130
131#ifdef DEBUG
132static __inline__ void log_state(struct pcbit_dev *dev) {
133 printk(KERN_DEBUG "writeptr = %ld\n",
134 (ulong) (dev->writeptr - dev->sh_mem));
135 printk(KERN_DEBUG "readptr = %ld\n",
136 (ulong) (dev->readptr - (dev->sh_mem + BANK2)));
137 printk(KERN_DEBUG "{rcv_seq=%01x, send_seq=%01x, unack_seq=%01x}\n",
138 dev->rcv_seq, dev->send_seq, dev->unack_seq);
139}
140#endif
141
142static __inline__ struct pcbit_dev * chan2dev(struct pcbit_chan * chan)
143{
144 struct pcbit_dev * dev;
145 int i;
146
147
148 for (i=0; i<MAX_PCBIT_CARDS; i++)
149 if ((dev=dev_pcbit[i]))
150 if (dev->b1 == chan || dev->b2 == chan)
151 return dev;
152 return NULL;
153
154}
155
156static __inline__ struct pcbit_dev * finddev(int id)
157{
158 struct pcbit_dev * dev;
159 int i;
160
161 for (i=0; i<MAX_PCBIT_CARDS; i++)
162 if ((dev=dev_pcbit[i]))
163 if (dev->id == id)
164 return dev;
165 return NULL;
166}
167
168
169/*
170 * Support routines for reading and writing in the board
171 */
172
173static __inline__ void pcbit_writeb(struct pcbit_dev *dev, unsigned char dt)
174{
175 writeb(dt, dev->writeptr++);
176 if (dev->writeptr == dev->sh_mem + BANKLEN)
177 dev->writeptr = dev->sh_mem;
178}
179
180static __inline__ void pcbit_writew(struct pcbit_dev *dev, unsigned short dt)
181{
182 int dist;
183
184 dist = BANKLEN - (dev->writeptr - dev->sh_mem);
185 switch (dist) {
186 case 2:
187 writew(dt, dev->writeptr);
188 dev->writeptr = dev->sh_mem;
189 break;
190 case 1:
191 writeb((u_char) (dt & 0x00ffU), dev->writeptr);
192 dev->writeptr = dev->sh_mem;
193 writeb((u_char) (dt >> 8), dev->writeptr++);
194 break;
195 default:
196 writew(dt, dev->writeptr);
197 dev->writeptr += 2;
198 break;
199 };
200}
201
202static __inline__ void memcpy_topcbit(struct pcbit_dev * dev, u_char * data,
203 int len)
204{
205 int diff;
206
207 diff = len - (BANKLEN - (dev->writeptr - dev->sh_mem) );
208
209 if (diff > 0)
210 {
211 memcpy_toio(dev->writeptr, data, len - diff);
212 memcpy_toio(dev->sh_mem, data + (len - diff), diff);
213 dev->writeptr = dev->sh_mem + diff;
214 }
215 else
216 {
217 memcpy_toio(dev->writeptr, data, len);
218
219 dev->writeptr += len;
220 if (diff == 0)
221 dev->writeptr = dev->sh_mem;
222 }
223}
224
225static __inline__ unsigned char pcbit_readb(struct pcbit_dev *dev)
226{
227 unsigned char val;
228
229 val = readb(dev->readptr++);
230 if (dev->readptr == dev->sh_mem + BANK2 + BANKLEN)
231 dev->readptr = dev->sh_mem + BANK2;
232
233 return val;
234}
235
236static __inline__ unsigned short pcbit_readw(struct pcbit_dev *dev)
237{
238 int dist;
239 unsigned short val;
240
241 dist = BANKLEN - ( dev->readptr - (dev->sh_mem + BANK2 ) );
242 switch (dist) {
243 case 2:
244 val = readw(dev->readptr);
245 dev->readptr = dev->sh_mem + BANK2;
246 break;
247 case 1:
248 val = readb(dev->readptr);
249 dev->readptr = dev->sh_mem + BANK2;
250 val = (readb(dev->readptr++) << 8) | val;
251 break;
252 default:
253 val = readw(dev->readptr);
254 dev->readptr += 2;
255 break;
256 };
257 return val;
258}
259
260static __inline__ void memcpy_frompcbit(struct pcbit_dev * dev, u_char * data, int len)
261{
262 int diff;
263
264 diff = len - (BANKLEN - (dev->readptr - (dev->sh_mem + BANK2) ) );
265 if (diff > 0)
266 {
267 memcpy_fromio(data, dev->readptr, len - diff);
268 memcpy_fromio(data + (len - diff), dev->sh_mem + BANK2 , diff);
269 dev->readptr = dev->sh_mem + BANK2 + diff;
270 }
271 else
272 {
273 memcpy_fromio(data, dev->readptr, len);
274 dev->readptr += len;
275 if (diff == 0)
276 dev->readptr = dev->sh_mem + BANK2;
277 }
278}
279
280
281#endif
282
283
284
285
286
287
288
diff --git a/drivers/isdn/pcbit/module.c b/drivers/isdn/pcbit/module.c
new file mode 100644
index 000000000000..282073a35d6a
--- /dev/null
+++ b/drivers/isdn/pcbit/module.c
@@ -0,0 +1,130 @@
1/*
2 * PCBIT-D module support
3 *
4 * Copyright (C) 1996 Universidade de Lisboa
5 *
6 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
7 *
8 * This software may be used and distributed according to the terms of
9 * the GNU General Public License, incorporated herein by reference.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sched.h>
15#include <linux/string.h>
16#include <linux/kernel.h>
17#include <linux/skbuff.h>
18
19#include <linux/isdnif.h>
20#include "pcbit.h"
21
22MODULE_DESCRIPTION("ISDN4Linux: Driver for PCBIT-T card");
23MODULE_AUTHOR("Pedro Roque Marques");
24MODULE_LICENSE("GPL");
25
26static int mem[MAX_PCBIT_CARDS];
27static int irq[MAX_PCBIT_CARDS];
28
29module_param_array(mem, int, NULL, 0);
30module_param_array(irq, int, NULL, 0);
31
32static int num_boards;
33struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS];
34
35extern void pcbit_terminate(int board);
36extern int pcbit_init_dev(int board, int mem_base, int irq);
37
38static int __init pcbit_init(void)
39{
40 int board;
41
42 num_boards = 0;
43
44 printk(KERN_NOTICE
45 "PCBIT-D device driver v 0.5-fjpc0 19991204 - "
46 "Copyright (C) 1996 Universidade de Lisboa\n");
47
48 if (mem[0] || irq[0])
49 {
50 for (board=0; board < MAX_PCBIT_CARDS && mem[board] && irq[board]; board++)
51 {
52 if (!mem[board])
53 mem[board] = 0xD0000;
54 if (!irq[board])
55 irq[board] = 5;
56
57 if (pcbit_init_dev(board, mem[board], irq[board]) == 0)
58 num_boards++;
59
60 else
61 {
62 printk(KERN_WARNING
63 "pcbit_init failed for dev %d",
64 board + 1);
65 return -EIO;
66 }
67 }
68 }
69
70 /* Hardcoded default settings detection */
71
72 if (!num_boards)
73 {
74 printk(KERN_INFO
75 "Trying to detect board using default settings\n");
76 if (pcbit_init_dev(0, 0xD0000, 5) == 0)
77 num_boards++;
78 else
79 return -EIO;
80 }
81 return 0;
82}
83
84static void __exit pcbit_exit(void)
85{
86#ifdef MODULE
87 int board;
88
89 for (board = 0; board < num_boards; board++)
90 pcbit_terminate(board);
91 printk(KERN_NOTICE
92 "PCBIT-D module unloaded\n");
93#endif
94}
95
96#ifndef MODULE
97#define MAX_PARA (MAX_PCBIT_CARDS * 2)
98static int __init pcbit_setup(char *line)
99{
100 int i, j, argc;
101 char *str;
102 int ints[MAX_PARA+1];
103
104 str = get_options(line, MAX_PARA, ints);
105 argc = ints[0];
106 i = 0;
107 j = 1;
108
109 while (argc && (i<MAX_PCBIT_CARDS)) {
110
111 if (argc) {
112 mem[i] = ints[j];
113 j++; argc--;
114 }
115
116 if (argc) {
117 irq[i] = ints[j];
118 j++; argc--;
119 }
120
121 i++;
122 }
123 return(1);
124}
125__setup("pcbit=", pcbit_setup);
126#endif
127
128module_init(pcbit_init);
129module_exit(pcbit_exit);
130
diff --git a/drivers/isdn/pcbit/pcbit.h b/drivers/isdn/pcbit/pcbit.h
new file mode 100644
index 000000000000..388bacefd23a
--- /dev/null
+++ b/drivers/isdn/pcbit/pcbit.h
@@ -0,0 +1,169 @@
1/*
2 * PCBIT-D device driver definitions
3 *
4 * Copyright (C) 1996 Universidade de Lisboa
5 *
6 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
7 *
8 * This software may be used and distributed according to the terms of
9 * the GNU General Public License, incorporated herein by reference.
10 */
11
12#ifndef PCBIT_H
13#define PCBIT_H
14
15#include <linux/workqueue.h>
16
17#define MAX_PCBIT_CARDS 4
18
19
20#define BLOCK_TIMER
21
22#ifdef __KERNEL__
23
24struct pcbit_chan {
25 unsigned short id;
26 unsigned short callref; /* Call Reference */
27 unsigned char proto; /* layer2protocol */
28 unsigned char queued; /* unacked data messages */
29 unsigned char layer2link; /* used in TData */
30 unsigned char snum; /* used in TData */
31 unsigned short s_refnum;
32 unsigned short r_refnum;
33 unsigned short fsm_state;
34 struct timer_list fsm_timer;
35#ifdef BLOCK_TIMER
36 struct timer_list block_timer;
37#endif
38};
39
40struct msn_entry {
41 char *msn;
42 struct msn_entry * next;
43};
44
45struct pcbit_dev {
46 /* board */
47
48 volatile unsigned char __iomem *sh_mem; /* RDP address */
49 unsigned long ph_mem;
50 unsigned int irq;
51 unsigned int id;
52 unsigned int interrupt; /* set during interrupt
53 processing */
54 spinlock_t lock;
55 /* isdn4linux */
56
57 struct msn_entry * msn_list; /* ISDN address list */
58
59 isdn_if * dev_if;
60
61 ushort ll_hdrlen;
62 ushort hl_hdrlen;
63
64 /* link layer */
65 unsigned char l2_state;
66
67 struct frame_buf *read_queue;
68 struct frame_buf *read_frame;
69 struct frame_buf *write_queue;
70
71 /* Protocol start */
72 wait_queue_head_t set_running_wq;
73 struct timer_list set_running_timer;
74
75 struct timer_list error_recover_timer;
76
77 struct work_struct qdelivery;
78
79 u_char w_busy;
80 u_char r_busy;
81
82 volatile unsigned char __iomem *readptr;
83 volatile unsigned char __iomem *writeptr;
84
85 ushort loadptr;
86
87 unsigned short fsize[8]; /* sent layer2 frames size */
88
89 unsigned char send_seq;
90 unsigned char rcv_seq;
91 unsigned char unack_seq;
92
93 unsigned short free;
94
95 /* channels */
96
97 struct pcbit_chan *b1;
98 struct pcbit_chan *b2;
99};
100
101#define STATS_TIMER (10*HZ)
102#define ERRTIME (HZ/10)
103
104/* MRU */
105#define MAXBUFSIZE 1534
106#define MRU MAXBUFSIZE
107
108#define STATBUF_LEN 2048
109/*
110 *
111 */
112
113#endif /* __KERNEL__ */
114
115/* isdn_ctrl only allows a long sized argument */
116
117struct pcbit_ioctl {
118 union {
119 struct byte_op {
120 ushort addr;
121 ushort value;
122 } rdp_byte;
123 unsigned long l2_status;
124 } info;
125};
126
127
128
129#define PCBIT_IOCTL_GETSTAT 0x01 /* layer2 status */
130#define PCBIT_IOCTL_LWMODE 0x02 /* linear write mode */
131#define PCBIT_IOCTL_STRLOAD 0x03 /* start load mode */
132#define PCBIT_IOCTL_ENDLOAD 0x04 /* end load mode */
133#define PCBIT_IOCTL_SETBYTE 0x05 /* set byte */
134#define PCBIT_IOCTL_GETBYTE 0x06 /* get byte */
135#define PCBIT_IOCTL_RUNNING 0x07 /* set protocol running */
136#define PCBIT_IOCTL_WATCH188 0x08 /* set watch 188 */
137#define PCBIT_IOCTL_PING188 0x09 /* ping 188 */
138#define PCBIT_IOCTL_FWMODE 0x0A /* firmware write mode */
139#define PCBIT_IOCTL_STOP 0x0B /* stop protocol */
140#define PCBIT_IOCTL_APION 0x0C /* issue API_ON */
141
142#ifndef __KERNEL__
143
144#define PCBIT_GETSTAT (PCBIT_IOCTL_GETSTAT + IIOCDRVCTL)
145#define PCBIT_LWMODE (PCBIT_IOCTL_LWMODE + IIOCDRVCTL)
146#define PCBIT_STRLOAD (PCBIT_IOCTL_STRLOAD + IIOCDRVCTL)
147#define PCBIT_ENDLOAD (PCBIT_IOCTL_ENDLOAD + IIOCDRVCTL)
148#define PCBIT_SETBYTE (PCBIT_IOCTL_SETBYTE + IIOCDRVCTL)
149#define PCBIT_GETBYTE (PCBIT_IOCTL_GETBYTE + IIOCDRVCTL)
150#define PCBIT_RUNNING (PCBIT_IOCTL_RUNNING + IIOCDRVCTL)
151#define PCBIT_WATCH188 (PCBIT_IOCTL_WATCH188 + IIOCDRVCTL)
152#define PCBIT_PING188 (PCBIT_IOCTL_PING188 + IIOCDRVCTL)
153#define PCBIT_FWMODE (PCBIT_IOCTL_FWMODE + IIOCDRVCTL)
154#define PCBIT_STOP (PCBIT_IOCTL_STOP + IIOCDRVCTL)
155#define PCBIT_APION (PCBIT_IOCTL_APION + IIOCDRVCTL)
156
157#define MAXSUPERLINE 3000
158
159#endif
160
161#define L2_DOWN 0
162#define L2_LOADING 1
163#define L2_LWMODE 2
164#define L2_FWMODE 3
165#define L2_STARTING 4
166#define L2_RUNNING 5
167#define L2_ERROR 6
168
169#endif