import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / drivers / isdn / hisax / avm_pci.c
1 /* $Id: avm_pci.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
2  *
3  * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards
4  *
5  * Author       Karsten Keil
6  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
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  * Thanks to AVM, Berlin for information
12  *
13  */
14
15 #define __NO_VERSION__
16 #include <linux/config.h>
17 #include <linux/init.h>
18 #include "hisax.h"
19 #include "isac.h"
20 #include "isdnl1.h"
21 #include <linux/pci.h>
22 #include <linux/isapnp.h>
23 #include <linux/interrupt.h>
24
25 extern const char *CardType[];
26 static const char *avm_pci_rev = "$Revision: 1.1.4.1 $";
27
28 #define  AVM_FRITZ_PCI          1
29 #define  AVM_FRITZ_PNP          2
30
31 #define  HDLC_FIFO              0x0
32 #define  HDLC_STATUS            0x4
33
34 #define  AVM_HDLC_1             0x00
35 #define  AVM_HDLC_2             0x01
36 #define  AVM_ISAC_FIFO          0x02
37 #define  AVM_ISAC_REG_LOW       0x04
38 #define  AVM_ISAC_REG_HIGH      0x06
39
40 #define  AVM_STATUS0_IRQ_ISAC   0x01
41 #define  AVM_STATUS0_IRQ_HDLC   0x02
42 #define  AVM_STATUS0_IRQ_TIMER  0x04
43 #define  AVM_STATUS0_IRQ_MASK   0x07
44
45 #define  AVM_STATUS0_RESET      0x01
46 #define  AVM_STATUS0_DIS_TIMER  0x02
47 #define  AVM_STATUS0_RES_TIMER  0x04
48 #define  AVM_STATUS0_ENA_IRQ    0x08
49 #define  AVM_STATUS0_TESTBIT    0x10
50
51 #define  AVM_STATUS1_INT_SEL    0x0f
52 #define  AVM_STATUS1_ENA_IOM    0x80
53
54 #define  HDLC_MODE_ITF_FLG      0x01
55 #define  HDLC_MODE_TRANS        0x02
56 #define  HDLC_MODE_CCR_7        0x04
57 #define  HDLC_MODE_CCR_16       0x08
58 #define  HDLC_MODE_TESTLOOP     0x80
59
60 #define  HDLC_INT_XPR           0x80
61 #define  HDLC_INT_XDU           0x40
62 #define  HDLC_INT_RPR           0x20
63 #define  HDLC_INT_MASK          0xE0
64
65 #define  HDLC_STAT_RME          0x01
66 #define  HDLC_STAT_RDO          0x10
67 #define  HDLC_STAT_CRCVFRRAB    0x0E
68 #define  HDLC_STAT_CRCVFR       0x06
69 #define  HDLC_STAT_RML_MASK     0x3f00
70
71 #define  HDLC_CMD_XRS           0x80
72 #define  HDLC_CMD_XME           0x01
73 #define  HDLC_CMD_RRS           0x20
74 #define  HDLC_CMD_XML_MASK      0x3f00
75
76
77 /* Interface functions */
78
79 static u_char
80 ReadISAC(struct IsdnCardState *cs, u_char offset)
81 {
82         register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
83         register u_char val;
84         register long flags;
85
86         save_flags(flags);
87         cli();
88         outb(idx, cs->hw.avm.cfg_reg + 4);
89         val = inb(cs->hw.avm.isac + (offset & 0xf));
90         restore_flags(flags);
91         return (val);
92 }
93
94 static void
95 WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
96 {
97         register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
98         register long flags;
99
100         save_flags(flags);
101         cli();
102         outb(idx, cs->hw.avm.cfg_reg + 4);
103         outb(value, cs->hw.avm.isac + (offset & 0xf));
104         restore_flags(flags);
105 }
106
107 static void
108 ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
109 {
110         outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
111         insb(cs->hw.avm.isac, data, size);
112 }
113
114 static void
115 WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
116 {
117         outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
118         outsb(cs->hw.avm.isac, data, size);
119 }
120
121 static inline u_int
122 ReadHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset)
123 {
124         register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
125         register u_int val;
126         register long flags;
127
128         save_flags(flags);
129         cli();
130         outl(idx, cs->hw.avm.cfg_reg + 4);
131         val = inl(cs->hw.avm.isac + offset);
132         restore_flags(flags);
133         return (val);
134 }
135
136 static inline void
137 WriteHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset, u_int value)
138 {
139         register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
140         register long flags;
141
142         save_flags(flags);
143         cli();
144         outl(idx, cs->hw.avm.cfg_reg + 4);
145         outl(value, cs->hw.avm.isac + offset);
146         restore_flags(flags);
147 }
148
149 static inline u_char
150 ReadHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset)
151 {
152         register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
153         register u_char val;
154         register long flags;
155
156         save_flags(flags);
157         cli();
158         outb(idx, cs->hw.avm.cfg_reg + 4);
159         val = inb(cs->hw.avm.isac + offset);
160         restore_flags(flags);
161         return (val);
162 }
163
164 static inline void
165 WriteHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset, u_char value)
166 {
167         register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
168         register long flags;
169
170         save_flags(flags);
171         cli();
172         outb(idx, cs->hw.avm.cfg_reg + 4);
173         outb(value, cs->hw.avm.isac + offset);
174         restore_flags(flags);
175 }
176
177 static u_char
178 ReadHDLC_s(struct IsdnCardState *cs, int chan, u_char offset)
179 {
180         return(0xff & ReadHDLCPCI(cs, chan, offset));
181 }
182
183 static void
184 WriteHDLC_s(struct IsdnCardState *cs, int chan, u_char offset, u_char value)
185 {
186         WriteHDLCPCI(cs, chan, offset, value);
187 }
188
189 static inline
190 struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
191 {
192         if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
193                 return(&cs->bcs[0]);
194         else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
195                 return(&cs->bcs[1]);
196         else
197                 return(NULL);
198 }
199
200 void inline
201 hdlc_sched_event(struct BCState *bcs, int event)
202 {
203         bcs->event |= 1 << event;
204         queue_task(&bcs->tqueue, &tq_immediate);
205         mark_bh(IMMEDIATE_BH);
206 }
207
208 void
209 write_ctrl(struct BCState *bcs, int which) {
210
211         if (bcs->cs->debug & L1_DEB_HSCX)
212                 debugl1(bcs->cs, "hdlc %c wr%x ctrl %x",
213                         'A' + bcs->channel, which, bcs->hw.hdlc.ctrl.ctrl);
214         if (bcs->cs->subtyp == AVM_FRITZ_PCI) {
215                 WriteHDLCPCI(bcs->cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl.ctrl);
216         } else {
217                 if (which & 4)
218                         WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 2,
219                                 bcs->hw.hdlc.ctrl.sr.mode);
220                 if (which & 2)
221                         WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 1,
222                                 bcs->hw.hdlc.ctrl.sr.xml);
223                 if (which & 1)
224                         WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS,
225                                 bcs->hw.hdlc.ctrl.sr.cmd);
226         }
227 }
228
229 void
230 modehdlc(struct BCState *bcs, int mode, int bc)
231 {
232         struct IsdnCardState *cs = bcs->cs;
233         int hdlc = bcs->channel;
234
235         if (cs->debug & L1_DEB_HSCX)
236                 debugl1(cs, "hdlc %c mode %d --> %d ichan %d --> %d",
237                         'A' + hdlc, bcs->mode, mode, hdlc, bc);
238         bcs->hw.hdlc.ctrl.ctrl = 0;
239         switch (mode) {
240                 case (-1): /* used for init */
241                         bcs->mode = 1;
242                         bcs->channel = bc;
243                         bc = 0;
244                 case (L1_MODE_NULL):
245                         if (bcs->mode == L1_MODE_NULL)
246                                 return;
247                         bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
248                         bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
249                         write_ctrl(bcs, 5);
250                         bcs->mode = L1_MODE_NULL;
251                         bcs->channel = bc;
252                         break;
253                 case (L1_MODE_TRANS):
254                         bcs->mode = mode;
255                         bcs->channel = bc;
256                         bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
257                         bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
258                         write_ctrl(bcs, 5);
259                         bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
260                         write_ctrl(bcs, 1);
261                         bcs->hw.hdlc.ctrl.sr.cmd = 0;
262                         hdlc_sched_event(bcs, B_XMTBUFREADY);
263                         break;
264                 case (L1_MODE_HDLC):
265                         bcs->mode = mode;
266                         bcs->channel = bc;
267                         bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
268                         bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_ITF_FLG;
269                         write_ctrl(bcs, 5);
270                         bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
271                         write_ctrl(bcs, 1);
272                         bcs->hw.hdlc.ctrl.sr.cmd = 0;
273                         hdlc_sched_event(bcs, B_XMTBUFREADY);
274                         break;
275         }
276 }
277
278 static inline void
279 hdlc_empty_fifo(struct BCState *bcs, int count)
280 {
281         register u_int *ptr;
282         u_char *p;
283         u_char idx = bcs->channel ? AVM_HDLC_2 : AVM_HDLC_1;
284         int cnt=0;
285         struct IsdnCardState *cs = bcs->cs;
286
287         if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
288                 debugl1(cs, "hdlc_empty_fifo %d", count);
289         if (bcs->hw.hdlc.rcvidx + count > HSCX_BUFMAX) {
290                 if (cs->debug & L1_DEB_WARN)
291                         debugl1(cs, "hdlc_empty_fifo: incoming packet too large");
292                 return;
293         }
294         p = bcs->hw.hdlc.rcvbuf + bcs->hw.hdlc.rcvidx;
295         ptr = (u_int *)p;
296         bcs->hw.hdlc.rcvidx += count;
297         if (cs->subtyp == AVM_FRITZ_PCI) {
298                 outl(idx, cs->hw.avm.cfg_reg + 4);
299                 while (cnt < count) {
300 #ifdef __powerpc__
301 #ifdef CONFIG_APUS
302                         *ptr++ = in_le32((unsigned *)(cs->hw.avm.isac +_IO_BASE));
303 #else
304                         *ptr++ = in_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE));
305 #endif /* CONFIG_APUS */
306 #else
307                         *ptr++ = inl(cs->hw.avm.isac);
308 #endif /* __powerpc__ */
309                         cnt += 4;
310                 }
311         } else {
312                 outb(idx, cs->hw.avm.cfg_reg + 4);
313                 while (cnt < count) {
314                         *p++ = inb(cs->hw.avm.isac);
315                         cnt++;
316                 }
317         }
318         if (cs->debug & L1_DEB_HSCX_FIFO) {
319                 char *t = bcs->blog;
320
321                 if (cs->subtyp == AVM_FRITZ_PNP)
322                         p = (u_char *) ptr;
323                 t += sprintf(t, "hdlc_empty_fifo %c cnt %d",
324                              bcs->channel ? 'B' : 'A', count);
325                 QuickHex(t, p, count);
326                 debugl1(cs, bcs->blog);
327         }
328 }
329
330 static inline void
331 hdlc_fill_fifo(struct BCState *bcs)
332 {
333         struct IsdnCardState *cs = bcs->cs;
334         int count, cnt =0;
335         int fifo_size = 32;
336         u_char *p;
337         u_int *ptr;
338
339         if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
340                 debugl1(cs, "hdlc_fill_fifo");
341         if (!bcs->tx_skb)
342                 return;
343         if (bcs->tx_skb->len <= 0)
344                 return;
345
346         bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XME;
347         if (bcs->tx_skb->len > fifo_size) {
348                 count = fifo_size;
349         } else {
350                 count = bcs->tx_skb->len;
351                 if (bcs->mode != L1_MODE_TRANS)
352                         bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XME;
353         }
354         if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
355                 debugl1(cs, "hdlc_fill_fifo %d/%ld", count, bcs->tx_skb->len);
356         p = bcs->tx_skb->data;
357         ptr = (u_int *)p;
358         skb_pull(bcs->tx_skb, count);
359         bcs->tx_cnt -= count;
360         bcs->hw.hdlc.count += count;
361         bcs->hw.hdlc.ctrl.sr.xml = ((count == fifo_size) ? 0 : count);
362         write_ctrl(bcs, 3);  /* sets the correct index too */
363         if (cs->subtyp == AVM_FRITZ_PCI) {
364                 while (cnt<count) {
365 #ifdef __powerpc__
366 #ifdef CONFIG_APUS
367                         out_le32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++);
368 #else
369                         out_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++);
370 #endif /* CONFIG_APUS */
371 #else
372                         outl(*ptr++, cs->hw.avm.isac);
373 #endif /* __powerpc__ */
374                         cnt += 4;
375                 }
376         } else {
377                 while (cnt<count) {
378                         outb(*p++, cs->hw.avm.isac);
379                         cnt++;
380                 }
381         }
382         if (cs->debug & L1_DEB_HSCX_FIFO) {
383                 char *t = bcs->blog;
384
385                 if (cs->subtyp == AVM_FRITZ_PNP)
386                         p = (u_char *) ptr;
387                 t += sprintf(t, "hdlc_fill_fifo %c cnt %d",
388                              bcs->channel ? 'B' : 'A', count);
389                 QuickHex(t, p, count);
390                 debugl1(cs, bcs->blog);
391         }
392 }
393
394 static void
395 fill_hdlc(struct BCState *bcs)
396 {
397         long flags;
398         save_flags(flags);
399         cli();
400         hdlc_fill_fifo(bcs);
401         restore_flags(flags);
402 }
403
404 static inline void
405 HDLC_irq(struct BCState *bcs, u_int stat) {
406         int len;
407         struct sk_buff *skb;
408
409         if (bcs->cs->debug & L1_DEB_HSCX)
410                 debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat);
411         if (stat & HDLC_INT_RPR) {
412                 if (stat & HDLC_STAT_RDO) {
413                         if (bcs->cs->debug & L1_DEB_HSCX)
414                                 debugl1(bcs->cs, "RDO");
415                         else
416                                 debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat);
417                         bcs->hw.hdlc.ctrl.sr.xml = 0;
418                         bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_RRS;
419                         write_ctrl(bcs, 1);
420                         bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_RRS;
421                         write_ctrl(bcs, 1);
422                         bcs->hw.hdlc.rcvidx = 0;
423                 } else {
424                         if (!(len = (stat & HDLC_STAT_RML_MASK)>>8))
425                                 len = 32;
426                         hdlc_empty_fifo(bcs, len);
427                         if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
428                                 if (((stat & HDLC_STAT_CRCVFRRAB)==HDLC_STAT_CRCVFR) ||
429                                         (bcs->mode == L1_MODE_TRANS)) {
430                                         if (!(skb = dev_alloc_skb(bcs->hw.hdlc.rcvidx)))
431                                                 printk(KERN_WARNING "HDLC: receive out of memory\n");
432                                         else {
433                                                 memcpy(skb_put(skb, bcs->hw.hdlc.rcvidx),
434                                                         bcs->hw.hdlc.rcvbuf, bcs->hw.hdlc.rcvidx);
435                                                 skb_queue_tail(&bcs->rqueue, skb);
436                                         }
437                                         bcs->hw.hdlc.rcvidx = 0;
438                                         hdlc_sched_event(bcs, B_RCVBUFREADY);
439                                 } else {
440                                         if (bcs->cs->debug & L1_DEB_HSCX)
441                                                 debugl1(bcs->cs, "invalid frame");
442                                         else
443                                                 debugl1(bcs->cs, "ch%d invalid frame %#x", bcs->channel, stat);
444                                         bcs->hw.hdlc.rcvidx = 0;
445                                 }
446                         }
447                 }
448         }
449         if (stat & HDLC_INT_XDU) {
450                 /* Here we lost an TX interrupt, so
451                  * restart transmitting the whole frame.
452                  */
453                 if (bcs->tx_skb) {
454                         skb_push(bcs->tx_skb, bcs->hw.hdlc.count);
455                         bcs->tx_cnt += bcs->hw.hdlc.count;
456                         bcs->hw.hdlc.count = 0;
457 //                      hdlc_sched_event(bcs, B_XMTBUFREADY);
458                         if (bcs->cs->debug & L1_DEB_WARN)
459                                 debugl1(bcs->cs, "ch%d XDU", bcs->channel);
460                 } else if (bcs->cs->debug & L1_DEB_WARN)
461                         debugl1(bcs->cs, "ch%d XDU without skb", bcs->channel);
462                 bcs->hw.hdlc.ctrl.sr.xml = 0;
463                 bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XRS;
464                 write_ctrl(bcs, 1);
465                 bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XRS;
466                 write_ctrl(bcs, 1);
467                 hdlc_fill_fifo(bcs);
468         } else if (stat & HDLC_INT_XPR) {
469                 if (bcs->tx_skb) {
470                         if (bcs->tx_skb->len) {
471                                 hdlc_fill_fifo(bcs);
472                                 return;
473                         } else {
474                                 if (bcs->st->lli.l1writewakeup &&
475                                         (PACKET_NOACK != bcs->tx_skb->pkt_type))
476                                         bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hdlc.count);
477                                 dev_kfree_skb_irq(bcs->tx_skb);
478                                 bcs->hw.hdlc.count = 0;
479                                 bcs->tx_skb = NULL;
480                         }
481                 }
482                 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
483                         bcs->hw.hdlc.count = 0;
484                         test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
485                         hdlc_fill_fifo(bcs);
486                 } else {
487                         test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
488                         hdlc_sched_event(bcs, B_XMTBUFREADY);
489                 }
490         }
491 }
492
493 inline void
494 HDLC_irq_main(struct IsdnCardState *cs)
495 {
496         u_int stat;
497         long  flags;
498         struct BCState *bcs;
499
500         save_flags(flags);
501         cli();
502         if (cs->subtyp == AVM_FRITZ_PCI) {
503                 stat = ReadHDLCPCI(cs, 0, HDLC_STATUS);
504         } else {
505                 stat = ReadHDLCPnP(cs, 0, HDLC_STATUS);
506                 if (stat & HDLC_INT_RPR)
507                         stat |= (ReadHDLCPnP(cs, 0, HDLC_STATUS+1))<<8;
508         }
509         if (stat & HDLC_INT_MASK) {
510                 if (!(bcs = Sel_BCS(cs, 0))) {
511                         if (cs->debug)
512                                 debugl1(cs, "hdlc spurious channel 0 IRQ");
513                 } else
514                         HDLC_irq(bcs, stat);
515         }
516         if (cs->subtyp == AVM_FRITZ_PCI) {
517                 stat = ReadHDLCPCI(cs, 1, HDLC_STATUS);
518         } else {
519                 stat = ReadHDLCPnP(cs, 1, HDLC_STATUS);
520                 if (stat & HDLC_INT_RPR)
521                         stat |= (ReadHDLCPnP(cs, 1, HDLC_STATUS+1))<<8;
522         }
523         if (stat & HDLC_INT_MASK) {
524                 if (!(bcs = Sel_BCS(cs, 1))) {
525                         if (cs->debug)
526                                 debugl1(cs, "hdlc spurious channel 1 IRQ");
527                 } else
528                         HDLC_irq(bcs, stat);
529         }
530         restore_flags(flags);
531 }
532
533 void
534 hdlc_l2l1(struct PStack *st, int pr, void *arg)
535 {
536         struct sk_buff *skb = arg;
537         long flags;
538
539         switch (pr) {
540                 case (PH_DATA | REQUEST):
541                         save_flags(flags);
542                         cli();
543                         if (st->l1.bcs->tx_skb) {
544                                 skb_queue_tail(&st->l1.bcs->squeue, skb);
545                                 restore_flags(flags);
546                         } else {
547                                 st->l1.bcs->tx_skb = skb;
548                                 test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
549                                 st->l1.bcs->hw.hdlc.count = 0;
550                                 restore_flags(flags);
551                                 st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
552                         }
553                         break;
554                 case (PH_PULL | INDICATION):
555                         if (st->l1.bcs->tx_skb) {
556                                 printk(KERN_WARNING "hdlc_l2l1: this shouldn't happen\n");
557                                 break;
558                         }
559                         test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
560                         st->l1.bcs->tx_skb = skb;
561                         st->l1.bcs->hw.hdlc.count = 0;
562                         st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
563                         break;
564                 case (PH_PULL | REQUEST):
565                         if (!st->l1.bcs->tx_skb) {
566                                 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
567                                 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
568                         } else
569                                 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
570                         break;
571                 case (PH_ACTIVATE | REQUEST):
572                         test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
573                         modehdlc(st->l1.bcs, st->l1.mode, st->l1.bc);
574                         l1_msg_b(st, pr, arg);
575                         break;
576                 case (PH_DEACTIVATE | REQUEST):
577                         l1_msg_b(st, pr, arg);
578                         break;
579                 case (PH_DEACTIVATE | CONFIRM):
580                         test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
581                         test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
582                         modehdlc(st->l1.bcs, 0, st->l1.bc);
583                         st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
584                         break;
585         }
586 }
587
588 void
589 close_hdlcstate(struct BCState *bcs)
590 {
591         modehdlc(bcs, 0, 0);
592         if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
593                 if (bcs->hw.hdlc.rcvbuf) {
594                         kfree(bcs->hw.hdlc.rcvbuf);
595                         bcs->hw.hdlc.rcvbuf = NULL;
596                 }
597                 if (bcs->blog) {
598                         kfree(bcs->blog);
599                         bcs->blog = NULL;
600                 }
601                 skb_queue_purge(&bcs->rqueue);
602                 skb_queue_purge(&bcs->squeue);
603                 if (bcs->tx_skb) {
604                         dev_kfree_skb_any(bcs->tx_skb);
605                         bcs->tx_skb = NULL;
606                         test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
607                 }
608         }
609 }
610
611 int
612 open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
613 {
614         if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
615                 if (!(bcs->hw.hdlc.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
616                         printk(KERN_WARNING
617                                "HiSax: No memory for hdlc.rcvbuf\n");
618                         return (1);
619                 }
620                 if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
621                         printk(KERN_WARNING
622                                 "HiSax: No memory for bcs->blog\n");
623                         test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
624                         kfree(bcs->hw.hdlc.rcvbuf);
625                         bcs->hw.hdlc.rcvbuf = NULL;
626                         return (2);
627                 }
628                 skb_queue_head_init(&bcs->rqueue);
629                 skb_queue_head_init(&bcs->squeue);
630         }
631         bcs->tx_skb = NULL;
632         test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
633         bcs->event = 0;
634         bcs->hw.hdlc.rcvidx = 0;
635         bcs->tx_cnt = 0;
636         return (0);
637 }
638
639 int
640 setstack_hdlc(struct PStack *st, struct BCState *bcs)
641 {
642         bcs->channel = st->l1.bc;
643         if (open_hdlcstate(st->l1.hardware, bcs))
644                 return (-1);
645         st->l1.bcs = bcs;
646         st->l2.l2l1 = hdlc_l2l1;
647         setstack_manager(st);
648         bcs->st = st;
649         setstack_l1_B(st);
650         return (0);
651 }
652
653 void __init
654 clear_pending_hdlc_ints(struct IsdnCardState *cs)
655 {
656         u_int val;
657
658         if (cs->subtyp == AVM_FRITZ_PCI) {
659                 val = ReadHDLCPCI(cs, 0, HDLC_STATUS);
660                 debugl1(cs, "HDLC 1 STA %x", val);
661                 val = ReadHDLCPCI(cs, 1, HDLC_STATUS);
662                 debugl1(cs, "HDLC 2 STA %x", val);
663         } else {
664                 val = ReadHDLCPnP(cs, 0, HDLC_STATUS);
665                 debugl1(cs, "HDLC 1 STA %x", val);
666                 val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 1);
667                 debugl1(cs, "HDLC 1 RML %x", val);
668                 val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 2);
669                 debugl1(cs, "HDLC 1 MODE %x", val);
670                 val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 3);
671                 debugl1(cs, "HDLC 1 VIN %x", val);
672                 val = ReadHDLCPnP(cs, 1, HDLC_STATUS);
673                 debugl1(cs, "HDLC 2 STA %x", val);
674                 val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 1);
675                 debugl1(cs, "HDLC 2 RML %x", val);
676                 val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 2);
677                 debugl1(cs, "HDLC 2 MODE %x", val);
678                 val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 3);
679                 debugl1(cs, "HDLC 2 VIN %x", val);
680         }
681 }
682
683 void __init
684 inithdlc(struct IsdnCardState *cs)
685 {
686         cs->bcs[0].BC_SetStack = setstack_hdlc;
687         cs->bcs[1].BC_SetStack = setstack_hdlc;
688         cs->bcs[0].BC_Close = close_hdlcstate;
689         cs->bcs[1].BC_Close = close_hdlcstate;
690         modehdlc(cs->bcs, -1, 0);
691         modehdlc(cs->bcs + 1, -1, 1);
692 }
693
694 static void
695 avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs)
696 {
697         struct IsdnCardState *cs = dev_id;
698         u_char val;
699         u_char sval;
700
701         if (!cs) {
702                 printk(KERN_WARNING "AVM PCI: Spurious interrupt!\n");
703                 return;
704         }
705         sval = inb(cs->hw.avm.cfg_reg + 2);
706         if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK)
707                 /* possible a shared  IRQ reqest */
708                 return;
709         if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
710                 val = ReadISAC(cs, ISAC_ISTA);
711                 isac_interrupt(cs, val);
712         }
713         if (!(sval & AVM_STATUS0_IRQ_HDLC)) {
714                 HDLC_irq_main(cs);
715         }
716         WriteISAC(cs, ISAC_MASK, 0xFF);
717         WriteISAC(cs, ISAC_MASK, 0x0);
718 }
719
720 static void
721 reset_avmpcipnp(struct IsdnCardState *cs)
722 {
723         long flags;
724
725         printk(KERN_INFO "AVM PCI/PnP: reset\n");
726         save_flags(flags);
727         sti();
728         outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2);
729         set_current_state(TASK_UNINTERRUPTIBLE);
730         schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
731         outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
732         outb(AVM_STATUS1_ENA_IOM | cs->irq, cs->hw.avm.cfg_reg + 3);
733         set_current_state(TASK_UNINTERRUPTIBLE);
734         schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
735         printk(KERN_INFO "AVM PCI/PnP: S1 %x\n", inb(cs->hw.avm.cfg_reg + 3));
736 }
737
738 static int
739 AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
740 {
741         switch (mt) {
742                 case CARD_RESET:
743                         reset_avmpcipnp(cs);
744                         return(0);
745                 case CARD_RELEASE:
746                         outb(0, cs->hw.avm.cfg_reg + 2);
747                         release_region(cs->hw.avm.cfg_reg, 32);
748                         return(0);
749                 case CARD_INIT:
750                         clear_pending_isac_ints(cs);
751                         initisac(cs);
752                         clear_pending_hdlc_ints(cs);
753                         inithdlc(cs);
754                         outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
755                                 cs->hw.avm.cfg_reg + 2);
756                         WriteISAC(cs, ISAC_MASK, 0);
757                         outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
758                                 AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
759                         /* RESET Receiver and Transmitter */
760                         WriteISAC(cs, ISAC_CMDR, 0x41);
761                         return(0);
762                 case CARD_TEST:
763                         return(0);
764         }
765         return(0);
766 }
767
768 static struct pci_dev *dev_avm __initdata = NULL;
769 #ifdef __ISAPNP__
770 static struct pci_bus *bus_avm __initdata = NULL;
771 static struct pci_dev *pnp_avm __initdata = NULL;
772 #endif
773
774 int __init
775 setup_avm_pcipnp(struct IsdnCard *card)
776 {
777         u_int val, ver;
778         struct IsdnCardState *cs = card->cs;
779         char tmp[64];
780
781         strcpy(tmp, avm_pci_rev);
782         printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp));
783         if (cs->typ != ISDN_CTYPE_FRITZPCI)
784                 return (0);
785         if (card->para[1]) {
786                 /* old manual method */
787                 cs->hw.avm.cfg_reg = card->para[1];
788                 cs->irq = card->para[0];
789                 cs->subtyp = AVM_FRITZ_PNP;
790         } else {
791 #ifdef __ISAPNP__
792                 if (isapnp_present()) {
793                         struct pci_bus *ba;
794                         if ((ba = isapnp_find_card(
795                                 ISAPNP_VENDOR('A', 'V', 'M'),
796                                 ISAPNP_FUNCTION(0x0900), bus_avm))) {
797                                 bus_avm = ba;
798                                 pnp_avm = NULL;
799                                 if ((pnp_avm = isapnp_find_dev(bus_avm,
800                                         ISAPNP_VENDOR('A', 'V', 'M'),
801                                         ISAPNP_FUNCTION(0x0900), pnp_avm))) {
802                                         pnp_avm->prepare(pnp_avm);
803                                         pnp_avm->deactivate(pnp_avm);
804                                         pnp_avm->activate(pnp_avm);
805                                         cs->hw.avm.cfg_reg =
806                                                 pnp_avm->resource[0].start;
807                                         cs->irq = 
808                                                 pnp_avm->irq_resource[0].start;
809                                         if (!cs->irq) {
810                                                 printk(KERN_ERR "FritzPnP:No IRQ\n");
811                                                 pnp_avm->deactivate(pnp_avm);
812                                                 return(0);
813                                         }
814                                         if (!cs->hw.avm.cfg_reg) {
815                                                 printk(KERN_ERR "FritzPnP:No IO address\n");
816                                                 pnp_avm->deactivate(pnp_avm);
817                                                 return(0);
818                                         }
819                                         cs->subtyp = AVM_FRITZ_PNP;
820                                         goto ready;
821                                 }
822                         }
823                 } else {
824                         printk(KERN_INFO "FritzPnP: no ISA PnP present\n");
825                 }
826 #endif
827 #if CONFIG_PCI
828                 if (!pci_present()) {
829                         printk(KERN_ERR "FritzPCI: no PCI bus present\n");
830                         return(0);
831                 }
832                 if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM,
833                         PCI_DEVICE_ID_AVM_A1,  dev_avm))) {
834                         cs->irq = dev_avm->irq;
835                         if (!cs->irq) {
836                                 printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n");
837                                 return(0);
838                         }
839                         if (pci_enable_device(dev_avm))
840                                 return(0);
841                         cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1);
842                         if (!cs->hw.avm.cfg_reg) {
843                                 printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n");
844                                 return(0);
845                         }
846                         cs->subtyp = AVM_FRITZ_PCI;
847                 } else {
848                         printk(KERN_WARNING "FritzPCI: No PCI card found\n");
849                         return(0);
850                 }
851                 cs->irq_flags |= SA_SHIRQ;
852 #else
853                 printk(KERN_WARNING "FritzPCI: NO_PCI_BIOS\n");
854                 return (0);
855 #endif /* CONFIG_PCI */
856         }
857 ready:
858         cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
859         if (check_region((cs->hw.avm.cfg_reg), 32)) {
860                 printk(KERN_WARNING
861                        "HiSax: %s config port %x-%x already in use\n",
862                        CardType[card->typ],
863                        cs->hw.avm.cfg_reg,
864                        cs->hw.avm.cfg_reg + 31);
865                 return (0);
866         } else {
867                 request_region(cs->hw.avm.cfg_reg, 32,
868                         (cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP");
869         }
870         switch (cs->subtyp) {
871           case AVM_FRITZ_PCI:
872                 val = inl(cs->hw.avm.cfg_reg);
873                 printk(KERN_INFO "AVM PCI: stat %#x\n", val);
874                 printk(KERN_INFO "AVM PCI: Class %X Rev %d\n",
875                         val & 0xff, (val>>8) & 0xff);
876                 cs->BC_Read_Reg = &ReadHDLC_s;
877                 cs->BC_Write_Reg = &WriteHDLC_s;
878                 break;
879           case AVM_FRITZ_PNP:
880                 val = inb(cs->hw.avm.cfg_reg);
881                 ver = inb(cs->hw.avm.cfg_reg + 1);
882                 printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver);
883                 reset_avmpcipnp(cs);
884                 cs->BC_Read_Reg = &ReadHDLCPnP;
885                 cs->BC_Write_Reg = &WriteHDLCPnP;
886                 break;
887           default:
888                 printk(KERN_WARNING "AVM unknown subtype %d\n", cs->subtyp);
889                 return(0);
890         }
891         printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n",
892                 (cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP",
893                 cs->irq, cs->hw.avm.cfg_reg);
894
895         cs->readisac = &ReadISAC;
896         cs->writeisac = &WriteISAC;
897         cs->readisacfifo = &ReadISACfifo;
898         cs->writeisacfifo = &WriteISACfifo;
899         cs->BC_Send_Data = &fill_hdlc;
900         cs->cardmsg = &AVM_card_msg;
901         cs->irq_func = &avm_pcipnp_interrupt;
902         ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:");
903         return (1);
904 }