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