Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
isac.c
Go to the documentation of this file.
1 /* $Id: isac.c,v 1.31.2.3 2004/01/13 14:31:25 keil Exp $
2  *
3  * ISAC specific routines
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  * For changes and modifications please read
12  * Documentation/isdn/HiSax.cert
13  *
14  */
15 
16 #include "hisax.h"
17 #include "isac.h"
18 #include "arcofi.h"
19 #include "isdnl1.h"
20 #include <linux/interrupt.h>
21 #include <linux/slab.h>
22 #include <linux/init.h>
23 
24 #define DBUSY_TIMER_VALUE 80
25 #define ARCOFI_USE 1
26 
27 static char *ISACVer[] __devinitdata =
28 {"2086/2186 V1.1", "2085 B1", "2085 B2",
29  "2085 V2.3"};
30 
31 void __devinit ISACVersion(struct IsdnCardState *cs, char *s)
32 {
33  int val;
34 
35  val = cs->readisac(cs, ISAC_RBCH);
36  printk(KERN_INFO "%s ISAC version (%x): %s\n", s, val, ISACVer[(val >> 5) & 3]);
37 }
38 
39 static void
40 ph_command(struct IsdnCardState *cs, unsigned int command)
41 {
42  if (cs->debug & L1_DEB_ISAC)
43  debugl1(cs, "ph_command %x", command);
44  cs->writeisac(cs, ISAC_CIX0, (command << 2) | 3);
45 }
46 
47 
48 static void
49 isac_new_ph(struct IsdnCardState *cs)
50 {
51  switch (cs->dc.isac.ph_state) {
52  case (ISAC_IND_RS):
53  case (ISAC_IND_EI):
54  ph_command(cs, ISAC_CMD_DUI);
56  break;
57  case (ISAC_IND_DID):
59  break;
60  case (ISAC_IND_DR):
62  break;
63  case (ISAC_IND_PU):
64  l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
65  break;
66  case (ISAC_IND_RSY):
68  break;
69  case (ISAC_IND_ARD):
71  break;
72  case (ISAC_IND_AI8):
74  break;
75  case (ISAC_IND_AI10):
77  break;
78  default:
79  break;
80  }
81 }
82 
83 static void
84 isac_bh(struct work_struct *work)
85 {
86  struct IsdnCardState *cs =
87  container_of(work, struct IsdnCardState, tqueue);
88  struct PStack *stptr;
89 
90  if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
91  if (cs->debug)
92  debugl1(cs, "D-Channel Busy cleared");
93  stptr = cs->stlist;
94  while (stptr != NULL) {
95  stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL);
96  stptr = stptr->next;
97  }
98  }
99  if (test_and_clear_bit(D_L1STATECHANGE, &cs->event))
100  isac_new_ph(cs);
101  if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
102  DChannel_proc_rcv(cs);
103  if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
104  DChannel_proc_xmt(cs);
105 #if ARCOFI_USE
106  if (!test_bit(HW_ARCOFI, &cs->HW_Flags))
107  return;
108  if (test_and_clear_bit(D_RX_MON1, &cs->event))
110  if (test_and_clear_bit(D_TX_MON1, &cs->event))
112 #endif
113 }
114 
115 static void
116 isac_empty_fifo(struct IsdnCardState *cs, int count)
117 {
118  u_char *ptr;
119 
120  if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
121  debugl1(cs, "isac_empty_fifo");
122 
123  if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
124  if (cs->debug & L1_DEB_WARN)
125  debugl1(cs, "isac_empty_fifo overrun %d",
126  cs->rcvidx + count);
127  cs->writeisac(cs, ISAC_CMDR, 0x80);
128  cs->rcvidx = 0;
129  return;
130  }
131  ptr = cs->rcvbuf + cs->rcvidx;
132  cs->rcvidx += count;
133  cs->readisacfifo(cs, ptr, count);
134  cs->writeisac(cs, ISAC_CMDR, 0x80);
135  if (cs->debug & L1_DEB_ISAC_FIFO) {
136  char *t = cs->dlog;
137 
138  t += sprintf(t, "isac_empty_fifo cnt %d", count);
139  QuickHex(t, ptr, count);
140  debugl1(cs, cs->dlog);
141  }
142 }
143 
144 static void
145 isac_fill_fifo(struct IsdnCardState *cs)
146 {
147  int count, more;
148  u_char *ptr;
149 
150  if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
151  debugl1(cs, "isac_fill_fifo");
152 
153  if (!cs->tx_skb)
154  return;
155 
156  count = cs->tx_skb->len;
157  if (count <= 0)
158  return;
159 
160  more = 0;
161  if (count > 32) {
162  more = !0;
163  count = 32;
164  }
165  ptr = cs->tx_skb->data;
166  skb_pull(cs->tx_skb, count);
167  cs->tx_cnt += count;
168  cs->writeisacfifo(cs, ptr, count);
169  cs->writeisac(cs, ISAC_CMDR, more ? 0x8 : 0xa);
170  if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
171  debugl1(cs, "isac_fill_fifo dbusytimer running");
172  del_timer(&cs->dbusytimer);
173  }
174  init_timer(&cs->dbusytimer);
175  cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
176  add_timer(&cs->dbusytimer);
177  if (cs->debug & L1_DEB_ISAC_FIFO) {
178  char *t = cs->dlog;
179 
180  t += sprintf(t, "isac_fill_fifo cnt %d", count);
181  QuickHex(t, ptr, count);
182  debugl1(cs, cs->dlog);
183  }
184 }
185 
186 void
187 isac_interrupt(struct IsdnCardState *cs, u_char val)
188 {
189  u_char exval, v1;
190  struct sk_buff *skb;
191  unsigned int count;
192 
193  if (cs->debug & L1_DEB_ISAC)
194  debugl1(cs, "ISAC interrupt %x", val);
195  if (val & 0x80) { /* RME */
196  exval = cs->readisac(cs, ISAC_RSTA);
197  if ((exval & 0x70) != 0x20) {
198  if (exval & 0x40) {
199  if (cs->debug & L1_DEB_WARN)
200  debugl1(cs, "ISAC RDO");
201 #ifdef ERROR_STATISTIC
202  cs->err_rx++;
203 #endif
204  }
205  if (!(exval & 0x20)) {
206  if (cs->debug & L1_DEB_WARN)
207  debugl1(cs, "ISAC CRC error");
208 #ifdef ERROR_STATISTIC
209  cs->err_crc++;
210 #endif
211  }
212  cs->writeisac(cs, ISAC_CMDR, 0x80);
213  } else {
214  count = cs->readisac(cs, ISAC_RBCL) & 0x1f;
215  if (count == 0)
216  count = 32;
217  isac_empty_fifo(cs, count);
218  if ((count = cs->rcvidx) > 0) {
219  cs->rcvidx = 0;
220  if (!(skb = alloc_skb(count, GFP_ATOMIC)))
221  printk(KERN_WARNING "HiSax: D receive out of memory\n");
222  else {
223  memcpy(skb_put(skb, count), cs->rcvbuf, count);
224  skb_queue_tail(&cs->rq, skb);
225  }
226  }
227  }
228  cs->rcvidx = 0;
230  }
231  if (val & 0x40) { /* RPF */
232  isac_empty_fifo(cs, 32);
233  }
234  if (val & 0x20) { /* RSC */
235  /* never */
236  if (cs->debug & L1_DEB_WARN)
237  debugl1(cs, "ISAC RSC interrupt");
238  }
239  if (val & 0x10) { /* XPR */
240  if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
241  del_timer(&cs->dbusytimer);
242  if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
244  if (cs->tx_skb) {
245  if (cs->tx_skb->len) {
246  isac_fill_fifo(cs);
247  goto afterXPR;
248  } else {
249  dev_kfree_skb_irq(cs->tx_skb);
250  cs->tx_cnt = 0;
251  cs->tx_skb = NULL;
252  }
253  }
254  if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
255  cs->tx_cnt = 0;
256  isac_fill_fifo(cs);
257  } else
259  }
260 afterXPR:
261  if (val & 0x04) { /* CISQ */
262  exval = cs->readisac(cs, ISAC_CIR0);
263  if (cs->debug & L1_DEB_ISAC)
264  debugl1(cs, "ISAC CIR0 %02X", exval);
265  if (exval & 2) {
266  cs->dc.isac.ph_state = (exval >> 2) & 0xf;
267  if (cs->debug & L1_DEB_ISAC)
268  debugl1(cs, "ph_state change %x", cs->dc.isac.ph_state);
270  }
271  if (exval & 1) {
272  exval = cs->readisac(cs, ISAC_CIR1);
273  if (cs->debug & L1_DEB_ISAC)
274  debugl1(cs, "ISAC CIR1 %02X", exval);
275  }
276  }
277  if (val & 0x02) { /* SIN */
278  /* never */
279  if (cs->debug & L1_DEB_WARN)
280  debugl1(cs, "ISAC SIN interrupt");
281  }
282  if (val & 0x01) { /* EXI */
283  exval = cs->readisac(cs, ISAC_EXIR);
284  if (cs->debug & L1_DEB_WARN)
285  debugl1(cs, "ISAC EXIR %02x", exval);
286  if (exval & 0x80) { /* XMR */
287  debugl1(cs, "ISAC XMR");
288  printk(KERN_WARNING "HiSax: ISAC XMR\n");
289  }
290  if (exval & 0x40) { /* XDU */
291  debugl1(cs, "ISAC XDU");
292  printk(KERN_WARNING "HiSax: ISAC XDU\n");
293 #ifdef ERROR_STATISTIC
294  cs->err_tx++;
295 #endif
296  if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
297  del_timer(&cs->dbusytimer);
298  if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
300  if (cs->tx_skb) { /* Restart frame */
301  skb_push(cs->tx_skb, cs->tx_cnt);
302  cs->tx_cnt = 0;
303  isac_fill_fifo(cs);
304  } else {
305  printk(KERN_WARNING "HiSax: ISAC XDU no skb\n");
306  debugl1(cs, "ISAC XDU no skb");
307  }
308  }
309  if (exval & 0x04) { /* MOS */
310  v1 = cs->readisac(cs, ISAC_MOSR);
311  if (cs->debug & L1_DEB_MONITOR)
312  debugl1(cs, "ISAC MOSR %02x", v1);
313 #if ARCOFI_USE
314  if (v1 & 0x08) {
315  if (!cs->dc.isac.mon_rx) {
316  if (!(cs->dc.isac.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
317  if (cs->debug & L1_DEB_WARN)
318  debugl1(cs, "ISAC MON RX out of memory!");
319  cs->dc.isac.mocr &= 0xf0;
320  cs->dc.isac.mocr |= 0x0a;
321  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
322  goto afterMONR0;
323  } else
324  cs->dc.isac.mon_rxp = 0;
325  }
326  if (cs->dc.isac.mon_rxp >= MAX_MON_FRAME) {
327  cs->dc.isac.mocr &= 0xf0;
328  cs->dc.isac.mocr |= 0x0a;
329  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
330  cs->dc.isac.mon_rxp = 0;
331  if (cs->debug & L1_DEB_WARN)
332  debugl1(cs, "ISAC MON RX overflow!");
333  goto afterMONR0;
334  }
335  cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp++] = cs->readisac(cs, ISAC_MOR0);
336  if (cs->debug & L1_DEB_MONITOR)
337  debugl1(cs, "ISAC MOR0 %02x", cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp - 1]);
338  if (cs->dc.isac.mon_rxp == 1) {
339  cs->dc.isac.mocr |= 0x04;
340  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
341  }
342  }
343  afterMONR0:
344  if (v1 & 0x80) {
345  if (!cs->dc.isac.mon_rx) {
346  if (!(cs->dc.isac.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
347  if (cs->debug & L1_DEB_WARN)
348  debugl1(cs, "ISAC MON RX out of memory!");
349  cs->dc.isac.mocr &= 0x0f;
350  cs->dc.isac.mocr |= 0xa0;
351  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
352  goto afterMONR1;
353  } else
354  cs->dc.isac.mon_rxp = 0;
355  }
356  if (cs->dc.isac.mon_rxp >= MAX_MON_FRAME) {
357  cs->dc.isac.mocr &= 0x0f;
358  cs->dc.isac.mocr |= 0xa0;
359  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
360  cs->dc.isac.mon_rxp = 0;
361  if (cs->debug & L1_DEB_WARN)
362  debugl1(cs, "ISAC MON RX overflow!");
363  goto afterMONR1;
364  }
365  cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp++] = cs->readisac(cs, ISAC_MOR1);
366  if (cs->debug & L1_DEB_MONITOR)
367  debugl1(cs, "ISAC MOR1 %02x", cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp - 1]);
368  cs->dc.isac.mocr |= 0x40;
369  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
370  }
371  afterMONR1:
372  if (v1 & 0x04) {
373  cs->dc.isac.mocr &= 0xf0;
374  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
375  cs->dc.isac.mocr |= 0x0a;
376  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
378  }
379  if (v1 & 0x40) {
380  cs->dc.isac.mocr &= 0x0f;
381  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
382  cs->dc.isac.mocr |= 0xa0;
383  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
385  }
386  if (v1 & 0x02) {
387  if ((!cs->dc.isac.mon_tx) || (cs->dc.isac.mon_txc &&
388  (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc) &&
389  !(v1 & 0x08))) {
390  cs->dc.isac.mocr &= 0xf0;
391  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
392  cs->dc.isac.mocr |= 0x0a;
393  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
394  if (cs->dc.isac.mon_txc &&
395  (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc))
397  goto AfterMOX0;
398  }
399  if (cs->dc.isac.mon_txc && (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc)) {
401  goto AfterMOX0;
402  }
403  cs->writeisac(cs, ISAC_MOX0,
404  cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]);
405  if (cs->debug & L1_DEB_MONITOR)
406  debugl1(cs, "ISAC %02x -> MOX0", cs->dc.isac.mon_tx[cs->dc.isac.mon_txp - 1]);
407  }
408  AfterMOX0:
409  if (v1 & 0x20) {
410  if ((!cs->dc.isac.mon_tx) || (cs->dc.isac.mon_txc &&
411  (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc) &&
412  !(v1 & 0x80))) {
413  cs->dc.isac.mocr &= 0x0f;
414  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
415  cs->dc.isac.mocr |= 0xa0;
416  cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
417  if (cs->dc.isac.mon_txc &&
418  (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc))
420  goto AfterMOX1;
421  }
422  if (cs->dc.isac.mon_txc && (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc)) {
424  goto AfterMOX1;
425  }
426  cs->writeisac(cs, ISAC_MOX1,
427  cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]);
428  if (cs->debug & L1_DEB_MONITOR)
429  debugl1(cs, "ISAC %02x -> MOX1", cs->dc.isac.mon_tx[cs->dc.isac.mon_txp - 1]);
430  }
431  AfterMOX1:;
432 #endif
433  }
434  }
435 }
436 
437 static void
438 ISAC_l1hw(struct PStack *st, int pr, void *arg)
439 {
440  struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
441  struct sk_buff *skb = arg;
442  u_long flags;
443  int val;
444 
445  switch (pr) {
446  case (PH_DATA | REQUEST):
447  if (cs->debug & DEB_DLOG_HEX)
448  LogFrame(cs, skb->data, skb->len);
449  if (cs->debug & DEB_DLOG_VERBOSE)
450  dlogframe(cs, skb, 0);
451  spin_lock_irqsave(&cs->lock, flags);
452  if (cs->tx_skb) {
453  skb_queue_tail(&cs->sq, skb);
454 #ifdef L2FRAME_DEBUG /* psa */
455  if (cs->debug & L1_DEB_LAPD)
456  Logl2Frame(cs, skb, "PH_DATA Queued", 0);
457 #endif
458  } else {
459  cs->tx_skb = skb;
460  cs->tx_cnt = 0;
461 #ifdef L2FRAME_DEBUG /* psa */
462  if (cs->debug & L1_DEB_LAPD)
463  Logl2Frame(cs, skb, "PH_DATA", 0);
464 #endif
465  isac_fill_fifo(cs);
466  }
467  spin_unlock_irqrestore(&cs->lock, flags);
468  break;
469  case (PH_PULL | INDICATION):
470  spin_lock_irqsave(&cs->lock, flags);
471  if (cs->tx_skb) {
472  if (cs->debug & L1_DEB_WARN)
473  debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
474  skb_queue_tail(&cs->sq, skb);
475  } else {
476  if (cs->debug & DEB_DLOG_HEX)
477  LogFrame(cs, skb->data, skb->len);
478  if (cs->debug & DEB_DLOG_VERBOSE)
479  dlogframe(cs, skb, 0);
480  cs->tx_skb = skb;
481  cs->tx_cnt = 0;
482 #ifdef L2FRAME_DEBUG /* psa */
483  if (cs->debug & L1_DEB_LAPD)
484  Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
485 #endif
486  isac_fill_fifo(cs);
487  }
488  spin_unlock_irqrestore(&cs->lock, flags);
489  break;
490  case (PH_PULL | REQUEST):
491 #ifdef L2FRAME_DEBUG /* psa */
492  if (cs->debug & L1_DEB_LAPD)
493  debugl1(cs, "-> PH_REQUEST_PULL");
494 #endif
495  if (!cs->tx_skb) {
496  test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
497  st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
498  } else
499  test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
500  break;
501  case (HW_RESET | REQUEST):
502  spin_lock_irqsave(&cs->lock, flags);
503  if ((cs->dc.isac.ph_state == ISAC_IND_EI) ||
504  (cs->dc.isac.ph_state == ISAC_IND_DR) ||
505  (cs->dc.isac.ph_state == ISAC_IND_RS))
506  ph_command(cs, ISAC_CMD_TIM);
507  else
508  ph_command(cs, ISAC_CMD_RS);
509  spin_unlock_irqrestore(&cs->lock, flags);
510  break;
511  case (HW_ENABLE | REQUEST):
512  spin_lock_irqsave(&cs->lock, flags);
513  ph_command(cs, ISAC_CMD_TIM);
514  spin_unlock_irqrestore(&cs->lock, flags);
515  break;
516  case (HW_INFO3 | REQUEST):
517  spin_lock_irqsave(&cs->lock, flags);
518  ph_command(cs, ISAC_CMD_AR8);
519  spin_unlock_irqrestore(&cs->lock, flags);
520  break;
521  case (HW_TESTLOOP | REQUEST):
522  spin_lock_irqsave(&cs->lock, flags);
523  val = 0;
524  if (1 & (long) arg)
525  val |= 0x0c;
526  if (2 & (long) arg)
527  val |= 0x3;
528  if (test_bit(HW_IOM1, &cs->HW_Flags)) {
529  /* IOM 1 Mode */
530  if (!val) {
531  cs->writeisac(cs, ISAC_SPCR, 0xa);
532  cs->writeisac(cs, ISAC_ADF1, 0x2);
533  } else {
534  cs->writeisac(cs, ISAC_SPCR, val);
535  cs->writeisac(cs, ISAC_ADF1, 0xa);
536  }
537  } else {
538  /* IOM 2 Mode */
539  cs->writeisac(cs, ISAC_SPCR, val);
540  if (val)
541  cs->writeisac(cs, ISAC_ADF1, 0x8);
542  else
543  cs->writeisac(cs, ISAC_ADF1, 0x0);
544  }
545  spin_unlock_irqrestore(&cs->lock, flags);
546  break;
547  case (HW_DEACTIVATE | RESPONSE):
548  skb_queue_purge(&cs->rq);
549  skb_queue_purge(&cs->sq);
550  if (cs->tx_skb) {
551  dev_kfree_skb_any(cs->tx_skb);
552  cs->tx_skb = NULL;
553  }
554  if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
555  del_timer(&cs->dbusytimer);
556  if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
558  break;
559  default:
560  if (cs->debug & L1_DEB_WARN)
561  debugl1(cs, "isac_l1hw unknown %04x", pr);
562  break;
563  }
564 }
565 
566 static void
567 setstack_isac(struct PStack *st, struct IsdnCardState *cs)
568 {
569  st->l1.l1hw = ISAC_l1hw;
570 }
571 
572 static void
573 DC_Close_isac(struct IsdnCardState *cs)
574 {
575  kfree(cs->dc.isac.mon_rx);
576  cs->dc.isac.mon_rx = NULL;
577  kfree(cs->dc.isac.mon_tx);
578  cs->dc.isac.mon_tx = NULL;
579 }
580 
581 static void
582 dbusy_timer_handler(struct IsdnCardState *cs)
583 {
584  struct PStack *stptr;
585  int rbch, star;
586 
587  if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
588  rbch = cs->readisac(cs, ISAC_RBCH);
589  star = cs->readisac(cs, ISAC_STAR);
590  if (cs->debug)
591  debugl1(cs, "D-Channel Busy RBCH %02x STAR %02x",
592  rbch, star);
593  if (rbch & ISAC_RBCH_XAC) { /* D-Channel Busy */
594  test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
595  stptr = cs->stlist;
596  while (stptr != NULL) {
597  stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL);
598  stptr = stptr->next;
599  }
600  } else {
601  /* discard frame; reset transceiver */
602  test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
603  if (cs->tx_skb) {
604  dev_kfree_skb_any(cs->tx_skb);
605  cs->tx_cnt = 0;
606  cs->tx_skb = NULL;
607  } else {
608  printk(KERN_WARNING "HiSax: ISAC D-Channel Busy no skb\n");
609  debugl1(cs, "D-Channel Busy no skb");
610  }
611  cs->writeisac(cs, ISAC_CMDR, 0x01); /* Transmitter reset */
612  cs->irq_func(cs->irq, cs);
613  }
614  }
615 }
616 
617 void initisac(struct IsdnCardState *cs)
618 {
619  cs->setstack_d = setstack_isac;
620  cs->DC_Close = DC_Close_isac;
621  cs->dc.isac.mon_tx = NULL;
622  cs->dc.isac.mon_rx = NULL;
623  cs->writeisac(cs, ISAC_MASK, 0xff);
624  cs->dc.isac.mocr = 0xaa;
625  if (test_bit(HW_IOM1, &cs->HW_Flags)) {
626  /* IOM 1 Mode */
627  cs->writeisac(cs, ISAC_ADF2, 0x0);
628  cs->writeisac(cs, ISAC_SPCR, 0xa);
629  cs->writeisac(cs, ISAC_ADF1, 0x2);
630  cs->writeisac(cs, ISAC_STCR, 0x70);
631  cs->writeisac(cs, ISAC_MODE, 0xc9);
632  } else {
633  /* IOM 2 Mode */
634  if (!cs->dc.isac.adf2)
635  cs->dc.isac.adf2 = 0x80;
636  cs->writeisac(cs, ISAC_ADF2, cs->dc.isac.adf2);
637  cs->writeisac(cs, ISAC_SQXR, 0x2f);
638  cs->writeisac(cs, ISAC_SPCR, 0x00);
639  cs->writeisac(cs, ISAC_STCR, 0x70);
640  cs->writeisac(cs, ISAC_MODE, 0xc9);
641  cs->writeisac(cs, ISAC_TIMR, 0x00);
642  cs->writeisac(cs, ISAC_ADF1, 0x00);
643  }
644  ph_command(cs, ISAC_CMD_RS);
645  cs->writeisac(cs, ISAC_MASK, 0x0);
646 }
647 
648 void clear_pending_isac_ints(struct IsdnCardState *cs)
649 {
650  int val, eval;
651 
652  val = cs->readisac(cs, ISAC_STAR);
653  debugl1(cs, "ISAC STAR %x", val);
654  val = cs->readisac(cs, ISAC_MODE);
655  debugl1(cs, "ISAC MODE %x", val);
656  val = cs->readisac(cs, ISAC_ADF2);
657  debugl1(cs, "ISAC ADF2 %x", val);
658  val = cs->readisac(cs, ISAC_ISTA);
659  debugl1(cs, "ISAC ISTA %x", val);
660  if (val & 0x01) {
661  eval = cs->readisac(cs, ISAC_EXIR);
662  debugl1(cs, "ISAC EXIR %x", eval);
663  }
664  val = cs->readisac(cs, ISAC_CIR0);
665  debugl1(cs, "ISAC CIR0 %x", val);
666  cs->dc.isac.ph_state = (val >> 2) & 0xf;
668  /* Disable all IRQ */
669  cs->writeisac(cs, ISAC_MASK, 0xFF);
670 }
671 
672 void __devinit
673 setup_isac(struct IsdnCardState *cs)
674 {
675  INIT_WORK(&cs->tqueue, isac_bh);
676  cs->dbusytimer.function = (void *) dbusy_timer_handler;
677  cs->dbusytimer.data = (long) cs;
678  init_timer(&cs->dbusytimer);
679 }