Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / drivers / isdn / hisax / diva.c
1 /* $Id: diva.c,v 1.33.2.6 2004/02/11 13:21:33 keil Exp $
2  *
3  * low level stuff for Eicon.Diehl Diva Family 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  * For changes and modifications please read
12  * Documentation/isdn/HiSax.cert
13  *
14  * Thanks to Eicon Technology for documents and information
15  *
16  */
17
18 #include <linux/init.h>
19 #include <linux/config.h>
20 #include "hisax.h"
21 #include "isac.h"
22 #include "hscx.h"
23 #include "ipac.h"
24 #include "ipacx.h"
25 #include "isdnl1.h"
26 #include <linux/pci.h>
27 #include <linux/isapnp.h>
28
29 extern const char *CardType[];
30
31 const char *Diva_revision = "$Revision: 1.33.2.6 $";
32
33 #define byteout(addr,val) outb(val,addr)
34 #define bytein(addr) inb(addr)
35
36 #define DIVA_HSCX_DATA          0
37 #define DIVA_HSCX_ADR           4
38 #define DIVA_ISA_ISAC_DATA      2
39 #define DIVA_ISA_ISAC_ADR       6
40 #define DIVA_ISA_CTRL           7
41 #define DIVA_IPAC_ADR           0
42 #define DIVA_IPAC_DATA          1
43
44 #define DIVA_PCI_ISAC_DATA      8
45 #define DIVA_PCI_ISAC_ADR       0xc
46 #define DIVA_PCI_CTRL           0x10
47
48 /* SUB Types */
49 #define DIVA_ISA        1
50 #define DIVA_PCI        2
51 #define DIVA_IPAC_ISA   3
52 #define DIVA_IPAC_PCI   4
53 #define DIVA_IPACX_PCI  5
54
55 /* CTRL (Read) */
56 #define DIVA_IRQ_STAT   0x01
57 #define DIVA_EEPROM_SDA 0x02
58
59 /* CTRL (Write) */
60 #define DIVA_IRQ_REQ    0x01
61 #define DIVA_RESET      0x08
62 #define DIVA_EEPROM_CLK 0x40
63 #define DIVA_PCI_LED_A  0x10
64 #define DIVA_PCI_LED_B  0x20
65 #define DIVA_ISA_LED_A  0x20
66 #define DIVA_ISA_LED_B  0x40
67 #define DIVA_IRQ_CLR    0x80
68
69 /* Siemens PITA */
70 #define PITA_MISC_REG           0x1c
71 #ifdef __BIG_ENDIAN
72 #define PITA_PARA_SOFTRESET     0x00000001
73 #define PITA_SER_SOFTRESET      0x00000002
74 #define PITA_PARA_MPX_MODE      0x00000004
75 #define PITA_INT0_ENABLE        0x00000200
76 #else
77 #define PITA_PARA_SOFTRESET     0x01000000
78 #define PITA_SER_SOFTRESET      0x02000000
79 #define PITA_PARA_MPX_MODE      0x04000000
80 #define PITA_INT0_ENABLE        0x00020000
81 #endif
82 #define PITA_INT0_STATUS        0x02
83
84 static inline u_char
85 readreg(unsigned int ale, unsigned int adr, u_char off)
86 {
87         register u_char ret;
88
89         byteout(ale, off);
90         ret = bytein(adr);
91         return (ret);
92 }
93
94 static inline void
95 readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
96 {
97         byteout(ale, off);
98         insb(adr, data, size);
99 }
100
101
102 static inline void
103 writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
104 {
105         byteout(ale, off);
106         byteout(adr, data);
107 }
108
109 static inline void
110 writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
111 {
112         byteout(ale, off);
113         outsb(adr, data, size);
114 }
115
116 static inline u_char
117 memreadreg(unsigned long adr, u_char off)
118 {
119         return(*((unsigned char *)
120                 (((unsigned int *)adr) + off)));
121 }
122
123 static inline void
124 memwritereg(unsigned long adr, u_char off, u_char data)
125 {
126         register u_char *p;
127         
128         p = (unsigned char *)(((unsigned int *)adr) + off);
129         *p = data;
130 }
131
132 /* Interface functions */
133
134 static u_char
135 ReadISAC(struct IsdnCardState *cs, u_char offset)
136 {
137         return(readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset));
138 }
139
140 static void
141 WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
142 {
143         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset, value);
144 }
145
146 static void
147 ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
148 {
149         readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size);
150 }
151
152 static void
153 WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
154 {
155         writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size);
156 }
157
158 static u_char
159 ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
160 {
161         return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset+0x80));
162 }
163
164 static void
165 WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
166 {
167         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset|0x80, value);
168 }
169
170 static void
171 ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
172 {
173         readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size);
174 }
175
176 static void
177 WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
178 {
179         writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size);
180 }
181
182 static u_char
183 ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
184 {
185         return(readreg(cs->hw.diva.hscx_adr,
186                 cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0)));
187 }
188
189 static void
190 WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
191 {
192         writereg(cs->hw.diva.hscx_adr,
193                 cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0), value);
194 }
195
196 static u_char
197 MemReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
198 {
199         return (memreadreg(cs->hw.diva.cfg_reg, offset+0x80));
200 }
201
202 static void
203 MemWriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
204 {
205         memwritereg(cs->hw.diva.cfg_reg, offset|0x80, value);
206 }
207
208 static void
209 MemReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
210 {
211         while(size--)
212                 *data++ = memreadreg(cs->hw.diva.cfg_reg, 0x80);
213 }
214
215 static void
216 MemWriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
217 {
218         while(size--)
219                 memwritereg(cs->hw.diva.cfg_reg, 0x80, *data++);
220 }
221
222 static u_char
223 MemReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
224 {
225         return(memreadreg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0)));
226 }
227
228 static void
229 MemWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
230 {
231         memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0), value);
232 }
233
234 /* IO-Functions for IPACX type cards */
235 static u_char
236 MemReadISAC_IPACX(struct IsdnCardState *cs, u_char offset)
237 {
238         return (memreadreg(cs->hw.diva.cfg_reg, offset));
239 }
240
241 static void
242 MemWriteISAC_IPACX(struct IsdnCardState *cs, u_char offset, u_char value)
243 {
244         memwritereg(cs->hw.diva.cfg_reg, offset, value);
245 }
246
247 static void
248 MemReadISACfifo_IPACX(struct IsdnCardState *cs, u_char * data, int size)
249 {
250         while(size--)
251                 *data++ = memreadreg(cs->hw.diva.cfg_reg, 0);
252 }
253
254 static void
255 MemWriteISACfifo_IPACX(struct IsdnCardState *cs, u_char * data, int size)
256 {
257         while(size--)
258                 memwritereg(cs->hw.diva.cfg_reg, 0, *data++);
259 }
260
261 static u_char
262 MemReadHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset)
263 {
264         return(memreadreg(cs->hw.diva.cfg_reg, offset + 
265                     (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1)));
266 }
267
268 static void
269 MemWriteHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
270 {
271         memwritereg(cs->hw.diva.cfg_reg, offset + 
272               (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1), value);
273 }
274
275 /*
276  * fast interrupt HSCX stuff goes here
277  */
278
279 #define READHSCX(cs, nr, reg) readreg(cs->hw.diva.hscx_adr, \
280                 cs->hw.diva.hscx, reg + (nr ? 0x40 : 0))
281 #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.diva.hscx_adr, \
282                 cs->hw.diva.hscx, reg + (nr ? 0x40 : 0), data)
283
284 #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.diva.hscx_adr, \
285                 cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
286
287 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.diva.hscx_adr, \
288                 cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
289
290 #include "hscx_irq.c"
291
292 static irqreturn_t
293 diva_interrupt(int intno, void *dev_id, struct pt_regs *regs)
294 {
295         struct IsdnCardState *cs = dev_id;
296         u_char val, sval;
297         u_long flags;
298         int cnt=5;
299
300         spin_lock_irqsave(&cs->lock, flags);
301         while (((sval = bytein(cs->hw.diva.ctrl)) & DIVA_IRQ_REQ) && cnt) {
302                 val = readreg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_ISTA + 0x40);
303                 if (val)
304                         hscx_int_main(cs, val);
305                 val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA);
306                 if (val)
307                         isac_interrupt(cs, val);
308                 cnt--;
309         }
310         if (!cnt)
311                 printk(KERN_WARNING "Diva: IRQ LOOP\n");
312         writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0xFF);
313         writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0xFF);
314         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0xFF);
315         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0x0);
316         writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0x0);
317         writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0x0);
318         spin_unlock_irqrestore(&cs->lock, flags);
319         return IRQ_HANDLED;
320 }
321
322 static irqreturn_t
323 diva_irq_ipac_isa(int intno, void *dev_id, struct pt_regs *regs)
324 {
325         struct IsdnCardState *cs = dev_id;
326         u_char ista,val;
327         u_long flags;
328         int icnt=5;
329
330         spin_lock_irqsave(&cs->lock, flags);
331         ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA);
332 Start_IPACISA:
333         if (cs->debug & L1_DEB_IPAC)
334                 debugl1(cs, "IPAC ISTA %02X", ista);
335         if (ista & 0x0f) {
336                 val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, HSCX_ISTA + 0x40);
337                 if (ista & 0x01)
338                         val |= 0x01;
339                 if (ista & 0x04)
340                         val |= 0x02;
341                 if (ista & 0x08)
342                         val |= 0x04;
343                 if (val)
344                         hscx_int_main(cs, val);
345         }
346         if (ista & 0x20) {
347                 val = 0xfe & readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA + 0x80);
348                 if (val) {
349                         isac_interrupt(cs, val);
350                 }
351         }
352         if (ista & 0x10) {
353                 val = 0x01;
354                 isac_interrupt(cs, val);
355         }
356         ista  = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA);
357         if ((ista & 0x3f) && icnt) {
358                 icnt--;
359                 goto Start_IPACISA;
360         }
361         if (!icnt)
362                 printk(KERN_WARNING "DIVA IPAC IRQ LOOP\n");
363         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xFF);
364         writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xC0);
365         spin_unlock_irqrestore(&cs->lock, flags);
366         return IRQ_HANDLED;
367 }
368
369 static inline void
370 MemwaitforCEC(struct IsdnCardState *cs, int hscx)
371 {
372         int to = 50;
373
374         while ((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x04) && to) {
375                 udelay(1);
376                 to--;
377         }
378         if (!to)
379                 printk(KERN_WARNING "HiSax: waitforCEC timeout\n");
380 }
381
382
383 static inline void
384 MemwaitforXFW(struct IsdnCardState *cs, int hscx)
385 {
386         int to = 50;
387
388         while ((!(MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) == 0x40) && to) {
389                 udelay(1);
390                 to--;
391         }
392         if (!to)
393                 printk(KERN_WARNING "HiSax: waitforXFW timeout\n");
394 }
395
396 static inline void
397 MemWriteHSCXCMDR(struct IsdnCardState *cs, int hscx, u_char data)
398 {
399         MemwaitforCEC(cs, hscx);
400         MemWriteHSCX(cs, hscx, HSCX_CMDR, data);
401 }
402
403 static void
404 Memhscx_empty_fifo(struct BCState *bcs, int count)
405 {
406         u_char *ptr;
407         struct IsdnCardState *cs = bcs->cs;
408         int cnt;
409
410         if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
411                 debugl1(cs, "hscx_empty_fifo");
412
413         if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) {
414                 if (cs->debug & L1_DEB_WARN)
415                         debugl1(cs, "hscx_empty_fifo: incoming packet too large");
416                 MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80);
417                 bcs->hw.hscx.rcvidx = 0;
418                 return;
419         }
420         ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
421         cnt = count;
422         while (cnt--)
423                 *ptr++ = memreadreg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0);
424         MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80);
425         ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
426         bcs->hw.hscx.rcvidx += count;
427         if (cs->debug & L1_DEB_HSCX_FIFO) {
428                 char *t = bcs->blog;
429
430                 t += sprintf(t, "hscx_empty_fifo %c cnt %d",
431                              bcs->hw.hscx.hscx ? 'B' : 'A', count);
432                 QuickHex(t, ptr, count);
433                 debugl1(cs, bcs->blog);
434         }
435 }
436
437 static void
438 Memhscx_fill_fifo(struct BCState *bcs)
439 {
440         struct IsdnCardState *cs = bcs->cs;
441         int more, count, cnt;
442         int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
443         u_char *ptr,*p;
444
445         if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
446                 debugl1(cs, "hscx_fill_fifo");
447
448         if (!bcs->tx_skb)
449                 return;
450         if (bcs->tx_skb->len <= 0)
451                 return;
452
453         more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0;
454         if (bcs->tx_skb->len > fifo_size) {
455                 more = !0;
456                 count = fifo_size;
457         } else
458                 count = bcs->tx_skb->len;
459         cnt = count;
460         MemwaitforXFW(cs, bcs->hw.hscx.hscx);
461         p = ptr = bcs->tx_skb->data;
462         skb_pull(bcs->tx_skb, count);
463         bcs->tx_cnt -= count;
464         bcs->hw.hscx.count += count;
465         while(cnt--)
466                 memwritereg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0,
467                         *p++);
468         MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa);
469         if (cs->debug & L1_DEB_HSCX_FIFO) {
470                 char *t = bcs->blog;
471
472                 t += sprintf(t, "hscx_fill_fifo %c cnt %d",
473                              bcs->hw.hscx.hscx ? 'B' : 'A', count);
474                 QuickHex(t, ptr, count);
475                 debugl1(cs, bcs->blog);
476         }
477 }
478
479 static inline void
480 Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
481 {
482         u_char r;
483         struct BCState *bcs = cs->bcs + hscx;
484         struct sk_buff *skb;
485         int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
486         int count;
487
488         if (!test_bit(BC_FLG_INIT, &bcs->Flag))
489                 return;
490
491         if (val & 0x80) {       /* RME */
492                 r = MemReadHSCX(cs, hscx, HSCX_RSTA);
493                 if ((r & 0xf0) != 0xa0) {
494                         if (!(r & 0x80))
495                                 if (cs->debug & L1_DEB_WARN)
496                                         debugl1(cs, "HSCX invalid frame");
497                         if ((r & 0x40) && bcs->mode)
498                                 if (cs->debug & L1_DEB_WARN)
499                                         debugl1(cs, "HSCX RDO mode=%d",
500                                                 bcs->mode);
501                         if (!(r & 0x20))
502                                 if (cs->debug & L1_DEB_WARN)
503                                         debugl1(cs, "HSCX CRC error");
504                         MemWriteHSCXCMDR(cs, hscx, 0x80);
505                 } else {
506                         count = MemReadHSCX(cs, hscx, HSCX_RBCL) & (
507                                 test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f);
508                         if (count == 0)
509                                 count = fifo_size;
510                         Memhscx_empty_fifo(bcs, count);
511                         if ((count = bcs->hw.hscx.rcvidx - 1) > 0) {
512                                 if (cs->debug & L1_DEB_HSCX_FIFO)
513                                         debugl1(cs, "HX Frame %d", count);
514                                 if (!(skb = dev_alloc_skb(count)))
515                                         printk(KERN_WARNING "HSCX: receive out of memory\n");
516                                 else {
517                                         memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count);
518                                         skb_queue_tail(&bcs->rqueue, skb);
519                                 }
520                         }
521                 }
522                 bcs->hw.hscx.rcvidx = 0;
523                 schedule_event(bcs, B_RCVBUFREADY);
524         }
525         if (val & 0x40) {       /* RPF */
526                 Memhscx_empty_fifo(bcs, fifo_size);
527                 if (bcs->mode == L1_MODE_TRANS) {
528                         /* receive audio data */
529                         if (!(skb = dev_alloc_skb(fifo_size)))
530                                 printk(KERN_WARNING "HiSax: receive out of memory\n");
531                         else {
532                                 memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size);
533                                 skb_queue_tail(&bcs->rqueue, skb);
534                         }
535                         bcs->hw.hscx.rcvidx = 0;
536                         schedule_event(bcs, B_RCVBUFREADY);
537                 }
538         }
539         if (val & 0x10) {       /* XPR */
540                 if (bcs->tx_skb) {
541                         if (bcs->tx_skb->len) {
542                                 Memhscx_fill_fifo(bcs);
543                                 return;
544                         } else {
545                                 if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
546                                         (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
547                                         u_long  flags;
548                                         spin_lock_irqsave(&bcs->aclock, flags);
549                                         bcs->ackcnt += bcs->hw.hscx.count;
550                                         spin_unlock_irqrestore(&bcs->aclock, flags);
551                                         schedule_event(bcs, B_ACKPENDING);
552                                 }
553                                 dev_kfree_skb_irq(bcs->tx_skb);
554                                 bcs->hw.hscx.count = 0; 
555                                 bcs->tx_skb = NULL;
556                         }
557                 }
558                 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
559                         bcs->hw.hscx.count = 0;
560                         test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
561                         Memhscx_fill_fifo(bcs);
562                 } else {
563                         test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
564                         schedule_event(bcs, B_XMTBUFREADY);
565                 }
566         }
567 }
568
569 static inline void
570 Memhscx_int_main(struct IsdnCardState *cs, u_char val)
571 {
572
573         u_char exval;
574         struct BCState *bcs;
575
576         if (val & 0x01) { // EXB
577                 bcs = cs->bcs + 1;
578                 exval = MemReadHSCX(cs, 1, HSCX_EXIR);
579                 if (exval & 0x40) {
580                         if (bcs->mode == 1)
581                                 Memhscx_fill_fifo(bcs);
582                         else {
583                                 /* Here we lost an TX interrupt, so
584                                    * restart transmitting the whole frame.
585                                  */
586                                 if (bcs->tx_skb) {
587                                         skb_push(bcs->tx_skb, bcs->hw.hscx.count);
588                                         bcs->tx_cnt += bcs->hw.hscx.count;
589                                         bcs->hw.hscx.count = 0;
590                                 }
591                                 MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01);
592                                 if (cs->debug & L1_DEB_WARN)
593                                         debugl1(cs, "HSCX B EXIR %x Lost TX", exval);
594                         }
595                 } else if (cs->debug & L1_DEB_HSCX)
596                         debugl1(cs, "HSCX B EXIR %x", exval);
597         }
598         if (val & 0xf8) {
599                 if (cs->debug & L1_DEB_HSCX)
600                         debugl1(cs, "HSCX B interrupt %x", val);
601                 Memhscx_interrupt(cs, val, 1);
602         }
603         if (val & 0x02) {       // EXA
604                 bcs = cs->bcs;
605                 exval = MemReadHSCX(cs, 0, HSCX_EXIR);
606                 if (exval & 0x40) {
607                         if (bcs->mode == L1_MODE_TRANS)
608                                 Memhscx_fill_fifo(bcs);
609                         else {
610                                 /* Here we lost an TX interrupt, so
611                                    * restart transmitting the whole frame.
612                                  */
613                                 if (bcs->tx_skb) {
614                                         skb_push(bcs->tx_skb, bcs->hw.hscx.count);
615                                         bcs->tx_cnt += bcs->hw.hscx.count;
616                                         bcs->hw.hscx.count = 0;
617                                 }
618                                 MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01);
619                                 if (cs->debug & L1_DEB_WARN)
620                                         debugl1(cs, "HSCX A EXIR %x Lost TX", exval);
621                         }
622                 } else if (cs->debug & L1_DEB_HSCX)
623                         debugl1(cs, "HSCX A EXIR %x", exval);
624         }
625         if (val & 0x04) {       // ICA
626                 exval = MemReadHSCX(cs, 0, HSCX_ISTA);
627                 if (cs->debug & L1_DEB_HSCX)
628                         debugl1(cs, "HSCX A interrupt %x", exval);
629                 Memhscx_interrupt(cs, exval, 0);
630         }
631 }
632
633 static irqreturn_t
634 diva_irq_ipac_pci(int intno, void *dev_id, struct pt_regs *regs)
635 {
636         struct IsdnCardState *cs = dev_id;
637         u_char ista,val;
638         int icnt=5;
639         u_char *cfg;
640         u_long flags;
641
642         spin_lock_irqsave(&cs->lock, flags);
643         cfg = (u_char *) cs->hw.diva.pci_cfg;
644         val = *cfg;
645         if (!(val & PITA_INT0_STATUS)) {
646                 spin_unlock_irqrestore(&cs->lock, flags);
647                 return IRQ_NONE; /* other shared IRQ */
648         }
649         *cfg = PITA_INT0_STATUS; /* Reset pending INT0 */
650         ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA);
651 Start_IPACPCI:
652         if (cs->debug & L1_DEB_IPAC)
653                 debugl1(cs, "IPAC ISTA %02X", ista);
654         if (ista & 0x0f) {
655                 val = memreadreg(cs->hw.diva.cfg_reg, HSCX_ISTA + 0x40);
656                 if (ista & 0x01)
657                         val |= 0x01;
658                 if (ista & 0x04)
659                         val |= 0x02;
660                 if (ista & 0x08)
661                         val |= 0x04;
662                 if (val)
663                         Memhscx_int_main(cs, val);
664         }
665         if (ista & 0x20) {
666                 val = 0xfe & memreadreg(cs->hw.diva.cfg_reg, ISAC_ISTA + 0x80);
667                 if (val) {
668                         isac_interrupt(cs, val);
669                 }
670         }
671         if (ista & 0x10) {
672                 val = 0x01;
673                 isac_interrupt(cs, val);
674         }
675         ista  = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA);
676         if ((ista & 0x3f) && icnt) {
677                 icnt--;
678                 goto Start_IPACPCI;
679         }
680         if (!icnt)
681                 printk(KERN_WARNING "DIVA IPAC PCI IRQ LOOP\n");
682         memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xFF);
683         memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xC0);
684         spin_unlock_irqrestore(&cs->lock, flags);
685         return IRQ_HANDLED;
686 }
687
688 static irqreturn_t
689 diva_irq_ipacx_pci(int intno, void *dev_id, struct pt_regs *regs)
690 {
691         struct IsdnCardState *cs = dev_id;
692         u_char val;
693         u_char *cfg;
694         u_long flags;
695
696         spin_lock_irqsave(&cs->lock, flags);
697         cfg = (u_char *) cs->hw.diva.pci_cfg;
698         val = *cfg;
699         if (!(val &PITA_INT0_STATUS)) {
700                 spin_unlock_irqrestore(&cs->lock, flags);
701                 return IRQ_NONE; // other shared IRQ
702         }
703         interrupt_ipacx(cs);      // handler for chip
704         *cfg = PITA_INT0_STATUS;  // Reset PLX interrupt
705         spin_unlock_irqrestore(&cs->lock, flags);
706         return IRQ_HANDLED;
707 }
708
709 void
710 release_io_diva(struct IsdnCardState *cs)
711 {
712         int bytecnt;
713
714         if ((cs->subtyp == DIVA_IPAC_PCI) || 
715             (cs->subtyp == DIVA_IPACX_PCI)   ) {
716                 u_int *cfg = (unsigned int *)cs->hw.diva.pci_cfg;
717
718                 *cfg = 0; /* disable INT0/1 */ 
719                 *cfg = 2; /* reset pending INT0 */
720                 iounmap((void *)cs->hw.diva.cfg_reg);
721                 iounmap((void *)cs->hw.diva.pci_cfg);
722                 return;
723         } else if (cs->subtyp != DIVA_IPAC_ISA) {
724                 del_timer(&cs->hw.diva.tl);
725                 if (cs->hw.diva.cfg_reg)
726                         byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */
727         }
728         if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA))
729                 bytecnt = 8;
730         else
731                 bytecnt = 32;
732         if (cs->hw.diva.cfg_reg) {
733                 release_region(cs->hw.diva.cfg_reg, bytecnt);
734         }
735 }
736
737 static void
738 reset_diva(struct IsdnCardState *cs)
739 {
740         if (cs->subtyp == DIVA_IPAC_ISA) {
741                 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x20);
742                 mdelay(10);
743                 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x00);
744                 mdelay(10);
745                 writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xc0);
746         } else if (cs->subtyp == DIVA_IPAC_PCI) {
747                 unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg +
748                                         PITA_MISC_REG);
749                 *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE;
750                 mdelay(10);
751                 *ireg = PITA_PARA_MPX_MODE;
752                 mdelay(10);
753                 memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xc0);
754         } else if (cs->subtyp == DIVA_IPACX_PCI) {
755                 unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg +
756                                         PITA_MISC_REG);
757                 *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE;
758                 mdelay(10);
759                 *ireg = PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET;
760                 mdelay(10);
761                 MemWriteISAC_IPACX(cs, IPACX_MASK, 0xff); // Interrupts off
762         } else { /* DIVA 2.0 */
763                 cs->hw.diva.ctrl_reg = 0;        /* Reset On */
764                 byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);
765                 mdelay(10);
766                 cs->hw.diva.ctrl_reg |= DIVA_RESET;  /* Reset Off */
767                 byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);
768                 mdelay(10);
769                 if (cs->subtyp == DIVA_ISA)
770                         cs->hw.diva.ctrl_reg |= DIVA_ISA_LED_A;
771                 else {
772                         /* Workaround PCI9060 */
773                         byteout(cs->hw.diva.pci_cfg + 0x69, 9);
774                         cs->hw.diva.ctrl_reg |= DIVA_PCI_LED_A;
775                 }
776                 byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);
777         }
778 }
779
780 #define DIVA_ASSIGN 1
781
782 static void
783 diva_led_handler(struct IsdnCardState *cs)
784 {
785         int blink = 0;
786
787         if ((cs->subtyp == DIVA_IPAC_ISA) ||
788             (cs->subtyp == DIVA_IPAC_PCI) ||
789             (cs->subtyp == DIVA_IPACX_PCI)   )
790                 return;
791         del_timer(&cs->hw.diva.tl);
792         if (cs->hw.diva.status & DIVA_ASSIGN)
793                 cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ?
794                         DIVA_ISA_LED_A : DIVA_PCI_LED_A;
795         else {
796                 cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ?
797                         DIVA_ISA_LED_A : DIVA_PCI_LED_A;
798                 blink = 250;
799         }
800         if (cs->hw.diva.status & 0xf000)
801                 cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ?
802                         DIVA_ISA_LED_B : DIVA_PCI_LED_B;
803         else if (cs->hw.diva.status & 0x0f00) {
804                 cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ?
805                         DIVA_ISA_LED_B : DIVA_PCI_LED_B;
806                 blink = 500;
807         } else
808                 cs->hw.diva.ctrl_reg &= ~((DIVA_ISA == cs->subtyp) ?
809                         DIVA_ISA_LED_B : DIVA_PCI_LED_B);
810
811         byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);
812         if (blink) {
813                 init_timer(&cs->hw.diva.tl);
814                 cs->hw.diva.tl.expires = jiffies + ((blink * HZ) / 1000);
815                 add_timer(&cs->hw.diva.tl);
816         }
817 }
818
819 static int
820 Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg)
821 {
822         u_int *ireg;
823         u_long flags;
824
825         switch (mt) {
826                 case CARD_RESET:
827                         spin_lock_irqsave(&cs->lock, flags);
828                         reset_diva(cs);
829                         spin_unlock_irqrestore(&cs->lock, flags);
830                         return(0);
831                 case CARD_RELEASE:
832                         release_io_diva(cs);
833                         return(0);
834                 case CARD_INIT:
835                         spin_lock_irqsave(&cs->lock, flags);
836                         reset_diva(cs);
837                         if (cs->subtyp == DIVA_IPACX_PCI) {
838                                 ireg = (unsigned int *)cs->hw.diva.pci_cfg;
839                                 *ireg = PITA_INT0_ENABLE;
840                                 init_ipacx(cs, 3); // init chip and enable interrupts
841                                 spin_unlock_irqrestore(&cs->lock, flags);
842                                 return (0);
843                         }
844                         if (cs->subtyp == DIVA_IPAC_PCI) {
845                                 ireg = (unsigned int *)cs->hw.diva.pci_cfg;
846                                 *ireg = PITA_INT0_ENABLE;
847                         }
848                         inithscxisac(cs, 3);
849                         spin_unlock_irqrestore(&cs->lock, flags);
850                         return(0);
851                 case CARD_TEST:
852                         return(0);
853                 case (MDL_REMOVE | REQUEST):
854                         cs->hw.diva.status = 0;
855                         break;
856                 case (MDL_ASSIGN | REQUEST):
857                         cs->hw.diva.status |= DIVA_ASSIGN;
858                         break;
859                 case MDL_INFO_SETUP:
860                         if ((long)arg)
861                                 cs->hw.diva.status |=  0x0200;
862                         else
863                                 cs->hw.diva.status |=  0x0100;
864                         break;
865                 case MDL_INFO_CONN:
866                         if ((long)arg)
867                                 cs->hw.diva.status |=  0x2000;
868                         else
869                                 cs->hw.diva.status |=  0x1000;
870                         break;
871                 case MDL_INFO_REL:
872                         if ((long)arg) {
873                                 cs->hw.diva.status &=  ~0x2000;
874                                 cs->hw.diva.status &=  ~0x0200;
875                         } else {
876                                 cs->hw.diva.status &=  ~0x1000;
877                                 cs->hw.diva.status &=  ~0x0100;
878                         }
879                         break;
880         }
881         if ((cs->subtyp != DIVA_IPAC_ISA) && 
882             (cs->subtyp != DIVA_IPAC_PCI) &&
883             (cs->subtyp != DIVA_IPACX_PCI)) {
884                 spin_lock_irqsave(&cs->lock, flags);
885                 diva_led_handler(cs);
886                 spin_unlock_irqrestore(&cs->lock, flags);
887         }
888         return(0);
889 }
890
891 static struct pci_dev *dev_diva __initdata = NULL;
892 static struct pci_dev *dev_diva_u __initdata = NULL;
893 static struct pci_dev *dev_diva201 __initdata = NULL;
894 static struct pci_dev *dev_diva202 __initdata = NULL;
895
896 #ifdef __ISAPNP__
897 static struct isapnp_device_id diva_ids[] __initdata = {
898         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
899           ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), 
900           (unsigned long) "Diva picola" },
901         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
902           ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), 
903           (unsigned long) "Diva picola" },
904         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
905           ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), 
906           (unsigned long) "Diva 2.0" },
907         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
908           ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), 
909           (unsigned long) "Diva 2.0" },
910         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
911           ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), 
912           (unsigned long) "Diva 2.01" },
913         { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
914           ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), 
915           (unsigned long) "Diva 2.01" },
916         { 0, }
917 };
918
919 static struct isapnp_device_id *ipid __initdata = &diva_ids[0];
920 static struct pnp_card *pnp_c __devinitdata = NULL;
921 #endif
922
923
924 int __init
925 setup_diva(struct IsdnCard *card)
926 {
927         int bytecnt = 8;
928         u_char val;
929         struct IsdnCardState *cs = card->cs;
930         char tmp[64];
931
932         strcpy(tmp, Diva_revision);
933         printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp));
934         if (cs->typ != ISDN_CTYPE_DIEHLDIVA)
935                 return(0);
936         cs->hw.diva.status = 0;
937         if (card->para[1]) {
938                 cs->hw.diva.ctrl_reg = 0;
939                 cs->hw.diva.cfg_reg = card->para[1];
940                 val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR,
941                         cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID);
942                 printk(KERN_INFO "Diva: IPAC version %x\n", val);
943                 if ((val == 1) || (val==2)) {
944                         cs->subtyp = DIVA_IPAC_ISA;
945                         cs->hw.diva.ctrl = 0;
946                         cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA;
947                         cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA;
948                         cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR;
949                         cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR;
950                         test_and_set_bit(HW_IPAC, &cs->HW_Flags);
951                 } else {
952                         cs->subtyp = DIVA_ISA;
953                         cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL;
954                         cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA;
955                         cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA;
956                         cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR;
957                         cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR;
958                 }
959                 cs->irq = card->para[0];
960         } else {
961 #ifdef __ISAPNP__
962                 if (isapnp_present()) {
963                         struct pnp_dev *pnp_d;
964                         while(ipid->card_vendor) {
965                                 if ((pnp_c = pnp_find_card(ipid->card_vendor,
966                                         ipid->card_device, pnp_c))) {
967                                         pnp_d = NULL;
968                                         if ((pnp_d = pnp_find_dev(pnp_c,
969                                                 ipid->vendor, ipid->function, pnp_d))) {
970                                                 int err;
971
972                                                 printk(KERN_INFO "HiSax: %s detected\n",
973                                                         (char *)ipid->driver_data);
974                                                 pnp_disable_dev(pnp_d);
975                                                 err = pnp_activate_dev(pnp_d);
976                                                 if (err<0) {
977                                                         printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
978                                                                 __FUNCTION__, err);
979                                                         return(0);
980                                                 }
981                                                 card->para[1] = pnp_port_start(pnp_d, 0);
982                                                 card->para[0] = pnp_irq(pnp_d, 0);
983                                                 if (!card->para[0] || !card->para[1]) {
984                                                         printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n",
985                                                                 card->para[0], card->para[1]);
986                                                         pnp_disable_dev(pnp_d); 
987                                                         return(0);
988                                                 }
989                                                 cs->hw.diva.cfg_reg  = card->para[1];
990                                                 cs->irq = card->para[0];
991                                                 if (ipid->function == ISAPNP_FUNCTION(0xA1)) {
992                                                         cs->subtyp = DIVA_IPAC_ISA;
993                                                         cs->hw.diva.ctrl = 0;
994                                                         cs->hw.diva.isac =
995                                                                 card->para[1] + DIVA_IPAC_DATA;
996                                                         cs->hw.diva.hscx =
997                                                                 card->para[1] + DIVA_IPAC_DATA;
998                                                         cs->hw.diva.isac_adr =
999                                                                 card->para[1] + DIVA_IPAC_ADR;
1000                                                         cs->hw.diva.hscx_adr =
1001                                                                 card->para[1] + DIVA_IPAC_ADR;
1002                                                         test_and_set_bit(HW_IPAC, &cs->HW_Flags);
1003                                                 } else {
1004                                                         cs->subtyp = DIVA_ISA;
1005                                                         cs->hw.diva.ctrl =
1006                                                                 card->para[1] + DIVA_ISA_CTRL;
1007                                                         cs->hw.diva.isac =
1008                                                                 card->para[1] + DIVA_ISA_ISAC_DATA;
1009                                                         cs->hw.diva.hscx =
1010                                                                 card->para[1] + DIVA_HSCX_DATA;
1011                                                         cs->hw.diva.isac_adr =
1012                                                                 card->para[1] + DIVA_ISA_ISAC_ADR;
1013                                                         cs->hw.diva.hscx_adr =
1014                                                                 card->para[1] + DIVA_HSCX_ADR;
1015                                                 }
1016                                                 goto ready;
1017                                         } else {
1018                                                 printk(KERN_ERR "Diva PnP: PnP error card found, no device\n");
1019                                                 return(0);
1020                                         }
1021                                 }
1022                                 ipid++;
1023                                 pnp_c=NULL;
1024                         } 
1025                         if (!ipid->card_vendor) {
1026                                 printk(KERN_INFO "Diva PnP: no ISAPnP card found\n");
1027                         }
1028                 }
1029 #endif
1030 #ifdef CONFIG_PCI
1031                 cs->subtyp = 0;
1032                 if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON,
1033                         PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) {
1034                         if (pci_enable_device(dev_diva))
1035                                 return(0);
1036                         cs->subtyp = DIVA_PCI;
1037                         cs->irq = dev_diva->irq;
1038                         cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2);
1039                 } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON,
1040                         PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) {
1041                         if (pci_enable_device(dev_diva_u))
1042                                 return(0);
1043                         cs->subtyp = DIVA_PCI;
1044                         cs->irq = dev_diva_u->irq;
1045                         cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2);
1046                 } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON,
1047                         PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) {
1048                         if (pci_enable_device(dev_diva201))
1049                                 return(0);
1050                         cs->subtyp = DIVA_IPAC_PCI;
1051                         cs->irq = dev_diva201->irq;
1052                         cs->hw.diva.pci_cfg =
1053                                 (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096);
1054                         cs->hw.diva.cfg_reg =
1055                                 (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096);
1056                 } else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON,
1057                         PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) {
1058                         if (pci_enable_device(dev_diva202))
1059                                 return(0);
1060                         cs->subtyp = DIVA_IPACX_PCI;
1061                         cs->irq = dev_diva202->irq;
1062                         cs->hw.diva.pci_cfg =
1063                                 (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096);
1064                         cs->hw.diva.cfg_reg =
1065                                 (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096);
1066                 } else {
1067                         printk(KERN_WARNING "Diva: No PCI card found\n");
1068                         return(0);
1069                 }
1070
1071                 if (!cs->irq) {
1072                         printk(KERN_WARNING "Diva: No IRQ for PCI card found\n");
1073                         return(0);
1074                 }
1075
1076                 if (!cs->hw.diva.cfg_reg) {
1077                         printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n");
1078                         return(0);
1079                 }
1080                 cs->irq_flags |= SA_SHIRQ;
1081 #else
1082                 printk(KERN_WARNING "Diva: cfgreg 0 and NO_PCI_BIOS\n");
1083                 printk(KERN_WARNING "Diva: unable to config DIVA PCI\n");
1084                 return (0);
1085 #endif /* CONFIG_PCI */
1086                 if ((cs->subtyp == DIVA_IPAC_PCI) ||
1087                     (cs->subtyp == DIVA_IPACX_PCI)   ) {
1088                         cs->hw.diva.ctrl = 0;
1089                         cs->hw.diva.isac = 0;
1090                         cs->hw.diva.hscx = 0;
1091                         cs->hw.diva.isac_adr = 0;
1092                         cs->hw.diva.hscx_adr = 0;
1093                         test_and_set_bit(HW_IPAC, &cs->HW_Flags);
1094                         bytecnt = 0;
1095                 } else {
1096                         cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL;
1097                         cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA;
1098                         cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA;
1099                         cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR;
1100                         cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR;
1101                         bytecnt = 32;
1102                 }
1103         }
1104 ready:
1105         printk(KERN_INFO
1106                 "Diva: %s card configured at %#lx IRQ %d\n",
1107                 (cs->subtyp == DIVA_PCI) ? "PCI" :
1108                 (cs->subtyp == DIVA_ISA) ? "ISA" : 
1109                 (cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" :
1110                 (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
1111                 cs->hw.diva.cfg_reg, cs->irq);
1112         if ((cs->subtyp == DIVA_IPAC_PCI)  || 
1113             (cs->subtyp == DIVA_IPACX_PCI) || 
1114             (cs->subtyp == DIVA_PCI)         )
1115                 printk(KERN_INFO "Diva: %s space at %#lx\n",
1116                         (cs->subtyp == DIVA_PCI) ? "PCI" :
1117                         (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
1118                         cs->hw.diva.pci_cfg);
1119         if ((cs->subtyp != DIVA_IPAC_PCI) &&
1120             (cs->subtyp != DIVA_IPACX_PCI)   ) {
1121                 if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) {
1122                         printk(KERN_WARNING
1123                                "HiSax: %s config port %lx-%lx already in use\n",
1124                                CardType[card->typ],
1125                                cs->hw.diva.cfg_reg,
1126                                cs->hw.diva.cfg_reg + bytecnt);
1127                         return (0);
1128                 }
1129         }
1130         cs->BC_Read_Reg  = &ReadHSCX;
1131         cs->BC_Write_Reg = &WriteHSCX;
1132         cs->BC_Send_Data = &hscx_fill_fifo;
1133         cs->cardmsg = &Diva_card_msg;
1134         setup_isac(cs);
1135         if (cs->subtyp == DIVA_IPAC_ISA) {
1136                 cs->readisac  = &ReadISAC_IPAC;
1137                 cs->writeisac = &WriteISAC_IPAC;
1138                 cs->readisacfifo  = &ReadISACfifo_IPAC;
1139                 cs->writeisacfifo = &WriteISACfifo_IPAC;
1140                 cs->irq_func = &diva_irq_ipac_isa;
1141                 val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID);
1142                 printk(KERN_INFO "Diva: IPAC version %x\n", val);
1143         } else if (cs->subtyp == DIVA_IPAC_PCI) {
1144                 cs->readisac  = &MemReadISAC_IPAC;
1145                 cs->writeisac = &MemWriteISAC_IPAC;
1146                 cs->readisacfifo  = &MemReadISACfifo_IPAC;
1147                 cs->writeisacfifo = &MemWriteISACfifo_IPAC;
1148                 cs->BC_Read_Reg  = &MemReadHSCX;
1149                 cs->BC_Write_Reg = &MemWriteHSCX;
1150                 cs->BC_Send_Data = &Memhscx_fill_fifo;
1151                 cs->irq_func = &diva_irq_ipac_pci;
1152                 val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID);
1153                 printk(KERN_INFO "Diva: IPAC version %x\n", val);
1154         } else if (cs->subtyp == DIVA_IPACX_PCI) {
1155                 cs->readisac  = &MemReadISAC_IPACX;
1156                 cs->writeisac = &MemWriteISAC_IPACX;
1157                 cs->readisacfifo  = &MemReadISACfifo_IPACX;
1158                 cs->writeisacfifo = &MemWriteISACfifo_IPACX;
1159                 cs->BC_Read_Reg  = &MemReadHSCX_IPACX;
1160                 cs->BC_Write_Reg = &MemWriteHSCX_IPACX;
1161                 cs->BC_Send_Data = NULL; // function located in ipacx module
1162                 cs->irq_func = &diva_irq_ipacx_pci;
1163                 printk(KERN_INFO "Diva: IPACX Design Id: %x\n", 
1164                         MemReadISAC_IPACX(cs, IPACX_ID) &0x3F);
1165         } else { /* DIVA 2.0 */
1166                 cs->hw.diva.tl.function = (void *) diva_led_handler;
1167                 cs->hw.diva.tl.data = (long) cs;
1168                 init_timer(&cs->hw.diva.tl);
1169                 cs->readisac  = &ReadISAC;
1170                 cs->writeisac = &WriteISAC;
1171                 cs->readisacfifo  = &ReadISACfifo;
1172                 cs->writeisacfifo = &WriteISACfifo;
1173                 cs->irq_func = &diva_interrupt;
1174                 ISACVersion(cs, "Diva:");
1175                 if (HscxVersion(cs, "Diva:")) {
1176                         printk(KERN_WARNING
1177                        "Diva: wrong HSCX versions check IO address\n");
1178                         release_io_diva(cs);
1179                         return (0);
1180                 }
1181         }
1182         return (1);
1183 }