[PATCH] fix semaphore handling in __unregister_chrdev_region
[linux/fpc-iii.git] / drivers / isdn / hisax / ipacx.c
blob6485e232d86936f728ebb70be5957f929f654cdb
1 /*
3 * IPACX specific routines
5 * Author Joerg Petersohn
6 * Derived from hisax_isac.c, isac.c, hscx.c and others
7 *
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
12 #include <linux/kernel.h>
13 #include <linux/config.h>
14 #include <linux/init.h>
15 #include "hisax_if.h"
16 #include "hisax.h"
17 #include "isdnl1.h"
18 #include "ipacx.h"
20 #define DBUSY_TIMER_VALUE 80
21 #define TIMER3_VALUE 7000
22 #define MAX_DFRAME_LEN_L1 300
23 #define B_FIFO_SIZE 64
24 #define D_FIFO_SIZE 32
27 // ipacx interrupt mask values
28 #define _MASK_IMASK 0x2E // global mask
29 #define _MASKB_IMASK 0x0B
30 #define _MASKD_IMASK 0x03 // all on
32 //----------------------------------------------------------
33 // local function declarations
34 //----------------------------------------------------------
35 static void ph_command(struct IsdnCardState *cs, unsigned int command);
36 static inline void cic_int(struct IsdnCardState *cs);
37 static void dch_l2l1(struct PStack *st, int pr, void *arg);
38 static void dbusy_timer_handler(struct IsdnCardState *cs);
39 static void ipacx_new_ph(struct IsdnCardState *cs);
40 static void dch_bh(struct IsdnCardState *cs);
41 static void dch_empty_fifo(struct IsdnCardState *cs, int count);
42 static void dch_fill_fifo(struct IsdnCardState *cs);
43 static inline void dch_int(struct IsdnCardState *cs);
44 static void __devinit dch_setstack(struct PStack *st, struct IsdnCardState *cs);
45 static void __devinit dch_init(struct IsdnCardState *cs);
46 static void bch_l2l1(struct PStack *st, int pr, void *arg);
47 static void bch_empty_fifo(struct BCState *bcs, int count);
48 static void bch_fill_fifo(struct BCState *bcs);
49 static void bch_int(struct IsdnCardState *cs, u_char hscx);
50 static void bch_mode(struct BCState *bcs, int mode, int bc);
51 static void bch_close_state(struct BCState *bcs);
52 static int bch_open_state(struct IsdnCardState *cs, struct BCState *bcs);
53 static int bch_setstack(struct PStack *st, struct BCState *bcs);
54 static void __devinit bch_init(struct IsdnCardState *cs, int hscx);
55 static void __init clear_pending_ints(struct IsdnCardState *cs);
57 //----------------------------------------------------------
58 // Issue Layer 1 command to chip
59 //----------------------------------------------------------
60 static void
61 ph_command(struct IsdnCardState *cs, unsigned int command)
63 if (cs->debug &L1_DEB_ISAC)
64 debugl1(cs, "ph_command (%#x) in (%#x)", command,
65 cs->dc.isac.ph_state);
66 //###################################
67 // printk(KERN_INFO "ph_command (%#x)\n", command);
68 //###################################
69 cs->writeisac(cs, IPACX_CIX0, (command << 4) | 0x0E);
72 //----------------------------------------------------------
73 // Transceiver interrupt handler
74 //----------------------------------------------------------
75 static inline void
76 cic_int(struct IsdnCardState *cs)
78 u_char event;
80 event = cs->readisac(cs, IPACX_CIR0) >> 4;
81 if (cs->debug &L1_DEB_ISAC) debugl1(cs, "cic_int(event=%#x)", event);
82 //#########################################
83 // printk(KERN_INFO "cic_int(%x)\n", event);
84 //#########################################
85 cs->dc.isac.ph_state = event;
86 schedule_event(cs, D_L1STATECHANGE);
89 //==========================================================
90 // D channel functions
91 //==========================================================
93 //----------------------------------------------------------
94 // Command entry point
95 //----------------------------------------------------------
96 static void
97 dch_l2l1(struct PStack *st, int pr, void *arg)
99 struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
100 struct sk_buff *skb = arg;
101 u_char cda1_cr, cda2_cr;
103 switch (pr) {
104 case (PH_DATA |REQUEST):
105 if (cs->debug &DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len);
106 if (cs->debug &DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0);
107 if (cs->tx_skb) {
108 skb_queue_tail(&cs->sq, skb);
109 #ifdef L2FRAME_DEBUG
110 if (cs->debug &L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0);
111 #endif
112 } else {
113 cs->tx_skb = skb;
114 cs->tx_cnt = 0;
115 #ifdef L2FRAME_DEBUG
116 if (cs->debug &L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0);
117 #endif
118 dch_fill_fifo(cs);
120 break;
122 case (PH_PULL |INDICATION):
123 if (cs->tx_skb) {
124 if (cs->debug & L1_DEB_WARN)
125 debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
126 skb_queue_tail(&cs->sq, skb);
127 break;
129 if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len);
130 if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0);
131 cs->tx_skb = skb;
132 cs->tx_cnt = 0;
133 #ifdef L2FRAME_DEBUG
134 if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
135 #endif
136 dch_fill_fifo(cs);
137 break;
139 case (PH_PULL | REQUEST):
140 #ifdef L2FRAME_DEBUG
141 if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL");
142 #endif
143 if (!cs->tx_skb) {
144 clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
145 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
146 } else
147 set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
148 break;
150 case (HW_RESET | REQUEST):
151 case (HW_ENABLE | REQUEST):
152 if ((cs->dc.isac.ph_state == IPACX_IND_RES) ||
153 (cs->dc.isac.ph_state == IPACX_IND_DR) ||
154 (cs->dc.isac.ph_state == IPACX_IND_DC))
155 ph_command(cs, IPACX_CMD_TIM);
156 else
157 ph_command(cs, IPACX_CMD_RES);
158 break;
160 case (HW_INFO3 | REQUEST):
161 ph_command(cs, IPACX_CMD_AR8);
162 break;
164 case (HW_TESTLOOP | REQUEST):
165 cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1
166 cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1
167 cda1_cr = cs->readisac(cs, IPACX_CDA1_CR);
168 cda2_cr = cs->readisac(cs, IPACX_CDA2_CR);
169 if ((long)arg &1) { // loop B1
170 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x0a);
172 else { // B1 off
173 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr &~0x0a);
175 if ((long)arg &2) { // loop B2
176 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x14);
178 else { // B2 off
179 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr &~0x14);
181 break;
183 case (HW_DEACTIVATE | RESPONSE):
184 skb_queue_purge(&cs->rq);
185 skb_queue_purge(&cs->sq);
186 if (cs->tx_skb) {
187 dev_kfree_skb_any(cs->tx_skb);
188 cs->tx_skb = NULL;
190 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
191 del_timer(&cs->dbusytimer);
192 break;
194 default:
195 if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_l2l1 unknown %04x", pr);
196 break;
200 //----------------------------------------------------------
201 //----------------------------------------------------------
202 static void
203 dbusy_timer_handler(struct IsdnCardState *cs)
205 struct PStack *st;
206 int rbchd, stard;
208 if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
209 rbchd = cs->readisac(cs, IPACX_RBCHD);
210 stard = cs->readisac(cs, IPACX_STARD);
211 if (cs->debug)
212 debugl1(cs, "D-Channel Busy RBCHD %02x STARD %02x", rbchd, stard);
213 if (!(stard &0x40)) { // D-Channel Busy
214 set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
215 for (st = cs->stlist; st; st = st->next) {
216 st->l1.l1l2(st, PH_PAUSE | INDICATION, NULL); // flow control on
218 } else {
219 // seems we lost an interrupt; reset transceiver */
220 clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
221 if (cs->tx_skb) {
222 dev_kfree_skb_any(cs->tx_skb);
223 cs->tx_cnt = 0;
224 cs->tx_skb = NULL;
225 } else {
226 printk(KERN_WARNING "HiSax: ISAC D-Channel Busy no skb\n");
227 debugl1(cs, "D-Channel Busy no skb");
229 cs->writeisac(cs, IPACX_CMDRD, 0x01); // Tx reset, generates XPR
234 //----------------------------------------------------------
235 // L1 state machine intermediate layer to isdnl1 module
236 //----------------------------------------------------------
237 static void
238 ipacx_new_ph(struct IsdnCardState *cs)
240 switch (cs->dc.isac.ph_state) {
241 case (IPACX_IND_RES):
242 ph_command(cs, IPACX_CMD_DI);
243 l1_msg(cs, HW_RESET | INDICATION, NULL);
244 break;
246 case (IPACX_IND_DC):
247 l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
248 break;
250 case (IPACX_IND_DR):
251 l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
252 break;
254 case (IPACX_IND_PU):
255 l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
256 break;
258 case (IPACX_IND_RSY):
259 l1_msg(cs, HW_RSYNC | INDICATION, NULL);
260 break;
262 case (IPACX_IND_AR):
263 l1_msg(cs, HW_INFO2 | INDICATION, NULL);
264 break;
266 case (IPACX_IND_AI8):
267 l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
268 break;
270 case (IPACX_IND_AI10):
271 l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
272 break;
274 default:
275 break;
279 //----------------------------------------------------------
280 // bottom half handler for D channel
281 //----------------------------------------------------------
282 static void
283 dch_bh(struct IsdnCardState *cs)
285 struct PStack *st;
287 if (!cs) return;
289 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
290 if (cs->debug) debugl1(cs, "D-Channel Busy cleared");
291 for (st = cs->stlist; st; st = st->next) {
292 st->l1.l1l2(st, PH_PAUSE | CONFIRM, NULL);
296 if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) {
297 DChannel_proc_rcv(cs);
300 if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) {
301 DChannel_proc_xmt(cs);
304 if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
305 ipacx_new_ph(cs);
309 //----------------------------------------------------------
310 // Fill buffer from receive FIFO
311 //----------------------------------------------------------
312 static void
313 dch_empty_fifo(struct IsdnCardState *cs, int count)
315 u_char *ptr;
317 if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO))
318 debugl1(cs, "dch_empty_fifo()");
320 // message too large, remove
321 if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
322 if (cs->debug &L1_DEB_WARN)
323 debugl1(cs, "dch_empty_fifo() incoming message too large");
324 cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC
325 cs->rcvidx = 0;
326 return;
329 ptr = cs->rcvbuf + cs->rcvidx;
330 cs->rcvidx += count;
332 cs->readisacfifo(cs, ptr, count);
333 cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC
335 if (cs->debug &L1_DEB_ISAC_FIFO) {
336 char *t = cs->dlog;
338 t += sprintf(t, "dch_empty_fifo() cnt %d", count);
339 QuickHex(t, ptr, count);
340 debugl1(cs, cs->dlog);
344 //----------------------------------------------------------
345 // Fill transmit FIFO
346 //----------------------------------------------------------
347 static void
348 dch_fill_fifo(struct IsdnCardState *cs)
350 int count;
351 u_char cmd, *ptr;
353 if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO))
354 debugl1(cs, "dch_fill_fifo()");
356 if (!cs->tx_skb) return;
357 count = cs->tx_skb->len;
358 if (count <= 0) return;
360 if (count > D_FIFO_SIZE) {
361 count = D_FIFO_SIZE;
362 cmd = 0x08; // XTF
363 } else {
364 cmd = 0x0A; // XTF | XME
367 ptr = cs->tx_skb->data;
368 skb_pull(cs->tx_skb, count);
369 cs->tx_cnt += count;
370 cs->writeisacfifo(cs, ptr, count);
371 cs->writeisac(cs, IPACX_CMDRD, cmd);
373 // set timeout for transmission contol
374 if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
375 debugl1(cs, "dch_fill_fifo dbusytimer running");
376 del_timer(&cs->dbusytimer);
378 init_timer(&cs->dbusytimer);
379 cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
380 add_timer(&cs->dbusytimer);
382 if (cs->debug &L1_DEB_ISAC_FIFO) {
383 char *t = cs->dlog;
385 t += sprintf(t, "dch_fill_fifo() cnt %d", count);
386 QuickHex(t, ptr, count);
387 debugl1(cs, cs->dlog);
391 //----------------------------------------------------------
392 // D channel interrupt handler
393 //----------------------------------------------------------
394 static inline void
395 dch_int(struct IsdnCardState *cs)
397 struct sk_buff *skb;
398 u_char istad, rstad;
399 int count;
401 istad = cs->readisac(cs, IPACX_ISTAD);
402 //##############################################
403 // printk(KERN_WARNING "dch_int(istad=%02x)\n", istad);
404 //##############################################
406 if (istad &0x80) { // RME
407 rstad = cs->readisac(cs, IPACX_RSTAD);
408 if ((rstad &0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
409 if (!(rstad &0x80))
410 if (cs->debug &L1_DEB_WARN)
411 debugl1(cs, "dch_int(): invalid frame");
412 if ((rstad &0x40))
413 if (cs->debug &L1_DEB_WARN)
414 debugl1(cs, "dch_int(): RDO");
415 if (!(rstad &0x20))
416 if (cs->debug &L1_DEB_WARN)
417 debugl1(cs, "dch_int(): CRC error");
418 cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC
419 } else { // received frame ok
420 count = cs->readisac(cs, IPACX_RBCLD);
421 if (count) count--; // RSTAB is last byte
422 count &= D_FIFO_SIZE-1;
423 if (count == 0) count = D_FIFO_SIZE;
424 dch_empty_fifo(cs, count);
425 if ((count = cs->rcvidx) > 0) {
426 cs->rcvidx = 0;
427 if (!(skb = dev_alloc_skb(count)))
428 printk(KERN_WARNING "HiSax dch_int(): receive out of memory\n");
429 else {
430 memcpy(skb_put(skb, count), cs->rcvbuf, count);
431 skb_queue_tail(&cs->rq, skb);
435 cs->rcvidx = 0;
436 schedule_event(cs, D_RCVBUFREADY);
439 if (istad &0x40) { // RPF
440 dch_empty_fifo(cs, D_FIFO_SIZE);
443 if (istad &0x20) { // RFO
444 if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): RFO");
445 cs->writeisac(cs, IPACX_CMDRD, 0x40); //RRES
448 if (istad &0x10) { // XPR
449 if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
450 del_timer(&cs->dbusytimer);
451 if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
452 schedule_event(cs, D_CLEARBUSY);
453 if (cs->tx_skb) {
454 if (cs->tx_skb->len) {
455 dch_fill_fifo(cs);
456 goto afterXPR;
458 else {
459 dev_kfree_skb_irq(cs->tx_skb);
460 cs->tx_skb = NULL;
461 cs->tx_cnt = 0;
464 if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
465 cs->tx_cnt = 0;
466 dch_fill_fifo(cs);
468 else {
469 schedule_event(cs, D_XMTBUFREADY);
472 afterXPR:
474 if (istad &0x0C) { // XDU or XMR
475 if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): XDU");
476 if (cs->tx_skb) {
477 skb_push(cs->tx_skb, cs->tx_cnt); // retransmit
478 cs->tx_cnt = 0;
479 dch_fill_fifo(cs);
480 } else {
481 printk(KERN_WARNING "HiSax: ISAC XDU no skb\n");
482 debugl1(cs, "ISAC XDU no skb");
487 //----------------------------------------------------------
488 //----------------------------------------------------------
489 static void __devinit
490 dch_setstack(struct PStack *st, struct IsdnCardState *cs)
492 st->l1.l1hw = dch_l2l1;
495 //----------------------------------------------------------
496 //----------------------------------------------------------
497 static void __devinit
498 dch_init(struct IsdnCardState *cs)
500 printk(KERN_INFO "HiSax: IPACX ISDN driver v0.1.0\n");
502 cs->setstack_d = dch_setstack;
504 cs->dbusytimer.function = (void *) dbusy_timer_handler;
505 cs->dbusytimer.data = (long) cs;
506 init_timer(&cs->dbusytimer);
508 cs->writeisac(cs, IPACX_TR_CONF0, 0x00); // clear LDD
509 cs->writeisac(cs, IPACX_TR_CONF2, 0x00); // enable transmitter
510 cs->writeisac(cs, IPACX_MODED, 0xC9); // transparent mode 0, RAC, stop/go
511 cs->writeisac(cs, IPACX_MON_CR, 0x00); // disable monitor channel
515 //==========================================================
516 // B channel functions
517 //==========================================================
519 //----------------------------------------------------------
520 // Entry point for commands
521 //----------------------------------------------------------
522 static void
523 bch_l2l1(struct PStack *st, int pr, void *arg)
525 struct BCState *bcs = st->l1.bcs;
526 struct sk_buff *skb = arg;
527 u_long flags;
529 switch (pr) {
530 case (PH_DATA | REQUEST):
531 spin_lock_irqsave(&bcs->cs->lock, flags);
532 if (bcs->tx_skb) {
533 skb_queue_tail(&bcs->squeue, skb);
534 } else {
535 bcs->tx_skb = skb;
536 set_bit(BC_FLG_BUSY, &bcs->Flag);
537 bcs->hw.hscx.count = 0;
538 bch_fill_fifo(bcs);
540 spin_unlock_irqrestore(&bcs->cs->lock, flags);
541 break;
542 case (PH_PULL | INDICATION):
543 spin_lock_irqsave(&bcs->cs->lock, flags);
544 if (bcs->tx_skb) {
545 printk(KERN_WARNING "HiSax bch_l2l1(): this shouldn't happen\n");
546 } else {
547 set_bit(BC_FLG_BUSY, &bcs->Flag);
548 bcs->tx_skb = skb;
549 bcs->hw.hscx.count = 0;
550 bch_fill_fifo(bcs);
552 spin_unlock_irqrestore(&bcs->cs->lock, flags);
553 break;
554 case (PH_PULL | REQUEST):
555 if (!bcs->tx_skb) {
556 clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
557 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
558 } else
559 set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
560 break;
561 case (PH_ACTIVATE | REQUEST):
562 spin_lock_irqsave(&bcs->cs->lock, flags);
563 set_bit(BC_FLG_ACTIV, &bcs->Flag);
564 bch_mode(bcs, st->l1.mode, st->l1.bc);
565 spin_unlock_irqrestore(&bcs->cs->lock, flags);
566 l1_msg_b(st, pr, arg);
567 break;
568 case (PH_DEACTIVATE | REQUEST):
569 l1_msg_b(st, pr, arg);
570 break;
571 case (PH_DEACTIVATE | CONFIRM):
572 spin_lock_irqsave(&bcs->cs->lock, flags);
573 clear_bit(BC_FLG_ACTIV, &bcs->Flag);
574 clear_bit(BC_FLG_BUSY, &bcs->Flag);
575 bch_mode(bcs, 0, st->l1.bc);
576 spin_unlock_irqrestore(&bcs->cs->lock, flags);
577 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
578 break;
582 //----------------------------------------------------------
583 // Read B channel fifo to receive buffer
584 //----------------------------------------------------------
585 static void
586 bch_empty_fifo(struct BCState *bcs, int count)
588 u_char *ptr, hscx;
589 struct IsdnCardState *cs;
590 int cnt;
592 cs = bcs->cs;
593 hscx = bcs->hw.hscx.hscx;
594 if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO))
595 debugl1(cs, "bch_empty_fifo()");
597 // message too large, remove
598 if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) {
599 if (cs->debug &L1_DEB_WARN)
600 debugl1(cs, "bch_empty_fifo() incoming packet too large");
601 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC
602 bcs->hw.hscx.rcvidx = 0;
603 return;
606 ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
607 cnt = count;
608 while (cnt--) *ptr++ = cs->BC_Read_Reg(cs, hscx, IPACX_RFIFOB);
609 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC
611 ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
612 bcs->hw.hscx.rcvidx += count;
614 if (cs->debug &L1_DEB_HSCX_FIFO) {
615 char *t = bcs->blog;
617 t += sprintf(t, "bch_empty_fifo() B-%d cnt %d", hscx, count);
618 QuickHex(t, ptr, count);
619 debugl1(cs, bcs->blog);
623 //----------------------------------------------------------
624 // Fill buffer to transmit FIFO
625 //----------------------------------------------------------
626 static void
627 bch_fill_fifo(struct BCState *bcs)
629 struct IsdnCardState *cs;
630 int more, count, cnt;
631 u_char *ptr, *p, hscx;
633 cs = bcs->cs;
634 if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO))
635 debugl1(cs, "bch_fill_fifo()");
637 if (!bcs->tx_skb) return;
638 if (bcs->tx_skb->len <= 0) return;
640 hscx = bcs->hw.hscx.hscx;
641 more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0;
642 if (bcs->tx_skb->len > B_FIFO_SIZE) {
643 more = 1;
644 count = B_FIFO_SIZE;
645 } else {
646 count = bcs->tx_skb->len;
648 cnt = count;
650 p = ptr = bcs->tx_skb->data;
651 skb_pull(bcs->tx_skb, count);
652 bcs->tx_cnt -= count;
653 bcs->hw.hscx.count += count;
654 while (cnt--) cs->BC_Write_Reg(cs, hscx, IPACX_XFIFOB, *p++);
655 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, (more ? 0x08 : 0x0a));
657 if (cs->debug &L1_DEB_HSCX_FIFO) {
658 char *t = bcs->blog;
660 t += sprintf(t, "chb_fill_fifo() B-%d cnt %d", hscx, count);
661 QuickHex(t, ptr, count);
662 debugl1(cs, bcs->blog);
666 //----------------------------------------------------------
667 // B channel interrupt handler
668 //----------------------------------------------------------
669 static void
670 bch_int(struct IsdnCardState *cs, u_char hscx)
672 u_char istab;
673 struct BCState *bcs;
674 struct sk_buff *skb;
675 int count;
676 u_char rstab;
678 bcs = cs->bcs + hscx;
679 istab = cs->BC_Read_Reg(cs, hscx, IPACX_ISTAB);
680 //##############################################
681 // printk(KERN_WARNING "bch_int(istab=%02x)\n", istab);
682 //##############################################
683 if (!test_bit(BC_FLG_INIT, &bcs->Flag)) return;
685 if (istab &0x80) { // RME
686 rstab = cs->BC_Read_Reg(cs, hscx, IPACX_RSTAB);
687 if ((rstab &0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
688 if (!(rstab &0x80))
689 if (cs->debug &L1_DEB_WARN)
690 debugl1(cs, "bch_int() B-%d: invalid frame", hscx);
691 if ((rstab &0x40) && (bcs->mode != L1_MODE_NULL))
692 if (cs->debug &L1_DEB_WARN)
693 debugl1(cs, "bch_int() B-%d: RDO mode=%d", hscx, bcs->mode);
694 if (!(rstab &0x20))
695 if (cs->debug &L1_DEB_WARN)
696 debugl1(cs, "bch_int() B-%d: CRC error", hscx);
697 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80); // RMC
699 else { // received frame ok
700 count = cs->BC_Read_Reg(cs, hscx, IPACX_RBCLB) &(B_FIFO_SIZE-1);
701 if (count == 0) count = B_FIFO_SIZE;
702 bch_empty_fifo(bcs, count);
703 if ((count = bcs->hw.hscx.rcvidx - 1) > 0) {
704 if (cs->debug &L1_DEB_HSCX_FIFO)
705 debugl1(cs, "bch_int Frame %d", count);
706 if (!(skb = dev_alloc_skb(count)))
707 printk(KERN_WARNING "HiSax bch_int(): receive frame out of memory\n");
708 else {
709 memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count);
710 skb_queue_tail(&bcs->rqueue, skb);
714 bcs->hw.hscx.rcvidx = 0;
715 schedule_event(bcs, B_RCVBUFREADY);
718 if (istab &0x40) { // RPF
719 bch_empty_fifo(bcs, B_FIFO_SIZE);
721 if (bcs->mode == L1_MODE_TRANS) { // queue every chunk
722 // receive transparent audio data
723 if (!(skb = dev_alloc_skb(B_FIFO_SIZE)))
724 printk(KERN_WARNING "HiSax bch_int(): receive transparent out of memory\n");
725 else {
726 memcpy(skb_put(skb, B_FIFO_SIZE), bcs->hw.hscx.rcvbuf, B_FIFO_SIZE);
727 skb_queue_tail(&bcs->rqueue, skb);
729 bcs->hw.hscx.rcvidx = 0;
730 schedule_event(bcs, B_RCVBUFREADY);
734 if (istab &0x20) { // RFO
735 if (cs->debug &L1_DEB_WARN)
736 debugl1(cs, "bch_int() B-%d: RFO error", hscx);
737 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x40); // RRES
740 if (istab &0x10) { // XPR
741 if (bcs->tx_skb) {
742 if (bcs->tx_skb->len) {
743 bch_fill_fifo(bcs);
744 goto afterXPR;
745 } else {
746 if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
747 (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
748 u_long flags;
749 spin_lock_irqsave(&bcs->aclock, flags);
750 bcs->ackcnt += bcs->hw.hscx.count;
751 spin_unlock_irqrestore(&bcs->aclock, flags);
752 schedule_event(bcs, B_ACKPENDING);
755 dev_kfree_skb_irq(bcs->tx_skb);
756 bcs->hw.hscx.count = 0;
757 bcs->tx_skb = NULL;
759 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
760 bcs->hw.hscx.count = 0;
761 set_bit(BC_FLG_BUSY, &bcs->Flag);
762 bch_fill_fifo(bcs);
763 } else {
764 clear_bit(BC_FLG_BUSY, &bcs->Flag);
765 schedule_event(bcs, B_XMTBUFREADY);
768 afterXPR:
770 if (istab &0x04) { // XDU
771 if (bcs->mode == L1_MODE_TRANS) {
772 bch_fill_fifo(bcs);
774 else {
775 if (bcs->tx_skb) { // restart transmitting the whole frame
776 skb_push(bcs->tx_skb, bcs->hw.hscx.count);
777 bcs->tx_cnt += bcs->hw.hscx.count;
778 bcs->hw.hscx.count = 0;
780 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x01); // XRES
781 if (cs->debug &L1_DEB_WARN)
782 debugl1(cs, "bch_int() B-%d XDU error", hscx);
787 //----------------------------------------------------------
788 //----------------------------------------------------------
789 static void
790 bch_mode(struct BCState *bcs, int mode, int bc)
792 struct IsdnCardState *cs = bcs->cs;
793 int hscx = bcs->hw.hscx.hscx;
795 bc = bc ? 1 : 0; // in case bc is greater than 1
796 if (cs->debug & L1_DEB_HSCX)
797 debugl1(cs, "mode_bch() switch B-% mode %d chan %d", hscx, mode, bc);
798 bcs->mode = mode;
799 bcs->channel = bc;
801 // map controller to according timeslot
802 if (!hscx)
804 cs->writeisac(cs, IPACX_BCHA_TSDP_BC1, 0x80 | bc);
805 cs->writeisac(cs, IPACX_BCHA_CR, 0x88);
807 else
809 cs->writeisac(cs, IPACX_BCHB_TSDP_BC1, 0x80 | bc);
810 cs->writeisac(cs, IPACX_BCHB_CR, 0x88);
813 switch (mode) {
814 case (L1_MODE_NULL):
815 cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC0); // rec off
816 cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x30); // std adj.
817 cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, 0xFF); // ints off
818 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments
819 break;
820 case (L1_MODE_TRANS):
821 cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0x88); // ext transp mode
822 cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x00); // xxx00000
823 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments
824 cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK);
825 break;
826 case (L1_MODE_HDLC):
827 cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC8); // transp mode 0
828 cs->BC_Write_Reg(cs, hscx, IPACX_EXMB, 0x01); // idle=hdlc flags crc enabled
829 cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41); // validate adjustments
830 cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK);
831 break;
835 //----------------------------------------------------------
836 //----------------------------------------------------------
837 static void
838 bch_close_state(struct BCState *bcs)
840 bch_mode(bcs, 0, bcs->channel);
841 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
842 if (bcs->hw.hscx.rcvbuf) {
843 kfree(bcs->hw.hscx.rcvbuf);
844 bcs->hw.hscx.rcvbuf = NULL;
846 if (bcs->blog) {
847 kfree(bcs->blog);
848 bcs->blog = NULL;
850 skb_queue_purge(&bcs->rqueue);
851 skb_queue_purge(&bcs->squeue);
852 if (bcs->tx_skb) {
853 dev_kfree_skb_any(bcs->tx_skb);
854 bcs->tx_skb = NULL;
855 clear_bit(BC_FLG_BUSY, &bcs->Flag);
860 //----------------------------------------------------------
861 //----------------------------------------------------------
862 static int
863 bch_open_state(struct IsdnCardState *cs, struct BCState *bcs)
865 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
866 if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
867 printk(KERN_WARNING
868 "HiSax open_bchstate(): No memory for hscx.rcvbuf\n");
869 clear_bit(BC_FLG_INIT, &bcs->Flag);
870 return (1);
872 if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
873 printk(KERN_WARNING
874 "HiSax open_bchstate: No memory for bcs->blog\n");
875 clear_bit(BC_FLG_INIT, &bcs->Flag);
876 kfree(bcs->hw.hscx.rcvbuf);
877 bcs->hw.hscx.rcvbuf = NULL;
878 return (2);
880 skb_queue_head_init(&bcs->rqueue);
881 skb_queue_head_init(&bcs->squeue);
883 bcs->tx_skb = NULL;
884 clear_bit(BC_FLG_BUSY, &bcs->Flag);
885 bcs->event = 0;
886 bcs->hw.hscx.rcvidx = 0;
887 bcs->tx_cnt = 0;
888 return (0);
891 //----------------------------------------------------------
892 //----------------------------------------------------------
893 static int
894 bch_setstack(struct PStack *st, struct BCState *bcs)
896 bcs->channel = st->l1.bc;
897 if (bch_open_state(st->l1.hardware, bcs)) return (-1);
898 st->l1.bcs = bcs;
899 st->l2.l2l1 = bch_l2l1;
900 setstack_manager(st);
901 bcs->st = st;
902 setstack_l1_B(st);
903 return (0);
906 //----------------------------------------------------------
907 //----------------------------------------------------------
908 static void __devinit
909 bch_init(struct IsdnCardState *cs, int hscx)
911 cs->bcs[hscx].BC_SetStack = bch_setstack;
912 cs->bcs[hscx].BC_Close = bch_close_state;
913 cs->bcs[hscx].hw.hscx.hscx = hscx;
914 cs->bcs[hscx].cs = cs;
915 bch_mode(cs->bcs + hscx, 0, hscx);
919 //==========================================================
920 // Shared functions
921 //==========================================================
923 //----------------------------------------------------------
924 // Main interrupt handler
925 //----------------------------------------------------------
926 void
927 interrupt_ipacx(struct IsdnCardState *cs)
929 u_char ista;
931 while ((ista = cs->readisac(cs, IPACX_ISTA))) {
932 //#################################################
933 // printk(KERN_WARNING "interrupt_ipacx(ista=%02x)\n", ista);
934 //#################################################
935 if (ista &0x80) bch_int(cs, 0); // B channel interrupts
936 if (ista &0x40) bch_int(cs, 1);
938 if (ista &0x01) dch_int(cs); // D channel
939 if (ista &0x10) cic_int(cs); // Layer 1 state
943 //----------------------------------------------------------
944 // Clears chip interrupt status
945 //----------------------------------------------------------
946 static void __init
947 clear_pending_ints(struct IsdnCardState *cs)
949 int ista;
951 // all interrupts off
952 cs->writeisac(cs, IPACX_MASK, 0xff);
953 cs->writeisac(cs, IPACX_MASKD, 0xff);
954 cs->BC_Write_Reg(cs, 0, IPACX_MASKB, 0xff);
955 cs->BC_Write_Reg(cs, 1, IPACX_MASKB, 0xff);
957 ista = cs->readisac(cs, IPACX_ISTA);
958 if (ista &0x80) cs->BC_Read_Reg(cs, 0, IPACX_ISTAB);
959 if (ista &0x40) cs->BC_Read_Reg(cs, 1, IPACX_ISTAB);
960 if (ista &0x10) cs->readisac(cs, IPACX_CIR0);
961 if (ista &0x01) cs->readisac(cs, IPACX_ISTAD);
964 //----------------------------------------------------------
965 // Does chip configuration work
966 // Work to do depends on bit mask in part
967 //----------------------------------------------------------
968 void __init
969 init_ipacx(struct IsdnCardState *cs, int part)
971 if (part &1) { // initialise chip
972 //##################################################
973 // printk(KERN_INFO "init_ipacx(%x)\n", part);
974 //##################################################
975 clear_pending_ints(cs);
976 bch_init(cs, 0);
977 bch_init(cs, 1);
978 dch_init(cs);
980 if (part &2) { // reenable all interrupts and start chip
981 cs->BC_Write_Reg(cs, 0, IPACX_MASKB, _MASKB_IMASK);
982 cs->BC_Write_Reg(cs, 1, IPACX_MASKB, _MASKB_IMASK);
983 cs->writeisac(cs, IPACX_MASKD, _MASKD_IMASK);
984 cs->writeisac(cs, IPACX_MASK, _MASK_IMASK); // global mask register
986 // reset HDLC Transmitters/receivers
987 cs->writeisac(cs, IPACX_CMDRD, 0x41);
988 cs->BC_Write_Reg(cs, 0, IPACX_CMDRB, 0x41);
989 cs->BC_Write_Reg(cs, 1, IPACX_CMDRB, 0x41);
990 ph_command(cs, IPACX_CMD_RES);
995 void __devinit
996 setup_ipacx(struct IsdnCardState *cs)
998 INIT_WORK(&cs->tqueue, (void *)(void *) dch_bh, cs);
999 cs->dbusytimer.function = (void *) dbusy_timer_handler;
1000 cs->dbusytimer.data = (long) cs;
1001 init_timer(&cs->dbusytimer);
1003 //----------------- end of file -----------------------