ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.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 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 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 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 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 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                 if (bcs->hw.hdlc.rcvbuf) {
556                         kfree(bcs->hw.hdlc.rcvbuf);
557                         bcs->hw.hdlc.rcvbuf = NULL;
558                 }
559                 if (bcs->blog) {
560                         kfree(bcs->blog);
561                         bcs->blog = NULL;
562                 }
563                 skb_queue_purge(&bcs->rqueue);
564                 skb_queue_purge(&bcs->squeue);
565                 if (bcs->tx_skb) {
566                         dev_kfree_skb_any(bcs->tx_skb);
567                         bcs->tx_skb = NULL;
568                         test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
569                 }
570         }
571 }
572
573 int
574 open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
575 {
576         if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
577                 if (!(bcs->hw.hdlc.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
578                         printk(KERN_WARNING
579                                "HiSax: No memory for hdlc.rcvbuf\n");
580                         return (1);
581                 }
582                 if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
583                         printk(KERN_WARNING
584                                 "HiSax: No memory for bcs->blog\n");
585                         test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
586                         kfree(bcs->hw.hdlc.rcvbuf);
587                         bcs->hw.hdlc.rcvbuf = NULL;
588                         return (2);
589                 }
590                 skb_queue_head_init(&bcs->rqueue);
591                 skb_queue_head_init(&bcs->squeue);
592         }
593         bcs->tx_skb = NULL;
594         test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
595         bcs->event = 0;
596         bcs->hw.hdlc.rcvidx = 0;
597         bcs->tx_cnt = 0;
598         return (0);
599 }
600
601 int
602 setstack_hdlc(struct PStack *st, struct BCState *bcs)
603 {
604         bcs->channel = st->l1.bc;
605         if (open_hdlcstate(st->l1.hardware, bcs))
606                 return (-1);
607         st->l1.bcs = bcs;
608         st->l2.l2l1 = hdlc_l2l1;
609         setstack_manager(st);
610         bcs->st = st;
611         setstack_l1_B(st);
612         return (0);
613 }
614
615 void __init
616 clear_pending_hdlc_ints(struct IsdnCardState *cs)
617 {
618         u_int val;
619
620         if (cs->subtyp == AVM_FRITZ_PCI) {
621                 val = ReadHDLCPCI(cs, 0, HDLC_STATUS);
622                 debugl1(cs, "HDLC 1 STA %x", val);
623                 val = ReadHDLCPCI(cs, 1, HDLC_STATUS);
624                 debugl1(cs, "HDLC 2 STA %x", val);
625         } else {
626                 val = ReadHDLCPnP(cs, 0, HDLC_STATUS);
627                 debugl1(cs, "HDLC 1 STA %x", val);
628                 val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 1);
629                 debugl1(cs, "HDLC 1 RML %x", val);
630                 val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 2);
631                 debugl1(cs, "HDLC 1 MODE %x", val);
632                 val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 3);
633                 debugl1(cs, "HDLC 1 VIN %x", val);
634                 val = ReadHDLCPnP(cs, 1, HDLC_STATUS);
635                 debugl1(cs, "HDLC 2 STA %x", val);
636                 val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 1);
637                 debugl1(cs, "HDLC 2 RML %x", val);
638                 val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 2);
639                 debugl1(cs, "HDLC 2 MODE %x", val);
640                 val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 3);
641                 debugl1(cs, "HDLC 2 VIN %x", val);
642         }
643 }
644
645 void __init
646 inithdlc(struct IsdnCardState *cs)
647 {
648         cs->bcs[0].BC_SetStack = setstack_hdlc;
649         cs->bcs[1].BC_SetStack = setstack_hdlc;
650         cs->bcs[0].BC_Close = close_hdlcstate;
651         cs->bcs[1].BC_Close = close_hdlcstate;
652         modehdlc(cs->bcs, -1, 0);
653         modehdlc(cs->bcs + 1, -1, 1);
654 }
655
656 static irqreturn_t
657 avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs)
658 {
659         struct IsdnCardState *cs = dev_id;
660         u_long flags;
661         u_char val;
662         u_char sval;
663
664         spin_lock_irqsave(&cs->lock, flags);
665         sval = inb(cs->hw.avm.cfg_reg + 2);
666         if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) {
667                 /* possible a shared  IRQ reqest */
668                 spin_unlock_irqrestore(&cs->lock, flags);
669                 return IRQ_NONE;
670         }
671         if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
672                 val = ReadISAC(cs, ISAC_ISTA);
673                 isac_interrupt(cs, val);
674         }
675         if (!(sval & AVM_STATUS0_IRQ_HDLC)) {
676                 HDLC_irq_main(cs);
677         }
678         WriteISAC(cs, ISAC_MASK, 0xFF);
679         WriteISAC(cs, ISAC_MASK, 0x0);
680         spin_unlock_irqrestore(&cs->lock, flags);
681         return IRQ_HANDLED;
682 }
683
684 static void
685 reset_avmpcipnp(struct IsdnCardState *cs)
686 {
687         printk(KERN_INFO "AVM PCI/PnP: reset\n");
688         outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2);
689         mdelay(10);
690         outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
691         outb(AVM_STATUS1_ENA_IOM | cs->irq, cs->hw.avm.cfg_reg + 3);
692         mdelay(10);
693         printk(KERN_INFO "AVM PCI/PnP: S1 %x\n", inb(cs->hw.avm.cfg_reg + 3));
694 }
695
696 static int
697 AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
698 {
699         u_long flags;
700
701         switch (mt) {
702                 case CARD_RESET:
703                         spin_lock_irqsave(&cs->lock, flags);
704                         reset_avmpcipnp(cs);
705                         spin_unlock_irqrestore(&cs->lock, flags);
706                         return(0);
707                 case CARD_RELEASE:
708                         outb(0, cs->hw.avm.cfg_reg + 2);
709                         release_region(cs->hw.avm.cfg_reg, 32);
710                         return(0);
711                 case CARD_INIT:
712                         spin_lock_irqsave(&cs->lock, flags);
713                         reset_avmpcipnp(cs);
714                         clear_pending_isac_ints(cs);
715                         initisac(cs);
716                         inithdlc(cs);
717                         outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
718                                 cs->hw.avm.cfg_reg + 2);
719                         WriteISAC(cs, ISAC_MASK, 0);
720                         outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
721                                 AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
722                         /* RESET Receiver and Transmitter */
723                         WriteISAC(cs, ISAC_CMDR, 0x41);
724                         spin_unlock_irqrestore(&cs->lock, flags);
725                         return(0);
726                 case CARD_TEST:
727                         return(0);
728         }
729         return(0);
730 }
731
732 static struct pci_dev *dev_avm __initdata = NULL;
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         } else {
754 #ifdef __ISAPNP__
755                 if (isapnp_present()) {
756                         struct pnp_dev *pnp_avm_d = NULL;
757                         if ((pnp_avm_c = pnp_find_card(
758                                 ISAPNP_VENDOR('A', 'V', 'M'),
759                                 ISAPNP_FUNCTION(0x0900), pnp_avm_c))) {
760                                 if ((pnp_avm_d = pnp_find_dev(pnp_avm_c,
761                                         ISAPNP_VENDOR('A', 'V', 'M'),
762                                         ISAPNP_FUNCTION(0x0900), pnp_avm_d))) {
763                                         int err;
764
765                                         pnp_disable_dev(pnp_avm_d);
766                                         err = pnp_activate_dev(pnp_avm_d);
767                                         if (err<0) {
768                                                 printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
769                                                         __FUNCTION__, err);
770                                                 return(0);
771                                         }
772                                         cs->hw.avm.cfg_reg =
773                                                 pnp_port_start(pnp_avm_d, 0);
774                                         cs->irq = pnp_irq(pnp_avm_d, 0);
775                                         if (!cs->irq) {
776                                                 printk(KERN_ERR "FritzPnP:No IRQ\n");
777                                                 return(0);
778                                         }
779                                         if (!cs->hw.avm.cfg_reg) {
780                                                 printk(KERN_ERR "FritzPnP:No IO address\n");
781                                                 return(0);
782                                         }
783                                         cs->subtyp = AVM_FRITZ_PNP;
784                                         goto ready;
785                                 }
786                         }
787                 } else {
788                         printk(KERN_INFO "FritzPnP: no ISA PnP present\n");
789                 }
790 #endif
791 #if CONFIG_PCI
792                 if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM,
793                         PCI_DEVICE_ID_AVM_A1,  dev_avm))) {
794                         cs->irq = dev_avm->irq;
795                         if (!cs->irq) {
796                                 printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n");
797                                 return(0);
798                         }
799                         if (pci_enable_device(dev_avm))
800                                 return(0);
801                         cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1);
802                         if (!cs->hw.avm.cfg_reg) {
803                                 printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n");
804                                 return(0);
805                         }
806                         cs->subtyp = AVM_FRITZ_PCI;
807                 } else {
808                         printk(KERN_WARNING "FritzPCI: No PCI card found\n");
809                         return(0);
810                 }
811                 cs->irq_flags |= SA_SHIRQ;
812 #else
813                 printk(KERN_WARNING "FritzPCI: NO_PCI_BIOS\n");
814                 return (0);
815 #endif /* CONFIG_PCI */
816         }
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 }