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