Import 2.1.42pre1
[davej-history.git] / drivers / isdn / hisax / isdnl1.c
blob0dc0bb52098b8288675169edd0059149c8c219c9
1 /* $Id: isdnl1.c,v 1.15 1997/05/27 15:17:55 fritz Exp $
3 * isdnl1.c common low level stuff for Siemens Chipsetbased isdn cards
4 * based on the teles driver from Jan den Ouden
6 * Author Karsten Keil (keil@temic-ech.spacenet.de)
8 * Thanks to Jan den Ouden
9 * Fritz Elfert
10 * Beat Doebeli
13 * $Log: isdnl1.c,v $
14 * Revision 1.15 1997/05/27 15:17:55 fritz
15 * Added changes for recent 2.1.x kernels:
16 * changed return type of isdn_close
17 * queue_task_* -> queue_task
18 * clear/set_bit -> test_and_... where apropriate.
19 * changed type of hard_header_cache parameter.
21 * Revision 1.14 1997/04/07 23:00:08 keil
22 * GFP_KERNEL ---> GFP_ATOMIC
24 * Revision 1.13 1997/04/06 22:55:50 keil
25 * Using SKB's
27 * Revision 1.12 1997/03/26 13:43:57 keil
28 * small cosmetics
30 * Revision 1.11 1997/03/25 23:11:23 keil
31 * US NI-1 protocol
33 * Revision 1.10 1997/03/13 14:45:05 keil
34 * using IRQ proof queue_task
36 * Revision 1.9 1997/03/12 21:44:21 keil
37 * change Interrupt routine from atomic quick to normal
39 * Revision 1.8 1997/02/09 00:24:31 keil
40 * new interface handling, one interface per card
42 * Revision 1.7 1997/01/27 15:56:03 keil
43 * PCMCIA Teles card and ITK ix1 micro added
45 * Revision 1.6 1997/01/21 22:20:00 keil
46 * changes for D-channel log; Elsa Quickstep support
48 * Revision 1.5 1997/01/10 12:51:19 keil
49 * cleanup; set newversion
51 * Revision 1.4 1996/12/08 19:44:53 keil
52 * L2FRAME_DEBUG and other changes from Pekka Sarnila
54 * Revision 1.3 1996/11/18 15:34:47 keil
55 * fix HSCX version code
57 * Revision 1.2 1996/10/27 22:16:54 keil
58 * ISAC/HSCX version lookup
60 * Revision 1.1 1996/10/13 20:04:53 keil
61 * Initial revision
67 const char *l1_revision = "$Revision: 1.15 $";
69 #define __NO_VERSION__
70 #include <linux/config.h>
71 #include "hisax.h"
72 #include "isdnl1.h"
74 #if CARD_TELES0
75 #include "teles0.h"
76 #endif
78 #if CARD_TELES3
79 #include "teles3.h"
80 #endif
82 #if CARD_AVM_A1
83 #include "avm_a1.h"
84 #endif
86 #if CARD_ELSA
87 #include "elsa.h"
88 #endif
90 #if CARD_IX1MICROR2
91 #include "ix1_micro.h"
92 #endif
94 /* #define I4L_IRQ_FLAG SA_INTERRUPT */
95 #define I4L_IRQ_FLAG 0
97 #define HISAX_STATUS_BUFSIZE 4096
99 #define INCLUDE_INLINE_FUNCS
100 #include <linux/tqueue.h>
101 #include <linux/interrupt.h>
103 const char *CardType[] =
104 {"No Card", "Teles 16.0", "Teles 8.0", "Teles 16.3",
105 "Creatix/Teles PnP", "AVM A1", "Elsa ML",
106 #ifdef CONFIG_HISAX_ELSA_PCMCIA
107 "Elsa PCMCIA",
108 #else
109 "Elsa Quickstep",
110 #endif
111 "Teles PCMCIA", "ITK ix1-micro Rev.2"};
113 static char *HSCXVer[] =
114 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
115 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
117 static char *ISACVer[] =
118 {"2086/2186 V1.1", "2085 B1", "2085 B2",
119 "2085 V2.3"};
121 extern struct IsdnCard cards[];
122 extern int nrcards;
123 extern char *HiSax_id;
126 * Find card with given driverId
128 static inline struct IsdnCardState
130 hisax_findcard(int driverid)
132 int i;
134 for (i = 0; i < nrcards; i++)
135 if (cards[i].sp)
136 if (cards[i].sp->myid == driverid)
137 return (cards[i].sp);
138 return (struct IsdnCardState *) 0;
142 HiSax_readstatus(u_char * buf, int len, int user, int id, int channel)
144 int count;
145 u_char *p;
146 struct IsdnCardState *csta = hisax_findcard(id);
148 if (csta) {
149 for (p = buf, count = 0; count < len; p++, count++) {
150 if (user)
151 put_user(*csta->status_read++, p);
152 else
153 *p++ = *csta->status_read++;
154 if (csta->status_read > csta->status_end)
155 csta->status_read = csta->status_buf;
157 return count;
158 } else {
159 printk(KERN_ERR
160 "HiSax: if_readstatus called with invalid driverId!\n");
161 return -ENODEV;
165 void
166 HiSax_putstatus(struct IsdnCardState *csta, char *buf)
168 long flags;
169 int len, count, i;
170 u_char *p;
171 isdn_ctrl ic;
173 save_flags(flags);
174 cli();
175 count = 0;
176 len = strlen(buf);
178 if (!csta) {
179 printk(KERN_WARNING "HiSax: No CardStatus for message %s", buf);
180 restore_flags(flags);
181 return;
183 for (p = buf, i = len; i > 0; i--, p++) {
184 *csta->status_write++ = *p;
185 if (csta->status_write > csta->status_end)
186 csta->status_write = csta->status_buf;
187 count++;
189 restore_flags(flags);
190 if (count) {
191 ic.command = ISDN_STAT_STAVAIL;
192 ic.driver = csta->myid;
193 ic.arg = count;
194 csta->iif.statcallb(&ic);
199 ll_run(struct IsdnCardState *csta)
201 long flags;
202 isdn_ctrl ic;
204 save_flags(flags);
205 cli();
206 ic.driver = csta->myid;
207 ic.command = ISDN_STAT_RUN;
208 csta->iif.statcallb(&ic);
209 restore_flags(flags);
210 return 0;
213 void
214 ll_stop(struct IsdnCardState *csta)
216 isdn_ctrl ic;
218 ic.command = ISDN_STAT_STOP;
219 ic.driver = csta->myid;
220 csta->iif.statcallb(&ic);
221 CallcFreeChan(csta);
224 static void
225 ll_unload(struct IsdnCardState *csta)
227 isdn_ctrl ic;
229 ic.command = ISDN_STAT_UNLOAD;
230 ic.driver = csta->myid;
231 csta->iif.statcallb(&ic);
232 if (csta->status_buf)
233 kfree(csta->status_buf);
234 csta->status_read = NULL;
235 csta->status_write = NULL;
236 csta->status_end = NULL;
237 kfree(csta->dlogspace);
240 void
241 debugl1(struct IsdnCardState *sp, char *msg)
243 char tmp[256], tm[32];
245 jiftime(tm, jiffies);
246 sprintf(tmp, "%s Card %d %s\n", tm, sp->cardnr + 1, msg);
247 HiSax_putstatus(sp, tmp);
251 * HSCX stuff goes here
255 char *
256 HscxVersion(u_char v)
258 return (HSCXVer[v & 0xf]);
261 void
262 hscx_sched_event(struct HscxState *hsp, int event)
264 hsp->event |= 1 << event;
265 queue_task(&hsp->tqueue, &tq_immediate);
266 mark_bh(IMMEDIATE_BH);
270 * ISAC stuff goes here
273 char *
274 ISACVersion(u_char v)
276 return (ISACVer[(v >> 5) & 3]);
279 void
280 isac_sched_event(struct IsdnCardState *sp, int event)
282 sp->event |= 1 << event;
283 queue_task(&sp->tqueue, &tq_immediate);
284 mark_bh(IMMEDIATE_BH);
288 act_wanted(struct IsdnCardState *sp)
290 struct PStack *st;
292 st = sp->stlist;
293 while (st)
294 if (st->l1.act_state)
295 return (!0);
296 else
297 st = st->next;
298 return (0);
301 void
302 isac_new_ph(struct IsdnCardState *sp)
304 int enq;
306 enq = act_wanted(sp);
308 switch (sp->ph_state) {
309 case (6):
310 sp->ph_active = 0;
311 sp->ph_command(sp, 15);
312 break;
313 case (15):
314 sp->ph_active = 0;
315 if (enq)
316 sp->ph_command(sp, 0);
317 break;
318 case (0):
319 sp->ph_active = 0;
320 if (enq)
321 sp->ph_command(sp, 0);
322 #if 0
323 else
324 sp->ph_command(sp, 15);
325 #endif
326 break;
327 case (7):
328 sp->ph_active = 0;
329 if (enq)
330 sp->ph_command(sp, 9);
331 break;
332 case (12):
333 sp->ph_command(sp, 8);
334 sp->ph_active = 5;
335 isac_sched_event(sp, ISAC_PHCHANGE);
336 if (!sp->tx_skb)
337 sp->tx_skb = skb_dequeue(&sp->sq);
338 if (sp->tx_skb) {
339 sp->tx_cnt = 0;
340 sp->isac_fill_fifo(sp);
342 break;
343 case (13):
344 sp->ph_command(sp, 9);
345 sp->ph_active = 5;
346 isac_sched_event(sp, ISAC_PHCHANGE);
347 if (!sp->tx_skb)
348 sp->tx_skb = skb_dequeue(&sp->sq);
349 if (sp->tx_skb) {
350 sp->tx_cnt = 0;
351 sp->isac_fill_fifo(sp);
353 break;
354 case (4):
355 case (8):
356 sp->ph_active = 0;
357 break;
358 default:
359 sp->ph_active = 0;
360 break;
364 static void
365 restart_ph(struct IsdnCardState *sp)
367 if (!sp->ph_active) {
368 if ((sp->ph_state == 6) || (sp->ph_state == 0)) {
369 sp->ph_command(sp, 0);
370 sp->ph_active = 2;
371 } else {
372 sp->ph_command(sp, 1);
373 sp->ph_active = 1;
375 } else if (sp->ph_active == 2) {
376 sp->ph_command(sp, 1);
377 sp->ph_active = 1;
382 static void
383 act_ivated(struct IsdnCardState *sp)
385 struct PStack *st;
387 st = sp->stlist;
388 while (st) {
389 if (st->l1.act_state == 1) {
390 st->l1.act_state = 2;
391 st->l1.l1man(st, PH_ACTIVATE, NULL);
393 st = st->next;
397 static void
398 process_new_ph(struct IsdnCardState *sp)
400 if (sp->ph_active == 5)
401 act_ivated(sp);
404 static void
405 process_xmt(struct IsdnCardState *sp)
407 struct PStack *stptr;
409 if (sp->tx_skb)
410 return;
412 stptr = sp->stlist;
413 while (stptr != NULL)
414 if (stptr->l1.requestpull) {
415 stptr->l1.requestpull = 0;
416 stptr->l1.l1l2(stptr, PH_PULL_ACK, NULL);
417 break;
418 } else
419 stptr = stptr->next;
422 static void
423 process_rcv(struct IsdnCardState *sp)
425 struct sk_buff *skb, *nskb;
426 struct PStack *stptr;
427 int found, broadc;
428 char tmp[64];
430 while ((skb = skb_dequeue(&sp->rq))) {
431 #ifdef L2FRAME_DEBUG /* psa */
432 if (sp->debug & L1_DEB_LAPD)
433 Logl2Frame(sp, skb, "PH_DATA", 1);
434 #endif
435 stptr = sp->stlist;
436 broadc = (skb->data[1] >> 1) == 127;
438 if (broadc) {
439 if (!(skb->data[0] >> 2)) { /* sapi 0 */
440 sp->CallFlags = 3;
441 if (sp->dlogflag) {
442 LogFrame(sp, skb->data, skb->len);
443 dlogframe(sp, skb->data + 3, skb->len - 3,
444 "Q.931 frame network->user broadcast");
447 while (stptr != NULL) {
448 if ((skb->data[0] >> 2) == stptr->l2.sap)
449 if ((nskb = skb_clone(skb, GFP_ATOMIC)))
450 stptr->l1.l1l2(stptr, PH_DATA, nskb);
451 else
452 printk(KERN_WARNING "HiSax: isdn broadcast buffer shortage\n");
453 stptr = stptr->next;
455 SET_SKB_FREE(skb);
456 dev_kfree_skb(skb, FREE_READ);
457 } else {
458 found = 0;
459 while (stptr != NULL)
460 if (((skb->data[0] >> 2) == stptr->l2.sap) &&
461 ((skb->data[1] >> 1) == stptr->l2.tei)) {
462 stptr->l1.l1l2(stptr, PH_DATA, skb);
463 found = !0;
464 break;
465 } else
466 stptr = stptr->next;
467 if (!found) {
468 /* BD 10.10.95
469 * Print out D-Channel msg not processed
470 * by isdn4linux
473 if ((!(skb->data[0] >> 2)) && (!(skb->data[2] & 0x01))) {
474 sprintf(tmp,
475 "Q.931 frame network->user with tei %d (not for us)",
476 skb->data[1] >> 1);
477 LogFrame(sp, skb->data, skb->len);
478 dlogframe(sp, skb->data + 4, skb->len - 4, tmp);
480 SET_SKB_FREE(skb);
481 dev_kfree_skb(skb, FREE_READ);
489 static void
490 isac_bh(struct IsdnCardState *sp)
492 if (!sp)
493 return;
495 if (test_and_clear_bit(ISAC_PHCHANGE, &sp->event))
496 process_new_ph(sp);
497 if (test_and_clear_bit(ISAC_RCVBUFREADY, &sp->event))
498 process_rcv(sp);
499 if (test_and_clear_bit(ISAC_XMTBUFREADY, &sp->event))
500 process_xmt(sp);
503 static void
504 l2l1(struct PStack *st, int pr, void *arg)
506 struct IsdnCardState *sp = (struct IsdnCardState *) st->l1.hardware;
507 struct sk_buff *skb = arg;
508 char str[64];
510 switch (pr) {
511 case (PH_DATA):
512 if (sp->tx_skb) {
513 skb_queue_tail(&sp->sq, skb);
514 #ifdef L2FRAME_DEBUG /* psa */
515 if (sp->debug & L1_DEB_LAPD)
516 Logl2Frame(sp, skb, "PH_DATA Queued", 0);
517 #endif
518 } else {
519 if ((sp->dlogflag) && (!(skb->data[2] & 1))) { /* I-FRAME */
520 LogFrame(sp, skb->data, skb->len);
521 sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
522 dlogframe(sp, skb->data + st->l2.ihsize, skb->len - st->l2.ihsize,
523 str);
525 sp->tx_skb = skb;
526 sp->tx_cnt = 0;
527 #ifdef L2FRAME_DEBUG /* psa */
528 if (sp->debug & L1_DEB_LAPD)
529 Logl2Frame(sp, skb, "PH_DATA", 0);
530 #endif
531 sp->isac_fill_fifo(sp);
533 break;
534 case (PH_DATA_PULLED):
535 if (sp->tx_skb) {
536 if (sp->debug & L1_DEB_WARN)
537 debugl1(sp, " l2l1 tx_skb exist this shouldn't happen");
538 break;
540 if ((sp->dlogflag) && (!(skb->data[2] & 1))) { /* I-FRAME */
541 LogFrame(sp, skb->data, skb->len);
542 sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
543 dlogframe(sp, skb->data + st->l2.ihsize, skb->len - st->l2.ihsize,
544 str);
546 sp->tx_skb = skb;
547 sp->tx_cnt = 0;
548 #ifdef L2FRAME_DEBUG /* psa */
549 if (sp->debug & L1_DEB_LAPD)
550 Logl2Frame(sp, skb, "PH_DATA_PULLED", 0);
551 #endif
552 sp->isac_fill_fifo(sp);
553 break;
554 case (PH_REQUEST_PULL):
555 #ifdef L2FRAME_DEBUG /* psa */
556 if (sp->debug & L1_DEB_LAPD)
557 debugl1(sp, "-> PH_REQUEST_PULL");
558 #endif
559 if (!sp->tx_skb) {
560 st->l1.requestpull = 0;
561 st->l1.l1l2(st, PH_PULL_ACK, NULL);
562 } else
563 st->l1.requestpull = !0;
564 break;
569 static void
570 hscx_process_xmt(struct HscxState *hsp)
572 struct PStack *st = hsp->st;
574 if (hsp->tx_skb)
575 return;
577 if (st->l1.requestpull) {
578 st->l1.requestpull = 0;
579 st->l1.l1l2(st, PH_PULL_ACK, NULL);
581 if (!hsp->active)
582 if ((!hsp->tx_skb) && (!skb_queue_len(&hsp->squeue)))
583 hsp->sp->modehscx(hsp, 0, 0);
586 static void
587 hscx_process_rcv(struct HscxState *hsp)
589 struct sk_buff *skb;
591 #ifdef DEBUG_MAGIC
592 if (hsp->magic != 301270) {
593 printk(KERN_DEBUG "hscx_process_rcv magic not 301270\n");
594 return;
596 #endif
597 while ((skb = skb_dequeue(&hsp->rqueue))) {
598 hsp->st->l1.l1l2(hsp->st, PH_DATA, skb);
602 static void
603 hscx_bh(struct HscxState *hsp)
606 if (!hsp)
607 return;
609 if (test_and_clear_bit(HSCX_RCVBUFREADY, &hsp->event))
610 hscx_process_rcv(hsp);
611 if (test_and_clear_bit(HSCX_XMTBUFREADY, &hsp->event))
612 hscx_process_xmt(hsp);
617 * interrupt stuff ends here
620 void
621 HiSax_addlist(struct IsdnCardState *sp,
622 struct PStack *st)
624 st->next = sp->stlist;
625 sp->stlist = st;
628 void
629 HiSax_rmlist(struct IsdnCardState *sp,
630 struct PStack *st)
632 struct PStack *p;
634 if (sp->stlist == st)
635 sp->stlist = st->next;
636 else {
637 p = sp->stlist;
638 while (p)
639 if (p->next == st) {
640 p->next = st->next;
641 return;
642 } else
643 p = p->next;
647 static void
648 check_ph_act(struct IsdnCardState *sp)
650 struct PStack *st = sp->stlist;
652 while (st) {
653 if (st->l1.act_state)
654 return;
655 st = st->next;
657 if (sp->ph_active == 5)
658 sp->ph_active = 4;
661 static void
662 HiSax_manl1(struct PStack *st, int pr,
663 void *arg)
665 struct IsdnCardState *sp = (struct IsdnCardState *)
666 st->l1.hardware;
667 long flags;
668 char tmp[32];
670 switch (pr) {
671 case (PH_ACTIVATE):
672 if (sp->debug) {
673 sprintf(tmp, "PH_ACT ph_active %d", sp->ph_active);
674 debugl1(sp, tmp);
676 save_flags(flags);
677 cli();
678 if (sp->ph_active & 4) {
679 sp->ph_active = 5;
680 st->l1.act_state = 2;
681 restore_flags(flags);
682 st->l1.l1man(st, PH_ACTIVATE, NULL);
683 } else {
684 st->l1.act_state = 1;
685 if (sp->ph_active == 0)
686 restart_ph(sp);
687 restore_flags(flags);
689 break;
690 case (PH_DEACTIVATE):
691 st->l1.act_state = 0;
692 if (sp->debug) {
693 sprintf(tmp, "PH_DEACT ph_active %d", sp->ph_active);
694 debugl1(sp, tmp);
696 check_ph_act(sp);
697 break;
701 static void
702 HiSax_l2l1discardq(struct PStack *st, int pr,
703 void *heldby, int releasetoo)
705 struct IsdnCardState *sp = (struct IsdnCardState *) st->l1.hardware;
706 struct sk_buff *skb;
708 #ifdef DEBUG_MAGIC
709 if (sp->magic != 301271) {
710 printk(KERN_DEBUG "isac_discardq magic not 301271\n");
711 return;
713 #endif
715 while ((skb = skb_dequeue(&sp->sq))) {
716 SET_SKB_FREE(skb);
717 dev_kfree_skb(skb, FREE_WRITE);
721 void
722 setstack_HiSax(struct PStack *st, struct IsdnCardState *sp)
724 st->l1.hardware = sp;
725 st->protocol = sp->protocol;
727 setstack_tei(st);
729 st->l1.stlistp = &(sp->stlist);
730 st->l1.act_state = 0;
731 st->l2.l2l1 = l2l1;
732 st->l2.l2l1discardq = HiSax_l2l1discardq;
733 st->ma.manl1 = HiSax_manl1;
734 st->l1.requestpull = 0;
737 void
738 init_hscxstate(struct IsdnCardState *sp,
739 int hscx)
741 struct HscxState *hsp = sp->hs + hscx;
743 hsp->sp = sp;
744 hsp->hscx = hscx;
746 hsp->tqueue.next = 0;
747 hsp->tqueue.sync = 0;
748 hsp->tqueue.routine = (void *) (void *) hscx_bh;
749 hsp->tqueue.data = hsp;
751 hsp->inuse = 0;
752 hsp->init = 0;
753 hsp->active = 0;
755 #ifdef DEBUG_MAGIC
756 hsp->magic = 301270;
757 #endif
761 get_irq(int cardnr, void *routine)
763 struct IsdnCard *card = cards + cardnr;
764 long flags;
766 save_flags(flags);
767 cli();
768 if (request_irq(card->sp->irq, routine,
769 I4L_IRQ_FLAG, "HiSax", NULL)) {
770 printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n",
771 card->sp->irq);
772 restore_flags(flags);
773 return (0);
775 irq2dev_map[card->sp->irq] = (void *) card->sp;
776 restore_flags(flags);
777 return (1);
780 static void
781 release_irq(int cardnr)
783 struct IsdnCard *card = cards + cardnr;
785 irq2dev_map[card->sp->irq] = NULL;
786 free_irq(card->sp->irq, NULL);
789 void
790 close_hscxstate(struct HscxState *hs)
792 struct sk_buff *skb;
794 hs->sp->modehscx(hs, 0, 0);
795 hs->inuse = 0;
796 if (hs->init) {
797 if (hs->rcvbuf) {
798 kfree(hs->rcvbuf);
799 hs->rcvbuf = NULL;
801 while ((skb = skb_dequeue(&hs->rqueue))) {
802 SET_SKB_FREE(skb);
803 dev_kfree_skb(skb, FREE_READ);
805 while ((skb = skb_dequeue(&hs->squeue))) {
806 SET_SKB_FREE(skb);
807 dev_kfree_skb(skb, FREE_WRITE);
809 if (hs->tx_skb) {
810 SET_SKB_FREE(hs->tx_skb);
811 dev_kfree_skb(hs->tx_skb, FREE_WRITE);
812 hs->tx_skb = NULL;
815 hs->init = 0;
818 static void
819 closecard(int cardnr)
821 struct IsdnCardState *csta = cards[cardnr].sp;
822 struct sk_buff *skb;
824 close_hscxstate(csta->hs + 1);
825 close_hscxstate(csta->hs);
827 if (csta->rcvbuf) {
828 kfree(csta->rcvbuf);
829 csta->rcvbuf = NULL;
831 while ((skb = skb_dequeue(&csta->rq))) {
832 SET_SKB_FREE(skb);
833 dev_kfree_skb(skb, FREE_READ);
835 while ((skb = skb_dequeue(&csta->sq))) {
836 SET_SKB_FREE(skb);
837 dev_kfree_skb(skb, FREE_WRITE);
839 if (csta->tx_skb) {
840 SET_SKB_FREE(csta->tx_skb);
841 dev_kfree_skb(csta->tx_skb, FREE_WRITE);
842 csta->tx_skb = NULL;
844 switch (csta->typ) {
845 #if CARD_TELES0
846 case ISDN_CTYPE_16_0:
847 case ISDN_CTYPE_8_0:
848 release_io_teles0(cards + cardnr);
849 break;
850 #endif
851 #if CARD_TELES3
852 case ISDN_CTYPE_PNP:
853 case ISDN_CTYPE_16_3:
854 case ISDN_CTYPE_TELESPCMCIA:
855 release_io_teles3(cards + cardnr);
856 break;
857 #endif
858 #if CARD_AVM_A1
859 case ISDN_CTYPE_A1:
860 release_io_avm_a1(cards + cardnr);
861 break;
862 #endif
863 #if CARD_ELSA
864 case ISDN_CTYPE_ELSA:
865 case ISDN_CTYPE_ELSA_QS1000:
866 release_io_elsa(cards + cardnr);
867 break;
868 #endif
869 #if CARD_IX1MICROR2
870 case ISDN_CTYPE_IX1MICROR2:
871 release_io_ix1micro(cards + cardnr);
872 break;
873 #endif
874 default:
875 break;
877 ll_unload(csta);
880 static int
881 checkcard(int cardnr, char *id)
883 long flags;
884 int ret = 0;
885 struct IsdnCard *card = cards + cardnr;
886 struct IsdnCardState *sp;
888 save_flags(flags);
889 cli();
890 if (!(sp = (struct IsdnCardState *)
891 kmalloc(sizeof(struct IsdnCardState), GFP_ATOMIC))) {
892 printk(KERN_WARNING
893 "HiSax: No memory for IsdnCardState(card %d)\n",
894 cardnr + 1);
895 restore_flags(flags);
896 return (0);
898 card->sp = sp;
899 sp->cardnr = cardnr;
900 sp->cfg_reg = 0;
901 sp->protocol = card->protocol;
903 if ((card->typ > 0) && (card->typ < 31)) {
904 if (!((1 << card->typ) & SUPORTED_CARDS)) {
905 printk(KERN_WARNING
906 "HiSax: Support for %s Card not selected\n",
907 CardType[card->typ]);
908 restore_flags(flags);
909 return (0);
911 } else {
912 printk(KERN_WARNING
913 "HiSax: Card Type %d out of range\n",
914 card->typ);
915 restore_flags(flags);
916 return (0);
918 if (!(sp->dlogspace = kmalloc(4096, GFP_ATOMIC))) {
919 printk(KERN_WARNING
920 "HiSax: No memory for dlogspace(card %d)\n",
921 cardnr + 1);
922 restore_flags(flags);
923 return (0);
925 if (!(sp->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) {
926 printk(KERN_WARNING
927 "HiSax: No memory for status_buf(card %d)\n",
928 cardnr + 1);
929 kfree(sp->dlogspace);
930 restore_flags(flags);
931 return (0);
933 sp->status_read = sp->status_buf;
934 sp->status_write = sp->status_buf;
935 sp->status_end = sp->status_buf + HISAX_STATUS_BUFSIZE - 1;
936 sp->typ = card->typ;
937 sp->CallFlags = 0;
938 strcpy(sp->iif.id, id);
939 sp->iif.channels = 2;
940 sp->iif.maxbufsize = MAX_DATA_SIZE;
941 sp->iif.hl_hdrlen = MAX_HEADER_LEN;
942 sp->iif.features =
943 ISDN_FEATURE_L2_X75I |
944 ISDN_FEATURE_L2_HDLC |
945 ISDN_FEATURE_L2_TRANS |
946 ISDN_FEATURE_L3_TRANS |
947 #ifdef CONFIG_HISAX_1TR6
948 ISDN_FEATURE_P_1TR6 |
949 #endif
950 #ifdef CONFIG_HISAX_EURO
951 ISDN_FEATURE_P_EURO |
952 #endif
953 #ifdef CONFIG_HISAX_NI1
954 ISDN_FEATURE_P_NI1 |
955 #endif
958 sp->iif.command = HiSax_command;
959 sp->iif.writebuf = NULL;
960 sp->iif.writecmd = NULL;
961 sp->iif.writebuf_skb = HiSax_writebuf_skb;
962 sp->iif.readstat = HiSax_readstatus;
963 register_isdn(&sp->iif);
964 sp->myid = sp->iif.channels;
965 restore_flags(flags);
966 printk(KERN_NOTICE
967 "HiSax: Card %d Protocol %s Id=%s (%d)\n", cardnr + 1,
968 (card->protocol == ISDN_PTYPE_1TR6) ? "1TR6" :
969 (card->protocol == ISDN_PTYPE_EURO) ? "EDSS1" :
970 (card->protocol == ISDN_PTYPE_LEASED) ? "LEASED" :
971 (card->protocol == ISDN_PTYPE_NI1) ? "NI1" :
972 "NONE", sp->iif.id, sp->myid);
973 switch (card->typ) {
974 #if CARD_TELES0
975 case ISDN_CTYPE_16_0:
976 case ISDN_CTYPE_8_0:
977 ret = setup_teles0(card);
978 break;
979 #endif
980 #if CARD_TELES3
981 case ISDN_CTYPE_16_3:
982 case ISDN_CTYPE_PNP:
983 case ISDN_CTYPE_TELESPCMCIA:
984 ret = setup_teles3(card);
985 break;
986 #endif
987 #if CARD_AVM_A1
988 case ISDN_CTYPE_A1:
989 ret = setup_avm_a1(card);
990 break;
991 #endif
992 #if CARD_ELSA
993 case ISDN_CTYPE_ELSA:
994 case ISDN_CTYPE_ELSA_QS1000:
995 ret = setup_elsa(card);
996 break;
997 #endif
998 #if CARD_IX1MICROR2
999 case ISDN_CTYPE_IX1MICROR2:
1000 ret = setup_ix1micro(card);
1001 break;
1002 #endif
1003 default:
1004 printk(KERN_WARNING "HiSax: Unknown Card Typ %d\n",
1005 card->typ);
1006 ll_unload(sp);
1007 return (0);
1009 if (!ret) {
1010 ll_unload(sp);
1011 return (0);
1013 if (!(sp->rcvbuf = kmalloc(MAX_DFRAME_LEN, GFP_ATOMIC))) {
1014 printk(KERN_WARNING
1015 "HiSax: No memory for isac rcvbuf\n");
1016 return (1);
1018 sp->rcvidx = 0;
1019 sp->tx_skb = NULL;
1020 sp->tx_cnt = 0;
1021 sp->event = 0;
1022 sp->tqueue.next = 0;
1023 sp->tqueue.sync = 0;
1024 sp->tqueue.routine = (void *) (void *) isac_bh;
1025 sp->tqueue.data = sp;
1027 skb_queue_head_init(&sp->rq);
1028 skb_queue_head_init(&sp->sq);
1030 sp->stlist = NULL;
1031 sp->ph_active = 0;
1032 sp->dlogflag = 0;
1033 sp->debug = L1_DEB_WARN;
1034 #ifdef DEBUG_MAGIC
1035 sp->magic = 301271;
1036 #endif
1038 init_hscxstate(sp, 0);
1039 init_hscxstate(sp, 1);
1041 switch (card->typ) {
1042 #if CARD_TELES0
1043 case ISDN_CTYPE_16_0:
1044 case ISDN_CTYPE_8_0:
1045 ret = initteles0(sp);
1046 break;
1047 #endif
1048 #if CARD_TELES3
1049 case ISDN_CTYPE_16_3:
1050 case ISDN_CTYPE_PNP:
1051 case ISDN_CTYPE_TELESPCMCIA:
1052 ret = initteles3(sp);
1053 break;
1054 #endif
1055 #if CARD_AVM_A1
1056 case ISDN_CTYPE_A1:
1057 ret = initavm_a1(sp);
1058 break;
1059 #endif
1060 #if CARD_ELSA
1061 case ISDN_CTYPE_ELSA:
1062 case ISDN_CTYPE_ELSA_QS1000:
1063 ret = initelsa(sp);
1064 break;
1065 #endif
1066 #if CARD_IX1MICROR2
1067 case ISDN_CTYPE_IX1MICROR2:
1068 ret = initix1micro(sp);
1069 break;
1070 #endif
1071 default:
1072 ret = 0;
1073 break;
1075 if (!ret) {
1076 closecard(cardnr);
1077 return (0);
1079 init_tei(sp, sp->protocol);
1080 CallcNewChan(sp);
1081 ll_run(sp);
1082 return (1);
1085 void
1086 HiSax_shiftcards(int idx)
1088 int i;
1090 for (i = idx; i < 15; i++)
1091 memcpy(&cards[i], &cards[i + 1], sizeof(cards[i]));
1095 HiSax_inithardware(void)
1097 int foundcards = 0;
1098 int i = 0;
1099 int t = ',';
1100 int flg = 0;
1101 char *id;
1102 char *next_id = HiSax_id;
1103 char ids[20];
1105 if (strchr(HiSax_id, ','))
1106 t = ',';
1107 else if (strchr(HiSax_id, '%'))
1108 t = '%';
1110 while (i < nrcards) {
1111 if (cards[i].typ < 1)
1112 break;
1113 id = next_id;
1114 if ((next_id = strchr(id, t))) {
1115 *next_id++ = 0;
1116 strcpy(ids, id);
1117 flg = i + 1;
1118 } else {
1119 next_id = id;
1120 if (flg >= i)
1121 strcpy(ids, id);
1122 else
1123 sprintf(ids, "%s%d", id, i);
1125 if (checkcard(i, ids)) {
1126 foundcards++;
1127 i++;
1128 } else {
1129 printk(KERN_WARNING "HiSax: Card %s not installed !\n",
1130 CardType[cards[i].typ]);
1131 if (cards[i].sp)
1132 kfree((void *) cards[i].sp);
1133 cards[i].sp = NULL;
1134 HiSax_shiftcards(i);
1137 return foundcards;
1140 void
1141 HiSax_closehardware(void)
1143 int i;
1144 long flags;
1146 save_flags(flags);
1147 cli();
1148 for (i = 0; i < nrcards; i++)
1149 if (cards[i].sp) {
1150 ll_stop(cards[i].sp);
1151 CallcFreeChan(cards[i].sp);
1152 release_tei(cards[i].sp);
1153 release_irq(i);
1154 closecard(i);
1155 kfree((void *) cards[i].sp);
1156 cards[i].sp = NULL;
1158 Isdnl2Free();
1159 CallcFree();
1160 restore_flags(flags);
1163 static void
1164 hscx_l2l1(struct PStack *st, int pr, void *arg)
1166 struct sk_buff *skb = arg;
1167 struct IsdnCardState *sp = (struct IsdnCardState *) st->l1.hardware;
1168 struct HscxState *hsp = sp->hs + st->l1.hscx;
1169 long flags;
1171 switch (pr) {
1172 case (PH_DATA):
1173 save_flags(flags);
1174 cli();
1175 if (hsp->tx_skb) {
1176 skb_queue_tail(&hsp->squeue, skb);
1177 restore_flags(flags);
1178 } else {
1179 restore_flags(flags);
1180 hsp->tx_skb = skb;
1181 hsp->count = 0;
1182 sp->hscx_fill_fifo(hsp);
1184 break;
1185 case (PH_DATA_PULLED):
1186 if (hsp->tx_skb) {
1187 printk(KERN_WARNING "hscx_l2l1: this shouldn't happen\n");
1188 break;
1190 hsp->tx_skb = skb;
1191 hsp->count = 0;
1192 sp->hscx_fill_fifo(hsp);
1193 break;
1194 case (PH_REQUEST_PULL):
1195 if (!hsp->tx_skb) {
1196 st->l1.requestpull = 0;
1197 st->l1.l1l2(st, PH_PULL_ACK, NULL);
1198 } else
1199 st->l1.requestpull = !0;
1200 break;
1204 extern struct IsdnBuffers *tracebuf;
1206 static void
1207 hscx_l2l1discardq(struct PStack *st, int pr, void *heldby,
1208 int releasetoo)
1210 struct IsdnCardState *sp = (struct IsdnCardState *)
1211 st->l1.hardware;
1212 struct HscxState *hsp = sp->hs + st->l1.hscx;
1213 struct sk_buff *skb;
1215 #ifdef DEBUG_MAGIC
1216 if (hsp->magic != 301270) {
1217 printk(KERN_DEBUG "hscx_discardq magic not 301270\n");
1218 return;
1220 #endif
1222 while ((skb = skb_dequeue(&hsp->squeue))) {
1223 SET_SKB_FREE(skb);
1224 dev_kfree_skb(skb, FREE_WRITE);
1228 static int
1229 open_hscxstate(struct IsdnCardState *sp,
1230 int hscx)
1232 struct HscxState *hsp = sp->hs + hscx;
1234 if (!hsp->init) {
1235 if (!(hsp->rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
1236 printk(KERN_WARNING
1237 "HiSax: No memory for hscx_rcvbuf\n");
1238 return (1);
1240 skb_queue_head_init(&hsp->rqueue);
1241 skb_queue_head_init(&hsp->squeue);
1243 hsp->init = !0;
1245 hsp->tx_skb = NULL;
1246 hsp->event = 0;
1247 hsp->rcvidx = 0;
1248 hsp->tx_cnt = 0;
1249 return (0);
1252 static void
1253 hscx_manl1(struct PStack *st, int pr,
1254 void *arg)
1256 struct IsdnCardState *sp = (struct IsdnCardState *) st->l1.hardware;
1257 struct HscxState *hsp = sp->hs + st->l1.hscx;
1259 switch (pr) {
1260 case (PH_ACTIVATE):
1261 hsp->active = !0;
1262 sp->modehscx(hsp, st->l1.hscxmode, st->l1.hscxchannel);
1263 st->l1.l1man(st, PH_ACTIVATE, NULL);
1264 break;
1265 case (PH_DEACTIVATE):
1266 if (!hsp->tx_skb)
1267 sp->modehscx(hsp, 0, 0);
1269 hsp->active = 0;
1270 break;
1275 setstack_hscx(struct PStack *st, struct HscxState *hs)
1277 if (open_hscxstate(st->l1.hardware, hs->hscx))
1278 return (-1);
1280 st->l1.hscx = hs->hscx;
1281 st->l2.l2l1 = hscx_l2l1;
1282 st->ma.manl1 = hscx_manl1;
1283 st->l2.l2l1discardq = hscx_l2l1discardq;
1285 st->l1.act_state = 0;
1286 st->l1.requestpull = 0;
1288 hs->st = st;
1289 return (0);
1292 void
1293 HiSax_reportcard(int cardnr)
1295 struct IsdnCardState *sp = cards[cardnr].sp;
1297 printk(KERN_DEBUG "HiSax: reportcard No %d\n", cardnr + 1);
1298 printk(KERN_DEBUG "HiSax: Type %s\n", CardType[sp->typ]);
1299 printk(KERN_DEBUG "HiSax: debuglevel %x\n", sp->debug);
1300 printk(KERN_DEBUG "HiSax: HiSax_reportcard address 0x%lX\n",
1301 (ulong) & HiSax_reportcard);
1304 #ifdef L2FRAME_DEBUG /* psa */
1306 char *
1307 l2cmd(u_char cmd)
1309 switch (cmd & ~0x10) {
1310 case 1:
1311 return "RR";
1312 case 5:
1313 return "RNR";
1314 case 9:
1315 return "REJ";
1316 case 0x6f:
1317 return "SABME";
1318 case 0x0f:
1319 return "DM";
1320 case 3:
1321 return "UI";
1322 case 0x43:
1323 return "DISC";
1324 case 0x63:
1325 return "UA";
1326 case 0x87:
1327 return "FRMR";
1328 case 0xaf:
1329 return "XID";
1330 default:
1331 if (!(cmd & 1))
1332 return "I";
1333 else
1334 return "invalid command";
1338 static char tmp[20];
1340 char *
1341 l2frames(u_char * ptr)
1343 switch (ptr[2] & ~0x10) {
1344 case 1:
1345 case 5:
1346 case 9:
1347 sprintf(tmp, "%s[%d](nr %d)", l2cmd(ptr[2]), ptr[3] & 1, ptr[3] >> 1);
1348 break;
1349 case 0x6f:
1350 case 0x0f:
1351 case 3:
1352 case 0x43:
1353 case 0x63:
1354 case 0x87:
1355 case 0xaf:
1356 sprintf(tmp, "%s[%d]", l2cmd(ptr[2]), (ptr[2] & 0x10) >> 4);
1357 break;
1358 default:
1359 if (!(ptr[2] & 1)) {
1360 sprintf(tmp, "I[%d](ns %d, nr %d)", ptr[3] & 1, ptr[2] >> 1, ptr[3] >> 1);
1361 break;
1362 } else
1363 return "invalid command";
1367 return tmp;
1370 void
1371 Logl2Frame(struct IsdnCardState *sp, struct sk_buff *skb, char *buf, int dir)
1373 char tmp[132];
1374 u_char *ptr;
1376 ptr = skb->data;
1378 if (ptr[0] & 1 || !(ptr[1] & 1))
1379 debugl1(sp, "Addres not LAPD");
1380 else {
1381 sprintf(tmp, "%s %s: %s%c (sapi %d, tei %d)",
1382 (dir ? "<-" : "->"), buf, l2frames(ptr),
1383 ((ptr[0] & 2) >> 1) == dir ? 'C' : 'R', ptr[0] >> 2, ptr[1] >> 1);
1384 debugl1(sp, tmp);
1388 #endif