Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hfc_2bs0.c
Go to the documentation of this file.
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);
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);
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;
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))) {
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 }