* better
[mascara-docs.git] / i386 / linux-2.3.21 / drivers / isdn / hisax / hfc_2bs0.c
blob71767c888d58c1deb3ca184731cf2ef98223f27a
1 /* $Id: hfc_2bs0.c,v 1.9 1999/07/01 08:11:36 keil Exp $
3 * specific routines for CCD's HFC 2BS0
5 * Author Karsten Keil (keil@isdn4linux.de)
8 * $Log: hfc_2bs0.c,v $
9 * Revision 1.9 1999/07/01 08:11:36 keil
10 * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel
12 * Revision 1.8 1998/11/15 23:54:43 keil
13 * changes from 2.0
15 * Revision 1.7 1998/09/30 22:24:46 keil
16 * Fix missing line in setstack*
18 * Revision 1.6 1998/08/13 23:36:28 keil
19 * HiSax 3.1 - don't work stable with current LinkLevel
21 * Revision 1.5 1998/05/25 12:57:54 keil
22 * HiSax golden code from certification, Don't use !!!
23 * No leased lines, no X75, but many changes.
25 * Revision 1.4 1998/02/12 23:07:29 keil
26 * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
28 * Revision 1.3 1997/11/06 17:13:35 keil
29 * New 2.1 init code
31 * Revision 1.2 1997/10/29 19:04:47 keil
32 * changes for 2.1
34 * Revision 1.1 1997/09/11 17:31:33 keil
35 * Common part for HFC 2BS0 based cards
40 #define __NO_VERSION__
41 #include "hisax.h"
42 #include "hfc_2bs0.h"
43 #include "isac.h"
44 #include "isdnl1.h"
45 #include <linux/interrupt.h>
47 static inline int
48 WaitForBusy(struct IsdnCardState *cs)
50 int to = 130;
51 long flags;
52 u_char val;
54 save_flags(flags);
55 cli();
56 while (!(cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) {
57 val = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2 |
58 (cs->hw.hfc.cip & 3));
59 udelay(1);
60 to--;
62 restore_flags(flags);
63 if (!to) {
64 printk(KERN_WARNING "HiSax: waitforBusy timeout\n");
65 return (0);
66 } else
67 return (to);
70 static inline int
71 WaitNoBusy(struct IsdnCardState *cs)
73 int to = 125;
75 while ((cs->BC_Read_Reg(cs, HFC_STATUS, 0) & HFC_BUSY) && to) {
76 udelay(1);
77 to--;
79 if (!to) {
80 printk(KERN_WARNING "HiSax: waitforBusy timeout\n");
81 return (0);
82 } else
83 return (to);
86 int
87 GetFreeFifoBytes(struct BCState *bcs)
89 int s;
91 if (bcs->hw.hfc.f1 == bcs->hw.hfc.f2)
92 return (bcs->cs->hw.hfc.fifosize);
93 s = bcs->hw.hfc.send[bcs->hw.hfc.f1] - bcs->hw.hfc.send[bcs->hw.hfc.f2];
94 if (s <= 0)
95 s += bcs->cs->hw.hfc.fifosize;
96 s = bcs->cs->hw.hfc.fifosize - s;
97 return (s);
101 ReadZReg(struct BCState *bcs, u_char reg)
103 int val;
105 WaitNoBusy(bcs->cs);
106 val = 256 * bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_HIGH);
107 WaitNoBusy(bcs->cs);
108 val += bcs->cs->BC_Read_Reg(bcs->cs, HFC_DATA, reg | HFC_CIP | HFC_Z_LOW);
109 return (val);
112 void
113 hfc_sched_event(struct BCState *bcs, int event)
115 bcs->event |= 1 << event;
116 queue_task(&bcs->tqueue, &tq_immediate);
117 mark_bh(IMMEDIATE_BH);
120 static void
121 hfc_clear_fifo(struct BCState *bcs)
123 struct IsdnCardState *cs = bcs->cs;
124 long flags;
125 int idx, cnt;
126 int rcnt, z1, z2;
127 u_char cip, f1, f2;
129 if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
130 debugl1(cs, "hfc_clear_fifo");
131 save_flags(flags);
132 cli();
133 cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
134 if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
135 cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
136 WaitForBusy(cs);
138 WaitNoBusy(cs);
139 f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
140 cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
141 WaitNoBusy(cs);
142 f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
143 z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
144 z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
145 cnt = 32;
146 while (((f1 != f2) || (z1 != z2)) && cnt--) {
147 if (cs->debug & L1_DEB_HSCX)
148 debugl1(cs, "hfc clear %d f1(%d) f2(%d)",
149 bcs->channel, f1, f2);
150 rcnt = z1 - z2;
151 if (rcnt < 0)
152 rcnt += cs->hw.hfc.fifosize;
153 if (rcnt)
154 rcnt++;
155 if (cs->debug & L1_DEB_HSCX)
156 debugl1(cs, "hfc clear %d z1(%x) z2(%x) cnt(%d)",
157 bcs->channel, z1, z2, rcnt);
158 cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
159 idx = 0;
160 while ((idx < rcnt) && WaitNoBusy(cs)) {
161 cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
162 idx++;
164 if (f1 != f2) {
165 WaitNoBusy(cs);
166 cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
167 HFC_CHANNEL(bcs->channel));
168 WaitForBusy(cs);
170 cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
171 WaitNoBusy(cs);
172 f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
173 cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
174 WaitNoBusy(cs);
175 f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
176 z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
177 z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
179 restore_flags(flags);
180 return;
184 static struct sk_buff
186 hfc_empty_fifo(struct BCState *bcs, int count)
188 u_char *ptr;
189 struct sk_buff *skb;
190 struct IsdnCardState *cs = bcs->cs;
191 int idx;
192 int chksum;
193 u_char stat, cip;
195 if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
196 debugl1(cs, "hfc_empty_fifo");
197 idx = 0;
198 if (count > HSCX_BUFMAX + 3) {
199 if (cs->debug & L1_DEB_WARN)
200 debugl1(cs, "hfc_empty_fifo: incoming packet too large");
201 cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
202 while ((idx++ < count) && WaitNoBusy(cs))
203 cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
204 WaitNoBusy(cs);
205 stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
206 HFC_CHANNEL(bcs->channel));
207 WaitForBusy(cs);
208 return (NULL);
210 if (count < 4) {
211 if (cs->debug & L1_DEB_WARN)
212 debugl1(cs, "hfc_empty_fifo: incoming packet too small");
213 cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
214 while ((idx++ < count) && WaitNoBusy(cs))
215 cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
216 WaitNoBusy(cs);
217 stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
218 HFC_CHANNEL(bcs->channel));
219 WaitForBusy(cs);
220 return (NULL);
222 if (!(skb = dev_alloc_skb(count - 3)))
223 printk(KERN_WARNING "HFC: receive out of memory\n");
224 else {
225 SET_SKB_FREE(skb);
226 ptr = skb_put(skb, count - 3);
227 idx = 0;
228 cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
229 while ((idx < count - 3) && WaitNoBusy(cs)) {
230 *ptr++ = cs->BC_Read_Reg(cs, HFC_DATA_NODEB, cip);
231 idx++;
233 if (idx != count - 3) {
234 debugl1(cs, "RFIFO BUSY error");
235 printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel);
236 idev_kfree_skb(skb, FREE_READ);
237 WaitNoBusy(cs);
238 stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
239 HFC_CHANNEL(bcs->channel));
240 WaitForBusy(cs);
241 return (NULL);
243 WaitNoBusy(cs);
244 chksum = (cs->BC_Read_Reg(cs, HFC_DATA, cip) << 8);
245 WaitNoBusy(cs);
246 chksum += cs->BC_Read_Reg(cs, HFC_DATA, cip);
247 WaitNoBusy(cs);
248 stat = cs->BC_Read_Reg(cs, HFC_DATA, cip);
249 if (cs->debug & L1_DEB_HSCX)
250 debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x",
251 bcs->channel, chksum, stat);
252 if (stat) {
253 debugl1(cs, "FIFO CRC error");
254 idev_kfree_skb(skb, FREE_READ);
255 skb = NULL;
257 WaitNoBusy(cs);
258 stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
259 HFC_CHANNEL(bcs->channel));
260 WaitForBusy(cs);
262 return (skb);
265 static void
266 hfc_fill_fifo(struct BCState *bcs)
268 struct IsdnCardState *cs = bcs->cs;
269 long flags;
270 int idx, fcnt;
271 int count;
272 u_char cip;
274 if (!bcs->tx_skb)
275 return;
276 if (bcs->tx_skb->len <= 0)
277 return;
279 save_flags(flags);
280 cli();
281 cip = HFC_CIP | HFC_F1 | HFC_SEND | HFC_CHANNEL(bcs->channel);
282 if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
283 cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
284 WaitForBusy(cs);
286 WaitNoBusy(cs);
287 bcs->hw.hfc.f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
288 cip = HFC_CIP | HFC_F2 | HFC_SEND | HFC_CHANNEL(bcs->channel);
289 WaitNoBusy(cs);
290 bcs->hw.hfc.f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
291 bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(bcs, HFC_Z1 | HFC_SEND | HFC_CHANNEL(bcs->channel));
292 if (cs->debug & L1_DEB_HSCX)
293 debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)",
294 bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2,
295 bcs->hw.hfc.send[bcs->hw.hfc.f1]);
296 fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2;
297 if (fcnt < 0)
298 fcnt += 32;
299 if (fcnt > 30) {
300 if (cs->debug & L1_DEB_HSCX)
301 debugl1(cs, "hfc_fill_fifo more as 30 frames");
302 restore_flags(flags);
303 return;
305 count = GetFreeFifoBytes(bcs);
306 if (cs->debug & L1_DEB_HSCX)
307 debugl1(cs, "hfc_fill_fifo %d count(%ld/%d)",
308 bcs->channel, bcs->tx_skb->len,
309 count);
310 if (count < bcs->tx_skb->len) {
311 if (cs->debug & L1_DEB_HSCX)
312 debugl1(cs, "hfc_fill_fifo no fifo mem");
313 restore_flags(flags);
314 return;
316 cip = HFC_CIP | HFC_FIFO_IN | HFC_SEND | HFC_CHANNEL(bcs->channel);
317 idx = 0;
318 while ((idx < bcs->tx_skb->len) && WaitNoBusy(cs))
319 cs->BC_Write_Reg(cs, HFC_DATA_NODEB, cip, bcs->tx_skb->data[idx++]);
320 if (idx != bcs->tx_skb->len) {
321 debugl1(cs, "FIFO Send BUSY error");
322 printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);
323 } else {
324 count = bcs->tx_skb->len;
325 bcs->tx_cnt -= count;
326 if (PACKET_NOACK == bcs->tx_skb->pkt_type)
327 count = -1;
328 idev_kfree_skb(bcs->tx_skb, FREE_WRITE);
329 bcs->tx_skb = NULL;
330 WaitForBusy(cs);
331 WaitNoBusy(cs);
332 cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs->channel));
333 if (bcs->st->lli.l1writewakeup && (count >= 0))
334 bcs->st->lli.l1writewakeup(bcs->st, count);
335 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
337 restore_flags(flags);
338 return;
341 void
342 main_irq_hfc(struct BCState *bcs)
344 long flags;
345 struct IsdnCardState *cs = bcs->cs;
346 int z1, z2, rcnt;
347 u_char f1, f2, cip;
348 int receive, transmit, count = 5;
349 struct sk_buff *skb;
351 save_flags(flags);
352 Begin:
353 cli();
354 count--;
355 cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
356 if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
357 cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
358 WaitForBusy(cs);
360 WaitNoBusy(cs);
361 f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
362 cip = HFC_CIP | HFC_F2 | HFC_REC | HFC_CHANNEL(bcs->channel);
363 WaitNoBusy(cs);
364 f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
365 if (f1 != f2) {
366 if (cs->debug & L1_DEB_HSCX)
367 debugl1(cs, "hfc rec %d f1(%d) f2(%d)",
368 bcs->channel, f1, f2);
369 WaitForBusy(cs);
370 z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
371 z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
372 rcnt = z1 - z2;
373 if (rcnt < 0)
374 rcnt += cs->hw.hfc.fifosize;
375 rcnt++;
376 if (cs->debug & L1_DEB_HSCX)
377 debugl1(cs, "hfc rec %d z1(%x) z2(%x) cnt(%d)",
378 bcs->channel, z1, z2, rcnt);
379 /* sti(); */
380 if ((skb = hfc_empty_fifo(bcs, rcnt))) {
381 skb_queue_tail(&bcs->rqueue, skb);
382 hfc_sched_event(bcs, B_RCVBUFREADY);
384 receive = 1;
385 } else
386 receive = 0;
387 restore_flags(flags);
388 udelay(1);
389 cli();
390 if (bcs->tx_skb) {
391 transmit = 1;
392 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
393 hfc_fill_fifo(bcs);
394 if (test_bit(BC_FLG_BUSY, &bcs->Flag))
395 transmit = 0;
396 } else {
397 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
398 transmit = 1;
399 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
400 hfc_fill_fifo(bcs);
401 if (test_bit(BC_FLG_BUSY, &bcs->Flag))
402 transmit = 0;
403 } else {
404 transmit = 0;
405 hfc_sched_event(bcs, B_XMTBUFREADY);
408 restore_flags(flags);
409 if ((receive || transmit) && count)
410 goto Begin;
411 return;
414 void
415 mode_hfc(struct BCState *bcs, int mode, int bc)
417 struct IsdnCardState *cs = bcs->cs;
419 if (cs->debug & L1_DEB_HSCX)
420 debugl1(cs, "HFC 2BS0 mode %d bchan %d/%d",
421 mode, bc, bcs->channel);
422 bcs->mode = mode;
423 bcs->channel = bc;
425 switch (mode) {
426 case (L1_MODE_NULL):
427 if (bc)
428 cs->hw.hfc.isac_spcr &= ~0x03;
429 else
430 cs->hw.hfc.isac_spcr &= ~0x0c;
431 break;
432 case (L1_MODE_TRANS):
433 if (bc) {
434 cs->hw.hfc.ctmt |= 1;
435 cs->hw.hfc.isac_spcr &= ~0x03;
436 cs->hw.hfc.isac_spcr |= 0x02;
437 } else {
438 cs->hw.hfc.ctmt |= 2;
439 cs->hw.hfc.isac_spcr &= ~0x0c;
440 cs->hw.hfc.isac_spcr |= 0x08;
442 break;
443 case (L1_MODE_HDLC):
444 if (bc) {
445 cs->hw.hfc.ctmt &= ~1;
446 cs->hw.hfc.isac_spcr &= ~0x03;
447 cs->hw.hfc.isac_spcr |= 0x02;
448 } else {
449 cs->hw.hfc.ctmt &= ~2;
450 cs->hw.hfc.isac_spcr &= ~0x0c;
451 cs->hw.hfc.isac_spcr |= 0x08;
453 break;
455 cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt);
456 cs->writeisac(cs, ISAC_SPCR, cs->hw.hfc.isac_spcr);
457 if (mode)
458 hfc_clear_fifo(bcs);
461 static void
462 hfc_l2l1(struct PStack *st, int pr, void *arg)
464 struct sk_buff *skb = arg;
465 long flags;
467 switch (pr) {
468 case (PH_DATA | REQUEST):
469 save_flags(flags);
470 cli();
471 if (st->l1.bcs->tx_skb) {
472 skb_queue_tail(&st->l1.bcs->squeue, skb);
473 restore_flags(flags);
474 } else {
475 st->l1.bcs->tx_skb = skb;
476 test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
477 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
478 restore_flags(flags);
480 break;
481 case (PH_PULL | INDICATION):
482 if (st->l1.bcs->tx_skb) {
483 printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
484 break;
486 save_flags(flags);
487 cli();
488 test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
489 st->l1.bcs->tx_skb = skb;
490 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
491 restore_flags(flags);
492 break;
493 case (PH_PULL | REQUEST):
494 if (!st->l1.bcs->tx_skb) {
495 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
496 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
497 } else
498 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
499 break;
500 case (PH_ACTIVATE | REQUEST):
501 test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
502 mode_hfc(st->l1.bcs, st->l1.mode, st->l1.bc);
503 l1_msg_b(st, pr, arg);
504 break;
505 case (PH_DEACTIVATE | REQUEST):
506 l1_msg_b(st, pr, arg);
507 break;
508 case (PH_DEACTIVATE | CONFIRM):
509 test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
510 test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
511 mode_hfc(st->l1.bcs, 0, st->l1.bc);
512 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
513 break;
518 void
519 close_hfcstate(struct BCState *bcs)
521 mode_hfc(bcs, 0, bcs->channel);
522 if (test_bit(BC_FLG_INIT, &bcs->Flag)) {
523 discard_queue(&bcs->rqueue);
524 discard_queue(&bcs->squeue);
525 if (bcs->tx_skb) {
526 idev_kfree_skb(bcs->tx_skb, FREE_WRITE);
527 bcs->tx_skb = NULL;
528 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
531 test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
534 static int
535 open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
537 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
538 skb_queue_head_init(&bcs->rqueue);
539 skb_queue_head_init(&bcs->squeue);
541 bcs->tx_skb = NULL;
542 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
543 bcs->event = 0;
544 bcs->tx_cnt = 0;
545 return (0);
549 setstack_hfc(struct PStack *st, struct BCState *bcs)
551 bcs->channel = st->l1.bc;
552 if (open_hfcstate(st->l1.hardware, bcs))
553 return (-1);
554 st->l1.bcs = bcs;
555 st->l2.l2l1 = hfc_l2l1;
556 setstack_manager(st);
557 bcs->st = st;
558 setstack_l1_B(st);
559 return (0);
562 void __init
563 init_send(struct BCState *bcs)
565 int i;
567 if (!(bcs->hw.hfc.send = kmalloc(32 * sizeof(unsigned int), GFP_ATOMIC))) {
568 printk(KERN_WARNING
569 "HiSax: No memory for hfc.send\n");
570 return;
572 for (i = 0; i < 32; i++)
573 bcs->hw.hfc.send[i] = 0x1fff;
576 void __init
577 inithfc(struct IsdnCardState *cs)
579 init_send(&cs->bcs[0]);
580 init_send(&cs->bcs[1]);
581 cs->BC_Send_Data = &hfc_fill_fifo;
582 cs->bcs[0].BC_SetStack = setstack_hfc;
583 cs->bcs[1].BC_SetStack = setstack_hfc;
584 cs->bcs[0].BC_Close = close_hfcstate;
585 cs->bcs[1].BC_Close = close_hfcstate;
586 mode_hfc(cs->bcs, 0, 0);
587 mode_hfc(cs->bcs + 1, 0, 0);
590 void
591 releasehfc(struct IsdnCardState *cs)
593 if (cs->bcs[0].hw.hfc.send) {
594 kfree(cs->bcs[0].hw.hfc.send);
595 cs->bcs[0].hw.hfc.send = NULL;
597 if (cs->bcs[1].hw.hfc.send) {
598 kfree(cs->bcs[1].hw.hfc.send);
599 cs->bcs[1].hw.hfc.send = NULL;