Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/isdn/hisax/hfc_2bs0.c
15115 views
1
/* $Id: hfc_2bs0.c,v 1.20.2.6 2004/02/11 13:21:33 keil Exp $
2
*
3
* specific routines for CCD's HFC 2BS0
4
*
5
* Author Karsten Keil
6
* Copyright by Karsten Keil <[email protected]>
7
*
8
* This software may be used and distributed according to the terms
9
* of the GNU General Public License, incorporated herein by reference.
10
*
11
*/
12
13
#include <linux/init.h>
14
#include "hisax.h"
15
#include "hfc_2bs0.h"
16
#include "isac.h"
17
#include "isdnl1.h"
18
#include <linux/interrupt.h>
19
#include <linux/slab.h>
20
21
static inline int
22
WaitForBusy(struct IsdnCardState *cs)
23
{
24
int to = 130;
25
u_char val;
26
27
while (!(cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) {
28
val = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2 |
29
(cs->hw.hfc.cip & 3));
30
udelay(1);
31
to--;
32
}
33
if (!to) {
34
printk(KERN_WARNING "HiSax: waitforBusy timeout\n");
35
return (0);
36
} else
37
return (to);
38
}
39
40
static inline int
41
WaitNoBusy(struct IsdnCardState *cs)
42
{
43
int to = 125;
44
45
while ((cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) {
46
udelay(1);
47
to--;
48
}
49
if (!to) {
50
printk(KERN_WARNING "HiSax: waitforBusy timeout\n");
51
return (0);
52
} else
53
return (to);
54
}
55
56
static int
57
GetFreeFifoBytes(struct BCState *bcs)
58
{
59
int s;
60
61
if (bcs->hw.hfc.f1 == bcs->hw.hfc.f2)
62
return (bcs->cs->hw.hfc.fifosize);
63
s = bcs->hw.hfc.send[bcs->hw.hfc.f1] - bcs->hw.hfc.send[bcs->hw.hfc.f2];
64
if (s <= 0)
65
s += bcs->cs->hw.hfc.fifosize;
66
s = bcs->cs->hw.hfc.fifosize - s;
67
return (s);
68
}
69
70
static int
71
ReadZReg(struct BCState *bcs, u_char reg)
72
{
73
int val;
74
75
WaitNoBusy(bcs->cs);
76
val = 256 * bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_HIGH);
77
WaitNoBusy(bcs->cs);
78
val += bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_LOW);
79
return (val);
80
}
81
82
static void
83
hfc_clear_fifo(struct BCState *bcs)
84
{
85
struct IsdnCardState *cs = bcs->cs;
86
int idx, cnt;
87
int rcnt, z1, z2;
88
u_char cip, f1, f2;
89
90
if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
91
debugl1(cs, "hfc_clear_fifo");
92
cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
93
if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
94
cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
95
WaitForBusy(cs);
96
}
97
WaitNoBusy(cs);
98
f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
99
cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
100
WaitNoBusy(cs);
101
f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
102
z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
103
z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
104
cnt = 32;
105
while (((f1 != f2) || (z1 != z2)) && cnt--) {
106
if (cs->debug & L1_DEB_HSCX)
107
debugl1(cs, "hfc clear %d f1(%d) f2(%d)",
108
bcs->channel, f1, f2);
109
rcnt = z1 - z2;
110
if (rcnt < 0)
111
rcnt += cs->hw.hfc.fifosize;
112
if (rcnt)
113
rcnt++;
114
if (cs->debug & L1_DEB_HSCX)
115
debugl1(cs, "hfc clear %d z1(%x) z2(%x) cnt(%d)",
116
bcs->channel, z1, z2, rcnt);
117
cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
118
idx = 0;
119
while ((idx < rcnt) && WaitNoBusy(cs)) {
120
cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
121
idx++;
122
}
123
if (f1 != f2) {
124
WaitNoBusy(cs);
125
cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
126
HFC_CHANNEL(bcs->channel));
127
WaitForBusy(cs);
128
}
129
cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
130
WaitNoBusy(cs);
131
f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
132
cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
133
WaitNoBusy(cs);
134
f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
135
z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
136
z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
137
}
138
return;
139
}
140
141
142
static struct sk_buff
143
*
144
hfc_empty_fifo(struct BCState *bcs, int count)
145
{
146
u_char *ptr;
147
struct sk_buff *skb;
148
struct IsdnCardState *cs = bcs->cs;
149
int idx;
150
int chksum;
151
u_char stat, cip;
152
153
if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
154
debugl1(cs, "hfc_empty_fifo");
155
idx = 0;
156
if (count > HSCX_BUFMAX + 3) {
157
if (cs->debug & L1_DEB_WARN)
158
debugl1(cs, "hfc_empty_fifo: incoming packet too large");
159
cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
160
while ((idx++ < count) && WaitNoBusy(cs))
161
cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
162
WaitNoBusy(cs);
163
stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
164
HFC_CHANNEL(bcs->channel));
165
WaitForBusy(cs);
166
return (NULL);
167
}
168
if ((count < 4) && (bcs->mode != L1_MODE_TRANS)) {
169
if (cs->debug & L1_DEB_WARN)
170
debugl1(cs, "hfc_empty_fifo: incoming packet too small");
171
cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
172
while ((idx++ < count) && WaitNoBusy(cs))
173
cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
174
WaitNoBusy(cs);
175
stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
176
HFC_CHANNEL(bcs->channel));
177
WaitForBusy(cs);
178
#ifdef ERROR_STATISTIC
179
bcs->err_inv++;
180
#endif
181
return (NULL);
182
}
183
if (bcs->mode == L1_MODE_TRANS)
184
count -= 1;
185
else
186
count -= 3;
187
if (!(skb = dev_alloc_skb(count)))
188
printk(KERN_WARNING "HFC: receive out of memory\n");
189
else {
190
ptr = skb_put(skb, count);
191
idx = 0;
192
cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
193
while ((idx < count) && WaitNoBusy(cs)) {
194
*ptr++ = cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
195
idx++;
196
}
197
if (idx != count) {
198
debugl1(cs, "RFIFO BUSY error");
199
printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel);
200
dev_kfree_skb_any(skb);
201
if (bcs->mode != L1_MODE_TRANS) {
202
WaitNoBusy(cs);
203
stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
204
HFC_CHANNEL(bcs->channel));
205
WaitForBusy(cs);
206
}
207
return (NULL);
208
}
209
if (bcs->mode != L1_MODE_TRANS) {
210
WaitNoBusy(cs);
211
chksum = (cs->BC_Read_Reg(cs, HFC_DATA, cip) << 8);
212
WaitNoBusy(cs);
213
chksum += cs->BC_Read_Reg(cs, HFC_DATA, cip);
214
WaitNoBusy(cs);
215
stat = cs->BC_Read_Reg(cs, HFC_DATA, cip);
216
if (cs->debug & L1_DEB_HSCX)
217
debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x",
218
bcs->channel, chksum, stat);
219
if (stat) {
220
debugl1(cs, "FIFO CRC error");
221
dev_kfree_skb_any(skb);
222
skb = NULL;
223
#ifdef ERROR_STATISTIC
224
bcs->err_crc++;
225
#endif
226
}
227
WaitNoBusy(cs);
228
stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
229
HFC_CHANNEL(bcs->channel));
230
WaitForBusy(cs);
231
}
232
}
233
return (skb);
234
}
235
236
static void
237
hfc_fill_fifo(struct BCState *bcs)
238
{
239
struct IsdnCardState *cs = bcs->cs;
240
int idx, fcnt;
241
int count;
242
int z1, z2;
243
u_char cip;
244
245
if (!bcs->tx_skb)
246
return;
247
if (bcs->tx_skb->len <= 0)
248
return;
249
250
cip = HFC_CIP | HFC_F1 | HFC_SEND | HFC_CHANNEL(bcs->channel);
251
if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
252
cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
253
WaitForBusy(cs);
254
}
255
WaitNoBusy(cs);
256
if (bcs->mode != L1_MODE_TRANS) {
257
bcs->hw.hfc.f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
258
cip = HFC_CIP | HFC_F2 | HFC_SEND | HFC_CHANNEL(bcs->channel);
259
WaitNoBusy(cs);
260
bcs->hw.hfc.f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
261
bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(bcs, HFC_Z1 | HFC_SEND | HFC_CHANNEL(bcs->channel));
262
if (cs->debug & L1_DEB_HSCX)
263
debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)",
264
bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2,
265
bcs->hw.hfc.send[bcs->hw.hfc.f1]);
266
fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2;
267
if (fcnt < 0)
268
fcnt += 32;
269
if (fcnt > 30) {
270
if (cs->debug & L1_DEB_HSCX)
271
debugl1(cs, "hfc_fill_fifo more as 30 frames");
272
return;
273
}
274
count = GetFreeFifoBytes(bcs);
275
}
276
else {
277
WaitForBusy(cs);
278
z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
279
z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
280
count = z1 - z2;
281
if (count < 0)
282
count += cs->hw.hfc.fifosize;
283
} /* L1_MODE_TRANS */
284
if (cs->debug & L1_DEB_HSCX)
285
debugl1(cs, "hfc_fill_fifo %d count(%u/%d)",
286
bcs->channel, bcs->tx_skb->len,
287
count);
288
if (count < bcs->tx_skb->len) {
289
if (cs->debug & L1_DEB_HSCX)
290
debugl1(cs, "hfc_fill_fifo no fifo mem");
291
return;
292
}
293
cip = HFC_CIP | HFC_FIFO_IN | HFC_SEND | HFC_CHANNEL(bcs->channel);
294
idx = 0;
295
while ((idx < bcs->tx_skb->len) && WaitNoBusy(cs))
296
cs->BC_Write_Reg(cs, HFC_DATA_NODEB, cip, bcs->tx_skb->data[idx++]);
297
if (idx != bcs->tx_skb->len) {
298
debugl1(cs, "FIFO Send BUSY error");
299
printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);
300
} else {
301
count = bcs->tx_skb->len;
302
bcs->tx_cnt -= count;
303
if (PACKET_NOACK == bcs->tx_skb->pkt_type)
304
count = -1;
305
dev_kfree_skb_any(bcs->tx_skb);
306
bcs->tx_skb = NULL;
307
if (bcs->mode != L1_MODE_TRANS) {
308
WaitForBusy(cs);
309
WaitNoBusy(cs);
310
cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs->channel));
311
}
312
if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
313
(count >= 0)) {
314
u_long flags;
315
spin_lock_irqsave(&bcs->aclock, flags);
316
bcs->ackcnt += count;
317
spin_unlock_irqrestore(&bcs->aclock, flags);
318
schedule_event(bcs, B_ACKPENDING);
319
}
320
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
321
}
322
return;
323
}
324
325
void
326
main_irq_hfc(struct BCState *bcs)
327
{
328
struct IsdnCardState *cs = bcs->cs;
329
int z1, z2, rcnt;
330
u_char f1, f2, cip;
331
int receive, transmit, count = 5;
332
struct sk_buff *skb;
333
334
Begin:
335
count--;
336
cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
337
if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
338
cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
339
WaitForBusy(cs);
340
}
341
WaitNoBusy(cs);
342
receive = 0;
343
if (bcs->mode == L1_MODE_HDLC) {
344
f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
345
cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
346
WaitNoBusy(cs);
347
f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
348
if (f1 != f2) {
349
if (cs->debug & L1_DEB_HSCX)
350
debugl1(cs, "hfc rec %d f1(%d) f2(%d)",
351
bcs->channel, f1, f2);
352
receive = 1;
353
}
354
}
355
if (receive || (bcs->mode == L1_MODE_TRANS)) {
356
WaitForBusy(cs);
357
z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
358
z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
359
rcnt = z1 - z2;
360
if (rcnt < 0)
361
rcnt += cs->hw.hfc.fifosize;
362
if ((bcs->mode == L1_MODE_HDLC) || (rcnt)) {
363
rcnt++;
364
if (cs->debug & L1_DEB_HSCX)
365
debugl1(cs, "hfc rec %d z1(%x) z2(%x) cnt(%d)",
366
bcs->channel, z1, z2, rcnt);
367
/* sti(); */
368
if ((skb = hfc_empty_fifo(bcs, rcnt))) {
369
skb_queue_tail(&bcs->rqueue, skb);
370
schedule_event(bcs, B_RCVBUFREADY);
371
}
372
}
373
receive = 1;
374
}
375
if (bcs->tx_skb) {
376
transmit = 1;
377
test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
378
hfc_fill_fifo(bcs);
379
if (test_bit(BC_FLG_BUSY, &bcs->Flag))
380
transmit = 0;
381
} else {
382
if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
383
transmit = 1;
384
test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
385
hfc_fill_fifo(bcs);
386
if (test_bit(BC_FLG_BUSY, &bcs->Flag))
387
transmit = 0;
388
} else {
389
transmit = 0;
390
schedule_event(bcs, B_XMTBUFREADY);
391
}
392
}
393
if ((receive || transmit) && count)
394
goto Begin;
395
return;
396
}
397
398
static void
399
mode_hfc(struct BCState *bcs, int mode, int bc)
400
{
401
struct IsdnCardState *cs = bcs->cs;
402
403
if (cs->debug & L1_DEB_HSCX)
404
debugl1(cs, "HFC 2BS0 mode %d bchan %d/%d",
405
mode, bc, bcs->channel);
406
bcs->mode = mode;
407
bcs->channel = bc;
408
409
switch (mode) {
410
case (L1_MODE_NULL):
411
if (bc) {
412
cs->hw.hfc.ctmt &= ~1;
413
cs->hw.hfc.isac_spcr &= ~0x03;
414
}
415
else {
416
cs->hw.hfc.ctmt &= ~2;
417
cs->hw.hfc.isac_spcr &= ~0x0c;
418
}
419
break;
420
case (L1_MODE_TRANS):
421
cs->hw.hfc.ctmt &= ~(1 << bc); /* set HDLC mode */
422
cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt);
423
hfc_clear_fifo(bcs); /* complete fifo clear */
424
if (bc) {
425
cs->hw.hfc.ctmt |= 1;
426
cs->hw.hfc.isac_spcr &= ~0x03;
427
cs->hw.hfc.isac_spcr |= 0x02;
428
} else {
429
cs->hw.hfc.ctmt |= 2;
430
cs->hw.hfc.isac_spcr &= ~0x0c;
431
cs->hw.hfc.isac_spcr |= 0x08;
432
}
433
break;
434
case (L1_MODE_HDLC):
435
if (bc) {
436
cs->hw.hfc.ctmt &= ~1;
437
cs->hw.hfc.isac_spcr &= ~0x03;
438
cs->hw.hfc.isac_spcr |= 0x02;
439
} else {
440
cs->hw.hfc.ctmt &= ~2;
441
cs->hw.hfc.isac_spcr &= ~0x0c;
442
cs->hw.hfc.isac_spcr |= 0x08;
443
}
444
break;
445
}
446
cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt);
447
cs->writeisac(cs, ISAC_SPCR, cs->hw.hfc.isac_spcr);
448
if (mode == L1_MODE_HDLC)
449
hfc_clear_fifo(bcs);
450
}
451
452
static void
453
hfc_l2l1(struct PStack *st, int pr, void *arg)
454
{
455
struct BCState *bcs = st->l1.bcs;
456
struct sk_buff *skb = arg;
457
u_long flags;
458
459
switch (pr) {
460
case (PH_DATA | REQUEST):
461
spin_lock_irqsave(&bcs->cs->lock, flags);
462
if (bcs->tx_skb) {
463
skb_queue_tail(&bcs->squeue, skb);
464
} else {
465
bcs->tx_skb = skb;
466
test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
467
bcs->cs->BC_Send_Data(bcs);
468
}
469
spin_unlock_irqrestore(&bcs->cs->lock, flags);
470
break;
471
case (PH_PULL | INDICATION):
472
spin_lock_irqsave(&bcs->cs->lock, flags);
473
if (bcs->tx_skb) {
474
printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
475
} else {
476
test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
477
bcs->tx_skb = skb;
478
bcs->cs->BC_Send_Data(bcs);
479
}
480
spin_unlock_irqrestore(&bcs->cs->lock, flags);
481
break;
482
case (PH_PULL | REQUEST):
483
if (!bcs->tx_skb) {
484
test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
485
st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
486
} else
487
test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
488
break;
489
case (PH_ACTIVATE | REQUEST):
490
spin_lock_irqsave(&bcs->cs->lock, flags);
491
test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
492
mode_hfc(bcs, st->l1.mode, st->l1.bc);
493
spin_unlock_irqrestore(&bcs->cs->lock, flags);
494
l1_msg_b(st, pr, arg);
495
break;
496
case (PH_DEACTIVATE | REQUEST):
497
l1_msg_b(st, pr, arg);
498
break;
499
case (PH_DEACTIVATE | CONFIRM):
500
spin_lock_irqsave(&bcs->cs->lock, flags);
501
test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
502
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
503
mode_hfc(bcs, 0, st->l1.bc);
504
spin_unlock_irqrestore(&bcs->cs->lock, flags);
505
st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
506
break;
507
}
508
}
509
510
511
static void
512
close_hfcstate(struct BCState *bcs)
513
{
514
mode_hfc(bcs, 0, bcs->channel);
515
if (test_bit(BC_FLG_INIT, &bcs->Flag)) {
516
skb_queue_purge(&bcs->rqueue);
517
skb_queue_purge(&bcs->squeue);
518
if (bcs->tx_skb) {
519
dev_kfree_skb_any(bcs->tx_skb);
520
bcs->tx_skb = NULL;
521
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
522
}
523
}
524
test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
525
}
526
527
static int
528
open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
529
{
530
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
531
skb_queue_head_init(&bcs->rqueue);
532
skb_queue_head_init(&bcs->squeue);
533
}
534
bcs->tx_skb = NULL;
535
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
536
bcs->event = 0;
537
bcs->tx_cnt = 0;
538
return (0);
539
}
540
541
static int
542
setstack_hfc(struct PStack *st, struct BCState *bcs)
543
{
544
bcs->channel = st->l1.bc;
545
if (open_hfcstate(st->l1.hardware, bcs))
546
return (-1);
547
st->l1.bcs = bcs;
548
st->l2.l2l1 = hfc_l2l1;
549
setstack_manager(st);
550
bcs->st = st;
551
setstack_l1_B(st);
552
return (0);
553
}
554
555
static void
556
init_send(struct BCState *bcs)
557
{
558
int i;
559
560
if (!(bcs->hw.hfc.send = kmalloc(32 * sizeof(unsigned int), GFP_ATOMIC))) {
561
printk(KERN_WARNING
562
"HiSax: No memory for hfc.send\n");
563
return;
564
}
565
for (i = 0; i < 32; i++)
566
bcs->hw.hfc.send[i] = 0x1fff;
567
}
568
569
void
570
inithfc(struct IsdnCardState *cs)
571
{
572
init_send(&cs->bcs[0]);
573
init_send(&cs->bcs[1]);
574
cs->BC_Send_Data = &hfc_fill_fifo;
575
cs->bcs[0].BC_SetStack = setstack_hfc;
576
cs->bcs[1].BC_SetStack = setstack_hfc;
577
cs->bcs[0].BC_Close = close_hfcstate;
578
cs->bcs[1].BC_Close = close_hfcstate;
579
mode_hfc(cs->bcs, 0, 0);
580
mode_hfc(cs->bcs + 1, 0, 0);
581
}
582
583
void
584
releasehfc(struct IsdnCardState *cs)
585
{
586
kfree(cs->bcs[0].hw.hfc.send);
587
cs->bcs[0].hw.hfc.send = NULL;
588
kfree(cs->bcs[1].hw.hfc.send);
589
cs->bcs[1].hw.hfc.send = NULL;
590
}
591
592